From 85d699fcd76098ffe696f83d75b5b7563ea79679 Mon Sep 17 00:00:00 2001 From: Arthrutus <75637913+Arthrutus@users.noreply.github.com> Date: Wed, 20 Oct 2021 10:38:20 -0500 Subject: [PATCH 001/213] fix: Fixes archery in CharacterCreation and duplicate decorations for bucs den (#833) --- .../Data/Decoration/Britannia/bucs.cfg | 52 +------------------ Projects/UOContent/Misc/CharacterCreation.cs | 2 +- 2 files changed, 2 insertions(+), 52 deletions(-) diff --git a/Distribution/Data/Decoration/Britannia/bucs.cfg b/Distribution/Data/Decoration/Britannia/bucs.cfg index deda623cf..1b9cfa84f 100644 --- a/Distribution/Data/Decoration/Britannia/bucs.cfg +++ b/Distribution/Data/Decoration/Britannia/bucs.cfg @@ -10,56 +10,6 @@ Static 0x051F Static 0x0520 2669 2073 -20 -# stone -Static 0x071E -2726 2133 0 -2727 2131 0 -2727 2131 5 -2727 2131 10 -2727 2131 15 -2727 2131 20 -2727 2131 25 -2727 2132 0 -2727 2132 30 -2727 2133 0 -2727 2133 30 -2727 2133 35 -2727 2134 0 -2727 2134 30 -2727 2135 0 -2727 2135 5 -2727 2135 10 -2727 2135 15 -2727 2135 20 -2727 2135 25 -2728 2133 0 - -# stone stairs -Static 0x071F -2727 2134 35 -2727 2135 30 - -# stone stairs -Static 0x0737 -2727 2131 30 -2727 2132 35 - -# stone stairs -Static 0x07A0 -2726 2132 0 - -# stone stairs -Static 0x07A1 -2728 2134 0 - -# stone stairs -Static 0x07A2 -2728 2132 0 - -# stone stairs -Static 0x07DA -2726 2134 0 - # bottle of ale BeverageBottle 0x099F (Content=Ale) 2659 2187 8 @@ -719,4 +669,4 @@ GlassMug 0x1F81 # glass of water GlassMug 0x1F91 (Content=Water) -2679 2233 4 \ No newline at end of file +2679 2233 4 diff --git a/Projects/UOContent/Misc/CharacterCreation.cs b/Projects/UOContent/Misc/CharacterCreation.cs index 0b58f83a8..da82bb8ec 100644 --- a/Projects/UOContent/Misc/CharacterCreation.cs +++ b/Projects/UOContent/Misc/CharacterCreation.cs @@ -855,7 +855,7 @@ namespace Server.Misc { Race.AllowElvesOnly => new ElvenCompositeLongbow(), Race.AllowGargoylesOnly => new SerpentstoneStaff(), - _ => new GnarledStaff() + _ => new Bow() }; private static void AddSkillItems(this Mobile m, SkillName skill) From 2890f5c3ec3820415ccbc0efe43caf263c9f3b79 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 31 Oct 2021 10:22:22 -0700 Subject: [PATCH 002/213] fix: Adds packet logging (#836) ### Enabling Packet Logging `[packetlogging on` and target the user. Supports command modifiers such as: `[online packetlogging on where accesslevel = player` Logs are saved in `path//packets.log`. It is a simple append-format log with no date splitting. --- Projects/Server/Buffers/CircularBuffer.cs | 2 +- .../Server/Buffers/CircularBufferReader.cs | 11 +- Projects/Server/Network/NetState/NetState.cs | 75 +++++++ Projects/Server/Text/HexStringConverter.cs | 21 ++ Projects/Server/Utilities/Utility.cs | 210 ++---------------- Projects/UOContent/Network/NetworkCommands.cs | 60 +++++ 6 files changed, 186 insertions(+), 193 deletions(-) create mode 100644 Projects/UOContent/Network/NetworkCommands.cs diff --git a/Projects/Server/Buffers/CircularBuffer.cs b/Projects/Server/Buffers/CircularBuffer.cs index 540d23a0b..20a9d3a55 100644 --- a/Projects/Server/Buffers/CircularBuffer.cs +++ b/Projects/Server/Buffers/CircularBuffer.cs @@ -129,7 +129,7 @@ namespace System.Buffers public Span GetSpan(int index) { - if (index < 0 || index > 1) + if (index is < 0 or > 1) { throw new ArgumentOutOfRangeException(nameof(index)); } diff --git a/Projects/Server/Buffers/CircularBufferReader.cs b/Projects/Server/Buffers/CircularBufferReader.cs index 56619c6e0..40eeafc2f 100644 --- a/Projects/Server/Buffers/CircularBufferReader.cs +++ b/Projects/Server/Buffers/CircularBufferReader.cs @@ -32,6 +32,10 @@ namespace Server.Network public int Position { get; private set; } public int Remaining => Length - Position; + // Only used for debugging! + public ReadOnlySpan First => _first; + public ReadOnlySpan Second => _second; + public CircularBufferReader(ref CircularBuffer buffer) : this(buffer.GetSpan(0), buffer.GetSpan(1)) { } @@ -58,12 +62,9 @@ namespace Server.Network try { - using var sw = new StreamWriter("Packets.log", true); - + using var sw = new StreamWriter("unhandled-packets.log", true); sw.WriteLine("Client: {0}: Unhandled packet 0x{1:X2}", state, _first[0]); - - Utility.FormatBuffer(sw, _first.ToArray(), new Memory(_second.ToArray())); - + sw.FormatBuffer(_first, _second, Length); sw.WriteLine(); sw.WriteLine(); } diff --git a/Projects/Server/Network/NetState/NetState.cs b/Projects/Server/Network/NetState/NetState.cs index 47c6bf381..5c0f91e60 100755 --- a/Projects/Server/Network/NetState/NetState.cs +++ b/Projects/Server/Network/NetState/NetState.cs @@ -73,6 +73,7 @@ namespace Server.Network internal ParserState _parserState = ParserState.AwaitingNextPacket; internal ProtocolState _protocolState = ProtocolState.AwaitingSeed; internal GCHandle _handle; + private bool _packetLogging; internal enum ParserState { @@ -97,6 +98,13 @@ namespace Server.Network Error } + private static string _packetLoggingPath; + + public static void Configure() + { + _packetLoggingPath = ServerConfiguration.GetSetting("netstate.packetLoggingPath", Path.Combine(Core.BaseDirectory, "Packets")); + } + public static void Initialize() { Timer.DelayCall(TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1.5), CheckAllAlive); @@ -142,6 +150,21 @@ namespace Server.Network CreatedCallback?.Invoke(this); } + // Only use this for debugging. This will make your server very slow! + public bool PacketLogging + { + get => _packetLogging; + set + { + _packetLogging = value; + + if (_packetLogging) + { + StartPacketLog(); + } + } + } + public DateTime ConnectedOn { get; } public TimeSpan ConnectedFor => Core.Now - ConnectedOn; @@ -486,6 +509,11 @@ namespace Server.Network buffer.CopyFrom(span); } + if (PacketLogging) + { + LogPacket(span, ReadOnlySpan.Empty, span.Length, false); + } + SendPipe.Writer.Advance((uint)length); if (!_flushQueued) @@ -506,6 +534,48 @@ namespace Server.Network } } + private void StartPacketLog() + { + try + { + var logDir = Path.Combine(_packetLoggingPath, _toString); + PathUtility.EnsureDirectory(logDir); + var logPath = Path.Combine(logDir, "packets.log"); + using var op = new StreamWriter(logPath, true); + + op.WriteLine(">>>>>>>>>> Logging started {0:yyyy/MM/dd HH:mm::ss} <<<<<<<<<<", Core.Now); + op.WriteLine(); + op.WriteLine(); + } + catch (Exception e) + { + Console.WriteLine(e); + } + } + + private void LogPacket(ReadOnlySpan first, ReadOnlySpan second, int totalLength, bool incoming) + { + try + { + var logDir = Path.Combine(_packetLoggingPath, _toString); + PathUtility.EnsureDirectory(logDir); + var logPath = Path.Combine(logDir, "packets.log"); + + const string incomingStr = "Client -> Server"; + const string outgoingStr = "Server -> Client"; + + using var sw = new StreamWriter(logPath, true); + sw.WriteLine($"{Core.Now:HH:mm:ss.ffff}: {(incoming ? incomingStr : outgoingStr)} 0x{first[0]:X2} (Length: {totalLength})"); + sw.FormatBuffer(first, second, totalLength); + sw.WriteLine(); + sw.WriteLine(); + } + catch + { + // ignored + } + } + public void HandleReceive() { if (!_running) @@ -760,6 +830,11 @@ namespace Server.Network UpdatePacketCount(packetId); + if (PacketLogging) + { + LogPacket(packetReader.First, packetReader.Second, packetLength, true); + } + handler.OnReceive(this, packetReader, ref packetLength); prof?.Finish(packetLength); diff --git a/Projects/Server/Text/HexStringConverter.cs b/Projects/Server/Text/HexStringConverter.cs index 28b786de3..257c73642 100644 --- a/Projects/Server/Text/HexStringConverter.cs +++ b/Projects/Server/Text/HexStringConverter.cs @@ -59,6 +59,27 @@ namespace Server.Text return result; } + public static unsafe int ToSpacedHexString(this ReadOnlySpan bytes, Span result) + { + var charsWritten = 0; + fixed (char* resultP = result) + { + for (int i = 0; i < bytes.Length; i++) + { + var resultP2 = (uint*)(resultP + charsWritten); + *resultP2 = m_Lookup32Chars[bytes[i]]; + charsWritten += 2; + + if (i < bytes.Length - 1) + { + *(resultP + charsWritten++) = ' '; + } + } + } + + return charsWritten; + } + public static string ToDelimitedHexString(this byte[] bytes) => ((ReadOnlySpan)bytes).ToDelimitedHexString(); public static unsafe string ToDelimitedHexString(this ReadOnlySpan bytes) diff --git a/Projects/Server/Utilities/Utility.cs b/Projects/Server/Utilities/Utility.cs index 286e488e7..e7cd004fb 100644 --- a/Projects/Server/Utilities/Utility.cs +++ b/Projects/Server/Utilities/Utility.cs @@ -11,6 +11,7 @@ using System.Xml; using Microsoft.Toolkit.HighPerformance; using Server.Buffers; using Server.Random; +using Server.Text; namespace Server { @@ -632,207 +633,42 @@ namespace Server } } - public static void FormatBuffer(TextWriter output, Stream input, int length) + public static void FormatBuffer(this TextWriter op, ReadOnlySpan first, ReadOnlySpan second, int totalLength) { - output.WriteLine(" 0 1 2 3 4 5 6 7 8 9 A B C D E F"); - output.WriteLine(" -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --"); + op.WriteLine(" 0 1 2 3 4 5 6 7 8 9 A B C D E F"); + op.WriteLine(" -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --"); - var byteIndex = 0; - - var whole = length >> 4; - var rem = length & 0xF; - - for (var i = 0; i < whole; ++i, byteIndex += 16) + if (totalLength <= 0) { - var bytes = new StringBuilder(49); - var chars = new StringBuilder(16); - - for (var j = 0; j < 16; ++j) - { - var c = input.ReadByte(); - - bytes.Append(c.ToString("X2")); - - if (j != 7) - { - bytes.Append(' '); - } - else - { - bytes.Append(" "); - } - - if (c >= 0x20 && c < 0x7F) - { - chars.Append((char)c); - } - else - { - chars.Append('.'); - } - } - - output.Write(byteIndex.ToString("X4")); - output.Write(" "); - output.Write(bytes.ToString()); - output.Write(" "); - output.WriteLine(chars.ToString()); + op.WriteLine("0000 "); + return; } - if (rem != 0) + Span lineBytes = stackalloc byte[16]; + Span lineChars = stackalloc char[47]; + for (var i = 0; i < totalLength; i += 16) { - var bytes = new StringBuilder(49); - var chars = new StringBuilder(rem); - - for (var j = 0; j < 16; ++j) + var length = Math.Min(totalLength - i, 16); + if (i < first.Length) { - if (j < rem) + var firstLength = Math.Min(length, first.Length - i); + first.Slice(i, firstLength).CopyTo(lineBytes); + + if (firstLength < length) { - var c = input.ReadByte(); - - bytes.Append(c.ToString("X2")); - - if (j != 7) - { - bytes.Append(' '); - } - else - { - bytes.Append(" "); - } - - if (c >= 0x20 && c < 0x7F) - { - chars.Append((char)c); - } - else - { - chars.Append('.'); - } - } - else - { - bytes.Append(" "); + second[..(length - first.Length - i)].CopyTo(lineBytes[(length - firstLength)..]); } } - - output.Write(byteIndex.ToString("X4")); - output.Write(" "); - output.Write(bytes.ToString()); - output.Write(" "); - output.WriteLine(chars.ToString()); - } - } - - public static void FormatBuffer(TextWriter output, params Memory[] mems) - { - output.WriteLine(" 0 1 2 3 4 5 6 7 8 9 A B C D E F"); - output.WriteLine(" -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --"); - - var byteIndex = 0; - - var length = 0; - for (var i = 0; i < mems.Length; i++) - { - length += mems[i].Length; - } - - var position = 0; - var memIndex = 0; - var span = mems[memIndex].Span; - - var whole = length >> 4; - var rem = length & 0xF; - - for (var i = 0; i < whole; ++i, byteIndex += 16) - { - var bytes = new StringBuilder(49); - var chars = new StringBuilder(16); - - for (var j = 0; j < 16; ++j) + else { - var c = span[position++]; - if (position > span.Length) - { - span = mems[memIndex++].Span; - position = 0; - } - - bytes.Append(c.ToString("X2")); - - if (j != 7) - { - bytes.Append(' '); - } - else - { - bytes.Append(" "); - } - - if (c >= 0x20 && c < 0x7F) - { - chars.Append((char)c); - } - else - { - chars.Append('.'); - } + second.Slice(i - first.Length, length).CopyTo(lineBytes); } - output.Write(byteIndex.ToString("X4")); - output.Write(" "); - output.Write(bytes.ToString()); - output.Write(" "); - output.WriteLine(chars.ToString()); - } + var charsWritten = ((ReadOnlySpan)lineBytes[..length]).ToSpacedHexString(lineChars); - if (rem != 0) - { - var bytes = new StringBuilder(49); - var chars = new StringBuilder(rem); - - for (var j = 0; j < 16; ++j) - { - if (j < rem) - { - var c = span[position++]; - if (position > span.Length) - { - span = mems[memIndex++].Span; - position = 0; - } - - bytes.Append(c.ToString("X2")); - - if (j != 7) - { - bytes.Append(' '); - } - else - { - bytes.Append(" "); - } - - if (c >= 0x20 && c < 0x7F) - { - chars.Append((char)c); - } - else - { - chars.Append('.'); - } - } - else - { - bytes.Append(" "); - } - } - - output.Write(byteIndex.ToString("X4")); - output.Write(" "); - output.Write(bytes.ToString()); - output.Write(" "); - output.WriteLine(chars.ToString()); + op.Write("{0:X4} ", i); + op.Write(lineChars[..charsWritten]); + op.WriteLine(); } } diff --git a/Projects/UOContent/Network/NetworkCommands.cs b/Projects/UOContent/Network/NetworkCommands.cs new file mode 100644 index 000000000..ce35f5af2 --- /dev/null +++ b/Projects/UOContent/Network/NetworkCommands.cs @@ -0,0 +1,60 @@ +using Server.Commands; +using Server.Commands.Generic; +using Server.Mobiles; + +namespace Server.Network +{ + public class PacketLoggingCommand : BaseCommand + { + public static void Initialize() + { + TargetCommands.Register(new PacketLoggingCommand()); + } + + public PacketLoggingCommand() + { + AccessLevel = AccessLevel.Developer; + Commands = new[] { "PacketLogging" }; + ObjectTypes = ObjectTypes.Mobiles; + Supports = CommandSupport.AllMobiles; + Usage = "PacketLogging "; + Description = "Enables or disables packet logging for a particular user until they disconnect."; + } + + public override void Execute(CommandEventArgs e, object targeted) + { + if (e.Arguments.Length == 0) + { + LogFailure("Format: PacketLogging "); + return; + } + + var from = e.Mobile; + var enable = Utility.ToBoolean(e.Arguments[0]); + + if (targeted is not PlayerMobile pm) + { + LogFailure("That is not a player."); + } + else if (pm.NetState == null) + { + LogFailure("The player is not connected."); + } + else if (from != pm && from.AccessLevel < pm.AccessLevel) + { + LogFailure("You do not have the required access level to do this."); + } + else + { + pm.NetState.PacketLogging = enable; + var enabled = enable ? "enabled" : "disabled"; + CommandLogging.WriteLine( + from, + $"{from.AccessLevel} {CommandLogging.Format(from)} {enabled} packet logging for {pm.Account.Username} ({pm.NetState})" + ); + + AddResponse($"Packet logging has been {enabled} for {pm.Account.Username} ({pm.NetState})"); + } + } + } +} From a4d9a3bdc2373277efdaa951347e72081195ea55 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 7 Nov 2021 13:20:11 -0800 Subject: [PATCH 003/213] Adds dictionary to codegen (#838) * Adds Dictionary serialization rule for codegen * Adds Tidy for Dictionary. By default will remove key/value pairs where the key or value is either null or deleted. Only works for ISerializable keys or values (or both). --- .../Rules/DictionaryMigrationRule.cs | 235 ++++++++++++++++++ .../SerializableMigrationRulesEngine.cs | 1 + .../SymbolMetadata/SymbolMetadata.Builtin.cs | 11 +- Projects/Server/Utilities/Utility.cs | 40 +++ 4 files changed, 285 insertions(+), 2 deletions(-) create mode 100644 Projects/SerializationGenerator/SerializableMigration/Rules/DictionaryMigrationRule.cs diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/DictionaryMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/DictionaryMigrationRule.cs new file mode 100644 index 000000000..632fa61fd --- /dev/null +++ b/Projects/SerializationGenerator/SerializableMigration/Rules/DictionaryMigrationRule.cs @@ -0,0 +1,235 @@ +/************************************************************************* + * ModernUO * + * Copyright 2019-2021 - ModernUO Development Team * + * Email: hi@modernuo.com * + * File: DictionaryMigrationRule.cs * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + +using System; +using System.Collections.Immutable; +using System.IO; +using System.Linq; +using System.Text; +using Microsoft.CodeAnalysis; +using SerializationGenerator; + +namespace SerializableMigration +{ + public class DictionaryMigrationRule : ISerializableMigrationRule + { + private const string KEY_VALUE_PAIR_DELIMITER = "----"; + public string RuleName => nameof(DictionaryMigrationRule); + + public bool GenerateRuleState( + Compilation compilation, + ISymbol symbol, + ImmutableArray attributes, + ImmutableArray serializableTypes, + ImmutableArray embeddedSerializableTypes, + ISymbol? parentSymbol, + out string[] ruleArguments + ) + { + if (symbol is not INamedTypeSymbol namedTypeSymbol || !symbol.IsDictionary(compilation)) + { + ruleArguments = null; + return false; + } + + var keySymbolType = namedTypeSymbol.TypeArguments[0]; + + var serializableKeyProperty = SerializableMigrationRulesEngine.GenerateSerializableProperty( + compilation, + "KeyEntry", + keySymbolType, + 0, + attributes, + serializableTypes, + embeddedSerializableTypes, + parentSymbol, + null + ); + + var valueSymbolType = namedTypeSymbol.TypeArguments[1]; + + var serializableValueProperty = SerializableMigrationRulesEngine.GenerateSerializableProperty( + compilation, + "ValueEntry", + valueSymbolType, + 0, + attributes, + serializableTypes, + embeddedSerializableTypes, + parentSymbol, + null + ); + + var extraOptions = ""; + if (attributes.Any(a => a.IsTidy(compilation))) + { + extraOptions += "@Tidy"; + } + + var keyPropertyLength = serializableKeyProperty.RuleArguments?.Length ?? 0; + var valuePropertyLength = serializableValueProperty.RuleArguments?.Length ?? 0; + ruleArguments = new string[keyPropertyLength + valuePropertyLength + 6]; + ruleArguments[0] = extraOptions; + ruleArguments[1] = keySymbolType.ToDisplayString(); + ruleArguments[2] = serializableKeyProperty.Rule; + + if (keyPropertyLength > 0) + { + Array.Copy(serializableKeyProperty.RuleArguments!, 0, ruleArguments, 3, keyPropertyLength); + } + + ruleArguments[3 + keyPropertyLength] = KEY_VALUE_PAIR_DELIMITER; + ruleArguments[4 + keyPropertyLength] = valueSymbolType.ToDisplayString(); + ruleArguments[5 + keyPropertyLength] = serializableValueProperty.Rule; + + if (valuePropertyLength > 0) + { + Array.Copy(serializableValueProperty.RuleArguments!, 0, ruleArguments, 6 + keyPropertyLength, valuePropertyLength); + } + + return true; + } + + public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference) + { + var expectedRule = RuleName; + var ruleName = property.Rule; + if (expectedRule != ruleName) + { + throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); + } + + var ruleArguments = property.RuleArguments; + + var keyElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments![2]]; + var valueRuleIndex = Array.IndexOf(ruleArguments, KEY_VALUE_PAIR_DELIMITER, 4); + if (valueRuleIndex == -1) + { + throw new InvalidDataException($"Cannot find key-value delimiter in arguments for {property.Name}"); + } + + var keyRuleArguments = new string[valueRuleIndex - 3]; + Array.Copy(ruleArguments, 3, keyRuleArguments, 0, keyRuleArguments.Length); + + var valueElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[valueRuleIndex + 2]]; + var valueRuleArguments = new string[ruleArguments.Length - valueRuleIndex - 2]; + Array.Copy(ruleArguments, 2 + valueRuleIndex, valueRuleArguments, 0, valueRuleArguments.Length); + + var propertyName = property.Name; + var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}"; + var propertyIndex = $"{propertyVarPrefix}Index"; + var propertyKeyEntry = $"{propertyVarPrefix}Key"; + var propertyValueEntry = $"{propertyVarPrefix}Value"; + var propertyCount = $"{propertyVarPrefix}Count"; + + source.AppendLine($"{indent}{ruleArguments[1]} {propertyKeyEntry};"); + source.AppendLine($"{indent}{ruleArguments[valueRuleIndex + 1]} {propertyValueEntry};"); + source.AppendLine($"{indent}var {propertyCount} = reader.ReadEncodedInt();"); + source.AppendLine($"{indent}{propertyName} = new System.Collections.Generic.Dictionary<{ruleArguments[1]}, {ruleArguments[valueRuleIndex + 1]}>({propertyCount});"); + source.AppendLine($"{indent}for (var {propertyIndex} = 0; {propertyIndex} < {propertyCount}; {propertyIndex}++)"); + source.AppendLine($"{indent}{{"); + + var serializableKeyElement = new SerializableProperty + { + Name = propertyKeyEntry, + Type = ruleArguments[1], + Rule = keyElementRule.RuleName, + RuleArguments = keyRuleArguments + }; + + keyElementRule.GenerateDeserializationMethod(source, $"{indent} ", serializableKeyElement, parentReference); + + var serializableValueElement = new SerializableProperty + { + Name = propertyValueEntry, + Type = ruleArguments[valueRuleIndex + 1], + Rule = valueElementRule.RuleName, + RuleArguments = valueRuleArguments + }; + + valueElementRule.GenerateDeserializationMethod(source, $"{indent} ", serializableValueElement, parentReference); + source.AppendLine($"{indent} {propertyName}.Add({propertyKeyEntry}, {propertyValueEntry});"); + + source.AppendLine($"{indent}}}"); + } + + public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property) + { + var expectedRule = RuleName; + var ruleName = property.Rule; + if (expectedRule != ruleName) + { + throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); + } + + var ruleArguments = property.RuleArguments; + var shouldTidy = ruleArguments![0].Contains("@Tidy"); + + var keyElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[2]]; + var valueRuleIndex = Array.IndexOf(ruleArguments, KEY_VALUE_PAIR_DELIMITER, 3); + if (valueRuleIndex == -1) + { + throw new InvalidDataException($"Cannot find key-value delimiter in arguments for {property.Name}"); + } + + var keyRuleArguments = new string[valueRuleIndex - 3]; + Array.Copy(ruleArguments, 3, keyRuleArguments, 0, keyRuleArguments.Length); + + var valueElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[valueRuleIndex + 2]]; + var valueRuleArguments = new string[ruleArguments.Length - valueRuleIndex - 2]; + Array.Copy(ruleArguments, 2 + valueRuleIndex, valueRuleArguments, 0, valueRuleArguments.Length); + + var propertyName = property.Name; + var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}"; + var propertyKeyEntry = $"{propertyVarPrefix}Key"; + var propertyValueEntry = $"{propertyVarPrefix}Value"; + var propertyCount = $"{propertyVarPrefix}Count"; + + if (shouldTidy) + { + source.AppendLine($"{indent}{property.Name}?.Tidy();"); + } + source.AppendLine($"{indent}var {propertyCount} = {property.Name}?.Count ?? 0;"); + source.AppendLine($"{indent}writer.WriteEncodedInt({propertyCount});"); + source.AppendLine($"{indent}if ({propertyCount} > 0)"); + source.AppendLine($"{indent}{{"); + source.AppendLine($"{indent} foreach (var ({propertyKeyEntry}, {propertyValueEntry}) in {property.Name}!)"); + source.AppendLine($"{indent} {{"); + + var serializableKeyElement = new SerializableProperty + { + Name = propertyKeyEntry, + Type = ruleArguments[1], + Rule = keyElementRule.RuleName, + RuleArguments = keyRuleArguments + }; + + keyElementRule.GenerateSerializationMethod(source, $"{indent} ", serializableKeyElement); + + var serializableValueElement = new SerializableProperty + { + Name = propertyValueEntry, + Type = ruleArguments[valueRuleIndex + 1], + Rule = valueElementRule.RuleName, + RuleArguments = valueRuleArguments + }; + + keyElementRule.GenerateSerializationMethod(source, $"{indent} ", serializableValueElement); + + source.AppendLine($"{indent} }}"); + source.AppendLine($"{indent}}}"); + } + } +} diff --git a/Projects/SerializationGenerator/SerializableMigration/SerializableMigrationRulesEngine.cs b/Projects/SerializationGenerator/SerializableMigration/SerializableMigrationRulesEngine.cs index 15abef66a..1fe3e32f5 100644 --- a/Projects/SerializationGenerator/SerializableMigration/SerializableMigrationRulesEngine.cs +++ b/Projects/SerializationGenerator/SerializableMigration/SerializableMigrationRulesEngine.cs @@ -33,6 +33,7 @@ namespace SerializableMigration new ListMigrationRule(), new ArrayMigrationRule(), new HashSetMigrationRule(), + new DictionaryMigrationRule(), new KeyValuePairMigrationRule(), new PrimitiveTypeMigrationRule(), new PrimitiveUOTypeMigrationRule(), diff --git a/Projects/SerializationGenerator/SourceGeneration/SymbolMetadata/SymbolMetadata.Builtin.cs b/Projects/SerializationGenerator/SourceGeneration/SymbolMetadata/SymbolMetadata.Builtin.cs index af2bc3241..28241d463 100644 --- a/Projects/SerializationGenerator/SourceGeneration/SymbolMetadata/SymbolMetadata.Builtin.cs +++ b/Projects/SerializationGenerator/SourceGeneration/SymbolMetadata/SymbolMetadata.Builtin.cs @@ -19,6 +19,7 @@ namespace SerializationGenerator { public static partial class SymbolMetadata { + public const string DICTIONARY_CLASS = "System.Collections.Generic.Dictionary`2"; public const string LIST_CLASS = "System.Collections.Generic.List`1"; public const string HASHSET_CLASS = "System.Collections.Generic.HashSet`1"; public const string IPADDRESS_CLASS = "System.Net.IPAddress"; @@ -43,9 +44,9 @@ namespace SerializationGenerator SymbolEqualityComparer.Default ) == true; - public static bool IsList(this ISymbol symbol, Compilation compilation) => + public static bool IsDictionary(this ISymbol symbol, Compilation compilation) => (symbol as INamedTypeSymbol)?.ConstructedFrom.Equals( - compilation.GetTypeByMetadataName(LIST_CLASS), + compilation.GetTypeByMetadataName(DICTIONARY_CLASS), SymbolEqualityComparer.Default ) == true; @@ -55,6 +56,12 @@ namespace SerializationGenerator SymbolEqualityComparer.Default ) == true; + public static bool IsList(this ISymbol symbol, Compilation compilation) => + (symbol as INamedTypeSymbol)?.ConstructedFrom.Equals( + compilation.GetTypeByMetadataName(LIST_CLASS), + SymbolEqualityComparer.Default + ) == true; + public static bool IsPrimitiveFromTypeDisplayString(string type) => type is "bool" or "sbyte" or "short" or "int" or "long" or "byte" or "ushort" or "uint" or "ulong" or "float" or "double" or "string" or "decimal"; diff --git a/Projects/Server/Utilities/Utility.cs b/Projects/Server/Utilities/Utility.cs index e7cd004fb..a184d4b23 100644 --- a/Projects/Server/Utilities/Utility.cs +++ b/Projects/Server/Utilities/Utility.cs @@ -10,6 +10,7 @@ using System.Text; using System.Xml; using Microsoft.Toolkit.HighPerformance; using Server.Buffers; +using Server.Collections; using Server.Random; using Server.Text; @@ -1188,6 +1189,45 @@ namespace Server set.RemoveWhere(entry => entry?.Deleted != false); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Tidy(this Dictionary dictionary) + { + var serializable = typeof(ISerializable); + var serializableKey = typeof(K).IsAssignableTo(serializable); + var serializableValue = typeof(V).IsAssignableTo(serializable); + + if (!serializableKey && !serializableValue) + { + return; + } + + using var queue = PooledRefQueue.Create(); + foreach (var (key, value) in dictionary) + { + if (serializableKey) + { + if (key == null || ((ISerializable)key).Deleted) + { + queue.Enqueue(key); + } + } + else + { + if (value == null || ((ISerializable)value).Deleted) + { + queue.Enqueue(key); + } + } + } + + while (queue.Count > 0) + { + dictionary.Remove(queue.Dequeue()); + } + + dictionary.TrimExcess(); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int NumberOfSetBits(this ulong i) { From c31bf20d0e96dcc93c4c0f8737eaeb9cae40aa90 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sat, 13 Nov 2021 13:38:01 -0800 Subject: [PATCH 004/213] feat: Updates to .NET 6 (#843) * Fixes an issue with moving directories across volumes * Removes usages of WebClient * Removes usages of Cryptographic Providers Note: Even though .NET 6 introduces Xoshiro RNG, there is no way to control the seed. I'll do some reconciliation of Xoshiro so it functions closer to the built in one. For the most part, it has parity though. Benchmarks show there is nothing odd about the implementations, they are within 1ns of each other. --- .github/workflows/build-test.yml | 4 +- Directory.Build.props | 4 +- Projects/Benchmarks/Benchmarks.csproj | 2 +- .../Collections/BenchmarkOrderedHashSet.cs | 2 +- .../FeatureFlags/BenchmarkFeatureFlags.cs | 90 ------------------- .../Benchmarks/FeatureFlags/FeatureFlag.cs | 9 -- .../Logging/BenchmarkConsoleLogging.cs | 2 +- .../Packets/BenchmarkOutgoingGumpPacket.cs | 2 +- .../Packets/BenchmarkPacketBroadcast.cs | 2 +- .../Benchmarks/Rng/BenchmarkXoshiro.cs | 46 ++++++++++ .../Benchmarks/Text/BenchmarkTextEncoding.cs | 2 +- .../Utilities/BenchmarkStringHelpers.cs | 2 +- Projects/Benchmarks/Program.cs | 4 +- .../SerializableMigrationSchema.cs | 3 +- .../Application.cs | 3 +- Projects/Server.Tests/Server.Tests.csproj | 2 +- Projects/Server/Json/JsonConfig.cs | 2 +- Projects/Server/Random/SecureRandom.cs | 4 +- Projects/Server/Utilities/PathUtility.cs | 19 ++++ Projects/Server/World/World.cs | 2 +- .../Security/PasswordProtectionTest.cs | 55 +++++++++--- .../UOContent.Tests/UOContent.Tests.csproj | 2 +- .../Accounting/Security/AccountSecurity.cs | 6 +- ....cs => HashAlgorithmPasswordProtection.cs} | 16 ++-- .../Security/MD5PasswordProtection.cs | 38 -------- .../Security/SHA1PasswordProtection.cs | 38 -------- Projects/UOContent/Compression/TarArchive.cs | 17 +++- Projects/UOContent/Compression/ZstdArchive.cs | 1 + Projects/UOContent/Misc/ProfessionInfo.cs | 2 +- Projects/UOContent/Misc/ServerList.cs | 10 ++- Projects/UOContent/Mobiles/Townfolk/Noble.cs | 1 - Projects/UOContent/UOContent.csproj | 2 +- Projects/UOContent/World Saves/AutoArchive.cs | 4 +- README.md | 11 ++- azure-pipelines.yml | 14 ++- 35 files changed, 192 insertions(+), 231 deletions(-) delete mode 100644 Projects/Benchmarks/Benchmarks/FeatureFlags/BenchmarkFeatureFlags.cs delete mode 100644 Projects/Benchmarks/Benchmarks/FeatureFlags/FeatureFlag.cs create mode 100644 Projects/Benchmarks/Benchmarks/Rng/BenchmarkXoshiro.cs rename Projects/UOContent/Accounting/Security/{SHA2PasswordProtection.cs => HashAlgorithmPasswordProtection.cs} (64%) delete mode 100644 Projects/UOContent/Accounting/Security/MD5PasswordProtection.cs delete mode 100644 Projects/UOContent/Accounting/Security/SHA1PasswordProtection.cs diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index cf746c82e..3a2b28871 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -23,10 +23,10 @@ jobs: - uses: actions/checkout@v2 with: fetch-depth: 0 # avoid shallow clone so nbgv can do its work. - - name: Setup .NET 5 + - name: Setup .NET 6 uses: actions/setup-dotnet@v1 with: - dotnet-version: 5.0.401 + dotnet-version: 6.0.100 - name: Build run: ./publish.cmd - name: Test diff --git a/Directory.Build.props b/Directory.Build.props index 0ac231599..7ebed0b53 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -4,7 +4,7 @@ Kamron Batman ModernUO 2019-2020 - net5.0 + net6.0 x64 x64 preview @@ -58,7 +58,7 @@ - 3.4.240 + 3.4.244 all diff --git a/Projects/Benchmarks/Benchmarks.csproj b/Projects/Benchmarks/Benchmarks.csproj index 2ed8e89fd..eff9ed660 100644 --- a/Projects/Benchmarks/Benchmarks.csproj +++ b/Projects/Benchmarks/Benchmarks.csproj @@ -1,7 +1,7 @@ Exe - net5.0 + net6.0 x64 x64 9 diff --git a/Projects/Benchmarks/Benchmarks/Collections/BenchmarkOrderedHashSet.cs b/Projects/Benchmarks/Benchmarks/Collections/BenchmarkOrderedHashSet.cs index 1414c571e..b9ec3d676 100644 --- a/Projects/Benchmarks/Benchmarks/Collections/BenchmarkOrderedHashSet.cs +++ b/Projects/Benchmarks/Benchmarks/Collections/BenchmarkOrderedHashSet.cs @@ -6,7 +6,7 @@ using Server.Collections; namespace Benchmarks { [MemoryDiagnoser] - [SimpleJob(RuntimeMoniker.NetCoreApp50)] + [SimpleJob(RuntimeMoniker.Net60)] public class BenchmarkOrderedHashSet { private readonly string[] _iterations = new string[16]; diff --git a/Projects/Benchmarks/Benchmarks/FeatureFlags/BenchmarkFeatureFlags.cs b/Projects/Benchmarks/Benchmarks/FeatureFlags/BenchmarkFeatureFlags.cs deleted file mode 100644 index fcfffebbe..000000000 --- a/Projects/Benchmarks/Benchmarks/FeatureFlags/BenchmarkFeatureFlags.cs +++ /dev/null @@ -1,90 +0,0 @@ -using System; -using System.Buffers.Binary; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Runtime.Loader; -using System.Security.Cryptography; -using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Jobs; -using Server; -using Server.Items; - -namespace Benchmarks -{ - [SimpleJob(RuntimeMoniker.NetCoreApp50)] - public class BenchmarkFeatureFlags - { - public Dictionary> m_Dictionary; - public ILookup> m_Lookup; - - public Type[] m_TypesToLookUp; - - [GlobalSetup] - public void Setup() - { - RNGCryptoServiceProvider csp = new RNGCryptoServiceProvider(); - - string file = Path.Join(AppDomain.CurrentDomain.BaseDirectory, "UOContent.dll"); - Assembly assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(file); - - m_Dictionary = new Dictionary>(); - List> m_Types = new List>(); - m_TypesToLookUp = new Type[100]; - - foreach (var type in assembly.GetTypes()) - { - if (typeof(Item).IsAssignableFrom(type)) - { - m_Dictionary.Add(type, new FeatureFlag()); - m_Types.Add(new FeatureFlag{Type = type}); - } - } - - Console.WriteLine("Dictionary Size: {0}", m_Dictionary.Count); - Console.WriteLine("Lookup Size: {0}", m_Types.Count); - - m_Dictionary.TrimExcess(); - m_Lookup = m_Types.ToLookup(f => f.Type); - Span bytes = stackalloc byte[4]; - - for (int i = 0; i < 100; i++) - { - csp.GetBytes(bytes); - m_TypesToLookUp[i] = m_Types[(int)(BinaryPrimitives.ReadUInt32BigEndian(bytes) % m_Types.Count)].Type; - } - } - - [Benchmark] - public FeatureFlag TestDictionary() - { - for (int i = 0; i < 100; i++) - { - m_Dictionary.TryGetValue(typeof(ExplosionPotion), out var ff); - if (i == 99) - { - return ff; - } - } - - return null; - } - - [Benchmark] - public FeatureFlag TestLookup() - { - FeatureFlag ff; - for (int i = 0; i < 100; i++) - { - ff = m_Lookup[typeof(ExplosionPotion)].GetEnumerator().Current; - if (i == 99) - { - return ff; - } - } - - return null; - } - } -} diff --git a/Projects/Benchmarks/Benchmarks/FeatureFlags/FeatureFlag.cs b/Projects/Benchmarks/Benchmarks/FeatureFlags/FeatureFlag.cs deleted file mode 100644 index f8b04716c..000000000 --- a/Projects/Benchmarks/Benchmarks/FeatureFlags/FeatureFlag.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System; - -namespace Server -{ - public class FeatureFlag where T : Item - { - public Type Type { get; set; } - } -} diff --git a/Projects/Benchmarks/Benchmarks/Logging/BenchmarkConsoleLogging.cs b/Projects/Benchmarks/Benchmarks/Logging/BenchmarkConsoleLogging.cs index 62bc428fa..f794d64b4 100644 --- a/Projects/Benchmarks/Benchmarks/Logging/BenchmarkConsoleLogging.cs +++ b/Projects/Benchmarks/Benchmarks/Logging/BenchmarkConsoleLogging.cs @@ -6,7 +6,7 @@ using Serilog.Core; namespace Benchmarks { - [SimpleJob(RuntimeMoniker.NetCoreApp50)] + [SimpleJob(RuntimeMoniker.Net60)] public class BenchmarkConsoleLogging { private const string text = "Sample message"; diff --git a/Projects/Benchmarks/Benchmarks/Packets/BenchmarkOutgoingGumpPacket.cs b/Projects/Benchmarks/Benchmarks/Packets/BenchmarkOutgoingGumpPacket.cs index 0225af652..114cac192 100644 --- a/Projects/Benchmarks/Benchmarks/Packets/BenchmarkOutgoingGumpPacket.cs +++ b/Projects/Benchmarks/Benchmarks/Packets/BenchmarkOutgoingGumpPacket.cs @@ -12,7 +12,7 @@ using Server.Tests.Network; namespace Benchmarks { [MemoryDiagnoser] - [SimpleJob(RuntimeMoniker.NetCoreApp50)] + [SimpleJob(RuntimeMoniker.Net60)] public class OutgoingGumpPacketBenchmarks { private static readonly byte[] _layoutBuffer = GC.AllocateUninitializedArray(0x20000); diff --git a/Projects/Benchmarks/Benchmarks/Packets/BenchmarkPacketBroadcast.cs b/Projects/Benchmarks/Benchmarks/Packets/BenchmarkPacketBroadcast.cs index 2535dca0f..4db59d432 100644 --- a/Projects/Benchmarks/Benchmarks/Packets/BenchmarkPacketBroadcast.cs +++ b/Projects/Benchmarks/Benchmarks/Packets/BenchmarkPacketBroadcast.cs @@ -7,7 +7,7 @@ using Server.Network; namespace Benchmarks { - [SimpleJob(RuntimeMoniker.NetCoreApp50)] + [SimpleJob(RuntimeMoniker.Net60)] public class BenchmarkPacketBroadcast { public static int SendUnicodeMessage( diff --git a/Projects/Benchmarks/Benchmarks/Rng/BenchmarkXoshiro.cs b/Projects/Benchmarks/Benchmarks/Rng/BenchmarkXoshiro.cs new file mode 100644 index 000000000..caced76b3 --- /dev/null +++ b/Projects/Benchmarks/Benchmarks/Rng/BenchmarkXoshiro.cs @@ -0,0 +1,46 @@ +using System; +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Jobs; +using Server.Random; + +namespace Benchmarks.Benchmarks.Rng +{ + [MemoryDiagnoser] + [SimpleJob(RuntimeMoniker.Net60)] + public class BenchmarkXoshiro + { + private Random _random; + private Xoshiro256PlusPlus _xoshiro256PlusPlus; + + [GlobalSetup] + public void Setup() + { + _xoshiro256PlusPlus = new Xoshiro256PlusPlus(); + _random = new Random(); + } + + [Benchmark] + public int SystemRandomULong() => _random.Next(10000); + + [Benchmark] + public int XoshiroRandomULong() => _xoshiro256PlusPlus.Next(10000); + + [Benchmark] + public double SystemRandomDouble() => _random.NextDouble(); + + [Benchmark] + public double XoshiroRandomDouble() => _xoshiro256PlusPlus.NextDouble(); + + [Benchmark] + public int SystemRandomMinMax() => _random.Next(5000, 85000); + + [Benchmark] + public int XoshiroRandomMinMax() + { + const int min = 5000; + const int max = 85000; + + return min + (int)_xoshiro256PlusPlus.Next((uint)(max - min + 1)); + } + } +} diff --git a/Projects/Benchmarks/Benchmarks/Text/BenchmarkTextEncoding.cs b/Projects/Benchmarks/Benchmarks/Text/BenchmarkTextEncoding.cs index 5594bf937..b2f716861 100644 --- a/Projects/Benchmarks/Benchmarks/Text/BenchmarkTextEncoding.cs +++ b/Projects/Benchmarks/Benchmarks/Text/BenchmarkTextEncoding.cs @@ -5,7 +5,7 @@ using Server.Text; namespace Benchmarks.BenchmarkText { [MemoryDiagnoser] - [SimpleJob(RuntimeMoniker.NetCoreApp50)] + [SimpleJob(RuntimeMoniker.Net60)] public class BenchmarkTextEncoding { private const string text = diff --git a/Projects/Benchmarks/Benchmarks/Utilities/BenchmarkStringHelpers.cs b/Projects/Benchmarks/Benchmarks/Utilities/BenchmarkStringHelpers.cs index 01cf5bb3c..55e4fd289 100644 --- a/Projects/Benchmarks/Benchmarks/Utilities/BenchmarkStringHelpers.cs +++ b/Projects/Benchmarks/Benchmarks/Utilities/BenchmarkStringHelpers.cs @@ -7,7 +7,7 @@ using Server.Buffers; namespace Benchmarks.BenchmarkUtilities { [MemoryDiagnoser] - [SimpleJob(RuntimeMoniker.NetCoreApp50)] + [SimpleJob(RuntimeMoniker.Net60)] public class BenchmarkStringHelpers { private readonly string[] names = diff --git a/Projects/Benchmarks/Program.cs b/Projects/Benchmarks/Program.cs index f28cc3e6f..845354d56 100644 --- a/Projects/Benchmarks/Program.cs +++ b/Projects/Benchmarks/Program.cs @@ -1,4 +1,5 @@ using BenchmarkDotNet.Running; +using Benchmarks.Benchmarks.Rng; namespace Benchmarks { @@ -10,10 +11,11 @@ namespace Benchmarks // var packetConstruction = BenchmarkRunner.Run(); // var broadcast = BenchmarkRunner.Run(); // var stringHelpers = BenchmarkRunner.Run(); - var indexList = BenchmarkRunner.Run(); + // var indexList = BenchmarkRunner.Run(); // var textEncoding = BenchmarkRunner.Run(); // var logging = BenchmarkRunner.Run(); // var gumpPacket = BenchmarkRunner.Run(); + var rngTest = BenchmarkRunner.Run(); } } } diff --git a/Projects/SerializationGenerator/SerializableMigration/SerializableMigrationSchema.cs b/Projects/SerializationGenerator/SerializableMigration/SerializableMigrationSchema.cs index 52b94d505..2f8613456 100644 --- a/Projects/SerializationGenerator/SerializableMigration/SerializableMigrationSchema.cs +++ b/Projects/SerializationGenerator/SerializableMigration/SerializableMigrationSchema.cs @@ -18,6 +18,7 @@ using System.IO; using System.Linq; using System.Text; using System.Text.Json; +using System.Text.Json.Serialization; using System.Text.RegularExpressions; using Microsoft.CodeAnalysis; @@ -30,7 +31,7 @@ namespace SerializableMigration { WriteIndented = true, AllowTrailingCommas = true, - IgnoreNullValues = true, + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, ReadCommentHandling = JsonCommentHandling.Skip }; diff --git a/Projects/SerializationSchemaGenerator/Application.cs b/Projects/SerializationSchemaGenerator/Application.cs index e8634aab7..eb6946787 100644 --- a/Projects/SerializationSchemaGenerator/Application.cs +++ b/Projects/SerializationSchemaGenerator/Application.cs @@ -17,6 +17,7 @@ using System; using System.Collections.Immutable; using System.IO; using System.Text.Json; +using System.Text.Json.Serialization; using System.Threading.Tasks; using SerializationGenerator; @@ -61,7 +62,7 @@ namespace SerializationSchemaGenerator { WriteIndented = true, AllowTrailingCommas = true, - IgnoreNullValues = true, + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, ReadCommentHandling = JsonCommentHandling.Skip }; diff --git a/Projects/Server.Tests/Server.Tests.csproj b/Projects/Server.Tests/Server.Tests.csproj index b6339a9a0..46a5a0981 100644 --- a/Projects/Server.Tests/Server.Tests.csproj +++ b/Projects/Server.Tests/Server.Tests.csproj @@ -3,7 +3,7 @@ false - + diff --git a/Projects/Server/Json/JsonConfig.cs b/Projects/Server/Json/JsonConfig.cs index 163776d84..7bddd24c8 100644 --- a/Projects/Server/Json/JsonConfig.cs +++ b/Projects/Server/Json/JsonConfig.cs @@ -34,7 +34,7 @@ namespace Server.Json { WriteIndented = true, AllowTrailingCommas = true, - IgnoreNullValues = true, + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, ReadCommentHandling = JsonCommentHandling.Skip, Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping }; diff --git a/Projects/Server/Random/SecureRandom.cs b/Projects/Server/Random/SecureRandom.cs index 284502d1b..30006b871 100644 --- a/Projects/Server/Random/SecureRandom.cs +++ b/Projects/Server/Random/SecureRandom.cs @@ -25,13 +25,13 @@ namespace Server { private RandomNumberGenerator m_Random; - public RandomNumberGenerator Generator => m_Random ??= new RNGCryptoServiceProvider(); + public RandomNumberGenerator Generator => m_Random ??= RandomNumberGenerator.Create(); [MethodImpl(MethodImplOptions.AggressiveInlining)] public override ulong NextULong() { Span buffer = stackalloc byte[sizeof(ulong)]; - Generator.GetBytes(buffer); + NextBytes(buffer); return BinaryPrimitives.ReadUInt64BigEndian(buffer); } diff --git a/Projects/Server/Utilities/PathUtility.cs b/Projects/Server/Utilities/PathUtility.cs index d2206143d..6f22c46db 100644 --- a/Projects/Server/Utilities/PathUtility.cs +++ b/Projects/Server/Utilities/PathUtility.cs @@ -63,5 +63,24 @@ namespace Server Utility.RandomBytes(bytes); return EnsureDirectory(Path.Combine(basePath, bytes.ToHexString())); } + + public static void CopyDirectory(string sourcePath, string destinationPath, bool recursive = true) + { + var searchOptions = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly; + foreach (var file in Directory.EnumerateFiles(sourcePath, "*", searchOptions)) + { + var fi = new FileInfo(file); + var relativePath = Path.GetRelativePath(sourcePath, fi.DirectoryName!); + var destFolder = Path.Combine(destinationPath, relativePath); + EnsureDirectory(destFolder); + fi.CopyTo(Path.Combine(destFolder, fi.Name)); + } + } + + public static void MoveDirectory(string sourcePath, string destinationPath) + { + CopyDirectory(sourcePath, destinationPath); + Directory.Delete(sourcePath, true); + } } } diff --git a/Projects/Server/World/World.cs b/Projects/Server/World/World.cs index 02b3013d5..72d21ac2b 100644 --- a/Projects/Server/World/World.cs +++ b/Projects/Server/World/World.cs @@ -421,7 +421,7 @@ namespace Server try { EventSink.InvokeWorldSavePostSnapshot(SavePath, tempPath); - Directory.Move(tempPath, SavePath); + PathUtility.MoveDirectory(tempPath, SavePath); } catch (Exception ex) { diff --git a/Projects/UOContent.Tests/Tests/Accounting/Security/PasswordProtectionTest.cs b/Projects/UOContent.Tests/Tests/Accounting/Security/PasswordProtectionTest.cs index e69e8db6c..380ab8954 100644 --- a/Projects/UOContent.Tests/Tests/Accounting/Security/PasswordProtectionTest.cs +++ b/Projects/UOContent.Tests/Tests/Accounting/Security/PasswordProtectionTest.cs @@ -1,4 +1,5 @@ using System; +using System.Security.Cryptography; using Server.Accounting; using Server.Accounting.Security; using Xunit; @@ -9,12 +10,29 @@ namespace Server.Tests.Accounting.Security { private const string plainPassword = "hello-good-sir"; - [Theory, InlineData(typeof(Argon2PasswordProtection)), InlineData(typeof(PBKDF2PasswordProtection)), - InlineData(typeof(SHA2PasswordProtection)), InlineData(typeof(SHA1PasswordProtection)), - InlineData(typeof(MD5PasswordProtection))] - public void TestValidates(Type protectionType) + [Theory] + [InlineData(typeof(Argon2PasswordProtection), null)] + [InlineData(typeof(PBKDF2PasswordProtection), null)] + [InlineData(typeof(HashAlgorithmPasswordProtection), "MD5")] + [InlineData(typeof(HashAlgorithmPasswordProtection), "SHA1")] + [InlineData(typeof(HashAlgorithmPasswordProtection), "SHA2")] + public void TestValidates(Type protectionType, string algorithmType) { - var passwordProtection = Activator.CreateInstance(protectionType) as IPasswordProtection; + IPasswordProtection passwordProtection; + if (protectionType == typeof(HashAlgorithmPasswordProtection)) + { + passwordProtection = algorithmType switch + { + "SHA1" => HashAlgorithmPasswordProtection.SHA1Instance, + "SHA2" => HashAlgorithmPasswordProtection.SHA2Instance, + _ => HashAlgorithmPasswordProtection.MD5Instance, + }; + } + else + { + passwordProtection = Activator.CreateInstance(protectionType) as IPasswordProtection; + } + if (passwordProtection == null) { Assert.False(true, $"{protectionType.Name} is not an IPasswordProtection."); @@ -25,12 +43,29 @@ namespace Server.Tests.Accounting.Security Assert.True(passwordProtection.ValidatePassword(encryptedPassword, plainPassword)); } - [Theory, InlineData(typeof(Argon2PasswordProtection)), InlineData(typeof(PBKDF2PasswordProtection)), - InlineData(typeof(SHA2PasswordProtection)), InlineData(typeof(SHA1PasswordProtection)), - InlineData(typeof(MD5PasswordProtection))] - public void TestPasswordDoesNotValidate(Type protectionType) + [Theory] + [InlineData(typeof(Argon2PasswordProtection), null)] + [InlineData(typeof(PBKDF2PasswordProtection), null)] + [InlineData(typeof(HashAlgorithmPasswordProtection), "MD5")] + [InlineData(typeof(HashAlgorithmPasswordProtection), "SHA1")] + [InlineData(typeof(HashAlgorithmPasswordProtection), "SHA2")] + public void TestPasswordDoesNotValidate(Type protectionType, string algorithmType) { - var passwordProtection = Activator.CreateInstance(protectionType) as IPasswordProtection; + IPasswordProtection passwordProtection; + if (protectionType == typeof(HashAlgorithmPasswordProtection)) + { + passwordProtection = algorithmType switch + { + "SHA1" => HashAlgorithmPasswordProtection.SHA1Instance, + "SHA2" => HashAlgorithmPasswordProtection.SHA2Instance, + _ => HashAlgorithmPasswordProtection.MD5Instance, + }; + } + else + { + passwordProtection = Activator.CreateInstance(protectionType) as IPasswordProtection; + } + if (passwordProtection == null) { Assert.False(true, $"{protectionType.Name} is not an IPasswordProtection."); diff --git a/Projects/UOContent.Tests/UOContent.Tests.csproj b/Projects/UOContent.Tests/UOContent.Tests.csproj index baa2a972e..fc960bae1 100644 --- a/Projects/UOContent.Tests/UOContent.Tests.csproj +++ b/Projects/UOContent.Tests/UOContent.Tests.csproj @@ -3,7 +3,7 @@ false - + diff --git a/Projects/UOContent/Accounting/Security/AccountSecurity.cs b/Projects/UOContent/Accounting/Security/AccountSecurity.cs index 0725b3af8..b6d697f6a 100644 --- a/Projects/UOContent/Accounting/Security/AccountSecurity.cs +++ b/Projects/UOContent/Accounting/Security/AccountSecurity.cs @@ -55,9 +55,9 @@ namespace Server.Accounting.Security { var passwordProtection = algorithm switch { - PasswordProtectionAlgorithm.MD5 => MD5PasswordProtection.Instance, - PasswordProtectionAlgorithm.SHA1 => SHA1PasswordProtection.Instance, - PasswordProtectionAlgorithm.SHA2 => SHA2PasswordProtection.Instance, + PasswordProtectionAlgorithm.MD5 => HashAlgorithmPasswordProtection.MD5Instance, + PasswordProtectionAlgorithm.SHA1 => HashAlgorithmPasswordProtection.SHA1Instance, + PasswordProtectionAlgorithm.SHA2 => HashAlgorithmPasswordProtection.SHA2Instance, PasswordProtectionAlgorithm.PBKDF2 => PBKDF2PasswordProtection.Instance, PasswordProtectionAlgorithm.Argon2 => Argon2PasswordProtection.Instance, PasswordProtectionAlgorithm.None => throw new Exception("Do not use PasswordProtectionAlgorithm.None"), diff --git a/Projects/UOContent/Accounting/Security/SHA2PasswordProtection.cs b/Projects/UOContent/Accounting/Security/HashAlgorithmPasswordProtection.cs similarity index 64% rename from Projects/UOContent/Accounting/Security/SHA2PasswordProtection.cs rename to Projects/UOContent/Accounting/Security/HashAlgorithmPasswordProtection.cs index 02d333aa2..5a689b3ce 100644 --- a/Projects/UOContent/Accounting/Security/SHA2PasswordProtection.cs +++ b/Projects/UOContent/Accounting/Security/HashAlgorithmPasswordProtection.cs @@ -1,8 +1,8 @@ /************************************************************************* * ModernUO * - * Copyright 2019-2020 - ModernUO Development Team * + * Copyright 2019-2021 - ModernUO Development Team * * Email: hi@modernuo.com * - * File: SHA2PasswordProtection.cs * + * File: HashAlgorithmPasswordProtection.cs * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -19,15 +19,19 @@ using Server.Text; namespace Server.Accounting.Security { - public class SHA2PasswordProtection : IPasswordProtection + public class HashAlgorithmPasswordProtection : IPasswordProtection { - public static IPasswordProtection Instance = new SHA2PasswordProtection(); - private readonly SHA512CryptoServiceProvider m_SHA2HashProvider = new(); + public static IPasswordProtection MD5Instance = new HashAlgorithmPasswordProtection(MD5.Create()); + public static IPasswordProtection SHA1Instance = new HashAlgorithmPasswordProtection(SHA1.Create()); + public static IPasswordProtection SHA2Instance = new HashAlgorithmPasswordProtection(SHA512.Create()); + private readonly HashAlgorithm _hashAlgorithm; + + public HashAlgorithmPasswordProtection(HashAlgorithm hashAlgorithm) => _hashAlgorithm = hashAlgorithm; public string EncryptPassword(string plainPassword) { byte[] bytes = plainPassword.AsSpan(0, Math.Min(256, plainPassword.Length)).GetBytesAscii(); - return m_SHA2HashProvider.ComputeHash(bytes).ToHexString(); + return _hashAlgorithm.ComputeHash(bytes).ToHexString(); } public bool ValidatePassword(string encryptedPassword, string plainPassword) => diff --git a/Projects/UOContent/Accounting/Security/MD5PasswordProtection.cs b/Projects/UOContent/Accounting/Security/MD5PasswordProtection.cs deleted file mode 100644 index ba69522d3..000000000 --- a/Projects/UOContent/Accounting/Security/MD5PasswordProtection.cs +++ /dev/null @@ -1,38 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2020 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: MD5PasswordProtection.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System; -using System.Security.Cryptography; -using Server.Text; - -namespace Server.Accounting.Security -{ - public class MD5PasswordProtection : IPasswordProtection - { - public static IPasswordProtection Instance = new MD5PasswordProtection(); -#pragma warning disable CA5351 - private readonly MD5CryptoServiceProvider m_MD5HashProvider = new(); -#pragma warning restore CA5351 - - public string EncryptPassword(string plainPassword) - { - byte[] bytes = plainPassword.AsSpan(0, Math.Min(256, plainPassword.Length)).GetBytesAscii(); - return m_MD5HashProvider.ComputeHash(bytes).ToHexString(); - } - - public bool ValidatePassword(string encryptedPassword, string plainPassword) => - EncryptPassword(plainPassword) == encryptedPassword; - } -} diff --git a/Projects/UOContent/Accounting/Security/SHA1PasswordProtection.cs b/Projects/UOContent/Accounting/Security/SHA1PasswordProtection.cs deleted file mode 100644 index fb2fa0ea5..000000000 --- a/Projects/UOContent/Accounting/Security/SHA1PasswordProtection.cs +++ /dev/null @@ -1,38 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2020 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SHA1PasswordProtection.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System; -using System.Security.Cryptography; -using Server.Text; - -namespace Server.Accounting.Security -{ - public class SHA1PasswordProtection : IPasswordProtection - { - public static IPasswordProtection Instance = new SHA1PasswordProtection(); -#pragma warning disable CA5350 - private readonly SHA1CryptoServiceProvider m_SHA1HashProvider = new(); -#pragma warning restore CA5350 - - public string EncryptPassword(string plainPassword) - { - byte[] bytes = plainPassword.AsSpan(0, Math.Min(256, plainPassword.Length)).GetBytesAscii(); - return m_SHA1HashProvider.ComputeHash(bytes).ToHexString(); - } - - public bool ValidatePassword(string encryptedPassword, string plainPassword) => - EncryptPassword(plainPassword) == encryptedPassword; - } -} diff --git a/Projects/UOContent/Compression/TarArchive.cs b/Projects/UOContent/Compression/TarArchive.cs index 0e5889e4a..69083e509 100755 --- a/Projects/UOContent/Compression/TarArchive.cs +++ b/Projects/UOContent/Compression/TarArchive.cs @@ -5,6 +5,10 @@ using System.Diagnostics; using System.IO; using System.IO.Compression; using System.Net; +using System.Net.Http; +using System.Text.Json; +using System.Threading; +using System.Threading.Tasks; using Server.Buffers; namespace Server.Compression @@ -53,13 +57,18 @@ namespace Server.Compression var tempDir = PathUtility.EnsureRandomPath(Path.GetTempPath()); var libarchiveFile = Path.Combine(tempDir, "libarchive.zip"); - using WebClient wc = new WebClient(); - wc.DownloadFile (new Uri(_libArchiveWindowsUrl), libarchiveFile); + // This isn't called often so we don't need to optimize + using (HttpClient hc = new HttpClient()) + { + var result = hc.Send(new HttpRequestMessage(HttpMethod.Get, new Uri(_libArchiveWindowsUrl))); + using var stream = result.Content.ReadAsStream(); + using FileStream fs = new FileStream(libarchiveFile, FileMode.Create, FileAccess.Write, FileShare.None); + stream.CopyTo(fs); + } ZipFile.ExtractToDirectory(libarchiveFile, tempDir); var libArchivePath = Path.Combine(tempDir, "libarchive"); - Directory.Move(Path.Combine(libArchivePath, "bin"), "bsdtar"); - Directory.Delete(libArchivePath, true); + PathUtility.MoveDirectory(Path.Combine(libArchivePath, "bin"), Path.Combine(Core.BaseDirectory, "bsdtar")); File.Delete(libarchiveFile); return Path.Combine(Core.BaseDirectory, "bsdtar/bsdtar.exe"); diff --git a/Projects/UOContent/Compression/ZstdArchive.cs b/Projects/UOContent/Compression/ZstdArchive.cs index 35fd533d5..a1f1fee2c 100755 --- a/Projects/UOContent/Compression/ZstdArchive.cs +++ b/Projects/UOContent/Compression/ZstdArchive.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; diff --git a/Projects/UOContent/Misc/ProfessionInfo.cs b/Projects/UOContent/Misc/ProfessionInfo.cs index 9eda06bd9..6a2902d20 100644 --- a/Projects/UOContent/Misc/ProfessionInfo.cs +++ b/Projects/UOContent/Misc/ProfessionInfo.cs @@ -43,7 +43,7 @@ namespace Server } }; - var file = Core.FindDataFile("prof.txt"); + var file = Core.FindDataFile("prof.txt", false); if (!File.Exists(file)) { var parent = Path.Combine(Core.BaseDirectory, "Data/Professions"); diff --git a/Projects/UOContent/Misc/ServerList.cs b/Projects/UOContent/Misc/ServerList.cs index 031f44bc8..7d3a95194 100644 --- a/Projects/UOContent/Misc/ServerList.cs +++ b/Projects/UOContent/Misc/ServerList.cs @@ -1,5 +1,7 @@ using System; +using System.IO; using System.Net; +using System.Net.Http; using System.Net.NetworkInformation; using System.Net.Sockets; using Server.Logging; @@ -165,12 +167,16 @@ namespace Server.Misc Utility.IPMatch("169.254.*", ip) || Utility.IPMatch("100.64-127.*", ip)); + private const string _ipifyUrl = "https://api.ipify.org"; + private static IPAddress FindPublicAddress() { try { - using WebClient wc = new WebClient(); - return IPAddress.Parse(wc.DownloadString("https://api.ipify.org")); + // This isn't called often so we don't need to optimize + using HttpClient hc = new HttpClient(); + var ipAddress = hc.GetStringAsync(_ipifyUrl).Result; + return IPAddress.Parse(ipAddress); } catch { diff --git a/Projects/UOContent/Mobiles/Townfolk/Noble.cs b/Projects/UOContent/Mobiles/Townfolk/Noble.cs index 85af8457d..46cbe227b 100644 --- a/Projects/UOContent/Mobiles/Townfolk/Noble.cs +++ b/Projects/UOContent/Mobiles/Townfolk/Noble.cs @@ -25,7 +25,6 @@ namespace Server.Mobiles { return Utility.Random(6) switch { - 0 => 0, 1 => Utility.RandomBlueHue(), 2 => Utility.RandomGreenHue(), 3 => Utility.RandomRedHue(), diff --git a/Projects/UOContent/UOContent.csproj b/Projects/UOContent/UOContent.csproj index aab3a5561..5f322c829 100755 --- a/Projects/UOContent/UOContent.csproj +++ b/Projects/UOContent/UOContent.csproj @@ -39,7 +39,7 @@ false - + diff --git a/Projects/UOContent/World Saves/AutoArchive.cs b/Projects/UOContent/World Saves/AutoArchive.cs index 7d46d6168..b7cf2d50b 100755 --- a/Projects/UOContent/World Saves/AutoArchive.cs +++ b/Projects/UOContent/World Saves/AutoArchive.cs @@ -97,7 +97,7 @@ namespace Server.Saves Directory.CreateDirectory(AutomaticBackupPath); var backupPath = Path.Combine(AutomaticBackupPath, Utility.GetTimeStamp()); - Directory.Move(args.OldSavePath, backupPath); + PathUtility.MoveDirectory(args.OldSavePath, backupPath); logger.Information($"Created backup at {backupPath}"); @@ -150,7 +150,7 @@ namespace Server.Saves Directory.Delete(savePath, true); var dirInfo = new DirectoryInfo(folder); logger.Information($"Restoring backup {dirInfo.Name}"); - Directory.Move(folder, savePath); + PathUtility.MoveDirectory(folder, savePath); break; } diff --git a/README.md b/README.md index 9cd03b05e..b37e7ef2e 100644 --- a/README.md +++ b/README.md @@ -24,16 +24,19 @@ ModernUO [![Discord](https://img.shields.io/discord/751317910504603701?logo=disc [![RedHat 7/8](https://img.shields.io/badge/-8-BE0000?logo=red%20hat&logoColor=white)](https://access.redhat.com/downloads) #### Running the server -[![.NET](https://img.shields.io/badge/.NET-%205.0-5C2D91)](https://dotnet.microsoft.com/download/dotnet/5.0) +[![.NET](https://img.shields.io/badge/.NET-%206.0-5C2D91)](https://dotnet.microsoft.com/download/dotnet/6.0) #### Development [![git](https://img.shields.io/badge/-git-F05032?logo=git&logoColor=white)](https://git-scm.com/downloads) -[![.NET](https://img.shields.io/badge/.NET-%205.0.10%20SDK-5C2D91)](https://dotnet.microsoft.com/download/dotnet/5.0) +[![.NET](https://img.shields.io/badge/.NET-%206.0%20SDK-5C2D91)](https://dotnet.microsoft.com/download/dotnet/6.0) #### Supported IDEs -[Jetbrains Rider 2021.2](https://www.jetbrains.com/rider/download) -[Visual Studio 2019](https://visualstudio.microsoft.com/downloads) +  +[Jetbrains Rider 2021.3](https://www.jetbrains.com/rider/download) +                     +[Visual Studio 2022](https://visualstudio.microsoft.com/downloads)
+Rider 2021.3+             Visual Studio 2022+ ###### Note: VS Code is not currently supported. ## Getting Started diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 4f721fc49..db3ef8f9a 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -18,7 +18,12 @@ jobs: displayName: 'Install .NET 5' inputs: packageType: sdk - version: 5.0.401 + version: 5.0.403 + - task: UseDotNet@2 + displayName: 'Install .NET 6' + inputs: + packageType: sdk + version: 6.0.100 - task: NuGetAuthenticate@0 - script: ./publish.cmd Release win displayName: 'Build' @@ -62,7 +67,12 @@ jobs: displayName: 'Install .NET 5' inputs: packageType: sdk - version: 5.0.401 + version: 5.0.403 + - task: UseDotNet@2 + displayName: 'Install .NET 6' + inputs: + packageType: sdk + version: 6.0.100 - task: NuGetAuthenticate@0 - script: ./publish.cmd Release $(os) displayName: 'Build' From 78f587f49604484aef7b60ea0006f73d07267715 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sat, 13 Nov 2021 16:18:16 -0800 Subject: [PATCH 005/213] fix: Fixes dictionary codegen (#844) * Fixes code gen with .net 6 by not using .net 6 * Fixes dictionary codegen * Fixes kvp codegen --- .github/workflows/build-test.yml | 2 +- Directory.Build.props | 2 +- .../Rules/DictionaryMigrationRule.cs | 96 +++++++++++-------- .../Rules/KeyValuePairMigrationRule.cs | 74 +++++++++----- .../SerializationGenerator.csproj | 2 +- azure-pipelines.yml | 4 +- publish.cmd | 8 +- 7 files changed, 112 insertions(+), 76 deletions(-) diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 3a2b28871..8e8872f94 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -30,4 +30,4 @@ jobs: - name: Build run: ./publish.cmd - name: Test - run: dotnet test --no-restore + run: dotnet test --no-restore --framework net6.0 diff --git a/Directory.Build.props b/Directory.Build.props index 7ebed0b53..27ca9d899 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -4,7 +4,7 @@ Kamron Batman ModernUO 2019-2020 - net6.0 + net5.0;net6.0 x64 x64 preview diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/DictionaryMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/DictionaryMigrationRule.cs index 632fa61fd..309e4c461 100644 --- a/Projects/SerializationGenerator/SerializableMigration/Rules/DictionaryMigrationRule.cs +++ b/Projects/SerializationGenerator/SerializableMigration/Rules/DictionaryMigrationRule.cs @@ -15,7 +15,6 @@ using System; using System.Collections.Immutable; -using System.IO; using System.Linq; using System.Text; using Microsoft.CodeAnalysis; @@ -25,7 +24,6 @@ namespace SerializableMigration { public class DictionaryMigrationRule : ISerializableMigrationRule { - private const string KEY_VALUE_PAIR_DELIMITER = "----"; public string RuleName => nameof(DictionaryMigrationRule); public bool GenerateRuleState( @@ -78,25 +76,29 @@ namespace SerializableMigration extraOptions += "@Tidy"; } - var keyPropertyLength = serializableKeyProperty.RuleArguments?.Length ?? 0; - var valuePropertyLength = serializableValueProperty.RuleArguments?.Length ?? 0; - ruleArguments = new string[keyPropertyLength + valuePropertyLength + 6]; - ruleArguments[0] = extraOptions; - ruleArguments[1] = keySymbolType.ToDisplayString(); - ruleArguments[2] = serializableKeyProperty.Rule; + var keyArgumentsLength = serializableKeyProperty.RuleArguments?.Length ?? 0; + var valueArgumentsLength = serializableValueProperty.RuleArguments?.Length ?? 0; + var index = 0; - if (keyPropertyLength > 0) + ruleArguments = new string[7 + keyArgumentsLength + valueArgumentsLength]; + ruleArguments[index++] = extraOptions; + ruleArguments[index++] = keySymbolType.ToDisplayString(); + ruleArguments[index++] = serializableKeyProperty.Rule; + ruleArguments[index++] = keyArgumentsLength.ToString(); + + if (keyArgumentsLength > 0) { - Array.Copy(serializableKeyProperty.RuleArguments!, 0, ruleArguments, 3, keyPropertyLength); + Array.Copy(serializableKeyProperty.RuleArguments!, 0, ruleArguments, index, keyArgumentsLength); + index += keyArgumentsLength; } - ruleArguments[3 + keyPropertyLength] = KEY_VALUE_PAIR_DELIMITER; - ruleArguments[4 + keyPropertyLength] = valueSymbolType.ToDisplayString(); - ruleArguments[5 + keyPropertyLength] = serializableValueProperty.Rule; + ruleArguments[index++] = valueSymbolType.ToDisplayString(); + ruleArguments[index++] = serializableValueProperty.Rule; + ruleArguments[index++] = valueArgumentsLength.ToString(); - if (valuePropertyLength > 0) + if (valueArgumentsLength > 0) { - Array.Copy(serializableValueProperty.RuleArguments!, 0, ruleArguments, 6 + keyPropertyLength, valuePropertyLength); + Array.Copy(serializableValueProperty.RuleArguments!, 0, ruleArguments, index, valueArgumentsLength); } return true; @@ -112,20 +114,26 @@ namespace SerializableMigration } var ruleArguments = property.RuleArguments; + var index = 1; + var keyType = ruleArguments![index++]; - var keyElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments![2]]; - var valueRuleIndex = Array.IndexOf(ruleArguments, KEY_VALUE_PAIR_DELIMITER, 4); - if (valueRuleIndex == -1) + var keyElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]]; + var keyRuleArguments = new string[int.Parse(ruleArguments[index++])]; + + if (keyRuleArguments.Length > 0) { - throw new InvalidDataException($"Cannot find key-value delimiter in arguments for {property.Name}"); + Array.Copy(ruleArguments, index, keyRuleArguments, 0, keyRuleArguments.Length); + index += keyRuleArguments.Length; } - var keyRuleArguments = new string[valueRuleIndex - 3]; - Array.Copy(ruleArguments, 3, keyRuleArguments, 0, keyRuleArguments.Length); + var valueType = ruleArguments[index++]; + var valueElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]]; + var valueRuleArguments = new string[int.Parse(ruleArguments[index++])]; - var valueElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[valueRuleIndex + 2]]; - var valueRuleArguments = new string[ruleArguments.Length - valueRuleIndex - 2]; - Array.Copy(ruleArguments, 2 + valueRuleIndex, valueRuleArguments, 0, valueRuleArguments.Length); + if (valueRuleArguments.Length > 0) + { + Array.Copy(ruleArguments, index, valueRuleArguments, 0, valueRuleArguments.Length); + } var propertyName = property.Name; var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}"; @@ -135,16 +143,16 @@ namespace SerializableMigration var propertyCount = $"{propertyVarPrefix}Count"; source.AppendLine($"{indent}{ruleArguments[1]} {propertyKeyEntry};"); - source.AppendLine($"{indent}{ruleArguments[valueRuleIndex + 1]} {propertyValueEntry};"); + source.AppendLine($"{indent}{valueType} {propertyValueEntry};"); source.AppendLine($"{indent}var {propertyCount} = reader.ReadEncodedInt();"); - source.AppendLine($"{indent}{propertyName} = new System.Collections.Generic.Dictionary<{ruleArguments[1]}, {ruleArguments[valueRuleIndex + 1]}>({propertyCount});"); + source.AppendLine($"{indent}{propertyName} = new System.Collections.Generic.Dictionary<{keyType}, {valueType}>({propertyCount});"); source.AppendLine($"{indent}for (var {propertyIndex} = 0; {propertyIndex} < {propertyCount}; {propertyIndex}++)"); source.AppendLine($"{indent}{{"); var serializableKeyElement = new SerializableProperty { Name = propertyKeyEntry, - Type = ruleArguments[1], + Type = keyType, Rule = keyElementRule.RuleName, RuleArguments = keyRuleArguments }; @@ -154,7 +162,7 @@ namespace SerializableMigration var serializableValueElement = new SerializableProperty { Name = propertyValueEntry, - Type = ruleArguments[valueRuleIndex + 1], + Type = valueType, Rule = valueElementRule.RuleName, RuleArguments = valueRuleArguments }; @@ -175,21 +183,27 @@ namespace SerializableMigration } var ruleArguments = property.RuleArguments; - var shouldTidy = ruleArguments![0].Contains("@Tidy"); + var index = 0; + var shouldTidy = ruleArguments![index++].Contains("@Tidy"); + var keyType = ruleArguments![index++]; - var keyElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[2]]; - var valueRuleIndex = Array.IndexOf(ruleArguments, KEY_VALUE_PAIR_DELIMITER, 3); - if (valueRuleIndex == -1) + var keyElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments![index++]]; + var keyRuleArguments = new string[int.Parse(ruleArguments[index++])]; + + if (keyRuleArguments.Length > 0) { - throw new InvalidDataException($"Cannot find key-value delimiter in arguments for {property.Name}"); + Array.Copy(ruleArguments, index, keyRuleArguments, 0, keyRuleArguments.Length); + index += keyRuleArguments.Length; } - var keyRuleArguments = new string[valueRuleIndex - 3]; - Array.Copy(ruleArguments, 3, keyRuleArguments, 0, keyRuleArguments.Length); + var valueType = ruleArguments[index++]; + var valueElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]]; + var valueRuleArguments = new string[int.Parse(ruleArguments[index++])]; - var valueElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[valueRuleIndex + 2]]; - var valueRuleArguments = new string[ruleArguments.Length - valueRuleIndex - 2]; - Array.Copy(ruleArguments, 2 + valueRuleIndex, valueRuleArguments, 0, valueRuleArguments.Length); + if (valueRuleArguments.Length > 0) + { + Array.Copy(ruleArguments, index, valueRuleArguments, 0, valueRuleArguments.Length); + } var propertyName = property.Name; var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}"; @@ -211,7 +225,7 @@ namespace SerializableMigration var serializableKeyElement = new SerializableProperty { Name = propertyKeyEntry, - Type = ruleArguments[1], + Type = keyType, Rule = keyElementRule.RuleName, RuleArguments = keyRuleArguments }; @@ -221,12 +235,12 @@ namespace SerializableMigration var serializableValueElement = new SerializableProperty { Name = propertyValueEntry, - Type = ruleArguments[valueRuleIndex + 1], + Type = valueType, Rule = valueElementRule.RuleName, RuleArguments = valueRuleArguments }; - keyElementRule.GenerateSerializationMethod(source, $"{indent} ", serializableValueElement); + valueElementRule.GenerateSerializationMethod(source, $"{indent} ", serializableValueElement); source.AppendLine($"{indent} }}"); source.AppendLine($"{indent}}}"); diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/KeyValuePairMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/KeyValuePairMigrationRule.cs index 7ebdf064d..1797764c1 100644 --- a/Projects/SerializationGenerator/SerializableMigration/Rules/KeyValuePairMigrationRule.cs +++ b/Projects/SerializationGenerator/SerializableMigration/Rules/KeyValuePairMigrationRule.cs @@ -41,12 +41,12 @@ namespace SerializableMigration return false; } - var typeArguments = namedTypeSymbol.TypeArguments; + var keySymbolType = namedTypeSymbol.TypeArguments[0]; var keySerializedProperty = SerializableMigrationRulesEngine.GenerateSerializableProperty( compilation, "key", - typeArguments[0], + keySymbolType, 0, attributes, serializableTypes, @@ -55,10 +55,12 @@ namespace SerializableMigration null ); + var valueSymbolType = namedTypeSymbol.TypeArguments[1]; + var valueSerializedProperty = SerializableMigrationRulesEngine.GenerateSerializableProperty( compilation, "value", - typeArguments[1], + valueSymbolType, 1, attributes, serializableTypes, @@ -72,17 +74,19 @@ namespace SerializableMigration var index = 0; // Key - ruleArguments = new string[5 + keyArgumentsLength + valueArgumentsLength]; - ruleArguments[index++] = typeArguments[0].ToDisplayString(); + ruleArguments = new string[6 + keyArgumentsLength + valueArgumentsLength]; + ruleArguments[index++] = ""; // Extra options + ruleArguments[index++] = keySymbolType.ToDisplayString(); ruleArguments[index++] = keySerializedProperty.Rule; ruleArguments[index++] = keyArgumentsLength.ToString(); if (keyArgumentsLength > 0) { Array.Copy(keySerializedProperty.RuleArguments!, 0, ruleArguments, index, keyArgumentsLength); + index += keyArgumentsLength; } // Value - ruleArguments[index++] = typeArguments[1].ToDisplayString(); + ruleArguments[index++] = valueSymbolType.ToDisplayString(); ruleArguments[index++] = valueSerializedProperty.Rule; if (valueArgumentsLength > 0) @@ -103,10 +107,16 @@ namespace SerializableMigration } var ruleArguments = property.RuleArguments; - var keyType = ruleArguments![0]; - var keyRule = SerializableMigrationRulesEngine.Rules[ruleArguments[1]]; - var keyRuleArguments = new string[int.Parse(ruleArguments[2])]; - Array.Copy(ruleArguments, 3, keyRuleArguments, 0, keyRuleArguments.Length); + var index = 1; // skip extra options + var keyType = ruleArguments![index++]; + var keyRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]]; + var keyRuleArguments = new string[int.Parse(ruleArguments[index++])]; + + if (keyRuleArguments.Length > 0) + { + Array.Copy(ruleArguments, index, keyRuleArguments, 0, keyRuleArguments.Length); + index += keyRuleArguments.Length; + } var serializableKeyProperty = new SerializableProperty { @@ -123,11 +133,14 @@ namespace SerializableMigration parentReference ); - var valueIndex = 3 + keyRuleArguments.Length; - var valueType = ruleArguments[valueIndex++]; - var valueRule = SerializableMigrationRulesEngine.Rules[ruleArguments[valueIndex++]]; - var valueRuleArguments = new string[ruleArguments.Length - valueIndex]; - Array.Copy(ruleArguments, valueIndex, valueRuleArguments, 0, valueRuleArguments.Length); + var valueType = ruleArguments[index++]; + var valueRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]]; + var valueRuleArguments = new string[int.Parse(ruleArguments[index++])]; + + if (valueRuleArguments.Length > 0) + { + Array.Copy(ruleArguments, index, valueRuleArguments, 0, valueRuleArguments.Length); + } var serializableValueProperty = new SerializableProperty { @@ -137,7 +150,7 @@ namespace SerializableMigration RuleArguments = valueRuleArguments }; - keyRule.GenerateDeserializationMethod( + valueRule.GenerateDeserializationMethod( source, indent, serializableValueProperty, @@ -159,10 +172,16 @@ namespace SerializableMigration } var ruleArguments = property.RuleArguments; - var keyType = ruleArguments![0]; - var keyRule = SerializableMigrationRulesEngine.Rules[ruleArguments[1]]; - var keyRuleArguments = new string[int.Parse(ruleArguments[2])]; - Array.Copy(ruleArguments, 3, keyRuleArguments, 0, keyRuleArguments.Length); + var index = 1; // skip extra options + var keyType = ruleArguments![index++]; + var keyRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]]; + var keyRuleArguments = new string[int.Parse(ruleArguments[index++])]; + + if (keyRuleArguments.Length > 0) + { + Array.Copy(ruleArguments, index, keyRuleArguments, 0, keyRuleArguments.Length); + index += keyRuleArguments.Length; + } var serializableKeyProperty = new SerializableProperty { @@ -178,11 +197,14 @@ namespace SerializableMigration serializableKeyProperty ); - var valueIndex = 3 + keyRuleArguments.Length; - var valueType = ruleArguments[valueIndex++]; - var valueRule = SerializableMigrationRulesEngine.Rules[ruleArguments[valueIndex++]]; - var valueRuleArguments = new string[ruleArguments.Length - valueIndex]; - Array.Copy(ruleArguments, valueIndex, valueRuleArguments, 0, valueRuleArguments.Length); + var valueType = ruleArguments[index++]; + var valueRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]]; + var valueRuleArguments = new string[int.Parse(ruleArguments[index++])]; + + if (valueRuleArguments.Length > 0) + { + Array.Copy(ruleArguments, index, valueRuleArguments, 0, valueRuleArguments.Length); + } var serializableValueProperty = new SerializableProperty { @@ -192,7 +214,7 @@ namespace SerializableMigration RuleArguments = valueRuleArguments }; - keyRule.GenerateSerializationMethod( + valueRule.GenerateSerializationMethod( source, indent, serializableValueProperty diff --git a/Projects/SerializationGenerator/SerializationGenerator.csproj b/Projects/SerializationGenerator/SerializationGenerator.csproj index 1839dfeb3..03b5a5bdb 100755 --- a/Projects/SerializationGenerator/SerializationGenerator.csproj +++ b/Projects/SerializationGenerator/SerializationGenerator.csproj @@ -1,6 +1,6 @@ - netstandard2.0 + netstandard2.0 preview analyzers diff --git a/azure-pipelines.yml b/azure-pipelines.yml index db3ef8f9a..6923ed2ae 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -27,7 +27,7 @@ jobs: - task: NuGetAuthenticate@0 - script: ./publish.cmd Release win displayName: 'Build' - - script: dotnet test --no-restore + - script: dotnet test --no-restore --framework net6.0 displayName: 'Test' - job: BuildLinux @@ -76,5 +76,5 @@ jobs: - task: NuGetAuthenticate@0 - script: ./publish.cmd Release $(os) displayName: 'Build' - - script: dotnet test --no-restore + - script: dotnet test --no-restore --framework net6.0 displayName: 'Test' diff --git a/publish.cmd b/publish.cmd index 140dd547c..e0f9fe6df 100755 --- a/publish.cmd +++ b/publish.cmd @@ -32,8 +32,8 @@ dotnet clean --verbosity quiet echo dotnet restore --force-evaluate --source https://api.nuget.org/v3/index.json dotnet restore --force-evaluate --source https://api.nuget.org/v3/index.json -echo dotnet publish ${config} ${os} --no-restore --self-contained=false -o Distribution/Assemblies Projects/UOContent/UOContent.csproj -dotnet publish ${config} ${os} --no-restore --self-contained=false -o Distribution/Assemblies Projects/UOContent/UOContent.csproj +echo dotnet publish ${config} ${os} --framework net6.0 --no-restore --self-contained=false -o Distribution/Assemblies Projects/UOContent/UOContent.csproj +dotnet publish ${config} ${os} --framework net6.0 --no-restore --self-contained=false -o Distribution/Assemblies Projects/UOContent/UOContent.csproj echo dotnet build -c Release Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj dotnet build -c Release Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj @@ -65,8 +65,8 @@ dotnet clean --verbosity quiet echo dotnet restore --force-evaluate --source https://api.nuget.org/v3/index.json dotnet restore --force-evaluate --source https://api.nuget.org/v3/index.json -echo dotnet publish %config% %os% --no-restore --self-contained=false -o Distribution\Assemblies Projects\UOContent\UOContent.csproj -dotnet publish %config% %os% --no-restore --self-contained=false -o Distribution\Assemblies Projects\UOContent\UOContent.csproj +echo dotnet publish %config% %os% --framework net6.0 --no-restore --self-contained=false -o Distribution\Assemblies Projects\UOContent\UOContent.csproj +dotnet publish %config% %os% --framework net6.0 --no-restore --self-contained=false -o Distribution\Assemblies Projects\UOContent\UOContent.csproj echo dotnet build -c Release Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj dotnet build -c Release Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj From ecaf8ca98a6814f21fef082ab17c77affbf8ec6b Mon Sep 17 00:00:00 2001 From: Arthrutus <75637913+Arthrutus@users.noreply.github.com> Date: Sat, 13 Nov 2021 18:18:46 -0600 Subject: [PATCH 006/213] fix: Fixes door location at hedge maze (#841) --- .../Data/Decoration/Britannia/_hedgemaze.cfg | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Distribution/Data/Decoration/Britannia/_hedgemaze.cfg b/Distribution/Data/Decoration/Britannia/_hedgemaze.cfg index 127f363c9..25a7f712f 100644 --- a/Distribution/Data/Decoration/Britannia/_hedgemaze.cfg +++ b/Distribution/Data/Decoration/Britannia/_hedgemaze.cfg @@ -133,8 +133,13 @@ LocalizedSign 0x1F28 (LabelNumber=1016109) # wooden gate DarkWoodGate 0x0866 (Facing=WestCW) -1131 2237 40 -1131 2237 50 +1132 2237 40 +1132 2237 50 + +# wooden gate +DarkWoodGate 0x0868 (Facing=EastCCW) +1133 2237 40 +1133 2237 50 # candelabra CandelabraStand 0x0B26 @@ -148,11 +153,6 @@ FancyArmoire 0x0A51 1132 2231 40 1132 2230 40 -# wooden gate -DarkWoodGate 0x0868 (Facing=EastCCW) -1132 2237 40 -1132 2237 50 - # book Static 0x1E20 1133 2235 24 From 38c4d09028cb3219c64d29490b767eea9f5230f4 Mon Sep 17 00:00:00 2001 From: nullptr-w8 <79784082+nullptr-w8@users.noreply.github.com> Date: Sun, 14 Nov 2021 05:19:34 +0500 Subject: [PATCH 007/213] fix: Fixes animal taming timeout in case target is cancelled. (#842) --- Projects/UOContent/Skills/AnimalTaming.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Projects/UOContent/Skills/AnimalTaming.cs b/Projects/UOContent/Skills/AnimalTaming.cs index 99833a41e..99b1293ef 100644 --- a/Projects/UOContent/Skills/AnimalTaming.cs +++ b/Projects/UOContent/Skills/AnimalTaming.cs @@ -33,7 +33,7 @@ namespace Server.SkillHandlers m.SendLocalizedMessage(502789); // Tame which animal? } - return TimeSpan.FromHours(6.0); + return TimeSpan.FromSeconds(30); } public static bool CheckMastery(Mobile tamer, BaseCreature creature) => From 91493f7f274c080a976c11781cc20cb82aecd219 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sat, 13 Nov 2021 16:31:10 -0800 Subject: [PATCH 008/213] fix: Fixes guild assignment (#846) --- Projects/Server/World/World.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Projects/Server/World/World.cs b/Projects/Server/World/World.cs index 72d21ac2b..a5d57436a 100644 --- a/Projects/Server/World/World.cs +++ b/Projects/Server/World/World.cs @@ -666,7 +666,7 @@ namespace Server T entity; // Add to this list when creating new serializable types - if (typeof(BaseGuild).IsAssignableTo(typeT)) + if (typeof(BaseGuild).IsAssignableFrom(typeT)) { entity = FindGuild(serial) as T; } From e5f55a424aec658481ef471ab4cb588d715cd51d Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 14 Nov 2021 18:31:32 -0800 Subject: [PATCH 009/213] fix: Cleans up spell info variable (#848) --- Projects/UOContent/Spells/Base/MagerySpell.cs | 3 +-- Projects/UOContent/Spells/Base/SpellHelper.cs | 9 +++------ Projects/UOContent/Spells/Bushido/Confidence.cs | 4 ++-- Projects/UOContent/Spells/Bushido/CounterAttack.cs | 4 ++-- Projects/UOContent/Spells/Bushido/Evasion.cs | 5 ++--- Projects/UOContent/Spells/Bushido/HonorableExecution.cs | 4 ++-- Projects/UOContent/Spells/Chivalry/CleanseByFire.cs | 4 ++-- Projects/UOContent/Spells/Chivalry/CloseWounds.cs | 4 ++-- Projects/UOContent/Spells/Chivalry/ConsecrateWeapon.cs | 4 ++-- Projects/UOContent/Spells/Chivalry/DispelEvil.cs | 4 ++-- Projects/UOContent/Spells/Chivalry/DivineFury.cs | 4 ++-- Projects/UOContent/Spells/Chivalry/EnemyOfOne.cs | 4 ++-- Projects/UOContent/Spells/Chivalry/HolyLight.cs | 4 ++-- Projects/UOContent/Spells/Chivalry/NobleSacrifice.cs | 4 ++-- Projects/UOContent/Spells/Chivalry/RemoveCurse.cs | 4 ++-- Projects/UOContent/Spells/Chivalry/SacredJourney.cs | 4 ++-- Projects/UOContent/Spells/Eighth/AirElemental.cs | 4 ++-- Projects/UOContent/Spells/Eighth/EarthElemental.cs | 4 ++-- Projects/UOContent/Spells/Eighth/Earthquake.cs | 4 ++-- Projects/UOContent/Spells/Eighth/EnergyVortex.cs | 4 ++-- Projects/UOContent/Spells/Eighth/FireElemental.cs | 4 ++-- Projects/UOContent/Spells/Eighth/Resurrection.cs | 4 ++-- Projects/UOContent/Spells/Eighth/SummonDaemon.cs | 4 ++-- Projects/UOContent/Spells/Eighth/WaterElemental.cs | 4 ++-- Projects/UOContent/Spells/Fifth/BladeSpirits.cs | 4 ++-- Projects/UOContent/Spells/Fifth/DispelField.cs | 4 ++-- Projects/UOContent/Spells/Fifth/Incognito.cs | 4 ++-- Projects/UOContent/Spells/Fifth/MagicReflect.cs | 4 ++-- Projects/UOContent/Spells/Fifth/MindBlast.cs | 6 +++--- Projects/UOContent/Spells/Fifth/Paralyze.cs | 4 ++-- Projects/UOContent/Spells/Fifth/PoisonField.cs | 4 ++-- Projects/UOContent/Spells/Fifth/SummonCreature.cs | 4 ++-- Projects/UOContent/Spells/First/Clumsy.cs | 4 ++-- Projects/UOContent/Spells/First/CreateFood.cs | 4 ++-- Projects/UOContent/Spells/First/Feeblemind.cs | 4 ++-- Projects/UOContent/Spells/First/Heal.cs | 4 ++-- Projects/UOContent/Spells/First/MagicArrow.cs | 4 ++-- Projects/UOContent/Spells/First/NightSight.cs | 4 ++-- Projects/UOContent/Spells/First/ReactiveArmor.cs | 4 ++-- Projects/UOContent/Spells/First/Weaken.cs | 4 ++-- Projects/UOContent/Spells/Fourth/ArchCure.cs | 4 ++-- Projects/UOContent/Spells/Fourth/ArchProtection.cs | 4 ++-- Projects/UOContent/Spells/Fourth/Curse.cs | 4 ++-- Projects/UOContent/Spells/Fourth/FireField.cs | 4 ++-- Projects/UOContent/Spells/Fourth/GreaterHeal.cs | 4 ++-- Projects/UOContent/Spells/Fourth/Lightning.cs | 4 ++-- Projects/UOContent/Spells/Fourth/ManaDrain.cs | 4 ++-- Projects/UOContent/Spells/Fourth/Recall.cs | 4 ++-- .../Spells/Gargoyle/SpellDefinitions/FlySpell.cs | 4 ++-- .../UOContent/Spells/Mysticism/AnimatedWeaponSpell.cs | 4 ++-- Projects/UOContent/Spells/Mysticism/EagleStrikeSpell.cs | 4 ++-- Projects/UOContent/Spells/Mysticism/HailStormSpell.cs | 4 ++-- .../UOContent/Spells/Mysticism/NetherCycloneSpell.cs | 4 ++-- Projects/UOContent/Spells/Mysticism/SpellPlagueSpell.cs | 4 ++-- Projects/UOContent/Spells/Mysticism/StoneFormSpell.cs | 4 ++-- Projects/UOContent/Spells/Necromancy/AnimateDeadSpell.cs | 4 ++-- Projects/UOContent/Spells/Necromancy/BloodOathSpell.cs | 4 ++-- Projects/UOContent/Spells/Necromancy/CorpseSkin.cs | 4 ++-- Projects/UOContent/Spells/Necromancy/CurseWeapon.cs | 4 ++-- Projects/UOContent/Spells/Necromancy/EvilOmen.cs | 4 ++-- Projects/UOContent/Spells/Necromancy/Exorcism.cs | 4 ++-- Projects/UOContent/Spells/Necromancy/HorrificBeast.cs | 4 ++-- Projects/UOContent/Spells/Necromancy/LichForm.cs | 4 ++-- Projects/UOContent/Spells/Necromancy/MindRot.cs | 4 ++-- Projects/UOContent/Spells/Necromancy/PainSpike.cs | 4 ++-- Projects/UOContent/Spells/Necromancy/PoisonStrike.cs | 4 ++-- Projects/UOContent/Spells/Necromancy/Strangle.cs | 4 ++-- Projects/UOContent/Spells/Necromancy/SummonFamiliar.cs | 4 ++-- Projects/UOContent/Spells/Necromancy/VampiricEmbrace.cs | 4 ++-- Projects/UOContent/Spells/Necromancy/VengefulSpirit.cs | 4 ++-- Projects/UOContent/Spells/Necromancy/Wither.cs | 4 ++-- Projects/UOContent/Spells/Necromancy/WraithForm.cs | 4 ++-- Projects/UOContent/Spells/Ninjitsu/AnimalForm.cs | 4 ++-- Projects/UOContent/Spells/Ninjitsu/MirrorImage.cs | 4 ++-- Projects/UOContent/Spells/Ninjitsu/ShadowJump.cs | 4 ++-- Projects/UOContent/Spells/Second/Agility.cs | 4 ++-- Projects/UOContent/Spells/Second/Cunning.cs | 4 ++-- Projects/UOContent/Spells/Second/Cure.cs | 4 ++-- Projects/UOContent/Spells/Second/Harm.cs | 4 ++-- Projects/UOContent/Spells/Second/MagicTrap.cs | 4 ++-- Projects/UOContent/Spells/Second/Protection.cs | 4 ++-- Projects/UOContent/Spells/Second/RemoveTrap.cs | 4 ++-- Projects/UOContent/Spells/Second/Strength.cs | 4 ++-- Projects/UOContent/Spells/Seventh/ChainLightning.cs | 4 ++-- Projects/UOContent/Spells/Seventh/EnergyField.cs | 4 ++-- Projects/UOContent/Spells/Seventh/FlameStrike.cs | 4 ++-- Projects/UOContent/Spells/Seventh/GateTravel.cs | 4 ++-- Projects/UOContent/Spells/Seventh/ManaVampire.cs | 4 ++-- Projects/UOContent/Spells/Seventh/MassDispel.cs | 4 ++-- Projects/UOContent/Spells/Seventh/MeteorSwarm.cs | 4 ++-- Projects/UOContent/Spells/Seventh/Polymorph.cs | 4 ++-- Projects/UOContent/Spells/Sixth/Dispel.cs | 4 ++-- Projects/UOContent/Spells/Sixth/EnergyBolt.cs | 4 ++-- Projects/UOContent/Spells/Sixth/Explosion.cs | 5 ++--- Projects/UOContent/Spells/Sixth/Invisibility.cs | 4 ++-- Projects/UOContent/Spells/Sixth/Mark.cs | 4 ++-- Projects/UOContent/Spells/Sixth/MassCurse.cs | 4 ++-- Projects/UOContent/Spells/Sixth/ParalyzeField.cs | 4 ++-- Projects/UOContent/Spells/Sixth/Reveal.cs | 4 ++-- Projects/UOContent/Spells/Spellweaving/ArcaneCircle.cs | 4 ++-- Projects/UOContent/Spells/Spellweaving/AttuneWeapon.cs | 4 ++-- Projects/UOContent/Spells/Spellweaving/EssenceOfWind.cs | 4 ++-- Projects/UOContent/Spells/Spellweaving/EtherealVoyage.cs | 4 ++-- Projects/UOContent/Spells/Spellweaving/GiftOfLife.cs | 4 ++-- Projects/UOContent/Spells/Spellweaving/GiftOfRenewal.cs | 4 ++-- .../UOContent/Spells/Spellweaving/ImmolatingWeapon.cs | 4 ++-- Projects/UOContent/Spells/Spellweaving/NatureFury.cs | 4 ++-- Projects/UOContent/Spells/Spellweaving/ReaperForm.cs | 4 ++-- Projects/UOContent/Spells/Spellweaving/SummonFey.cs | 4 ++-- Projects/UOContent/Spells/Spellweaving/SummonFiend.cs | 4 ++-- Projects/UOContent/Spells/Spellweaving/Thunderstorm.cs | 4 ++-- Projects/UOContent/Spells/Spellweaving/WordOfDeath.cs | 4 ++-- Projects/UOContent/Spells/Third/Bless.cs | 4 ++-- Projects/UOContent/Spells/Third/Fireball.cs | 4 ++-- Projects/UOContent/Spells/Third/MagicLock.cs | 4 ++-- Projects/UOContent/Spells/Third/Poison.cs | 4 ++-- Projects/UOContent/Spells/Third/Telekinesis.cs | 4 ++-- Projects/UOContent/Spells/Third/Teleport.cs | 4 ++-- Projects/UOContent/Spells/Third/Unlock.cs | 4 ++-- Projects/UOContent/Spells/Third/WallOfStone.cs | 4 ++-- 120 files changed, 241 insertions(+), 247 deletions(-) diff --git a/Projects/UOContent/Spells/Base/MagerySpell.cs b/Projects/UOContent/Spells/Base/MagerySpell.cs index d496cf100..c42d60954 100644 --- a/Projects/UOContent/Spells/Base/MagerySpell.cs +++ b/Projects/UOContent/Spells/Base/MagerySpell.cs @@ -9,8 +9,7 @@ namespace Server.Spells private static readonly int[] m_ManaTable = { 4, 6, 9, 11, 14, 20, 40, 50 }; - public MagerySpell(Mobile caster, Item scroll, SpellInfo info) - : base(caster, scroll, info) + public MagerySpell(Mobile caster, Item scroll, SpellInfo info) : base(caster, scroll, info) { } diff --git a/Projects/UOContent/Spells/Base/SpellHelper.cs b/Projects/UOContent/Spells/Base/SpellHelper.cs index 6b7cb8a24..cbf225459 100644 --- a/Projects/UOContent/Spells/Base/SpellHelper.cs +++ b/Projects/UOContent/Spells/Base/SpellHelper.cs @@ -33,8 +33,7 @@ namespace Server { private readonly Mobile m_Mobile; - public InternalTimer(Mobile m) - : base(TimeSpan.FromMinutes(1.0)) + public InternalTimer(Mobile m) : base(TimeSpan.FromMinutes(1.0)) { m_Mobile = m; } @@ -1128,8 +1127,7 @@ namespace Server.Spells private readonly Mobile m_Target; private int m_Damage; - public SpellDamageTimer(Spell s, Mobile target, Mobile from, int damage, TimeSpan delay) - : base(delay) + public SpellDamageTimer(Spell s, Mobile target, Mobile from, int damage, TimeSpan delay) : base(delay) { m_Target = target; m_From = from; @@ -1170,8 +1168,7 @@ namespace Server.Spells public SpellDamageTimerAOS( Spell s, TimeSpan delay, Mobile target, Mobile from, int damage, int phys, int fire, int cold, int pois, int nrgy, int chaos, DFAlgorithm dfa - ) - : base(delay) + ) : base(delay) { m_Target = target; m_From = from; diff --git a/Projects/UOContent/Spells/Bushido/Confidence.cs b/Projects/UOContent/Spells/Bushido/Confidence.cs index a846088f1..be3313cf8 100644 --- a/Projects/UOContent/Spells/Bushido/Confidence.cs +++ b/Projects/UOContent/Spells/Bushido/Confidence.cs @@ -5,7 +5,7 @@ namespace Server.Spells.Bushido { public class Confidence : SamuraiSpell { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Confidence", null, -1, @@ -15,7 +15,7 @@ namespace Server.Spells.Bushido private static readonly Dictionary m_Table = new(); private static readonly Dictionary m_RegenTable = new(); - public Confidence(Mobile caster, Item scroll) : base(caster, scroll, m_Info) + public Confidence(Mobile caster, Item scroll) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Bushido/CounterAttack.cs b/Projects/UOContent/Spells/Bushido/CounterAttack.cs index 04eb1ebcb..ba546fa5b 100644 --- a/Projects/UOContent/Spells/Bushido/CounterAttack.cs +++ b/Projects/UOContent/Spells/Bushido/CounterAttack.cs @@ -6,7 +6,7 @@ namespace Server.Spells.Bushido { public class CounterAttack : SamuraiSpell { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "CounterAttack", null, -1, @@ -15,7 +15,7 @@ namespace Server.Spells.Bushido private static readonly Dictionary m_Table = new(); - public CounterAttack(Mobile caster, Item scroll) : base(caster, scroll, m_Info) + public CounterAttack(Mobile caster, Item scroll) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Bushido/Evasion.cs b/Projects/UOContent/Spells/Bushido/Evasion.cs index 6c1c37b5c..d39b43194 100644 --- a/Projects/UOContent/Spells/Bushido/Evasion.cs +++ b/Projects/UOContent/Spells/Bushido/Evasion.cs @@ -6,7 +6,7 @@ namespace Server.Spells.Bushido { public class Evasion : SamuraiSpell { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Evasion", null, -1, @@ -15,8 +15,7 @@ namespace Server.Spells.Bushido private static readonly Dictionary m_Table = new(); - public Evasion(Mobile caster, Item scroll) - : base(caster, scroll, m_Info) + public Evasion(Mobile caster, Item scroll) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Bushido/HonorableExecution.cs b/Projects/UOContent/Spells/Bushido/HonorableExecution.cs index 0df746862..35da3b3d8 100644 --- a/Projects/UOContent/Spells/Bushido/HonorableExecution.cs +++ b/Projects/UOContent/Spells/Bushido/HonorableExecution.cs @@ -98,8 +98,8 @@ namespace Server.Spells.Bushido } public HonorableExecutionTimer( - TimeSpan duration, Mobile from, int swingBonus, List mods = null, bool penalty = false) - : base(duration) + TimeSpan duration, Mobile from, int swingBonus, List mods = null, bool penalty = false + ) : base(duration) { m_Mobile = from; m_SwingBonus = swingBonus; diff --git a/Projects/UOContent/Spells/Chivalry/CleanseByFire.cs b/Projects/UOContent/Spells/Chivalry/CleanseByFire.cs index f5ef5332a..952dd7ce9 100644 --- a/Projects/UOContent/Spells/Chivalry/CleanseByFire.cs +++ b/Projects/UOContent/Spells/Chivalry/CleanseByFire.cs @@ -6,14 +6,14 @@ namespace Server.Spells.Chivalry { public class CleanseByFireSpell : PaladinSpell, ISpellTargetingMobile { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Cleanse By Fire", "Expor Flamus", -1, 9002 ); - public CleanseByFireSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public CleanseByFireSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Chivalry/CloseWounds.cs b/Projects/UOContent/Spells/Chivalry/CloseWounds.cs index b3211b5d5..615fc8202 100644 --- a/Projects/UOContent/Spells/Chivalry/CloseWounds.cs +++ b/Projects/UOContent/Spells/Chivalry/CloseWounds.cs @@ -9,14 +9,14 @@ namespace Server.Spells.Chivalry { public class CloseWoundsSpell : PaladinSpell, ISpellTargetingMobile { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Close Wounds", "Obsu Vulni", -1, 9002 ); - public CloseWoundsSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public CloseWoundsSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Chivalry/ConsecrateWeapon.cs b/Projects/UOContent/Spells/Chivalry/ConsecrateWeapon.cs index def2f58b2..4033ce18c 100644 --- a/Projects/UOContent/Spells/Chivalry/ConsecrateWeapon.cs +++ b/Projects/UOContent/Spells/Chivalry/ConsecrateWeapon.cs @@ -6,7 +6,7 @@ namespace Server.Spells.Chivalry { public class ConsecrateWeaponSpell : PaladinSpell { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Consecrate Weapon", "Consecrus Arma", -1, @@ -15,7 +15,7 @@ namespace Server.Spells.Chivalry private static readonly Dictionary m_Table = new(); - public ConsecrateWeaponSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public ConsecrateWeaponSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Chivalry/DispelEvil.cs b/Projects/UOContent/Spells/Chivalry/DispelEvil.cs index 71b48ee72..d70ef6859 100644 --- a/Projects/UOContent/Spells/Chivalry/DispelEvil.cs +++ b/Projects/UOContent/Spells/Chivalry/DispelEvil.cs @@ -8,14 +8,14 @@ namespace Server.Spells.Chivalry { public class DispelEvilSpell : PaladinSpell { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Dispel Evil", "Dispiro Malas", -1, 9002 ); - public DispelEvilSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public DispelEvilSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Chivalry/DivineFury.cs b/Projects/UOContent/Spells/Chivalry/DivineFury.cs index c29ac7959..405d60064 100644 --- a/Projects/UOContent/Spells/Chivalry/DivineFury.cs +++ b/Projects/UOContent/Spells/Chivalry/DivineFury.cs @@ -5,7 +5,7 @@ namespace Server.Spells.Chivalry { public class DivineFurySpell : PaladinSpell { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Divine Fury", "Divinum Furis", -1, @@ -14,7 +14,7 @@ namespace Server.Spells.Chivalry private static readonly Dictionary m_Table = new(); - public DivineFurySpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public DivineFurySpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Chivalry/EnemyOfOne.cs b/Projects/UOContent/Spells/Chivalry/EnemyOfOne.cs index 5e58b04cc..b41410fed 100644 --- a/Projects/UOContent/Spells/Chivalry/EnemyOfOne.cs +++ b/Projects/UOContent/Spells/Chivalry/EnemyOfOne.cs @@ -6,7 +6,7 @@ namespace Server.Spells.Chivalry { public class EnemyOfOneSpell : PaladinSpell { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Enemy of One", "Forul Solum", -1, @@ -15,7 +15,7 @@ namespace Server.Spells.Chivalry private static readonly Dictionary m_Table = new(); - public EnemyOfOneSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public EnemyOfOneSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Chivalry/HolyLight.cs b/Projects/UOContent/Spells/Chivalry/HolyLight.cs index ddb1896fb..ae0b79d25 100644 --- a/Projects/UOContent/Spells/Chivalry/HolyLight.cs +++ b/Projects/UOContent/Spells/Chivalry/HolyLight.cs @@ -5,14 +5,14 @@ namespace Server.Spells.Chivalry { public class HolyLightSpell : PaladinSpell { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Holy Light", "Augus Luminos", -1, 9002 ); - public HolyLightSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public HolyLightSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Chivalry/NobleSacrifice.cs b/Projects/UOContent/Spells/Chivalry/NobleSacrifice.cs index f17e2df88..8009e46de 100644 --- a/Projects/UOContent/Spells/Chivalry/NobleSacrifice.cs +++ b/Projects/UOContent/Spells/Chivalry/NobleSacrifice.cs @@ -8,14 +8,14 @@ namespace Server.Spells.Chivalry { public class NobleSacrificeSpell : PaladinSpell { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Noble Sacrifice", "Dium Prostra", -1, 9002 ); - public NobleSacrificeSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public NobleSacrificeSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Chivalry/RemoveCurse.cs b/Projects/UOContent/Spells/Chivalry/RemoveCurse.cs index 10436d6de..21357ec64 100644 --- a/Projects/UOContent/Spells/Chivalry/RemoveCurse.cs +++ b/Projects/UOContent/Spells/Chivalry/RemoveCurse.cs @@ -9,14 +9,14 @@ namespace Server.Spells.Chivalry { public class RemoveCurseSpell : PaladinSpell, ISpellTargetingMobile { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Remove Curse", "Extermo Vomica", -1, 9002 ); - public RemoveCurseSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public RemoveCurseSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Chivalry/SacredJourney.cs b/Projects/UOContent/Spells/Chivalry/SacredJourney.cs index 3c56bb4c0..0b8667796 100644 --- a/Projects/UOContent/Spells/Chivalry/SacredJourney.cs +++ b/Projects/UOContent/Spells/Chivalry/SacredJourney.cs @@ -8,7 +8,7 @@ namespace Server.Spells.Chivalry { public class SacredJourneySpell : PaladinSpell, IRecallSpell { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Sacred Journey", "Sanctum Viatas", -1, @@ -21,7 +21,7 @@ namespace Server.Spells.Chivalry public SacredJourneySpell( Mobile caster, RunebookEntry entry = null, Runebook book = null, Item scroll = null - ) : base(caster, scroll, m_Info) + ) : base(caster, scroll, _info) { m_Entry = entry; m_Book = book; diff --git a/Projects/UOContent/Spells/Eighth/AirElemental.cs b/Projects/UOContent/Spells/Eighth/AirElemental.cs index 40107272a..a70a940e6 100644 --- a/Projects/UOContent/Spells/Eighth/AirElemental.cs +++ b/Projects/UOContent/Spells/Eighth/AirElemental.cs @@ -5,7 +5,7 @@ namespace Server.Spells.Eighth { public class AirElementalSpell : MagerySpell { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Air Elemental", "Kal Vas Xen Hur", 269, @@ -16,7 +16,7 @@ namespace Server.Spells.Eighth Reagent.SpidersSilk ); - public AirElementalSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public AirElementalSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Eighth/EarthElemental.cs b/Projects/UOContent/Spells/Eighth/EarthElemental.cs index 5c06991ef..9bad3b1ec 100644 --- a/Projects/UOContent/Spells/Eighth/EarthElemental.cs +++ b/Projects/UOContent/Spells/Eighth/EarthElemental.cs @@ -5,7 +5,7 @@ namespace Server.Spells.Eighth { public class EarthElementalSpell : MagerySpell { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Earth Elemental", "Kal Vas Xen Ylem", 269, @@ -16,7 +16,7 @@ namespace Server.Spells.Eighth Reagent.SpidersSilk ); - public EarthElementalSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public EarthElementalSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Eighth/Earthquake.cs b/Projects/UOContent/Spells/Eighth/Earthquake.cs index 80bd47bee..ffa480feb 100644 --- a/Projects/UOContent/Spells/Eighth/Earthquake.cs +++ b/Projects/UOContent/Spells/Eighth/Earthquake.cs @@ -5,7 +5,7 @@ namespace Server.Spells.Eighth { public class EarthquakeSpell : MagerySpell { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Earthquake", "In Vas Por", 233, @@ -17,7 +17,7 @@ namespace Server.Spells.Eighth Reagent.SulfurousAsh ); - public EarthquakeSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public EarthquakeSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Eighth/EnergyVortex.cs b/Projects/UOContent/Spells/Eighth/EnergyVortex.cs index c61d0dbaa..812f67bf0 100644 --- a/Projects/UOContent/Spells/Eighth/EnergyVortex.cs +++ b/Projects/UOContent/Spells/Eighth/EnergyVortex.cs @@ -5,7 +5,7 @@ namespace Server.Spells.Eighth { public class EnergyVortexSpell : MagerySpell, ISpellTargetingPoint3D { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Energy Vortex", "Vas Corp Por", 260, @@ -17,7 +17,7 @@ namespace Server.Spells.Eighth Reagent.Nightshade ); - public EnergyVortexSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public EnergyVortexSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Eighth/FireElemental.cs b/Projects/UOContent/Spells/Eighth/FireElemental.cs index 790d34527..2f99f35f0 100644 --- a/Projects/UOContent/Spells/Eighth/FireElemental.cs +++ b/Projects/UOContent/Spells/Eighth/FireElemental.cs @@ -5,7 +5,7 @@ namespace Server.Spells.Eighth { public class FireElementalSpell : MagerySpell { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Fire Elemental", "Kal Vas Xen Flam", 269, @@ -17,7 +17,7 @@ namespace Server.Spells.Eighth Reagent.SulfurousAsh ); - public FireElementalSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public FireElementalSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Eighth/Resurrection.cs b/Projects/UOContent/Spells/Eighth/Resurrection.cs index 04f7023bf..77fcc0afb 100644 --- a/Projects/UOContent/Spells/Eighth/Resurrection.cs +++ b/Projects/UOContent/Spells/Eighth/Resurrection.cs @@ -6,7 +6,7 @@ namespace Server.Spells.Eighth { public class ResurrectionSpell : MagerySpell, ISpellTargetingMobile { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Resurrection", "An Corp", 245, @@ -16,7 +16,7 @@ namespace Server.Spells.Eighth Reagent.Ginseng ); - public ResurrectionSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public ResurrectionSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Eighth/SummonDaemon.cs b/Projects/UOContent/Spells/Eighth/SummonDaemon.cs index 8dcb1d367..10f393fd3 100644 --- a/Projects/UOContent/Spells/Eighth/SummonDaemon.cs +++ b/Projects/UOContent/Spells/Eighth/SummonDaemon.cs @@ -5,7 +5,7 @@ namespace Server.Spells.Eighth { public class SummonDaemonSpell : MagerySpell { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Summon Daemon", "Kal Vas Xen Corp", 269, @@ -17,7 +17,7 @@ namespace Server.Spells.Eighth Reagent.SulfurousAsh ); - public SummonDaemonSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public SummonDaemonSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Eighth/WaterElemental.cs b/Projects/UOContent/Spells/Eighth/WaterElemental.cs index 597bc919e..92b332c96 100644 --- a/Projects/UOContent/Spells/Eighth/WaterElemental.cs +++ b/Projects/UOContent/Spells/Eighth/WaterElemental.cs @@ -5,7 +5,7 @@ namespace Server.Spells.Eighth { public class WaterElementalSpell : MagerySpell { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Water Elemental", "Kal Vas Xen An Flam", 269, @@ -16,7 +16,7 @@ namespace Server.Spells.Eighth Reagent.SpidersSilk ); - public WaterElementalSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public WaterElementalSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Fifth/BladeSpirits.cs b/Projects/UOContent/Spells/Fifth/BladeSpirits.cs index 3128673d9..296752d60 100644 --- a/Projects/UOContent/Spells/Fifth/BladeSpirits.cs +++ b/Projects/UOContent/Spells/Fifth/BladeSpirits.cs @@ -5,7 +5,7 @@ namespace Server.Spells.Fifth { public class BladeSpiritsSpell : MagerySpell, ISpellTargetingPoint3D { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Blade Spirits", "In Jux Hur Ylem", 266, @@ -16,7 +16,7 @@ namespace Server.Spells.Fifth Reagent.Nightshade ); - public BladeSpiritsSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public BladeSpiritsSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Fifth/DispelField.cs b/Projects/UOContent/Spells/Fifth/DispelField.cs index 055eff7be..e05b2718c 100644 --- a/Projects/UOContent/Spells/Fifth/DispelField.cs +++ b/Projects/UOContent/Spells/Fifth/DispelField.cs @@ -6,7 +6,7 @@ namespace Server.Spells.Fifth { public class DispelFieldSpell : MagerySpell, ISpellTargetingItem { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Dispel Field", "An Grav", 206, @@ -17,7 +17,7 @@ namespace Server.Spells.Fifth Reagent.Garlic ); - public DispelFieldSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public DispelFieldSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Fifth/Incognito.cs b/Projects/UOContent/Spells/Fifth/Incognito.cs index a0eb9b041..58dc05fb3 100644 --- a/Projects/UOContent/Spells/Fifth/Incognito.cs +++ b/Projects/UOContent/Spells/Fifth/Incognito.cs @@ -9,7 +9,7 @@ namespace Server.Spells.Fifth { public class IncognitoSpell : MagerySpell { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Incognito", "Kal In Ex", 206, @@ -21,7 +21,7 @@ namespace Server.Spells.Fifth private static readonly Dictionary m_Table = new(); - public IncognitoSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public IncognitoSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Fifth/MagicReflect.cs b/Projects/UOContent/Spells/Fifth/MagicReflect.cs index 814887828..a00100674 100644 --- a/Projects/UOContent/Spells/Fifth/MagicReflect.cs +++ b/Projects/UOContent/Spells/Fifth/MagicReflect.cs @@ -4,7 +4,7 @@ namespace Server.Spells.Fifth { public class MagicReflectSpell : MagerySpell { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Magic Reflection", "In Jux Sanct", 242, @@ -16,7 +16,7 @@ namespace Server.Spells.Fifth private static readonly Dictionary m_Table = new(); - public MagicReflectSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public MagicReflectSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Fifth/MindBlast.cs b/Projects/UOContent/Spells/Fifth/MindBlast.cs index cc19f0743..7f1b6945d 100644 --- a/Projects/UOContent/Spells/Fifth/MindBlast.cs +++ b/Projects/UOContent/Spells/Fifth/MindBlast.cs @@ -5,7 +5,7 @@ namespace Server.Spells.Fifth { public class MindBlastSpell : MagerySpell, ISpellTargetingMobile { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Mind Blast", "Por Corp Wis", 218, @@ -16,11 +16,11 @@ namespace Server.Spells.Fifth Reagent.SulfurousAsh ); - public MindBlastSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public MindBlastSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { if (Core.AOS) { - m_Info.LeftHandEffect = m_Info.RightHandEffect = 9002; + _info.LeftHandEffect = _info.RightHandEffect = 9002; } } diff --git a/Projects/UOContent/Spells/Fifth/Paralyze.cs b/Projects/UOContent/Spells/Fifth/Paralyze.cs index 5ff2a3d72..b7dc8c20d 100644 --- a/Projects/UOContent/Spells/Fifth/Paralyze.cs +++ b/Projects/UOContent/Spells/Fifth/Paralyze.cs @@ -7,7 +7,7 @@ namespace Server.Spells.Fifth { public class ParalyzeSpell : MagerySpell, ISpellTargetingMobile { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Paralyze", "An Ex Por", 218, @@ -17,7 +17,7 @@ namespace Server.Spells.Fifth Reagent.SpidersSilk ); - public ParalyzeSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public ParalyzeSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Fifth/PoisonField.cs b/Projects/UOContent/Spells/Fifth/PoisonField.cs index 4d4216a20..f08d8ca42 100644 --- a/Projects/UOContent/Spells/Fifth/PoisonField.cs +++ b/Projects/UOContent/Spells/Fifth/PoisonField.cs @@ -9,7 +9,7 @@ namespace Server.Spells.Fifth { public class PoisonFieldSpell : MagerySpell, ISpellTargetingPoint3D { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Poison Field", "In Nox Grav", 230, @@ -20,7 +20,7 @@ namespace Server.Spells.Fifth Reagent.SpidersSilk ); - public PoisonFieldSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public PoisonFieldSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Fifth/SummonCreature.cs b/Projects/UOContent/Spells/Fifth/SummonCreature.cs index 93c147c72..b8a4103e1 100644 --- a/Projects/UOContent/Spells/Fifth/SummonCreature.cs +++ b/Projects/UOContent/Spells/Fifth/SummonCreature.cs @@ -6,7 +6,7 @@ namespace Server.Spells.Fifth { public class SummonCreatureSpell : MagerySpell { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Summon Creature", "Kal Xen", 16, @@ -40,7 +40,7 @@ namespace Server.Spells.Fifth typeof(Rabbit) }; - public SummonCreatureSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public SummonCreatureSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/First/Clumsy.cs b/Projects/UOContent/Spells/First/Clumsy.cs index d63d16b67..e47ddbe16 100644 --- a/Projects/UOContent/Spells/First/Clumsy.cs +++ b/Projects/UOContent/Spells/First/Clumsy.cs @@ -4,7 +4,7 @@ namespace Server.Spells.First { public class ClumsySpell : MagerySpell, ISpellTargetingMobile { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Clumsy", "Uus Jux", 212, @@ -13,7 +13,7 @@ namespace Server.Spells.First Reagent.Nightshade ); - public ClumsySpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public ClumsySpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/First/CreateFood.cs b/Projects/UOContent/Spells/First/CreateFood.cs index 720ec2d37..ab98b5ec0 100644 --- a/Projects/UOContent/Spells/First/CreateFood.cs +++ b/Projects/UOContent/Spells/First/CreateFood.cs @@ -6,7 +6,7 @@ namespace Server.Spells.First { public class CreateFoodSpell : MagerySpell { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Create Food", "In Mani Ylem", 224, @@ -30,7 +30,7 @@ namespace Server.Spells.First new(typeof(Peach), "a peach") }; - public CreateFoodSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public CreateFoodSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/First/Feeblemind.cs b/Projects/UOContent/Spells/First/Feeblemind.cs index 277cffb32..22a06ef38 100644 --- a/Projects/UOContent/Spells/First/Feeblemind.cs +++ b/Projects/UOContent/Spells/First/Feeblemind.cs @@ -4,7 +4,7 @@ namespace Server.Spells.First { public class FeeblemindSpell : MagerySpell, ISpellTargetingMobile { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Feeblemind", "Rel Wis", 212, @@ -13,7 +13,7 @@ namespace Server.Spells.First Reagent.Nightshade ); - public FeeblemindSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public FeeblemindSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/First/Heal.cs b/Projects/UOContent/Spells/First/Heal.cs index 395b69674..efde53803 100644 --- a/Projects/UOContent/Spells/First/Heal.cs +++ b/Projects/UOContent/Spells/First/Heal.cs @@ -8,7 +8,7 @@ namespace Server.Spells.First { public class HealSpell : MagerySpell, ISpellTargetingMobile { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Heal", "In Mani", 224, @@ -18,7 +18,7 @@ namespace Server.Spells.First Reagent.SpidersSilk ); - public HealSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public HealSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/First/MagicArrow.cs b/Projects/UOContent/Spells/First/MagicArrow.cs index e8cdb0c0b..e8922739d 100644 --- a/Projects/UOContent/Spells/First/MagicArrow.cs +++ b/Projects/UOContent/Spells/First/MagicArrow.cs @@ -4,7 +4,7 @@ namespace Server.Spells.First { public class MagicArrowSpell : MagerySpell, ISpellTargetingMobile { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Magic Arrow", "In Por Ylem", 212, @@ -12,7 +12,7 @@ namespace Server.Spells.First Reagent.SulfurousAsh ); - public MagicArrowSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public MagicArrowSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/First/NightSight.cs b/Projects/UOContent/Spells/First/NightSight.cs index daa618c97..39bee6514 100644 --- a/Projects/UOContent/Spells/First/NightSight.cs +++ b/Projects/UOContent/Spells/First/NightSight.cs @@ -5,7 +5,7 @@ namespace Server.Spells.First { public class NightSightSpell : MagerySpell { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Night Sight", "In Lor", 236, @@ -14,7 +14,7 @@ namespace Server.Spells.First Reagent.SpidersSilk ); - public NightSightSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public NightSightSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/First/ReactiveArmor.cs b/Projects/UOContent/Spells/First/ReactiveArmor.cs index 4e85f0e02..b60167b13 100644 --- a/Projects/UOContent/Spells/First/ReactiveArmor.cs +++ b/Projects/UOContent/Spells/First/ReactiveArmor.cs @@ -5,7 +5,7 @@ namespace Server.Spells.First { public class ReactiveArmorSpell : MagerySpell { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Reactive Armor", "Flam Sanct", 236, @@ -17,7 +17,7 @@ namespace Server.Spells.First private static readonly Dictionary m_Table = new(); - public ReactiveArmorSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public ReactiveArmorSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/First/Weaken.cs b/Projects/UOContent/Spells/First/Weaken.cs index 4ff913447..3fcaf4bbe 100644 --- a/Projects/UOContent/Spells/First/Weaken.cs +++ b/Projects/UOContent/Spells/First/Weaken.cs @@ -4,7 +4,7 @@ namespace Server.Spells.First { public class WeakenSpell : MagerySpell, ISpellTargetingMobile { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Weaken", "Des Mani", 212, @@ -13,7 +13,7 @@ namespace Server.Spells.First Reagent.Nightshade ); - public WeakenSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public WeakenSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Fourth/ArchCure.cs b/Projects/UOContent/Spells/Fourth/ArchCure.cs index 55e031045..f2b2bf95e 100644 --- a/Projects/UOContent/Spells/Fourth/ArchCure.cs +++ b/Projects/UOContent/Spells/Fourth/ArchCure.cs @@ -8,7 +8,7 @@ namespace Server.Spells.Fourth { public class ArchCureSpell : MagerySpell, ISpellTargetingPoint3D { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Arch Cure", "Vas An Nox", 215, @@ -18,7 +18,7 @@ namespace Server.Spells.Fourth Reagent.MandrakeRoot ); - public ArchCureSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public ArchCureSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Fourth/ArchProtection.cs b/Projects/UOContent/Spells/Fourth/ArchProtection.cs index 2f1923f3f..916c9643e 100644 --- a/Projects/UOContent/Spells/Fourth/ArchProtection.cs +++ b/Projects/UOContent/Spells/Fourth/ArchProtection.cs @@ -9,7 +9,7 @@ namespace Server.Spells.Fourth { public class ArchProtectionSpell : MagerySpell, ISpellTargetingPoint3D { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Arch Protection", "Vas Uus Sanct", Core.AOS ? 239 : 215, @@ -22,7 +22,7 @@ namespace Server.Spells.Fourth private static readonly Dictionary _Table = new(); - public ArchProtectionSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public ArchProtectionSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Fourth/Curse.cs b/Projects/UOContent/Spells/Fourth/Curse.cs index 73bff2c02..a78c32e76 100644 --- a/Projects/UOContent/Spells/Fourth/Curse.cs +++ b/Projects/UOContent/Spells/Fourth/Curse.cs @@ -5,7 +5,7 @@ namespace Server.Spells.Fourth { public class CurseSpell : MagerySpell, ISpellTargetingMobile { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Curse", "Des Sanct", 227, @@ -17,7 +17,7 @@ namespace Server.Spells.Fourth private static readonly HashSet m_UnderEffect = new(); - public CurseSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public CurseSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Fourth/FireField.cs b/Projects/UOContent/Spells/Fourth/FireField.cs index df1ea840c..cd4934744 100644 --- a/Projects/UOContent/Spells/Fourth/FireField.cs +++ b/Projects/UOContent/Spells/Fourth/FireField.cs @@ -9,7 +9,7 @@ namespace Server.Spells.Fourth { public class FireFieldSpell : MagerySpell, ISpellTargetingPoint3D { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Fire Field", "In Flam Grav", 215, @@ -20,7 +20,7 @@ namespace Server.Spells.Fourth Reagent.SulfurousAsh ); - public FireFieldSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public FireFieldSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Fourth/GreaterHeal.cs b/Projects/UOContent/Spells/Fourth/GreaterHeal.cs index fd1fcc010..36647df92 100644 --- a/Projects/UOContent/Spells/Fourth/GreaterHeal.cs +++ b/Projects/UOContent/Spells/Fourth/GreaterHeal.cs @@ -8,7 +8,7 @@ namespace Server.Spells.Fourth { public class GreaterHealSpell : MagerySpell, ISpellTargetingMobile { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Greater Heal", "In Vas Mani", 204, @@ -19,7 +19,7 @@ namespace Server.Spells.Fourth Reagent.SpidersSilk ); - public GreaterHealSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public GreaterHealSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Fourth/Lightning.cs b/Projects/UOContent/Spells/Fourth/Lightning.cs index e0f2b8745..badf7db64 100644 --- a/Projects/UOContent/Spells/Fourth/Lightning.cs +++ b/Projects/UOContent/Spells/Fourth/Lightning.cs @@ -4,7 +4,7 @@ namespace Server.Spells.Fourth { public class LightningSpell : MagerySpell, ISpellTargetingMobile { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Lightning", "Por Ort Grav", 239, @@ -13,7 +13,7 @@ namespace Server.Spells.Fourth Reagent.SulfurousAsh ); - public LightningSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public LightningSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Fourth/ManaDrain.cs b/Projects/UOContent/Spells/Fourth/ManaDrain.cs index 342b4aed4..e06997783 100644 --- a/Projects/UOContent/Spells/Fourth/ManaDrain.cs +++ b/Projects/UOContent/Spells/Fourth/ManaDrain.cs @@ -6,7 +6,7 @@ namespace Server.Spells.Fourth { public class ManaDrainSpell : MagerySpell, ISpellTargetingMobile { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Mana Drain", "Ort Rel", 215, @@ -18,7 +18,7 @@ namespace Server.Spells.Fourth private static readonly HashSet m_Table = new(); - public ManaDrainSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public ManaDrainSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Fourth/Recall.cs b/Projects/UOContent/Spells/Fourth/Recall.cs index 4ffa32f60..c2f556e33 100644 --- a/Projects/UOContent/Spells/Fourth/Recall.cs +++ b/Projects/UOContent/Spells/Fourth/Recall.cs @@ -8,7 +8,7 @@ namespace Server.Spells.Fourth { public class RecallSpell : MagerySpell, IRecallSpell { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Recall", "Kal Ort Por", 239, @@ -25,7 +25,7 @@ namespace Server.Spells.Fourth public RecallSpell(Mobile caster, RunebookEntry entry = null, Runebook book = null, Item scroll = null) : base( caster, scroll, - m_Info + _info ) { m_Entry = entry; diff --git a/Projects/UOContent/Spells/Gargoyle/SpellDefinitions/FlySpell.cs b/Projects/UOContent/Spells/Gargoyle/SpellDefinitions/FlySpell.cs index 3ead16edf..d6769c25f 100644 --- a/Projects/UOContent/Spells/Gargoyle/SpellDefinitions/FlySpell.cs +++ b/Projects/UOContent/Spells/Gargoyle/SpellDefinitions/FlySpell.cs @@ -4,11 +4,11 @@ namespace Server.Spells { public class FlySpell : Spell { - private static readonly SpellInfo m_Info = new("Gargoyle Flight", null, -1, 9002); + private static readonly SpellInfo _info = new("Gargoyle Flight", null, -1, 9002); private bool m_Stop; public FlySpell(Mobile caster) - : base(caster, null, m_Info) + : base(caster, null, _info) { } diff --git a/Projects/UOContent/Spells/Mysticism/AnimatedWeaponSpell.cs b/Projects/UOContent/Spells/Mysticism/AnimatedWeaponSpell.cs index 341d06697..740ee09c8 100644 --- a/Projects/UOContent/Spells/Mysticism/AnimatedWeaponSpell.cs +++ b/Projects/UOContent/Spells/Mysticism/AnimatedWeaponSpell.cs @@ -5,7 +5,7 @@ namespace Server.Spells.Mysticism { public class AnimatedWeaponSpell : MysticSpell, ISpellTargetingPoint3D { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Animated Weapon", "In Jux Por Ylem", -1, @@ -17,7 +17,7 @@ namespace Server.Spells.Mysticism ); public AnimatedWeaponSpell(Mobile caster, Item scroll = null) - : base(caster, scroll, m_Info) + : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Mysticism/EagleStrikeSpell.cs b/Projects/UOContent/Spells/Mysticism/EagleStrikeSpell.cs index 408ce92c1..30e263db6 100644 --- a/Projects/UOContent/Spells/Mysticism/EagleStrikeSpell.cs +++ b/Projects/UOContent/Spells/Mysticism/EagleStrikeSpell.cs @@ -5,7 +5,7 @@ namespace Server.Spells.Mysticism { public class EagleStrikeSpell : MysticSpell, ISpellTargetingMobile { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Eagle Strike", "Kal Por Xen", -1, @@ -17,7 +17,7 @@ namespace Server.Spells.Mysticism ); public EagleStrikeSpell(Mobile caster, Item scroll = null) - : base(caster, scroll, m_Info) + : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Mysticism/HailStormSpell.cs b/Projects/UOContent/Spells/Mysticism/HailStormSpell.cs index 9030619cb..586833388 100644 --- a/Projects/UOContent/Spells/Mysticism/HailStormSpell.cs +++ b/Projects/UOContent/Spells/Mysticism/HailStormSpell.cs @@ -5,7 +5,7 @@ namespace Server.Spells.Mysticism { public class HailStormSpell : MysticSpell, ISpellTargetingPoint3D { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Hail Storm", "Kal Des Ylem", -1, @@ -17,7 +17,7 @@ namespace Server.Spells.Mysticism ); public HailStormSpell(Mobile caster, Item scroll = null) - : base(caster, scroll, m_Info) + : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Mysticism/NetherCycloneSpell.cs b/Projects/UOContent/Spells/Mysticism/NetherCycloneSpell.cs index f927aba56..15a79e752 100644 --- a/Projects/UOContent/Spells/Mysticism/NetherCycloneSpell.cs +++ b/Projects/UOContent/Spells/Mysticism/NetherCycloneSpell.cs @@ -5,7 +5,7 @@ namespace Server.Spells.Mysticism { public class NetherCycloneSpell : MysticSpell, ISpellTargetingPoint3D { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Nether Cyclone", "Grav Hur", -1, @@ -17,7 +17,7 @@ namespace Server.Spells.Mysticism ); public NetherCycloneSpell(Mobile caster, Item scroll = null) - : base(caster, scroll, m_Info) + : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Mysticism/SpellPlagueSpell.cs b/Projects/UOContent/Spells/Mysticism/SpellPlagueSpell.cs index 8daac52e0..a5f47d3c4 100644 --- a/Projects/UOContent/Spells/Mysticism/SpellPlagueSpell.cs +++ b/Projects/UOContent/Spells/Mysticism/SpellPlagueSpell.cs @@ -6,7 +6,7 @@ namespace Server.Spells.Mysticism { public class SpellPlagueSpell : MysticSpell { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Spell Plague", "Vas Rel Jux Ort", -1, @@ -20,7 +20,7 @@ namespace Server.Spells.Mysticism private static readonly Dictionary m_Table = new(); public SpellPlagueSpell(Mobile caster, Item scroll = null) - : base(caster, scroll, m_Info) + : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Mysticism/StoneFormSpell.cs b/Projects/UOContent/Spells/Mysticism/StoneFormSpell.cs index 5cdfa8198..a707caecb 100644 --- a/Projects/UOContent/Spells/Mysticism/StoneFormSpell.cs +++ b/Projects/UOContent/Spells/Mysticism/StoneFormSpell.cs @@ -9,7 +9,7 @@ namespace Server.Spells.Mysticism { public class StoneFormSpell : MysticSpell { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Stone Form", "In Rel Ylem", -1, @@ -22,7 +22,7 @@ namespace Server.Spells.Mysticism private static readonly Dictionary m_Table = new(); public StoneFormSpell(Mobile caster, Item scroll = null) - : base(caster, scroll, m_Info) + : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Necromancy/AnimateDeadSpell.cs b/Projects/UOContent/Spells/Necromancy/AnimateDeadSpell.cs index d4e14cfe5..5363f8cb6 100644 --- a/Projects/UOContent/Spells/Necromancy/AnimateDeadSpell.cs +++ b/Projects/UOContent/Spells/Necromancy/AnimateDeadSpell.cs @@ -11,7 +11,7 @@ namespace Server.Spells.Necromancy { public class AnimateDeadSpell : NecromancerSpell, ISpellTargetingItem { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Animate Dead", "Uus Corp", 203, @@ -110,7 +110,7 @@ namespace Server.Spells.Necromancy private static readonly Dictionary> m_Table = new(); - public AnimateDeadSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public AnimateDeadSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Necromancy/BloodOathSpell.cs b/Projects/UOContent/Spells/Necromancy/BloodOathSpell.cs index d68d5c997..dd05819ff 100644 --- a/Projects/UOContent/Spells/Necromancy/BloodOathSpell.cs +++ b/Projects/UOContent/Spells/Necromancy/BloodOathSpell.cs @@ -7,7 +7,7 @@ namespace Server.Spells.Necromancy { public class BloodOathSpell : NecromancerSpell, ISpellTargetingMobile { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Blood Oath", "In Jux Mani Xen", 203, @@ -18,7 +18,7 @@ namespace Server.Spells.Necromancy private static readonly Dictionary m_OathTable = new(); private static readonly Dictionary m_Table = new(); - public BloodOathSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public BloodOathSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Necromancy/CorpseSkin.cs b/Projects/UOContent/Spells/Necromancy/CorpseSkin.cs index 11fa13137..e39f33118 100644 --- a/Projects/UOContent/Spells/Necromancy/CorpseSkin.cs +++ b/Projects/UOContent/Spells/Necromancy/CorpseSkin.cs @@ -6,7 +6,7 @@ namespace Server.Spells.Necromancy { public class CorpseSkinSpell : NecromancerSpell, ISpellTargetingMobile { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Corpse Skin", "In Agle Corp Ylem", 203, @@ -17,7 +17,7 @@ namespace Server.Spells.Necromancy private static readonly Dictionary m_Table = new(); - public CorpseSkinSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public CorpseSkinSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Necromancy/CurseWeapon.cs b/Projects/UOContent/Spells/Necromancy/CurseWeapon.cs index eb1ec7582..61062abe6 100644 --- a/Projects/UOContent/Spells/Necromancy/CurseWeapon.cs +++ b/Projects/UOContent/Spells/Necromancy/CurseWeapon.cs @@ -6,7 +6,7 @@ namespace Server.Spells.Necromancy { public class CurseWeaponSpell : NecromancerSpell { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Curse Weapon", "An Sanct Gra Char", 203, @@ -16,7 +16,7 @@ namespace Server.Spells.Necromancy private static readonly Dictionary m_Table = new(); - public CurseWeaponSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public CurseWeaponSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Necromancy/EvilOmen.cs b/Projects/UOContent/Spells/Necromancy/EvilOmen.cs index 789110ffe..686db22ff 100644 --- a/Projects/UOContent/Spells/Necromancy/EvilOmen.cs +++ b/Projects/UOContent/Spells/Necromancy/EvilOmen.cs @@ -7,7 +7,7 @@ namespace Server.Spells.Necromancy { public class EvilOmenSpell : NecromancerSpell, ISpellTargetingMobile { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Evil Omen", "Pas Tym An Sanct", 203, @@ -19,7 +19,7 @@ namespace Server.Spells.Necromancy private static readonly Dictionary m_Table = new(); public EvilOmenSpell(Mobile caster, Item scroll = null) - : base(caster, scroll, m_Info) + : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Necromancy/Exorcism.cs b/Projects/UOContent/Spells/Necromancy/Exorcism.cs index 37602bf04..4f1c8980a 100644 --- a/Projects/UOContent/Spells/Necromancy/Exorcism.cs +++ b/Projects/UOContent/Spells/Necromancy/Exorcism.cs @@ -10,7 +10,7 @@ namespace Server.Spells.Necromancy { public class ExorcismSpell : NecromancerSpell { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Exorcism", "Ort Corp Grav", 203, @@ -57,7 +57,7 @@ namespace Server.Spells.Necromancy new(295, 712, 55) }; - public ExorcismSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public ExorcismSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Necromancy/HorrificBeast.cs b/Projects/UOContent/Spells/Necromancy/HorrificBeast.cs index 8a2335baa..cfc56e308 100644 --- a/Projects/UOContent/Spells/Necromancy/HorrificBeast.cs +++ b/Projects/UOContent/Spells/Necromancy/HorrificBeast.cs @@ -4,7 +4,7 @@ namespace Server.Spells.Necromancy { public class HorrificBeastSpell : TransformationSpell { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Horrific Beast", "Rel Xen Vas Bal", 203, @@ -13,7 +13,7 @@ namespace Server.Spells.Necromancy Reagent.DaemonBlood ); - public HorrificBeastSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public HorrificBeastSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Necromancy/LichForm.cs b/Projects/UOContent/Spells/Necromancy/LichForm.cs index 42676075e..d53a6b2b2 100644 --- a/Projects/UOContent/Spells/Necromancy/LichForm.cs +++ b/Projects/UOContent/Spells/Necromancy/LichForm.cs @@ -4,7 +4,7 @@ namespace Server.Spells.Necromancy { public class LichFormSpell : TransformationSpell { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Lich Form", "Rel Xen Corp Ort", 203, @@ -14,7 +14,7 @@ namespace Server.Spells.Necromancy Reagent.NoxCrystal ); - public LichFormSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public LichFormSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Necromancy/MindRot.cs b/Projects/UOContent/Spells/Necromancy/MindRot.cs index 44a70e316..3aaeda206 100644 --- a/Projects/UOContent/Spells/Necromancy/MindRot.cs +++ b/Projects/UOContent/Spells/Necromancy/MindRot.cs @@ -6,7 +6,7 @@ namespace Server.Spells.Necromancy { public class MindRotSpell : NecromancerSpell, ISpellTargetingMobile { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Mind Rot", "Wis An Ben", 203, @@ -18,7 +18,7 @@ namespace Server.Spells.Necromancy private static readonly Dictionary m_Table = new(); - public MindRotSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public MindRotSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Necromancy/PainSpike.cs b/Projects/UOContent/Spells/Necromancy/PainSpike.cs index 7a8646016..632c2af6b 100644 --- a/Projects/UOContent/Spells/Necromancy/PainSpike.cs +++ b/Projects/UOContent/Spells/Necromancy/PainSpike.cs @@ -7,7 +7,7 @@ namespace Server.Spells.Necromancy { public class PainSpikeSpell : NecromancerSpell, ISpellTargetingMobile { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Pain Spike", "In Sar", 203, @@ -18,7 +18,7 @@ namespace Server.Spells.Necromancy private static readonly Dictionary m_Table = new(); - public PainSpikeSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public PainSpikeSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Necromancy/PoisonStrike.cs b/Projects/UOContent/Spells/Necromancy/PoisonStrike.cs index 79d88a9d7..a978d9834 100644 --- a/Projects/UOContent/Spells/Necromancy/PoisonStrike.cs +++ b/Projects/UOContent/Spells/Necromancy/PoisonStrike.cs @@ -8,7 +8,7 @@ namespace Server.Spells.Necromancy { public class PoisonStrikeSpell : NecromancerSpell, ISpellTargetingMobile { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Poison Strike", "In Vas Nox", 203, @@ -17,7 +17,7 @@ namespace Server.Spells.Necromancy ); public PoisonStrikeSpell(Mobile caster, Item scroll = null) - : base(caster, scroll, m_Info) + : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Necromancy/Strangle.cs b/Projects/UOContent/Spells/Necromancy/Strangle.cs index f92943b7d..c221e1dac 100644 --- a/Projects/UOContent/Spells/Necromancy/Strangle.cs +++ b/Projects/UOContent/Spells/Necromancy/Strangle.cs @@ -6,7 +6,7 @@ namespace Server.Spells.Necromancy { public class StrangleSpell : NecromancerSpell, ISpellTargetingMobile { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Strangle", "In Bal Nox", 209, @@ -17,7 +17,7 @@ namespace Server.Spells.Necromancy private static readonly Dictionary m_Table = new(); - public StrangleSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public StrangleSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Necromancy/SummonFamiliar.cs b/Projects/UOContent/Spells/Necromancy/SummonFamiliar.cs index 9bff30d79..59dc363fb 100644 --- a/Projects/UOContent/Spells/Necromancy/SummonFamiliar.cs +++ b/Projects/UOContent/Spells/Necromancy/SummonFamiliar.cs @@ -9,7 +9,7 @@ namespace Server.Spells.Necromancy { public class SummonFamiliarSpell : NecromancerSpell { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Summon Familiar", "Kal Xen Bal", 203, @@ -19,7 +19,7 @@ namespace Server.Spells.Necromancy Reagent.DaemonBlood ); - public SummonFamiliarSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public SummonFamiliarSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Necromancy/VampiricEmbrace.cs b/Projects/UOContent/Spells/Necromancy/VampiricEmbrace.cs index 968e63e3c..31baa8533 100644 --- a/Projects/UOContent/Spells/Necromancy/VampiricEmbrace.cs +++ b/Projects/UOContent/Spells/Necromancy/VampiricEmbrace.cs @@ -5,7 +5,7 @@ namespace Server.Spells.Necromancy { public class VampiricEmbraceSpell : TransformationSpell { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Vampiric Embrace", "Rel Xen An Sanct", 203, @@ -15,7 +15,7 @@ namespace Server.Spells.Necromancy Reagent.PigIron ); - public VampiricEmbraceSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public VampiricEmbraceSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Necromancy/VengefulSpirit.cs b/Projects/UOContent/Spells/Necromancy/VengefulSpirit.cs index 017c12fe0..ea6428845 100644 --- a/Projects/UOContent/Spells/Necromancy/VengefulSpirit.cs +++ b/Projects/UOContent/Spells/Necromancy/VengefulSpirit.cs @@ -6,7 +6,7 @@ namespace Server.Spells.Necromancy { public class VengefulSpiritSpell : NecromancerSpell, ISpellTargetingMobile { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Vengeful Spirit", "Kal Xen Bal Beh", 203, @@ -16,7 +16,7 @@ namespace Server.Spells.Necromancy Reagent.PigIron ); - public VengefulSpiritSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public VengefulSpiritSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Necromancy/Wither.cs b/Projects/UOContent/Spells/Necromancy/Wither.cs index 25f548644..64329bf17 100644 --- a/Projects/UOContent/Spells/Necromancy/Wither.cs +++ b/Projects/UOContent/Spells/Necromancy/Wither.cs @@ -7,7 +7,7 @@ namespace Server.Spells.Necromancy { public class WitherSpell : NecromancerSpell { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Wither", "Kal Vas An Flam", 203, @@ -18,7 +18,7 @@ namespace Server.Spells.Necromancy ); public WitherSpell(Mobile caster, Item scroll = null) - : base(caster, scroll, m_Info) + : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Necromancy/WraithForm.cs b/Projects/UOContent/Spells/Necromancy/WraithForm.cs index 48f847330..a866e58be 100644 --- a/Projects/UOContent/Spells/Necromancy/WraithForm.cs +++ b/Projects/UOContent/Spells/Necromancy/WraithForm.cs @@ -5,7 +5,7 @@ namespace Server.Spells.Necromancy { public class WraithFormSpell : TransformationSpell { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Wraith Form", "Rel Xen Um", 203, @@ -14,7 +14,7 @@ namespace Server.Spells.Necromancy Reagent.PigIron ); - public WraithFormSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public WraithFormSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Ninjitsu/AnimalForm.cs b/Projects/UOContent/Spells/Ninjitsu/AnimalForm.cs index 78a16e8bf..c07995af0 100644 --- a/Projects/UOContent/Spells/Ninjitsu/AnimalForm.cs +++ b/Projects/UOContent/Spells/Ninjitsu/AnimalForm.cs @@ -18,7 +18,7 @@ namespace Server.Spells.Ninjitsu NoSkill } - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Animal Form", null, -1, @@ -31,7 +31,7 @@ namespace Server.Spells.Ninjitsu private bool m_WasMoving; public AnimalForm(Mobile caster, Item scroll) - : base(caster, scroll, m_Info) + : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Ninjitsu/MirrorImage.cs b/Projects/UOContent/Spells/Ninjitsu/MirrorImage.cs index d01b7b60e..4444a19c0 100644 --- a/Projects/UOContent/Spells/Ninjitsu/MirrorImage.cs +++ b/Projects/UOContent/Spells/Ninjitsu/MirrorImage.cs @@ -12,14 +12,14 @@ namespace Server.Spells.Ninjitsu { private static readonly Dictionary m_CloneCount = new(); - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Mirror Image", null, -1, 9002 ); - public MirrorImage(Mobile caster, Item scroll) : base(caster, scroll, m_Info) + public MirrorImage(Mobile caster, Item scroll) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Ninjitsu/ShadowJump.cs b/Projects/UOContent/Spells/Ninjitsu/ShadowJump.cs index 008132b42..e8dab71e9 100644 --- a/Projects/UOContent/Spells/Ninjitsu/ShadowJump.cs +++ b/Projects/UOContent/Spells/Ninjitsu/ShadowJump.cs @@ -11,14 +11,14 @@ namespace Server.Spells.Ninjitsu { public class Shadowjump : NinjaSpell, ISpellTargetingPoint3D { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Shadowjump", null, -1, 9002 ); - public Shadowjump(Mobile caster, Item scroll) : base(caster, scroll, m_Info) + public Shadowjump(Mobile caster, Item scroll) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Second/Agility.cs b/Projects/UOContent/Spells/Second/Agility.cs index 56380d476..fbe8fa473 100644 --- a/Projects/UOContent/Spells/Second/Agility.cs +++ b/Projects/UOContent/Spells/Second/Agility.cs @@ -5,7 +5,7 @@ namespace Server.Spells.Second { public class AgilitySpell : MagerySpell, ISpellTargetingMobile { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Agility", "Ex Uus", 212, @@ -14,7 +14,7 @@ namespace Server.Spells.Second Reagent.MandrakeRoot ); - public AgilitySpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public AgilitySpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Second/Cunning.cs b/Projects/UOContent/Spells/Second/Cunning.cs index e3ad7c701..ad966c643 100644 --- a/Projects/UOContent/Spells/Second/Cunning.cs +++ b/Projects/UOContent/Spells/Second/Cunning.cs @@ -5,7 +5,7 @@ namespace Server.Spells.Second { public class CunningSpell : MagerySpell, ISpellTargetingMobile { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Cunning", "Uus Wis", 212, @@ -14,7 +14,7 @@ namespace Server.Spells.Second Reagent.Nightshade ); - public CunningSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public CunningSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Second/Cure.cs b/Projects/UOContent/Spells/Second/Cure.cs index 1b02a0240..1b0bc413e 100644 --- a/Projects/UOContent/Spells/Second/Cure.cs +++ b/Projects/UOContent/Spells/Second/Cure.cs @@ -5,7 +5,7 @@ namespace Server.Spells.Second { public class CureSpell : MagerySpell, ISpellTargetingMobile { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Cure", "An Nox", 212, @@ -14,7 +14,7 @@ namespace Server.Spells.Second Reagent.Ginseng ); - public CureSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public CureSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Second/Harm.cs b/Projects/UOContent/Spells/Second/Harm.cs index 3960d2b54..fd1d58adc 100644 --- a/Projects/UOContent/Spells/Second/Harm.cs +++ b/Projects/UOContent/Spells/Second/Harm.cs @@ -4,7 +4,7 @@ namespace Server.Spells.Second { public class HarmSpell : MagerySpell, ISpellTargetingMobile { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Harm", "An Mani", 212, @@ -13,7 +13,7 @@ namespace Server.Spells.Second Reagent.SpidersSilk ); - public HarmSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public HarmSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Second/MagicTrap.cs b/Projects/UOContent/Spells/Second/MagicTrap.cs index 5dfbc66ac..c8b2a37ec 100644 --- a/Projects/UOContent/Spells/Second/MagicTrap.cs +++ b/Projects/UOContent/Spells/Second/MagicTrap.cs @@ -5,7 +5,7 @@ namespace Server.Spells.Second { public class MagicTrapSpell : MagerySpell, ISpellTargetingItem { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Magic Trap", "In Jux", 212, @@ -15,7 +15,7 @@ namespace Server.Spells.Second Reagent.SulfurousAsh ); - public MagicTrapSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public MagicTrapSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Second/Protection.cs b/Projects/UOContent/Spells/Second/Protection.cs index 430df38b6..30fe8d194 100644 --- a/Projects/UOContent/Spells/Second/Protection.cs +++ b/Projects/UOContent/Spells/Second/Protection.cs @@ -5,7 +5,7 @@ namespace Server.Spells.Second { public class ProtectionSpell : MagerySpell { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Protection", "Uus Sanct", 236, @@ -18,7 +18,7 @@ namespace Server.Spells.Second private static readonly Dictionary> m_Table = new(); - public ProtectionSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public ProtectionSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Second/RemoveTrap.cs b/Projects/UOContent/Spells/Second/RemoveTrap.cs index a573cada7..7ff0c0005 100644 --- a/Projects/UOContent/Spells/Second/RemoveTrap.cs +++ b/Projects/UOContent/Spells/Second/RemoveTrap.cs @@ -5,7 +5,7 @@ namespace Server.Spells.Second { public class RemoveTrapSpell : MagerySpell, ISpellTargetingItem { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Remove Trap", "An Jux", 212, @@ -14,7 +14,7 @@ namespace Server.Spells.Second Reagent.SulfurousAsh ); - public RemoveTrapSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public RemoveTrapSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Second/Strength.cs b/Projects/UOContent/Spells/Second/Strength.cs index 749c624e9..536662cbd 100644 --- a/Projects/UOContent/Spells/Second/Strength.cs +++ b/Projects/UOContent/Spells/Second/Strength.cs @@ -5,7 +5,7 @@ namespace Server.Spells.Second { public class StrengthSpell : MagerySpell, ISpellTargetingMobile { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Strength", "Uus Mani", 212, @@ -14,7 +14,7 @@ namespace Server.Spells.Second Reagent.Nightshade ); - public StrengthSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public StrengthSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Seventh/ChainLightning.cs b/Projects/UOContent/Spells/Seventh/ChainLightning.cs index 7823ba97b..f036fab6d 100644 --- a/Projects/UOContent/Spells/Seventh/ChainLightning.cs +++ b/Projects/UOContent/Spells/Seventh/ChainLightning.cs @@ -6,7 +6,7 @@ namespace Server.Spells.Seventh { public class ChainLightningSpell : MagerySpell, ISpellTargetingPoint3D { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Chain Lightning", "Vas Ort Grav", 209, @@ -18,7 +18,7 @@ namespace Server.Spells.Seventh Reagent.SulfurousAsh ); - public ChainLightningSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public ChainLightningSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Seventh/EnergyField.cs b/Projects/UOContent/Spells/Seventh/EnergyField.cs index 0562fd4b0..5bee0d18c 100644 --- a/Projects/UOContent/Spells/Seventh/EnergyField.cs +++ b/Projects/UOContent/Spells/Seventh/EnergyField.cs @@ -8,7 +8,7 @@ namespace Server.Spells.Seventh { public class EnergyFieldSpell : MagerySpell, ISpellTargetingPoint3D { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Energy Field", "In Sanct Grav", 221, @@ -20,7 +20,7 @@ namespace Server.Spells.Seventh Reagent.SulfurousAsh ); - public EnergyFieldSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public EnergyFieldSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Seventh/FlameStrike.cs b/Projects/UOContent/Spells/Seventh/FlameStrike.cs index 81e1c4af2..e307f9be7 100644 --- a/Projects/UOContent/Spells/Seventh/FlameStrike.cs +++ b/Projects/UOContent/Spells/Seventh/FlameStrike.cs @@ -4,7 +4,7 @@ namespace Server.Spells.Seventh { public class FlameStrikeSpell : MagerySpell, ISpellTargetingMobile { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Flame Strike", "Kal Vas Flam", 245, @@ -13,7 +13,7 @@ namespace Server.Spells.Seventh Reagent.SulfurousAsh ); - public FlameStrikeSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public FlameStrikeSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Seventh/GateTravel.cs b/Projects/UOContent/Spells/Seventh/GateTravel.cs index 709b6d42a..258dce8a3 100644 --- a/Projects/UOContent/Spells/Seventh/GateTravel.cs +++ b/Projects/UOContent/Spells/Seventh/GateTravel.cs @@ -8,7 +8,7 @@ namespace Server.Spells.Seventh { public class GateTravelSpell : MagerySpell, IRecallSpell { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Gate Travel", "Vas Rel Por", 263, @@ -21,7 +21,7 @@ namespace Server.Spells.Seventh private readonly RunebookEntry m_Entry; public GateTravelSpell(Mobile caster, RunebookEntry entry = null, Item scroll = null) : - base(caster, scroll, m_Info) => m_Entry = entry; + base(caster, scroll, _info) => m_Entry = entry; public override SpellCircle Circle => SpellCircle.Seventh; diff --git a/Projects/UOContent/Spells/Seventh/ManaVampire.cs b/Projects/UOContent/Spells/Seventh/ManaVampire.cs index d7ec16654..15d99f19d 100644 --- a/Projects/UOContent/Spells/Seventh/ManaVampire.cs +++ b/Projects/UOContent/Spells/Seventh/ManaVampire.cs @@ -5,7 +5,7 @@ namespace Server.Spells.Seventh { public class ManaVampireSpell : MagerySpell, ISpellTargetingMobile { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Mana Vampire", "Ort Sanct", 221, @@ -16,7 +16,7 @@ namespace Server.Spells.Seventh Reagent.SpidersSilk ); - public ManaVampireSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public ManaVampireSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Seventh/MassDispel.cs b/Projects/UOContent/Spells/Seventh/MassDispel.cs index 63b4109e7..8ba30654d 100644 --- a/Projects/UOContent/Spells/Seventh/MassDispel.cs +++ b/Projects/UOContent/Spells/Seventh/MassDispel.cs @@ -6,7 +6,7 @@ namespace Server.Spells.Seventh { public class MassDispelSpell : MagerySpell, ISpellTargetingPoint3D { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Mass Dispel", "Vas An Ort", 263, @@ -17,7 +17,7 @@ namespace Server.Spells.Seventh Reagent.SulfurousAsh ); - public MassDispelSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public MassDispelSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Seventh/MeteorSwarm.cs b/Projects/UOContent/Spells/Seventh/MeteorSwarm.cs index cfc11ee54..594afccc7 100644 --- a/Projects/UOContent/Spells/Seventh/MeteorSwarm.cs +++ b/Projects/UOContent/Spells/Seventh/MeteorSwarm.cs @@ -6,7 +6,7 @@ namespace Server.Spells.Seventh { public class MeteorSwarmSpell : MagerySpell, ISpellTargetingPoint3D { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Meteor Swarm", "Flam Kal Des Ylem", 233, @@ -18,7 +18,7 @@ namespace Server.Spells.Seventh Reagent.SpidersSilk ); - public MeteorSwarmSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public MeteorSwarmSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Seventh/Polymorph.cs b/Projects/UOContent/Spells/Seventh/Polymorph.cs index a473a7e04..f53deedcd 100644 --- a/Projects/UOContent/Spells/Seventh/Polymorph.cs +++ b/Projects/UOContent/Spells/Seventh/Polymorph.cs @@ -9,7 +9,7 @@ namespace Server.Spells.Seventh { public class PolymorphSpell : MagerySpell { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Polymorph", "Vas Ylem Rel", 221, @@ -23,7 +23,7 @@ namespace Server.Spells.Seventh private readonly int m_NewBody; - public PolymorphSpell(Mobile caster, Item scroll, int body = 0) : base(caster, scroll, m_Info) => m_NewBody = body; + public PolymorphSpell(Mobile caster, Item scroll, int body = 0) : base(caster, scroll, _info) => m_NewBody = body; public override SpellCircle Circle => SpellCircle.Seventh; diff --git a/Projects/UOContent/Spells/Sixth/Dispel.cs b/Projects/UOContent/Spells/Sixth/Dispel.cs index d67753515..f4cfbd8fc 100644 --- a/Projects/UOContent/Spells/Sixth/Dispel.cs +++ b/Projects/UOContent/Spells/Sixth/Dispel.cs @@ -6,7 +6,7 @@ namespace Server.Spells.Sixth { public class DispelSpell : MagerySpell, ISpellTargetingMobile { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Dispel", "An Ort", 218, @@ -16,7 +16,7 @@ namespace Server.Spells.Sixth Reagent.SulfurousAsh ); - public DispelSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public DispelSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Sixth/EnergyBolt.cs b/Projects/UOContent/Spells/Sixth/EnergyBolt.cs index 6026fceaf..9ebcb415b 100644 --- a/Projects/UOContent/Spells/Sixth/EnergyBolt.cs +++ b/Projects/UOContent/Spells/Sixth/EnergyBolt.cs @@ -4,7 +4,7 @@ namespace Server.Spells.Sixth { public class EnergyBoltSpell : MagerySpell, ISpellTargetingMobile { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Energy Bolt", "Corp Por", 230, @@ -13,7 +13,7 @@ namespace Server.Spells.Sixth Reagent.Nightshade ); - public EnergyBoltSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public EnergyBoltSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Sixth/Explosion.cs b/Projects/UOContent/Spells/Sixth/Explosion.cs index 407699b5b..88acce5b2 100644 --- a/Projects/UOContent/Spells/Sixth/Explosion.cs +++ b/Projects/UOContent/Spells/Sixth/Explosion.cs @@ -5,7 +5,7 @@ namespace Server.Spells.Sixth { public class ExplosionSpell : MagerySpell, ISpellTargetingMobile { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Explosion", "Vas Ort Flam", 230, @@ -14,8 +14,7 @@ namespace Server.Spells.Sixth Reagent.MandrakeRoot ); - public ExplosionSpell(Mobile caster, Item scroll = null) - : base(caster, scroll, m_Info) + public ExplosionSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Sixth/Invisibility.cs b/Projects/UOContent/Spells/Sixth/Invisibility.cs index ae69a58fe..aeb42f8d0 100644 --- a/Projects/UOContent/Spells/Sixth/Invisibility.cs +++ b/Projects/UOContent/Spells/Sixth/Invisibility.cs @@ -9,7 +9,7 @@ namespace Server.Spells.Sixth { public class InvisibilitySpell : MagerySpell, ISpellTargetingMobile { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Invisibility", "An Lor Xen", 206, @@ -20,7 +20,7 @@ namespace Server.Spells.Sixth private static readonly Dictionary m_Table = new(); - public InvisibilitySpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public InvisibilitySpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Sixth/Mark.cs b/Projects/UOContent/Spells/Sixth/Mark.cs index 076998990..b35a25784 100644 --- a/Projects/UOContent/Spells/Sixth/Mark.cs +++ b/Projects/UOContent/Spells/Sixth/Mark.cs @@ -6,7 +6,7 @@ namespace Server.Spells.Sixth { public class MarkSpell : MagerySpell, ISpellTargetingItem { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Mark", "Kal Por Ylem", 218, @@ -16,7 +16,7 @@ namespace Server.Spells.Sixth Reagent.MandrakeRoot ); - public MarkSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public MarkSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Sixth/MassCurse.cs b/Projects/UOContent/Spells/Sixth/MassCurse.cs index 3130a9817..375789e41 100644 --- a/Projects/UOContent/Spells/Sixth/MassCurse.cs +++ b/Projects/UOContent/Spells/Sixth/MassCurse.cs @@ -4,7 +4,7 @@ namespace Server.Spells.Sixth { public class MassCurseSpell : MagerySpell, ISpellTargetingPoint3D { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Mass Curse", "Vas Des Sanct", 218, @@ -16,7 +16,7 @@ namespace Server.Spells.Sixth Reagent.SulfurousAsh ); - public MassCurseSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public MassCurseSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Sixth/ParalyzeField.cs b/Projects/UOContent/Spells/Sixth/ParalyzeField.cs index 73110b457..cea6f4e50 100644 --- a/Projects/UOContent/Spells/Sixth/ParalyzeField.cs +++ b/Projects/UOContent/Spells/Sixth/ParalyzeField.cs @@ -8,7 +8,7 @@ namespace Server.Spells.Sixth { public class ParalyzeFieldSpell : MagerySpell, ISpellTargetingPoint3D { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Paralyze Field", "In Ex Grav", 230, @@ -19,7 +19,7 @@ namespace Server.Spells.Sixth Reagent.SpidersSilk ); - public ParalyzeFieldSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public ParalyzeFieldSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Sixth/Reveal.cs b/Projects/UOContent/Spells/Sixth/Reveal.cs index 86576fa0b..a6793b1e5 100644 --- a/Projects/UOContent/Spells/Sixth/Reveal.cs +++ b/Projects/UOContent/Spells/Sixth/Reveal.cs @@ -5,7 +5,7 @@ namespace Server.Spells.Sixth { public class RevealSpell : MagerySpell, ISpellTargetingPoint3D { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Reveal", "Wis Quas", 206, @@ -14,7 +14,7 @@ namespace Server.Spells.Sixth Reagent.SulfurousAsh ); - public RevealSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public RevealSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Spellweaving/ArcaneCircle.cs b/Projects/UOContent/Spells/Spellweaving/ArcaneCircle.cs index b55588a0e..5399efdec 100644 --- a/Projects/UOContent/Spells/Spellweaving/ArcaneCircle.cs +++ b/Projects/UOContent/Spells/Spellweaving/ArcaneCircle.cs @@ -7,14 +7,14 @@ namespace Server.Spells.Spellweaving { public class ArcaneCircleSpell : ArcanistSpell { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Arcane Circle", "Myrshalee", -1 ); public ArcaneCircleSpell(Mobile caster, Item scroll = null) - : base(caster, scroll, m_Info) + : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Spellweaving/AttuneWeapon.cs b/Projects/UOContent/Spells/Spellweaving/AttuneWeapon.cs index ce1db2da5..fcd22bc9b 100644 --- a/Projects/UOContent/Spells/Spellweaving/AttuneWeapon.cs +++ b/Projects/UOContent/Spells/Spellweaving/AttuneWeapon.cs @@ -5,7 +5,7 @@ namespace Server.Spells.Spellweaving { public class AttuneWeaponSpell : ArcanistSpell { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Attune Weapon", "Haeldril", -1 @@ -14,7 +14,7 @@ namespace Server.Spells.Spellweaving private static readonly Dictionary m_Table = new(); public AttuneWeaponSpell(Mobile caster, Item scroll = null) - : base(caster, scroll, m_Info) + : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Spellweaving/EssenceOfWind.cs b/Projects/UOContent/Spells/Spellweaving/EssenceOfWind.cs index 0292dea1d..7f676a578 100644 --- a/Projects/UOContent/Spells/Spellweaving/EssenceOfWind.cs +++ b/Projects/UOContent/Spells/Spellweaving/EssenceOfWind.cs @@ -5,11 +5,11 @@ namespace Server.Spells.Spellweaving { public class EssenceOfWindSpell : ArcanistSpell { - private static readonly SpellInfo m_Info = new("Essence of Wind", "Anathrae", -1); + private static readonly SpellInfo _info = new("Essence of Wind", "Anathrae", -1); private static readonly Dictionary m_Table = new(); - public EssenceOfWindSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public EssenceOfWindSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Spellweaving/EtherealVoyage.cs b/Projects/UOContent/Spells/Spellweaving/EtherealVoyage.cs index a68b50207..de9fbaf2b 100644 --- a/Projects/UOContent/Spells/Spellweaving/EtherealVoyage.cs +++ b/Projects/UOContent/Spells/Spellweaving/EtherealVoyage.cs @@ -4,14 +4,14 @@ namespace Server.Spells.Spellweaving { public class EtherealVoyageSpell : ArcaneForm { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Ethereal Voyage", "Orlavdra", -1 ); public EtherealVoyageSpell(Mobile caster, Item scroll = null) - : base(caster, scroll, m_Info) + : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Spellweaving/GiftOfLife.cs b/Projects/UOContent/Spells/Spellweaving/GiftOfLife.cs index 8d27cd5c6..9f0b2247b 100644 --- a/Projects/UOContent/Spells/Spellweaving/GiftOfLife.cs +++ b/Projects/UOContent/Spells/Spellweaving/GiftOfLife.cs @@ -8,7 +8,7 @@ namespace Server.Spells.Spellweaving { public class GiftOfLifeSpell : ArcanistSpell, ISpellTargetingMobile { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Gift of Life", "Illorae", -1 @@ -17,7 +17,7 @@ namespace Server.Spells.Spellweaving private static readonly Dictionary m_Table = new(); public GiftOfLifeSpell(Mobile caster, Item scroll = null) - : base(caster, scroll, m_Info) + : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Spellweaving/GiftOfRenewal.cs b/Projects/UOContent/Spells/Spellweaving/GiftOfRenewal.cs index 692c909a4..5bf8db8ac 100644 --- a/Projects/UOContent/Spells/Spellweaving/GiftOfRenewal.cs +++ b/Projects/UOContent/Spells/Spellweaving/GiftOfRenewal.cs @@ -6,7 +6,7 @@ namespace Server.Spells.Spellweaving { public class GiftOfRenewalSpell : ArcanistSpell, ISpellTargetingMobile { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Gift of Renewal", "Olorisstra", -1 @@ -15,7 +15,7 @@ namespace Server.Spells.Spellweaving private static readonly Dictionary m_Table = new(); public GiftOfRenewalSpell(Mobile caster, Item scroll = null) - : base(caster, scroll, m_Info) + : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Spellweaving/ImmolatingWeapon.cs b/Projects/UOContent/Spells/Spellweaving/ImmolatingWeapon.cs index 929f077f8..10ce95d8d 100644 --- a/Projects/UOContent/Spells/Spellweaving/ImmolatingWeapon.cs +++ b/Projects/UOContent/Spells/Spellweaving/ImmolatingWeapon.cs @@ -6,7 +6,7 @@ namespace Server.Spells.Spellweaving { public class ImmolatingWeaponSpell : ArcanistSpell { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Immolating Weapon", "Thalshara", -1 @@ -15,7 +15,7 @@ namespace Server.Spells.Spellweaving private static readonly Dictionary m_Table = new(); public ImmolatingWeaponSpell(Mobile caster, Item scroll = null) - : base(caster, scroll, m_Info) + : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Spellweaving/NatureFury.cs b/Projects/UOContent/Spells/Spellweaving/NatureFury.cs index 4216be3e1..bd8fe059d 100644 --- a/Projects/UOContent/Spells/Spellweaving/NatureFury.cs +++ b/Projects/UOContent/Spells/Spellweaving/NatureFury.cs @@ -7,7 +7,7 @@ namespace Server.Spells.Spellweaving { public class NatureFurySpell : ArcanistSpell, ISpellTargetingPoint3D { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Nature's Fury", "Rauvvrae", -1, @@ -15,7 +15,7 @@ namespace Server.Spells.Spellweaving ); public NatureFurySpell(Mobile caster, Item scroll = null) - : base(caster, scroll, m_Info) + : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Spellweaving/ReaperForm.cs b/Projects/UOContent/Spells/Spellweaving/ReaperForm.cs index a98eeeb66..3486393a2 100644 --- a/Projects/UOContent/Spells/Spellweaving/ReaperForm.cs +++ b/Projects/UOContent/Spells/Spellweaving/ReaperForm.cs @@ -5,9 +5,9 @@ namespace Server.Spells.Spellweaving { public class ReaperFormSpell : ArcaneForm { - private static readonly SpellInfo m_Info = new("Reaper Form", "Tarisstree", -1); + private static readonly SpellInfo _info = new("Reaper Form", "Tarisstree", -1); - public ReaperFormSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public ReaperFormSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Spellweaving/SummonFey.cs b/Projects/UOContent/Spells/Spellweaving/SummonFey.cs index 5e2b13f3f..d9daf6210 100644 --- a/Projects/UOContent/Spells/Spellweaving/SummonFey.cs +++ b/Projects/UOContent/Spells/Spellweaving/SummonFey.cs @@ -6,14 +6,14 @@ namespace Server.Spells.Spellweaving { public class SummonFeySpell : ArcaneSummon { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Summon Fey", "Alalithra", -1 ); public SummonFeySpell(Mobile caster, Item scroll = null) - : base(caster, scroll, m_Info) + : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Spellweaving/SummonFiend.cs b/Projects/UOContent/Spells/Spellweaving/SummonFiend.cs index a4341304d..1e1d35c60 100644 --- a/Projects/UOContent/Spells/Spellweaving/SummonFiend.cs +++ b/Projects/UOContent/Spells/Spellweaving/SummonFiend.cs @@ -6,14 +6,14 @@ namespace Server.Spells.Spellweaving { public class SummonFiendSpell : ArcaneSummon { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Summon Fiend", "Nylisstra", -1 ); public SummonFiendSpell(Mobile caster, Item scroll = null) - : base(caster, scroll, m_Info) + : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Spellweaving/Thunderstorm.cs b/Projects/UOContent/Spells/Spellweaving/Thunderstorm.cs index 38fa38cff..c69e01f50 100644 --- a/Projects/UOContent/Spells/Spellweaving/Thunderstorm.cs +++ b/Projects/UOContent/Spells/Spellweaving/Thunderstorm.cs @@ -5,7 +5,7 @@ namespace Server.Spells.Spellweaving { public class ThunderstormSpell : ArcanistSpell { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Thunderstorm", "Erelonia", -1 @@ -14,7 +14,7 @@ namespace Server.Spells.Spellweaving private static readonly Dictionary m_Table = new(); public ThunderstormSpell(Mobile caster, Item scroll = null) - : base(caster, scroll, m_Info) + : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Spellweaving/WordOfDeath.cs b/Projects/UOContent/Spells/Spellweaving/WordOfDeath.cs index bed32e92f..7cdd76846 100644 --- a/Projects/UOContent/Spells/Spellweaving/WordOfDeath.cs +++ b/Projects/UOContent/Spells/Spellweaving/WordOfDeath.cs @@ -5,9 +5,9 @@ namespace Server.Spells.Spellweaving { public class WordOfDeathSpell : ArcanistSpell, ISpellTargetingMobile { - private static readonly SpellInfo m_Info = new("Word of Death", "Nyraxle", -1); + private static readonly SpellInfo _info = new("Word of Death", "Nyraxle", -1); - public WordOfDeathSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public WordOfDeathSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Third/Bless.cs b/Projects/UOContent/Spells/Third/Bless.cs index 89862201e..3c694cc69 100644 --- a/Projects/UOContent/Spells/Third/Bless.cs +++ b/Projects/UOContent/Spells/Third/Bless.cs @@ -5,7 +5,7 @@ namespace Server.Spells.Third { public class BlessSpell : MagerySpell, ISpellTargetingMobile { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Bless", "Rel Sanct", 203, @@ -14,7 +14,7 @@ namespace Server.Spells.Third Reagent.MandrakeRoot ); - public BlessSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public BlessSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Third/Fireball.cs b/Projects/UOContent/Spells/Third/Fireball.cs index 4c650115d..298dc2f0a 100644 --- a/Projects/UOContent/Spells/Third/Fireball.cs +++ b/Projects/UOContent/Spells/Third/Fireball.cs @@ -4,7 +4,7 @@ namespace Server.Spells.Third { public class FireballSpell : MagerySpell, ISpellTargetingMobile { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Fireball", "Vas Flam", 203, @@ -12,7 +12,7 @@ namespace Server.Spells.Third Reagent.BlackPearl ); - public FireballSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public FireballSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Third/MagicLock.cs b/Projects/UOContent/Spells/Third/MagicLock.cs index 13a7ca597..040976001 100644 --- a/Projects/UOContent/Spells/Third/MagicLock.cs +++ b/Projects/UOContent/Spells/Third/MagicLock.cs @@ -7,7 +7,7 @@ namespace Server.Spells.Third { public class MagicLockSpell : MagerySpell, ISpellTargetingItem { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Magic Lock", "An Por", 215, @@ -17,7 +17,7 @@ namespace Server.Spells.Third Reagent.SulfurousAsh ); - public MagicLockSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public MagicLockSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Third/Poison.cs b/Projects/UOContent/Spells/Third/Poison.cs index 24180f5cb..71cd43495 100644 --- a/Projects/UOContent/Spells/Third/Poison.cs +++ b/Projects/UOContent/Spells/Third/Poison.cs @@ -5,7 +5,7 @@ namespace Server.Spells.Third { public class PoisonSpell : MagerySpell, ISpellTargetingMobile { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Poison", "In Nox", 203, @@ -13,7 +13,7 @@ namespace Server.Spells.Third Reagent.Nightshade ); - public PoisonSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public PoisonSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Third/Telekinesis.cs b/Projects/UOContent/Spells/Third/Telekinesis.cs index 94728d372..37d92c4d9 100644 --- a/Projects/UOContent/Spells/Third/Telekinesis.cs +++ b/Projects/UOContent/Spells/Third/Telekinesis.cs @@ -5,7 +5,7 @@ namespace Server.Spells.Third { public class TelekinesisSpell : MagerySpell, ISpellTargetingItem { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Telekinesis", "Ort Por Ylem", 203, @@ -14,7 +14,7 @@ namespace Server.Spells.Third Reagent.MandrakeRoot ); - public TelekinesisSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public TelekinesisSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Third/Teleport.cs b/Projects/UOContent/Spells/Third/Teleport.cs index 2ea13dfa7..2e1981525 100644 --- a/Projects/UOContent/Spells/Third/Teleport.cs +++ b/Projects/UOContent/Spells/Third/Teleport.cs @@ -11,7 +11,7 @@ namespace Server.Spells.Third { public class TeleportSpell : MagerySpell, ISpellTargetingPoint3D { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Teleport", "Rel Por", 215, @@ -20,7 +20,7 @@ namespace Server.Spells.Third Reagent.MandrakeRoot ); - public TeleportSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public TeleportSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Third/Unlock.cs b/Projects/UOContent/Spells/Third/Unlock.cs index 284e6693a..d303b3151 100644 --- a/Projects/UOContent/Spells/Third/Unlock.cs +++ b/Projects/UOContent/Spells/Third/Unlock.cs @@ -7,7 +7,7 @@ namespace Server.Spells.Third { public class UnlockSpell : MagerySpell, ISpellTargetingPoint3D { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Unlock Spell", "Ex Por", 215, @@ -16,7 +16,7 @@ namespace Server.Spells.Third Reagent.SulfurousAsh ); - public UnlockSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public UnlockSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } diff --git a/Projects/UOContent/Spells/Third/WallOfStone.cs b/Projects/UOContent/Spells/Third/WallOfStone.cs index c03f403e5..f0f1ec926 100644 --- a/Projects/UOContent/Spells/Third/WallOfStone.cs +++ b/Projects/UOContent/Spells/Third/WallOfStone.cs @@ -7,7 +7,7 @@ namespace Server.Spells.Third { public class WallOfStoneSpell : MagerySpell, ISpellTargetingPoint3D { - private static readonly SpellInfo m_Info = new( + private static readonly SpellInfo _info = new( "Wall of Stone", "In Sanct Ylem", 227, @@ -17,7 +17,7 @@ namespace Server.Spells.Third Reagent.Garlic ); - public WallOfStoneSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) + public WallOfStoneSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { } From 5df7bf6a7572fb0011a0f65408e1bc3f138af3cc Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 14 Nov 2021 18:45:16 -0800 Subject: [PATCH 010/213] fix: Removes duplicative spell checks (#849) --- Projects/Server/Targeting/Target.cs | 55 +++++++++---------- Projects/UOContent/Commands/Handlers.cs | 2 - Projects/UOContent/Compression/TarArchive.cs | 5 -- Projects/UOContent/Compression/ZstdArchive.cs | 1 - .../UOContent/Spells/Eighth/Resurrection.cs | 11 +--- .../UOContent/Spells/Fifth/DispelField.cs | 10 +--- Projects/UOContent/Spells/Fifth/MindBlast.cs | 11 +--- Projects/UOContent/Spells/Fifth/Paralyze.cs | 12 +--- .../UOContent/Spells/Fifth/PoisonField.cs | 6 +- Projects/UOContent/Spells/First/Clumsy.cs | 11 +--- Projects/UOContent/Spells/First/Feeblemind.cs | 11 +--- Projects/UOContent/Spells/First/Heal.cs | 11 +--- Projects/UOContent/Spells/First/MagicArrow.cs | 11 +--- Projects/UOContent/Spells/First/Weaken.cs | 11 +--- Projects/UOContent/Spells/Fourth/ArchCure.cs | 6 +- .../UOContent/Spells/Fourth/ArchProtection.cs | 6 +- Projects/UOContent/Spells/Fourth/Curse.cs | 15 +---- Projects/UOContent/Spells/Fourth/FireField.cs | 6 +- .../UOContent/Spells/Fourth/GreaterHeal.cs | 11 +--- Projects/UOContent/Spells/Fourth/Lightning.cs | 11 +--- Projects/UOContent/Spells/Fourth/ManaDrain.cs | 11 +--- .../Spells/Mysticism/SpellPlagueSpell.cs | 6 +- Projects/UOContent/Spells/Second/Agility.cs | 11 +--- Projects/UOContent/Spells/Second/Cunning.cs | 11 +--- Projects/UOContent/Spells/Second/Cure.cs | 11 +--- Projects/UOContent/Spells/Second/Harm.cs | 11 +--- Projects/UOContent/Spells/Second/MagicTrap.cs | 4 -- .../UOContent/Spells/Second/RemoveTrap.cs | 8 +-- Projects/UOContent/Spells/Second/Strength.cs | 11 +--- .../Spells/Seventh/ChainLightning.cs | 6 +- .../UOContent/Spells/Seventh/EnergyField.cs | 6 +- .../UOContent/Spells/Seventh/FlameStrike.cs | 11 +--- .../UOContent/Spells/Seventh/ManaVampire.cs | 11 +--- .../UOContent/Spells/Seventh/MassDispel.cs | 6 +- .../UOContent/Spells/Seventh/MeteorSwarm.cs | 6 +- Projects/UOContent/Spells/Sixth/Dispel.cs | 11 +--- Projects/UOContent/Spells/Sixth/EnergyBolt.cs | 11 +--- Projects/UOContent/Spells/Sixth/Explosion.cs | 11 +--- .../UOContent/Spells/Sixth/Invisibility.cs | 11 +--- Projects/UOContent/Spells/Sixth/Mark.cs | 17 ++---- Projects/UOContent/Spells/Sixth/MassCurse.cs | 6 +- .../UOContent/Spells/Sixth/ParalyzeField.cs | 6 +- Projects/UOContent/Spells/Sixth/Reveal.cs | 6 +- .../Spells/Spellweaving/GiftOfLife.cs | 10 +--- .../Spells/Spellweaving/GiftOfRenewal.cs | 11 +--- .../Spells/Spellweaving/WordOfDeath.cs | 11 +--- Projects/UOContent/Spells/Third/Bless.cs | 11 +--- Projects/UOContent/Spells/Third/Fireball.cs | 11 +--- Projects/UOContent/Spells/Third/Poison.cs | 11 +--- .../UOContent/Spells/Third/WallOfStone.cs | 6 +- 50 files changed, 78 insertions(+), 425 deletions(-) diff --git a/Projects/Server/Targeting/Target.cs b/Projects/Server/Targeting/Target.cs index d0035ed3b..e60231322 100644 --- a/Projects/Server/Targeting/Target.cs +++ b/Projects/Server/Targeting/Target.cs @@ -164,36 +164,33 @@ namespace Server.Targeting { OnTargetOutOfRange(from, targeted); } - else + else if (!from.CanSee(targeted)) { - if (!from.CanSee(targeted)) - { - OnCantSeeTarget(from, targeted); - } - else if (CheckLOS && !from.InLOS(targeted)) - { - OnTargetOutOfLOS(from, targeted); - } - else if (item?.InSecureTrade == true) - { - OnTargetInSecureTrade(from, targeted); - } - else if (item?.IsAccessibleTo(from) == false) - { - OnTargetNotAccessible(from, targeted); - } - else if (item?.CheckTarget(from, this, targeted) == false) - { - OnTargetUntargetable(from, targeted); - } - else if (mobile?.CheckTarget(from, this, mobile) == false) - { - OnTargetUntargetable(from, mobile); - } - else if (from.Region.OnTarget(from, this, targeted)) - { - OnTarget(from, targeted); - } + OnCantSeeTarget(from, targeted); + } + else if (CheckLOS && !from.InLOS(targeted)) + { + OnTargetOutOfLOS(from, targeted); + } + else if (item?.InSecureTrade == true) + { + OnTargetInSecureTrade(from, targeted); + } + else if (item?.IsAccessibleTo(from) == false) + { + OnTargetNotAccessible(from, targeted); + } + else if (item?.CheckTarget(from, this, targeted) == false) + { + OnTargetUntargetable(from, targeted); + } + else if (mobile?.CheckTarget(from, this, mobile) == false) + { + OnTargetUntargetable(from, mobile); + } + else if (from.Region.OnTarget(from, this, targeted)) + { + OnTarget(from, targeted); } OnTargetFinish(from); diff --git a/Projects/UOContent/Commands/Handlers.cs b/Projects/UOContent/Commands/Handlers.cs index 867ed68d6..b289f9acd 100644 --- a/Projects/UOContent/Commands/Handlers.cs +++ b/Projects/UOContent/Commands/Handlers.cs @@ -7,11 +7,9 @@ using Server.Gumps; using Server.Items; using Server.Menus.ItemLists; using Server.Menus.Questions; -using Server.Misc; using Server.Mobiles; using Server.Multis; using Server.Network; -using Server.Saves; using Server.Spells; using Server.Targeting; using Server.Targets; diff --git a/Projects/UOContent/Compression/TarArchive.cs b/Projects/UOContent/Compression/TarArchive.cs index 69083e509..4905a3683 100755 --- a/Projects/UOContent/Compression/TarArchive.cs +++ b/Projects/UOContent/Compression/TarArchive.cs @@ -1,14 +1,9 @@ using System; -using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.IO.Compression; -using System.Net; using System.Net.Http; -using System.Text.Json; -using System.Threading; -using System.Threading.Tasks; using Server.Buffers; namespace Server.Compression diff --git a/Projects/UOContent/Compression/ZstdArchive.cs b/Projects/UOContent/Compression/ZstdArchive.cs index a1f1fee2c..35fd533d5 100755 --- a/Projects/UOContent/Compression/ZstdArchive.cs +++ b/Projects/UOContent/Compression/ZstdArchive.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; diff --git a/Projects/UOContent/Spells/Eighth/Resurrection.cs b/Projects/UOContent/Spells/Eighth/Resurrection.cs index 77fcc0afb..c485850fa 100644 --- a/Projects/UOContent/Spells/Eighth/Resurrection.cs +++ b/Projects/UOContent/Spells/Eighth/Resurrection.cs @@ -24,16 +24,7 @@ namespace Server.Spells.Eighth public void Target(Mobile m) { - if (m == null) - { - return; - } - - if (!Caster.CanSee(m)) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. - } - else if (m == Caster) + if (m == Caster) { Caster.SendLocalizedMessage(501039); // Thou can not resurrect thyself. } diff --git a/Projects/UOContent/Spells/Fifth/DispelField.cs b/Projects/UOContent/Spells/Fifth/DispelField.cs index e05b2718c..cd7c3240c 100644 --- a/Projects/UOContent/Spells/Fifth/DispelField.cs +++ b/Projects/UOContent/Spells/Fifth/DispelField.cs @@ -25,15 +25,7 @@ namespace Server.Spells.Fifth public void Target(Item item) { - if (item == null) - { - Caster.SendLocalizedMessage(1005049); // That cannot be dispelled. - } - else if (!Caster.CanSee(item)) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. - } - else if (!item.GetType().IsDefined(typeof(DispellableFieldAttribute), false)) + if (!item.GetType().IsDefined(typeof(DispellableFieldAttribute), false)) { Caster.SendLocalizedMessage(1005049); // That cannot be dispelled. } diff --git a/Projects/UOContent/Spells/Fifth/MindBlast.cs b/Projects/UOContent/Spells/Fifth/MindBlast.cs index 7f1b6945d..a5e2644e0 100644 --- a/Projects/UOContent/Spells/Fifth/MindBlast.cs +++ b/Projects/UOContent/Spells/Fifth/MindBlast.cs @@ -30,16 +30,7 @@ namespace Server.Spells.Fifth public void Target(Mobile m) { - if (m == null) - { - return; - } - - if (!Caster.CanSee(m)) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. - } - else if (Core.AOS) + if (Core.AOS) { if (Caster.CanBeHarmful(m) && CheckSequence()) { diff --git a/Projects/UOContent/Spells/Fifth/Paralyze.cs b/Projects/UOContent/Spells/Fifth/Paralyze.cs index b7dc8c20d..fcc12f643 100644 --- a/Projects/UOContent/Spells/Fifth/Paralyze.cs +++ b/Projects/UOContent/Spells/Fifth/Paralyze.cs @@ -25,17 +25,7 @@ namespace Server.Spells.Fifth public void Target(Mobile m) { - if (m == null) - { - return; - } - - if (!Caster.CanSee(m)) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. - } - else if (Core.AOS && (m.Frozen || m.Paralyzed || - m.Spell?.IsCasting == true && !(m.Spell is PaladinSpell))) + if (Core.AOS && (m.Frozen || m.Paralyzed || m.Spell?.IsCasting == true && m.Spell is not PaladinSpell)) { Caster.SendLocalizedMessage(1061923); // The target is already frozen. } diff --git a/Projects/UOContent/Spells/Fifth/PoisonField.cs b/Projects/UOContent/Spells/Fifth/PoisonField.cs index f08d8ca42..1c7ceb92a 100644 --- a/Projects/UOContent/Spells/Fifth/PoisonField.cs +++ b/Projects/UOContent/Spells/Fifth/PoisonField.cs @@ -28,11 +28,7 @@ namespace Server.Spells.Fifth public void Target(IPoint3D p) { - if (!Caster.CanSee(p)) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. - } - else if (SpellHelper.CheckTown(p, Caster) && CheckSequence()) + if (SpellHelper.CheckTown(p, Caster) && CheckSequence()) { SpellHelper.Turn(Caster, p); diff --git a/Projects/UOContent/Spells/First/Clumsy.cs b/Projects/UOContent/Spells/First/Clumsy.cs index e47ddbe16..e777ea455 100644 --- a/Projects/UOContent/Spells/First/Clumsy.cs +++ b/Projects/UOContent/Spells/First/Clumsy.cs @@ -21,16 +21,7 @@ namespace Server.Spells.First public void Target(Mobile m) { - if (m == null) - { - return; - } - - if (!Caster.CanSee(m)) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. - } - else if (CheckHSequence(m)) + if (CheckHSequence(m)) { SpellHelper.Turn(Caster, m); diff --git a/Projects/UOContent/Spells/First/Feeblemind.cs b/Projects/UOContent/Spells/First/Feeblemind.cs index 22a06ef38..ac339bca6 100644 --- a/Projects/UOContent/Spells/First/Feeblemind.cs +++ b/Projects/UOContent/Spells/First/Feeblemind.cs @@ -21,16 +21,7 @@ namespace Server.Spells.First public void Target(Mobile m) { - if (m == null) - { - return; - } - - if (!Caster.CanSee(m)) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. - } - else if (CheckHSequence(m)) + if (CheckHSequence(m)) { SpellHelper.Turn(Caster, m); diff --git a/Projects/UOContent/Spells/First/Heal.cs b/Projects/UOContent/Spells/First/Heal.cs index efde53803..1379759c5 100644 --- a/Projects/UOContent/Spells/First/Heal.cs +++ b/Projects/UOContent/Spells/First/Heal.cs @@ -26,16 +26,7 @@ namespace Server.Spells.First public void Target(Mobile m) { - if (m == null) - { - return; - } - - if (!Caster.CanSee(m)) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. - } - else if (m.IsDeadBondedPet) + if (m.IsDeadBondedPet) { Caster.SendLocalizedMessage(1060177); // You cannot heal a creature that is already dead! } diff --git a/Projects/UOContent/Spells/First/MagicArrow.cs b/Projects/UOContent/Spells/First/MagicArrow.cs index e8922739d..02f4de6e7 100644 --- a/Projects/UOContent/Spells/First/MagicArrow.cs +++ b/Projects/UOContent/Spells/First/MagicArrow.cs @@ -24,16 +24,7 @@ namespace Server.Spells.First public void Target(Mobile m) { - if (m == null) - { - return; - } - - if (!Caster.CanSee(m)) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. - } - else if (CheckHSequence(m)) + if (CheckHSequence(m)) { var source = Caster; diff --git a/Projects/UOContent/Spells/First/Weaken.cs b/Projects/UOContent/Spells/First/Weaken.cs index 3fcaf4bbe..cdac84af0 100644 --- a/Projects/UOContent/Spells/First/Weaken.cs +++ b/Projects/UOContent/Spells/First/Weaken.cs @@ -21,16 +21,7 @@ namespace Server.Spells.First public void Target(Mobile m) { - if (m == null) - { - return; - } - - if (!Caster.CanSee(m)) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. - } - else if (CheckHSequence(m)) + if (CheckHSequence(m)) { SpellHelper.Turn(Caster, m); diff --git a/Projects/UOContent/Spells/Fourth/ArchCure.cs b/Projects/UOContent/Spells/Fourth/ArchCure.cs index f2b2bf95e..9b618138f 100644 --- a/Projects/UOContent/Spells/Fourth/ArchCure.cs +++ b/Projects/UOContent/Spells/Fourth/ArchCure.cs @@ -29,11 +29,7 @@ namespace Server.Spells.Fourth public void Target(IPoint3D p) { - if (!Caster.CanSee(p)) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. - } - else if (CheckSequence()) + if (CheckSequence()) { SpellHelper.Turn(Caster, p); diff --git a/Projects/UOContent/Spells/Fourth/ArchProtection.cs b/Projects/UOContent/Spells/Fourth/ArchProtection.cs index 916c9643e..a9ae7f7bb 100644 --- a/Projects/UOContent/Spells/Fourth/ArchProtection.cs +++ b/Projects/UOContent/Spells/Fourth/ArchProtection.cs @@ -30,11 +30,7 @@ namespace Server.Spells.Fourth public void Target(IPoint3D p) { - if (!Caster.CanSee(p)) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. - } - else if (CheckSequence()) + if (CheckSequence()) { SpellHelper.Turn(Caster, p); diff --git a/Projects/UOContent/Spells/Fourth/Curse.cs b/Projects/UOContent/Spells/Fourth/Curse.cs index a78c32e76..84a076e3d 100644 --- a/Projects/UOContent/Spells/Fourth/Curse.cs +++ b/Projects/UOContent/Spells/Fourth/Curse.cs @@ -25,16 +25,7 @@ namespace Server.Spells.Fourth public void Target(Mobile m) { - if (m == null) - { - return; - } - - if (!Caster.CanSee(m)) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. - } - else if (CheckHSequence(m)) + if (CheckHSequence(m)) { SpellHelper.Turn(Caster, m); @@ -46,8 +37,8 @@ namespace Server.Spells.Fourth SpellHelper.AddStatCurse(Caster, m, StatType.Int); SpellHelper.DisableSkillCheck = false; - if (Caster.Player && m.Player /*&& Caster != m */ && !UnderEffect(m) - ) // On OSI you CAN curse yourself and get this effect. + // On OSI you CAN curse yourself and get this effect. + if (Caster.Player && m.Player /*&& Caster != m */ && !UnderEffect(m)) { var duration = SpellHelper.GetDuration(Caster, m); m_UnderEffect.Add(m); diff --git a/Projects/UOContent/Spells/Fourth/FireField.cs b/Projects/UOContent/Spells/Fourth/FireField.cs index cd4934744..c06739a78 100644 --- a/Projects/UOContent/Spells/Fourth/FireField.cs +++ b/Projects/UOContent/Spells/Fourth/FireField.cs @@ -28,11 +28,7 @@ namespace Server.Spells.Fourth public void Target(IPoint3D p) { - if (!Caster.CanSee(p)) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. - } - else if (SpellHelper.CheckTown(p, Caster) && CheckSequence()) + if (SpellHelper.CheckTown(p, Caster) && CheckSequence()) { SpellHelper.Turn(Caster, p); diff --git a/Projects/UOContent/Spells/Fourth/GreaterHeal.cs b/Projects/UOContent/Spells/Fourth/GreaterHeal.cs index 36647df92..4c02942f4 100644 --- a/Projects/UOContent/Spells/Fourth/GreaterHeal.cs +++ b/Projects/UOContent/Spells/Fourth/GreaterHeal.cs @@ -27,16 +27,7 @@ namespace Server.Spells.Fourth public void Target(Mobile m) { - if (m == null) - { - return; - } - - if (!Caster.CanSee(m)) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. - } - else if (m is BaseCreature creature && creature.IsAnimatedDead) + if (m is BaseCreature creature && creature.IsAnimatedDead) { Caster.SendLocalizedMessage(1061654); // You cannot heal that which is not alive. } diff --git a/Projects/UOContent/Spells/Fourth/Lightning.cs b/Projects/UOContent/Spells/Fourth/Lightning.cs index badf7db64..63eb3455c 100644 --- a/Projects/UOContent/Spells/Fourth/Lightning.cs +++ b/Projects/UOContent/Spells/Fourth/Lightning.cs @@ -23,16 +23,7 @@ namespace Server.Spells.Fourth public void Target(Mobile m) { - if (m == null) - { - return; - } - - if (!Caster.CanSee(m)) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. - } - else if (CheckHSequence(m)) + if (CheckHSequence(m)) { SpellHelper.Turn(Caster, m); diff --git a/Projects/UOContent/Spells/Fourth/ManaDrain.cs b/Projects/UOContent/Spells/Fourth/ManaDrain.cs index e06997783..52bd11a8e 100644 --- a/Projects/UOContent/Spells/Fourth/ManaDrain.cs +++ b/Projects/UOContent/Spells/Fourth/ManaDrain.cs @@ -26,16 +26,7 @@ namespace Server.Spells.Fourth public void Target(Mobile m) { - if (m == null) - { - return; - } - - if (!Caster.CanSee(m)) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. - } - else if (CheckHSequence(m)) + if (CheckHSequence(m)) { SpellHelper.Turn(Caster, m); diff --git a/Projects/UOContent/Spells/Mysticism/SpellPlagueSpell.cs b/Projects/UOContent/Spells/Mysticism/SpellPlagueSpell.cs index a5f47d3c4..a02032856 100644 --- a/Projects/UOContent/Spells/Mysticism/SpellPlagueSpell.cs +++ b/Projects/UOContent/Spells/Mysticism/SpellPlagueSpell.cs @@ -41,11 +41,7 @@ namespace Server.Spells.Mysticism public void Target(Mobile targeted) { - if (!Caster.CanSee(targeted)) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. - } - else if (CheckHSequence(targeted)) + if (CheckHSequence(targeted)) { SpellHelper.Turn(Caster, targeted); diff --git a/Projects/UOContent/Spells/Second/Agility.cs b/Projects/UOContent/Spells/Second/Agility.cs index fbe8fa473..c7843437f 100644 --- a/Projects/UOContent/Spells/Second/Agility.cs +++ b/Projects/UOContent/Spells/Second/Agility.cs @@ -22,16 +22,7 @@ namespace Server.Spells.Second public void Target(Mobile m) { - if (m == null) - { - return; - } - - if (!Caster.CanSee(m)) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. - } - else if (CheckBSequence(m)) + if (CheckBSequence(m)) { SpellHelper.Turn(Caster, m); diff --git a/Projects/UOContent/Spells/Second/Cunning.cs b/Projects/UOContent/Spells/Second/Cunning.cs index ad966c643..353ff9715 100644 --- a/Projects/UOContent/Spells/Second/Cunning.cs +++ b/Projects/UOContent/Spells/Second/Cunning.cs @@ -22,16 +22,7 @@ namespace Server.Spells.Second public void Target(Mobile m) { - if (m == null) - { - return; - } - - if (!Caster.CanSee(m)) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. - } - else if (CheckBSequence(m)) + if (CheckBSequence(m)) { SpellHelper.Turn(Caster, m); diff --git a/Projects/UOContent/Spells/Second/Cure.cs b/Projects/UOContent/Spells/Second/Cure.cs index 1b0bc413e..895f9eb89 100644 --- a/Projects/UOContent/Spells/Second/Cure.cs +++ b/Projects/UOContent/Spells/Second/Cure.cs @@ -22,16 +22,7 @@ namespace Server.Spells.Second public void Target(Mobile m) { - if (m == null) - { - return; - } - - if (!Caster.CanSee(m)) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. - } - else if (CheckBSequence(m)) + if (CheckBSequence(m)) { SpellHelper.Turn(Caster, m); diff --git a/Projects/UOContent/Spells/Second/Harm.cs b/Projects/UOContent/Spells/Second/Harm.cs index fd1d58adc..25735664e 100644 --- a/Projects/UOContent/Spells/Second/Harm.cs +++ b/Projects/UOContent/Spells/Second/Harm.cs @@ -23,16 +23,7 @@ namespace Server.Spells.Second public void Target(Mobile m) { - if (m == null) - { - return; - } - - if (!Caster.CanSee(m)) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. - } - else if (CheckHSequence(m)) + if (CheckHSequence(m)) { SpellHelper.Turn(Caster, m); diff --git a/Projects/UOContent/Spells/Second/MagicTrap.cs b/Projects/UOContent/Spells/Second/MagicTrap.cs index c8b2a37ec..259cfcad0 100644 --- a/Projects/UOContent/Spells/Second/MagicTrap.cs +++ b/Projects/UOContent/Spells/Second/MagicTrap.cs @@ -27,10 +27,6 @@ namespace Server.Spells.Second { Caster.SendLocalizedMessage(502942); // You can't trap this! } - else if (!Caster.CanSee(item)) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. - } else if (cont.TrapType != TrapType.None && cont.TrapType != TrapType.MagicTrap) { DoFizzle(); diff --git a/Projects/UOContent/Spells/Second/RemoveTrap.cs b/Projects/UOContent/Spells/Second/RemoveTrap.cs index 7ff0c0005..c684e603c 100644 --- a/Projects/UOContent/Spells/Second/RemoveTrap.cs +++ b/Projects/UOContent/Spells/Second/RemoveTrap.cs @@ -22,13 +22,9 @@ namespace Server.Spells.Second public void Target(Item item) { - if (!(item is TrappableContainer cont)) + if (item is not TrappableContainer cont) { - Caster.SendMessage("You can't disarm that"); // TODO: Localization? - } - else if (!Caster.CanSee(item)) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. + Caster.SendLocalizedMessage(502373); // That doesn't appear to be trapped } else if (cont.TrapType != TrapType.None && cont.TrapType != TrapType.MagicTrap) { diff --git a/Projects/UOContent/Spells/Second/Strength.cs b/Projects/UOContent/Spells/Second/Strength.cs index 536662cbd..0896c0402 100644 --- a/Projects/UOContent/Spells/Second/Strength.cs +++ b/Projects/UOContent/Spells/Second/Strength.cs @@ -22,16 +22,7 @@ namespace Server.Spells.Second public void Target(Mobile m) { - if (m == null) - { - return; - } - - if (!Caster.CanSee(m)) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. - } - else if (CheckBSequence(m)) + if (CheckBSequence(m)) { SpellHelper.Turn(Caster, m); diff --git a/Projects/UOContent/Spells/Seventh/ChainLightning.cs b/Projects/UOContent/Spells/Seventh/ChainLightning.cs index f036fab6d..7251597aa 100644 --- a/Projects/UOContent/Spells/Seventh/ChainLightning.cs +++ b/Projects/UOContent/Spells/Seventh/ChainLightning.cs @@ -28,11 +28,7 @@ namespace Server.Spells.Seventh public void Target(IPoint3D p) { - if (!Caster.CanSee(p)) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. - } - else if (SpellHelper.CheckTown(p, Caster) && CheckSequence()) + if (SpellHelper.CheckTown(p, Caster) && CheckSequence()) { SpellHelper.Turn(Caster, p); diff --git a/Projects/UOContent/Spells/Seventh/EnergyField.cs b/Projects/UOContent/Spells/Seventh/EnergyField.cs index 5bee0d18c..8e6489779 100644 --- a/Projects/UOContent/Spells/Seventh/EnergyField.cs +++ b/Projects/UOContent/Spells/Seventh/EnergyField.cs @@ -28,11 +28,7 @@ namespace Server.Spells.Seventh public void Target(IPoint3D p) { - if (!Caster.CanSee(p)) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. - } - else if (SpellHelper.CheckTown(p, Caster) && CheckSequence()) + if (SpellHelper.CheckTown(p, Caster) && CheckSequence()) { SpellHelper.Turn(Caster, p); diff --git a/Projects/UOContent/Spells/Seventh/FlameStrike.cs b/Projects/UOContent/Spells/Seventh/FlameStrike.cs index e307f9be7..6a53b053a 100644 --- a/Projects/UOContent/Spells/Seventh/FlameStrike.cs +++ b/Projects/UOContent/Spells/Seventh/FlameStrike.cs @@ -23,16 +23,7 @@ namespace Server.Spells.Seventh public void Target(Mobile m) { - if (m == null) - { - return; - } - - if (!Caster.CanSee(m)) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. - } - else if (CheckHSequence(m)) + if (CheckHSequence(m)) { SpellHelper.Turn(Caster, m); diff --git a/Projects/UOContent/Spells/Seventh/ManaVampire.cs b/Projects/UOContent/Spells/Seventh/ManaVampire.cs index 15d99f19d..02b07b385 100644 --- a/Projects/UOContent/Spells/Seventh/ManaVampire.cs +++ b/Projects/UOContent/Spells/Seventh/ManaVampire.cs @@ -24,16 +24,7 @@ namespace Server.Spells.Seventh public void Target(Mobile m) { - if (m == null) - { - return; - } - - if (!Caster.CanSee(m)) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. - } - else if (CheckHSequence(m)) + if (CheckHSequence(m)) { SpellHelper.Turn(Caster, m); diff --git a/Projects/UOContent/Spells/Seventh/MassDispel.cs b/Projects/UOContent/Spells/Seventh/MassDispel.cs index 8ba30654d..fad116d3d 100644 --- a/Projects/UOContent/Spells/Seventh/MassDispel.cs +++ b/Projects/UOContent/Spells/Seventh/MassDispel.cs @@ -25,11 +25,7 @@ namespace Server.Spells.Seventh public void Target(IPoint3D p) { - if (!Caster.CanSee(p)) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. - } - else if (CheckSequence()) + if (CheckSequence()) { SpellHelper.Turn(Caster, p); diff --git a/Projects/UOContent/Spells/Seventh/MeteorSwarm.cs b/Projects/UOContent/Spells/Seventh/MeteorSwarm.cs index 594afccc7..10e3d5530 100644 --- a/Projects/UOContent/Spells/Seventh/MeteorSwarm.cs +++ b/Projects/UOContent/Spells/Seventh/MeteorSwarm.cs @@ -28,11 +28,7 @@ namespace Server.Spells.Seventh public void Target(IPoint3D p) { - if (!Caster.CanSee(p)) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. - } - else if (SpellHelper.CheckTown(p, Caster) && CheckSequence()) + if (SpellHelper.CheckTown(p, Caster) && CheckSequence()) { SpellHelper.Turn(Caster, p); diff --git a/Projects/UOContent/Spells/Sixth/Dispel.cs b/Projects/UOContent/Spells/Sixth/Dispel.cs index f4cfbd8fc..b1ab2dbf3 100644 --- a/Projects/UOContent/Spells/Sixth/Dispel.cs +++ b/Projects/UOContent/Spells/Sixth/Dispel.cs @@ -24,16 +24,7 @@ namespace Server.Spells.Sixth public void Target(Mobile m) { - if (m == null) - { - return; - } - - if (!Caster.CanSee(m)) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. - } - else if (!(m is BaseCreature bc && bc.IsDispellable)) + if (m is not BaseCreature { IsDispellable: true } bc) { Caster.SendLocalizedMessage(1005049); // That cannot be dispelled. } diff --git a/Projects/UOContent/Spells/Sixth/EnergyBolt.cs b/Projects/UOContent/Spells/Sixth/EnergyBolt.cs index 9ebcb415b..d7723204b 100644 --- a/Projects/UOContent/Spells/Sixth/EnergyBolt.cs +++ b/Projects/UOContent/Spells/Sixth/EnergyBolt.cs @@ -23,16 +23,7 @@ namespace Server.Spells.Sixth public void Target(Mobile m) { - if (m == null) - { - return; - } - - if (!Caster.CanSee(m)) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. - } - else if (CheckHSequence(m)) + if (CheckHSequence(m)) { var source = Caster; diff --git a/Projects/UOContent/Spells/Sixth/Explosion.cs b/Projects/UOContent/Spells/Sixth/Explosion.cs index 88acce5b2..16b0f69b3 100644 --- a/Projects/UOContent/Spells/Sixth/Explosion.cs +++ b/Projects/UOContent/Spells/Sixth/Explosion.cs @@ -26,16 +26,7 @@ namespace Server.Spells.Sixth public void Target(Mobile m) { - if (m == null) - { - return; - } - - if (!Caster.CanSee(m)) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. - } - else if (Caster.CanBeHarmful(m) && CheckSequence()) + if (Caster.CanBeHarmful(m) && CheckSequence()) { Mobile attacker = Caster, defender = m; diff --git a/Projects/UOContent/Spells/Sixth/Invisibility.cs b/Projects/UOContent/Spells/Sixth/Invisibility.cs index aeb42f8d0..1fd01bfcd 100644 --- a/Projects/UOContent/Spells/Sixth/Invisibility.cs +++ b/Projects/UOContent/Spells/Sixth/Invisibility.cs @@ -28,16 +28,7 @@ namespace Server.Spells.Sixth public void Target(Mobile m) { - if (m == null) - { - return; - } - - if (!Caster.CanSee(m)) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. - } - else if (m is BaseVendor || m is PlayerVendor || m.AccessLevel > Caster.AccessLevel) + if (m is BaseVendor or PlayerVendor || m.AccessLevel > Caster.AccessLevel) { Caster.SendLocalizedMessage(501857); // This spell won't work on that! } diff --git a/Projects/UOContent/Spells/Sixth/Mark.cs b/Projects/UOContent/Spells/Sixth/Mark.cs index b35a25784..7a4fb4e36 100644 --- a/Projects/UOContent/Spells/Sixth/Mark.cs +++ b/Projects/UOContent/Spells/Sixth/Mark.cs @@ -24,7 +24,7 @@ namespace Server.Spells.Sixth public void Target(Item item) { - if (!(item is RecallRune rune)) + if (item is not RecallRune rune) { Caster.NetState.SendMessageLocalized( Caster.Serial, @@ -32,13 +32,9 @@ namespace Server.Spells.Sixth MessageType.Regular, 0x3B2, 3, - 501797, + 501797, // I cannot mark that object. Caster.Name - ); // I cannot mark that object. - } - else if (!Caster.CanSee(rune)) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. + ); } else if (!SpellHelper.CheckTravel(Caster, TravelCheckType.Mark)) { @@ -49,11 +45,8 @@ namespace Server.Spells.Sixth } else if (!rune.IsChildOf(Caster.Backpack)) { - Caster.LocalOverheadMessage( - MessageType.Regular, - 0x3B2, - 1062422 - ); // You must have this rune in your backpack in order to mark it. + // You must have this rune in your backpack in order to mark it. + Caster.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1062422); } else if (CheckSequence()) { diff --git a/Projects/UOContent/Spells/Sixth/MassCurse.cs b/Projects/UOContent/Spells/Sixth/MassCurse.cs index 375789e41..ee2e8ba38 100644 --- a/Projects/UOContent/Spells/Sixth/MassCurse.cs +++ b/Projects/UOContent/Spells/Sixth/MassCurse.cs @@ -24,11 +24,7 @@ namespace Server.Spells.Sixth public void Target(IPoint3D p) { - if (!Caster.CanSee(p)) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. - } - else if (SpellHelper.CheckTown(p, Caster) && CheckSequence()) + if (SpellHelper.CheckTown(p, Caster) && CheckSequence()) { SpellHelper.Turn(Caster, p); diff --git a/Projects/UOContent/Spells/Sixth/ParalyzeField.cs b/Projects/UOContent/Spells/Sixth/ParalyzeField.cs index cea6f4e50..0cff8699c 100644 --- a/Projects/UOContent/Spells/Sixth/ParalyzeField.cs +++ b/Projects/UOContent/Spells/Sixth/ParalyzeField.cs @@ -27,11 +27,7 @@ namespace Server.Spells.Sixth public void Target(IPoint3D p) { - if (!Caster.CanSee(p)) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. - } - else if (SpellHelper.CheckTown(p, Caster) && CheckSequence()) + if (SpellHelper.CheckTown(p, Caster) && CheckSequence()) { SpellHelper.Turn(Caster, p); diff --git a/Projects/UOContent/Spells/Sixth/Reveal.cs b/Projects/UOContent/Spells/Sixth/Reveal.cs index a6793b1e5..c95539c77 100644 --- a/Projects/UOContent/Spells/Sixth/Reveal.cs +++ b/Projects/UOContent/Spells/Sixth/Reveal.cs @@ -22,11 +22,7 @@ namespace Server.Spells.Sixth public void Target(IPoint3D p) { - if (!Caster.CanSee(p)) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. - } - else if (CheckSequence()) + if (CheckSequence()) { SpellHelper.Turn(Caster, p); SpellHelper.GetSurfaceTop(ref p); diff --git a/Projects/UOContent/Spells/Spellweaving/GiftOfLife.cs b/Projects/UOContent/Spells/Spellweaving/GiftOfLife.cs index 9f0b2247b..55623c555 100644 --- a/Projects/UOContent/Spells/Spellweaving/GiftOfLife.cs +++ b/Projects/UOContent/Spells/Spellweaving/GiftOfLife.cs @@ -30,15 +30,7 @@ namespace Server.Spells.Spellweaving public void Target(Mobile m) { - if (m == null) - { - Caster.SendLocalizedMessage(1072077); // You may only cast this spell on yourself or a bonded pet. - } - else if (!Caster.CanSee(m)) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. - } - else if (m.IsDeadBondedPet || !m.Alive) + if (m.IsDeadBondedPet || !m.Alive) { // As per Osi: Nothing happens. } diff --git a/Projects/UOContent/Spells/Spellweaving/GiftOfRenewal.cs b/Projects/UOContent/Spells/Spellweaving/GiftOfRenewal.cs index 5bf8db8ac..e99471fcd 100644 --- a/Projects/UOContent/Spells/Spellweaving/GiftOfRenewal.cs +++ b/Projects/UOContent/Spells/Spellweaving/GiftOfRenewal.cs @@ -26,16 +26,7 @@ namespace Server.Spells.Spellweaving public void Target(Mobile m) { - if (m == null) - { - return; - } - - if (!Caster.CanSee(m)) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. - } - else if (m_Table.ContainsKey(m)) + if (m_Table.ContainsKey(m)) { Caster.SendLocalizedMessage(501775); // This spell is already in effect. } diff --git a/Projects/UOContent/Spells/Spellweaving/WordOfDeath.cs b/Projects/UOContent/Spells/Spellweaving/WordOfDeath.cs index 7cdd76846..572b68073 100644 --- a/Projects/UOContent/Spells/Spellweaving/WordOfDeath.cs +++ b/Projects/UOContent/Spells/Spellweaving/WordOfDeath.cs @@ -18,16 +18,7 @@ namespace Server.Spells.Spellweaving public void Target(Mobile m) { - if (m == null) - { - return; - } - - if (!Caster.CanSee(m)) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. - } - else if (CheckHSequence(m)) + if (CheckHSequence(m)) { var loc = m.Location; loc.Z += 50; diff --git a/Projects/UOContent/Spells/Third/Bless.cs b/Projects/UOContent/Spells/Third/Bless.cs index 3c694cc69..8bf3803ed 100644 --- a/Projects/UOContent/Spells/Third/Bless.cs +++ b/Projects/UOContent/Spells/Third/Bless.cs @@ -22,16 +22,7 @@ namespace Server.Spells.Third public void Target(Mobile m) { - if (m == null) - { - return; - } - - if (!Caster.CanSee(m)) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. - } - else if (CheckBSequence(m)) + if (CheckBSequence(m)) { SpellHelper.Turn(Caster, m); diff --git a/Projects/UOContent/Spells/Third/Fireball.cs b/Projects/UOContent/Spells/Third/Fireball.cs index 298dc2f0a..aa5ca6941 100644 --- a/Projects/UOContent/Spells/Third/Fireball.cs +++ b/Projects/UOContent/Spells/Third/Fireball.cs @@ -22,16 +22,7 @@ namespace Server.Spells.Third public void Target(Mobile m) { - if (m == null) - { - return; - } - - if (!Caster.CanSee(m)) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. - } - else if (CheckHSequence(m)) + if (CheckHSequence(m)) { var source = Caster; diff --git a/Projects/UOContent/Spells/Third/Poison.cs b/Projects/UOContent/Spells/Third/Poison.cs index 71cd43495..584d3a20e 100644 --- a/Projects/UOContent/Spells/Third/Poison.cs +++ b/Projects/UOContent/Spells/Third/Poison.cs @@ -21,16 +21,7 @@ namespace Server.Spells.Third public void Target(Mobile m) { - if (m == null) - { - return; - } - - if (!Caster.CanSee(m)) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. - } - else if (CheckHSequence(m)) + if (CheckHSequence(m)) { SpellHelper.Turn(Caster, m); diff --git a/Projects/UOContent/Spells/Third/WallOfStone.cs b/Projects/UOContent/Spells/Third/WallOfStone.cs index f0f1ec926..271455d05 100644 --- a/Projects/UOContent/Spells/Third/WallOfStone.cs +++ b/Projects/UOContent/Spells/Third/WallOfStone.cs @@ -25,11 +25,7 @@ namespace Server.Spells.Third public void Target(IPoint3D p) { - if (!Caster.CanSee(p)) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. - } - else if (SpellHelper.CheckTown(p, Caster) && CheckSequence()) + if (SpellHelper.CheckTown(p, Caster) && CheckSequence()) { SpellHelper.Turn(Caster, p); From 15b2d08ea25c448059abb515675b013cd9866277 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 14 Nov 2021 18:48:44 -0800 Subject: [PATCH 011/213] fix: More spell variable cleanup (#850) --- Projects/UOContent/Spells/Base/SpellHelper.cs | 8 ++++---- Projects/UOContent/Spells/Bushido/Confidence.cs | 8 ++++---- .../UOContent/Spells/Bushido/CounterAttack.cs | 8 ++++---- Projects/UOContent/Spells/Bushido/Evasion.cs | 8 ++++---- .../Spells/Bushido/HonorableExecution.cs | 10 +++++----- .../Spells/Chivalry/ConsecrateWeapon.cs | 8 ++++---- Projects/UOContent/Spells/Chivalry/DivineFury.cs | 8 ++++---- Projects/UOContent/Spells/Chivalry/EnemyOfOne.cs | 6 +++--- Projects/UOContent/Spells/Fifth/Incognito.cs | 6 +++--- Projects/UOContent/Spells/Fifth/MagicReflect.cs | 8 ++++---- Projects/UOContent/Spells/First/ReactiveArmor.cs | 8 ++++---- Projects/UOContent/Spells/Fourth/ManaDrain.cs | 8 ++++---- .../Spells/Mysticism/SpellPlagueSpell.cs | 16 ++++++++-------- .../UOContent/Spells/Mysticism/StoneFormSpell.cs | 8 ++++---- .../Spells/Necromancy/AnimateDeadSpell.cs | 10 +++++----- .../Spells/Necromancy/BloodOathSpell.cs | 10 +++++----- .../UOContent/Spells/Necromancy/CorpseSkin.cs | 10 +++++----- .../UOContent/Spells/Necromancy/CurseWeapon.cs | 8 ++++---- Projects/UOContent/Spells/Necromancy/EvilOmen.cs | 8 ++++---- Projects/UOContent/Spells/Necromancy/MindRot.cs | 12 ++++++------ .../UOContent/Spells/Necromancy/PainSpike.cs | 8 ++++---- Projects/UOContent/Spells/Necromancy/Strangle.cs | 12 ++++++------ Projects/UOContent/Spells/Ninjitsu/AnimalForm.cs | 10 +++++----- .../UOContent/Spells/Ninjitsu/DeathStrike.cs | 8 ++++---- Projects/UOContent/Spells/Ninjitsu/KiAttack.cs | 10 +++++----- .../UOContent/Spells/Ninjitsu/SurpriseAttack.cs | 8 ++++---- Projects/UOContent/Spells/Second/Protection.cs | 8 ++++---- Projects/UOContent/Spells/Seventh/Polymorph.cs | 6 +++--- Projects/UOContent/Spells/Sixth/Invisibility.cs | 8 ++++---- .../Spells/Spellweaving/AttuneWeapon.cs | 12 ++++++------ .../Spells/Spellweaving/EssenceOfWind.cs | 14 +++++++------- .../UOContent/Spells/Spellweaving/GiftOfLife.cs | 14 +++++++------- .../Spells/Spellweaving/GiftOfRenewal.cs | 10 +++++----- .../Spells/Spellweaving/ImmolatingWeapon.cs | 12 ++++++------ .../Spells/Spellweaving/Thunderstorm.cs | 8 ++++---- 35 files changed, 162 insertions(+), 162 deletions(-) diff --git a/Projects/UOContent/Spells/Base/SpellHelper.cs b/Projects/UOContent/Spells/Base/SpellHelper.cs index cbf225459..f855ad5ac 100644 --- a/Projects/UOContent/Spells/Base/SpellHelper.cs +++ b/Projects/UOContent/Spells/Base/SpellHelper.cs @@ -1226,7 +1226,7 @@ namespace Server.Spells public static class TransformationSpellHelper { - private static readonly Dictionary m_Table = new(); + private static readonly Dictionary _table = new(); public static bool CheckCast(Mobile caster, Spell spell) { @@ -1360,7 +1360,7 @@ namespace Server.Spells public static void AddContext(Mobile m, TransformContext context) { - m_Table[m] = context; + _table[m] = context; } public static void RemoveContext(Mobile m, bool resetGraphics) @@ -1375,7 +1375,7 @@ namespace Server.Spells public static void RemoveContext(Mobile m, TransformContext context, bool resetGraphics) { - if (!m_Table.Remove(m)) + if (!_table.Remove(m)) { return; } @@ -1399,7 +1399,7 @@ namespace Server.Spells public static TransformContext GetContext(Mobile m) { - m_Table.TryGetValue(m, out var context); + _table.TryGetValue(m, out var context); return context; } diff --git a/Projects/UOContent/Spells/Bushido/Confidence.cs b/Projects/UOContent/Spells/Bushido/Confidence.cs index be3313cf8..e8eab62dc 100644 --- a/Projects/UOContent/Spells/Bushido/Confidence.cs +++ b/Projects/UOContent/Spells/Bushido/Confidence.cs @@ -12,7 +12,7 @@ namespace Server.Spells.Bushido 9002 ); - private static readonly Dictionary m_Table = new(); + private static readonly Dictionary _table = new(); private static readonly Dictionary m_RegenTable = new(); public Confidence(Mobile caster, Item scroll) : base(caster, scroll, _info) @@ -49,7 +49,7 @@ namespace Server.Spells.Bushido FinishSequence(); } - public static bool IsConfident(Mobile m) => m_Table.ContainsKey(m); + public static bool IsConfident(Mobile m) => _table.ContainsKey(m); public static void BeginConfidence(Mobile m) { @@ -64,12 +64,12 @@ namespace Server.Spells.Bushido out var timerToken ); - m_Table[m] = timerToken; + _table[m] = timerToken; } private static bool StopConfidenceTimer(Mobile m) { - if (m_Table.Remove(m, out var timerToken)) + if (_table.Remove(m, out var timerToken)) { timerToken.Cancel(); return true; diff --git a/Projects/UOContent/Spells/Bushido/CounterAttack.cs b/Projects/UOContent/Spells/Bushido/CounterAttack.cs index ba546fa5b..ea3c07e22 100644 --- a/Projects/UOContent/Spells/Bushido/CounterAttack.cs +++ b/Projects/UOContent/Spells/Bushido/CounterAttack.cs @@ -13,7 +13,7 @@ namespace Server.Spells.Bushido 9002 ); - private static readonly Dictionary m_Table = new(); + private static readonly Dictionary _table = new(); public CounterAttack(Mobile caster, Item scroll) : base(caster, scroll, _info) { @@ -71,11 +71,11 @@ namespace Server.Spells.Bushido FinishSequence(); } - public static bool IsCountering(Mobile m) => m_Table.ContainsKey(m); + public static bool IsCountering(Mobile m) => _table.ContainsKey(m); private static bool StopCounterTimer(Mobile m) { - if (m_Table.Remove(m, out var timerToken)) + if (_table.Remove(m, out var timerToken)) { timerToken.Cancel(); return true; @@ -97,7 +97,7 @@ namespace Server.Spells.Bushido out var timerToken ); - m_Table[m] = timerToken; + _table[m] = timerToken; } public static void StopCountering(Mobile m) diff --git a/Projects/UOContent/Spells/Bushido/Evasion.cs b/Projects/UOContent/Spells/Bushido/Evasion.cs index d39b43194..a5eab88e2 100644 --- a/Projects/UOContent/Spells/Bushido/Evasion.cs +++ b/Projects/UOContent/Spells/Bushido/Evasion.cs @@ -13,7 +13,7 @@ namespace Server.Spells.Bushido 9002 ); - private static readonly Dictionary m_Table = new(); + private static readonly Dictionary _table = new(); public Evasion(Mobile caster, Item scroll) : base(caster, scroll, _info) { @@ -138,7 +138,7 @@ namespace Server.Spells.Bushido FinishSequence(); } - public static bool IsEvading(Mobile m) => m_Table.ContainsKey(m); + public static bool IsEvading(Mobile m) => _table.ContainsKey(m); public static TimeSpan GetEvadeDuration(Mobile m) { @@ -216,12 +216,12 @@ namespace Server.Spells.Bushido out var timerToken ); - m_Table[m] = timerToken; + _table[m] = timerToken; } private static bool StopEvasionTimer(Mobile m) { - if (m_Table.Remove(m, out var timer)) + if (_table.Remove(m, out var timer)) { timer.Cancel(); return true; diff --git a/Projects/UOContent/Spells/Bushido/HonorableExecution.cs b/Projects/UOContent/Spells/Bushido/HonorableExecution.cs index 35da3b3d8..266644850 100644 --- a/Projects/UOContent/Spells/Bushido/HonorableExecution.cs +++ b/Projects/UOContent/Spells/Bushido/HonorableExecution.cs @@ -5,7 +5,7 @@ namespace Server.Spells.Bushido { public class HonorableExecution : SamuraiMove { - private static readonly Dictionary m_Table = new(); + private static readonly Dictionary _table = new(); public override int BaseMana => 0; public override double RequiredSkill => 25.0; @@ -63,20 +63,20 @@ namespace Server.Spells.Bushido timer = new HonorableExecutionTimer(attacker, mods); } - m_Table[attacker] = timer; + _table[attacker] = timer; timer.Start(); attacker.Delta(MobileDelta.WeaponDamage); CheckGain(attacker); } - public static int GetSwingBonus(Mobile target) => m_Table.TryGetValue(target, out var info) ? info.m_SwingBonus : 0; + public static int GetSwingBonus(Mobile target) => _table.TryGetValue(target, out var info) ? info.m_SwingBonus : 0; - public static bool IsUnderPenalty(Mobile target) => m_Table.TryGetValue(target, out var info) && info.m_Penalty; + public static bool IsUnderPenalty(Mobile target) => _table.TryGetValue(target, out var info) && info.m_Penalty; public static void RemovePenalty(Mobile target) { - if (m_Table.Remove(target, out var timer)) + if (_table.Remove(target, out var timer)) { timer.Clear(); } diff --git a/Projects/UOContent/Spells/Chivalry/ConsecrateWeapon.cs b/Projects/UOContent/Spells/Chivalry/ConsecrateWeapon.cs index 4033ce18c..01eea62a2 100644 --- a/Projects/UOContent/Spells/Chivalry/ConsecrateWeapon.cs +++ b/Projects/UOContent/Spells/Chivalry/ConsecrateWeapon.cs @@ -13,7 +13,7 @@ namespace Server.Spells.Chivalry 9002 ); - private static readonly Dictionary m_Table = new(); + private static readonly Dictionary _table = new(); public ConsecrateWeaponSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { @@ -86,12 +86,12 @@ namespace Server.Spells.Chivalry var duration = TimeSpan.FromSeconds(seconds); - m_Table.TryGetValue(weapon, out var timer); + _table.TryGetValue(weapon, out var timer); timer?.Stop(); weapon.Consecrated = true; - m_Table[weapon] = timer = new ExpireTimer(weapon, duration); + _table[weapon] = timer = new ExpireTimer(weapon, duration); timer.Start(); } @@ -112,7 +112,7 @@ namespace Server.Spells.Chivalry { m_Weapon.Consecrated = false; Effects.PlaySound(m_Weapon.GetWorldLocation(), m_Weapon.Map, 0x1F8); - m_Table.Remove(m_Weapon); + _table.Remove(m_Weapon); } } } diff --git a/Projects/UOContent/Spells/Chivalry/DivineFury.cs b/Projects/UOContent/Spells/Chivalry/DivineFury.cs index 405d60064..6716c7d66 100644 --- a/Projects/UOContent/Spells/Chivalry/DivineFury.cs +++ b/Projects/UOContent/Spells/Chivalry/DivineFury.cs @@ -12,7 +12,7 @@ namespace Server.Spells.Chivalry 9002 ); - private static readonly Dictionary m_Table = new(); + private static readonly Dictionary _table = new(); public DivineFurySpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { @@ -46,7 +46,7 @@ namespace Server.Spells.Chivalry out var timerToken ); - m_Table[Caster] = timerToken; + _table[Caster] = timerToken; Caster.Delta(MobileDelta.WeaponDamage); @@ -61,7 +61,7 @@ namespace Server.Spells.Chivalry private static void RemoveTimer(Mobile m) { - if (m_Table.Remove(m, out var timerToken)) + if (_table.Remove(m, out var timerToken)) { timerToken.Cancel(); } @@ -74,6 +74,6 @@ namespace Server.Spells.Chivalry m.PlaySound(0xF8); } - public static bool UnderEffect(Mobile m) => m_Table.ContainsKey(m); + public static bool UnderEffect(Mobile m) => _table.ContainsKey(m); } } diff --git a/Projects/UOContent/Spells/Chivalry/EnemyOfOne.cs b/Projects/UOContent/Spells/Chivalry/EnemyOfOne.cs index b41410fed..5014eab26 100644 --- a/Projects/UOContent/Spells/Chivalry/EnemyOfOne.cs +++ b/Projects/UOContent/Spells/Chivalry/EnemyOfOne.cs @@ -13,7 +13,7 @@ namespace Server.Spells.Chivalry 9002 ); - private static readonly Dictionary m_Table = new(); + private static readonly Dictionary _table = new(); public EnemyOfOneSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { @@ -42,7 +42,7 @@ namespace Server.Spells.Chivalry Timer.StartTimer(TimeSpan.FromMinutes(delay), () => Expire_Callback(Caster), out var timerToken); - m_Table[Caster] = timerToken; + _table[Caster] = timerToken; if (Caster is PlayerMobile mobile) { @@ -61,7 +61,7 @@ namespace Server.Spells.Chivalry private static void RemoveTimer(Mobile m) { - if (m_Table.Remove(m, out var timerToken)) + if (_table.Remove(m, out var timerToken)) { timerToken.Cancel(); } diff --git a/Projects/UOContent/Spells/Fifth/Incognito.cs b/Projects/UOContent/Spells/Fifth/Incognito.cs index 58dc05fb3..978af3dfa 100644 --- a/Projects/UOContent/Spells/Fifth/Incognito.cs +++ b/Projects/UOContent/Spells/Fifth/Incognito.cs @@ -19,7 +19,7 @@ namespace Server.Spells.Fifth Reagent.Nightshade ); - private static readonly Dictionary m_Table = new(); + private static readonly Dictionary _table = new(); public IncognitoSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { @@ -112,7 +112,7 @@ namespace Server.Spells.Fifth var length = TimeSpan.FromSeconds(timeVal); Timer.StartTimer(length, () => EndIncognito(Caster), out var timerToken); - m_Table[Caster] = timerToken; + _table[Caster] = timerToken; BuffInfo.AddBuff(Caster, new BuffInfo(BuffIcon.Incognito, 1075819, length, Caster)); } @@ -127,7 +127,7 @@ namespace Server.Spells.Fifth public static void StopTimer(Mobile m) { - if (m_Table.Remove(m, out var timerToken)) + if (_table.Remove(m, out var timerToken)) { timerToken.Cancel(); } diff --git a/Projects/UOContent/Spells/Fifth/MagicReflect.cs b/Projects/UOContent/Spells/Fifth/MagicReflect.cs index a00100674..d83582374 100644 --- a/Projects/UOContent/Spells/Fifth/MagicReflect.cs +++ b/Projects/UOContent/Spells/Fifth/MagicReflect.cs @@ -14,7 +14,7 @@ namespace Server.Spells.Fifth Reagent.SpidersSilk ); - private static readonly Dictionary m_Table = new(); + private static readonly Dictionary _table = new(); public MagicReflectSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { @@ -59,7 +59,7 @@ namespace Server.Spells.Fifth { var targ = Caster; - if (m_Table.Remove(targ, out var mods)) + if (_table.Remove(targ, out var mods)) { targ.PlaySound(0x1ED); targ.FixedParticles(0x375A, 10, 15, 5037, EffectLayer.Waist); @@ -88,7 +88,7 @@ namespace Server.Spells.Fifth new ResistanceMod(ResistanceType.Energy, otherMod) }; - m_Table[targ] = mods; + _table[targ] = mods; for (var i = 0; i < mods.Length; ++i) { @@ -137,7 +137,7 @@ namespace Server.Spells.Fifth public static void EndReflect(Mobile m) { - if (!m_Table.Remove(m, out var mods)) + if (!_table.Remove(m, out var mods)) { return; } diff --git a/Projects/UOContent/Spells/First/ReactiveArmor.cs b/Projects/UOContent/Spells/First/ReactiveArmor.cs index b60167b13..8659c1253 100644 --- a/Projects/UOContent/Spells/First/ReactiveArmor.cs +++ b/Projects/UOContent/Spells/First/ReactiveArmor.cs @@ -15,7 +15,7 @@ namespace Server.Spells.First Reagent.SulfurousAsh ); - private static readonly Dictionary m_Table = new(); + private static readonly Dictionary _table = new(); public ReactiveArmorSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { @@ -61,7 +61,7 @@ namespace Server.Spells.First { var targ = Caster; - if (m_Table.Remove(targ, out var mods)) + if (_table.Remove(targ, out var mods)) { targ.PlaySound(0x1ED); targ.FixedParticles(0x376A, 9, 32, 5008, EffectLayer.Waist); @@ -90,7 +90,7 @@ namespace Server.Spells.First new ResistanceMod(ResistanceType.Energy, -5) }; - m_Table[targ] = mods; + _table[targ] = mods; for (var i = 0; i < mods.Length; ++i) { @@ -144,7 +144,7 @@ namespace Server.Spells.First public static void EndArmor(Mobile m) { - if (!m_Table.Remove(m, out var mods)) + if (!_table.Remove(m, out var mods)) { return; } diff --git a/Projects/UOContent/Spells/Fourth/ManaDrain.cs b/Projects/UOContent/Spells/Fourth/ManaDrain.cs index 52bd11a8e..d3dc42e78 100644 --- a/Projects/UOContent/Spells/Fourth/ManaDrain.cs +++ b/Projects/UOContent/Spells/Fourth/ManaDrain.cs @@ -16,7 +16,7 @@ namespace Server.Spells.Fourth Reagent.SpidersSilk ); - private static readonly HashSet m_Table = new(); + private static readonly HashSet _table = new(); public ManaDrainSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { @@ -40,7 +40,7 @@ namespace Server.Spells.Fourth { var toDrain = Math.Clamp(40 + (int)(GetDamageSkill(Caster) - GetResistSkill(m)), 0, m.Mana); - if (m_Table.Contains(m)) + if (_table.Contains(m)) { toDrain = 0; } @@ -52,7 +52,7 @@ namespace Server.Spells.Fourth { m.Mana -= toDrain; - m_Table.Add(m); + _table.Add(m); Timer.StartTimer(TimeSpan.FromSeconds(5.0), () => AosDelay_Callback(m, toDrain)); } } @@ -96,7 +96,7 @@ namespace Server.Spells.Fourth m.PlaySound(0x28E); } - m_Table.Remove(m); + _table.Remove(m); } public override double GetResistPercent(Mobile target) => 99.0; diff --git a/Projects/UOContent/Spells/Mysticism/SpellPlagueSpell.cs b/Projects/UOContent/Spells/Mysticism/SpellPlagueSpell.cs index a02032856..23c991a4d 100644 --- a/Projects/UOContent/Spells/Mysticism/SpellPlagueSpell.cs +++ b/Projects/UOContent/Spells/Mysticism/SpellPlagueSpell.cs @@ -17,7 +17,7 @@ namespace Server.Spells.Mysticism Reagent.SulfurousAsh ); - private static readonly Dictionary m_Table = new(); + private static readonly Dictionary _table = new(); public SpellPlagueSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) @@ -64,13 +64,13 @@ namespace Server.Spells.Mysticism var timer = new SpellPlagueTimer(this, targeted); - if (m_Table.TryGetValue(targeted, out var oldtimer)) + if (_table.TryGetValue(targeted, out var oldtimer)) { oldtimer.SetNext(timer); } else { - m_Table[targeted] = timer; + _table[targeted] = timer; timer.StartPlague(); } } @@ -78,11 +78,11 @@ namespace Server.Spells.Mysticism FinishSequence(); } - public static bool UnderEffect(Mobile m) => m_Table.ContainsKey(m); + public static bool UnderEffect(Mobile m) => _table.ContainsKey(m); public static void RemoveEffect(Mobile m) { - if (m_Table.TryGetValue(m, out var context)) + if (_table.TryGetValue(m, out var context)) { context.EndPlague(false); } @@ -90,7 +90,7 @@ namespace Server.Spells.Mysticism public static void CheckPlague(Mobile m) { - if (m_Table.TryGetValue(m, out var context)) + if (_table.TryGetValue(m, out var context)) { context.OnDamage(); } @@ -183,12 +183,12 @@ namespace Server.Spells.Mysticism { if (restart && m_Next != null) { - m_Table[m_Target] = m_Next; + _table[m_Target] = m_Next; m_Next.StartPlague(); } else { - m_Table.Remove(m_Target); + _table.Remove(m_Target); BuffInfo.RemoveBuff(m_Target, BuffIcon.SpellPlague); } } diff --git a/Projects/UOContent/Spells/Mysticism/StoneFormSpell.cs b/Projects/UOContent/Spells/Mysticism/StoneFormSpell.cs index a707caecb..fa2e83169 100644 --- a/Projects/UOContent/Spells/Mysticism/StoneFormSpell.cs +++ b/Projects/UOContent/Spells/Mysticism/StoneFormSpell.cs @@ -19,7 +19,7 @@ namespace Server.Spells.Mysticism Reagent.Garlic ); - private static readonly Dictionary m_Table = new(); + private static readonly Dictionary _table = new(); public StoneFormSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) @@ -36,7 +36,7 @@ namespace Server.Spells.Mysticism EventSink.PlayerDeath += OnPlayerDeath; } - public static bool UnderEffect(Mobile m) => m_Table.ContainsKey(m); + public static bool UnderEffect(Mobile m) => _table.ContainsKey(m); public override bool CheckCast() { @@ -118,7 +118,7 @@ namespace Server.Spells.Mysticism Caster.AddResistanceMod(mods[i]); } - m_Table[Caster] = mods; + _table[Caster] = mods; Caster.PlaySound(0x65A); Caster.Delta(MobileDelta.Resistances); @@ -145,7 +145,7 @@ namespace Server.Spells.Mysticism public static void RemoveEffects(Mobile m) { - if (!m_Table.Remove(m, out var mods)) + if (!_table.Remove(m, out var mods)) { return; } diff --git a/Projects/UOContent/Spells/Necromancy/AnimateDeadSpell.cs b/Projects/UOContent/Spells/Necromancy/AnimateDeadSpell.cs index 5363f8cb6..dc2740166 100644 --- a/Projects/UOContent/Spells/Necromancy/AnimateDeadSpell.cs +++ b/Projects/UOContent/Spells/Necromancy/AnimateDeadSpell.cs @@ -108,7 +108,7 @@ namespace Server.Spells.Necromancy ) }; - private static readonly Dictionary> m_Table = new(); + private static readonly Dictionary> _table = new(); public AnimateDeadSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { @@ -235,7 +235,7 @@ namespace Server.Spells.Necromancy public static void Unregister(Mobile master, Mobile summoned) { - if (master == null || !m_Table.TryGetValue(master, out var list)) + if (master == null || !_table.TryGetValue(master, out var list)) { return; } @@ -244,7 +244,7 @@ namespace Server.Spells.Necromancy if (list.Count == 0) { - m_Table.Remove(master); + _table.Remove(master); } } @@ -255,9 +255,9 @@ namespace Server.Spells.Necromancy return; } - if (!m_Table.TryGetValue(master, out var list)) + if (!_table.TryGetValue(master, out var list)) { - m_Table[master] = list = new List(); + _table[master] = list = new List(); } for (var i = list.Count - 1; i >= 0; --i) diff --git a/Projects/UOContent/Spells/Necromancy/BloodOathSpell.cs b/Projects/UOContent/Spells/Necromancy/BloodOathSpell.cs index dd05819ff..0d7969f7d 100644 --- a/Projects/UOContent/Spells/Necromancy/BloodOathSpell.cs +++ b/Projects/UOContent/Spells/Necromancy/BloodOathSpell.cs @@ -16,7 +16,7 @@ namespace Server.Spells.Necromancy ); private static readonly Dictionary m_OathTable = new(); - private static readonly Dictionary m_Table = new(); + private static readonly Dictionary _table = new(); public BloodOathSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { @@ -65,7 +65,7 @@ namespace Server.Spells.Necromancy * ((ss-rm)/8)+8 */ - m_Table.TryGetValue(m, out var timer); + _table.TryGetValue(m, out var timer); timer?.DoExpire(); m_OathTable[Caster] = Caster; @@ -90,7 +90,7 @@ namespace Server.Spells.Necromancy BuffInfo.AddBuff(Caster, new BuffInfo(BuffIcon.BloodOathCaster, 1075659, duration, Caster, m.Name)); BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.BloodOathCurse, 1075661, duration, m, Caster.Name)); - m_Table[m] = timer; + _table[m] = timer; HarmfulSpell(m); } @@ -104,7 +104,7 @@ namespace Server.Spells.Necromancy public static void RemoveCurse(Mobile m) { - m_Table.TryGetValue(m, out var t); + _table.TryGetValue(m, out var t); t?.DoExpire(); } @@ -153,7 +153,7 @@ namespace Server.Spells.Necromancy BuffInfo.RemoveBuff(m_Caster, BuffIcon.BloodOathCaster); BuffInfo.RemoveBuff(m_Target, BuffIcon.BloodOathCurse); - m_Table.Remove(m_Caster); + _table.Remove(m_Caster); } } } diff --git a/Projects/UOContent/Spells/Necromancy/CorpseSkin.cs b/Projects/UOContent/Spells/Necromancy/CorpseSkin.cs index e39f33118..fb5909bd7 100644 --- a/Projects/UOContent/Spells/Necromancy/CorpseSkin.cs +++ b/Projects/UOContent/Spells/Necromancy/CorpseSkin.cs @@ -15,7 +15,7 @@ namespace Server.Spells.Necromancy Reagent.GraveDust ); - private static readonly Dictionary m_Table = new(); + private static readonly Dictionary _table = new(); public CorpseSkinSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { @@ -49,7 +49,7 @@ namespace Server.Spells.Necromancy * NOTE: Resistance is not checked if targeting yourself */ - if (m_Table.TryGetValue(m, out var timer)) + if (_table.TryGetValue(m, out var timer)) { timer.DoExpire(); } @@ -82,7 +82,7 @@ namespace Server.Spells.Necromancy BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.CorpseSkin, 1075663, duration, m)); - m_Table[m] = timer; + _table[m] = timer; for (var i = 0; i < mods.Length; ++i) { @@ -102,7 +102,7 @@ namespace Server.Spells.Necromancy public static bool RemoveCurse(Mobile m) { - if (!m_Table.TryGetValue(m, out var t)) + if (!_table.TryGetValue(m, out var t)) { return false; } @@ -132,7 +132,7 @@ namespace Server.Spells.Necromancy Stop(); BuffInfo.RemoveBuff(m_Mobile, BuffIcon.CorpseSkin); - m_Table.Remove(m_Mobile); + _table.Remove(m_Mobile); } protected override void OnTick() diff --git a/Projects/UOContent/Spells/Necromancy/CurseWeapon.cs b/Projects/UOContent/Spells/Necromancy/CurseWeapon.cs index 61062abe6..96b5fd3ea 100644 --- a/Projects/UOContent/Spells/Necromancy/CurseWeapon.cs +++ b/Projects/UOContent/Spells/Necromancy/CurseWeapon.cs @@ -14,7 +14,7 @@ namespace Server.Spells.Necromancy Reagent.PigIron ); - private static readonly Dictionary m_Table = new(); + private static readonly Dictionary _table = new(); public CurseWeaponSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { @@ -50,11 +50,11 @@ namespace Server.Spells.Necromancy var duration = TimeSpan.FromSeconds(Caster.Skills.SpiritSpeak.Value / 3.4 + 1.0); - m_Table.TryGetValue(weapon, out var timer); + _table.TryGetValue(weapon, out var timer); timer?.Stop(); weapon.Cursed = true; - m_Table[weapon] = timer = new ExpireTimer(weapon, duration); + _table[weapon] = timer = new ExpireTimer(weapon, duration); timer.Start(); } @@ -75,7 +75,7 @@ namespace Server.Spells.Necromancy { m_Weapon.Cursed = false; Effects.PlaySound(m_Weapon.GetWorldLocation(), m_Weapon.Map, 0xFA); - m_Table.Remove(m_Weapon); + _table.Remove(m_Weapon); } } diff --git a/Projects/UOContent/Spells/Necromancy/EvilOmen.cs b/Projects/UOContent/Spells/Necromancy/EvilOmen.cs index 686db22ff..ea3cd5335 100644 --- a/Projects/UOContent/Spells/Necromancy/EvilOmen.cs +++ b/Projects/UOContent/Spells/Necromancy/EvilOmen.cs @@ -16,7 +16,7 @@ namespace Server.Spells.Necromancy Reagent.NoxCrystal ); - private static readonly Dictionary m_Table = new(); + private static readonly Dictionary _table = new(); public EvilOmenSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) @@ -52,7 +52,7 @@ namespace Server.Spells.Necromancy m.FixedParticles(0x3728, 1, 13, 9912, 1150, 7, EffectLayer.Head); m.FixedParticles(0x3779, 1, 15, 9502, 67, 7, EffectLayer.Head); - if (!m_Table.ContainsKey(m)) + if (!_table.ContainsKey(m)) { var mod = new DefaultSkillMod(SkillName.MagicResist, false, 50.0); @@ -61,7 +61,7 @@ namespace Server.Spells.Necromancy m.AddSkillMod(mod); } - m_Table[m] = mod; + _table[m] = mod; } var duration = TimeSpan.FromSeconds(Caster.Skills.SpiritSpeak.Value / 12 + 1.0); @@ -83,7 +83,7 @@ namespace Server.Spells.Necromancy public static bool TryEndEffect(Mobile m) { - if (!m_Table.Remove(m, out var mod)) + if (!_table.Remove(m, out var mod)) { return false; } diff --git a/Projects/UOContent/Spells/Necromancy/MindRot.cs b/Projects/UOContent/Spells/Necromancy/MindRot.cs index 3aaeda206..784fcaa11 100644 --- a/Projects/UOContent/Spells/Necromancy/MindRot.cs +++ b/Projects/UOContent/Spells/Necromancy/MindRot.cs @@ -16,7 +16,7 @@ namespace Server.Spells.Necromancy Reagent.DaemonBlood ); - private static readonly Dictionary m_Table = new(); + private static readonly Dictionary _table = new(); public MindRotSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { @@ -73,7 +73,7 @@ namespace Server.Spells.Necromancy public static void ClearMindRotScalar(Mobile m) { - if (m_Table.Remove(m, out var tmpB)) + if (_table.Remove(m, out var tmpB)) { tmpB.m_MRExpireTimer.Stop(); m.SendLocalizedMessage(1060872); // Your mind feels normal again. @@ -82,11 +82,11 @@ namespace Server.Spells.Necromancy BuffInfo.RemoveBuff(m, BuffIcon.Mindrot); } - public static bool HasMindRotScalar(Mobile m) => m_Table.ContainsKey(m); + public static bool HasMindRotScalar(Mobile m) => _table.ContainsKey(m); public static bool GetMindRotScalar(Mobile m, ref double scalar) { - if (m_Table.TryGetValue(m, out var tmpB)) + if (_table.TryGetValue(m, out var tmpB)) { scalar = tmpB.m_Scalar; return true; @@ -97,10 +97,10 @@ namespace Server.Spells.Necromancy public static void SetMindRotScalar(Mobile caster, Mobile target, double scalar, TimeSpan duration) { - if (!m_Table.ContainsKey(target)) + if (!_table.ContainsKey(target)) { var tmpB = new MRBucket(scalar, new MRExpireTimer(target, duration)); - m_Table.Add(target, tmpB); + _table.Add(target, tmpB); BuffInfo.AddBuff(target, new BuffInfo(BuffIcon.Mindrot, 1075665, duration, target)); tmpB.m_MRExpireTimer.Start(); target.SendLocalizedMessage(1074384); diff --git a/Projects/UOContent/Spells/Necromancy/PainSpike.cs b/Projects/UOContent/Spells/Necromancy/PainSpike.cs index 632c2af6b..e270c144c 100644 --- a/Projects/UOContent/Spells/Necromancy/PainSpike.cs +++ b/Projects/UOContent/Spells/Necromancy/PainSpike.cs @@ -16,7 +16,7 @@ namespace Server.Spells.Necromancy Reagent.PigIron ); - private static readonly Dictionary m_Table = new(); + private static readonly Dictionary _table = new(); public PainSpikeSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { @@ -56,9 +56,9 @@ namespace Server.Spells.Necromancy var buffTime = TimeSpan.FromSeconds(10.0); - if (!m_Table.TryGetValue(m, out var timer)) + if (!_table.TryGetValue(m, out var timer)) { - m_Table[m] = timer = new InternalTimer(m, damage); + _table[m] = timer = new InternalTimer(m, damage); timer.Start(); } else @@ -102,7 +102,7 @@ namespace Server.Spells.Necromancy protected override void OnTick() { - m_Table.Remove(m_Mobile); + _table.Remove(m_Mobile); if (m_Mobile.Alive && !m_Mobile.IsDeadBondedPet) { diff --git a/Projects/UOContent/Spells/Necromancy/Strangle.cs b/Projects/UOContent/Spells/Necromancy/Strangle.cs index c221e1dac..a7aeab5dd 100644 --- a/Projects/UOContent/Spells/Necromancy/Strangle.cs +++ b/Projects/UOContent/Spells/Necromancy/Strangle.cs @@ -15,7 +15,7 @@ namespace Server.Spells.Necromancy Reagent.NoxCrystal ); - private static readonly Dictionary m_Table = new(); + private static readonly Dictionary _table = new(); public StrangleSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { @@ -60,9 +60,9 @@ namespace Server.Spells.Necromancy m.FixedParticles(0x36CB, 1, 9, 9911, 67, 5, EffectLayer.Head); m.FixedParticles(0x374A, 1, 17, 9502, 1108, 4, (EffectLayer)255); - if (!m_Table.TryGetValue(m, out var timer)) + if (!_table.TryGetValue(m, out var timer)) { - m_Table[m] = timer = new InternalTimer(m, Caster); + _table[m] = timer = new InternalTimer(m, Caster); timer.Start(); } @@ -118,7 +118,7 @@ namespace Server.Spells.Necromancy public static bool RemoveCurse(Mobile m) { - if (!m_Table.Remove(m, out var timer)) + if (!_table.Remove(m, out var timer)) { return false; } @@ -168,7 +168,7 @@ namespace Server.Spells.Necromancy { if (!m_Target.Alive) { - m_Table.Remove(m_Target); + _table.Remove(m_Target); Stop(); } @@ -203,7 +203,7 @@ namespace Server.Spells.Necromancy if (m_Count == 0) { m_Target.SendLocalizedMessage(1061687); // You can breath normally again. - m_Table.Remove(m_Target); + _table.Remove(m_Target); Stop(); } else diff --git a/Projects/UOContent/Spells/Ninjitsu/AnimalForm.cs b/Projects/UOContent/Spells/Ninjitsu/AnimalForm.cs index c07995af0..041a10eab 100644 --- a/Projects/UOContent/Spells/Ninjitsu/AnimalForm.cs +++ b/Projects/UOContent/Spells/Ninjitsu/AnimalForm.cs @@ -26,7 +26,7 @@ namespace Server.Spells.Ninjitsu ); private static readonly Dictionary m_LastAnimalForms = new(); - private static readonly Dictionary m_Table = new(); + private static readonly Dictionary _table = new(); private bool m_WasMoving; @@ -272,7 +272,7 @@ namespace Server.Spells.Ninjitsu public static void AddContext(Mobile m, AnimalFormContext context) { - m_Table[m] = context; + _table[m] = context; if (context.Type == typeof(BakeKitsune) || context.Type == typeof(GreyWolf)) { @@ -292,7 +292,7 @@ namespace Server.Spells.Ninjitsu public static void RemoveContext(Mobile m, AnimalFormContext context, bool resetGraphics) { - m_Table.Remove(m); + _table.Remove(m); if (context.SpeedBoost) { @@ -324,9 +324,9 @@ namespace Server.Spells.Ninjitsu context.Timer.Stop(); } - public static AnimalFormContext GetContext(Mobile m) => m_Table.TryGetValue(m, out var context) ? context : null; + public static AnimalFormContext GetContext(Mobile m) => _table.TryGetValue(m, out var context) ? context : null; - public static bool UnderTransformation(Mobile m) => m_Table.ContainsKey(m); + public static bool UnderTransformation(Mobile m) => _table.ContainsKey(m); public static bool UnderTransformation(Mobile m, Type type) => GetContext(m)?.Type == type; diff --git a/Projects/UOContent/Spells/Ninjitsu/DeathStrike.cs b/Projects/UOContent/Spells/Ninjitsu/DeathStrike.cs index dab80c215..ca4ef48a3 100644 --- a/Projects/UOContent/Spells/Ninjitsu/DeathStrike.cs +++ b/Projects/UOContent/Spells/Ninjitsu/DeathStrike.cs @@ -8,7 +8,7 @@ namespace Server.Spells.Ninjitsu { public class DeathStrike : NinjaMove { - private static readonly Dictionary m_Table = new(); + private static readonly Dictionary _table = new(); public override int BaseMana => 30; public override double RequiredSkill => 85.0; @@ -51,7 +51,7 @@ namespace Server.Spells.Ninjitsu var damageBonus = 0; - if (m_Table.Remove(defender, out var timer)) + if (_table.Remove(defender, out var timer)) { defender.SendLocalizedMessage(1063092); // Your opponent lands another Death Strike! @@ -74,7 +74,7 @@ namespace Server.Spells.Ninjitsu var t = new DeathStrikeTimer(defender, attacker, damageBonus, isRanged); - m_Table[defender] = t; + _table[defender] = t; t.Start(); @@ -83,7 +83,7 @@ namespace Server.Spells.Ninjitsu public static void AddStep(Mobile m) { - if (m_Table.TryGetValue(m, out var timer) && ++timer.Steps >= 5) + if (_table.TryGetValue(m, out var timer) && ++timer.Steps >= 5) { timer.ProcessDeathStrike(); } diff --git a/Projects/UOContent/Spells/Ninjitsu/KiAttack.cs b/Projects/UOContent/Spells/Ninjitsu/KiAttack.cs index c957c7ae0..ba573e3aa 100644 --- a/Projects/UOContent/Spells/Ninjitsu/KiAttack.cs +++ b/Projects/UOContent/Spells/Ninjitsu/KiAttack.cs @@ -6,7 +6,7 @@ namespace Server.Spells.Ninjitsu { public class KiAttack : NinjaMove { - private static readonly Dictionary m_Table = new(); + private static readonly Dictionary _table = new(); public override int BaseMana => 25; public override double RequiredSkill => 80.0; @@ -22,7 +22,7 @@ namespace Server.Spells.Ninjitsu } var t = new KiAttackTimer(from); - m_Table[from] = t; + _table[from] = t; t.Start(); } @@ -86,7 +86,7 @@ namespace Server.Spells.Ninjitsu public override void OnClearMove(Mobile from) { - if (m_Table.Remove(from, out var t)) + if (_table.Remove(from, out var t)) { t.Stop(); } @@ -94,7 +94,7 @@ namespace Server.Spells.Ninjitsu public static double GetBonus(Mobile from) { - if (!m_Table.TryGetValue(from, out var t)) + if (!_table.TryGetValue(from, out var t)) { return 0; } @@ -121,7 +121,7 @@ namespace Server.Spells.Ninjitsu ClearCurrentMove(m_Mobile); m_Mobile.SendLocalizedMessage(1063102); // You failed to complete your Ki Attack in time. - m_Table.Remove(m_Mobile); + _table.Remove(m_Mobile); } } } diff --git a/Projects/UOContent/Spells/Ninjitsu/SurpriseAttack.cs b/Projects/UOContent/Spells/Ninjitsu/SurpriseAttack.cs index d918509bd..e66df4db9 100644 --- a/Projects/UOContent/Spells/Ninjitsu/SurpriseAttack.cs +++ b/Projects/UOContent/Spells/Ninjitsu/SurpriseAttack.cs @@ -7,7 +7,7 @@ namespace Server.Spells.Ninjitsu public class SurpriseAttack : NinjaMove { private static readonly Dictionary - m_Table = new(); + _table = new(); public override int BaseMana => 20; public override double RequiredSkill => Core.ML ? 60.0 : 30.0; @@ -62,7 +62,7 @@ namespace Server.Spells.Ninjitsu var info = new SurpriseAttackInfo(defender, malus); Timer.StartTimer(TimeSpan.FromSeconds(8.0), () => EndSurprise(info), out info._timerToken); - m_Table[defender] = info; + _table[defender] = info; CheckGain(attacker); } @@ -78,7 +78,7 @@ namespace Server.Spells.Ninjitsu public static bool GetMalus(Mobile target, ref int malus) { - if (!m_Table.TryGetValue(target, out var info)) + if (!_table.TryGetValue(target, out var info)) { return false; } @@ -89,7 +89,7 @@ namespace Server.Spells.Ninjitsu private static void StopTimer(Mobile m) { - if (m_Table.Remove(m, out var info)) + if (_table.Remove(m, out var info)) { info._timerToken.Cancel(); } diff --git a/Projects/UOContent/Spells/Second/Protection.cs b/Projects/UOContent/Spells/Second/Protection.cs index 30fe8d194..38f1342c7 100644 --- a/Projects/UOContent/Spells/Second/Protection.cs +++ b/Projects/UOContent/Spells/Second/Protection.cs @@ -15,7 +15,7 @@ namespace Server.Spells.Second Reagent.SulfurousAsh ); - private static readonly Dictionary> m_Table = + private static readonly Dictionary> _table = new(); public ProtectionSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) @@ -60,7 +60,7 @@ namespace Server.Spells.Second * even after dying�until you �turn them off� by casting them again. */ - if (m_Table.Remove(target, out var mods)) + if (_table.Remove(target, out var mods)) { target.PlaySound(0x1ED); target.FixedParticles(0x375A, 9, 20, 5016, EffectLayer.Waist); @@ -89,7 +89,7 @@ namespace Server.Spells.Second ) ); - m_Table[target] = mods; + _table[target] = mods; Registry[target] = 1000; // 100.0% protection from disruption target.AddResistanceMod(mods.Item1); @@ -104,7 +104,7 @@ namespace Server.Spells.Second public static void EndProtection(Mobile m) { - if (!m_Table.Remove(m, out var mods)) + if (!_table.Remove(m, out var mods)) { return; } diff --git a/Projects/UOContent/Spells/Seventh/Polymorph.cs b/Projects/UOContent/Spells/Seventh/Polymorph.cs index f53deedcd..e4631aec0 100644 --- a/Projects/UOContent/Spells/Seventh/Polymorph.cs +++ b/Projects/UOContent/Spells/Seventh/Polymorph.cs @@ -19,7 +19,7 @@ namespace Server.Spells.Seventh Reagent.MandrakeRoot ); - private static readonly Dictionary m_Table = new(); + private static readonly Dictionary _table = new(); private readonly int m_NewBody; @@ -170,7 +170,7 @@ namespace Server.Spells.Seventh var duration = Math.Max((int)caster.Skills.Magery.Value, 120); Timer.StartTimer(TimeSpan.FromSeconds(duration), () => EndPolymorph(caster), out var timerToken); - m_Table[caster] = timerToken; + _table[caster] = timerToken; } } } @@ -185,7 +185,7 @@ namespace Server.Spells.Seventh public static void StopTimer(Mobile m) { - if (m_Table.Remove(m, out var timer)) + if (_table.Remove(m, out var timer)) { timer.Cancel(); } diff --git a/Projects/UOContent/Spells/Sixth/Invisibility.cs b/Projects/UOContent/Spells/Sixth/Invisibility.cs index 1fd01bfcd..f7d545538 100644 --- a/Projects/UOContent/Spells/Sixth/Invisibility.cs +++ b/Projects/UOContent/Spells/Sixth/Invisibility.cs @@ -18,7 +18,7 @@ namespace Server.Spells.Sixth Reagent.Nightshade ); - private static readonly Dictionary m_Table = new(); + private static readonly Dictionary _table = new(); public InvisibilitySpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { @@ -65,7 +65,7 @@ namespace Server.Spells.Sixth out var timerToken ); - m_Table[m] = timerToken; + _table[m] = timerToken; } FinishSequence(); @@ -87,11 +87,11 @@ namespace Server.Spells.Sixth Caster.Target = new SpellTargetMobile(this, TargetFlags.Beneficial, Core.ML ? 10 : 12); } - public static bool HasTimer(Mobile m) => m_Table.ContainsKey(m); + public static bool HasTimer(Mobile m) => _table.ContainsKey(m); public static void StopTimer(Mobile m) { - if (m_Table.Remove(m, out var timerToken)) + if (_table.Remove(m, out var timerToken)) { timerToken.Cancel(); } diff --git a/Projects/UOContent/Spells/Spellweaving/AttuneWeapon.cs b/Projects/UOContent/Spells/Spellweaving/AttuneWeapon.cs index fcd22bc9b..1adc28c12 100644 --- a/Projects/UOContent/Spells/Spellweaving/AttuneWeapon.cs +++ b/Projects/UOContent/Spells/Spellweaving/AttuneWeapon.cs @@ -11,7 +11,7 @@ namespace Server.Spells.Spellweaving -1 ); - private static readonly Dictionary m_Table = new(); + private static readonly Dictionary _table = new(); public AttuneWeaponSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) @@ -25,7 +25,7 @@ namespace Server.Spells.Spellweaving public override bool CheckCast() { - if (m_Table.ContainsKey(Caster)) + if (_table.ContainsKey(Caster)) { Caster.SendLocalizedMessage(501775); // This spell is already in effect. return false; @@ -58,7 +58,7 @@ namespace Server.Spells.Spellweaving var t = new ExpireTimer(Caster, duration); t.Start(); - m_Table[Caster] = t; + _table[Caster] = t; Caster.BeginAction(); @@ -94,11 +94,11 @@ namespace Server.Spells.Spellweaving } } - public static bool IsAbsorbing(Mobile m) => m_Table.ContainsKey(m); + public static bool IsAbsorbing(Mobile m) => _table.ContainsKey(m); public static void StopAbsorbing(Mobile m, bool message) { - if (m_Table.TryGetValue(m, out var t)) + if (_table.TryGetValue(m, out var t)) { t.DoExpire(message); } @@ -129,7 +129,7 @@ namespace Server.Spells.Spellweaving m_Mobile.PlaySound(0x1F8); } - m_Table.Remove(m_Mobile); + _table.Remove(m_Mobile); StartTimer(TimeSpan.FromSeconds(120), m_Mobile.EndAction); BuffInfo.RemoveBuff(m_Mobile, BuffIcon.AttuneWeapon); diff --git a/Projects/UOContent/Spells/Spellweaving/EssenceOfWind.cs b/Projects/UOContent/Spells/Spellweaving/EssenceOfWind.cs index 7f676a578..c5f2c4698 100644 --- a/Projects/UOContent/Spells/Spellweaving/EssenceOfWind.cs +++ b/Projects/UOContent/Spells/Spellweaving/EssenceOfWind.cs @@ -7,7 +7,7 @@ namespace Server.Spells.Spellweaving { private static readonly SpellInfo _info = new("Essence of Wind", "Anathrae", -1); - private static readonly Dictionary m_Table = new(); + private static readonly Dictionary _table = new(); public EssenceOfWindSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { @@ -56,7 +56,7 @@ namespace Server.Spells.Spellweaving var t = new EssenceOfWindTimer(m, fcMalus, ssiMalus, duration); t.Start(); - m_Table[m] = t; + _table[m] = t; BuffInfo.AddBuff( m, @@ -76,15 +76,15 @@ namespace Server.Spells.Spellweaving FinishSequence(); } - public static int GetFCMalus(Mobile m) => m_Table.TryGetValue(m, out var timer) ? timer._fcMalus : 0; + public static int GetFCMalus(Mobile m) => _table.TryGetValue(m, out var timer) ? timer._fcMalus : 0; - public static int GetSSIMalus(Mobile m) => m_Table.TryGetValue(m, out var timer) ? timer._ssiMalus : 0; + public static int GetSSIMalus(Mobile m) => _table.TryGetValue(m, out var timer) ? timer._ssiMalus : 0; - public static bool IsDebuffed(Mobile m) => m_Table.ContainsKey(m); + public static bool IsDebuffed(Mobile m) => _table.ContainsKey(m); public static void StopDebuffing(Mobile m, bool message) { - if (m_Table.TryGetValue(m, out var timer)) + if (_table.TryGetValue(m, out var timer)) { timer.DoExpire(message); } @@ -111,7 +111,7 @@ namespace Server.Spells.Spellweaving internal void DoExpire(bool message = true) { Stop(); - m_Table.Remove(_defender); + _table.Remove(_defender); BuffInfo.RemoveBuff(_defender, BuffIcon.EssenceOfWind); } diff --git a/Projects/UOContent/Spells/Spellweaving/GiftOfLife.cs b/Projects/UOContent/Spells/Spellweaving/GiftOfLife.cs index 55623c555..3367d4c3e 100644 --- a/Projects/UOContent/Spells/Spellweaving/GiftOfLife.cs +++ b/Projects/UOContent/Spells/Spellweaving/GiftOfLife.cs @@ -14,7 +14,7 @@ namespace Server.Spells.Spellweaving -1 ); - private static readonly Dictionary m_Table = new(); + private static readonly Dictionary _table = new(); public GiftOfLifeSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) @@ -38,7 +38,7 @@ namespace Server.Spells.Spellweaving { Caster.SendLocalizedMessage(1072077); // You may only cast this spell on yourself or a bonded pet. } - else if (m_Table.ContainsKey(m)) + else if (_table.ContainsKey(m)) { Caster.SendLocalizedMessage(501775); // This spell is already in effect. } @@ -65,7 +65,7 @@ namespace Server.Spells.Spellweaving var t = new ExpireTimer(m, duration, this); t.Start(); - m_Table[m] = t; + _table[m] = t; BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.GiftOfLife, 1031615, 1075807, duration, m, null, true)); } @@ -85,7 +85,7 @@ namespace Server.Spells.Spellweaving public static void HandleDeath(Mobile m) { - if (m_Table.ContainsKey(m)) + if (_table.ContainsKey(m)) { Timer.StartTimer(TimeSpan.FromSeconds(Utility.RandomMinMax(2, 4)), () => HandleDeath_OnCallback(m)); } @@ -93,7 +93,7 @@ namespace Server.Spells.Spellweaving private static void HandleDeath_OnCallback(Mobile m) { - if (!m_Table.TryGetValue(m, out var timer)) + if (!_table.TryGetValue(m, out var timer)) { return; } @@ -138,7 +138,7 @@ namespace Server.Spells.Spellweaving public static void OnLogin(Mobile m) { - if (m?.Alive != false || m_Table[m] == null) + if (m?.Alive != false || _table[m] == null) { return; } @@ -169,7 +169,7 @@ namespace Server.Spells.Spellweaving Stop(); m_Mobile.SendLocalizedMessage(1074776); // You are no longer protected with Gift of Life. - m_Table.Remove(m_Mobile); + _table.Remove(m_Mobile); BuffInfo.RemoveBuff(m_Mobile, BuffIcon.GiftOfLife); } diff --git a/Projects/UOContent/Spells/Spellweaving/GiftOfRenewal.cs b/Projects/UOContent/Spells/Spellweaving/GiftOfRenewal.cs index e99471fcd..26b2917f8 100644 --- a/Projects/UOContent/Spells/Spellweaving/GiftOfRenewal.cs +++ b/Projects/UOContent/Spells/Spellweaving/GiftOfRenewal.cs @@ -12,7 +12,7 @@ namespace Server.Spells.Spellweaving -1 ); - private static readonly Dictionary m_Table = new(); + private static readonly Dictionary _table = new(); public GiftOfRenewalSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) @@ -26,7 +26,7 @@ namespace Server.Spells.Spellweaving public void Target(Mobile m) { - if (m_Table.ContainsKey(m)) + if (_table.ContainsKey(m)) { Caster.SendLocalizedMessage(501775); // This spell is already in effect. } @@ -54,7 +54,7 @@ namespace Server.Spells.Spellweaving var t = new GiftOfRenewalTimer(Caster, m, hitsPerRound, duration); - m_Table[m] = t; + _table[m] = t; t.Start(); @@ -79,7 +79,7 @@ namespace Server.Spells.Spellweaving { BuffInfo.RemoveBuff(m, BuffIcon.GiftOfRenewal); - if (m_Table.Remove(m, out var timer)) + if (_table.Remove(m, out var timer)) { timer.Stop(); Timer.StartTimer(TimeSpan.FromSeconds(60), timer.m_Caster.EndAction); @@ -115,7 +115,7 @@ namespace Server.Spells.Spellweaving var m = m_Mobile; - if (!m_Table.ContainsKey(m)) + if (!_table.ContainsKey(m)) { Stop(); return; diff --git a/Projects/UOContent/Spells/Spellweaving/ImmolatingWeapon.cs b/Projects/UOContent/Spells/Spellweaving/ImmolatingWeapon.cs index 10ce95d8d..33b1a58cc 100644 --- a/Projects/UOContent/Spells/Spellweaving/ImmolatingWeapon.cs +++ b/Projects/UOContent/Spells/Spellweaving/ImmolatingWeapon.cs @@ -12,7 +12,7 @@ namespace Server.Spells.Spellweaving -1 ); - private static readonly Dictionary m_Table = new(); + private static readonly Dictionary _table = new(); public ImmolatingWeaponSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) @@ -54,7 +54,7 @@ namespace Server.Spells.Spellweaving var damage = 5 + (int)(skill / 24) + FocusLevel; var t = new ImmolatingWeaponTimer(TimeSpan.FromSeconds(duration), damage, Caster, weapon); - m_Table[weapon] = t; + _table[weapon] = t; t.Start(); weapon.InvalidateProperties(); @@ -64,14 +64,14 @@ namespace Server.Spells.Spellweaving FinishSequence(); } - public static bool IsImmolating(BaseWeapon weapon) => m_Table.ContainsKey(weapon); + public static bool IsImmolating(BaseWeapon weapon) => _table.ContainsKey(weapon); public static int GetImmolatingDamage(BaseWeapon weapon) => - m_Table.TryGetValue(weapon, out var entry) ? entry._damage : 0; + _table.TryGetValue(weapon, out var entry) ? entry._damage : 0; public static void DoEffect(BaseWeapon weapon, Mobile target) { - if (m_Table.Remove(weapon, out var timer)) + if (_table.Remove(weapon, out var timer)) { timer.Stop(); @@ -86,7 +86,7 @@ namespace Server.Spells.Spellweaving public static void StopImmolating(BaseWeapon weapon) { - if (m_Table.Remove(weapon, out var timer)) + if (_table.Remove(weapon, out var timer)) { timer._caster?.PlaySound(0x27); timer.Stop(); diff --git a/Projects/UOContent/Spells/Spellweaving/Thunderstorm.cs b/Projects/UOContent/Spells/Spellweaving/Thunderstorm.cs index c69e01f50..8b198a2f9 100644 --- a/Projects/UOContent/Spells/Spellweaving/Thunderstorm.cs +++ b/Projects/UOContent/Spells/Spellweaving/Thunderstorm.cs @@ -11,7 +11,7 @@ namespace Server.Spells.Spellweaving -1 ); - private static readonly Dictionary m_Table = new(); + private static readonly Dictionary _table = new(); public ThunderstormSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) @@ -66,7 +66,7 @@ namespace Server.Spells.Spellweaving StopTimer(m); Timer.StartTimer(duration, () => DoExpire(m), out var timerToken); - m_Table[m] = timerToken; + _table[m] = timerToken; BuffInfo.AddBuff( m, @@ -80,11 +80,11 @@ namespace Server.Spells.Spellweaving FinishSequence(); } - public static int GetCastRecoveryMalus(Mobile m) => m_Table.ContainsKey(m) ? 6 : 0; + public static int GetCastRecoveryMalus(Mobile m) => _table.ContainsKey(m) ? 6 : 0; private static void StopTimer(Mobile m) { - if (m_Table.Remove(m, out var timerToken)) + if (_table.Remove(m, out var timerToken)) { timerToken.Cancel(); } From 239dda4b3bf8c35ff936f98b7bcde4d175e1a1c8 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 14 Nov 2021 21:07:54 -0800 Subject: [PATCH 012/213] fix: Cleans up spell targeting (#851) --- Projects/UOContent/Spells/Base/Spell.cs | 25 ++++++------------- .../UOContent/Spells/Eighth/EnergyVortex.cs | 2 +- .../UOContent/Spells/Fifth/BladeSpirits.cs | 2 +- .../UOContent/Spells/Fifth/DispelField.cs | 2 +- .../UOContent/Spells/Fifth/PoisonField.cs | 2 +- Projects/UOContent/Spells/Fourth/ArchCure.cs | 2 +- .../UOContent/Spells/Fourth/ArchProtection.cs | 2 +- Projects/UOContent/Spells/Fourth/FireField.cs | 2 +- .../Spells/Necromancy/AnimateDeadSpell.cs | 2 +- Projects/UOContent/Spells/Second/MagicTrap.cs | 2 +- .../UOContent/Spells/Second/RemoveTrap.cs | 2 +- .../Spells/Seventh/ChainLightning.cs | 2 +- .../UOContent/Spells/Seventh/EnergyField.cs | 2 +- .../UOContent/Spells/Seventh/MassDispel.cs | 2 +- .../UOContent/Spells/Seventh/MeteorSwarm.cs | 2 +- Projects/UOContent/Spells/Sixth/Mark.cs | 2 +- Projects/UOContent/Spells/Sixth/MassCurse.cs | 2 +- .../UOContent/Spells/Sixth/ParalyzeField.cs | 2 +- Projects/UOContent/Spells/Sixth/Reveal.cs | 2 +- .../Spells/Targeting/RecallSpellTarget.cs | 16 ++++++------ .../Spells/Targeting/SpellTargetItem.cs | 12 ++++----- .../Spells/Targeting/SpellTargetMobile.cs | 10 ++++---- .../Spells/Targeting/SpellTargetPoint3D.cs | 22 ++++++++-------- Projects/UOContent/Spells/Third/MagicLock.cs | 2 +- .../UOContent/Spells/Third/Telekinesis.cs | 2 +- Projects/UOContent/Spells/Third/Teleport.cs | 2 +- Projects/UOContent/Spells/Third/Unlock.cs | 2 +- .../UOContent/Spells/Third/WallOfStone.cs | 2 +- 28 files changed, 61 insertions(+), 70 deletions(-) diff --git a/Projects/UOContent/Spells/Base/Spell.cs b/Projects/UOContent/Spells/Base/Spell.cs index 4be93b9b3..85c8c4ceb 100644 --- a/Projects/UOContent/Spells/Base/Spell.cs +++ b/Projects/UOContent/Spells/Base/Spell.cs @@ -377,20 +377,19 @@ namespace Server.Spells return; } + if (!firstCircle && !Core.AOS && (this as MagerySpell)?.Circle == SpellCircle.First) + { + return; + } + + State = SpellState.None; + Caster.Spell = null; + if (State == SpellState.Casting) { - if (!firstCircle && !Core.AOS && this is MagerySpell && ((MagerySpell)this).Circle == SpellCircle.First) - { - return; - } - - State = SpellState.None; - Caster.Spell = null; - OnDisturb(type, true); m_CastTimer?.Stop(); - m_AnimTimer?.Stop(); if (Core.AOS && Caster.Player && type == DisturbType.Hurt) @@ -402,14 +401,6 @@ namespace Server.Spells } else if (State == SpellState.Sequencing) { - if (!firstCircle && !Core.AOS && this is MagerySpell && ((MagerySpell)this).Circle == SpellCircle.First) - { - return; - } - - State = SpellState.None; - Caster.Spell = null; - OnDisturb(type, false); Target.Cancel(Caster); diff --git a/Projects/UOContent/Spells/Eighth/EnergyVortex.cs b/Projects/UOContent/Spells/Eighth/EnergyVortex.cs index 812f67bf0..f2d917b61 100644 --- a/Projects/UOContent/Spells/Eighth/EnergyVortex.cs +++ b/Projects/UOContent/Spells/Eighth/EnergyVortex.cs @@ -70,7 +70,7 @@ namespace Server.Spells.Eighth public override void OnCast() { - Caster.Target = new SpellTargetPoint3D(this); + Caster.Target = new SpellTargetPoint3D(this, retryOnLOS: true); } } } diff --git a/Projects/UOContent/Spells/Fifth/BladeSpirits.cs b/Projects/UOContent/Spells/Fifth/BladeSpirits.cs index 296752d60..6bf8cf6a0 100644 --- a/Projects/UOContent/Spells/Fifth/BladeSpirits.cs +++ b/Projects/UOContent/Spells/Fifth/BladeSpirits.cs @@ -79,7 +79,7 @@ namespace Server.Spells.Fifth public override void OnCast() { - Caster.Target = new SpellTargetPoint3D(this); + Caster.Target = new SpellTargetPoint3D(this, retryOnLOS: true); } } } diff --git a/Projects/UOContent/Spells/Fifth/DispelField.cs b/Projects/UOContent/Spells/Fifth/DispelField.cs index cd7c3240c..ff0241410 100644 --- a/Projects/UOContent/Spells/Fifth/DispelField.cs +++ b/Projects/UOContent/Spells/Fifth/DispelField.cs @@ -54,7 +54,7 @@ namespace Server.Spells.Fifth public override void OnCast() { - Caster.Target = new SpellTargetItem(this, TargetFlags.None, Core.ML ? 10 : 12); + Caster.Target = new SpellTargetItem(this, range: Core.ML ? 10 : 12); } } } diff --git a/Projects/UOContent/Spells/Fifth/PoisonField.cs b/Projects/UOContent/Spells/Fifth/PoisonField.cs index 1c7ceb92a..bbc26fb85 100644 --- a/Projects/UOContent/Spells/Fifth/PoisonField.cs +++ b/Projects/UOContent/Spells/Fifth/PoisonField.cs @@ -55,7 +55,7 @@ namespace Server.Spells.Fifth public override void OnCast() { - Caster.Target = new SpellTargetPoint3D(this, TargetFlags.None, Core.ML ? 10 : 12, false); + Caster.Target = new SpellTargetPoint3D(this, range: Core.ML ? 10 : 12); } [DispellableField] diff --git a/Projects/UOContent/Spells/Fourth/ArchCure.cs b/Projects/UOContent/Spells/Fourth/ArchCure.cs index 9b618138f..f7be3f3e9 100644 --- a/Projects/UOContent/Spells/Fourth/ArchCure.cs +++ b/Projects/UOContent/Spells/Fourth/ArchCure.cs @@ -100,7 +100,7 @@ namespace Server.Spells.Fourth public override void OnCast() { - Caster.Target = new SpellTargetPoint3D(this, TargetFlags.None, Core.ML ? 10 : 12); + Caster.Target = new SpellTargetPoint3D(this, range: Core.ML ? 10 : 12); } private bool AreaCanTarget(Mobile target, bool feluccaRules) diff --git a/Projects/UOContent/Spells/Fourth/ArchProtection.cs b/Projects/UOContent/Spells/Fourth/ArchProtection.cs index a9ae7f7bb..a798ad83b 100644 --- a/Projects/UOContent/Spells/Fourth/ArchProtection.cs +++ b/Projects/UOContent/Spells/Fourth/ArchProtection.cs @@ -103,7 +103,7 @@ namespace Server.Spells.Fourth public override void OnCast() { - Caster.Target = new SpellTargetPoint3D(this, TargetFlags.None, Core.ML ? 10 : 12); + Caster.Target = new SpellTargetPoint3D(this, range: Core.ML ? 10 : 12); } private static void AddEntry(Mobile m, int v) diff --git a/Projects/UOContent/Spells/Fourth/FireField.cs b/Projects/UOContent/Spells/Fourth/FireField.cs index c06739a78..e685fd6c0 100644 --- a/Projects/UOContent/Spells/Fourth/FireField.cs +++ b/Projects/UOContent/Spells/Fourth/FireField.cs @@ -64,7 +64,7 @@ namespace Server.Spells.Fourth public override void OnCast() { - Caster.Target = new SpellTargetPoint3D(this, TargetFlags.None, Core.ML ? 10 : 12); + Caster.Target = new SpellTargetPoint3D(this, range: Core.ML ? 10 : 12); } [DispellableField] diff --git a/Projects/UOContent/Spells/Necromancy/AnimateDeadSpell.cs b/Projects/UOContent/Spells/Necromancy/AnimateDeadSpell.cs index dc2740166..47448544b 100644 --- a/Projects/UOContent/Spells/Necromancy/AnimateDeadSpell.cs +++ b/Projects/UOContent/Spells/Necromancy/AnimateDeadSpell.cs @@ -206,7 +206,7 @@ namespace Server.Spells.Necromancy public override void OnCast() { - Caster.Target = new SpellTargetItem(this, TargetFlags.None, Core.ML ? 10 : 12); + Caster.Target = new SpellTargetItem(this, range: Core.ML ? 10 : 12); Caster.SendLocalizedMessage(1061083); // Animate what corpse? } diff --git a/Projects/UOContent/Spells/Second/MagicTrap.cs b/Projects/UOContent/Spells/Second/MagicTrap.cs index 259cfcad0..13200240f 100644 --- a/Projects/UOContent/Spells/Second/MagicTrap.cs +++ b/Projects/UOContent/Spells/Second/MagicTrap.cs @@ -85,7 +85,7 @@ namespace Server.Spells.Second public override void OnCast() { - Caster.Target = new SpellTargetItem(this, TargetFlags.None, Core.ML ? 10 : 12); + Caster.Target = new SpellTargetItem(this, range: Core.ML ? 10 : 12); } } } diff --git a/Projects/UOContent/Spells/Second/RemoveTrap.cs b/Projects/UOContent/Spells/Second/RemoveTrap.cs index c684e603c..3850205c0 100644 --- a/Projects/UOContent/Spells/Second/RemoveTrap.cs +++ b/Projects/UOContent/Spells/Second/RemoveTrap.cs @@ -55,7 +55,7 @@ namespace Server.Spells.Second public override void OnCast() { - Caster.Target = new SpellTargetItem(this, TargetFlags.None, Core.ML ? 10 : 12); + Caster.Target = new SpellTargetItem(this, range: Core.ML ? 10 : 12); Caster.SendMessage("What do you wish to untrap?"); // TODO: Localization? } } diff --git a/Projects/UOContent/Spells/Seventh/ChainLightning.cs b/Projects/UOContent/Spells/Seventh/ChainLightning.cs index 7251597aa..0286729fe 100644 --- a/Projects/UOContent/Spells/Seventh/ChainLightning.cs +++ b/Projects/UOContent/Spells/Seventh/ChainLightning.cs @@ -119,7 +119,7 @@ namespace Server.Spells.Seventh public override void OnCast() { - Caster.Target = new SpellTargetPoint3D(this, TargetFlags.None, Core.ML ? 10 : 12); + Caster.Target = new SpellTargetPoint3D(this, range: Core.ML ? 10 : 12); } } } diff --git a/Projects/UOContent/Spells/Seventh/EnergyField.cs b/Projects/UOContent/Spells/Seventh/EnergyField.cs index 8e6489779..98177d63f 100644 --- a/Projects/UOContent/Spells/Seventh/EnergyField.cs +++ b/Projects/UOContent/Spells/Seventh/EnergyField.cs @@ -82,7 +82,7 @@ namespace Server.Spells.Seventh public override void OnCast() { - Caster.Target = new SpellTargetPoint3D(this, TargetFlags.None, Core.ML ? 10 : 12); + Caster.Target = new SpellTargetPoint3D(this, range: Core.ML ? 10 : 12); } [DispellableField] diff --git a/Projects/UOContent/Spells/Seventh/MassDispel.cs b/Projects/UOContent/Spells/Seventh/MassDispel.cs index fad116d3d..8a1b3b164 100644 --- a/Projects/UOContent/Spells/Seventh/MassDispel.cs +++ b/Projects/UOContent/Spells/Seventh/MassDispel.cs @@ -77,7 +77,7 @@ namespace Server.Spells.Seventh public override void OnCast() { - Caster.Target = new SpellTargetPoint3D(this, TargetFlags.None, Core.ML ? 10 : 12); + Caster.Target = new SpellTargetPoint3D(this, range: Core.ML ? 10 : 12); } } } diff --git a/Projects/UOContent/Spells/Seventh/MeteorSwarm.cs b/Projects/UOContent/Spells/Seventh/MeteorSwarm.cs index 10e3d5530..1d6e56825 100644 --- a/Projects/UOContent/Spells/Seventh/MeteorSwarm.cs +++ b/Projects/UOContent/Spells/Seventh/MeteorSwarm.cs @@ -119,7 +119,7 @@ namespace Server.Spells.Seventh public override void OnCast() { - Caster.Target = new SpellTargetPoint3D(this, TargetFlags.None, Core.ML ? 10 : 12); + Caster.Target = new SpellTargetPoint3D(this, range: Core.ML ? 10 : 12); } } } diff --git a/Projects/UOContent/Spells/Sixth/Mark.cs b/Projects/UOContent/Spells/Sixth/Mark.cs index 7a4fb4e36..0f8d7d6a1 100644 --- a/Projects/UOContent/Spells/Sixth/Mark.cs +++ b/Projects/UOContent/Spells/Sixth/Mark.cs @@ -61,7 +61,7 @@ namespace Server.Spells.Sixth public override void OnCast() { - Caster.Target = new SpellTargetItem(this, TargetFlags.None, Core.ML ? 10 : 12); + Caster.Target = new SpellTargetItem(this, range: Core.ML ? 10 : 12); } public override bool CheckCast() => base.CheckCast() && SpellHelper.CheckTravel(Caster, TravelCheckType.Mark); diff --git a/Projects/UOContent/Spells/Sixth/MassCurse.cs b/Projects/UOContent/Spells/Sixth/MassCurse.cs index ee2e8ba38..bbd7e183e 100644 --- a/Projects/UOContent/Spells/Sixth/MassCurse.cs +++ b/Projects/UOContent/Spells/Sixth/MassCurse.cs @@ -67,7 +67,7 @@ namespace Server.Spells.Sixth public override void OnCast() { - Caster.Target = new SpellTargetPoint3D(this, TargetFlags.None, Core.ML ? 10 : 12); + Caster.Target = new SpellTargetPoint3D(this, range: Core.ML ? 10 : 12); } } } diff --git a/Projects/UOContent/Spells/Sixth/ParalyzeField.cs b/Projects/UOContent/Spells/Sixth/ParalyzeField.cs index 0cff8699c..475bc4406 100644 --- a/Projects/UOContent/Spells/Sixth/ParalyzeField.cs +++ b/Projects/UOContent/Spells/Sixth/ParalyzeField.cs @@ -68,7 +68,7 @@ namespace Server.Spells.Sixth public override void OnCast() { - Caster.Target = new SpellTargetPoint3D(this, TargetFlags.None, Core.ML ? 10 : 12); + Caster.Target = new SpellTargetPoint3D(this, range: Core.ML ? 10 : 12); } [DispellableField] diff --git a/Projects/UOContent/Spells/Sixth/Reveal.cs b/Projects/UOContent/Spells/Sixth/Reveal.cs index c95539c77..653594d25 100644 --- a/Projects/UOContent/Spells/Sixth/Reveal.cs +++ b/Projects/UOContent/Spells/Sixth/Reveal.cs @@ -60,7 +60,7 @@ namespace Server.Spells.Sixth public override void OnCast() { - Caster.Target = new SpellTargetPoint3D(this, TargetFlags.None, Core.ML ? 10 : 12); + Caster.Target = new SpellTargetPoint3D(this, range: Core.ML ? 10 : 12); } // Reveal uses magery and detect hidden vs. hide and stealth diff --git a/Projects/UOContent/Spells/Targeting/RecallSpellTarget.cs b/Projects/UOContent/Spells/Targeting/RecallSpellTarget.cs index 2a43e6ea4..4e6b61090 100644 --- a/Projects/UOContent/Spells/Targeting/RecallSpellTarget.cs +++ b/Projects/UOContent/Spells/Targeting/RecallSpellTarget.cs @@ -7,14 +7,14 @@ namespace Server.Spells { public class RecallSpellTarget : Target { - private readonly IRecallSpell m_Spell; + private readonly IRecallSpell _spell; private readonly bool m_ToBoat; public RecallSpellTarget(IRecallSpell spell, bool toBoat = true) : base(Core.ML ? 10 : 12, false, TargetFlags.None) { - m_Spell = spell; + _spell = spell; m_ToBoat = toBoat; - m_Spell.Caster.LocalOverheadMessage(MessageType.Regular, 0x3B2, 501029); // Select Marked item. + _spell.Caster.LocalOverheadMessage(MessageType.Regular, 0x3B2, 501029); // Select Marked item. } protected override void OnTarget(Mobile from, object o) @@ -23,7 +23,7 @@ namespace Server.Spells { if (rune.Marked) { - m_Spell.Effect(rune.Target, rune.TargetMap, true); + _spell.Effect(rune.Target, rune.TargetMap, true); } else { @@ -36,7 +36,7 @@ namespace Server.Spells if (e != null) { - m_Spell.Effect(e.Location, e.Map, true); + _spell.Effect(e.Location, e.Map, true); } else { @@ -47,7 +47,7 @@ namespace Server.Spells { if (!boat.Deleted && boat.CheckKey(key.KeyValue)) { - m_Spell.Effect(boat.GetMarkedLocation(), boat.Map, false); + _spell.Effect(boat.GetMarkedLocation(), boat.Map, false); } else { @@ -64,7 +64,7 @@ namespace Server.Spells } else if (o is HouseRaffleDeed deed && deed.ValidLocation()) { - m_Spell.Effect(deed.PlotLocation, deed.PlotFacet, true); + _spell.Effect(deed.PlotLocation, deed.PlotFacet, true); } else { @@ -86,7 +86,7 @@ namespace Server.Spells protected override void OnTargetFinish(Mobile from) { - m_Spell?.FinishSequence(); + _spell?.FinishSequence(); } } } diff --git a/Projects/UOContent/Spells/Targeting/SpellTargetItem.cs b/Projects/UOContent/Spells/Targeting/SpellTargetItem.cs index 0130beda4..0bab04b1d 100644 --- a/Projects/UOContent/Spells/Targeting/SpellTargetItem.cs +++ b/Projects/UOContent/Spells/Targeting/SpellTargetItem.cs @@ -9,24 +9,24 @@ namespace Server.Spells public class SpellTargetItem : Target, ISpellTarget { - private readonly ISpellTargetingItem m_Spell; + private readonly ISpellTargetingItem _spell; - public SpellTargetItem(ISpellTargetingItem spell, TargetFlags flags, int range = 12) : base(range, false, flags) => - m_Spell = spell; + public SpellTargetItem(ISpellTargetingItem spell, TargetFlags flags = TargetFlags.None, int range = 12) + : base(range, false, flags) => _spell = spell; - public ISpell Spell => m_Spell; + public ISpell Spell => _spell; protected override void OnTarget(Mobile from, object o) { if (o is Item item) { - m_Spell.Target(item); + _spell.Target(item); } } protected override void OnTargetFinish(Mobile from) { - m_Spell?.FinishSequence(); + _spell?.FinishSequence(); } } } diff --git a/Projects/UOContent/Spells/Targeting/SpellTargetMobile.cs b/Projects/UOContent/Spells/Targeting/SpellTargetMobile.cs index e5758e734..b8e245cf7 100644 --- a/Projects/UOContent/Spells/Targeting/SpellTargetMobile.cs +++ b/Projects/UOContent/Spells/Targeting/SpellTargetMobile.cs @@ -9,21 +9,21 @@ namespace Server.Spells public class SpellTargetMobile : Target, ISpellTarget { - private readonly ISpellTargetingMobile m_Spell; + private readonly ISpellTargetingMobile _spell; public SpellTargetMobile(ISpellTargetingMobile spell, TargetFlags flags, int range = 12) : - base(range, false, flags) => m_Spell = spell; + base(range, false, flags) => _spell = spell; - public ISpell Spell => m_Spell; + public ISpell Spell => _spell; protected override void OnTarget(Mobile from, object o) { - m_Spell.Target(o as Mobile); + _spell.Target(o as Mobile); } protected override void OnTargetFinish(Mobile from) { - m_Spell?.FinishSequence(); + _spell?.FinishSequence(); } } } diff --git a/Projects/UOContent/Spells/Targeting/SpellTargetPoint3D.cs b/Projects/UOContent/Spells/Targeting/SpellTargetPoint3D.cs index 8c9a03283..40da7d383 100644 --- a/Projects/UOContent/Spells/Targeting/SpellTargetPoint3D.cs +++ b/Projects/UOContent/Spells/Targeting/SpellTargetPoint3D.cs @@ -9,43 +9,43 @@ namespace Server.Spells public class SpellTargetPoint3D : Target, ISpellTarget { - private readonly bool m_CheckLOS; - private ISpellTargetingPoint3D m_Spell; + private readonly bool _retryOnLos; + private ISpellTargetingPoint3D _spell; public SpellTargetPoint3D( - ISpellTargetingPoint3D spell, TargetFlags flags = TargetFlags.None, int range = 12, bool checkLOS = true + ISpellTargetingPoint3D spell, TargetFlags flags = TargetFlags.None, int range = 12, bool retryOnLOS = false ) : base(range, true, flags) { - m_Spell = spell; - m_CheckLOS = checkLOS; + _spell = spell; + _retryOnLos = retryOnLOS; } - public ISpell Spell => m_Spell; + public ISpell Spell => _spell; protected override void OnTarget(Mobile from, object o) { if (o is IPoint3D p) { - m_Spell.Target(p); + _spell.Target(p); } } protected override void OnTargetOutOfLOS(Mobile from, object o) { - if (!m_CheckLOS) + if (!_retryOnLos) { return; } from.SendLocalizedMessage(501943); // Target cannot be seen. Try again. - from.Target = new SpellTargetPoint3D(m_Spell); + from.Target = new SpellTargetPoint3D(_spell); from.Target.BeginTimeout(from, TimeoutTime - Core.TickCount); - m_Spell = null; // Needed? + _spell = null; // Needed? } protected override void OnTargetFinish(Mobile from) { - m_Spell?.FinishSequence(); + _spell?.FinishSequence(); } } } diff --git a/Projects/UOContent/Spells/Third/MagicLock.cs b/Projects/UOContent/Spells/Third/MagicLock.cs index 040976001..55da042cc 100644 --- a/Projects/UOContent/Spells/Third/MagicLock.cs +++ b/Projects/UOContent/Spells/Third/MagicLock.cs @@ -69,7 +69,7 @@ namespace Server.Spells.Third public override void OnCast() { - Caster.Target = new SpellTargetItem(this, TargetFlags.None, Core.ML ? 10 : 12); + Caster.Target = new SpellTargetItem(this, range: Core.ML ? 10 : 12); } } } diff --git a/Projects/UOContent/Spells/Third/Telekinesis.cs b/Projects/UOContent/Spells/Third/Telekinesis.cs index 37d92c4d9..f41be5a7f 100644 --- a/Projects/UOContent/Spells/Third/Telekinesis.cs +++ b/Projects/UOContent/Spells/Third/Telekinesis.cs @@ -75,7 +75,7 @@ namespace Server.Spells.Third public override void OnCast() { - Caster.Target = new SpellTargetItem(this, TargetFlags.None, Core.ML ? 10 : 12); + Caster.Target = new SpellTargetItem(this, range: Core.ML ? 10 : 12); } } } diff --git a/Projects/UOContent/Spells/Third/Teleport.cs b/Projects/UOContent/Spells/Third/Teleport.cs index 2e1981525..c2797f9f4 100644 --- a/Projects/UOContent/Spells/Third/Teleport.cs +++ b/Projects/UOContent/Spells/Third/Teleport.cs @@ -131,7 +131,7 @@ namespace Server.Spells.Third public override void OnCast() { - Caster.Target = new SpellTargetPoint3D(this, TargetFlags.None, Core.ML ? 10 : 12); + Caster.Target = new SpellTargetPoint3D(this, range: Core.ML ? 10 : 12); } } } diff --git a/Projects/UOContent/Spells/Third/Unlock.cs b/Projects/UOContent/Spells/Third/Unlock.cs index d303b3151..6476bd0c7 100644 --- a/Projects/UOContent/Spells/Third/Unlock.cs +++ b/Projects/UOContent/Spells/Third/Unlock.cs @@ -96,7 +96,7 @@ namespace Server.Spells.Third public override void OnCast() { - Caster.Target = new SpellTargetPoint3D(this, TargetFlags.None, Core.ML ? 10 : 12); + Caster.Target = new SpellTargetPoint3D(this, range: Core.ML ? 10 : 12); } } } diff --git a/Projects/UOContent/Spells/Third/WallOfStone.cs b/Projects/UOContent/Spells/Third/WallOfStone.cs index 271455d05..fd4bd0b2d 100644 --- a/Projects/UOContent/Spells/Third/WallOfStone.cs +++ b/Projects/UOContent/Spells/Third/WallOfStone.cs @@ -60,7 +60,7 @@ namespace Server.Spells.Third public override void OnCast() { - Caster.Target = new SpellTargetPoint3D(this, TargetFlags.None, Core.ML ? 10 : 12); + Caster.Target = new SpellTargetPoint3D(this, range: Core.ML ? 10 : 12); } [DispellableField] From 8c66be9090ce26026dd9d63798897ea9cd8b19ba Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sat, 20 Nov 2021 11:34:46 -0800 Subject: [PATCH 013/213] fix: Cleans up protection (#854) --- .../UOContent/Spells/Second/Protection.cs | 25 ++++++------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/Projects/UOContent/Spells/Second/Protection.cs b/Projects/UOContent/Spells/Second/Protection.cs index 38f1342c7..cecab823d 100644 --- a/Projects/UOContent/Spells/Second/Protection.cs +++ b/Projects/UOContent/Spells/Second/Protection.cs @@ -77,27 +77,18 @@ namespace Server.Spells.Second target.PlaySound(0x1E9); target.FixedParticles(0x375A, 9, 20, 5016, EffectLayer.Waist); - mods = new Tuple( - new ResistanceMod( - ResistanceType.Physical, - -15 + Math.Min((int)(caster.Skills.Inscribe.Value / 20), 15) - ), - new DefaultSkillMod( - SkillName.MagicResist, - true, - -35 + Math.Min((int)(caster.Skills.Inscribe.Value / 20), 35) - ) - ); + var physLoss = Math.Max(0, -15 + (int)(caster.Skills.Inscribe.Value / 20)); + var resistLoss = Math.Max(0, -35 + (int)(caster.Skills.Inscribe.Value / 20)); + var physMod = new ResistanceMod(ResistanceType.Physical, physLoss); + var resistMod = new DefaultSkillMod(SkillName.MagicResist, true, resistLoss); - _table[target] = mods; + _table[target] = Tuple.Create(physMod, resistMod); Registry[target] = 1000; // 100.0% protection from disruption - target.AddResistanceMod(mods.Item1); - target.AddSkillMod(mods.Item2); + target.AddResistanceMod(physmod); + target.AddSkillMod(resistmod); - var physloss = -15 + (int)(caster.Skills.Inscribe.Value / 20); - var resistloss = -35 + (int)(caster.Skills.Inscribe.Value / 20); - var args = $"{physloss}\t{resistloss}"; + var args = $"{physLoss}\t{resistLoss}"; BuffInfo.AddBuff(target, new BuffInfo(BuffIcon.Protection, 1075814, 1075815, args)); } } From 8806d6d7a7a41c90e2eb82d4cadbe2e161f11425 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sat, 20 Nov 2021 11:37:13 -0800 Subject: [PATCH 014/213] fix: Fixes compiling (#855) --- Projects/UOContent/Spells/Second/Protection.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Projects/UOContent/Spells/Second/Protection.cs b/Projects/UOContent/Spells/Second/Protection.cs index cecab823d..7944e3015 100644 --- a/Projects/UOContent/Spells/Second/Protection.cs +++ b/Projects/UOContent/Spells/Second/Protection.cs @@ -85,8 +85,8 @@ namespace Server.Spells.Second _table[target] = Tuple.Create(physMod, resistMod); Registry[target] = 1000; // 100.0% protection from disruption - target.AddResistanceMod(physmod); - target.AddSkillMod(resistmod); + target.AddResistanceMod(physMod); + target.AddSkillMod(resistMod); var args = $"{physLoss}\t{resistLoss}"; BuffInfo.AddBuff(target, new BuffInfo(BuffIcon.Protection, 1075814, 1075815, args)); From 09613e253631a3ca15af3e22b0437bbcfe876ef5 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sat, 20 Nov 2021 14:26:52 -0800 Subject: [PATCH 015/213] fix: Fixes crash in mass dispel (#856) --- Projects/UOContent/Spells/Seventh/MassDispel.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Projects/UOContent/Spells/Seventh/MassDispel.cs b/Projects/UOContent/Spells/Seventh/MassDispel.cs index 8a1b3b164..9e40a0930 100644 --- a/Projects/UOContent/Spells/Seventh/MassDispel.cs +++ b/Projects/UOContent/Spells/Seventh/MassDispel.cs @@ -1,3 +1,4 @@ +using Server.Collections; using Server.Items; using Server.Mobiles; using Server.Targeting; @@ -37,6 +38,8 @@ namespace Server.Spells.Seventh { var eable = map.GetMobilesInRange(new Point3D(p), 8); + using var queue = PooledRefQueue.Create(); + foreach (var bc in eable) { if (!(bc.IsDispellable && Caster.CanBeHarmful(bc, false))) @@ -58,17 +61,21 @@ namespace Server.Spells.Seventh ); Effects.PlaySound(bc, 0x201); - bc.Delete(); + queue.Enqueue(bc); } else { Caster.DoHarmful(bc); - bc.FixedEffect(0x3779, 10, 20); } } eable.Free(); + + while (queue.Count > 0) + { + queue.Dequeue().Delete(); + } } } From 43db0d09c90e78a5d527ccbc0f710d77ea355b32 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 21 Nov 2021 09:19:09 -0800 Subject: [PATCH 016/213] fix: Weapons cleanup (#857) * Removes linq * Removes list allocation for area effect * Removes redundant swing overload * Cleans up code --- Projects/Server/Interfaces.cs | 3 +- .../UOContent/Items/Weapons/BaseWeapon.cs | 381 ++++++++---------- Projects/UOContent/Items/Weapons/Fists.cs | 2 +- .../Items/Weapons/Ranged/BaseRanged.cs | 2 +- 4 files changed, 173 insertions(+), 215 deletions(-) diff --git a/Projects/Server/Interfaces.cs b/Projects/Server/Interfaces.cs index 587abead0..3e46e8bb2 100644 --- a/Projects/Server/Interfaces.cs +++ b/Projects/Server/Interfaces.cs @@ -22,8 +22,7 @@ namespace Server { int MaxRange { get; } void OnBeforeSwing(Mobile attacker, Mobile defender); - TimeSpan OnSwing(Mobile attacker, Mobile defender); - TimeSpan OnSwing(Mobile attacker, Mobile defender, double damageBonus); + TimeSpan OnSwing(Mobile attacker, Mobile defender, double damageBonus = 1.0); void GetStatusDamage(Mobile from, out int min, out int max); } diff --git a/Projects/UOContent/Items/Weapons/BaseWeapon.cs b/Projects/UOContent/Items/Weapons/BaseWeapon.cs index b50b97f32..8e183a7b9 100644 --- a/Projects/UOContent/Items/Weapons/BaseWeapon.cs +++ b/Projects/UOContent/Items/Weapons/BaseWeapon.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using System.Linq; +using Server.Collections; using Server.Engines.Craft; using Server.Ethics; using Server.Factions; @@ -695,8 +695,6 @@ namespace Server.Items } } - public virtual TimeSpan OnSwing(Mobile attacker, Mobile defender) => OnSwing(attacker, defender, 1.0); - public virtual void GetStatusDamage(Mobile from, out int min, out int max) { GetBaseDamageRange(from, out var baseMin, out var baseMax); @@ -713,7 +711,7 @@ namespace Server.Items } } - public virtual TimeSpan OnSwing(Mobile attacker, Mobile defender, double damageBonus) + public virtual TimeSpan OnSwing(Mobile attacker, Mobile defender, double damageBonus = 1.0) { var canSwing = true; @@ -723,12 +721,12 @@ namespace Server.Items if (canSwing) { - canSwing = !(attacker.Spell is Spell sp) || !sp.IsCasting || !sp.BlocksMovement; + canSwing = attacker.Spell is not Spell sp || !sp.IsCasting || !sp.BlocksMovement; } if (canSwing) { - canSwing = !(attacker is PlayerMobile p) || p.PeacedUntil <= Core.Now; + canSwing = attacker is not PlayerMobile p || p.PeacedUntil <= Core.Now; } } @@ -786,7 +784,7 @@ namespace Server.Items public override void OnAfterDuped(Item newItem) { - if (!(newItem is BaseWeapon weap)) + if (newItem is not BaseWeapon weap) { return; } @@ -877,8 +875,8 @@ namespace Server.Items return true; } - if (Layer == Layer.OneHanded && layer == Layer.TwoHanded && !(item is BaseShield) && - !(item is BaseEquipableLight)) + if (Layer == Layer.OneHanded && layer == Layer.TwoHanded && item is not BaseShield && + item is not BaseEquipableLight) { m.SendLocalizedMessage(500215); // You can only wield one weapon at a time. return true; @@ -1096,7 +1094,6 @@ namespace Server.Items var defWeapon = defender.Weapon as BaseWeapon; var atkSkill = attacker.Skills[atkWeapon?.Skill ?? SkillName.Wrestling]; - // Skill defSkill = defender.Skills[defWeapon.Skill]; var atkValue = atkWeapon?.GetAttackSkillValue(attacker, defender) ?? 0.0; var defValue = defWeapon?.GetDefendSkillValue(attacker, defender) ?? 0.0; @@ -1209,23 +1206,11 @@ namespace Server.Items } else { - if (atkValue <= -50.0) - { - atkValue = -49.9; - } - - if (defValue <= -50.0) - { - defValue = -49.9; - } - - ourValue = atkValue + 50.0; - theirValue = defValue + 50.0; + ourValue = Math.Max(0.1, atkValue + 50.0); + theirValue = Math.Max(0.1, defValue + 50.0); } - var chance = ourValue / (theirValue * 2.0); - - chance *= 1.0 + (double)bonus / 100; + var chance = ourValue / (theirValue * 2.0) * 1.0 + (double)bonus / 100; if (Core.AOS && chance < 0.02) { @@ -1418,7 +1403,7 @@ namespace Server.Items return defender.CheckSkill(SkillName.Parry, chance); } - if (defender.Weapon is Fists || defender.Weapon is BaseRanged) + if (defender.Weapon is Server.Items.Fists or BaseRanged) { return false; } @@ -1459,9 +1444,8 @@ namespace Server.Items return defender.CheckSkill(SkillName.Parry, chance); } - return - aosChance > Utility - .RandomDouble(); // Only skillcheck if wielding a shield & there's no effect from Bushido + // Only skillcheck if wielding a shield & there's no effect from Bushido + return aosChance > Utility.RandomDouble(); } public virtual int AbsorbDamageAOS(Mobile attacker, Mobile defender, int damage) @@ -1493,9 +1477,8 @@ namespace Server.Items if (Confidence.IsConfident(defender)) { - defender.SendLocalizedMessage( - 1063117 - ); // Your confidence reassures you as you successfully block your opponent's blow. + // Your confidence reassures you as you successfully block your opponent's blow. + defender.SendLocalizedMessage(1063117); var bushido = defender.Skills.Bushido.Value; @@ -1590,7 +1573,7 @@ namespace Server.Items return 0; } - if (!(attacker is BaseCreature bc) || bc.PackInstinct == PackInstinct.None || !bc.Controlled && !bc.Summoned) + if (attacker is not BaseCreature bc || bc.PackInstinct == PackInstinct.None || !bc.Controlled && !bc.Summoned) { return 0; } @@ -1603,16 +1586,26 @@ namespace Server.Items } var eable = defender.GetMobilesInRange(1); - var inPack = 1 + eable - .Where(m => m != attacker && (m.PackInstinct & bc.PackInstinct) != 0 && (m.Controlled || m.Summoned)) - .Count(m => master == (m.ControlMaster ?? m.SummonMaster) && m.Combatant == defender); + var inPack = 1; + foreach (var m in eable) + { + if (m != attacker && (m.PackInstinct & bc.PackInstinct) != 0 && (m.Controlled || m.Summoned) && + master == (m.ControlMaster ?? m.SummonMaster) && m.Combatant == defender) + { + inPack++; + } + } eable.Free(); - return inPack >= 5 ? 100 : - inPack >= 4 ? 75 : - inPack >= 3 ? 50 : - inPack >= 2 ? 25 : 0; + return inPack switch + { + >= 5 => 100, + 4 => 75, + 3 => 50, + 2 => 25, + _ => 0 + }; } public virtual void OnHit(Mobile attacker, Mobile defender, double damageBonus = 1.0) @@ -1688,12 +1681,9 @@ namespace Server.Items if (!attacker.Player) { - if (defender is PlayerMobile pm) + if (defender is PlayerMobile pm && pm.EnemyOfOneType != null && pm.EnemyOfOneType != attacker.GetType()) { - if (pm.EnemyOfOneType != null && pm.EnemyOfOneType != attacker.GetType()) - { - percentageBonus += 100; - } + percentageBonus += 100; } } else if (!defender.Player) @@ -1769,16 +1759,14 @@ namespace Server.Items { damage = 1; } - else if (Core.AOS && damage == 0) // parried + // Parried + else if (Core.AOS && damage == 0 && a?.Validate(attacker) == true) { - if (a?.Validate(attacker) == true) /*&& a.CheckMana( attacker, true )*/ - // Parried special moves have no mana cost - { - a = null; - WeaponAbility.ClearCurrentAbility(attacker); - - attacker.SendLocalizedMessage(1061140); // Your attack was parried! - } + /*&& a.CheckMana( attacker, true )*/ + // Parried special moves have no mana cost + a = null; + WeaponAbility.ClearCurrentAbility(attacker); + attacker.SendLocalizedMessage(1061140); // Your attack was parried! } AddBlood(attacker, defender, damage); @@ -1936,9 +1924,8 @@ namespace Server.Items if (context?.Type == typeof(WraithFormSpell)) { - wraithLeech = - 5 + (int)(15 * attacker.Skills.SpiritSpeak.Value / - 100); // Wraith form gives an additional 5-20% mana leech + // Wraith form gives an additional 5-20% mana leech + wraithLeech = 5 + (int)(15 * attacker.Skills.SpiritSpeak.Value / 100); // Mana leeched by the Wraith Form spell is actually stolen, not just leeched. defender.Mana -= AOS.Scale(damageGiven, wraithLeech); @@ -1967,10 +1954,10 @@ namespace Server.Items } } - if (m_MaxHits > 0 && (MaxRange <= 1 && (defender is Slime || defender is AcidElemental) || - Utility.RandomDouble() < .04)) // Stratics says 50% chance, seems more like 4%.. + // Stratics says 50% chance, seems more like 4%.. + if (m_MaxHits > 0 && MaxRange <= 1 && defender is Slime or AcidElemental |Utility.RandomDouble() < .04) { - if (MaxRange <= 1 && (defender is Slime || defender is AcidElemental)) + if (MaxRange <= 1 && defender is Slime or AcidElemental) { attacker.LocalOverheadMessage(MessageType.Regular, 0x3B2, 500263); // *Acid blood scars your weapon!* } @@ -1979,29 +1966,23 @@ namespace Server.Items { HitPoints += 2; } + else if (m_Hits > 0) + { + --HitPoints; + } + else if (m_MaxHits > 1) + { + --MaxHitPoints; + + if (Parent is Mobile mobile) + { + // Your equipment is severely damaged. + mobile.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1061121); + } + } else { - if (m_Hits > 0) - { - --HitPoints; - } - else if (m_MaxHits > 1) - { - --MaxHitPoints; - - if (Parent is Mobile mobile) - { - mobile.LocalOverheadMessage( - MessageType.Regular, - 0x3B2, - 1061121 // Your equipment is severely damaged. - ); - } - } - else - { - Delete(); - } + Delete(); } } @@ -2021,16 +2002,20 @@ namespace Server.Items if (Core.AOS) { - var physChance = (int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitPhysicalArea) * - propertyBonus); + var physChance = + (int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitPhysicalArea) * propertyBonus); + var fireChance = (int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitFireArea) * propertyBonus); + var coldChance = (int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitColdArea) * propertyBonus); - var poisChance = (int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitPoisonArea) * - propertyBonus); - var nrgyChance = (int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitEnergyArea) * - propertyBonus); + + var poisChance = + (int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitPoisonArea) * propertyBonus); + + var nrgyChance = + (int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitEnergyArea) * propertyBonus); if (physChance != 0 && physChance > Utility.Random(100)) { @@ -2092,10 +2077,10 @@ namespace Server.Items DoDispel(attacker, defender); } - var laChance = (int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitLowerAttack) * - propertyBonus); - var ldChance = (int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitLowerDefend) * - propertyBonus); + var laChance = + (int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitLowerAttack) * propertyBonus); + var ldChance = + (int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitLowerDefend) * propertyBonus); if (laChance != 0 && laChance > Utility.Random(100)) { @@ -2121,7 +2106,7 @@ namespace Server.Items it.ReceivedHonorContext?.OnTargetHit(attacker); } - if (!(this is BaseRanged)) + if (this is not BaseRanged) { if (AnimalForm.UnderTransformation(attacker, typeof(GiantSerpent))) { @@ -2157,7 +2142,7 @@ namespace Server.Items // SDI bonus damageBonus += AosAttributes.GetValue(attacker, AosAttribute.SpellDamage); - if(PsychicAttack.Registry.TryGetValue(attacker,out var timer)) + if (PsychicAttack.Registry.TryGetValue(attacker,out var timer)) { damageBonus -= timer.SpellDamageMalus; } @@ -2319,13 +2304,8 @@ namespace Server.Items attacker.PlaySound(GetMissAttackSound(attacker, defender)); defender.PlaySound(GetMissDefendSound(attacker, defender)); - var ability = WeaponAbility.GetCurrentAbility(attacker); - - ability?.OnMiss(attacker, defender); - - var move = SpecialMove.GetCurrentMove(attacker); - - move?.OnMiss(attacker, defender); + WeaponAbility.GetCurrentAbility(attacker)?.OnMiss(attacker, defender); + SpecialMove.GetCurrentMove(attacker)?.OnMiss(attacker, defender); if (defender is IHonorTarget target) { @@ -2417,56 +2397,38 @@ namespace Server.Items { var bonus = VirtualDamageBonus; - switch (m_Quality) + bonus += m_Quality switch { - case WeaponQuality.Low: - bonus -= 20; - break; - case WeaponQuality.Exceptional: - bonus += 20; - break; - } + WeaponQuality.Low => -20, + WeaponQuality.Exceptional => 20, + _ => 0 + }; - switch (m_DamageLevel) + return bonus + m_DamageLevel switch { - case WeaponDamageLevel.Ruin: - bonus += 15; - break; - case WeaponDamageLevel.Might: - bonus += 20; - break; - case WeaponDamageLevel.Force: - bonus += 25; - break; - case WeaponDamageLevel.Power: - bonus += 30; - break; - case WeaponDamageLevel.Vanq: - bonus += 35; - break; - } - - return bonus; + WeaponDamageLevel.Ruin => 15, + WeaponDamageLevel.Might => 20, + WeaponDamageLevel.Force => 25, + WeaponDamageLevel.Power => 30, + WeaponDamageLevel.Vanq => 35, + _ => bonus + }; } public virtual double ScaleDamageAOS(Mobile attacker, double damage, bool checkSkills) { if (checkSkills) { - attacker.CheckSkill( - SkillName.Tactics, - 0.0, - attacker.Skills.Tactics.Cap - ); // Passively check tactics for gain - attacker.CheckSkill( - SkillName.Anatomy, - 0.0, - attacker.Skills.Anatomy.Cap - ); // Passively check Anatomy for gain + // Passively check tactics for gain + attacker.CheckSkill(SkillName.Tactics, 0.0, attacker.Skills.Tactics.Cap); + + // Passively check Anatomy for gain + attacker.CheckSkill(SkillName.Anatomy, 0.0, attacker.Skills.Anatomy.Cap); if (Type == WeaponType.Axe) { - attacker.CheckSkill(SkillName.Lumberjacking, 0.0, 100.0); // Passively check Lumberjacking for gain + // Passively check Lumberjacking for gain + attacker.CheckSkill(SkillName.Lumberjacking, 0.0, 100.0); } } @@ -2536,20 +2498,16 @@ namespace Server.Items { if (checkSkills) { - attacker.CheckSkill( - SkillName.Tactics, - 0.0, - attacker.Skills.Tactics.Cap - ); // Passively check tactics for gain - attacker.CheckSkill( - SkillName.Anatomy, - 0.0, - attacker.Skills.Anatomy.Cap - ); // Passively check Anatomy for gain + // Passively check tactics for gain + attacker.CheckSkill(SkillName.Tactics, 0.0, attacker.Skills.Tactics.Cap); + + // Passively check Anatomy for gain + attacker.CheckSkill(SkillName.Anatomy, 0.0, attacker.Skills.Anatomy.Cap); if (Type == WeaponType.Axe) { - attacker.CheckSkill(SkillName.Lumberjacking, 0.0, 100.0); // Passively check Lumberjacking for gain + // Passively check Lumberjacking for gain + attacker.CheckSkill(SkillName.Lumberjacking, 0.0, 100.0); } } @@ -2633,9 +2591,9 @@ namespace Server.Items var damage = (int)ScaleDamageOld(attacker, GetBaseDamage(attacker), true); // pre-AOS, halve damage if the defender is a player or the attacker is not a player - if (defender is PlayerMobile || !(attacker is PlayerMobile)) + if (defender is PlayerMobile || attacker is not PlayerMobile) { - damage = (int)(damage / 2.0); + damage /= 2; } return damage; @@ -2643,6 +2601,11 @@ namespace Server.Items public virtual void PlayHurtAnimation(Mobile from) { + if (from.Mounted) + { + return; + } + int action; int frames; @@ -2667,12 +2630,10 @@ namespace Server.Items frames = 5; break; } - default: return; - } - - if (from.Mounted) - { - return; + default: + { + return; + } } from.Animate(action, frames, 1, true, false, 0); @@ -2695,10 +2656,18 @@ namespace Server.Items switch (Animation) { default: - action = Utility.Random(4, 3); - break; - case WeaponAnimation.ShootBow: return; // 7 - case WeaponAnimation.ShootXBow: return; // 8 + { + action = Utility.Random(4, 3); + break; + } + case WeaponAnimation.ShootBow: + { + return; // 7 + } + case WeaponAnimation.ShootXBow: + { + return; // 8 + } } break; @@ -2728,7 +2697,10 @@ namespace Server.Items break; } - default: return; + default: + { + return; + } } from.Animate(action, 7, 1, true, false, 0); @@ -2739,11 +2711,11 @@ namespace Server.Items public int GetElementalDamageHue() { GetDamageTypes(null, out _, out var fire, out var cold, out var pois, out var nrgy, out _, out _); - // Order is Cold, Energy, Fire, Poison, Physical left var currentMax = 50; var hue = 0; + // Order is Cold, Energy, Fire, Poison, Physical if (pois >= currentMax) { hue = 1267 + (pois - 50) / 10; @@ -2812,7 +2784,7 @@ namespace Server.Items * formatting show, and remove CLILOCs embedded: more like OSI * did with the books that had markup, etc. * - * This will have a negative effect on a few event things imgame + * This will have a negative effect on a few event things in-game * as is. * * If we cant find a more OSI-ish way to clean it up, we can @@ -2828,29 +2800,10 @@ namespace Server.Items /* list.Add( 1062613, Utility.FixHtml( m_EngravedText ) ); */ } - public override bool AllowEquippedCast(Mobile from) - { - if (base.AllowEquippedCast(from)) - { - return true; - } + public override bool AllowEquippedCast(Mobile from) => + base.AllowEquippedCast(from) || Attributes.SpellChanneling != 0; - return Attributes.SpellChanneling != 0; - } - - public virtual int GetLuckBonus() - { - var resInfo = CraftResources.GetInfo(m_Resource); - - var attrInfo = resInfo?.AttributeInfo; - - if (attrInfo == null) - { - return 0; - } - - return attrInfo.WeaponLuck; - } + public virtual int GetLuckBonus() => CraftResources.GetInfo(m_Resource)?.AttributeInfo?.WeaponLuck ?? 0; public override void GetProperties(ObjectPropertyList list) { @@ -3235,17 +3188,25 @@ namespace Server.Items switch (Skill) { case SkillName.Swords: - list.Add(1061172); - break; // skill required: swordsmanship + { + list.Add(1061172); // skill required: swordsmanship + break; + } case SkillName.Macing: - list.Add(1061173); - break; // skill required: mace fighting + { + list.Add(1061173); // skill required: mace fighting + break; + } case SkillName.Fencing: - list.Add(1061174); - break; // skill required: fencing + { + list.Add(1061174); // skill required: fencing + break; + } case SkillName.Archery: - list.Add(1061175); - break; // skill required: archery + { + list.Add(1061175); // skill required: archery + break; + } } } @@ -3351,13 +3312,7 @@ namespace Server.Items public virtual int GetHitAttackSound(Mobile attacker, Mobile defender) { var sound = attacker.GetAttackSound(); - - if (sound == -1) - { - sound = HitSound; - } - - return sound; + return sound == -1 ? HitSound : sound; } public virtual int GetHitDefendSound(Mobile attacker, Mobile defender) => defender.GetHurtSound(); @@ -3518,33 +3473,37 @@ namespace Server.Items var range = Core.ML ? 5 : 10; var eable = from.GetMobilesInRange(range); - var list = eable.Where( - m => - from != m && defender != m && SpellHelper.ValidIndirectTarget(from, m) - && from.CanBeHarmful(m, false) && (!Core.ML || from.InLOS(m)) - ) - .ToList(); + using var queue = PooledRefQueue.Create(); + foreach (var m in eable) + { + if (from != m && defender != m && SpellHelper.ValidIndirectTarget(from, m) + && from.CanBeHarmful(m, false) && (!Core.ML || from.InLOS(m))) + { + queue.Enqueue(m); + } + } eable.Free(); - if (list.Count == 0) + if (queue.Count == 0) { return; } Effects.PlaySound(from.Location, map, sound); - for (var i = 0; i < list.Count; ++i) + while (queue.Count > 0) { - var m = list[i]; + var m = queue.Dequeue(); var scalar = Core.ML ? 1.0 : (11 - from.GetDistanceToSqrt(m)) / 10; - var damage = GetBaseDamage(from); if (scalar <= 0) { continue; } + var damage = GetBaseDamage(from); + if (scalar < 1.0) { damage *= (11 - from.GetDistanceToSqrt(m)) / 10; diff --git a/Projects/UOContent/Items/Weapons/Fists.cs b/Projects/UOContent/Items/Weapons/Fists.cs index 8be6fe5ac..b2fe3fc93 100644 --- a/Projects/UOContent/Items/Weapons/Fists.cs +++ b/Projects/UOContent/Items/Weapons/Fists.cs @@ -157,7 +157,7 @@ namespace Server.Items } } - public override TimeSpan OnSwing(Mobile attacker, Mobile defender) + public override TimeSpan OnSwing(Mobile attacker, Mobile defender, double damageBonus = 1.0) { if (!Core.AOS) { diff --git a/Projects/UOContent/Items/Weapons/Ranged/BaseRanged.cs b/Projects/UOContent/Items/Weapons/Ranged/BaseRanged.cs index 2c66dd3f2..a3a393a33 100644 --- a/Projects/UOContent/Items/Weapons/Ranged/BaseRanged.cs +++ b/Projects/UOContent/Items/Weapons/Ranged/BaseRanged.cs @@ -37,7 +37,7 @@ namespace Server.Items public override SkillName AccuracySkill => SkillName.Archery; - public override TimeSpan OnSwing(Mobile attacker, Mobile defender) + public override TimeSpan OnSwing(Mobile attacker, Mobile defender, double damageBonus = 1.0) { // WeaponAbility a = WeaponAbility.GetCurrentAbility( attacker ); From 1bec4feb0d54b9486a6bf31239248eb5537f4979 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 21 Nov 2021 09:43:09 -0800 Subject: [PATCH 017/213] fix: BaseCreature cleanup (#858) * Removes LINQ * Removes some list allocations --- Projects/UOContent/Mobiles/BaseCreature.cs | 454 +++++++++------------ 1 file changed, 198 insertions(+), 256 deletions(-) diff --git a/Projects/UOContent/Mobiles/BaseCreature.cs b/Projects/UOContent/Mobiles/BaseCreature.cs index f846378ac..1debdd3cd 100644 --- a/Projects/UOContent/Mobiles/BaseCreature.cs +++ b/Projects/UOContent/Mobiles/BaseCreature.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using System.Linq; +using Server.Collections; using Server.ContextMenus; using Server.Engines.ConPVP; using Server.Engines.MLQuests; @@ -512,11 +512,11 @@ namespace Server.Mobiles public virtual bool DeathAdderCharmable => false; // TODO: Find the pub 31 tweaks to the DispelDifficulty and apply them of course. - public virtual double DispelDifficulty // at this skill level we dispel 50% chance - => 0.0; + // at this skill level we dispel 50% chance + public virtual double DispelDifficulty => 0.0; - public virtual double DispelFocus // at difficulty - focus we have 0%, at difficulty + focus we have 100% - => 20.0; + // at difficulty - focus we have 0%, at difficulty + focus we have 100% + public virtual double DispelFocus => 20.0; public virtual bool DisplayWeight => Backpack is StrongBackpack; @@ -1169,9 +1169,8 @@ namespace Server.Mobiles if (m_MLQuests == null) { - return - MLQuestSystem - .EmptyList; // return EmptyList, but don't cache it (run construction again next time) + // return EmptyList, but don't cache it (run construction again next time) + return MLQuestSystem.EmptyList; } } @@ -1211,7 +1210,7 @@ namespace Server.Mobiles return false; } - if (!(m is BaseCreature c) || m is MilitiaFighter) + if (m is not BaseCreature c || m is MilitiaFighter) { return true; } @@ -2153,11 +2152,8 @@ namespace Server.Mobiles // even if they can't offer you anything at the moment if (MLQuestSystem.Enabled && CanGiveMLQuest && from is PlayerMobile mobile) { - MLQuestSystem.Tell( - this, - mobile, - 1074893 - ); // You need to mark your quest items so I don't take the wrong object. Then speak to me. + // You need to mark your quest items so I don't take the wrong object. Then speak to me. + MLQuestSystem.Tell(this, mobile, 1074893); return false; } @@ -2536,8 +2532,8 @@ namespace Server.Mobiles public override bool IsHarmfulCriminal(Mobile target) => (!Controlled || target != m_ControlMaster) && (!Summoned || target != m_SummonMaster) && - (!(target is BaseCreature creature) || !creature.InitialInnocent || creature.Controlled) && - (!(target is PlayerMobile mobile) || mobile.PermaFlags.Count <= 0) && base.IsHarmfulCriminal(target); + (target is not BaseCreature { InitialInnocent: true } creature || creature.Controlled) && + (target is not PlayerMobile mobile || mobile.PermaFlags.Count <= 0) && base.IsHarmfulCriminal(target); public override void CriminalAction(bool message) { @@ -2837,18 +2833,6 @@ namespace Server.Mobiles return null; } - public static void Cap(ref int val, int min, int max) - { - if (val < min) - { - val = min; - } - else if (val > max) - { - val = max; - } - } - public override void OnDoubleClick(Mobile from) { if (from.AccessLevel >= AccessLevel.GameMaster && !Body.IsHuman) @@ -2903,7 +2887,8 @@ namespace Server.Mobiles } else if (Controlled && Commandable) { - if (IsBonded) // Intentional difference (showing ONLY bonded when bonded instead of bonded & tame) + // Intentional difference (showing ONLY bonded when bonded instead of bonded & tame) + if (IsBonded) { list.Add(1049608); // (bonded) } @@ -3028,7 +3013,7 @@ namespace Server.Mobiles { var de = list[i]; - if (de.Damager == m || !(de.Damager is BaseCreature bc)) + if (de.Damager == m || de.Damager is not BaseCreature bc) { continue; } @@ -3144,10 +3129,8 @@ namespace Server.Mobiles if (rights.Count > 0) { - rights[0].m_Damage = - (int)(rights[0].m_Damage * - 1.25 - ); // This would be the first valid person attacking it. Gets a 25% bonus. Per 1/19/07 Five on Friday + // This would be the first valid person attacking it. Gets a 25% bonus. Per 1/19/07 Five on Friday + rights[0].m_Damage = (int)(rights[0].m_Damage * 1.25); if (rights.Count > 1) { @@ -3155,24 +3138,14 @@ namespace Server.Mobiles } var topDamage = rights[0].m_Damage; - int minDamage; - if (hitsMax >= 3000) + int minDamage = hitsMax switch { - minDamage = topDamage / 16; - } - else if (hitsMax >= 1000) - { - minDamage = topDamage / 8; - } - else if (hitsMax >= 200) - { - minDamage = topDamage / 4; - } - else - { - minDamage = topDamage / 2; - } + >= 3000 => topDamage / 16, + >= 1000 => topDamage / 8, + >= 200 => topDamage / 4, + _ => topDamage / 2 + }; for (var i = 0; i < rights.Count; ++i) { @@ -3271,127 +3244,126 @@ namespace Server.Mobiles GiftOfLifeSpell.HandleDeath(this); CheckStatTimers(); + return; } - else - { - if (!Summoned && !NoKillAwards) - { - var totalFame = Fame / 100; - var totalKarma = -Karma / 100; - if (Map == Map.Felucca) + if (!Summoned && !NoKillAwards) + { + var totalFame = Fame / 100; + var totalKarma = -Karma / 100; + + if (Map == Map.Felucca) + { + totalFame += totalFame / 10 * 3; + totalKarma += totalKarma / 10 * 3; + } + + var list = GetLootingRights(DamageEntries, HitsMax); + var titles = new List(); + var fame = new List(); + var karma = new List(); + + var givenQuestKill = false; + var givenFactionKill = false; + var givenToTKill = false; + + for (var i = 0; i < list.Count; ++i) + { + var ds = list[i]; + + if (!ds.m_HasRight) { - totalFame += totalFame / 10 * 3; - totalKarma += totalKarma / 10 * 3; + continue; } - var list = GetLootingRights(DamageEntries, HitsMax); - var titles = new List(); - var fame = new List(); - var karma = new List(); + var party = Engines.PartySystem.Party.Get(ds.m_Mobile); - var givenQuestKill = false; - var givenFactionKill = false; - var givenToTKill = false; - - for (var i = 0; i < list.Count; ++i) + if (party != null) { - var ds = list[i]; + var divedFame = totalFame / party.Members.Count; + var divedKarma = totalKarma / party.Members.Count; - if (!ds.m_HasRight) + for (var j = 0; j < party.Members.Count; ++j) + { + var info = party.Members[j]; + + if (info?.Mobile != null) + { + var index = titles.IndexOf(info.Mobile); + + if (index == -1) + { + titles.Add(info.Mobile); + fame.Add(divedFame); + karma.Add(divedKarma); + } + else + { + fame[index] += divedFame; + karma[index] += divedKarma; + } + } + } + } + else + { + titles.Add(ds.m_Mobile); + fame.Add(totalFame); + karma.Add(totalKarma); + } + + OnKilledBy(ds.m_Mobile); + + if (!givenFactionKill) + { + givenFactionKill = true; + Faction.HandleDeath(this, ds.m_Mobile); + } + + var region = ds.m_Mobile.Region; + + if (!givenToTKill && (Map == Map.Tokuno || region.IsPartOf("Yomotsu Mines") || + region.IsPartOf("Fan Dancer's Dojo"))) + { + givenToTKill = true; + TreasuresOfTokuno.HandleKill(this, ds.m_Mobile); + } + + if (ds.m_Mobile is PlayerMobile pm) + { + if (MLQuestSystem.Enabled) + { + MLQuestSystem.HandleKill(pm, this); + } + + if (givenQuestKill) { continue; } - var party = Engines.PartySystem.Party.Get(ds.m_Mobile); + var qs = pm.Quest; - if (party != null) + if (qs != null) { - var divedFame = totalFame / party.Members.Count; - var divedKarma = totalKarma / party.Members.Count; - - for (var j = 0; j < party.Members.Count; ++j) - { - var info = party.Members[j]; - - if (info?.Mobile != null) - { - var index = titles.IndexOf(info.Mobile); - - if (index == -1) - { - titles.Add(info.Mobile); - fame.Add(divedFame); - karma.Add(divedKarma); - } - else - { - fame[index] += divedFame; - karma[index] += divedKarma; - } - } - } + qs.OnKill(this, c); + givenQuestKill = true; } - else - { - titles.Add(ds.m_Mobile); - fame.Add(totalFame); - karma.Add(totalKarma); - } - - OnKilledBy(ds.m_Mobile); - - if (!givenFactionKill) - { - givenFactionKill = true; - Faction.HandleDeath(this, ds.m_Mobile); - } - - var region = ds.m_Mobile.Region; - - if (!givenToTKill && (Map == Map.Tokuno || region.IsPartOf("Yomotsu Mines") || - region.IsPartOf("Fan Dancer's Dojo"))) - { - givenToTKill = true; - TreasuresOfTokuno.HandleKill(this, ds.m_Mobile); - } - - if (ds.m_Mobile is PlayerMobile pm) - { - if (MLQuestSystem.Enabled) - { - MLQuestSystem.HandleKill(pm, this); - } - - if (givenQuestKill) - { - continue; - } - - var qs = pm.Quest; - - if (qs != null) - { - qs.OnKill(this, c); - givenQuestKill = true; - } - } - } - - for (var i = 0; i < titles.Count; ++i) - { - Titles.AwardFame(titles[i], fame[i], true); - Titles.AwardKarma(titles[i], karma[i], true); } } - base.OnDeath(c); - - if (DeleteCorpseOnDeath) + for (var i = 0; i < titles.Count; ++i) { - c.Delete(); + Titles.AwardFame(titles[i], fame[i], true); + Titles.AwardKarma(titles[i], karma[i], true); } } + + base.OnDeath(c); + + if (DeleteCorpseOnDeath) + { + c.Delete(); + } } public override void OnDelete() @@ -3642,17 +3614,25 @@ namespace Server.Mobiles public virtual bool Rummage() { - var eable = GetItemsInRange(2); - var toRummage = eable.FirstOrDefault(item => item.Items.Count > 0); - - eable.Free(); - - if (toRummage == null) + if (Backpack == null) { return false; } - if (Backpack == null) + var eable = GetItemsInRange(2); + Corpse toRummage = null; + foreach (var c in eable) + { + if (c.Items.Count > 0) + { + toRummage = c; + break; + } + } + + eable.Free(); + + if (toRummage == null) { return false; } @@ -3788,27 +3768,24 @@ namespace Server.Mobiles public static void TeleportPets(Mobile master, Point3D loc, Map map, bool onlyBonded = false) { - var move = new List(); + using var queue = PooledRefQueue.Create(); - foreach (var m in master.GetMobilesInRange(3)) + var eable = master.GetMobilesInRange(3); + foreach (var m in eable) { - if ( - m is BaseCreature { - Controlled: true, - ControlOrder: OrderType.Guard or OrderType.Follow or OrderType.Come - } pet - ) + if (m is BaseCreature + { Controlled: true, ControlOrder: OrderType.Guard or OrderType.Follow or OrderType.Come } pet && + pet.ControlMaster == master && (!onlyBonded || pet.IsBonded)) { - if (pet.ControlMaster == master && (!onlyBonded || pet.IsBonded)) - { - move.Add(pet); - } + queue.Enqueue(pet); } } - foreach (var m in move) + eable.Free(); + + while (queue.Count > 0) { - m.MoveToWorld(loc, map); + queue.Dequeue().MoveToWorld(loc, map); } } @@ -3844,18 +3821,14 @@ namespace Server.Mobiles var owner = ControlMaster; - if (owner?.Deleted != false || owner.Map != Map || !owner.InRange(this, 12) || !CanSee(owner) || - !InLOS(owner)) - { - if (OwnerAbandonTime == DateTime.MinValue) - { - OwnerAbandonTime = Core.Now; - } - } - else + if (owner?.Deleted == false && owner.Map == Map && owner.InRange(this, 12) && CanSee(owner) && InLOS(owner)) { OwnerAbandonTime = DateTime.MinValue; } + else if (OwnerAbandonTime == DateTime.MinValue) + { + OwnerAbandonTime = Core.Now; + } CheckStatTimers(); } @@ -3961,7 +3934,7 @@ namespace Server.Mobiles public void BeginDeleteTimer() { - if (!(this is BaseEscortable) && !Summoned && !Deleted && !IsStabled) + if (this is not BaseEscortable && !Summoned && !Deleted && !IsStabled) { StopDeleteTimer(); m_DeleteTimer = new DeleteTimer(this, TimeSpan.FromDays(3.0)); @@ -4261,40 +4234,13 @@ namespace Server.Mobiles { } - public virtual bool CheckFoodPreference(Item f) - { - if (CheckFoodPreference(f, FoodType.Eggs, m_Eggs)) - { - return true; - } - - if (CheckFoodPreference(f, FoodType.Fish, m_Fish)) - { - return true; - } - - if (CheckFoodPreference(f, FoodType.GrainsAndHay, m_GrainsAndHay)) - { - return true; - } - - if (CheckFoodPreference(f, FoodType.Meat, m_Meat)) - { - return true; - } - - if (CheckFoodPreference(f, FoodType.FruitsAndVegies, m_FruitsAndVegies)) - { - return true; - } - - if (CheckFoodPreference(f, FoodType.Gold, m_Gold)) - { - return true; - } - - return false; - } + public virtual bool CheckFoodPreference(Item f) => + CheckFoodPreference(f, FoodType.Eggs, m_Eggs) || + CheckFoodPreference(f, FoodType.Fish, m_Fish) || + CheckFoodPreference(f, FoodType.GrainsAndHay, m_GrainsAndHay) || + CheckFoodPreference(f, FoodType.Meat, m_Meat) || + CheckFoodPreference(f, FoodType.FruitsAndVegies, m_FruitsAndVegies) || + CheckFoodPreference(f, FoodType.Gold, m_Gold); public virtual bool CheckFoodPreference(Item fed, FoodType type, Type[] types) { @@ -4396,9 +4342,8 @@ namespace Server.Mobiles } else if (Core.ML) { - from.SendLocalizedMessage( - 1075268 - ); // Your pet cannot form a bond with you until your animal taming ability has risen. + // Your pet cannot form a bond with you until your animal taming ability has risen. + from.SendLocalizedMessage(1075268); } } } @@ -4454,12 +4399,7 @@ namespace Server.Mobiles return false; } - if (!Core.AOS && (skill == SkillName.Focus || skill == SkillName.Chivalry || skill == SkillName.Necromancy)) - { - return false; - } - - return true; + return Core.AOS || skill != SkillName.Focus && skill != SkillName.Chivalry && skill != SkillName.Necromancy; } public virtual TeachResult CheckTeachSkills( @@ -5033,8 +4973,8 @@ namespace Server.Mobiles return false; } - Cap(ref minLevel, 0, 5); - Cap(ref maxLevel, 0, 5); + minLevel = Math.Clamp(minLevel, 0, 5); + maxLevel = Math.Clamp(maxLevel, 0, 5); if (Core.AOS) { @@ -5121,9 +5061,7 @@ namespace Server.Mobiles if (min > max) { - var hold = min; - min = max; - max = hold; + (min, max) = (max, min); } /* Example: @@ -5204,8 +5142,8 @@ namespace Server.Mobiles return false; } - Cap(ref minLevel, 0, 5); - Cap(ref maxLevel, 0, 5); + minLevel = Math.Clamp(minLevel, 0, 5); + maxLevel = Math.Clamp(maxLevel, 0, 5); if (Core.AOS) { @@ -5481,15 +5419,21 @@ namespace Server.Mobiles } var eable = GetMobilesInRange(AuraRange); - - var list = eable.Where( - m => - m != this && CanBeHarmful(m, false) && (Core.AOS || InLOS(m)) && - (m is BaseCreature bc && (bc.Controlled || bc.Summoned || bc.Team != Team) || m.Player) - ); - - foreach (var m in list) + using var queue = PooledRefQueue.Create(); + foreach (var m in eable) { + if (m != this && CanBeHarmful(m, false) && (Core.AOS || InLOS(m)) && + (m is BaseCreature bc && (bc.Controlled || bc.Summoned || bc.Team != Team) || m.Player)) + { + queue.Enqueue(m); + } + } + eable.Free(); + + while (queue.Count > 0) + { + var m = queue.Dequeue(); + AOS.Damage( m, this, @@ -5503,8 +5447,6 @@ namespace Server.Mobiles ); AuraEffect(m); } - - eable.Free(); } public virtual void AuraEffect(Mobile m) @@ -5599,10 +5541,8 @@ namespace Server.Mobiles private DateTime m_NextHourlyCheck; - public LoyaltyTimer() : base(InternalDelay, InternalDelay) - { + public LoyaltyTimer() : base(InternalDelay, InternalDelay) => m_NextHourlyCheck = Core.Now + TimeSpan.FromHours(1.0); - } public static void Initialize() { @@ -5618,14 +5558,14 @@ namespace Server.Mobiles m_NextHourlyCheck = Core.Now + TimeSpan.FromHours(1.0); - var toRelease = new List(); + using var toRelease = PooledRefQueue.Create(); // added array for wild creatures in house regions to be removed - var toRemove = new List(); + using var toRemove = PooledRefQueue.Create(); foreach (var m in World.Mobiles.Values) { - if (!(m is BaseCreature c)) + if (m is not BaseCreature c) { continue; } @@ -5649,7 +5589,7 @@ namespace Server.Mobiles } else if (c.OwnerAbandonTime + c.BondingAbandonDelay <= Core.Now) { - toRemove.Add(c); + toRemove.Enqueue(c); } } else @@ -5673,7 +5613,7 @@ namespace Server.Mobiles if (c.Loyalty <= 0) { - toRelease.Add(c); + toRelease.Enqueue(c); } } } @@ -5686,7 +5626,7 @@ namespace Server.Mobiles if (c.RemoveStep >= 20) { - toRemove.Add(c); + toRemove.Enqueue(c); } } else @@ -5695,22 +5635,24 @@ namespace Server.Mobiles } } - foreach (var c in toRelease) + while (toRelease.Count > 0) { - c.Say(1043255, c.Name); // ~1_NAME~ appears to have decided that is better off without a master! + var c = toRelease.Dequeue(); + + c.Say(1043255, c.Name); // ~1_NAME~ appears to have decided that is better off without a master! c.Loyalty = BaseCreature.MaxLoyalty; // Wonderfully Happy c.IsBonded = false; c.BondingBegin = DateTime.MinValue; c.OwnerAbandonTime = DateTime.MinValue; c.ControlTarget = null; - c.AIObject - .DoOrderRelease(); // this will prevent no release of creatures left alone with AI disabled (and consequent bug of Followers) + // This will prevent no release of creatures left alone with AI disabled (and consequent bug of Followers) + c.AIObject.DoOrderRelease(); c.DropBackpack(); } - foreach (var c in toRemove) + while (toRemove.Count > 0) { - c.Delete(); + toRemove.Dequeue().Delete(); } } } From c8043e8dd299c50a0dcc5a4da59648353ce28583 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 21 Nov 2021 10:45:07 -0800 Subject: [PATCH 018/213] fix: Codegens remaining construction items (#859) --- .../UOContent/Items/Construction/Ankhs.cs | 181 +++++------------- .../Items/Construction/Tables/Tables.cs | 120 +----------- .../Items/Construction/Tables/WritingTable.cs | 26 +-- .../Items/Construction/Walls/BaseWall.cs | 21 +- .../Items/Construction/Walls/DarkWoodWall.cs | 21 +- .../Construction/Walls/ThickGrayStoneWall.cs | 21 +- .../Items/Construction/Walls/ThinBrickWall.cs | 21 +- .../Items/Construction/Walls/ThinStoneWall.cs | 21 +- .../Construction/Walls/WhiteStoneWall.cs | 21 +- ...erver.Items.AnkhNorth.InternalItem.v0.json | 11 ++ .../Migrations/Server.Items.AnkhNorth.v0.json | 11 ++ ...Server.Items.AnkhWest.InternalItem.v0.json | 11 ++ .../Migrations/Server.Items.AnkhWest.v0.json | 11 ++ .../Migrations/Server.Items.BaseWall.v0.json | 4 + .../Server.Items.DarkWoodWall.v0.json | 4 + .../Server.Items.ElegantLowTable.v0.json | 4 + .../Server.Items.LargeTable.v0.json | 4 + .../Server.Items.Nightstand.v0.json | 4 + .../Server.Items.PlainLowTable.v0.json | 4 + .../Server.Items.ThickGrayStoneWall.v0.json | 4 + .../Server.Items.ThinBrickWall.v0.json | 4 + .../Server.Items.ThinStoneWall.v0.json | 4 + .../Server.Items.WhiteStoneWall.v0.json | 4 + .../Server.Items.WritingTable.v0.json | 4 + .../Server.Items.YewWoodTable.v0.json | 4 + 25 files changed, 164 insertions(+), 381 deletions(-) create mode 100644 Projects/UOContent/Migrations/Server.Items.AnkhNorth.InternalItem.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.AnkhNorth.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.AnkhWest.InternalItem.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.AnkhWest.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.BaseWall.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.DarkWoodWall.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.ElegantLowTable.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.LargeTable.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Nightstand.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.PlainLowTable.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.ThickGrayStoneWall.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.ThinBrickWall.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.ThinStoneWall.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.WhiteStoneWall.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.WritingTable.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.YewWoodTable.v0.json diff --git a/Projects/UOContent/Items/Construction/Ankhs.cs b/Projects/UOContent/Items/Construction/Ankhs.cs index 2e3202048..a9993b5df 100644 --- a/Projects/UOContent/Items/Construction/Ankhs.cs +++ b/Projects/UOContent/Items/Construction/Ankhs.cs @@ -80,9 +80,8 @@ namespace Server.Items if (m_Mobile.KarmaLocked) { - m_Mobile.SendLocalizedMessage( - 1060192 - ); // Your karma has been locked. Your karma can no longer be raised. + // Your karma has been locked. Your karma can no longer be raised. + m_Mobile.SendLocalizedMessage(1060192); } else { @@ -112,20 +111,17 @@ namespace Server.Items } } - public class AnkhWest : Item + [Serializable(0, false)] + public partial class AnkhWest : Item { - private InternalItem m_Item; + [SerializableField(0)] + private InternalItem _item; [Constructible] public AnkhWest(bool bloodied = false) : base(bloodied ? 0x1D98 : 0x3) { Movable = false; - - m_Item = new InternalItem(bloodied, this); - } - - public AnkhWest(Serial serial) : base(serial) - { + _item = new InternalItem(bloodied, this); } public override bool HandlesOnMovement => true; // Tell the core that we implement OnMovement @@ -138,9 +134,9 @@ namespace Server.Items set { base.Hue = value; - if (m_Item.Hue != value) + if (_item.Hue != value) { - m_Item.Hue = value; + _item.Hue = value; } } } @@ -166,17 +162,17 @@ namespace Server.Items public override void OnLocationChange(Point3D oldLocation) { - if (m_Item != null) + if (_item != null) { - m_Item.Location = new Point3D(X, Y + 1, Z); + _item.Location = new Point3D(X, Y + 1, Z); } } public override void OnMapChange() { - if (m_Item != null) + if (_item != null) { - m_Item.Map = Map; + _item.Map = Map; } } @@ -184,40 +180,19 @@ namespace Server.Items { base.OnAfterDelete(); - m_Item?.Delete(); - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); // version - - writer.Write(m_Item); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - m_Item = reader.ReadEntity(); + _item?.Delete(); } + [Serializable(0, false)] private class InternalItem : Item { - private AnkhWest m_Item; + [SerializableField(0)] + private AnkhWest _item; public InternalItem(bool bloodied, AnkhWest item) : base(bloodied ? 0x1D97 : 0x2) { Movable = false; - - m_Item = item; - } - - public InternalItem(Serial serial) : base(serial) - { + _item = item; } public override bool HandlesOnMovement => true; // Tell the core that we implement OnMovement @@ -230,26 +205,26 @@ namespace Server.Items set { base.Hue = value; - if (m_Item.Hue != value) + if (_item.Hue != value) { - m_Item.Hue = value; + _item.Hue = value; } } } public override void OnLocationChange(Point3D oldLocation) { - if (m_Item != null) + if (_item != null) { - m_Item.Location = new Point3D(X, Y - 1, Z); + _item.Location = new Point3D(X, Y - 1, Z); } } public override void OnMapChange() { - if (m_Item != null) + if (_item != null) { - m_Item.Map = Map; + _item.Map = Map; } } @@ -257,7 +232,7 @@ namespace Server.Items { base.OnAfterDelete(); - m_Item?.Delete(); + _item?.Delete(); } public override void OnMovement(Mobile m, Point3D oldLocation) @@ -278,43 +253,22 @@ namespace Server.Items { Ankhs.Resurrect(m, this); } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); // version - - writer.Write(m_Item); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - m_Item = reader.ReadEntity(); - } } } [TypeAlias("Server.Items.AnkhEast")] - public class AnkhNorth : Item + [Serializable(0, false)] + public partial class AnkhNorth : Item { - private InternalItem m_Item; + [SerializableField(0)] + private InternalItem _item; [Constructible] public AnkhNorth(bool bloodied = false) : base(bloodied ? 0x1E5D : 0x4) { Movable = false; - m_Item = new InternalItem(bloodied, this); - } - - public AnkhNorth(Serial serial) - : base(serial) - { + _item = new InternalItem(bloodied, this); } public override bool HandlesOnMovement => true; // Tell the core that we implement OnMovement @@ -327,9 +281,9 @@ namespace Server.Items set { base.Hue = value; - if (m_Item.Hue != value) + if (_item.Hue != value) { - m_Item.Hue = value; + _item.Hue = value; } } } @@ -355,17 +309,17 @@ namespace Server.Items public override void OnLocationChange(Point3D oldLocation) { - if (m_Item != null) + if (_item != null) { - m_Item.Location = new Point3D(X + 1, Y, Z); + _item.Location = new Point3D(X + 1, Y, Z); } } public override void OnMapChange() { - if (m_Item != null) + if (_item != null) { - m_Item.Map = Map; + _item.Map = Map; } } @@ -373,42 +327,21 @@ namespace Server.Items { base.OnAfterDelete(); - m_Item?.Delete(); - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); // version - - writer.Write(m_Item); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - m_Item = reader.ReadEntity(); + _item?.Delete(); } [TypeAlias("Server.Items.AnkhEast+InternalItem")] + [Serializable(0, false)] private class InternalItem : Item { - private AnkhNorth m_Item; + [SerializableField(0)] + private AnkhNorth _item; public InternalItem(bool bloodied, AnkhNorth item) : base(bloodied ? 0x1E5C : 0x5) { Movable = false; - - m_Item = item; - } - - public InternalItem(Serial serial) : base(serial) - { + _item = item; } public override bool HandlesOnMovement => true; // Tell the core that we implement OnMovement @@ -421,26 +354,26 @@ namespace Server.Items set { base.Hue = value; - if (m_Item.Hue != value) + if (_item.Hue != value) { - m_Item.Hue = value; + _item.Hue = value; } } } public override void OnLocationChange(Point3D oldLocation) { - if (m_Item != null) + if (_item != null) { - m_Item.Location = new Point3D(X - 1, Y, Z); + _item.Location = new Point3D(X - 1, Y, Z); } } public override void OnMapChange() { - if (m_Item != null) + if (_item != null) { - m_Item.Map = Map; + _item.Map = Map; } } @@ -448,7 +381,7 @@ namespace Server.Items { base.OnAfterDelete(); - m_Item?.Delete(); + _item?.Delete(); } public override void OnMovement(Mobile m, Point3D oldLocation) @@ -469,24 +402,6 @@ namespace Server.Items { Ankhs.Resurrect(m, this); } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); // version - - writer.Write(m_Item); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - m_Item = reader.ReadEntity(); - } } } } diff --git a/Projects/UOContent/Items/Construction/Tables/Tables.cs b/Projects/UOContent/Items/Construction/Tables/Tables.cs index eef852237..65f1bdbf1 100644 --- a/Projects/UOContent/Items/Construction/Tables/Tables.cs +++ b/Projects/UOContent/Items/Construction/Tables/Tables.cs @@ -1,145 +1,45 @@ namespace Server.Items { [Furniture] - public class ElegantLowTable : Item + [Serializable(0, false)] + public partial class ElegantLowTable : Item { [Constructible] public ElegantLowTable() : base(0x2819) => Weight = 1.0; - - public ElegantLowTable(Serial serial) : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } } [Furniture] - public class PlainLowTable : Item + [Serializable(0, false)] + public partial class PlainLowTable : Item { [Constructible] public PlainLowTable() : base(0x281A) => Weight = 1.0; - - public PlainLowTable(Serial serial) : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } } [Furniture] [Flippable(0xB90, 0xB7D)] - public class LargeTable : Item + [Serializable(0, false)] + public partial class LargeTable : Item { [Constructible] public LargeTable() : base(0xB90) => Weight = 1.0; - - public LargeTable(Serial serial) : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - if (Weight == 4.0) - { - Weight = 1.0; - } - } } [Furniture] [Flippable(0xB35, 0xB34)] - public class Nightstand : Item + [Serializable(0, false)] + public partial class Nightstand : Item { [Constructible] public Nightstand() : base(0xB35) => Weight = 1.0; - - public Nightstand(Serial serial) : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - if (Weight == 4.0) - { - Weight = 1.0; - } - } } [Furniture] [Flippable(0xB8F, 0xB7C)] - public class YewWoodTable : Item + [Serializable(0, false)] + public partial class YewWoodTable : Item { [Constructible] public YewWoodTable() : base(0xB8F) => Weight = 1.0; - - public YewWoodTable(Serial serial) : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - if (Weight == 4.0) - { - Weight = 1.0; - } - } } } diff --git a/Projects/UOContent/Items/Construction/Tables/WritingTable.cs b/Projects/UOContent/Items/Construction/Tables/WritingTable.cs index a711392b7..35ec06c37 100644 --- a/Projects/UOContent/Items/Construction/Tables/WritingTable.cs +++ b/Projects/UOContent/Items/Construction/Tables/WritingTable.cs @@ -2,32 +2,10 @@ namespace Server.Items { [Furniture] [Flippable(0xB4A, 0xB49, 0xB4B, 0xB4C)] - public class WritingTable : Item + [Serializable(0, false)] + public partial class WritingTable : Item { [Constructible] public WritingTable() : base(0xB4A) => Weight = 1.0; - - public WritingTable(Serial serial) : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - if (Weight == 4.0) - { - Weight = 1.0; - } - } } } diff --git a/Projects/UOContent/Items/Construction/Walls/BaseWall.cs b/Projects/UOContent/Items/Construction/Walls/BaseWall.cs index d7ab25c27..6b5914a07 100644 --- a/Projects/UOContent/Items/Construction/Walls/BaseWall.cs +++ b/Projects/UOContent/Items/Construction/Walls/BaseWall.cs @@ -1,25 +1,8 @@ namespace Server.Items { - public abstract class BaseWall : Item + [Serializable(0, false)] + public abstract partial class BaseWall : Item { public BaseWall(int itemID) : base(itemID) => Movable = false; - - public BaseWall(Serial serial) : base(serial) - { - } - - 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/Walls/DarkWoodWall.cs b/Projects/UOContent/Items/Construction/Walls/DarkWoodWall.cs index 282863781..a1e6e4077 100644 --- a/Projects/UOContent/Items/Construction/Walls/DarkWoodWall.cs +++ b/Projects/UOContent/Items/Construction/Walls/DarkWoodWall.cs @@ -24,29 +24,12 @@ namespace Server.Items EastWallVShort } - public class DarkWoodWall : BaseWall + [Serializable(0, false)] + public partial class DarkWoodWall : BaseWall { [Constructible] public DarkWoodWall(DarkWoodWallTypes type) : base(0x0006 + (int)type) { } - - public DarkWoodWall(Serial serial) : base(serial) - { - } - - 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/Walls/ThickGrayStoneWall.cs b/Projects/UOContent/Items/Construction/Walls/ThickGrayStoneWall.cs index 044af3bc8..17514de42 100644 --- a/Projects/UOContent/Items/Construction/Walls/ThickGrayStoneWall.cs +++ b/Projects/UOContent/Items/Construction/Walls/ThickGrayStoneWall.cs @@ -34,29 +34,12 @@ namespace Server.Items EastWindow2 } - public class ThickGrayStoneWall : BaseWall + [Serializable(0, false)] + public partial class ThickGrayStoneWall : BaseWall { [Constructible] public ThickGrayStoneWall(ThickGrayStoneWallTypes type) : base(0x007A + (int)type) { } - - public ThickGrayStoneWall(Serial serial) : base(serial) - { - } - - 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/Walls/ThinBrickWall.cs b/Projects/UOContent/Items/Construction/Walls/ThinBrickWall.cs index a7636cccf..f69a3cda3 100644 --- a/Projects/UOContent/Items/Construction/Walls/ThinBrickWall.cs +++ b/Projects/UOContent/Items/Construction/Walls/ThinBrickWall.cs @@ -40,29 +40,12 @@ namespace Server.Items EastWallVShort } - public class ThinBrickWall : BaseWall + [Serializable(0, false)] + public partial class ThinBrickWall : BaseWall { [Constructible] public ThinBrickWall(ThinBrickWallTypes type) : base(0x0033 + (int)type) { } - - public ThinBrickWall(Serial serial) : base(serial) - { - } - - 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/Walls/ThinStoneWall.cs b/Projects/UOContent/Items/Construction/Walls/ThinStoneWall.cs index 49794458c..7754c7b10 100644 --- a/Projects/UOContent/Items/Construction/Walls/ThinStoneWall.cs +++ b/Projects/UOContent/Items/Construction/Walls/ThinStoneWall.cs @@ -29,29 +29,12 @@ namespace Server.Items EastWallShort2 } - public class ThinStoneWall : BaseWall + [Serializable(0, false)] + public partial class ThinStoneWall : BaseWall { [Constructible] public ThinStoneWall(ThinStoneWallTypes type) : base(0x001A + (int)type) { } - - public ThinStoneWall(Serial serial) : base(serial) - { - } - - 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/Walls/WhiteStoneWall.cs b/Projects/UOContent/Items/Construction/Walls/WhiteStoneWall.cs index 093892d15..07a6f0d16 100644 --- a/Projects/UOContent/Items/Construction/Walls/WhiteStoneWall.cs +++ b/Projects/UOContent/Items/Construction/Walls/WhiteStoneWall.cs @@ -47,29 +47,12 @@ namespace Server.Items EastWallVVShort } - public class WhiteStoneWall : BaseWall + [Serializable(0, false)] + public partial class WhiteStoneWall : BaseWall { [Constructible] public WhiteStoneWall(WhiteStoneWallTypes type) : base(0x0057 + (int)type) { } - - public WhiteStoneWall(Serial serial) : base(serial) - { - } - - 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/Migrations/Server.Items.AnkhNorth.InternalItem.v0.json b/Projects/UOContent/Migrations/Server.Items.AnkhNorth.InternalItem.v0.json new file mode 100644 index 000000000..f0bb8bf9d --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.AnkhNorth.InternalItem.v0.json @@ -0,0 +1,11 @@ +{ + "version": 0, + "type": "Server.Items.AnkhNorth.InternalItem", + "properties": [ + { + "name": "Item", + "type": "Server.Items.AnkhNorth", + "rule": "SerializableInterfaceMigrationRule" + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.AnkhNorth.v0.json b/Projects/UOContent/Migrations/Server.Items.AnkhNorth.v0.json new file mode 100644 index 000000000..e6276daa9 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.AnkhNorth.v0.json @@ -0,0 +1,11 @@ +{ + "version": 0, + "type": "Server.Items.AnkhNorth", + "properties": [ + { + "name": "Item", + "type": "Server.Items.AnkhNorth.InternalItem", + "rule": "SerializableInterfaceMigrationRule" + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.AnkhWest.InternalItem.v0.json b/Projects/UOContent/Migrations/Server.Items.AnkhWest.InternalItem.v0.json new file mode 100644 index 000000000..ce8487ea3 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.AnkhWest.InternalItem.v0.json @@ -0,0 +1,11 @@ +{ + "version": 0, + "type": "Server.Items.AnkhWest.InternalItem", + "properties": [ + { + "name": "Item", + "type": "Server.Items.AnkhWest", + "rule": "SerializableInterfaceMigrationRule" + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.AnkhWest.v0.json b/Projects/UOContent/Migrations/Server.Items.AnkhWest.v0.json new file mode 100644 index 000000000..4d2c54228 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.AnkhWest.v0.json @@ -0,0 +1,11 @@ +{ + "version": 0, + "type": "Server.Items.AnkhWest", + "properties": [ + { + "name": "Item", + "type": "Server.Items.AnkhWest.InternalItem", + "rule": "SerializableInterfaceMigrationRule" + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.BaseWall.v0.json b/Projects/UOContent/Migrations/Server.Items.BaseWall.v0.json new file mode 100644 index 000000000..6d0cdab23 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.BaseWall.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.BaseWall" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.DarkWoodWall.v0.json b/Projects/UOContent/Migrations/Server.Items.DarkWoodWall.v0.json new file mode 100644 index 000000000..f520f6f5d --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.DarkWoodWall.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.DarkWoodWall" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.ElegantLowTable.v0.json b/Projects/UOContent/Migrations/Server.Items.ElegantLowTable.v0.json new file mode 100644 index 000000000..2ea3c2834 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.ElegantLowTable.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.ElegantLowTable" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.LargeTable.v0.json b/Projects/UOContent/Migrations/Server.Items.LargeTable.v0.json new file mode 100644 index 000000000..238f1c5c9 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.LargeTable.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.LargeTable" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Nightstand.v0.json b/Projects/UOContent/Migrations/Server.Items.Nightstand.v0.json new file mode 100644 index 000000000..96a1d9f80 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Nightstand.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Nightstand" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.PlainLowTable.v0.json b/Projects/UOContent/Migrations/Server.Items.PlainLowTable.v0.json new file mode 100644 index 000000000..f11168e93 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.PlainLowTable.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.PlainLowTable" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.ThickGrayStoneWall.v0.json b/Projects/UOContent/Migrations/Server.Items.ThickGrayStoneWall.v0.json new file mode 100644 index 000000000..783cf62be --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.ThickGrayStoneWall.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.ThickGrayStoneWall" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.ThinBrickWall.v0.json b/Projects/UOContent/Migrations/Server.Items.ThinBrickWall.v0.json new file mode 100644 index 000000000..a91f76dfa --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.ThinBrickWall.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.ThinBrickWall" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.ThinStoneWall.v0.json b/Projects/UOContent/Migrations/Server.Items.ThinStoneWall.v0.json new file mode 100644 index 000000000..a10bfd271 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.ThinStoneWall.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.ThinStoneWall" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.WhiteStoneWall.v0.json b/Projects/UOContent/Migrations/Server.Items.WhiteStoneWall.v0.json new file mode 100644 index 000000000..e8172178e --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.WhiteStoneWall.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.WhiteStoneWall" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.WritingTable.v0.json b/Projects/UOContent/Migrations/Server.Items.WritingTable.v0.json new file mode 100644 index 000000000..14728f82e --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.WritingTable.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.WritingTable" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.YewWoodTable.v0.json b/Projects/UOContent/Migrations/Server.Items.YewWoodTable.v0.json new file mode 100644 index 000000000..72738fa69 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.YewWoodTable.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.YewWoodTable" +} \ No newline at end of file From c8a6d4c696134b3d5d37e7847d6e321b0ea44ae5 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 21 Nov 2021 18:06:39 -0800 Subject: [PATCH 019/213] fix: Fixes .net 6 compilation (#860) --- Directory.Build.props | 4 ++-- .../SerializationGenerator.csproj | 14 ++++++++------ .../SerializationSchemaGenerator.csproj | 8 +++++--- Projects/Server/Server.csproj | 2 +- Projects/Server/Utilities/Utility.cs | 15 +++++++++++++++ Projects/UOContent/Items/Construction/Ankhs.cs | 8 ++++---- Projects/UOContent/UOContent.csproj | 2 +- 7 files changed, 36 insertions(+), 17 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 27ca9d899..c48855eab 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -4,7 +4,7 @@ Kamron Batman ModernUO 2019-2020 - net5.0;net6.0 + net6.0 x64 x64 preview @@ -56,7 +56,7 @@ - + 3.4.244 all diff --git a/Projects/SerializationGenerator/SerializationGenerator.csproj b/Projects/SerializationGenerator/SerializationGenerator.csproj index 03b5a5bdb..f74e5e965 100755 --- a/Projects/SerializationGenerator/SerializationGenerator.csproj +++ b/Projects/SerializationGenerator/SerializationGenerator.csproj @@ -1,16 +1,17 @@ - netstandard2.0 + netstandard2.0 preview analyzers - - - - - + + + + + + @@ -22,6 +23,7 @@ + diff --git a/Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj b/Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj index 31e89d561..d3d1a168e 100755 --- a/Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj +++ b/Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj @@ -1,7 +1,6 @@ Exe - net5.0 Output @@ -14,7 +13,10 @@ - - + + + + + diff --git a/Projects/Server/Server.csproj b/Projects/Server/Server.csproj index cf357a582..f2cc0ec7a 100755 --- a/Projects/Server/Server.csproj +++ b/Projects/Server/Server.csproj @@ -34,7 +34,7 @@ - + diff --git a/Projects/Server/Utilities/Utility.cs b/Projects/Server/Utilities/Utility.cs index a184d4b23..d3a780a4f 100644 --- a/Projects/Server/Utilities/Utility.cs +++ b/Projects/Server/Utilities/Utility.cs @@ -1049,6 +1049,21 @@ namespace Server return min + (int)RandomSources.Source.Next((uint)(max - min + 1)); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static long RandomMinMax(long min, long max) + { + if (min > max) + { + (min, max) = (max, min); + } + else if (min == max) + { + return min; + } + + return min + RandomSources.Source.Next(max - min + 1); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int Random(int from, int count) => RandomSources.Source.Next(from, count); diff --git a/Projects/UOContent/Items/Construction/Ankhs.cs b/Projects/UOContent/Items/Construction/Ankhs.cs index a9993b5df..d75e968f5 100644 --- a/Projects/UOContent/Items/Construction/Ankhs.cs +++ b/Projects/UOContent/Items/Construction/Ankhs.cs @@ -114,7 +114,7 @@ namespace Server.Items [Serializable(0, false)] public partial class AnkhWest : Item { - [SerializableField(0)] + [SerializableField(0, getter: "private", setter: "private")] private InternalItem _item; [Constructible] @@ -184,7 +184,7 @@ namespace Server.Items } [Serializable(0, false)] - private class InternalItem : Item + private partial class InternalItem : Item { [SerializableField(0)] private AnkhWest _item; @@ -260,7 +260,7 @@ namespace Server.Items [Serializable(0, false)] public partial class AnkhNorth : Item { - [SerializableField(0)] + [SerializableField(0, getter: "private", setter: "private")] private InternalItem _item; [Constructible] @@ -332,7 +332,7 @@ namespace Server.Items [TypeAlias("Server.Items.AnkhEast+InternalItem")] [Serializable(0, false)] - private class InternalItem : Item + private partial class InternalItem : Item { [SerializableField(0)] private AnkhNorth _item; diff --git a/Projects/UOContent/UOContent.csproj b/Projects/UOContent/UOContent.csproj index 5f322c829..2ef0f6dfc 100755 --- a/Projects/UOContent/UOContent.csproj +++ b/Projects/UOContent/UOContent.csproj @@ -40,7 +40,7 @@ - + From 7439cc3a95ead4eb15a2d2c5fad752e8173229e1 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Mon, 22 Nov 2021 07:39:01 -0800 Subject: [PATCH 020/213] fix: Bumps native runtimes to .NET 6 (#861) --- Projects/Server.Tests/Server.Tests.csproj | 2 +- Projects/Server/Server.csproj | 2 +- Projects/UOContent/UOContent.csproj | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Projects/Server.Tests/Server.Tests.csproj b/Projects/Server.Tests/Server.Tests.csproj index 46a5a0981..2a47a0de7 100644 --- a/Projects/Server.Tests/Server.Tests.csproj +++ b/Projects/Server.Tests/Server.Tests.csproj @@ -7,7 +7,7 @@ - + diff --git a/Projects/Server/Server.csproj b/Projects/Server/Server.csproj index f2cc0ec7a..6a0cc1ab5 100755 --- a/Projects/Server/Server.csproj +++ b/Projects/Server/Server.csproj @@ -36,7 +36,7 @@ - + diff --git a/Projects/UOContent/UOContent.csproj b/Projects/UOContent/UOContent.csproj index 2ef0f6dfc..fc7ae24ab 100755 --- a/Projects/UOContent/UOContent.csproj +++ b/Projects/UOContent/UOContent.csproj @@ -41,9 +41,9 @@ - - - + + + From fcc91cbd995146f9ff0ac77d2dfba4df2208baa3 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Mon, 22 Nov 2021 13:29:17 -0800 Subject: [PATCH 021/213] fix (workflow): Adds manual release for github actions (#863) --- .github/workflows/create-release.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml index f08889d15..b2d3a260a 100644 --- a/.github/workflows/create-release.yml +++ b/.github/workflows/create-release.yml @@ -3,6 +3,7 @@ name: Create Release on: repository_dispatch: types: [release] + workflow_dispatch: jobs: release: From 1ac803e7780bdd922724f674e2d45100ff42ed5e Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sat, 27 Nov 2021 10:06:39 -0800 Subject: [PATCH 022/213] fix: Adds better client verification (#853) * Adds MinRequired and MaxRequired settings * Removes god client detection * Streamlines the kick messaging * Fixes detecting client version on mac/linux --- .../Configuration/ServerConfiguration.cs | 10 +- Projects/Server/Network/NetState/NetState.cs | 4 +- Projects/Server/Network/TcpServer.cs | 27 +- Projects/UOContent/Misc/ClientVerification.cs | 230 +++++++++++------- 4 files changed, 158 insertions(+), 113 deletions(-) diff --git a/Projects/Server/Configuration/ServerConfiguration.cs b/Projects/Server/Configuration/ServerConfiguration.cs index 7463aadff..d32519748 100644 --- a/Projects/Server/Configuration/ServerConfiguration.cs +++ b/Projects/Server/Configuration/ServerConfiguration.cs @@ -38,11 +38,11 @@ namespace Server public static List Listeners => m_Settings.Listeners; - public static string GetSetting(string key, string defaultValue) - { - m_Settings.Settings.TryGetValue(key, out var value); - return value ?? defaultValue; - } + public static ClientVersion GetSetting(string key, ClientVersion defaultValue) => + m_Settings.Settings.TryGetValue(key, out var value) ? new ClientVersion(value) : defaultValue; + + public static string GetSetting(string key, string defaultValue) => + m_Settings.Settings.TryGetValue(key, out var value) ? value : defaultValue; public static int GetSetting(string key, int defaultValue) { diff --git a/Projects/Server/Network/NetState/NetState.cs b/Projects/Server/Network/NetState/NetState.cs index 5c0f91e60..46a9622aa 100755 --- a/Projects/Server/Network/NetState/NetState.cs +++ b/Projects/Server/Network/NetState/NetState.cs @@ -197,7 +197,9 @@ namespace Server.Network public Pipe SendPipe { get; } - public Socket Connection { get; } + public bool Running => _running; + + public Socket Connection { get; private set; } public bool CompressionEnabled { get; set; } diff --git a/Projects/Server/Network/TcpServer.cs b/Projects/Server/Network/TcpServer.cs index a9b9f1955..b78e67a41 100644 --- a/Projects/Server/Network/TcpServer.cs +++ b/Projects/Server/Network/TcpServer.cs @@ -39,7 +39,7 @@ namespace Server.Network private static readonly byte[] _socketRejected = { 0x82, 0xFF }; public static IPEndPoint[] ListeningAddresses { get; private set; } - public static TcpListener[] Listeners { get; private set; } + public static Socket[] Listeners { get; private set; } public static HashSet Instances { get; } = new(2048); private static readonly ConcurrentQueue _connectedQueue = new(); @@ -52,7 +52,7 @@ namespace Server.Network public static void Start() { HashSet listeningAddresses = new HashSet(); - List listeners = new List(); + List listeners = new List(); foreach (var ipep in ServerConfiguration.Listeners) { @@ -88,7 +88,7 @@ namespace Server.Network { foreach (var listener in Listeners) { - listener.Server.Close(); + listener.Close(); } } @@ -99,21 +99,19 @@ namespace Server.Network .Select(uip => new IPEndPoint(uip.Address, ipep.Port)) ); - public static TcpListener CreateListener(IPEndPoint ipep) + public static Socket CreateListener(IPEndPoint ipep) { - var listener = new TcpListener(ipep) + var listener = new Socket(ipep.AddressFamily, SocketType.Stream, ProtocolType.Tcp) { - Server = - { - LingerState = new LingerOption(false, 0), - ExclusiveAddressUse = true, - NoDelay = true - } + LingerState = new LingerOption(false, 0), + ExclusiveAddressUse = true, + NoDelay = true }; try { - listener.Start(32); + listener.Bind(ipep); + listener.Listen(32); return listener; } catch (SocketException se) @@ -148,13 +146,14 @@ namespace Server.Network } } - private static async void BeginAcceptingSockets(this TcpListener listener) + private static async void BeginAcceptingSockets(this Socket listener) { while (true) { try { - var socket = await listener.AcceptSocketAsync(); + var socket = await listener.AcceptAsync(); + var rejected = false; if (Instances.Count >= MaxConnections) { diff --git a/Projects/UOContent/Misc/ClientVerification.cs b/Projects/UOContent/Misc/ClientVerification.cs index 23764174a..046455d2e 100644 --- a/Projects/UOContent/Misc/ClientVerification.cs +++ b/Projects/UOContent/Misc/ClientVerification.cs @@ -1,10 +1,12 @@ using System; -using System.Diagnostics; +using System.Buffers.Binary; using System.IO; +using Server.Buffers; using Server.Gumps; using Server.Logging; using Server.Mobiles; using Server.Network; +using Server.Text; namespace Server.Misc { @@ -12,29 +14,36 @@ namespace Server.Misc { private static readonly ILogger logger = LogFactory.GetLogger(typeof(ClientVerification)); - private static bool m_DetectClientRequirement; - private static OldClientResponse m_OldClientResponse; + private static bool _enable; + private static bool _detectClientRequirement; + private static InvalidClientResponse _invalidClientResponse; + private static string _versionExpression; - private static TimeSpan m_AgeLeniency; - private static TimeSpan m_GameTimeLeniency; + private static TimeSpan _ageLeniency; + private static TimeSpan _gameTimeLeniency; - public static ClientVersion Required { get; set; } + public static ClientVersion MinRequired { get; private set; } + public static ClientVersion MaxRequired { get; private set; } - public static bool AllowRegular { get; set; } = true; - - public static bool AllowUOTD { get; set; } = true; - - public static bool AllowGod { get; set; } = true; - - public static TimeSpan KickDelay { get; set; } + public static bool AllowRegular => true; + public static bool AllowUOTD => false; + public static TimeSpan KickDelay { get; private set; } public static void Configure() { - m_DetectClientRequirement = ServerConfiguration.GetOrUpdateSetting("clientVerification.enable", true); - m_OldClientResponse = - ServerConfiguration.GetOrUpdateSetting("clientVerification.oldClientResponse", OldClientResponse.Kick); - m_AgeLeniency = ServerConfiguration.GetOrUpdateSetting("clientVerification.ageLeniency", TimeSpan.FromDays(10)); - m_GameTimeLeniency = ServerConfiguration.GetOrUpdateSetting( + MinRequired = ServerConfiguration.GetSetting("clientVerification.minRequired", (ClientVersion)null); + MaxRequired = ServerConfiguration.GetSetting("clientVerification.maxRequired", (ClientVersion)null); + + if (MinRequired == null && MaxRequired == null) + { + _detectClientRequirement = ServerConfiguration.GetOrUpdateSetting("clientVerification.detectFromClientExe", true); + } + + _enable = ServerConfiguration.GetOrUpdateSetting("clientVerification.enable", true); + _invalidClientResponse = + ServerConfiguration.GetOrUpdateSetting("clientVerification.invalidClientResponse", InvalidClientResponse.Kick); + _ageLeniency = ServerConfiguration.GetOrUpdateSetting("clientVerification.ageLeniency", TimeSpan.FromDays(10)); + _gameTimeLeniency = ServerConfiguration.GetOrUpdateSetting( "clientVerification.gameTimeLeniency", TimeSpan.FromHours(25) ); @@ -45,121 +54,154 @@ namespace Server.Misc { EventSink.ClientVersionReceived += EventSink_ClientVersionReceived; - if (m_DetectClientRequirement) + if (_detectClientRequirement) { var path = Core.FindDataFile("client.exe", false); if (File.Exists(path)) { - var info = FileVersionInfo.GetVersionInfo(path); - - if (info.FileMajorPart != 0 || info.FileMinorPart != 0 || info.FileBuildPart != 0 || - info.FilePrivatePart != 0) + using FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read); + var buffer = GC.AllocateUninitializedArray((int)fs.Length, true); + fs.Read(buffer); + // VS_VERSION_INFO (unicode) + Span vsVersionInfo = stackalloc byte[] { - Required = new ClientVersion( - info.FileMajorPart, - info.FileMinorPart, - info.FileBuildPart, - info.FilePrivatePart - ); + 0x56, 0x00, 0x53, 0x00, 0x5F, 0x00, 0x56, 0x00, + 0x45, 0x00, 0x52, 0x00, 0x53, 0x00, 0x49, 0x00, + 0x4F, 0x00, 0x4E, 0x00, 0x5F, 0x00, 0x49, 0x00, + 0x4E, 0x00, 0x46, 0x00, 0x4F, 0x00 + }; + + for (var i = 0; i < buffer.Length; i++) + { + if (vsVersionInfo.SequenceEqual(buffer.AsSpan(i, 30))) + { + var offset = i + 42; // 30 + 12 + + var minorPart = BinaryPrimitives.ReadUInt16LittleEndian(buffer.AsSpan(offset)); + var majorPart = BinaryPrimitives.ReadUInt16LittleEndian(buffer.AsSpan(offset + 2)); + var privatePart = BinaryPrimitives.ReadUInt16LittleEndian(buffer.AsSpan(offset + 4)); + var buildPart = BinaryPrimitives.ReadUInt16LittleEndian(buffer.AsSpan(offset + 6)); + + MinRequired = new ClientVersion(majorPart, minorPart, buildPart, privatePart); + break; + } } } } - if (Required != null) + if (MinRequired != null || MaxRequired != null) { logger.Information( - "Restricting client version to {0}. Action to be taken: {1}", - Required, - m_OldClientResponse + $"Restricting client version to {GetVersionExpression()}. Action to be taken: {_invalidClientResponse}" ); } } + private static string GetVersionExpression() + { + if (_versionExpression == null) + { + if (MinRequired != null && MaxRequired != null) + { + _versionExpression = $"{MinRequired}-{MaxRequired}"; + } + else if (MinRequired != null) + { + _versionExpression = $"{MinRequired} or newer"; + } + else + { + _versionExpression = $"{MaxRequired} or older"; + } + } + + return _versionExpression; + } + private static void EventSink_ClientVersionReceived(NetState state, ClientVersion version) { - string kickMessage = null; + using var message = new ValueStringBuilder(); - if (state.Mobile?.AccessLevel != AccessLevel.Player) + if (!_enable || state.Mobile?.AccessLevel != AccessLevel.Player) { return; } - if (Required != null && version < Required && (m_OldClientResponse == OldClientResponse.Kick || - m_OldClientResponse == OldClientResponse.LenientKick && - Core.Now - state.Mobile.Created > m_AgeLeniency && - state.Mobile is PlayerMobile mobile && - mobile.GameTime > m_GameTimeLeniency)) + var strictRequirement = _invalidClientResponse == InvalidClientResponse.Kick || + _invalidClientResponse == InvalidClientResponse.LenientKick && + Core.Now - state.Mobile.Created > _ageLeniency && + state.Mobile is PlayerMobile mobile && + mobile.GameTime > _gameTimeLeniency; + + bool shouldKick = false; + + if (MinRequired != null && version < MinRequired) { - kickMessage = $"This server requires your client version be at least {Required}."; + message.Append($"This server doesn't support clients older than {MinRequired}."); + shouldKick = strictRequirement; } - else if (!AllowGod || !AllowRegular || !AllowUOTD) + else if (MaxRequired != null && version > MaxRequired) { - if (!AllowGod && version.Type == ClientType.God) + message.Append($"This server doesn't support clients newer than {MaxRequired}."); + shouldKick = strictRequirement; + } + else if (!AllowRegular || !AllowUOTD) + { + if (!AllowRegular && version.Type == ClientType.Regular) { - kickMessage = "This server does not allow god clients to connect."; - } - else if (!AllowRegular && version.Type == ClientType.Regular) - { - kickMessage = "This server does not allow regular clients to connect."; + message.Append("This server does not allow regular clients to connect."); + shouldKick = true; } else if (!AllowUOTD && state.IsUOTDClient) { - kickMessage = "This server does not allow UO:TD clients to connect."; + message.Append("This server does not allow UO:TD clients to connect."); + shouldKick = true; } - if (!AllowGod && !AllowRegular && !AllowUOTD) - { - kickMessage = "This server does not allow any clients to connect."; - } - else if (AllowGod && !AllowRegular && !AllowUOTD && version.Type != ClientType.God) - { - kickMessage = "This server requires you to use the god client."; - } - else if (kickMessage != null) + if (message.Length > 0) { if (AllowRegular && AllowUOTD) { - kickMessage += " You can use regular or UO:TD clients."; + message.Append(" You can use regular or UO:TD clients."); } else if (AllowRegular) { - kickMessage += " You can use regular clients."; + message.Append(" You can use regular clients."); } else if (AllowUOTD) { - kickMessage += " You can use UO:TD clients."; + message.Append(" You can use UO:TD clients."); } } } - if (kickMessage != null) + if (message.Length > 0) { - state.Mobile.SendMessage(0x22, kickMessage); - state.Mobile.SendMessage(0x22, "You will be disconnected in {0} seconds.", KickDelay.TotalSeconds); - - Timer.StartTimer(KickDelay, () => OnKick(state)); + state.Mobile.SendMessage(0x22, message.ToString()); } - else if (Required != null && version < Required) + + if (shouldKick) { - switch (m_OldClientResponse) + state.Mobile.SendMessage(0x22, "You will be disconnected in {0} seconds.", KickDelay.TotalSeconds); + Timer.StartTimer(KickDelay, () => OnKick(state)); + return; + } + + if (message.Length > 0) + { + switch (_invalidClientResponse) { - case OldClientResponse.Warn: + case InvalidClientResponse.Warn: { state.Mobile.SendMessage( 0x22, - "Your client is out of date. Please update your client.", - Required - ); - state.Mobile.SendMessage( - 0x22, - "This server recommends that your client version be at least {0}.", - Required + $"This server recommends that your client version is {GetVersionExpression()}." ); break; } - case OldClientResponse.LenientKick: - case OldClientResponse.Annoy: + case InvalidClientResponse.LenientKick: + case InvalidClientResponse.Annoy: { SendAnnoyGump(state.Mobile); break; @@ -170,10 +212,11 @@ namespace Server.Misc private static void OnKick(NetState ns) { - if (ns.Connection != null) + if (ns.Running) { - ns.LogInfo("Disconnecting, bad version"); - ns.Disconnect($"Invalid client version {ns.Version}."); + var version = ns.Version; + ns.LogInfo($"Disconnecting, bad version ({version})"); + ns.Disconnect($"Invalid client version {version}."); } } @@ -181,12 +224,12 @@ namespace Server.Misc { from.SendMessage("You will be reminded of this again."); - if (m_OldClientResponse == OldClientResponse.LenientKick) + if (_invalidClientResponse == InvalidClientResponse.LenientKick) { from.SendMessage( - "Old clients will be kicked after {0} days of character age and {1} hours of play time", - m_AgeLeniency, - m_GameTimeLeniency + "Invalid clients will be kicked after {0} days of character age and {1} hours of play time", + _ageLeniency, + _gameTimeLeniency ); } @@ -195,28 +238,29 @@ namespace Server.Misc private static void SendAnnoyGump(Mobile m) { - if (m.NetState != null && m.NetState.Version < Required) + if (m.NetState != null) { Gump g = new WarningGump( 1060637, 30720, - $"Your client is out of date. Please update your client.
This server recommends that your client version be at least {Required}.

You are currently using version {m.NetState.Version}.

To patch, run UOPatch.exe inside your Ultima Online folder.", + $"Your client is invalid.
This server recommends that your client version is {GetVersionExpression()}.

You are currently using version {m.NetState.Version}.", 0xFFC000, 480, 360, okay => KickMessage(m, okay), false - ); - - g.Draggable = false; - g.Closable = false; - g.Resizable = false; + ) + { + Draggable = false, + Closable = false, + Resizable = false, + }; m.SendGump(g); } } - private enum OldClientResponse + private enum InvalidClientResponse { Ignore, Warn, From aff2f15a6cf9f5d6a2223c50ce2864b3bd99b8b8 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 28 Nov 2021 20:54:16 -0800 Subject: [PATCH 023/213] fix: Fixes guild deserialization (#867) * Fixes guilds being marked as deleted because the leader hasn't been deserialized yet. * Fixes LastSerialization issue. --- Projects/Server/Serialization/BufferReader.cs | 4 ++-- Projects/Server/World/World.cs | 14 ++++++++------ Projects/UOContent/Misc/Guild.cs | 10 +--------- Projects/UOContent/Spells/Base/Spell.cs | 4 +--- 4 files changed, 12 insertions(+), 20 deletions(-) diff --git a/Projects/Server/Serialization/BufferReader.cs b/Projects/Server/Serialization/BufferReader.cs index e04135db5..309ac26f4 100644 --- a/Projects/Server/Serialization/BufferReader.cs +++ b/Projects/Server/Serialization/BufferReader.cs @@ -37,7 +37,7 @@ namespace Server _encoding = encoding ?? TextEncoding.UTF8; } - public BufferReader(byte[] buffer, DateTime LastSerialized) : this(buffer) => LastSerialized = LastSerialized; + public BufferReader(byte[] buffer, DateTime lastSerialized) : this(buffer) => LastSerialized = lastSerialized; public void Reset(byte[] newBuffer, out byte[] oldBuffer) { @@ -47,7 +47,7 @@ namespace Server } // Compatible with BinaryReader.ReadString() - public DateTime LastSerialized { get; init; } = DateTime.MinValue; + public DateTime LastSerialized { get; init; } public string ReadString(bool intern = false) { diff --git a/Projects/Server/World/World.cs b/Projects/Server/World/World.cs index a5d57436a..1db4b3e30 100644 --- a/Projects/Server/World/World.cs +++ b/Projects/Server/World/World.cs @@ -525,7 +525,7 @@ namespace Server } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static IEntity FindEntity(Serial serial, bool returnDeleted = false) => FindEntity(serial); + public static IEntity FindEntity(Serial serial, bool returnDeleted = false) => FindEntity(serial, returnDeleted); public static T FindEntity(Serial serial, bool returnDeleted = false) where T : class, IEntity { @@ -669,15 +669,17 @@ namespace Server if (typeof(BaseGuild).IsAssignableFrom(typeT)) { entity = FindGuild(serial) as T; + // If we check for `entity.Deleted` here during deserialization then all guilds are deleted because + // Deleted -> Disbanded -> No leader, which is the case before deserialization. + // TODO: Use a deleted flag instead, and actively check for dibanded guilds properly. } else { entity = FindEntity(serial) as T; - } - - if (entity?.Deleted == false) - { - return entity; + if (entity?.Deleted == false) + { + return entity; + } } return entity?.Created <= reader.LastSerialized ? entity : null; diff --git a/Projects/UOContent/Misc/Guild.cs b/Projects/UOContent/Misc/Guild.cs index dd891a8b1..a9902f759 100644 --- a/Projects/UOContent/Misc/Guild.cs +++ b/Projects/UOContent/Misc/Guild.cs @@ -661,15 +661,7 @@ namespace Server.Guilds public AllianceInfo Alliance { - get - { - if (m_AllianceInfo != null) - { - return m_AllianceInfo; - } - - return m_AllianceLeader?.m_AllianceInfo; - } + get => m_AllianceInfo ?? m_AllianceLeader?.m_AllianceInfo; set { var current = Alliance; diff --git a/Projects/UOContent/Spells/Base/Spell.cs b/Projects/UOContent/Spells/Base/Spell.cs index 85c8c4ceb..73afcba5b 100644 --- a/Projects/UOContent/Spells/Base/Spell.cs +++ b/Projects/UOContent/Spells/Base/Spell.cs @@ -790,9 +790,7 @@ namespace Server.Spells return false; } - public bool CheckBSequence(Mobile target) => CheckBSequence(target, false); - - public bool CheckBSequence(Mobile target, bool allowDead) + public bool CheckBSequence(Mobile target, bool allowDead = false) { if (!target.Alive && !allowDead) { From 09a3bc97545c045a333d653c7428b67fa2cc86c2 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Tue, 30 Nov 2021 08:19:44 -0800 Subject: [PATCH 024/213] fix: Fixes winner determination (#868) --- Projects/UOContent/Misc/Guild.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Projects/UOContent/Misc/Guild.cs b/Projects/UOContent/Misc/Guild.cs index a9902f759..2893071ce 100644 --- a/Projects/UOContent/Misc/Guild.cs +++ b/Projects/UOContent/Misc/Guild.cs @@ -1608,10 +1608,10 @@ namespace Server.Guilds if (m_Leader != winner && winner != null) { - GuildMessage(1018015, true, winner.Name); // Guild Message: Guildmaster changed to: + Leader = winner; + GuildMessage(1018015, true, winner.RawName); // Guild Message: Guildmaster changed to: } - Leader = winner; LastFealty = Core.Now; } From bea20f36a03976eec2087cca8c19de532ef17b96 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Wed, 1 Dec 2021 08:15:16 -0800 Subject: [PATCH 025/213] fix: Fixes targeting checks (#869) * Adds CanTarget for more granular overrides of specific targeting restrictions * Updates spell targeting * Fixes targeting checks --- Projects/Server/Targeting/Target.cs | 144 ++++++++++-------- .../UOContent/Items/Addons/AddonComponent.cs | 2 - .../Items/Deeds/VendorRentalContract.cs | 15 +- .../Items/Weapons/Abilities/Bladeweave.cs | 1 - .../Items/Weapons/Abilities/DoubleShot.cs | 2 - Projects/UOContent/Misc/ClientVerification.cs | 1 - Projects/UOContent/Misc/Guild.cs | 6 +- Projects/UOContent/Misc/ServerList.cs | 1 - Projects/UOContent/Skills/Inscribe.cs | 10 +- .../UOContent/Spells/Fifth/DispelField.cs | 1 - .../UOContent/Spells/Fifth/PoisonField.cs | 1 - Projects/UOContent/Spells/Fourth/ArchCure.cs | 1 - .../UOContent/Spells/Fourth/ArchProtection.cs | 1 - Projects/UOContent/Spells/Fourth/FireField.cs | 1 - .../Spells/Necromancy/AnimateDeadSpell.cs | 1 - Projects/UOContent/Spells/Second/MagicTrap.cs | 1 - .../UOContent/Spells/Second/RemoveTrap.cs | 1 - .../Spells/Seventh/ChainLightning.cs | 1 - .../UOContent/Spells/Seventh/EnergyField.cs | 1 - .../UOContent/Spells/Seventh/MassDispel.cs | 1 - .../UOContent/Spells/Seventh/MeteorSwarm.cs | 1 - Projects/UOContent/Spells/Sixth/Mark.cs | 1 - Projects/UOContent/Spells/Sixth/MassCurse.cs | 2 - .../UOContent/Spells/Sixth/ParalyzeField.cs | 1 - Projects/UOContent/Spells/Sixth/Reveal.cs | 1 - .../Spells/Targeting/SpellTargetItem.cs | 8 +- .../Spells/Targeting/SpellTargetMobile.cs | 3 + .../Spells/Targeting/SpellTargetPoint3D.cs | 5 +- Projects/UOContent/Spells/Third/MagicLock.cs | 1 - .../UOContent/Spells/Third/Telekinesis.cs | 1 - Projects/UOContent/Spells/Third/Teleport.cs | 1 - Projects/UOContent/Spells/Third/Unlock.cs | 1 - .../UOContent/Spells/Third/WallOfStone.cs | 1 - 33 files changed, 104 insertions(+), 116 deletions(-) diff --git a/Projects/Server/Targeting/Target.cs b/Projects/Server/Targeting/Target.cs index e60231322..90d08d3db 100644 --- a/Projects/Server/Targeting/Target.cs +++ b/Projects/Server/Targeting/Target.cs @@ -79,6 +79,72 @@ namespace Server.Targeting OnTargetFinish(from); } + protected virtual bool CanTarget(Mobile from, LandTarget landTarget, ref Point3D loc, ref Map map) + { + if (!AllowGround) + { + // We should actually never get here. If we do, it's probably a misbehaving client/macro. + OnTargetCancel(from, TargetCancelType.Canceled); + return false; + } + + loc = landTarget.Location; + map = from.Map; + return true; + } + + protected virtual bool CanTarget(Mobile from, StaticTarget staticTarget, ref Point3D loc, ref Map map) + { + loc = staticTarget.Location; + map = from.Map; + return true; + } + + protected virtual bool CanTarget(Mobile from, Item item, ref Point3D loc, ref Map map) + { + if (item.Deleted) + { + OnTargetDeleted(from, item); + return false; + } + + if (!item.CanTarget) + { + OnTargetUntargetable(from, item); + return false; + } + + if (!AllowNonlocal && item.RootParent is Mobile && item.RootParent != from && + from.AccessLevel == AccessLevel.Player) + { + OnNonlocalTarget(from, item); + return false; + } + + loc = item.GetWorldLocation(); + map = item.Map; + return true; + } + + protected virtual bool CanTarget(Mobile from, Mobile mobile, ref Point3D loc, ref Map map) + { + if (mobile.Deleted) + { + OnTargetDeleted(from, mobile); + return false; + } + + if (!mobile.CanTarget) + { + OnTargetUntargetable(from, mobile); + return false; + } + + loc = mobile.Location; + map = mobile.Map; + return true; + } + public void Invoke(Mobile from, object targeted) { CancelTimeout(); @@ -91,76 +157,32 @@ namespace Server.Targeting return; } - Point3D loc; - Map map; + Point3D loc = default; + Map map = null; + Item item = null; + Mobile mobile = null; + bool isValidTargetType = true; - var item = targeted as Item; - var mobile = targeted as Mobile; + bool valid = targeted switch + { + LandTarget landTarget => CanTarget(from, landTarget, ref loc, ref map), + StaticTarget staticTarget => CanTarget(from, staticTarget, ref loc, ref map), + Item i => CanTarget(from, item = i, ref loc, ref map), + Mobile m => CanTarget(from, mobile = m, ref loc, ref map), + _ => isValidTargetType = false + }; - if (targeted is LandTarget target) + if (!valid) { - loc = target.Location; - map = from.Map; - } - else if (targeted is StaticTarget staticTarget) - { - loc = staticTarget.Location; - map = from.Map; - } - else if (mobile != null) - { - if (mobile.Deleted) + if (!isValidTargetType) { - OnTargetDeleted(from, mobile); - OnTargetFinish(from); - return; + OnTargetCancel(from, TargetCancelType.Canceled); } - if (!mobile.CanTarget) - { - OnTargetUntargetable(from, mobile); - OnTargetFinish(from); - return; - } - - loc = mobile.Location; - map = mobile.Map; - } - else if (item != null) - { - if (item.Deleted) - { - OnTargetDeleted(from, item); - OnTargetFinish(from); - return; - } - - if (!item.CanTarget) - { - OnTargetUntargetable(from, item); - OnTargetFinish(from); - return; - } - - if (!AllowNonlocal && item.RootParent is Mobile && item.RootParent != from && - from.AccessLevel == AccessLevel.Player) - { - OnNonlocalTarget(from, item); - OnTargetFinish(from); - return; - } - - loc = item.GetWorldLocation(); - map = item.Map; - } - else - { - OnTargetCancel(from, TargetCancelType.Canceled); OnTargetFinish(from); - return; } - if (map == null || map != from.Map || Range != -1 && !from.InRange(loc, Range)) + if (map == null || map != from.Map || Range < 0 && !from.InRange(loc, Range)) { OnTargetOutOfRange(from, targeted); } diff --git a/Projects/UOContent/Items/Addons/AddonComponent.cs b/Projects/UOContent/Items/Addons/AddonComponent.cs index f32576ff7..90d74dbc0 100644 --- a/Projects/UOContent/Items/Addons/AddonComponent.cs +++ b/Projects/UOContent/Items/Addons/AddonComponent.cs @@ -1,5 +1,3 @@ -using System.Collections.Generic; -using Server.ContextMenus; using Server.Engines.Craft; namespace Server.Items diff --git a/Projects/UOContent/Items/Deeds/VendorRentalContract.cs b/Projects/UOContent/Items/Deeds/VendorRentalContract.cs index 37969839b..437d4d0f4 100644 --- a/Projects/UOContent/Items/Deeds/VendorRentalContract.cs +++ b/Projects/UOContent/Items/Deeds/VendorRentalContract.cs @@ -290,9 +290,8 @@ namespace Server.Items } else if (BaseHouse.FindHouseAt(from) != house) { - from.SendLocalizedMessage( - 1062339 - ); // You must be located inside of the house in which you are trying to place the contract. + // You must be located inside of the house in which you are trying to place the contract. + from.SendLocalizedMessage(1062339); } else if (!house.IsAosRules) { @@ -320,15 +319,13 @@ namespace Server.Items if (vendor) { - from.SendLocalizedMessage( - 1062342 - ); // You may not place a rental contract at this location while other beings occupy it. + // You may not place a rental contract at this location while other beings occupy it. + from.SendLocalizedMessage(1062342); } else if (contract) { - from.SendLocalizedMessage( - 1062341 - ); // That location is cluttered. Please clear out any objects there and try again. + // That location is cluttered. Please clear out any objects there and try again. + from.SendLocalizedMessage(1062341); } else { diff --git a/Projects/UOContent/Items/Weapons/Abilities/Bladeweave.cs b/Projects/UOContent/Items/Weapons/Abilities/Bladeweave.cs index 48e69f012..3ac67b7e2 100644 --- a/Projects/UOContent/Items/Weapons/Abilities/Bladeweave.cs +++ b/Projects/UOContent/Items/Weapons/Abilities/Bladeweave.cs @@ -1,4 +1,3 @@ -using Server.Mobiles; using System; using System.Collections.Generic; diff --git a/Projects/UOContent/Items/Weapons/Abilities/DoubleShot.cs b/Projects/UOContent/Items/Weapons/Abilities/DoubleShot.cs index 8f01dea14..c32132fac 100644 --- a/Projects/UOContent/Items/Weapons/Abilities/DoubleShot.cs +++ b/Projects/UOContent/Items/Weapons/Abilities/DoubleShot.cs @@ -1,5 +1,3 @@ -using System; - namespace Server.Items { /// diff --git a/Projects/UOContent/Misc/ClientVerification.cs b/Projects/UOContent/Misc/ClientVerification.cs index 046455d2e..7b264eec8 100644 --- a/Projects/UOContent/Misc/ClientVerification.cs +++ b/Projects/UOContent/Misc/ClientVerification.cs @@ -6,7 +6,6 @@ using Server.Gumps; using Server.Logging; using Server.Mobiles; using Server.Network; -using Server.Text; namespace Server.Misc { diff --git a/Projects/UOContent/Misc/Guild.cs b/Projects/UOContent/Misc/Guild.cs index 2893071ce..bccad8bb9 100644 --- a/Projects/UOContent/Misc/Guild.cs +++ b/Projects/UOContent/Misc/Guild.cs @@ -1351,10 +1351,10 @@ namespace Server.Guilds alliance = Alliance; // CheckLeader could possibly change the value of this.Alliance - if (alliance?.IsMember(this) == false && !alliance.IsPendingMember(this) - ) // This block is there to fix a bug in the code in an older version. + // This block is there to fix a bug in the code in an older version. + if (alliance?.IsMember(this) == false && !alliance.IsPendingMember(this)) { - Alliance = null; // Will call Alliance.RemoveGuild which will set it null & perform all the pertient checks as far as alliacne disbanding + Alliance = null; // Will call Alliance.RemoveGuild which will set it null & perform all the pertinent checks as far as alliance disbanding } } diff --git a/Projects/UOContent/Misc/ServerList.cs b/Projects/UOContent/Misc/ServerList.cs index 7d3a95194..d457a102a 100644 --- a/Projects/UOContent/Misc/ServerList.cs +++ b/Projects/UOContent/Misc/ServerList.cs @@ -1,5 +1,4 @@ using System; -using System.IO; using System.Net; using System.Net.Http; using System.Net.NetworkInformation; diff --git a/Projects/UOContent/Skills/Inscribe.cs b/Projects/UOContent/Skills/Inscribe.cs index 3c97e95ee..dbcca17e8 100644 --- a/Projects/UOContent/Skills/Inscribe.cs +++ b/Projects/UOContent/Skills/Inscribe.cs @@ -112,9 +112,8 @@ namespace Server.SkillHandlers { if (cancelType == TargetCancelType.Timeout) { - from.SendLocalizedMessage( - 501619 - ); // You have waited too long to make your inscribe selection, your inscription attempt has timed out. + // You have waited too long to make your inscribe selection, your inscription attempt has timed out. + from.SendLocalizedMessage(501619); } } } @@ -172,9 +171,8 @@ namespace Server.SkillHandlers { if (cancelType == TargetCancelType.Timeout) { - from.SendLocalizedMessage( - 501619 - ); // You have waited too long to make your inscribe selection, your inscription attempt has timed out. + // You have waited too long to make your inscribe selection, your inscription attempt has timed out. + from.SendLocalizedMessage(501619); } } diff --git a/Projects/UOContent/Spells/Fifth/DispelField.cs b/Projects/UOContent/Spells/Fifth/DispelField.cs index ff0241410..ac0bfe41e 100644 --- a/Projects/UOContent/Spells/Fifth/DispelField.cs +++ b/Projects/UOContent/Spells/Fifth/DispelField.cs @@ -1,6 +1,5 @@ using Server.Items; using Server.Misc; -using Server.Targeting; namespace Server.Spells.Fifth { diff --git a/Projects/UOContent/Spells/Fifth/PoisonField.cs b/Projects/UOContent/Spells/Fifth/PoisonField.cs index bbc26fb85..8a55f0d0b 100644 --- a/Projects/UOContent/Spells/Fifth/PoisonField.cs +++ b/Projects/UOContent/Spells/Fifth/PoisonField.cs @@ -3,7 +3,6 @@ using Server.Collections; using Server.Items; using Server.Misc; using Server.Mobiles; -using Server.Targeting; namespace Server.Spells.Fifth { diff --git a/Projects/UOContent/Spells/Fourth/ArchCure.cs b/Projects/UOContent/Spells/Fourth/ArchCure.cs index f7be3f3e9..3d7158499 100644 --- a/Projects/UOContent/Spells/Fourth/ArchCure.cs +++ b/Projects/UOContent/Spells/Fourth/ArchCure.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; using System.Linq; using Server.Mobiles; -using Server.Targeting; namespace Server.Spells.Fourth { diff --git a/Projects/UOContent/Spells/Fourth/ArchProtection.cs b/Projects/UOContent/Spells/Fourth/ArchProtection.cs index a798ad83b..d924d4c82 100644 --- a/Projects/UOContent/Spells/Fourth/ArchProtection.cs +++ b/Projects/UOContent/Spells/Fourth/ArchProtection.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using Server.Collections; using Server.Engines.PartySystem; using Server.Spells.Second; -using Server.Targeting; namespace Server.Spells.Fourth { diff --git a/Projects/UOContent/Spells/Fourth/FireField.cs b/Projects/UOContent/Spells/Fourth/FireField.cs index e685fd6c0..c3979af90 100644 --- a/Projects/UOContent/Spells/Fourth/FireField.cs +++ b/Projects/UOContent/Spells/Fourth/FireField.cs @@ -3,7 +3,6 @@ using Server.Collections; using Server.Items; using Server.Misc; using Server.Mobiles; -using Server.Targeting; namespace Server.Spells.Fourth { diff --git a/Projects/UOContent/Spells/Necromancy/AnimateDeadSpell.cs b/Projects/UOContent/Spells/Necromancy/AnimateDeadSpell.cs index 47448544b..f67cdeb78 100644 --- a/Projects/UOContent/Spells/Necromancy/AnimateDeadSpell.cs +++ b/Projects/UOContent/Spells/Necromancy/AnimateDeadSpell.cs @@ -4,7 +4,6 @@ using Server.Engines.Quests; using Server.Engines.Quests.Necro; using Server.Items; using Server.Mobiles; -using Server.Targeting; using Server.Utilities; namespace Server.Spells.Necromancy diff --git a/Projects/UOContent/Spells/Second/MagicTrap.cs b/Projects/UOContent/Spells/Second/MagicTrap.cs index 13200240f..baf6e346f 100644 --- a/Projects/UOContent/Spells/Second/MagicTrap.cs +++ b/Projects/UOContent/Spells/Second/MagicTrap.cs @@ -1,5 +1,4 @@ using Server.Items; -using Server.Targeting; namespace Server.Spells.Second { diff --git a/Projects/UOContent/Spells/Second/RemoveTrap.cs b/Projects/UOContent/Spells/Second/RemoveTrap.cs index 3850205c0..cb800ddf2 100644 --- a/Projects/UOContent/Spells/Second/RemoveTrap.cs +++ b/Projects/UOContent/Spells/Second/RemoveTrap.cs @@ -1,5 +1,4 @@ using Server.Items; -using Server.Targeting; namespace Server.Spells.Second { diff --git a/Projects/UOContent/Spells/Seventh/ChainLightning.cs b/Projects/UOContent/Spells/Seventh/ChainLightning.cs index 0286729fe..6f3ec9923 100644 --- a/Projects/UOContent/Spells/Seventh/ChainLightning.cs +++ b/Projects/UOContent/Spells/Seventh/ChainLightning.cs @@ -1,6 +1,5 @@ using System.Collections.Generic; using System.Linq; -using Server.Targeting; namespace Server.Spells.Seventh { diff --git a/Projects/UOContent/Spells/Seventh/EnergyField.cs b/Projects/UOContent/Spells/Seventh/EnergyField.cs index 98177d63f..d802cd5e8 100644 --- a/Projects/UOContent/Spells/Seventh/EnergyField.cs +++ b/Projects/UOContent/Spells/Seventh/EnergyField.cs @@ -2,7 +2,6 @@ using System; using Server.Items; using Server.Misc; using Server.Mobiles; -using Server.Targeting; namespace Server.Spells.Seventh { diff --git a/Projects/UOContent/Spells/Seventh/MassDispel.cs b/Projects/UOContent/Spells/Seventh/MassDispel.cs index 9e40a0930..1b355af71 100644 --- a/Projects/UOContent/Spells/Seventh/MassDispel.cs +++ b/Projects/UOContent/Spells/Seventh/MassDispel.cs @@ -1,7 +1,6 @@ using Server.Collections; using Server.Items; using Server.Mobiles; -using Server.Targeting; namespace Server.Spells.Seventh { diff --git a/Projects/UOContent/Spells/Seventh/MeteorSwarm.cs b/Projects/UOContent/Spells/Seventh/MeteorSwarm.cs index 1d6e56825..19899f7b0 100644 --- a/Projects/UOContent/Spells/Seventh/MeteorSwarm.cs +++ b/Projects/UOContent/Spells/Seventh/MeteorSwarm.cs @@ -1,6 +1,5 @@ using System.Collections.Generic; using System.Linq; -using Server.Targeting; namespace Server.Spells.Seventh { diff --git a/Projects/UOContent/Spells/Sixth/Mark.cs b/Projects/UOContent/Spells/Sixth/Mark.cs index 0f8d7d6a1..d656ea5bd 100644 --- a/Projects/UOContent/Spells/Sixth/Mark.cs +++ b/Projects/UOContent/Spells/Sixth/Mark.cs @@ -1,6 +1,5 @@ using Server.Items; using Server.Network; -using Server.Targeting; namespace Server.Spells.Sixth { diff --git a/Projects/UOContent/Spells/Sixth/MassCurse.cs b/Projects/UOContent/Spells/Sixth/MassCurse.cs index bbd7e183e..069805a0f 100644 --- a/Projects/UOContent/Spells/Sixth/MassCurse.cs +++ b/Projects/UOContent/Spells/Sixth/MassCurse.cs @@ -1,5 +1,3 @@ -using Server.Targeting; - namespace Server.Spells.Sixth { public class MassCurseSpell : MagerySpell, ISpellTargetingPoint3D diff --git a/Projects/UOContent/Spells/Sixth/ParalyzeField.cs b/Projects/UOContent/Spells/Sixth/ParalyzeField.cs index 475bc4406..8a018caba 100644 --- a/Projects/UOContent/Spells/Sixth/ParalyzeField.cs +++ b/Projects/UOContent/Spells/Sixth/ParalyzeField.cs @@ -2,7 +2,6 @@ using System; using Server.Items; using Server.Misc; using Server.Mobiles; -using Server.Targeting; namespace Server.Spells.Sixth { diff --git a/Projects/UOContent/Spells/Sixth/Reveal.cs b/Projects/UOContent/Spells/Sixth/Reveal.cs index 653594d25..edaf005a3 100644 --- a/Projects/UOContent/Spells/Sixth/Reveal.cs +++ b/Projects/UOContent/Spells/Sixth/Reveal.cs @@ -1,5 +1,4 @@ using Server.Mobiles; -using Server.Targeting; namespace Server.Spells.Sixth { diff --git a/Projects/UOContent/Spells/Targeting/SpellTargetItem.cs b/Projects/UOContent/Spells/Targeting/SpellTargetItem.cs index 0bab04b1d..3d29a33a5 100644 --- a/Projects/UOContent/Spells/Targeting/SpellTargetItem.cs +++ b/Projects/UOContent/Spells/Targeting/SpellTargetItem.cs @@ -16,12 +16,12 @@ namespace Server.Spells public ISpell Spell => _spell; + protected override bool CanTarget(Mobile from, StaticTarget staticTarget, ref Point3D loc, ref Map map) => false; + protected override bool CanTarget(Mobile from, Mobile mobile, ref Point3D loc, ref Map map) => false; + protected override void OnTarget(Mobile from, object o) { - if (o is Item item) - { - _spell.Target(item); - } + _spell.Target(o as Item); } protected override void OnTargetFinish(Mobile from) diff --git a/Projects/UOContent/Spells/Targeting/SpellTargetMobile.cs b/Projects/UOContent/Spells/Targeting/SpellTargetMobile.cs index b8e245cf7..c97511dcd 100644 --- a/Projects/UOContent/Spells/Targeting/SpellTargetMobile.cs +++ b/Projects/UOContent/Spells/Targeting/SpellTargetMobile.cs @@ -16,6 +16,9 @@ namespace Server.Spells public ISpell Spell => _spell; + protected override bool CanTarget(Mobile from, StaticTarget staticTarget, ref Point3D loc, ref Map map) => false; + protected override bool CanTarget(Mobile from, Item item, ref Point3D loc, ref Map map) => false; + protected override void OnTarget(Mobile from, object o) { _spell.Target(o as Mobile); diff --git a/Projects/UOContent/Spells/Targeting/SpellTargetPoint3D.cs b/Projects/UOContent/Spells/Targeting/SpellTargetPoint3D.cs index 40da7d383..ba6b4838b 100644 --- a/Projects/UOContent/Spells/Targeting/SpellTargetPoint3D.cs +++ b/Projects/UOContent/Spells/Targeting/SpellTargetPoint3D.cs @@ -24,10 +24,7 @@ namespace Server.Spells protected override void OnTarget(Mobile from, object o) { - if (o is IPoint3D p) - { - _spell.Target(p); - } + _spell.Target(o as IPoint3D); } protected override void OnTargetOutOfLOS(Mobile from, object o) diff --git a/Projects/UOContent/Spells/Third/MagicLock.cs b/Projects/UOContent/Spells/Third/MagicLock.cs index 55da042cc..76b0ef7a6 100644 --- a/Projects/UOContent/Spells/Third/MagicLock.cs +++ b/Projects/UOContent/Spells/Third/MagicLock.cs @@ -1,7 +1,6 @@ using Server.Items; using Server.Multis; using Server.Network; -using Server.Targeting; namespace Server.Spells.Third { diff --git a/Projects/UOContent/Spells/Third/Telekinesis.cs b/Projects/UOContent/Spells/Third/Telekinesis.cs index f41be5a7f..aeb3a24be 100644 --- a/Projects/UOContent/Spells/Third/Telekinesis.cs +++ b/Projects/UOContent/Spells/Third/Telekinesis.cs @@ -1,5 +1,4 @@ using Server.Items; -using Server.Targeting; namespace Server.Spells.Third { diff --git a/Projects/UOContent/Spells/Third/Teleport.cs b/Projects/UOContent/Spells/Third/Teleport.cs index c2797f9f4..9e2b2236a 100644 --- a/Projects/UOContent/Spells/Third/Teleport.cs +++ b/Projects/UOContent/Spells/Third/Teleport.cs @@ -5,7 +5,6 @@ using Server.Regions; using Server.Spells.Fifth; using Server.Spells.Fourth; using Server.Spells.Sixth; -using Server.Targeting; namespace Server.Spells.Third { diff --git a/Projects/UOContent/Spells/Third/Unlock.cs b/Projects/UOContent/Spells/Third/Unlock.cs index 6476bd0c7..715cf1e82 100644 --- a/Projects/UOContent/Spells/Third/Unlock.cs +++ b/Projects/UOContent/Spells/Third/Unlock.cs @@ -1,7 +1,6 @@ using Server.Items; using Server.Multis; using Server.Network; -using Server.Targeting; namespace Server.Spells.Third { diff --git a/Projects/UOContent/Spells/Third/WallOfStone.cs b/Projects/UOContent/Spells/Third/WallOfStone.cs index fd4bd0b2d..0be6b4b9c 100644 --- a/Projects/UOContent/Spells/Third/WallOfStone.cs +++ b/Projects/UOContent/Spells/Third/WallOfStone.cs @@ -1,7 +1,6 @@ using System; using Server.Misc; using Server.Mobiles; -using Server.Targeting; namespace Server.Spells.Third { From d1f4632012a6244e6add216df57415d9b8550f4f Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Thu, 2 Dec 2021 09:35:52 -0800 Subject: [PATCH 026/213] fix: Fixes targeting range (#871) --- Projects/Server/Targeting/Target.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Projects/Server/Targeting/Target.cs b/Projects/Server/Targeting/Target.cs index 90d08d3db..69cec2c75 100644 --- a/Projects/Server/Targeting/Target.cs +++ b/Projects/Server/Targeting/Target.cs @@ -182,7 +182,7 @@ namespace Server.Targeting OnTargetFinish(from); } - if (map == null || map != from.Map || Range < 0 && !from.InRange(loc, Range)) + if (map == null || map != from.Map || Range >= 0 && !from.InRange(loc, Range)) { OnTargetOutOfRange(from, targeted); } From 12255fd7a8b24f5f82a54c7652ad95b17da5e80d Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Thu, 2 Dec 2021 11:49:36 -0800 Subject: [PATCH 027/213] fix: Adds back pre-pub-21 para blow (#872) --- .../Items/Weapons/Abilities/ParalyzingBlow.cs | 37 +++++++++++++++++-- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/Projects/UOContent/Items/Weapons/Abilities/ParalyzingBlow.cs b/Projects/UOContent/Items/Weapons/Abilities/ParalyzingBlow.cs index 43f985df1..ecd9ebf1b 100644 --- a/Projects/UOContent/Items/Weapons/Abilities/ParalyzingBlow.cs +++ b/Projects/UOContent/Items/Weapons/Abilities/ParalyzingBlow.cs @@ -17,9 +17,31 @@ namespace Server.Items public override int BaseMana => 30; - // When using Wrestling, tactics isnt needed. + // When using Wrestling, tactics isn't needed. public override bool RequiresTactics(Mobile from) => - !(from.Weapon is BaseWeapon weapon && weapon.Skill == SkillName.Wrestling); + Core.AOS && from.Weapon is not BaseWeapon { Skill: SkillName.Wrestling }; + + public override bool CheckSkills(Mobile from) + { + if (!base.CheckSkills(from)) + { + return false; + } + + if (Core.AOS || from.Weapon is not Fists) + { + return true; + } + + if (from.Skills[SkillName.Anatomy] is { Value: >= 80.0 }) + { + return true; + } + + from.SendLocalizedMessage(1061811); // You lack the required anatomy skill to perform that attack! + + return false; + } public override bool OnBeforeSwing(Mobile attacker, Mobile defender) { @@ -56,8 +78,15 @@ namespace Server.Items var duration = defender.Player ? PlayerFreezeDuration : NPCFreezeDuration; - // Treat it as paralyze not as freeze, effect must be removed when damaged. - defender.Paralyze(duration); + // Pub 21: Treat it as paralyze, not as freeze, effect must be removed when damaged. + if (Core.AOS) + { + defender.Paralyze(duration); + } + else + { + defender.Freeze(duration); + } BeginImmunity(defender, duration + FreezeDelayDuration); } From 08baf3c35dffc5a2f682f1704b50f2203ed55d42 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sat, 4 Dec 2021 11:31:52 -0800 Subject: [PATCH 028/213] fix: Fixes explosion potions (#873) * Fixes the users list not being cleared out * Removes the LINQ allocations --- .../Explosion Potions/BaseExplosionPotion.cs | 66 +++++++++---------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/Projects/UOContent/Items/Skill Items/Magical/Potions/Explosion Potions/BaseExplosionPotion.cs b/Projects/UOContent/Items/Skill Items/Magical/Potions/Explosion Potions/BaseExplosionPotion.cs index 3ada8a14a..01de15b12 100644 --- a/Projects/UOContent/Items/Skill Items/Magical/Potions/Explosion Potions/BaseExplosionPotion.cs +++ b/Projects/UOContent/Items/Skill Items/Magical/Potions/Explosion Potions/BaseExplosionPotion.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using System.Linq; +using Server.Collections; using Server.Network; using Server.Spells; using Server.Targeting; @@ -30,7 +30,7 @@ namespace Server.Items public override bool RequireFreeHand => false; - public List Users { get; private set; } + private HashSet _users; public override void Serialize(IGenericWriter writer) { @@ -84,12 +84,8 @@ namespace Server.Items from.RevealingAction(); - Users ??= new List(); - - if (!Users.Contains(from)) - { - Users.Add(from); - } + _users ??= new HashSet(); + _users.Add(from); from.Target = new ThrowTarget(this); @@ -195,65 +191,69 @@ namespace Server.Items Consume(); - for (var i = 0; i < Users?.Count; ++i) + foreach (var user in _users) { - var m = Users[i]; - - if (m.Target is ThrowTarget targ && targ.Potion == this) + if (user.Target is ThrowTarget targ && targ.Potion == this) { - Target.Cancel(m); + Target.Cancel(user); } } + _users.Clear(); + if (map == null) { return; } Effects.PlaySound(loc, map, 0x307); - Effects.SendLocationEffect(loc, map, 0x36B0, 9); - var alchemyBonus = 0; + var alchemyBonus = 0; if (direct) { alchemyBonus = (int)(from.Skills.Alchemy.Value / (Core.AOS ? 5 : 10)); } var eable = map.GetObjectsInRange(loc, ExplosionRange, LeveledExplosion); + using var queue = PooledRefQueue.Create(); + var toDamage = 0; + foreach (var entity in eable) + { + if (entity == this) + { + continue; + } - var toExplode = eable.Where( - o => + if (entity is Mobile mobile) + { + if (from == null || SpellHelper.ValidIndirectTarget(from, mobile) && from.CanBeHarmful(mobile, false)) { - if (!(o is Mobile mobile) || from != null && - (!SpellHelper.ValidIndirectTarget(from, mobile) || !from.CanBeHarmful(mobile, false))) - { - return o is BaseExplosionPotion && o != this; - } - ++toDamage; - return true; + queue.Enqueue(entity); } - ) - .ToList(); + } + else if (entity is BaseExplosionPotion) + { + queue.Enqueue(entity); + } + } eable.Free(); var min = Scale(from, MinDamage); var max = Scale(from, MaxDamage); - for (var i = 0; i < toExplode.Count; ++i) + while (queue.Count > 0) { - var o = toExplode[i]; + var entity = queue.Dequeue(); - if (o is Mobile m) + if (entity is Mobile m) { from?.DoHarmful(m); - var damage = Utility.RandomMinMax(min, max); - - damage += alchemyBonus; + var damage = Utility.RandomMinMax(min, max) + alchemyBonus; if (!Core.AOS && damage > 40) { @@ -266,7 +266,7 @@ namespace Server.Items AOS.Damage(m, from, damage, 0, 100, 0, 0, 0); } - else if (o is BaseExplosionPotion pot) + else if (entity is BaseExplosionPotion pot) { pot.Explode(from, false, pot.GetWorldLocation(), pot.Map); } From 7da6cec27ed56519768a3f1f844884ee75bcb7a5 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sat, 4 Dec 2021 11:58:59 -0800 Subject: [PATCH 029/213] fix: Bumps source generator to netstandard2.1 (#874) --- .github/workflows/build-test.yml | 2 +- .../SerializationGenerator.csproj | 8 ++++---- .../SerializationSchemaGenerator.csproj | 1 + Projects/Server/Server.csproj | 2 +- Projects/UOContent/UOContent.csproj | 2 +- azure-pipelines.yml | 16 +++------------- 6 files changed, 11 insertions(+), 20 deletions(-) diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 8e8872f94..3a2b28871 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -30,4 +30,4 @@ jobs: - name: Build run: ./publish.cmd - name: Test - run: dotnet test --no-restore --framework net6.0 + run: dotnet test --no-restore diff --git a/Projects/SerializationGenerator/SerializationGenerator.csproj b/Projects/SerializationGenerator/SerializationGenerator.csproj index f74e5e965..1daae2ff1 100755 --- a/Projects/SerializationGenerator/SerializationGenerator.csproj +++ b/Projects/SerializationGenerator/SerializationGenerator.csproj @@ -1,6 +1,6 @@ - netstandard2.0 + netstandard2.1 preview analyzers @@ -21,9 +21,9 @@ - - - + + + diff --git a/Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj b/Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj index d3d1a168e..1df2df68a 100755 --- a/Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj +++ b/Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj @@ -12,6 +12,7 @@ + diff --git a/Projects/Server/Server.csproj b/Projects/Server/Server.csproj index 6a0cc1ab5..5694a4e65 100755 --- a/Projects/Server/Server.csproj +++ b/Projects/Server/Server.csproj @@ -40,7 +40,7 @@ - TargetFramework=netstandard2.0 + TargetFramework=netstandard2.1 Analyzer false all diff --git a/Projects/UOContent/UOContent.csproj b/Projects/UOContent/UOContent.csproj index fc7ae24ab..a6094ec12 100755 --- a/Projects/UOContent/UOContent.csproj +++ b/Projects/UOContent/UOContent.csproj @@ -47,7 +47,7 @@ - TargetFramework=netstandard2.0 + TargetFramework=netstandard2.1 Analyzer false all diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 6923ed2ae..01b7d413d 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -14,11 +14,6 @@ jobs: vmImage: 'windows-latest' steps: - - task: UseDotNet@2 - displayName: 'Install .NET 5' - inputs: - packageType: sdk - version: 5.0.403 - task: UseDotNet@2 displayName: 'Install .NET 6' inputs: @@ -27,7 +22,7 @@ jobs: - task: NuGetAuthenticate@0 - script: ./publish.cmd Release win displayName: 'Build' - - script: dotnet test --no-restore --framework net6.0 + - script: dotnet test --no-restore displayName: 'Test' - job: BuildLinux @@ -46,7 +41,7 @@ jobs: # containerImage: amd64/buildpack-deps:bullseye # os: debian.11-x64 'Ubuntu 20': - containerImage: mcr.microsoft.com/dotnet/sdk:5.0-focal + containerImage: mcr.microsoft.com/dotnet/sdk:6.0-focal os: ubuntu.20.04 'Fedora 32': containerImage: fedora:32 @@ -63,11 +58,6 @@ jobs: container: $[ variables['containerImage'] ] steps: - - task: UseDotNet@2 - displayName: 'Install .NET 5' - inputs: - packageType: sdk - version: 5.0.403 - task: UseDotNet@2 displayName: 'Install .NET 6' inputs: @@ -76,5 +66,5 @@ jobs: - task: NuGetAuthenticate@0 - script: ./publish.cmd Release $(os) displayName: 'Build' - - script: dotnet test --no-restore --framework net6.0 + - script: dotnet test --no-restore displayName: 'Test' From b67d57d806c4dc2ced928992eb4ee8a9f5a989e5 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sat, 4 Dec 2021 23:40:38 -0800 Subject: [PATCH 030/213] fix: Adds Debian 11 and fixes Fedora 34 support (#875) * Adds Debian 11 support * Fixes Fedora 34 support * Updates CentOS8 support --- Directory.Build.props | 2 +- Projects/Server.Tests/Server.Tests.csproj | 2 +- Projects/Server/Server.csproj | 2 +- Projects/UOContent/UOContent.csproj | 6 +++--- azure-pipelines.yml | 12 ++++++------ 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index c48855eab..aa4172a54 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -11,7 +11,7 @@ true true NU1603 - win-x64;debian.10-x64;debian.9-x64;ubuntu.16.04-x64;ubuntu.18.04-x64;ubuntu.20.04-x64;centos.7-x64;centos.8-x64;fedora.32-x64;fedora.33-x64;rhel.7-x64;rhel.8-x64;osx-x64 + win-x64;debian.9-x64;debian.10-x64;debian.11-x64;ubuntu.16.04-x64;ubuntu.18.04-x64;ubuntu.20.04-x64;centos.7-x64;centos.8-x64;fedora.32-x64;fedora.33-x64;fedora.34-x64;rhel.7-x64;rhel.8-x64;osx-x64 Debug;Release;Analyze false true diff --git a/Projects/Server.Tests/Server.Tests.csproj b/Projects/Server.Tests/Server.Tests.csproj index 2a47a0de7..6536e8cab 100644 --- a/Projects/Server.Tests/Server.Tests.csproj +++ b/Projects/Server.Tests/Server.Tests.csproj @@ -7,7 +7,7 @@ - + diff --git a/Projects/Server/Server.csproj b/Projects/Server/Server.csproj index 5694a4e65..4efc9e1a9 100755 --- a/Projects/Server/Server.csproj +++ b/Projects/Server/Server.csproj @@ -36,7 +36,7 @@ - + diff --git a/Projects/UOContent/UOContent.csproj b/Projects/UOContent/UOContent.csproj index a6094ec12..c5561de3d 100755 --- a/Projects/UOContent/UOContent.csproj +++ b/Projects/UOContent/UOContent.csproj @@ -41,9 +41,9 @@ - - - + + + diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 01b7d413d..38df04622 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -34,12 +34,9 @@ jobs: 'CentOS 7': containerImage: centos:7 os: centos.7 - 'Debian 10': - containerImage: mcr.microsoft.com/dotnet/sdk:5.0-buster-slim - os: debian.10 - # 'Debian 11': - # containerImage: amd64/buildpack-deps:bullseye - # os: debian.11-x64 + 'Debian 11': + containerImage: mcr.microsoft.com/dotnet/sdk:6.0-bullseye-slim + os: debian.11 'Ubuntu 20': containerImage: mcr.microsoft.com/dotnet/sdk:6.0-focal os: ubuntu.20.04 @@ -49,6 +46,9 @@ jobs: 'Fedora 33': containerImage: fedora:33 os: fedora.33 + 'Fedora 34': + containerImage: fedora:34 + os: fedora.34 displayName: Linux From a103b2af2d5c51d05e4d1f2e9ec90dac5c646f67 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 5 Dec 2021 00:02:32 -0800 Subject: [PATCH 031/213] fix: Updates README (#876) --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index b37e7ef2e..8825dd323 100644 --- a/README.md +++ b/README.md @@ -15,12 +15,12 @@ ModernUO [![Discord](https://img.shields.io/discord/751317910504603701?logo=disc ## Requirements #### Supported Operating Systems -[![Windows 8.1/10/2016/2019](https://img.shields.io/badge/-server%202019-0078D6?logo=windows)](https://www.microsoft.com/en-US/evalcenter/evaluate-windows-server-2019) -![MacOS 10/11](https://img.shields.io/badge/-big%20sur-222222?logo=apple&logoColor=white) -[![Debian 9/10](https://img.shields.io/badge/-buster-A81D33?logo=debian)](https://www.debian.org/distrib/) +[![Windows 8.1/10/2016/2019/2022](https://img.shields.io/badge/-server%202022-0078D6?logo=windows)](https://www.microsoft.com/en-US/evalcenter/evaluate-windows-server-2019) +![MacOS 10/11/12](https://img.shields.io/badge/-monterey-222222?logo=apple&logoColor=white) +[![Debian 9/10/11](https://img.shields.io/badge/-bullseye-A81D33?logo=debian)](https://www.debian.org/distrib/) [![Ubuntu 16/18/20 LTS](https://img.shields.io/badge/-20LTS-E95420?logo=ubuntu&logoColor=white)](https://ubuntu.com/download/server) -[![CentOS 7/8](https://img.shields.io/badge/-8.3-262577?logo=centos&logoColor=white)](https://www.centos.org/download/) -[![Fedora 32/33/34](https://img.shields.io/badge/-33-0B57A4?logo=fedora&logoColor=white)](https://getfedora.org/en/server/download/) +[![CentOS 7/8](https://img.shields.io/badge/-8.5-262577?logo=centos&logoColor=white)](https://www.centos.org/download/) +[![Fedora 32/33/34](https://img.shields.io/badge/-34-0B57A4?logo=fedora&logoColor=white)](https://getfedora.org/en/server/download/) [![RedHat 7/8](https://img.shields.io/badge/-8-BE0000?logo=red%20hat&logoColor=white)](https://access.redhat.com/downloads) #### Running the server @@ -31,9 +31,9 @@ ModernUO [![Discord](https://img.shields.io/discord/751317910504603701?logo=disc [![.NET](https://img.shields.io/badge/.NET-%206.0%20SDK-5C2D91)](https://dotnet.microsoft.com/download/dotnet/6.0) #### Supported IDEs -  +    [Jetbrains Rider 2021.3](https://www.jetbrains.com/rider/download) -                     +                          [Visual Studio 2022](https://visualstudio.microsoft.com/downloads)
Rider 2021.3+             Visual Studio 2022+ @@ -49,9 +49,9 @@ Rider 2021.3+           & - Run `./publish.cmd [release|debug (default: release)] [os]` - `os` - [Supported operating systems](https://github.com/dotnet/core/blob/master/release-notes/5.0/5.0-supported-os.md) - `win` - Windows 8.1/10/2016/2019 - - `osx` - MacOS 10.13+/11.0 (High Sierra, Mojave, Catalina, & Big Sur) + - `osx` - MacOS 10.15/11.0+/12.0+ (Catalina, Big Sur, Monterey) - `ubuntu.16.04`, `ubuntu.18.04` `ubuntu.20.04` - Ubuntu LTS - - `debian.9`, `debian.10` - Debian + - `debian.9`, `debian.10`, `debian.11` - Debian - `centos.7`, `centos.8` - CentOS - `fedora.32`, `fedora.33`, `fedora.34` - Fedora - `rhel.7`, `rhel.8` - Redhat From b3c153eae36d7b178bcbffc9d52038a49c3e1961 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 5 Dec 2021 00:13:47 -0800 Subject: [PATCH 032/213] fix: Removes Debian 9 support, Adds Windows 11 (#877) --- Directory.Build.props | 2 +- README.md | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index aa4172a54..be723978b 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -11,7 +11,7 @@ true true NU1603 - win-x64;debian.9-x64;debian.10-x64;debian.11-x64;ubuntu.16.04-x64;ubuntu.18.04-x64;ubuntu.20.04-x64;centos.7-x64;centos.8-x64;fedora.32-x64;fedora.33-x64;fedora.34-x64;rhel.7-x64;rhel.8-x64;osx-x64 + win-x64;debian.10-x64;debian.11-x64;ubuntu.16.04-x64;ubuntu.18.04-x64;ubuntu.20.04-x64;centos.7-x64;centos.8-x64;fedora.32-x64;fedora.33-x64;fedora.34-x64;rhel.7-x64;rhel.8-x64;osx-x64 Debug;Release;Analyze false true diff --git a/README.md b/README.md index 8825dd323..1ee0cb293 100644 --- a/README.md +++ b/README.md @@ -15,9 +15,9 @@ ModernUO [![Discord](https://img.shields.io/discord/751317910504603701?logo=disc ## Requirements #### Supported Operating Systems -[![Windows 8.1/10/2016/2019/2022](https://img.shields.io/badge/-server%202022-0078D6?logo=windows)](https://www.microsoft.com/en-US/evalcenter/evaluate-windows-server-2019) -![MacOS 10/11/12](https://img.shields.io/badge/-monterey-222222?logo=apple&logoColor=white) -[![Debian 9/10/11](https://img.shields.io/badge/-bullseye-A81D33?logo=debian)](https://www.debian.org/distrib/) +[![Windows 10/11/2016/2019/2022](https://img.shields.io/badge/-server%202022-0078D6?logo=windows)](https://www.microsoft.com/en-US/evalcenter/evaluate-windows-server-2022) +![MacOS 10.15/11/12](https://img.shields.io/badge/-monterey-222222?logo=apple&logoColor=white) +[![Debian 10/11](https://img.shields.io/badge/-bullseye-A81D33?logo=debian)](https://www.debian.org/distrib/) [![Ubuntu 16/18/20 LTS](https://img.shields.io/badge/-20LTS-E95420?logo=ubuntu&logoColor=white)](https://ubuntu.com/download/server) [![CentOS 7/8](https://img.shields.io/badge/-8.5-262577?logo=centos&logoColor=white)](https://www.centos.org/download/) [![Fedora 32/33/34](https://img.shields.io/badge/-34-0B57A4?logo=fedora&logoColor=white)](https://getfedora.org/en/server/download/) @@ -47,11 +47,11 @@ Rider 2021.3+           & ## Building/Publishing - Run `./publish.cmd [release|debug (default: release)] [os]` - - `os` - [Supported operating systems](https://github.com/dotnet/core/blob/master/release-notes/5.0/5.0-supported-os.md) - - `win` - Windows 8.1/10/2016/2019 + - `os` - [Supported operating systems](https://github.com/dotnet/core/blob/main/release-notes/6.0/supported-os.md) + - `win` - Windows 10/11/2016/2019/2022 - `osx` - MacOS 10.15/11.0+/12.0+ (Catalina, Big Sur, Monterey) - `ubuntu.16.04`, `ubuntu.18.04` `ubuntu.20.04` - Ubuntu LTS - - `debian.9`, `debian.10`, `debian.11` - Debian + - `debian.10`, `debian.11` - Debian - `centos.7`, `centos.8` - CentOS - `fedora.32`, `fedora.33`, `fedora.34` - Fedora - `rhel.7`, `rhel.8` - Redhat From 1cf7b6c056ae8fb458cf176a30e82352ac6fb72a Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 5 Dec 2021 08:56:09 -0800 Subject: [PATCH 033/213] fix: Fixes badly formatted files (#878) --- Projects/UOContent/Engines/Help/HelpGump.cs | 10 +- .../ML Quests/Definitions/AGhostOfCovetous.cs | 16 +- .../ML Quests/Definitions/Heartwood.cs | 217 +++++++++--------- .../Engines/ML Quests/Definitions/Heritage.cs | 4 +- .../ML Quests/Definitions/HonestBeggar.cs | 8 +- .../Engines/ML Quests/Definitions/Ilshenar.cs | 10 +- .../ML Quests/Definitions/MistakenIdentity.cs | 6 +- .../Definitions/NewHavenSkillTraining.cs | 4 +- .../ML Quests/Definitions/NewHavenTraining.cs | 46 ++-- .../ML Quests/Definitions/Sanctuary.cs | 41 ++-- .../ML Quests/Definitions/Spellweaving.cs | 29 +-- .../ML Quests/Definitions/TheAncientWorld.cs | 2 +- .../ML Quests/Definitions/UnfadingMemories.cs | 49 ++-- .../Dark Tides/Items/ScrollOfAbraxus.cs | 2 +- .../Mobiles/HiddenFigure.cs | 2 +- .../Quests/Haochi's Trials/Conversations.cs | 51 ++-- Projects/UOContent/Gumps/RunebookGump.cs | 12 +- .../Items/Shields/Artifacts/Aegis.cs | 2 +- .../UOContent/Items/Shields/BaseShield.cs | 34 +-- .../Items/Skill Items/Fishing/Misc/SOS.cs | 2 +- .../Items/Skill Items/Fishing/Misc/Sextant.cs | 2 +- .../Dawn's Music Box/DawnsMusicBox.cs | 2 +- .../8th Anniversary Items/DupresShield.cs | 2 +- .../Items/Special/Gifts/ShaminoCrossbow.cs | 2 +- .../Items/Special/Holiday/HolidayFoods.cs | 4 +- Projects/UOContent/Items/Wands/BaseWand.cs | 9 +- .../Weapons/Abilities/InfectiousStrike.cs | 2 +- .../Items/Weapons/Abilities/ShadowStrike.cs | 2 +- Projects/UOContent/Spells/Base/Spell.cs | 2 +- .../UOContent/Spells/Fifth/MagicReflect.cs | 3 +- .../UOContent/Spells/First/ReactiveArmor.cs | 3 +- .../UOContent/Spells/Necromancy/Wither.cs | 2 +- .../UOContent/Spells/Second/Protection.cs | 4 +- 33 files changed, 274 insertions(+), 312 deletions(-) diff --git a/Projects/UOContent/Engines/Help/HelpGump.cs b/Projects/UOContent/Engines/Help/HelpGump.cs index de622407e..4d46a047b 100644 --- a/Projects/UOContent/Engines/Help/HelpGump.cs +++ b/Projects/UOContent/Engines/Help/HelpGump.cs @@ -225,21 +225,21 @@ namespace Server.Engines.Help * Use this option when another player is verbally harassing your character. * Verbal harassment behaviors include but are not limited to, using bad language, threats etc.. * Before you submit a complaint be sure you understand what constitutes harassment - * � what is verbal harassment? - + * - what is verbal harassment? - * and that you have followed these steps:
* 1. You have asked the player to stop and they have continued.
* 2. You have tried to remove yourself from the situation.
* 3. You have done nothing to instigate or further encourage the harassment.
* 4. You have added the player to your ignore list. * - How do I ignore a player?
- * 5. You have read and understand Origin�s definition of harassment.
+ * 5. You have read and understand Origin's definition of harassment.
* 6. Your account information is up to date. (Including a current email address)
* *If these steps have not been taken, GMs may be unable to take action against the offending player.
* **A chat log will be review by a GM to assess the validity of this complaint. * Abuse of this system is a violation of the Rules of Conduct.
* EXPLOITING
* Use this option to report someone who may be exploiting or cheating. - * � What constitutes an exploit? + * - What constitutes an exploit? */ AddHtmlLocalized( 110, @@ -259,14 +259,14 @@ namespace Server.Engines.Help * Use this option when another player is harassing your character using game mechanics. * Physical harassment includes but is not limited to luring, Kill Stealing, and any act that causes a players death in Trammel. * Before you submit a complaint be sure you understand what constitutes harassment - * � what is physical harassment? + * - what is physical harassment? * and that you have followed these steps:
* 1. You have asked the player to stop and they have continued.
* 2. You have tried to remove yourself from the situation.
* 3. You have done nothing to instigate or further encourage the harassment.
* 4. You have added the player to your ignore list. * - how do I ignore a player?
- * 5. You have read and understand Origin�s definition of harassment.
+ * 5. You have read and understand Origin's definition of harassment.
* 6. Your account information is up to date. (Including a current email address)
* *If these steps have not been taken, GMs may be unable to take action against the offending player.
* **This issue will be reviewed by a GM to assess the validity of this complaint. diff --git a/Projects/UOContent/Engines/ML Quests/Definitions/AGhostOfCovetous.cs b/Projects/UOContent/Engines/ML Quests/Definitions/AGhostOfCovetous.cs index 71afef63e..754d1d8f0 100644 --- a/Projects/UOContent/Engines/ML Quests/Definitions/AGhostOfCovetous.cs +++ b/Projects/UOContent/Engines/ML Quests/Definitions/AGhostOfCovetous.cs @@ -42,8 +42,8 @@ namespace Server.Engines.MLQuests.Definitions Activated = true; Title = 1075337; // Save His Dad Description = - 1075338; // My father, Andros, is a smith in Minoc. Last week his forge overturned and he was splashed by molten steel. He was horribly burned, and we feared he would die. An alchemist in Vesper promised to make a bandage that could heal him, but he needed the silk of a dread spider. I came here to get some, but I was careless, and succumbed to their poison. Please, won�t you help my father? - RefusalMessage = 1075340; // Oh . . . that�s your decision . . . OooOoooOOoo . . . + 1075338; // My father, Andros, is a smith in Minoc. Last week his forge overturned and he was splashed by molten steel. He was horribly burned, and we feared he would die. An alchemist in Vesper promised to make a bandage that could heal him, but he needed the silk of a dread spider. I came here to get some, but I was careless, and succumbed to their poison. Please, won't you help my father? + RefusalMessage = 1075340; // Oh . . . that's your decision . . . OooOoooOOoo . . . InProgressMessage = 1075341; // Thank you! Deliver it to Leon the Alchemist in Vesper. The silk crumbles easily, and much time has already passed since I died. Please! Hurry! CompletionMessage = @@ -74,20 +74,20 @@ namespace Server.Engines.MLQuests.Definitions { Activated = true; OneTimeOnly = true; - Title = 1075343; // A Father�s Gratitude + Title = 1075343; // A Father's Gratitude Description = - 1075344; // That is simply terrible. First Andros, and now his son. Well, let�s make sure Frederic�s sacrifice wasn�t in vain. Will you take the bandages to his father? You can probably deliver them faster than I can, can�t you? + 1075344; // That is simply terrible. First Andros, and now his son. Well, let's make sure Frederic's sacrifice wasn't in vain. Will you take the bandages to his father? You can probably deliver them faster than I can, can't you? RefusalMessage = - 1075346; // Well I�m sorry to hear you say that. Without your help, I don�t know if I can get these to Andros quickly enough to help him. + 1075346; // Well I'm sorry to hear you say that. Without your help, I don't know if I can get these to Andros quickly enough to help him. InProgressMessage = - 1075347; // I don�t know how much longer Andros will survive. You�d better get this to him as quick as you can. Every second counts! + 1075347; // I don't know how much longer Andros will survive. You'd better get this to him as quick as you can. Every second counts! CompletionMessage = - 1075348; // Sorry, I�m not accepting commissions at the moment. What? You have the bandage I need from Leon? Thank you so much! But why didn�t my son bring this to me himself? . . . Oh, no! You can't be serious! *sag* My Freddie, my son! Thank you for carrying out his last wish. Here -- I made this for my son, to give to him when he became a journeyman. I want you to have it. + 1075348; // Sorry, I'm not accepting commissions at the moment. What? You have the bandage I need from Leon? Thank you so much! But why didn't my son bring this to me himself? . . . Oh, no! You can't be serious! *sag* My Freddie, my son! Thank you for carrying out his last wish. Here -- I made this for my son, to give to him when he became a journeyman. I want you to have it. CompletionNotice = CompletionNoticeShort; Objectives.Add(new DeliverObjective(typeof(AlchemistsBandage), 1, "Alchemist's Bandage", typeof(Andros))); - Rewards.Add(new ItemReward(1075345, typeof(AndrosGratitude))); // Andros� Gratitude + Rewards.Add(new ItemReward(1075345, typeof(AndrosGratitude))); // Andros' Gratitude } public override bool IsChainTriggered => true; diff --git a/Projects/UOContent/Engines/ML Quests/Definitions/Heartwood.cs b/Projects/UOContent/Engines/ML Quests/Definitions/Heartwood.cs index fe29cbcf7..20e0216f3 100644 --- a/Projects/UOContent/Engines/ML Quests/Definitions/Heartwood.cs +++ b/Projects/UOContent/Engines/ML Quests/Definitions/Heartwood.cs @@ -230,7 +230,7 @@ namespace Server.Engines.MLQuests.Definitions // Restless spirits are known to inhabit these parts, taking the lives of unwary travelers. // It is about time a hero put the dead back in their graves. I'm sure such a hero would be justly rewarded. Description = 1073566; - RefusalMessage = 1073580; // I hope you'll reconsider. Until then, farewell. + RefusalMessage = 1073580; // I hope you'll reconsider. Until then, farwell. InProgressMessage = 1073586; // The restless spirts still walk -- you must kill 15 of them. Objectives.Add( @@ -313,7 +313,7 @@ namespace Server.Engines.MLQuests.Definitions // Please, put them out of their misery. // I will offer you what payment I can if you will end the torment of these undead wretches. Description = 1073565; - RefusalMessage = 1073580; // I hope you'll reconsider. Until then, farewell. + RefusalMessage = 1073580; // I hope you'll reconsider. Until then, farwell. InProgressMessage = 1073585; // Your task is not done. Continue putting the Skeleton and Bone Knights to rest. Objectives.Add( @@ -1314,12 +1314,12 @@ namespace Server.Engines.MLQuests.Definitions { Activated = true; Title = 1074280; // Reptilian Dentist - Description = - 1074710; // I'm working on a striking necklace -- something really unique -- and I know just what I need to finish it up. A huge fang! Won't that catch the eye? I would like to employ you to find me such an item, perhaps a snake would make the ideal donor. I'll make it worth your while, of course. + // I'm working on a striking necklace -- something really unique -- and I know just what I need to finish it up. A huge fang! Won't that catch the eye? I would like to employ you to find me such an item, perhaps a snake would make the ideal donor. I'll make it worth your while, of course. + Description = 1074710; RefusalMessage = 1074723; // I understand. I don't like snakes much either. They're so creepy. - InProgressMessage = - 1074722; // Those really big snakes like swamps, I've heard. You might try the blighted grove. - CompletionMessage = 1074721; // Do you have it? *gasp* What a tooth! Here � I must get right to work. + // Those really big snakes like swamps, I've heard. You might try the blighted grove. + InProgressMessage = 1074722; + CompletionMessage = 1074721; // Do you have it? *gasp* What a tooth! Here … I must get right to work. Objectives.Add(new CollectObjective(1, typeof(CoilsFang), "coil's fang")); @@ -1334,8 +1334,8 @@ namespace Server.Engines.MLQuests.Definitions Activated = true; HasRestartDelay = true; Title = 1073881; // Stop Harping on Me - Description = - 1074071; // Humans artistry can be a remarkable thing. For instance, I have heard of a wonderful instrument which creates the most melodious of music. A lap harp. I would be ever so grateful if I could examine one in person. + // Humans artistry can be a remarkable thing. For instance, I have heard of a wonderful instrument which creates the most melodious of music. A lap harp. I would be ever so grateful if I could examine one in person. + Description = 1074071; RefusalMessage = 1073921; // I will patiently await your reconsideration. InProgressMessage = 1073927; // I will be in your debt if you bring me lap harp. CompletionMessage = 1073969; // My thanks for your service. Now, I will show you something of elven carpentry. @@ -1353,8 +1353,8 @@ namespace Server.Engines.MLQuests.Definitions Activated = true; HasRestartDelay = true; Title = 1073908; // The Far Eye - Description = - 1074098; // The wonders of human invention! Turning sand and metal into a far-seeing eye! This is something I must experience for myself. Bring me some of these spyglasses friend human. + // The wonders of human invention! Turning sand and metal into a far-seeing eye! This is something I must experience for myself. Bring me some of these spyglasses friend human. + Description = 1074098; RefusalMessage = 1073921; // I will patiently await your reconsideration. InProgressMessage = 1073954; // I will be in your debt if you bring me spyglasses. CompletionMessage = 1073978; // Enjoy my thanks for your service. @@ -1372,8 +1372,8 @@ namespace Server.Engines.MLQuests.Definitions Activated = true; HasRestartDelay = true; Title = 1073876; // Lethal Darts - Description = - 1074066; // We elves are no strangers to archery but I would be interested in learning whether there is anything to learn from the human approach. I would gladly trade you something I have if you could teach me of the deadly crossbow bolt. + // We elves are no strangers to archery but I would be interested in learning whether there is anything to learn from the human approach. I would gladly trade you something I have if you could teach me of the deadly crossbow bolt. + Description = 1074066; RefusalMessage = 1073921; // I will patiently await your reconsideration. InProgressMessage = 1073922; // I will be in your debt if you bring me crossbow bolts. CompletionMessage = 1073968; // My thanks for your service. Now, I shall teach you of elven archery. @@ -1392,8 +1392,8 @@ namespace Server.Engines.MLQuests.Definitions Activated = true; HasRestartDelay = true; Title = 1073877; // A Simple Bow - Description = - 1074067; // I wish to try a bow crafted in the human style. Is it possible for you to bring me such a weapon? I would be happy to return this favor. + // I wish to try a bow crafted in the human style. Is it possible for you to bring me such a weapon? I would be happy to return this favor. + Description = 1074067; RefusalMessage = 1073921; // I will patiently await your reconsideration. InProgressMessage = 1073923; // I will be in your debt if you bring me bows. CompletionMessage = 1073968; // My thanks for your service. Now, I shall teach you of elven archery. @@ -1412,8 +1412,8 @@ namespace Server.Engines.MLQuests.Definitions Activated = true; HasRestartDelay = true; Title = 1073878; // Ingenious Archery, Part I - Description = - 1074068; // I have heard of a curious type of bow, you call it a "crossbow". It sounds fascinating and I would very much like to examine one closely. Would you be able to obtain such an instrument for me? + // I have heard of a curious type of bow, you call it a "crossbow". It sounds fascinating and I would very much like to examine one closely. Would you be able to obtain such an instrument for me? + Description = 1074068; RefusalMessage = 1073921; // I will patiently await your reconsideration. InProgressMessage = 1073924; // I will be in your debt if you bring me crossbows. CompletionMessage = 1073968; // My thanks for your service. Now, I shall teach you of elven archery. @@ -1432,8 +1432,8 @@ namespace Server.Engines.MLQuests.Definitions Activated = true; HasRestartDelay = true; Title = 1073879; // Ingenious Archery, Part II - Description = - 1074069; // These human "crossbows" are complex and clever. The "heavy crossbow" is a remarkable instrument of war. I am interested in seeing one up close, if you could arrange for one to make its way to my hands. + // These human "crossbows" are complex and clever. The "heavy crossbow" is a remarkable instrument of war. I am interested in seeing one up close, if you could arrange for one to make its way to my hands. + Description = 1074069; RefusalMessage = 1073921; // I will patiently await your reconsideration. InProgressMessage = 1073925; // I will be in your debt if you bring me heavy crossbows. CompletionMessage = 1073968; // My thanks for your service. Now, I shall teach you of elven archery. @@ -1452,8 +1452,8 @@ namespace Server.Engines.MLQuests.Definitions Activated = true; HasRestartDelay = true; Title = 1073880; // Ingenious Archery, Part III - Description = - 1074070; // My friend, I am in search of a device, a instrument of remarkable human ingenuity. It is a repeating crossbow. If you were to obtain such a device, I would gladly reveal to you some of the secrets of elven craftsmanship. + // My friend, I am in search of a device, a instrument of remarkable human ingenuity. It is a repeating crossbow. If you were to obtain such a device, I would gladly reveal to you some of the secrets of elven craftsmanship. + Description = 1074070; RefusalMessage = 1073921; // I will patiently await your reconsideration. InProgressMessage = 1073926; // I will be in your debt if you bring me repeating crossbows. CompletionMessage = 1073968; // My thanks for your service. Now, I shall teach you of elven archery. @@ -1471,11 +1471,11 @@ namespace Server.Engines.MLQuests.Definitions { Activated = true; Title = 1074711; // Scale Armor - Description = - 1074712; // Here's what I need ... there are some creatures called hydra, fearsome beasts, whose scales are especially suitable for a new sort of armor that I'm developing. I need a few such pieces and then some supple alligator skin for the backing. I'm going to need a really large piece that's shaped just right ... the tail I think would do nicely. I appreciate your help. + // Here's what I need ... there are some creatures called hydra, fearsome beasts, whose scales are especially suitable for a new sort of armor that I'm developing. I need a few such pieces and then some supple alligator skin for the backing. I'm going to need a really large piece that's shaped just right ... the tail I think would do nicely. I appreciate your help. + Description = 1074712; RefusalMessage = 1073580; // I hope you'll reconsider. Until then, farwell. - InProgressMessage = - 1074724; // Hydras have been spotted in the Blighted Grove. You won't get those scales without getting your feet wet, I'm afraid. + // Hydras have been spotted in the Blighted Grove. You won't get those scales without getting your feet wet, I'm afraid. + InProgressMessage = 1074724; CompletionMessage = 1074725; // I can't wait to get to work now that you've returned with my scales. Objectives.Add(new CollectObjective(1, typeof(ThrashersTail), "Thrasher's Tail")); @@ -1492,8 +1492,8 @@ namespace Server.Engines.MLQuests.Definitions Activated = true; HasRestartDelay = true; Title = 1073913; // Cuts Both Ways - Description = - 1074103; // What would you say is a typical human instrument of war? Is a broadsword a typical example? I wish to see more of such human weapons, so I would gladly trade elven knowledge for human steel. + // What would you say is a typical human instrument of war? Is a broadsword a typical example? I wish to see more of such human weapons, so I would gladly trade elven knowledge for human steel. + Description = 1074103; RefusalMessage = 1073921; // I will patiently await your reconsideration. InProgressMessage = 1073959; // I will be in your debt if you bring me broadswords. CompletionMessage = 1073978; // Enjoy my thanks for your service. @@ -1511,8 +1511,8 @@ namespace Server.Engines.MLQuests.Definitions Activated = true; HasRestartDelay = true; Title = 1073915; // Dragon Protection - Description = - 1074105; // Mankind, I am told, knows how to take the scales of a terrible dragon and forge them into powerful armor. Such a feat of craftsmanship! I would give anything to view such a creation - I would even teach some of the prize secrets of the elven people. + // Mankind, I am told, knows how to take the scales of a terrible dragon and forge them into powerful armor. Such a feat of craftsmanship! I would give anything to view such a creation - I would even teach some of the prize secrets of the elven people. + Description = 1074105; RefusalMessage = 1073921; // I will patiently await your reconsideration. InProgressMessage = 1073961; // I will be in your debt if you bring me dragon armor. CompletionMessage = 1073978; // Enjoy my thanks for your service. @@ -1530,8 +1530,8 @@ namespace Server.Engines.MLQuests.Definitions Activated = true; HasRestartDelay = true; Title = 1073911; // Nothing Fancy - Description = - 1074101; // I am curious to see the results of human blacksmithing. To examine the care and quality of a simple item. Perhaps, a simple bascinet helmet? Yes, indeed -- if you could bring to me some bascinet helmets, I would demonstrate my gratitude. + // I am curious to see the results of human blacksmithing. To examine the care and quality of a simple item. Perhaps, a simple bascinet helmet? Yes, indeed -- if you could bring to me some bascinet helmets, I would demonstrate my gratitude. + Description = 1074101; RefusalMessage = 1073921; // I will patiently await your reconsideration. InProgressMessage = 1073957; // I will be in your debt if you bring me bascinets. CompletionMessage = 1073978; // Enjoy my thanks for your service. @@ -1549,8 +1549,8 @@ namespace Server.Engines.MLQuests.Definitions Activated = true; HasRestartDelay = true; Title = 1073912; // The Bulwark - Description = - 1074102; // The clank of human iron and steel is strange to elven ears. For instance, the metallic heater shield which human warriors carry into battle. It is odd to an elf, but nevertheless intriguing. Tell me friend, could you bring me such an example of human smithing skill? + // The clank of human iron and steel is strange to elven ears. For instance, the metallic heater shield which human warriors carry into battle. It is odd to an elf, but nevertheless intriguing. Tell me friend, could you bring me such an example of human smithing skill? + Description = 1074102; RefusalMessage = 1073921; // I will patiently await your reconsideration. InProgressMessage = 1073958; // I will be in your debt if you bring me heater shields. CompletionMessage = 1073978; // Enjoy my thanks for your service. @@ -1568,8 +1568,8 @@ namespace Server.Engines.MLQuests.Definitions Activated = true; HasRestartDelay = true; Title = 1073882; // Arch Support - Description = - 1074072; // How clever humans are - to understand the need of feet to rest from time to time! Imagine creating a special stool just for weary toes. I would like to examine and learn the secret of their making. Would you bring me some foot stools to examine? + // How clever humans are - to understand the need of feet to rest from time to time! Imagine creating a special stool just for weary toes. I would like to examine and learn the secret of their making. Would you bring me some foot stools to examine? + Description = 1074072; RefusalMessage = 1073921; // I will patiently await your reconsideration. InProgressMessage = 1073928; // I will be in your debt if you bring me foot stools. CompletionMessage = 1073969; // My thanks for your service. Now, I will show you something of elven carpentry. @@ -1597,10 +1597,7 @@ namespace Server.Engines.MLQuests.Definitions 3, new[] { typeof(Succubus) }, "succubi", - new QuestArea( - 1074806, // The Palace of Paroxysmus - "The Palace of Paroxysmus" - ) + new QuestArea(1074806, "The Palace of Paroxysmus") ) ); @@ -1627,7 +1624,7 @@ namespace Server.Engines.MLQuests.Definitions "molochs", new QuestArea(1074806, "The Palace of Paroxysmus") ) - ); // The Palace of Paroxysmus + ); Rewards.Add(ItemReward.LargeBagOfTreasure); } @@ -1652,7 +1649,7 @@ namespace Server.Engines.MLQuests.Definitions "daemons", new QuestArea(1074806, "The Palace of Paroxysmus") ) - ); // The Palace of Paroxysmus + ); Rewards.Add(ItemReward.LargeBagOfTreasure); } @@ -1677,7 +1674,7 @@ namespace Server.Engines.MLQuests.Definitions "arcane daemons", new QuestArea(1074806, "The Palace of Paroxysmus") ) - ); // The Palace of Paroxysmus + ); Rewards.Add(ItemReward.LargeBagOfTreasure); } @@ -1703,7 +1700,7 @@ namespace Server.Engines.MLQuests.Definitions "poison elementals", new QuestArea(1074806, "The Palace of Paroxysmus") ) - ); // The Palace of Paroxysmus + ); Objectives.Add( new KillObjective( 6, @@ -1781,7 +1778,7 @@ namespace Server.Engines.MLQuests.Definitions "crystal lattice seekers", new QuestArea(1074805, "The Prism of Light") ) - ); // The Prism of Light + ); Rewards.Add(ItemReward.LargeBagOfTreasure); } @@ -1809,7 +1806,7 @@ namespace Server.Engines.MLQuests.Definitions "crystal daemons", new QuestArea(1074805, "The Prism of Light") ) - ); // The Prism of Light + ); Rewards.Add(ItemReward.LargeBagOfTreasure); } @@ -1837,7 +1834,7 @@ namespace Server.Engines.MLQuests.Definitions "crystal vortices", new QuestArea(1074805, "The Prism of Light") ) - ); // The Prism of Light + ); Rewards.Add(ItemReward.LargeBagOfTreasure); } @@ -1945,11 +1942,11 @@ namespace Server.Engines.MLQuests.Definitions { Activated = true; Title = 1072913; // Death to the Ninja! - Description = - 1072966; // I wish to make a statement of censure against the elite ninjas of the Black Order. Deliver, in the strongest manner, my disdain. But do not make war on women, even those that take arms against you. It is not ... fitting. + // I wish to make a statement of censure against the elite ninjas of the Black Order. Deliver, in the strongest manner, my disdain. But do not make war on women, even those that take arms against you. It is not ... fitting. + Description = 1072966; RefusalMessage = 1072979; // As you wish. - InProgressMessage = - 1072980; // The Black Order's fortress home is well hidden. Legend has it that a humble fishing village disguises the magical portal. + // The Black Order's fortress home is well hidden. Legend has it that a humble fishing village disguises the magical portal. + InProgressMessage = 1072980; // TODO: Verify that this has to be males only (as per the description) Objectives.Add( @@ -1959,7 +1956,7 @@ namespace Server.Engines.MLQuests.Definitions "elite ninjas", new QuestArea(1074804, "The Citadel") ) - ); // The Citadel + ); Rewards.Add(ItemReward.BagOfTreasure); } @@ -2049,9 +2046,9 @@ namespace Server.Engines.MLQuests.Definitions pm, Utility.RandomList( 1074186, // Come here, I have a task. - 1074183 + 1074183 // You there! I have a job for you. ) - ); // You there! I have a job for you. + ); } public override void Serialize(IGenericWriter writer) @@ -2116,9 +2113,9 @@ namespace Server.Engines.MLQuests.Definitions pm, Utility.RandomList( 1074187, // Want a job? - 1074210 + 1074210 // Hi. Looking for something to do? ) - ); // Hi.� Looking for something to do? + ); } public override void Serialize(IGenericWriter writer) @@ -2180,10 +2177,10 @@ namespace Server.Engines.MLQuests.Definitions this, pm, Utility.RandomList( - 1074213, // Hey buddy.� Looking for work? - 1074187 + 1074213, // Hey buddy. Looking for work? + 1074187 // Want a job? ) - ); // Want a job? + ); } public override void Serialize(IGenericWriter writer) @@ -2247,9 +2244,9 @@ namespace Server.Engines.MLQuests.Definitions pm, Utility.RandomList( 1074211, // I could use some help. - 1074218 + 1074218 // Hey! I want to talk to you, now. ) - ); // Hey!� I want to talk to you, now. + ); } public override void Serialize(IGenericWriter writer) @@ -2314,7 +2311,7 @@ namespace Server.Engines.MLQuests.Definitions public override void Shout(PlayerMobile pm) { - MLQuestSystem.Tell(this, pm, 1074223); // Have you done it yet?� Oh, I haven�t told you, have I? + MLQuestSystem.Tell(this, pm, 1074223); // Have you done it yet? Oh, I haven't told you, have I? } public override void Serialize(IGenericWriter writer) @@ -2375,9 +2372,9 @@ namespace Server.Engines.MLQuests.Definitions pm, Utility.RandomList( 1074219, // Hello there, can I have a moment of your time? - 1074223 + 1074223 // Have you done it yet? Oh, I haven't told you, have I? ) - ); // Have you done it yet?� Oh, I haven�t told you, have I? + ); } public override void Serialize(IGenericWriter writer) @@ -2446,9 +2443,9 @@ namespace Server.Engines.MLQuests.Definitions pm, Utility.RandomList( 1074206, // Excuse me please traveler, might I have a little of your time? - 1074186 + 1074186 // Come here, I have a task. ) - ); // Come here, I have a task. + ); } public override void Serialize(IGenericWriter writer) @@ -2508,10 +2505,10 @@ namespace Server.Engines.MLQuests.Definitions this, pm, Utility.RandomList( - 1074220, // May I call you friend?� I have a favor to beg of you. - 1074222 + 1074220, // May I call you friend? I have a favor to beg of you. + 1074222 // Could I trouble you for some assistance? ) - ); // Could I trouble you for some assistance? + ); } public override void Serialize(IGenericWriter writer) @@ -2585,10 +2582,10 @@ namespace Server.Engines.MLQuests.Definitions pm, Utility.RandomList( 1074188, // Weakling! You are not up to the task I have. - 1074191, // Just keep walking away!� I thought so. Coward!� I�ll bite your legs off! - 1074195 + 1074191, // Just keep walking away! I thought so. Coward! I'll bite your legs off! + 1074195 // You there, in the stupid hat! Come here. ) - ); // You there, in the stupid hat! Come here. + ); } public override void Serialize(IGenericWriter writer) @@ -2645,9 +2642,9 @@ namespace Server.Engines.MLQuests.Definitions pm, Utility.RandomList( 1074212, // *yawn* You busy? - 1074210 + 1074210 // Hi. Looking for something to do? ) - ); // Hi.� Looking for something to do? + ); } public override void Serialize(IGenericWriter writer) @@ -2707,10 +2704,10 @@ namespace Server.Engines.MLQuests.Definitions this, pm, Utility.RandomList( - 1074204, // Greetings seeker.� I have an urgent matter for you, if you are willing. - 1074201 + 1074204, // Greetings seeker. I have an urgent matter for you, if you are willing. + 1074201 // Waste not a minute! There's work to be done. ) - ); // Waste not a minute! There�s work to be done. + ); } public override void Serialize(IGenericWriter writer) @@ -2770,9 +2767,9 @@ namespace Server.Engines.MLQuests.Definitions pm, Utility.RandomList( 1074211, // I could use some help. - 1074186 + 1074186 // Come here, I have a task. ) - ); // Come here, I have a task. + ); } public override void Serialize(IGenericWriter writer) @@ -2845,9 +2842,9 @@ namespace Server.Engines.MLQuests.Definitions pm, Utility.RandomList( 1074185, // Hey you! Want to help me out? - 1074186 + 1074186 // Come here, I have a task. ) - ); // Come here, I have a task. + ); } public override void Serialize(IGenericWriter writer) @@ -2927,10 +2924,10 @@ namespace Server.Engines.MLQuests.Definitions this, pm, Utility.RandomList( - 1074207, // Good day to you friend! Allow me to offer you a fabulous opportunity!� Thrills and adventure await! - 1074209 + 1074207, // Good day to you friend! Allow me to offer you a fabulous opportunity! Thrills and adventure await! + 1074209 // Hey, could you help me out with something? ) - ); // Hey, could you help me out with something? + ); } public override void Serialize(IGenericWriter writer) @@ -2994,10 +2991,10 @@ namespace Server.Engines.MLQuests.Definitions this, pm, Utility.RandomList( - 1074210, // Hi.� Looking for something to do? - 1074220 + 1074210, // Hi. Looking for something to do? + 1074220 // May I call you friend? I have a favor to beg of you. ) - ); // May I call you friend?� I have a favor to beg of you. + ); } public override void Serialize(IGenericWriter writer) @@ -3126,9 +3123,9 @@ namespace Server.Engines.MLQuests.Definitions pm, Utility.RandomList( 1074187, // Want a job? - 1074222 + 1074222 // Could I trouble you for some assistance? ) - ); // Could I trouble you for some assistance? + ); } public override void Serialize(IGenericWriter writer) @@ -3194,10 +3191,10 @@ namespace Server.Engines.MLQuests.Definitions this, pm, Utility.RandomList( - 1074221, // Greetings!� I have a small task for you good traveler. - 1074201 + 1074221, // Greetings! I have a small task for you good traveler. + 1074201 // Waste not a minute! There's work to be done. ) - ); // Waste not a minute! There�s work to be done. + ); } public override void Serialize(IGenericWriter writer) @@ -3257,10 +3254,10 @@ namespace Server.Engines.MLQuests.Definitions this, pm, Utility.RandomList( - 1074200, // Thank goodness you are here, there�s no time to lose. - 1074206 + 1074200, // Thank goodness you are here, there's no time to lose. + 1074206 // Excuse me please traveler, might I have a little of your time? ) - ); // Excuse me please traveler, might I have a little of your time? + ); } public override void Serialize(IGenericWriter writer) @@ -3440,10 +3437,10 @@ namespace Server.Engines.MLQuests.Definitions this, pm, Utility.RandomList( - 1074210, // Hi.� Looking for something to do? - 1074213 + 1074210, // Hi. Looking for something to do? + 1074213 // Hey buddy. Looking for work? ) - ); // Hey buddy.� Looking for work? + ); } public override void Serialize(IGenericWriter writer) @@ -3502,10 +3499,10 @@ namespace Server.Engines.MLQuests.Definitions this, pm, Utility.RandomList( - 1074223, // Have you done it yet?� Oh, I haven�t told you, have I? - 1074213 + 1074223, // Have you done it yet?' Oh, I haven't told you, have I? + 1074213 // Hey buddy. Looking for work? ) - ); // Hey buddy.� Looking for work? + ); } public override void Serialize(IGenericWriter writer) @@ -3698,10 +3695,10 @@ namespace Server.Engines.MLQuests.Definitions this, pm, Utility.RandomList( - 1074221, // Greetings!� I have a small task for you good traveler. - 1074212 + 1074221, // Greetings! I have a small task for you good traveler. + 1074212 // *yawn* You busy? ) - ); // *yawn* You busy? + ); } public override void Serialize(IGenericWriter writer) @@ -3762,9 +3759,9 @@ namespace Server.Engines.MLQuests.Definitions pm, Utility.RandomList( 1074206, // Excuse me please traveler, might I have a little of your time? - 1074203 + 1074203 // Hello friend. I realize you are busy but if you would be willing to render me a service I can assure you that you will be judiciously renumerated. ) - ); // Hello friend. I realize you are busy but if you would be willing to render me a service I can assure you that you will be judiciously renumerated. + ); } public override void Serialize(IGenericWriter writer) @@ -4612,10 +4609,10 @@ namespace Server.Engines.MLQuests.Definitions this, pm, Utility.RandomList( - 1074204, // Greetings seeker.� I have an urgent matter for you, if you are willing. - 1074200 + 1074204, // Greetings seeker. I have an urgent matter for you, if you are willing. + 1074200 // Thank goodness you are here, there's no time to lose. ) - ); // Thank goodness you are here, there�s no time to lose. + ); } public override void Serialize(IGenericWriter writer) @@ -4725,7 +4722,7 @@ namespace Server.Engines.MLQuests.Definitions public override void Shout(PlayerMobile pm) { - MLQuestSystem.Tell(this, pm, 1074197); // Pardon me, but if you could spare some time I�d greatly appreciate it. + MLQuestSystem.Tell(this, pm, 1074197); // Pardon me, but if you could spare some time I'd greatly appreciate it. } public override void Serialize(IGenericWriter writer) @@ -4780,7 +4777,7 @@ namespace Server.Engines.MLQuests.Definitions public override void Shout(PlayerMobile pm) { - MLQuestSystem.Tell(this, pm, 1074204); // Greetings seeker.� I have an urgent matter for you, if you are willing. + MLQuestSystem.Tell(this, pm, 1074204); // Greetings seeker. I have an urgent matter for you, if you are willing. } public override void Serialize(IGenericWriter writer) diff --git a/Projects/UOContent/Engines/ML Quests/Definitions/Heritage.cs b/Projects/UOContent/Engines/ML Quests/Definitions/Heritage.cs index 016d7be50..4284e0906 100644 --- a/Projects/UOContent/Engines/ML Quests/Definitions/Heritage.cs +++ b/Projects/UOContent/Engines/ML Quests/Definitions/Heritage.cs @@ -647,9 +647,9 @@ namespace Server.Engines.MLQuests.Definitions pm, Utility.RandomList( 1074188, // Weakling! You are not up to the task I have. - 1074195 + 1074195 // You there, in the stupid hat! Come here. ) - ); // You there, in the stupid hat! Come here. + ); } public override void Serialize(IGenericWriter writer) diff --git a/Projects/UOContent/Engines/ML Quests/Definitions/HonestBeggar.cs b/Projects/UOContent/Engines/ML Quests/Definitions/HonestBeggar.cs index 249f6d0f5..3173d8179 100644 --- a/Projects/UOContent/Engines/ML Quests/Definitions/HonestBeggar.cs +++ b/Projects/UOContent/Engines/ML Quests/Definitions/HonestBeggar.cs @@ -16,14 +16,14 @@ namespace Server.Engines.MLQuests.Definitions 1075393; // Beg pardon, sir. I mean, madam. Uh, can I ask a favor of you? I found this jeweled ring. Most people would sell it and keep the money, but not me. I ain't never stole nothing, and I ain't about to start. I tried to take it over to Brit castle, figgerin' it must belong to some highborn lady, but the guards threw me out. You look like they might let you pass. Will you take the ring over there and see if you can find the owner? RefusalMessage = 1075395; // I see. Too good to help an honest beggar like me, eh? InProgressMessage = - 1075396; // A jewel like this must be worth a lot, so it must belong to some noble or another. I would show it around the castle. Someone�s bound to recognize it. + 1075396; // A jewel like this must be worth a lot, so it must belong to some noble or another. I would show it around the castle. Someone's bound to recognize it. CompletionMessage = 1075397; // Didst thou find my ring? I thank thee very much! It is an old ring, and a gift from my husband. I was most distraught when I realized it was missing. CompletionNotice = CompletionNoticeShort; Objectives.Add(new DeliverObjective(typeof(ReginasRing), 1, "Regina's Ring", typeof(Regina))); - Rewards.Add(new DummyReward(1075394)); // Find the ring�s owner. + Rewards.Add(new DummyReward(1075394)); // Find the ring's owner. } public override Type NextQuest => typeof(ReginasThanks); @@ -35,9 +35,9 @@ namespace Server.Engines.MLQuests.Definitions { Activated = true; OneTimeOnly = true; - Title = 1075398; // Regina�s Thanks + Title = 1075398; // Regina's Thanks Description = - 1075399; // What�s that you say? It was a humble beggar that found my ring? Such honesty must be rewarded. Here, take this packet and return it to him, and I will be in your debt. + 1075399; // What's that you say? It was a humble beggar that found my ring? Such honesty must be rewarded. Here, take this packet and return it to him, and I will be in your debt. RefusalMessage = 1075401; // Hmph. Very well. What did you say his name was? InProgressMessage = 1075402; // Take the packet and return it to the beggar who found my ring. CompletionMessage = diff --git a/Projects/UOContent/Engines/ML Quests/Definitions/Ilshenar.cs b/Projects/UOContent/Engines/ML Quests/Definitions/Ilshenar.cs index 3740ed710..394010258 100644 --- a/Projects/UOContent/Engines/ML Quests/Definitions/Ilshenar.cs +++ b/Projects/UOContent/Engines/ML Quests/Definitions/Ilshenar.cs @@ -127,10 +127,10 @@ namespace Server.Engines.MLQuests.Definitions this, pm, Utility.RandomList( - 1074204, // Greetings seeker.  I have an urgent matter for you, if you are willing. - 1074222 + 1074204, // Greetings seeker. I have an urgent matter for you, if you are willing. + 1074222 // Could I trouble you for some assistance? ) - ); // Could I trouble you for some assistance? + ); } public override void InitBody() @@ -254,7 +254,7 @@ namespace Server.Engines.MLQuests.Definitions public override void Shout(PlayerMobile pm) { - MLQuestSystem.Tell(this, pm, 1074221); // Greetings!  I have a small task for you good traveler. + MLQuestSystem.Tell(this, pm, 1074221); // Greetings! I have a small task for you good traveler. } public override void Serialize(IGenericWriter writer) @@ -305,7 +305,7 @@ namespace Server.Engines.MLQuests.Definitions public override void Shout(PlayerMobile pm) { - MLQuestSystem.Tell(this, pm, 1074218); // Hey!  I want to talk to you, now. + MLQuestSystem.Tell(this, pm, 1074218); // Hey! I want to talk to you, now. } public override void Serialize(IGenericWriter writer) diff --git a/Projects/UOContent/Engines/ML Quests/Definitions/MistakenIdentity.cs b/Projects/UOContent/Engines/ML Quests/Definitions/MistakenIdentity.cs index 386948938..057188b8d 100644 --- a/Projects/UOContent/Engines/ML Quests/Definitions/MistakenIdentity.cs +++ b/Projects/UOContent/Engines/ML Quests/Definitions/MistakenIdentity.cs @@ -273,10 +273,10 @@ namespace Server.Engines.MLQuests.Definitions this, pm, Utility.RandomList( - 1074200, // Thank goodness you are here, there�s no time to lose. - 1074203 + 1074200, // Thank goodness you are here, there's no time to lose. + 1074203 // Hello friend. I realize you are busy but if you would be willing to render me a service I can assure you that you will be judiciously renumerated. ) - ); // Hello friend. I realize you are busy but if you would be willing to render me a service I can assure you that you will be judiciously renumerated. + ); } public override void Serialize(IGenericWriter writer) diff --git a/Projects/UOContent/Engines/ML Quests/Definitions/NewHavenSkillTraining.cs b/Projects/UOContent/Engines/ML Quests/Definitions/NewHavenSkillTraining.cs index 0e1bcdd58..d0d38411c 100644 --- a/Projects/UOContent/Engines/ML Quests/Definitions/NewHavenSkillTraining.cs +++ b/Projects/UOContent/Engines/ML Quests/Definitions/NewHavenSkillTraining.cs @@ -1995,9 +1995,9 @@ namespace Server.Engines.MLQuests.Definitions Utility.RandomList( 1078213, // I don't sleep. I wait. 1078212, // There is no theory of evolution. Just a list of creatures I allow to live. - 1078214 + 1078214 // I can lead a horse to water and make it drink. ) - ); // I can lead a horse to water and make it drink. + ); } public override void Serialize(IGenericWriter writer) diff --git a/Projects/UOContent/Engines/ML Quests/Definitions/NewHavenTraining.cs b/Projects/UOContent/Engines/ML Quests/Definitions/NewHavenTraining.cs index 42d2e9227..3eeccc7b0 100644 --- a/Projects/UOContent/Engines/ML Quests/Definitions/NewHavenTraining.cs +++ b/Projects/UOContent/Engines/ML Quests/Definitions/NewHavenTraining.cs @@ -114,7 +114,7 @@ namespace Server.Engines.MLQuests.Definitions 1075529; // Have a pickaxe? My supplier is late and I need some iron ore so I can complete a bulk order for another merchant. If you can get me some soon I'll pay you double what it's worth on the market. Just find a cave or mountainside and try to use your pickaxe there, maybe you'll strike a good vein! 5 large pieces should do it. RefusalMessage = 1075531; // Not feeling strong enough today? Its alright, I didn't need a bucket of rocks anyway. - InProgressMessage = 1075532; // Hmmm� we need some more Ore. Try finding a mountain or cave, and give it a whack. + InProgressMessage = 1075532; // Hmmm' we need some more Ore. Try finding a mountain or cave, and give it a whack. CompletionMessage = 1075533; // I see you found a good vien! Great! This will help get this order out on time. Good work! @@ -317,9 +317,9 @@ namespace Server.Engines.MLQuests.Definitions pm, Utility.RandomList( 1074205, // Oh great adventurer, would you please assist a weak soul in need of aid? - 1074213 + 1074213 // Hey buddy. Looking for work? ) - ); // Hey buddy.� Looking for work? + ); } public override void Serialize(IGenericWriter writer) @@ -438,9 +438,9 @@ namespace Server.Engines.MLQuests.Definitions pm, Utility.RandomList( 1074205, // Oh great adventurer, would you please assist a weak soul in need of aid? - 1074213 + 1074213 // Hey buddy. Looking for work? ) - ); // Hey buddy.� Looking for work? + ); } public override void Serialize(IGenericWriter writer) @@ -495,9 +495,9 @@ namespace Server.Engines.MLQuests.Definitions pm, Utility.RandomList( 1074205, // Oh great adventurer, would you please assist a weak soul in need of aid? - 1074213 + 1074213 // Hey buddy. Looking for work? ) - ); // Hey buddy.� Looking for work? + ); } public override void Serialize(IGenericWriter writer) @@ -562,10 +562,10 @@ namespace Server.Engines.MLQuests.Definitions pm, Utility.RandomList( 1074205, // Oh great adventurer, would you please assist a weak soul in need of aid? - 1074213, // Hey buddy.� Looking for work? - 1074211 + 1074213, // Hey buddy. Looking for work? + 1074211 // I could use some help. ) - ); // I could use some help. + ); } public override void Serialize(IGenericWriter writer) @@ -674,9 +674,9 @@ namespace Server.Engines.MLQuests.Definitions pm, Utility.RandomList( 1074205, // Oh great adventurer, would you please assist a weak soul in need of aid? - 1074213 + 1074213 // Hey buddy. Looking for work? ) - ); // Hey buddy.� Looking for work? + ); } public override void Serialize(IGenericWriter writer) @@ -730,9 +730,9 @@ namespace Server.Engines.MLQuests.Definitions pm, Utility.RandomList( 1074205, // Oh great adventurer, would you please assist a weak soul in need of aid? - 1074213 + 1074213 // Hey buddy. Looking for work? ) - ); // Hey buddy.� Looking for work? + ); } public override void Serialize(IGenericWriter writer) @@ -832,10 +832,10 @@ namespace Server.Engines.MLQuests.Definitions pm, Utility.RandomList( 1074205, // Oh great adventurer, would you please assist a weak soul in need of aid? - 1074213, // Hey buddy.� Looking for work? - 1074211 + 1074213, // Hey buddy. Looking for work? + 1074211 // I could use some help. ) - ); // I could use some help. + ); } public override void Serialize(IGenericWriter writer) @@ -892,10 +892,10 @@ namespace Server.Engines.MLQuests.Definitions pm, Utility.RandomList( 1074205, // Oh great adventurer, would you please assist a weak soul in need of aid? - 1074213, // Hey buddy.� Looking for work? - 1074211 + 1074213, // Hey buddy. Looking for work? + 1074211 // I could use some help. ) - ); // I could use some help. + ); } public override void Serialize(IGenericWriter writer) @@ -957,10 +957,10 @@ namespace Server.Engines.MLQuests.Definitions this, pm, Utility.RandomList( - 1074213, // Hey buddy.� Looking for work? - 1074211 + 1074213, // Hey buddy. Looking for work? + 1074211 // I could use some help. ) - ); // I could use some help. + ); } public override void Serialize(IGenericWriter writer) diff --git a/Projects/UOContent/Engines/ML Quests/Definitions/Sanctuary.cs b/Projects/UOContent/Engines/ML Quests/Definitions/Sanctuary.cs index 555574a9f..97a363595 100644 --- a/Projects/UOContent/Engines/ML Quests/Definitions/Sanctuary.cs +++ b/Projects/UOContent/Engines/ML Quests/Definitions/Sanctuary.cs @@ -389,7 +389,7 @@ namespace Server.Engines.MLQuests.Definitions Activated = true; Title = 1073085; // Arch Enemies Description = - 1073575; // Vermin! They get into everything! I told the boy to leave out some poisoned cheese -- and they shot him. What else can I do? Unless�these ratmen are skilled with a bow, but I'd lay a wager you're better, eh? Could you skin a few of the wretches for me? + 1073575; // Vermin! They get into everything! I told the boy to leave out some poisoned cheese -- and they shot him. What else can I do? Unless these ratmen are skilled with a bow, but I'd lay a wager you're better, eh? Could you skin a few of the wretches for me? RefusalMessage = 1073580; // I hope you'll reconsider. Until then, farwell. InProgressMessage = 1073595; // I don't see 10 tails from Ratman Archers on your belt -- and until I do, no reward for you. @@ -804,9 +804,9 @@ namespace Server.Engines.MLQuests.Definitions pm, Utility.RandomList( 1074187, // Want a job? - 1074184 + 1074184 // Come here, I have work for you. ) - ); // Come here, I have work for you. + ); } public override void Serialize(IGenericWriter writer) @@ -864,7 +864,7 @@ namespace Server.Engines.MLQuests.Definitions public override void Shout(PlayerMobile pm) { - MLQuestSystem.Tell(this, pm, 1074197); // Pardon me, but if you could spare some time I�d greatly appreciate it. + MLQuestSystem.Tell(this, pm, 1074197); // Pardon me, but if you could spare some time I'd greatly appreciate it. } public override void Serialize(IGenericWriter writer) @@ -923,9 +923,9 @@ namespace Server.Engines.MLQuests.Definitions pm, Utility.RandomList( 1074188, // Weakling! You are not up to the task I have. - 1074211 + 1074211 // I could use some help. ) - ); // I could use some help. + ); } public override void Serialize(IGenericWriter writer) @@ -993,11 +993,10 @@ namespace Server.Engines.MLQuests.Definitions MLQuestSystem.Tell( this, pm, - Utility.RandomList( - 1074214, // Knave! Come here right now! - 1074218 - ) - ); // Hey!� I want to talk to you, now. + // Knave! Come here right now! + // Hey! I want to talk to you, now. + 1074214 + Utility.Random(2) + ); } public override void Serialize(IGenericWriter writer) @@ -1119,10 +1118,10 @@ namespace Server.Engines.MLQuests.Definitions this, pm, Utility.RandomList( - 1074196, // Excuse me! I�m sorry to interrupt but I urgently need some assistance. - 1074197 + 1074196, // Excuse me! I'm sorry to interrupt but I urgently need some assistance. + 1074197 // Pardon me, but if you could spare some time I'd greatly appreciate it. ) - ); // Pardon me, but if you could spare some time I�d greatly appreciate it. + ); } public override void Serialize(IGenericWriter writer) @@ -1183,9 +1182,9 @@ namespace Server.Engines.MLQuests.Definitions pm, Utility.RandomList( 1074185, // Hey you! Want to help me out? - 1074195 + 1074195 // You there, in the stupid hat! Come here. ) - ); // You there, in the stupid hat! Come here. + ); } public override void Serialize(IGenericWriter writer) @@ -1245,9 +1244,9 @@ namespace Server.Engines.MLQuests.Definitions pm, Utility.RandomList( 1074193, // You there! Yes you. Stop looking about like a toadie and come here. - 1074186 + 1074186 // Come here, I have a task. ) - ); // Come here, I have a task. + ); } public override void Serialize(IGenericWriter writer) @@ -1350,10 +1349,10 @@ namespace Server.Engines.MLQuests.Definitions this, pm, Utility.RandomList( - 1074217, // I want to make you an offer you�d be a fool to �refuse. - 1074218 + 1074217, // I want to make you an offer you'd be a fool to 'refuse. + 1074218 // Hey! I want to talk to you, now. ) - ); // Hey!� I want to talk to you, now. + ); } public override void Serialize(IGenericWriter writer) diff --git a/Projects/UOContent/Engines/ML Quests/Definitions/Spellweaving.cs b/Projects/UOContent/Engines/ML Quests/Definitions/Spellweaving.cs index c583a9cd2..38104cf18 100644 --- a/Projects/UOContent/Engines/ML Quests/Definitions/Spellweaving.cs +++ b/Projects/UOContent/Engines/ML Quests/Definitions/Spellweaving.cs @@ -347,11 +347,8 @@ namespace Server.Engines.MLQuests.Definitions Objectives.Add(new CollectObjective(1, typeof(Beads), 1024235)); // beads Objectives.Add(new CollectObjective(1, typeof(JarHoney), 1022540)); // jar of honey - Rewards.Add( - new DummyReward( - 1074874 - ) - ); // The opportunity to prove yourself worthy of learning to Summon Fey. (Sufficient spellweaving skill is required to cast the spell) + // The opportunity to prove yourself worthy of learning to Summon Fey. (Sufficient spellweaving skill is required to cast the spell) + Rewards.Add(new DummyReward(1074874)); } public override Type NextQuest => typeof(TokenOfFriendship); @@ -372,11 +369,8 @@ namespace Server.Engines.MLQuests.Definitions Objectives.Add(new DeliverObjective(typeof(GiftForArielle), 1, "gift for Arielle", typeof(Arielle))); - Rewards.Add( - new DummyReward( - 1074874 - ) - ); // The opportunity to prove yourself worthy of learning to Summon Fey. (Sufficient spellweaving skill is required to cast the spell) + // The opportunity to prove yourself worthy of learning to Summon Fey. (Sufficient spellweaving skill is required to cast the spell) + Rewards.Add(new DummyReward(1074874)); } public override Type NextQuest => typeof(Alliance); @@ -455,11 +449,8 @@ namespace Server.Engines.MLQuests.Definitions Objectives.Add(new CollectObjective(1, typeof(StoutWhip), "Stout Whip")); - Rewards.Add( - new DummyReward( - 1074873 - ) - ); // The opportunity to prove yourself worthy of learning to Summon Fiends. (Sufficient spellweaving skill is required to cast the spell) + // The opportunity to prove yourself worthy of learning to Summon Fiends. (Sufficient spellweaving skill is required to cast the spell) + Rewards.Add(new DummyReward(1074873)); } public override Type NextQuest => typeof(CrackingTheWhipII); @@ -607,9 +598,9 @@ namespace Server.Engines.MLQuests.Definitions pm, Utility.RandomList( 1074186, // Come here, I have a task. - 1074218 + 1074218 // Hey! I want to talk to you, now. ) - ); // Hey! I want to talk to you, now. + ); } public override void Serialize(IGenericWriter writer) @@ -728,9 +719,9 @@ namespace Server.Engines.MLQuests.Definitions pm, Utility.RandomList( 1074215, // Don’t test my patience you sniveling worm! - 1074218 + 1074218 // Hey! I want to talk to you, now. ) - ); // Hey!  I want to talk to you, now. + ); } public override void Serialize(IGenericWriter writer) diff --git a/Projects/UOContent/Engines/ML Quests/Definitions/TheAncientWorld.cs b/Projects/UOContent/Engines/ML Quests/Definitions/TheAncientWorld.cs index f7752d8b7..61a66f811 100644 --- a/Projects/UOContent/Engines/ML Quests/Definitions/TheAncientWorld.cs +++ b/Projects/UOContent/Engines/ML Quests/Definitions/TheAncientWorld.cs @@ -130,7 +130,7 @@ namespace Server.Engines.MLQuests.Definitions public override void Shout(PlayerMobile pm) { - MLQuestSystem.Tell(this, pm, 1074200); // Thank goodness you are here, there�s no time to lose. + MLQuestSystem.Tell(this, pm, 1074200); // Thank goodness you are here, there's no time to lose. } public override void Serialize(IGenericWriter writer) diff --git a/Projects/UOContent/Engines/ML Quests/Definitions/UnfadingMemories.cs b/Projects/UOContent/Engines/ML Quests/Definitions/UnfadingMemories.cs index b7a9b6b12..cfa189062 100644 --- a/Projects/UOContent/Engines/ML Quests/Definitions/UnfadingMemories.cs +++ b/Projects/UOContent/Engines/ML Quests/Definitions/UnfadingMemories.cs @@ -12,22 +12,19 @@ namespace Server.Engines.MLQuests.Definitions { Activated = true; Title = 1075355; // Unfading Memories - Description = - 1075356; // Aargh! It�s just not right! It doesn�t capture the unique color of her hair at all! If only I had some Prismatic Amber. That would be perfect. They used to mine it in Malas, but alas, those veins ran dry some time ago. I hear it may have been found in the Prism of Light. Oh, if only there were a bold adventurer within earshot who would go to the Prism of Light and retrieve some for me! + // Aargh! It's just not right! It doesn't capture the unique color of her hair at all! If only I had some Prismatic Amber. That would be perfect. They used to mine it in Malas, but alas, those veins ran dry some time ago. I hear it may have been found in the Prism of Light. Oh, if only there were a bold adventurer within earshot who would go to the Prism of Light and retrieve some for me! + Description = 1075356; RefusalMessage = 1075358; // Is there no one who can help a humble artist pursue his Muse? - InProgressMessage = - 1075359; // You can find Prismatic Amber in the Prism of Light, located just north of the city of Nujel'm. - CompletionMessage = - 1075360; // I knew it! See, it�s just the color I needed! Look how it brings out the highlights of her wheaten tresses! + // You can find Prismatic Amber in the Prism of Light, located just north of the city of Nujel'm. + InProgressMessage = 1075359; + // I knew it! See, it's just the color I needed! Look how it brings out the highlights of her wheaten tresses! + CompletionMessage = 1075360; CompletionNotice = CompletionNoticeShort; Objectives.Add(new CollectObjective(1, typeof(PrismaticAmber), "Prismatic Amber")); - Rewards.Add( - new DummyReward( - 1075357 - ) - ); // The joy of contributing to a noble artistic effort, however paltry the end product. + // The joy of contributing to a noble artistic effort, however paltry the end product. + Rewards.Add(new DummyReward(1075357)); } public override Type NextQuest => typeof(UnfadingMemoriesPartTwo); @@ -39,19 +36,19 @@ namespace Server.Engines.MLQuests.Definitions { Activated = true; Title = 1075367; // Unfading Memories - Description = - 1075368; // Finished! With the pigment I was able to create from the Prismatic Amber you brought me, I was able to complete my humble work. I should explain. Once, I loved a noble lady of gentleness and refinement, who possessed such beauty that I have found myself unable to love another to this day. But it was from afar that I admired her, for it is not for one so lowly as I to pay court to the likes of her. You have heard of the fair Thalia, Lady of Nujel'm? No? Well, she was my Muse, my inspiration, and when I heard she was to be married, I lost whatever pitiful talent I possessed. I felt I must compose a portrait of her, my masterpiece, or I would never be able to paint again. You, my friend, have helped me complete my work. Now I ask another favor of you. Will you take it to her as a wedding gift? She will probably reject it, but I must make the offer. - RefusalMessage = - 1075370; // Alright then, you have already helped me more than I deserved. I shall find someone else to undertake this task. - InProgressMessage = - 1075371; // The wedding is taking place in the palace in Nujel'm. You will likely find her there. - CompletionMessage = - 1075372; // I�m sorry, I�m getting ready to be married. I don�t have time to . . . what�s that you say? + // Finished! With the pigment I was able to create from the Prismatic Amber you brought me, I was able to complete my humble work. I should explain. Once, I loved a noble lady of gentleness and refinement, who possessed such beauty that I have found myself unable to love another to this day. But it was from afar that I admired her, for it is not for one so lowly as I to pay court to the likes of her. You have heard of the fair Thalia, Lady of Nujel'm? No? Well, she was my Muse, my inspiration, and when I heard she was to be married, I lost whatever pitiful talent I possessed. I felt I must compose a portrait of her, my masterpiece, or I would never be able to paint again. You, my friend, have helped me complete my work. Now I ask another favor of you. Will you take it to her as a wedding gift? She will probably reject it, but I must make the offer. + Description = 1075368; + // Alright then, you have already helped me more than I deserved. I shall find someone else to undertake this task. + RefusalMessage = 1075370; + // The wedding is taking place in the palace in Nujel'm. You will likely find her there. + InProgressMessage = 1075371; + // I'm sorry, I'm getting ready to be married. I don't have time to . . . what's that you say? + CompletionMessage = 1075372; CompletionNotice = CompletionNoticeShort; Objectives.Add(new DeliverObjective(typeof(PortraitOfTheBride), 1, "Portrait of the Bride", typeof(Thalia))); - Rewards.Add(new DummyReward(1075369)); // The Artist�s gratitude. + Rewards.Add(new DummyReward(1075369)); // The Artist's gratitude. } public override Type NextQuest => typeof(UnfadingMemoriesPartThree); @@ -65,13 +62,13 @@ namespace Server.Engines.MLQuests.Definitions Activated = true; OneTimeOnly = true; Title = 1075373; // Unfading Memories - Description = - 1075374; // Emilio painted this? It is absolutely wonderful! I used to love looking at his paintings, but I don�t remember him creating anything like this before. Would you be so kind as to carry a letter to him? Fate may have it that I am to marry another, yet I am compelled to reveal to him that his love was not entirely unrequited. + // Emilio painted this? It is absolutely wonderful! I used to love looking at his paintings, but I don't remember him creating anything like this before. Would you be so kind as to carry a letter to him? Fate may have it that I am to marry another, yet I am compelled to reveal to him that his love was not entirely unrequited. + Description = 1075374; RefusalMessage = 1075376; // Very well, then. If you will excuse me, I need to get ready. - InProgressMessage = - 1075377; // Take the letter back to the Artist�s Guild in Britain, if you would do me this kindness. - CompletionMessage = - 1075378; // She said what? She thinks what of me? I . . . I can�t believe it! All this time, I never knew how she truly felt. Thank you, my friend. I believe now I will be able to paint once again. Here, take this bleach. I was going to use it to destroy all of my works. Perhaps you can find a better use for it now. + // Take the letter back to the Artist's Guild in Britain, if you would do me this kindness. + InProgressMessage = 1075377; + // She said what? She thinks what of me? I . . . I can't believe it! All this time, I never knew how she truly felt. Thank you, my friend. I believe now I will be able to paint once again. Here, take this bleach. I was going to use it to destroy all of my works. Perhaps you can find a better use for it now. + CompletionMessage = 1075378; CompletionNotice = CompletionNoticeShort; Objectives.Add(new DeliverObjective(typeof(BridesLetter), 1, "Bride's Letter", typeof(Emilio))); diff --git a/Projects/UOContent/Engines/Quests/Dark Tides/Items/ScrollOfAbraxus.cs b/Projects/UOContent/Engines/Quests/Dark Tides/Items/ScrollOfAbraxus.cs index c86e0915f..e372f9c17 100644 --- a/Projects/UOContent/Engines/Quests/Dark Tides/Items/ScrollOfAbraxus.cs +++ b/Projects/UOContent/Engines/Quests/Dark Tides/Items/ScrollOfAbraxus.cs @@ -119,7 +119,7 @@ namespace Server.Engines.Quests.Necro * * Do not speak this password anywhere except when seeking passage * into the Crystal Cave, as our adversaries are lurking in the - * shadows � they are everywhere.

Go with the light, friend.

+ * shadows ' they are everywhere.

Go with the light, friend.

* * - Frater Melkeer */ diff --git a/Projects/UOContent/Engines/Quests/Emino's Undertaking/Mobiles/HiddenFigure.cs b/Projects/UOContent/Engines/Quests/Emino's Undertaking/Mobiles/HiddenFigure.cs index 06b511eb3..ae582b41d 100644 --- a/Projects/UOContent/Engines/Quests/Emino's Undertaking/Mobiles/HiddenFigure.cs +++ b/Projects/UOContent/Engines/Quests/Emino's Undertaking/Mobiles/HiddenFigure.cs @@ -8,7 +8,7 @@ namespace Server.Engines.Quests.Ninja { public static int[] Messages = { - 1063191, // They won�t find me here. + 1063191, // They won't find me here. 1063192 // Ah, a quiet hideout. }; diff --git a/Projects/UOContent/Engines/Quests/Haochi's Trials/Conversations.cs b/Projects/UOContent/Engines/Quests/Haochi's Trials/Conversations.cs index 861b3620e..1ff8e26b0 100644 --- a/Projects/UOContent/Engines/Quests/Haochi's Trials/Conversations.cs +++ b/Projects/UOContent/Engines/Quests/Haochi's Trials/Conversations.cs @@ -242,24 +242,23 @@ namespace Server.Engines.Quests.Samurai { if (m_KilledCat) { + /* + * Respect comes from allowing another to make their own decisions. + * By denying the gypsy her animals, you negate the respect she is due. + * Perhaps you will have learned something to use next time a similar situation arises. + *

And now you must prove yourself again. Please retrieve my katana from the treasure room and return it to me. + */ return 1063071; } - /* You showed respect by helping another out while allowing the gypsy - * what little dignity she has left.

- * - * Now she will be able to feed herself and gain enough energy to walk - * to her camp.

- * - * The cats are her family members� cursed by an evil mage.

- * - * Once she has enough strength to walk back to the camp, she will be - * able to undo the spell.

- * - * You have been rewarded for completing your trial. And now you must - * prove yourself again.

Please retrieve my katana from the - * treasure room and return it to me. - */ + /* + * You showed respect by helping another out while allowing the gypsy what little dignity she has left. + *

Now she will be able to feed herself and gain enough energy to walk to her camp. + *

The cats are her family members– cursed by an evil mage. + *

Once she has enough strength to walk back to the camp, she will be able to undo the spell. + *

You have been rewarded for completing your trial. And now you must prove yourself again. + *

Please retrieve my katana from the treasure room and return it to me. + */ return 1063070; } } @@ -317,17 +316,23 @@ namespace Server.Engines.Quests.Samurai { if (m_StolenTreasure) { + /* + * I thank you for returning this sword. + * However, you should admonished for also taking treasure that was not asked for nor given back. + *

Think about your actions youngling. + *

Your training is nearly complete. + * Before you have your final trial, you should pay homage to Samurai who came before you. + *

Go into the Altar Room and light a candle for them. Afterwards, return to me. + */ return 1063077; } - /* Thank you for returning this sword to me and leaving the remaining - * treasure alone.

- * - * Your training is nearly complete. Before you have your final trial, - * you should pay homage to Samurai who came before you.

- * - * Go into the Altar Room and light a candle for them. Afterwards, return to me. - */ + /* + * Thank you for returning this sword to me and leaving the remaining treasure alone. + *

Your training is nearly complete. + * Before you have your final trial, you should pay homage to Samurai who came before you. + *

Go into the Altar Room and light a candle for them. Afterwards, return to me. + */ return 1063076; } } diff --git a/Projects/UOContent/Gumps/RunebookGump.cs b/Projects/UOContent/Gumps/RunebookGump.cs index b7bb8d81c..8e95372d8 100644 --- a/Projects/UOContent/Gumps/RunebookGump.cs +++ b/Projects/UOContent/Gumps/RunebookGump.cs @@ -182,8 +182,8 @@ namespace Server.Gumps if (Sextant.Format(e.Location, e.Map, ref xLong, ref yLat, ref xMins, ref yMins, ref xEast, ref ySouth)) { - AddLabel(135 + half * 160, 80, 0, $"{yLat}� {yMins}'{(ySouth ? "S" : "N")}"); - AddLabel(135 + half * 160, 95, 0, $"{xLong}� {xMins}'{(xEast ? "E" : "W")}"); + AddLabel(135 + half * 160, 80, 0, $"{yLat}° {yMins}'{(ySouth ? "S" : "N")}"); + AddLabel(135 + half * 160, 95, 0, $"{xLong}° {xMins}'{(xEast ? "E" : "W")}"); } // Drop rune button @@ -294,7 +294,7 @@ namespace Server.Gumps )) { var location = - $"{yLat}� {yMins}'{(ySouth ? "S" : "N")}, {xLong}� {xMins}'{(xEast ? "E" : "W")}"; + $"{yLat}° {yMins}'{(ySouth ? "S" : "N")}, {xLong}' {xMins}'{(xEast ? "E" : "W")}"; from.SendMessage(location); } @@ -365,7 +365,7 @@ namespace Server.Gumps )) { var location = - $"{yLat}� {yMins}'{(ySouth ? "S" : "N")}, {xLong}� {xMins}'{(xEast ? "E" : "W")}"; + $"{yLat}° {yMins}'{(ySouth ? "S" : "N")}, {xLong}' {xMins}'{(xEast ? "E" : "W")}"; from.SendMessage(location); } @@ -401,7 +401,7 @@ namespace Server.Gumps )) { var location = - $"{yLat}� {yMins}'{(ySouth ? "S" : "N")}, {xLong}� {xMins}'{(xEast ? "E" : "W")}"; + $"{yLat}° {yMins}'{(ySouth ? "S" : "N")}, {xLong}' {xMins}'{(xEast ? "E" : "W")}"; from.SendMessage(location); } @@ -439,7 +439,7 @@ namespace Server.Gumps )) { var location = - $"{yLat}� {yMins}'{(ySouth ? "S" : "N")}, {xLong}� {xMins}'{(xEast ? "E" : "W")}"; + $"{yLat}° {yMins}'{(ySouth ? "S" : "N")}, {xLong}' {xMins}'{(xEast ? "E" : "W")}"; from.SendMessage(location); } diff --git a/Projects/UOContent/Items/Shields/Artifacts/Aegis.cs b/Projects/UOContent/Items/Shields/Artifacts/Aegis.cs index 9696cb3b4..52ecdc322 100644 --- a/Projects/UOContent/Items/Shields/Artifacts/Aegis.cs +++ b/Projects/UOContent/Items/Shields/Artifacts/Aegis.cs @@ -16,7 +16,7 @@ namespace Server.Items { } - public override int LabelNumber => 1061602; // �gis + public override int LabelNumber => 1061602; // Ægis public override int ArtifactRarity => 11; public override int BasePhysicalResistance => 15; diff --git a/Projects/UOContent/Items/Shields/BaseShield.cs b/Projects/UOContent/Items/Shields/BaseShield.cs index 93f4bcd35..1b2ca14cd 100644 --- a/Projects/UOContent/Items/Shields/BaseShield.cs +++ b/Projects/UOContent/Items/Shields/BaseShield.cs @@ -78,16 +78,7 @@ namespace Server.Items absorbed = 2; } - int wear; - - if (weapon.Type == WeaponType.Bashing) - { - wear = absorbed / 2; - } - else - { - wear = Utility.Random(2); - } + var wear = weapon.Type == WeaponType.Bashing ? absorbed / 2 : Utility.Random(2); if (wear > 0 && MaxHitPoints > 0) { @@ -110,11 +101,8 @@ namespace Server.Items if (Parent is Mobile mobile) { - mobile.LocalOverheadMessage( - MessageType.Regular, - 0x3B2, - 1061121 - ); // Your equipment is severely damaged. + // Your equipment is severely damaged. + mobile.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1061121); } } else @@ -128,7 +116,7 @@ namespace Server.Items return 0; } - if (!(Parent is Mobile owner)) + if (Parent is not Mobile owner) { return damage; } @@ -141,13 +129,6 @@ namespace Server.Items chance = 0.01; } - /* - FORMULA: Displayed AR = ((Parrying Skill * Base AR of Shield) � 200) + 1 - - FORMULA: % Chance of Blocking = parry skill - (shieldAR * 2) - - FORMULA: Melee Damage Absorbed = (AR of Shield) / 2 | Archery Damage Absorbed = AR of Shield - */ if (owner.CheckSkill(SkillName.Parry, chance)) { damage -= Math.Min(damage, weapon.Skill == SkillName.Archery ? (int)ar : (int)(ar / 2.0)); @@ -177,11 +158,8 @@ namespace Server.Items { MaxHitPoints -= wear; - ((Mobile)Parent).LocalOverheadMessage( - MessageType.Regular, - 0x3B2, - 1061121 - ); // Your equipment is severely damaged. + // Your equipment is severely damaged. + ((Mobile)Parent).LocalOverheadMessage(MessageType.Regular, 0x3B2, 1061121); } else { diff --git a/Projects/UOContent/Items/Skill Items/Fishing/Misc/SOS.cs b/Projects/UOContent/Items/Skill Items/Fishing/Misc/SOS.cs index 416550283..26a0f6b7a 100644 --- a/Projects/UOContent/Items/Skill Items/Fishing/Misc/SOS.cs +++ b/Projects/UOContent/Items/Skill Items/Fishing/Misc/SOS.cs @@ -281,7 +281,7 @@ namespace Server.Items if (Sextant.Format(loc, map, ref xLong, ref yLat, ref xMins, ref yMins, ref xEast, ref ySouth)) { - fmt = $"{yLat}°{yMins}'{(ySouth ? "S" : "N")},{xLong}°{xMins}'{(xEast ? "E" : "W")}"; + fmt = $"{yLat}° {yMins}'{(ySouth ? "S" : "N")}, {xLong}°{xMins}'{(xEast ? "E" : "W")}"; } else { diff --git a/Projects/UOContent/Items/Skill Items/Fishing/Misc/Sextant.cs b/Projects/UOContent/Items/Skill Items/Fishing/Misc/Sextant.cs index 4302ea80c..a36fd7644 100644 --- a/Projects/UOContent/Items/Skill Items/Fishing/Misc/Sextant.cs +++ b/Projects/UOContent/Items/Skill Items/Fishing/Misc/Sextant.cs @@ -33,7 +33,7 @@ namespace Server.Items if (Format(from.Location, from.Map, ref xLong, ref yLat, ref xMins, ref yMins, ref xEast, ref ySouth)) { - var location = $"{yLat}� {yMins}'{(ySouth ? "S" : "N")}, {xLong}� {xMins}'{(xEast ? "E" : "W")}"; + var location = $"{yLat}° {yMins}'{(ySouth ? "S" : "N")}, {xLong}' {xMins}'{(xEast ? "E" : "W")}"; from.LocalOverheadMessage(MessageType.Regular, from.SpeechHue, false, location); } } diff --git a/Projects/UOContent/Items/Special/8th Anniversary Items/Dawn's Music Box/DawnsMusicBox.cs b/Projects/UOContent/Items/Special/8th Anniversary Items/Dawn's Music Box/DawnsMusicBox.cs index 794d5f582..3e89229a0 100644 --- a/Projects/UOContent/Items/Special/8th Anniversary Items/Dawn's Music Box/DawnsMusicBox.cs +++ b/Projects/UOContent/Items/Special/8th Anniversary Items/Dawn's Music Box/DawnsMusicBox.cs @@ -123,7 +123,7 @@ namespace Server.Items { } - public override int LabelNumber => 1075198; // Dawn�s Music Box + public override int LabelNumber => 1075198; // Dawn's Music Box public List Tracks { get; private set; } diff --git a/Projects/UOContent/Items/Special/8th Anniversary Items/DupresShield.cs b/Projects/UOContent/Items/Special/8th Anniversary Items/DupresShield.cs index 8cc2ebff7..1471b0bb8 100644 --- a/Projects/UOContent/Items/Special/8th Anniversary Items/DupresShield.cs +++ b/Projects/UOContent/Items/Special/8th Anniversary Items/DupresShield.cs @@ -18,7 +18,7 @@ namespace Server.Items { } - public override int LabelNumber => 1075196; // Dupre�s Shield + public override int LabelNumber => 1075196; // Dupre's Shield public override int BasePhysicalResistance => 1; public override int BaseFireResistance => 0; diff --git a/Projects/UOContent/Items/Special/Gifts/ShaminoCrossbow.cs b/Projects/UOContent/Items/Special/Gifts/ShaminoCrossbow.cs index 3589cad06..e6bf55857 100644 --- a/Projects/UOContent/Items/Special/Gifts/ShaminoCrossbow.cs +++ b/Projects/UOContent/Items/Special/Gifts/ShaminoCrossbow.cs @@ -18,7 +18,7 @@ namespace Server.Items { } - public override int LabelNumber => 1062915; // Shamino�s Best Crossbow + public override int LabelNumber => 1062915; // Shamino's Best Crossbow public override int InitMinHits => 255; public override int InitMaxHits => 255; diff --git a/Projects/UOContent/Items/Special/Holiday/HolidayFoods.cs b/Projects/UOContent/Items/Special/Holiday/HolidayFoods.cs index 499240523..47d7fa94e 100644 --- a/Projects/UOContent/Items/Special/Holiday/HolidayFoods.cs +++ b/Projects/UOContent/Items/Special/Holiday/HolidayFoods.cs @@ -118,9 +118,9 @@ namespace Server.Items 1077396, // Noooo! 1077397, // Please don't eat me... *whimper* 1077405, // Not the face! - 1077406, // Ahhhhhh! My foot�s gone! + 1077406, // Ahhhhhh! My foot's gone! 1077407, // Please. No! I have gingerkids! - 1077408, // No, no! I�m really made of poison. Really. + 1077408, // No, no! I'm really made of poison. Really. 1077409 // Run, run as fast as you can! You can't catch me! I'm the gingerbread man! }; diff --git a/Projects/UOContent/Items/Wands/BaseWand.cs b/Projects/UOContent/Items/Wands/BaseWand.cs index 8bab32252..448985af1 100644 --- a/Projects/UOContent/Items/Wands/BaseWand.cs +++ b/Projects/UOContent/Items/Wands/BaseWand.cs @@ -34,14 +34,7 @@ namespace Server.Items [SerializableField(1)] private int _charges; - public BaseWand(WandEffect effect, int minCharges, int maxCharges) : base( - Utility.RandomList( - 0xDF2, - 0xDF3, - 0xDF4, - 0xDF5 - ) - ) + public BaseWand(WandEffect effect, int minCharges, int maxCharges) : base(0xDF2 + Utility.Random(4)) { Weight = 1.0; _wandEffect = effect; diff --git a/Projects/UOContent/Items/Weapons/Abilities/InfectiousStrike.cs b/Projects/UOContent/Items/Weapons/Abilities/InfectiousStrike.cs index 05b0e9969..9939e2a14 100644 --- a/Projects/UOContent/Items/Weapons/Abilities/InfectiousStrike.cs +++ b/Projects/UOContent/Items/Weapons/Abilities/InfectiousStrike.cs @@ -4,7 +4,7 @@ namespace Server.Items { /// /// This special move represents a significant change to the use of poisons in Age of Shadows. - /// Now, only certain weapon types � those that have Infectious Strike as an available special move � will be able to be + /// Now, only certain weapon types, those that have Infectious Strike as an available special move will be able to be /// poisoned. /// Targets will no longer be poisoned at random when hit by poisoned weapons. /// Instead, the wielder must use this ability to deliver the venom. diff --git a/Projects/UOContent/Items/Weapons/Abilities/ShadowStrike.cs b/Projects/UOContent/Items/Weapons/Abilities/ShadowStrike.cs index 29d6e5eaa..18b174893 100644 --- a/Projects/UOContent/Items/Weapons/Abilities/ShadowStrike.cs +++ b/Projects/UOContent/Items/Weapons/Abilities/ShadowStrike.cs @@ -2,7 +2,7 @@ namespace Server.Items { /// /// This powerful ability requires secondary skills to activate. - /// Successful use of Shadowstrike deals extra damage to the target � and renders the attacker invisible! + /// Successful use of Shadowstrike deals extra damage to the target and renders the attacker invisible! /// Only those who are adept at the art of stealth will be able to use this ability. /// public class ShadowStrike : WeaponAbility diff --git a/Projects/UOContent/Spells/Base/Spell.cs b/Projects/UOContent/Spells/Base/Spell.cs index 73afcba5b..120d85be1 100644 --- a/Projects/UOContent/Spells/Base/Spell.cs +++ b/Projects/UOContent/Spells/Base/Spell.cs @@ -206,7 +206,7 @@ namespace Server.Spells damageBonus += intBonus; var sdiBonus = AosAttributes.GetValue(Caster, AosAttribute.SpellDamage); - // PvP spell damage increase cap of 15% from an item�s magic property + // PvP spell damage increase cap of 15% from an item's magic property if (playerVsPlayer && sdiBonus > 15) { sdiBonus = 15; diff --git a/Projects/UOContent/Spells/Fifth/MagicReflect.cs b/Projects/UOContent/Spells/Fifth/MagicReflect.cs index d83582374..ca1e0256e 100644 --- a/Projects/UOContent/Spells/Fifth/MagicReflect.cs +++ b/Projects/UOContent/Spells/Fifth/MagicReflect.cs @@ -52,7 +52,8 @@ namespace Server.Spells.Fifth * Physical decrease = 25 - (Inscription/20). * Elemental resistance = +10 (-20 physical, +10 elemental at GM Inscription) * The magic reflection spell has an indefinite duration, becoming active when cast, and deactivated when re-cast. - * Reactive Armor, Protection, and Magic Reflection will stay on�even after logging out, even after dying�until you �turn them off� by casting them again. + * Reactive Armor, Protection, and Magic Reflection will stay on even after logging out, + * even after dying, until you turn them off by casting them again. */ if (CheckSequence()) diff --git a/Projects/UOContent/Spells/First/ReactiveArmor.cs b/Projects/UOContent/Spells/First/ReactiveArmor.cs index 8659c1253..168ba4b81 100644 --- a/Projects/UOContent/Spells/First/ReactiveArmor.cs +++ b/Projects/UOContent/Spells/First/ReactiveArmor.cs @@ -53,7 +53,8 @@ namespace Server.Spells.First * 15 + (Inscription/20) Physcial bonus * -5 Elemental * The reactive armor spell has an indefinite duration, becoming active when cast, and deactivated when re-cast. - * Reactive Armor, Protection, and Magic Reflection will stay on�even after logging out, even after dying�until you �turn them off� by casting them again. + * Reactive Armor, Protection, and Magic Reflection will stay on even after logging out, + * even after dying, until you turn them off by casting them again. * (+20 physical -5 elemental at 100 Inscription) */ diff --git a/Projects/UOContent/Spells/Necromancy/Wither.cs b/Projects/UOContent/Spells/Necromancy/Wither.cs index 64329bf17..9ecf7fdfe 100644 --- a/Projects/UOContent/Spells/Necromancy/Wither.cs +++ b/Projects/UOContent/Spells/Necromancy/Wither.cs @@ -98,7 +98,7 @@ namespace Server.Spells.Necromancy var sdiBonus = AosAttributes.GetValue(Caster, AosAttribute.SpellDamage); - // PvP spell damage increase cap of 15% from an item�s magic property in Publish 33(SE) + // PvP spell damage increase cap of 15% from an item's magic property in Publish 33(SE) if (Core.SE && m.Player && Caster.Player && sdiBonus > 15) { sdiBonus = 15; diff --git a/Projects/UOContent/Spells/Second/Protection.cs b/Projects/UOContent/Spells/Second/Protection.cs index 7944e3015..8271276b5 100644 --- a/Projects/UOContent/Spells/Second/Protection.cs +++ b/Projects/UOContent/Spells/Second/Protection.cs @@ -56,8 +56,8 @@ namespace Server.Spells.Second * a decreased "resisting spells" skill value by -35 + (Inscription/20), * and a slower casting speed modifier (technically, a negative "faster cast speed") of 2 points. * The protection spell has an indefinite duration, becoming active when cast, and deactivated when re-cast. - * Reactive Armor, Protection, and Magic Reflection will stay on�even after logging out, - * even after dying�until you �turn them off� by casting them again. + * Reactive Armor, Protection, and Magic Reflection will stay on even after logging out, + * even after dying, until you turn them off by casting them again. */ if (_table.Remove(target, out var mods)) From 4f9714818d222def73eddde41b7a29154b51c363 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 5 Dec 2021 09:40:57 -0800 Subject: [PATCH 034/213] fix: Fixes skill requirements and cleans up magery spells (#870) * Preps damage stacking for mysticism, necromancy fixes, and spellweaving * Removes extra LINQ allocations * Fixes skill requirements for magery spells. --- Projects/UOContent/Spells/Base/MagerySpell.cs | 31 +++-- Projects/UOContent/Spells/Base/SpecialMove.cs | 58 +++----- Projects/UOContent/Spells/Base/Spell.cs | 90 ++++++------ Projects/UOContent/Spells/Base/SpellHelper.cs | 124 ++++++----------- .../UOContent/Spells/Eighth/Resurrection.cs | 5 +- Projects/UOContent/Spells/First/Feeblemind.cs | 2 + Projects/UOContent/Spells/First/MagicArrow.cs | 9 +- Projects/UOContent/Spells/Fourth/ArchCure.cs | 31 +++-- .../UOContent/Spells/Fourth/ArchProtection.cs | 6 +- Projects/UOContent/Spells/Fourth/Curse.cs | 12 +- .../UOContent/Spells/Second/RemoveTrap.cs | 2 +- .../Spells/Seventh/ChainLightning.cs | 129 ++++++++---------- .../UOContent/Spells/Seventh/EnergyField.cs | 6 +- .../UOContent/Spells/Seventh/MeteorSwarm.cs | 115 +++++++--------- Projects/UOContent/Spells/Sixth/Explosion.cs | 50 +++---- Projects/UOContent/Spells/Third/Poison.cs | 23 +--- 16 files changed, 311 insertions(+), 382 deletions(-) diff --git a/Projects/UOContent/Spells/Base/MagerySpell.cs b/Projects/UOContent/Spells/Base/MagerySpell.cs index c42d60954..68c261e8e 100644 --- a/Projects/UOContent/Spells/Base/MagerySpell.cs +++ b/Projects/UOContent/Spells/Base/MagerySpell.cs @@ -5,9 +5,10 @@ namespace Server.Spells { public abstract class MagerySpell : Spell { - private const double ChanceOffset = 20.0, ChanceLength = 100.0 / 7.0; - - private static readonly int[] m_ManaTable = { 4, 6, 9, 11, 14, 20, 40, 50 }; + private static readonly int[] _manaTable = { 4, 6, 9, 11, 14, 20, 40, 50 }; + private static readonly double[] _requiredSkill = Core.ML ? + new[] { 0.0, -4.0, 10.0, 24.0, 38.0, 52.0, 66.0, 80.0 } : + new[] { 0.0, 10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0 }; public MagerySpell(Mobile caster, Item scroll, SpellInfo info) : base(caster, scroll, info) { @@ -29,13 +30,20 @@ namespace Server.Spells circle -= 2; } - var avg = ChanceLength * circle; + // Original RunUO algorithm for required skill + // const double chanceOffset = 20.0 + // const double chanceLength = 100.0 / 7.0 + // var avg = chanceLength * circle; + // min = avg - chanceOffset; + // max = avg + chanceOffset; - min = avg - ChanceOffset; - max = avg + ChanceOffset; + // Correct algorithm according to OSI. + // TODO: Verify this algorithm on OSI for latest expansion. + min = _requiredSkill[circle]; + max = min + 40; } - public override int GetMana() => Scroll is BaseWand ? 0 : m_ManaTable[(int)Circle]; + public override int GetMana() => Scroll is BaseWand ? 0 : _manaTable[(int)Circle]; public override double GetResistSkill(Mobile m) { @@ -79,12 +87,13 @@ namespace Server.Spells public virtual double GetResistPercentForCircle(Mobile target, SpellCircle circle) { - var firstPercent = target.Skills.MagicResist.Value / 5.0; - var secondPercent = target.Skills.MagicResist.Value - + var magicResist = target.Skills.MagicResist.Value; + var firstPercent = magicResist / 5.0; + var secondPercent = magicResist - ((Caster.Skills[CastSkill].Value - 20.0) / 5.0 + (1 + (int)circle) * 5.0); - return (firstPercent > secondPercent ? firstPercent : secondPercent) / - 2.0; // Seems should be about half of what stratics says. + // Seems should be about half of what stratics says. + return (firstPercent > secondPercent ? firstPercent : secondPercent) / 2.0; } public virtual double GetResistPercent(Mobile target) => GetResistPercentForCircle(target, Circle); diff --git a/Projects/UOContent/Spells/Base/SpecialMove.cs b/Projects/UOContent/Spells/Base/SpecialMove.cs index f42ea076b..d0b98ac79 100644 --- a/Projects/UOContent/Spells/Base/SpecialMove.cs +++ b/Projects/UOContent/Spells/Base/SpecialMove.cs @@ -10,8 +10,7 @@ namespace Server.Spells { public abstract class SpecialMove { - private static readonly Dictionary m_PlayersTable = - new(); + private static readonly Dictionary _playersTable = new(); public virtual int BaseMana => 0; @@ -159,40 +158,18 @@ namespace Server.Spells return false; } - string option = null; - - if (this is Backstab) + string option = this switch { - option = "Backstab"; - } - else if (this is DeathStrike) - { - option = "Death Strike"; - } - else if (this is FocusAttack) - { - option = "Focus Attack"; - } - else if (this is KiAttack) - { - option = "Ki Attack"; - } - else if (this is SurpriseAttack) - { - option = "Surprise Attack"; - } - else if (this is HonorableExecution) - { - option = "Honorable Execution"; - } - else if (this is LightningStrike) - { - option = "Lightning Strike"; - } - else if (this is MomentumStrike) - { - option = "Momentum Strike"; - } + Backstab => "Backstab", + DeathStrike => "Death Strike", + FocusAttack => "Focus Attack", + KiAttack => "Ki Attack", + SurpriseAttack => "Surprise Attack", + HonorableExecution => "Honorable Execution", + LightningStrike => "Lightning Strike", + MomentumStrike => "Momentum Strike", + _ => null + }; if (option != null && !DuelContext.AllowSpecialMove(from, option, this)) { @@ -303,7 +280,7 @@ namespace Server.Spells private static void AddContext(Mobile m, SpecialMoveContext context) { - m_PlayersTable[m] = context; + _playersTable[m] = context; } private static void RemoveContext(Mobile m) @@ -312,23 +289,20 @@ namespace Server.Spells if (context != null) { - m_PlayersTable.Remove(m); + _playersTable.Remove(m); context.Timer.Stop(); } } private static SpecialMoveContext GetContext(Mobile m) => - m_PlayersTable.TryGetValue(m, out var context) ? context : null; + _playersTable.TryGetValue(m, out var context) ? context : null; private class SpecialMoveTimer : Timer { private readonly Mobile m_Mobile; - public SpecialMoveTimer(Mobile from) : base(TimeSpan.FromSeconds(3.0)) - { - m_Mobile = from; - } + public SpecialMoveTimer(Mobile from) : base(TimeSpan.FromSeconds(3.0)) => m_Mobile = from; protected override void OnTick() { diff --git a/Projects/UOContent/Spells/Base/Spell.cs b/Projects/UOContent/Spells/Base/Spell.cs index 120d85be1..78eea7bdc 100644 --- a/Projects/UOContent/Spells/Base/Spell.cs +++ b/Projects/UOContent/Spells/Base/Spell.cs @@ -17,19 +17,16 @@ namespace Server.Spells public abstract class Spell : ISpell { private static readonly TimeSpan NextSpellDelay = TimeSpan.FromSeconds(0.75); - private static readonly TimeSpan AnimateDelay = TimeSpan.FromSeconds(1.5); // In reality, it's ANY delayed Damage spell Post-AoS that can't stack, but, only // Expo & Magic Arrow have enough delay and a short enough cast time to bring up // the possibility of stacking 'em. Note that a MA & an Explosion will stack, but // of course, two MA's won't. - private static readonly Dictionary m_ContextTable = - new(); + private static readonly Dictionary _contextTable = new(); - private AnimTimer m_AnimTimer; - - private CastTimer m_CastTimer; + private AnimTimer _animTimer; + private CastTimer _castTimer; public Spell(Mobile caster, Item scroll, SpellInfo info) { @@ -60,13 +57,17 @@ namespace Server.Spells public virtual bool DelayedDamage => false; - public virtual bool DelayedDamageStacking => true; + public static readonly Type[] AOSNoDelayedDamageStackingSelf = Core.AOS ? Array.Empty() : null; + + // Null means stacking is allowed while empty indicates no stacking with self + // More than zero means no stacking with self and other spells + public virtual Type[] DelayedDamageSpellFamilyStacking => null; public virtual bool BlockedByHorrificBeast => true; public virtual bool BlockedByAnimalForm => true; public virtual bool BlocksMovement => true; - public virtual bool CheckNextSpellTime => !(Scroll is BaseWand); + public virtual bool CheckNextSpellTime => Scroll is not BaseWand; public virtual int CastRecoveryBase => 6; public virtual int CastRecoveryFastScalar => 1; @@ -149,22 +150,39 @@ namespace Server.Spells public void StartDelayedDamageContext(Mobile m, Timer t) { - if (DelayedDamageStacking) + var damageStacking = DelayedDamageSpellFamilyStacking; + if (damageStacking == null) { return; // Sanity } - if (!m_ContextTable.TryGetValue(GetType(), out var contexts)) + var type = GetType(); + + if (!_contextTable.TryGetValue(type, out var context)) { - m_ContextTable[GetType()] = contexts = new DelayedDamageContextWrapper(); + _contextTable[type] = context = new DelayedDamageContextWrapper(); + + for (int i = 0; i < damageStacking.Length; i++) + { + _contextTable.Add(damageStacking[i], context); + } } - contexts.Add(m, t); + context.Add(m, t); } + public bool HasDelayedDamageContext(Mobile m) => + DelayedDamageSpellFamilyStacking != null && + _contextTable.TryGetValue(GetType(), out var context) && context.Contains(m); + public void RemoveDelayedDamageContext(Mobile m) { - if (m_ContextTable.TryGetValue(GetType(), out var contexts)) + if (m == null || DelayedDamageSpellFamilyStacking == null) + { + return; // Sanity + } + + if (_contextTable.TryGetValue(GetType(), out var contexts)) { contexts.Remove(m); } @@ -389,8 +407,8 @@ namespace Server.Spells { OnDisturb(type, true); - m_CastTimer?.Stop(); - m_AnimTimer?.Stop(); + _castTimer?.Stop(); + _animTimer?.Stop(); if (Core.AOS && Caster.Player && type == DisturbType.Hurt) { @@ -469,7 +487,7 @@ namespace Server.Spells { Caster.SendLocalizedMessage(1061091); // You cannot cast that spell in this form. } - else if (!(Scroll is BaseWand) && (Caster.Paralyzed || Caster.Frozen)) + else if (Scroll is not BaseWand && (Caster.Paralyzed || Caster.Frozen)) { Caster.SendLocalizedMessage(502643); // You can not cast a spell while frozen. } @@ -492,7 +510,7 @@ namespace Server.Spells State = SpellState.Casting; Caster.Spell = this; - if (!(Scroll is BaseWand) && RevealOnCast) + if (Scroll is not BaseWand && RevealOnCast) { Caster.RevealingAction(); } @@ -507,8 +525,8 @@ namespace Server.Spells if (count != 0) { - m_AnimTimer = new AnimTimer(this, count); - m_AnimTimer.Start(); + _animTimer = new AnimTimer(this, count); + _animTimer.Start(); } if (Info.LeftHandEffect > 0) @@ -532,18 +550,18 @@ namespace Server.Spells WeaponAbility.ClearCurrentAbility(Caster); } - m_CastTimer = new CastTimer(this, castDelay); + _castTimer = new CastTimer(this, castDelay); // m_CastTimer.Start(); OnBeginCast(); if (castDelay > TimeSpan.Zero) { - m_CastTimer.Start(); + _castTimer.Start(); } else { - m_CastTimer.Tick(); + _castTimer.Tick(); } return true; @@ -647,11 +665,6 @@ namespace Server.Spells return TimeSpan.FromSeconds((double)delay / CastRecoveryPerSecond); } - // public virtual int CastDelayBase{ get{ return 3; } } - // public virtual int CastDelayFastScalar{ get{ return 1; } } - // public virtual int CastDelayPerSecond{ get{ return 4; } } - // public virtual int CastDelayMinimum{ get{ return 1; } } - public virtual TimeSpan GetCastDelay() { if (Scroll is BaseWand) @@ -665,7 +678,7 @@ namespace Server.Spells // Paladins with magery of 70.0 or above are subject to a faster casting cap of 2 var fcMax = 4; - if (CastSkill == SkillName.Magery || CastSkill == SkillName.Necromancy || + if (CastSkill is SkillName.Magery or SkillName.Necromancy || CastSkill == SkillName.Chivalry && Caster.Skills.Magery.Value >= 70.0) { fcMax = 2; @@ -749,12 +762,9 @@ namespace Server.Spells Scroll.Movable = m; } - else + else if (ClearHandsOnCast) { - if (ClearHandsOnCast) - { - Caster.ClearHands(); - } + Caster.ClearHands(); } var karma = ComputeKarmaAward(); @@ -838,10 +848,14 @@ namespace Server.Spells m_Contexts.Add(m, t); } + public bool Contains(Mobile m) => m_Contexts.ContainsKey(m); + public void Remove(Mobile m) { - m_Contexts.Remove(m); - // TODO: Should we stop the timer? + if (m_Contexts.Remove(m, out var t)) + { + t.Stop(); + } } } @@ -876,7 +890,7 @@ namespace Server.Spells if (!Running) { - m_Spell.m_AnimTimer = null; + m_Spell._animTimer = null; } } } @@ -900,7 +914,7 @@ namespace Server.Spells if (m_Spell.State == SpellState.Casting && m_Spell.Caster.Spell == m_Spell) { m_Spell.State = SpellState.Sequencing; - m_Spell.m_CastTimer = null; + m_Spell._castTimer = null; m_Spell.Caster.OnSpellCast(m_Spell); m_Spell.Caster.Region?.OnSpellCast(m_Spell.Caster, m_Spell); m_Spell.Caster.NextSpellTime = @@ -915,7 +929,7 @@ namespace Server.Spells m_Spell.Caster.Target?.BeginTimeout(m_Spell.Caster, 30000); // 30 seconds } - m_Spell.m_CastTimer = null; + m_Spell._castTimer = null; } } diff --git a/Projects/UOContent/Spells/Base/SpellHelper.cs b/Projects/UOContent/Spells/Base/SpellHelper.cs index f855ad5ac..383228b49 100644 --- a/Projects/UOContent/Spells/Base/SpellHelper.cs +++ b/Projects/UOContent/Spells/Base/SpellHelper.cs @@ -184,7 +184,7 @@ namespace Server.Spells public static void Turn(Mobile from, object to) { - if (!(to is IPoint3D target)) + if (to is not IPoint3D target) { return; } @@ -333,7 +333,7 @@ namespace Server.Spells public static bool AddStatCurse(Mobile caster, Mobile target, StatType type, int curse, TimeSpan duration) { var offset = -curse; - var name = $"[Magic] {type} Offset"; + var name = $"[Magic] {type} Curse"; var mod = target.GetStatMod(name); @@ -447,26 +447,8 @@ namespace Server.Spells var bcFrom = from as BaseCreature; var bcTarg = to as BaseCreature; - PlayerMobile pmFrom; - PlayerMobile pmTarg; - - if (bcFrom?.Summoned == true) - { - pmFrom = bcFrom.SummonMaster as PlayerMobile; - } - else - { - pmFrom = from as PlayerMobile; - } - - if (bcTarg?.Summoned == true) - { - pmTarg = bcTarg.SummonMaster as PlayerMobile; - } - else - { - pmTarg = to as PlayerMobile; - } + var pmFrom = (bcFrom?.Summoned == true ? bcFrom.SummonMaster : from) as PlayerMobile; + var pmTarg = (bcTarg?.Summoned == true ? bcTarg.SummonMaster : to) as PlayerMobile; if (pmFrom?.DuelContext != null && pmFrom.DuelContext == pmTarg?.DuelContext && pmFrom.DuelContext.Started && pmFrom.DuelPlayer != null && pmTarg?.DuelPlayer != null) @@ -864,17 +846,6 @@ namespace Server.Spells return x < 0 || y < 0 || x >= map.Width || y >= map.Height; } - // towns - public static bool IsTown(IPoint3D ip, Mobile caster) - { - if (ip is Item item) - { - ip = item.GetWorldLocation(); - } - - return IsTown(new Point3D(ip), caster); - } - public static bool IsTown(Point3D loc, Mobile caster) { var map = caster.Map; @@ -897,15 +868,8 @@ namespace Server.Spells return reg?.IsDisabled() == false; } - public static bool CheckTown(IPoint3D ip, Mobile caster) - { - if (ip is Item item) - { - ip = item.GetWorldLocation(); - } - - return CheckTown(new Point3D(ip), caster); - } + public static bool CheckTown(IPoint3D ip, Mobile caster) => + CheckTown((ip as Item)?.GetWorldLocation() ?? new Point3D(ip), caster); public static bool CheckTown(Point3D loc, Mobile caster) { @@ -919,13 +883,13 @@ namespace Server.Spells } // magic reflection - public static void CheckReflect(int circle, Mobile caster, ref Mobile target) - { + public static bool CheckReflect(int circle, Mobile caster, ref Mobile target) => CheckReflect(circle, ref caster, ref target); - } - public static void CheckReflect(int circle, ref Mobile caster, ref Mobile target) + public static bool CheckReflect(int circle, ref Mobile caster, ref Mobile target) { + var reflect = false; + if (target.MagicDamageAbsorb > 0) { ++circle; @@ -933,41 +897,26 @@ namespace Server.Spells target.MagicDamageAbsorb -= circle; // This order isn't very intuitive, but you have to nullify reflect before target gets switched - - var reflect = target.MagicDamageAbsorb >= 0; - - (target as BaseCreature)?.CheckReflect(caster, ref reflect); - + reflect = target.MagicDamageAbsorb >= 0; if (target.MagicDamageAbsorb <= 0) { target.MagicDamageAbsorb = 0; DefensiveSpell.Nullify(target); } - - if (reflect) - { - target.FixedEffect(0x37B9, 10, 5); - - var temp = caster; - caster = target; - target = temp; - } } - else if (target is BaseCreature creature) + + if (target is BaseCreature creature) { - var reflect = false; - creature.CheckReflect(caster, ref reflect); - - if (reflect) - { - creature.FixedEffect(0x37B9, 10, 5); - - var temp = caster; - caster = creature; - target = temp; - } } + + if (reflect) + { + target.FixedEffect(0x37B9, 10, 5); + (caster, target) = (target, caster); + } + + return reflect; } public static void Damage(Spell spell, Mobile target, double damage) @@ -995,20 +944,21 @@ namespace Server.Spells { (from as BaseCreature)?.AlterSpellDamageTo(target, ref iDamage); - (target as BaseCreature)?.AlterSpellDamageFrom(from, ref iDamage); + var bcTarget = target as BaseCreature; + bcTarget?.AlterSpellDamageFrom(from, ref iDamage); target.Damage(iDamage, from); + + if (from != null) + { + bcTarget?.OnHarmfulSpell(from); + bcTarget?.OnDamagedBySpell(from); + } } else { new SpellDamageTimer(spell, target, from, iDamage, delay).Start(); } - - if (target is BaseCreature c && from != null && delay == TimeSpan.Zero) - { - c.OnHarmfulSpell(from); - c.OnDamagedBySpell(from); - } } public static void Damage( @@ -1086,6 +1036,11 @@ namespace Server.Spells public static void DoLeech(int damageGiven, Mobile from, Mobile target) { + if (target == null) + { + return; + } + var context = TransformationSpellHelper.GetContext(from); if (context == null) /* cleanup */ @@ -1134,7 +1089,7 @@ namespace Server.Spells m_Damage = damage; m_Spell = s; - if (m_Spell?.DelayedDamage == true && !m_Spell.DelayedDamageStacking) + if (m_Spell?.DelayedDamage == true) { m_Spell.StartDelayedDamageContext(target, this); } @@ -1143,7 +1098,6 @@ namespace Server.Spells protected override void OnTick() { (m_From as BaseCreature)?.AlterSpellDamageTo(m_Target, ref m_Damage); - (m_Target as BaseCreature)?.AlterSpellDamageFrom(m_From, ref m_Damage); m_Target.Damage(m_Damage); @@ -1181,7 +1135,8 @@ namespace Server.Spells m_Chaos = chaos; m_DFA = dfa; m_Spell = s; - if (m_Spell?.DelayedDamage == true && !m_Spell.DelayedDamageStacking) + + if (m_Spell?.DelayedDamage == true) { m_Spell.StartDelayedDamageContext(target, this); } @@ -1189,10 +1144,9 @@ namespace Server.Spells protected override void OnTick() { - var bcFrom = m_From as BaseCreature; var bcTarg = m_Target as BaseCreature; - if (bcFrom != null && m_Target != null) + if (m_From is BaseCreature bcFrom && m_Target != null) { bcFrom.AlterSpellDamageTo(m_Target, ref m_Damage); } @@ -1253,7 +1207,7 @@ namespace Server.Spells public static bool OnCast(Mobile caster, Spell spell) { - if (!(spell is ITransformationSpell transformSpell)) + if (spell is not ITransformationSpell transformSpell) { return false; } diff --git a/Projects/UOContent/Spells/Eighth/Resurrection.cs b/Projects/UOContent/Spells/Eighth/Resurrection.cs index c485850fa..2bda277a0 100644 --- a/Projects/UOContent/Spells/Eighth/Resurrection.cs +++ b/Projects/UOContent/Spells/Eighth/Resurrection.cs @@ -51,9 +51,8 @@ namespace Server.Spells.Eighth } else if (m.Region?.IsPartOf("Khaldun") == true) { - Caster.SendLocalizedMessage( - 1010395 - ); // The veil of death in this area is too strong and resists thy efforts to restore life. + // The veil of death in this area is too strong and resists thy efforts to restore life. + Caster.SendLocalizedMessage(1010395); } else if (CheckBSequence(m, true)) { diff --git a/Projects/UOContent/Spells/First/Feeblemind.cs b/Projects/UOContent/Spells/First/Feeblemind.cs index ac339bca6..674c71b3e 100644 --- a/Projects/UOContent/Spells/First/Feeblemind.cs +++ b/Projects/UOContent/Spells/First/Feeblemind.cs @@ -27,6 +27,8 @@ namespace Server.Spells.First SpellHelper.CheckReflect((int)Circle, Caster, ref m); + // TODO: StoneForm immunity + SpellHelper.AddStatCurse(Caster, m, StatType.Int); m.Spell?.OnCasterHurt(); diff --git a/Projects/UOContent/Spells/First/MagicArrow.cs b/Projects/UOContent/Spells/First/MagicArrow.cs index 02f4de6e7..1461e3548 100644 --- a/Projects/UOContent/Spells/First/MagicArrow.cs +++ b/Projects/UOContent/Spells/First/MagicArrow.cs @@ -1,3 +1,4 @@ +using System; using Server.Targeting; namespace Server.Spells.First @@ -18,7 +19,7 @@ namespace Server.Spells.First public override SpellCircle Circle => SpellCircle.First; - public override bool DelayedDamageStacking => !Core.AOS; + public override Type[] DelayedDamageSpellFamilyStacking => AOSNoDelayedDamageStackingSelf; public override bool DelayedDamage => true; @@ -30,6 +31,12 @@ namespace Server.Spells.First SpellHelper.Turn(source, m); + if (Core.SA && HasDelayedDamageContext(m)) + { + DoHurtFizzle(); + return; + } + SpellHelper.CheckReflect((int)Circle, ref source, ref m); double damage; diff --git a/Projects/UOContent/Spells/Fourth/ArchCure.cs b/Projects/UOContent/Spells/Fourth/ArchCure.cs index 3d7158499..9cacd8790 100644 --- a/Projects/UOContent/Spells/Fourth/ArchCure.cs +++ b/Projects/UOContent/Spells/Fourth/ArchCure.cs @@ -1,6 +1,5 @@ using System; -using System.Collections.Generic; -using System.Linq; +using Server.Collections; using Server.Mobiles; namespace Server.Spells.Fourth @@ -34,37 +33,39 @@ namespace Server.Spells.Fourth SpellHelper.GetSurfaceTop(ref p); - var targets = new List(); - var map = Caster.Map; - var directTarget = p as Mobile; - var loc = new Point3D(p); - if (map != null) { + using var pool = PooledRefQueue.Create(); + var directTarget = p as Mobile; + var loc = new Point3D(p); + var feluccaRules = map.Rules == MapRules.FeluccaRules; // You can target any living mobile directly, beneficial checks apply if (directTarget != null && Caster.CanBeBeneficial(directTarget, false)) { - targets.Add(directTarget); + pool.Enqueue(directTarget); } var eable = map.GetMobilesInRange(loc, 2); - targets.AddRange(eable.Where(m => m != directTarget).Where(m => AreaCanTarget(m, feluccaRules))); + foreach (var m in eable) + { + if (m != directTarget && AreaCanTarget(m, feluccaRules)) + { + pool.Enqueue(m); + } + } eable.Free(); - } - Effects.PlaySound(loc, Caster.Map, 0x299); + Effects.PlaySound(loc, Caster.Map, 0x299); - if (targets.Count > 0) - { var cured = 0; - for (var i = 0; i < targets.Count; ++i) + while (pool.Count > 0) { - var m = targets[i]; + var m = pool.Dequeue(); Caster.DoBeneficial(m); diff --git a/Projects/UOContent/Spells/Fourth/ArchProtection.cs b/Projects/UOContent/Spells/Fourth/ArchProtection.cs index d924d4c82..dfb258ec9 100644 --- a/Projects/UOContent/Spells/Fourth/ArchProtection.cs +++ b/Projects/UOContent/Spells/Fourth/ArchProtection.cs @@ -19,7 +19,7 @@ namespace Server.Spells.Fourth Reagent.SulfurousAsh ); - private static readonly Dictionary _Table = new(); + private static readonly Dictionary _table = new(); public ArchProtectionSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { @@ -107,12 +107,12 @@ namespace Server.Spells.Fourth private static void AddEntry(Mobile m, int v) { - _Table[m] = v; + _table[m] = v; } public static void RemoveEntry(Mobile m) { - if (_Table.Remove(m, out var v)) + if (_table.Remove(m, out var v)) { m.EndAction(); m.VirtualArmorMod -= Math.Min(v, m.VirtualArmorMod); diff --git a/Projects/UOContent/Spells/Fourth/Curse.cs b/Projects/UOContent/Spells/Fourth/Curse.cs index 84a076e3d..2eb06c82d 100644 --- a/Projects/UOContent/Spells/Fourth/Curse.cs +++ b/Projects/UOContent/Spells/Fourth/Curse.cs @@ -15,7 +15,7 @@ namespace Server.Spells.Fourth Reagent.SulfurousAsh ); - private static readonly HashSet m_UnderEffect = new(); + private static readonly HashSet _underEffect = new(); public CurseSpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { @@ -41,7 +41,7 @@ namespace Server.Spells.Fourth if (Caster.Player && m.Player /*&& Caster != m */ && !UnderEffect(m)) { var duration = SpellHelper.GetDuration(Caster, m); - m_UnderEffect.Add(m); + _underEffect.Add(m); Timer.StartTimer(duration, () => RemoveEffect(m)); m.UpdateResistances(); } @@ -71,13 +71,13 @@ namespace Server.Spells.Fourth Caster.Target = new SpellTargetMobile(this, TargetFlags.Harmful, Core.ML ? 10 : 12); } - public static void RemoveEffect(Mobile m) + public static bool RemoveEffect(Mobile m) { - m_UnderEffect.Remove(m); - + var effectRemoved = _underEffect.Remove(m); m.UpdateResistances(); + return effectRemoved; } - public static bool UnderEffect(Mobile m) => m_UnderEffect.Contains(m); + public static bool UnderEffect(Mobile m) => _underEffect.Contains(m); } } diff --git a/Projects/UOContent/Spells/Second/RemoveTrap.cs b/Projects/UOContent/Spells/Second/RemoveTrap.cs index cb800ddf2..085aa319f 100644 --- a/Projects/UOContent/Spells/Second/RemoveTrap.cs +++ b/Projects/UOContent/Spells/Second/RemoveTrap.cs @@ -55,7 +55,7 @@ namespace Server.Spells.Second public override void OnCast() { Caster.Target = new SpellTargetItem(this, range: Core.ML ? 10 : 12); - Caster.SendMessage("What do you wish to untrap?"); // TODO: Localization? + Caster.SendLocalizedMessage(502368); } } } diff --git a/Projects/UOContent/Spells/Seventh/ChainLightning.cs b/Projects/UOContent/Spells/Seventh/ChainLightning.cs index 6f3ec9923..d9edf0567 100644 --- a/Projects/UOContent/Spells/Seventh/ChainLightning.cs +++ b/Projects/UOContent/Spells/Seventh/ChainLightning.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; -using System.Linq; +using Server.Collections; namespace Server.Spells.Seventh { @@ -27,89 +26,77 @@ namespace Server.Spells.Seventh public void Target(IPoint3D p) { - if (SpellHelper.CheckTown(p, Caster) && CheckSequence()) + var loc = (p as Item)?.GetWorldLocation() ?? new Point3D(p); + if (SpellHelper.CheckTown(loc, Caster) && CheckSequence()) { SpellHelper.Turn(Caster, p); - if (p is Item item) - { - p = item.GetWorldLocation(); - } - - var targets = new List(); - var map = Caster.Map; - var playerVsPlayer = false; - if (map != null) { - var eable = map.GetMobilesInRange(new Point3D(p), 2); + using var pool = PooledRefQueue.Create(); + var pvp = false; - targets.AddRange( - eable.Where( - m => - { - if (Core.AOS && (m == Caster || !Caster.InLOS(m)) || - !SpellHelper.ValidIndirectTarget(Caster, m) || - !Caster.CanBeHarmful(m, false)) - { - return false; - } - - if (m.Player) - { - playerVsPlayer = true; - } - - return true; - } - ) - .ToList() - ); - - eable.Free(); - } - - double damage; - - damage = Core.AOS - ? GetNewAosDamage(51, 1, 5, playerVsPlayer) - : Utility.Random(27, 22); - - if (targets.Count > 0) - { - if (Core.AOS && targets.Count > 2) + var eable = map.GetMobilesInRange(loc, 2); + foreach (var m in eable) { - damage = damage * 2 / targets.Count; - } - else if (!Core.AOS) - { - damage /= targets.Count; - } - - for (var i = 0; i < targets.Count; ++i) - { - var toDeal = damage; - var m = targets[i]; - - if (!Core.AOS && CheckResisted(m)) + if (Core.AOS && (m == Caster || !Caster.InLOS(m)) || + !SpellHelper.ValidIndirectTarget(Caster, m) || + !Caster.CanBeHarmful(m, false)) { - toDeal *= 0.5; - - m.SendLocalizedMessage(501783); // You feel yourself resisting magical energy. + continue; } - toDeal *= GetDamageScalar(m); - Caster.DoHarmful(m); - SpellHelper.Damage(this, m, toDeal, 0, 0, 0, 0, 100); + if (m.Player) + { + pvp = true; + } - m.BoltEffect(0); + pool.Enqueue(m); + } + + eable.Free(); + + if (pool.Count > 0) + { + double damage = Core.AOS + ? GetNewAosDamage(51, 1, 5, pvp) + : Utility.Random(27, 22); + + if (pool.Count > 2) + { + if (Core.AOS) + { + damage *= 2; + } + + damage /= pool.Count; + } + + while (pool.Count > 0) + { + var toDeal = damage; + var m = pool.Dequeue(); + + if (!Core.AOS && CheckResisted(m)) + { + toDeal *= 0.5; + + m.SendLocalizedMessage(501783); // You feel yourself resisting magical energy. + } + + toDeal *= GetDamageScalar(m); + Caster.DoHarmful(m); + SpellHelper.Damage(this, m, toDeal, 0, 0, 0, 0, 100); + + m.BoltEffect(0); + } + } + else + { + Caster.PlaySound(0x29); } - } - else - { - Caster.PlaySound(0x29); } } diff --git a/Projects/UOContent/Spells/Seventh/EnergyField.cs b/Projects/UOContent/Spells/Seventh/EnergyField.cs index d802cd5e8..abb0895ef 100644 --- a/Projects/UOContent/Spells/Seventh/EnergyField.cs +++ b/Projects/UOContent/Spells/Seventh/EnergyField.cs @@ -45,10 +45,8 @@ namespace Server.Spells.Seventh } else { - duration = TimeSpan.FromSeconds( - Caster.Skills.Magery.Value * 0.28 + - 2.0 - ); // (28% of magery) + 2.0 seconds + // (28% of magery) + 2.0 seconds + duration = TimeSpan.FromSeconds(Caster.Skills.Magery.Value * 0.28 + 2.0); } var itemID = eastToWest ? 0x3946 : 0x3956; diff --git a/Projects/UOContent/Spells/Seventh/MeteorSwarm.cs b/Projects/UOContent/Spells/Seventh/MeteorSwarm.cs index 19899f7b0..f8f934a18 100644 --- a/Projects/UOContent/Spells/Seventh/MeteorSwarm.cs +++ b/Projects/UOContent/Spells/Seventh/MeteorSwarm.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; -using System.Linq; +using Server.Collections; namespace Server.Spells.Seventh { @@ -36,8 +35,6 @@ namespace Server.Spells.Seventh p = item.GetWorldLocation(); } - List targets; - var map = Caster.Map; var playerVsPlayer = false; @@ -46,69 +43,63 @@ namespace Server.Spells.Seventh if (map != null) { var eable = map.GetMobilesInRange(loc, 2); - - targets = eable.Where( - m => - { - if (Caster == m || !SpellHelper.ValidIndirectTarget(Caster, m) || - !Caster.CanBeHarmful(m, false) || - Core.AOS && !Caster.InLOS(m)) - { - return false; - } - - if (m.Player) - { - playerVsPlayer = true; - } - - return true; - } - ) - .ToList(); - - eable.Free(); - } - else - { - targets = new List(); - } - - double damage = Core.AOS - ? GetNewAosDamage(51, 1, 5, playerVsPlayer) - : Utility.Random(27, 22); - - if (targets.Count > 0) - { - Effects.PlaySound(loc, Caster.Map, 0x160); - - if (Core.AOS && targets.Count > 2) + using var queue = PooledRefQueue.Create(); + foreach (var m in eable) { - damage = damage * 2 / targets.Count; - } - else if (!Core.AOS) - { - damage /= targets.Count; - } - - for (var i = 0; i < targets.Count; ++i) - { - var m = targets[i]; - - var toDeal = damage; - - if (!Core.AOS && CheckResisted(m)) + if (Caster == m || !SpellHelper.ValidIndirectTarget(Caster, m) || + !Caster.CanBeHarmful(m, false) || Core.AOS && !Caster.InLOS(m)) { - damage *= 0.5; - - m.SendLocalizedMessage(501783); // You feel yourself resisting magical energy. + continue; } - toDeal *= GetDamageScalar(m); - Caster.DoHarmful(m); - SpellHelper.Damage(this, m, toDeal, 0, 100, 0, 0, 0); + if (m.Player) + { + playerVsPlayer = true; + } - Caster.MovingParticles(m, 0x36D4, 7, 0, false, true, 9501, 1, 0, 0x100); + queue.Enqueue(m); + } + + eable.Free(); + + double damage = Core.AOS + ? GetNewAosDamage(51, 1, 5, playerVsPlayer) + : Utility.Random(27, 22); + + int count = queue.Count; + + if (count > 0) + { + Effects.PlaySound(loc, Caster.Map, 0x160); + + if (Core.AOS && count > 2) + { + damage = damage * 2 / count; + } + else if (!Core.AOS) + { + damage /= count; + } + + while (queue.Count > 0) + { + var m = queue.Dequeue(); + + var toDeal = damage; + + if (!Core.AOS && CheckResisted(m)) + { + damage *= 0.5; + + m.SendLocalizedMessage(501783); // You feel yourself resisting magical energy. + } + + toDeal *= GetDamageScalar(m); + Caster.DoHarmful(m); + SpellHelper.Damage(this, m, toDeal, 0, 100, 0, 0, 0); + + Caster.MovingParticles(m, 0x36D4, 7, 0, false, true, 9501, 1, 0, 0x100); + } } } } diff --git a/Projects/UOContent/Spells/Sixth/Explosion.cs b/Projects/UOContent/Spells/Sixth/Explosion.cs index 16b0f69b3..7b21fd54e 100644 --- a/Projects/UOContent/Spells/Sixth/Explosion.cs +++ b/Projects/UOContent/Spells/Sixth/Explosion.cs @@ -20,22 +20,26 @@ namespace Server.Spells.Sixth public override SpellCircle Circle => SpellCircle.Sixth; - public override bool DelayedDamageStacking => !Core.AOS; + public override Type[] DelayedDamageSpellFamilyStacking => AOSNoDelayedDamageStackingSelf; public override bool DelayedDamage => false; public void Target(Mobile m) { + if (Core.SA && HasDelayedDamageContext(m)) + { + DoHurtFizzle(); + return; + } + if (Caster.CanBeHarmful(m) && CheckSequence()) { - Mobile attacker = Caster, defender = m; + Mobile defender = m; SpellHelper.Turn(Caster, m); - SpellHelper.CheckReflect((int)Circle, Caster, ref m); - var t = new InternalTimer(this, attacker, defender, m); - t.Start(); + var t = new InternalTimer(this, Caster, defender, m).Start(); } FinishSequence(); @@ -48,52 +52,52 @@ namespace Server.Spells.Sixth private class InternalTimer : Timer { - private readonly Mobile m_Attacker; - private readonly Mobile m_Defender; - private readonly MagerySpell m_Spell; - private readonly Mobile m_Target; + private readonly Mobile _attacker; + private readonly Mobile _defender; + private readonly MagerySpell _spell; + private readonly Mobile _target; public InternalTimer(MagerySpell spell, Mobile attacker, Mobile defender, Mobile target) : base(TimeSpan.FromSeconds(Core.AOS ? 3.0 : 2.5)) { - m_Spell = spell; - m_Attacker = attacker; - m_Defender = defender; - m_Target = target; + _spell = spell; + _attacker = attacker; + _defender = defender; + _target = target; - m_Spell?.StartDelayedDamageContext(attacker, this); + _spell?.StartDelayedDamageContext(_attacker, this); } protected override void OnTick() { - if (m_Attacker.HarmfulCheck(m_Defender)) + if (_attacker.HarmfulCheck(_defender)) { double damage; if (Core.AOS) { - damage = m_Spell.GetNewAosDamage(40, 1, 5, m_Defender); + damage = _spell.GetNewAosDamage(40, 1, 5, _defender); } else { damage = Utility.Random(23, 22); - if (m_Spell.CheckResisted(m_Target)) + if (_spell.CheckResisted(_target)) { damage *= 0.75; - m_Target.SendLocalizedMessage(501783); // You feel yourself resisting magical energy. + _target.SendLocalizedMessage(501783); // You feel yourself resisting magical energy. } - damage *= m_Spell.GetDamageScalar(m_Target); + damage *= _spell.GetDamageScalar(_target); } - m_Target.FixedParticles(0x36BD, 20, 10, 5044, EffectLayer.Head); - m_Target.PlaySound(0x307); + _target.FixedParticles(0x36BD, 20, 10, 5044, EffectLayer.Head); + _target.PlaySound(0x307); - SpellHelper.Damage(m_Spell, m_Target, damage, 0, 100, 0, 0, 0); + SpellHelper.Damage(_spell, _target, damage, 0, 100, 0, 0, 0); - m_Spell?.RemoveDelayedDamageContext(m_Attacker); + _spell?.RemoveDelayedDamageContext(_attacker); } } } diff --git a/Projects/UOContent/Spells/Third/Poison.cs b/Projects/UOContent/Spells/Third/Poison.cs index 584d3a20e..67d0e3b01 100644 --- a/Projects/UOContent/Spells/Third/Poison.cs +++ b/Projects/UOContent/Spells/Third/Poison.cs @@ -43,24 +43,13 @@ namespace Server.Spells.Third { if (Caster.InRange(m, 2)) { - var total = (Caster.Skills.Magery.Fixed + Caster.Skills.Poisoning.Fixed) / 2; - - if (total >= 1000) + level = (Caster.Skills.Magery.Fixed + Caster.Skills.Poisoning.Fixed) / 2 switch { - level = 3; - } - else if (total > 850) - { - level = 2; - } - else if (total > 650) - { - level = 1; - } - else - { - level = 0; - } + >= 1000 => 3, + > 850 => 2, + > 650 => 1, + _ => 0 + }; } else { From 32589478979d51f5dd49643c24ffd4c473e08052 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 5 Dec 2021 21:23:08 -0800 Subject: [PATCH 035/213] fix: Fixes codege of hashsets (#879) --- .../SerializableMigration/Rules/HashSetMigrationRule.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/HashSetMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/HashSetMigrationRule.cs index 46e425a3d..d670ae01f 100644 --- a/Projects/SerializationGenerator/SerializableMigration/Rules/HashSetMigrationRule.cs +++ b/Projects/SerializationGenerator/SerializableMigration/Rules/HashSetMigrationRule.cs @@ -67,7 +67,11 @@ namespace SerializableMigration ruleArguments[0] = extraOptions; ruleArguments[1] = setTypeSymbol.ToDisplayString(); ruleArguments[2] = serializableSetType.Rule; - Array.Copy(serializableSetType.RuleArguments, 0, ruleArguments, 3, length); + + if (length > 0) + { + Array.Copy(serializableSetType.RuleArguments, 0, ruleArguments, 3, length); + } return true; } @@ -98,7 +102,7 @@ namespace SerializableMigration source.AppendLine($"{indent}{ruleArguments[argumentsOffset]} {propertyEntry};"); source.AppendLine($"{indent}var {propertyCount} = reader.ReadEncodedInt();"); source.AppendLine($"{indent}{property.Name} = new System.Collections.Generic.HashSet<{ruleArguments[argumentsOffset]}>({propertyCount});"); - source.AppendLine($"{indent}for (var {propertyIndex} = 0; i < {propertyCount}; {propertyIndex}++)"); + source.AppendLine($"{indent}for (var {propertyIndex} = 0; {propertyIndex} < {propertyCount}; {propertyIndex}++)"); source.AppendLine($"{indent}{{"); var serializableSetElement = new SerializableProperty From ef5aee87f38d11f56f335df8ff28da66f66a621a Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 5 Dec 2021 22:55:24 -0800 Subject: [PATCH 036/213] fix: Adds back generic timer delay call (#880) --- Projects/Server/Timer/Timer.DelayStateCall.cs | 242 ++++++++++++++++++ 1 file changed, 242 insertions(+) create mode 100644 Projects/Server/Timer/Timer.DelayStateCall.cs diff --git a/Projects/Server/Timer/Timer.DelayStateCall.cs b/Projects/Server/Timer/Timer.DelayStateCall.cs new file mode 100644 index 000000000..5c7712e55 --- /dev/null +++ b/Projects/Server/Timer/Timer.DelayStateCall.cs @@ -0,0 +1,242 @@ +/************************************************************************* + * ModernUO * + * Copyright 2019-2021 - ModernUO Development Team * + * Email: hi@modernuo.com * + * File: Timer.DelayStateCall.cs * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + +using System; +using System.Runtime.CompilerServices; + +namespace Server +{ + public partial class Timer + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Timer DelayCall(Action callback, T state) => + DelayCall(TimeSpan.Zero, TimeSpan.Zero, 1, callback, state); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Timer DelayCall(TimeSpan delay, Action callback, T state) => + DelayCall(delay, TimeSpan.Zero, 1, callback, state); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Timer DelayCall(TimeSpan delay, TimeSpan interval, Action callback, T state) => + DelayCall(delay, interval, 0, callback, state); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Timer DelayCall(TimeSpan delay, TimeSpan interval, int count, Action callback, T state) => + new DelayStateCallTimer(delay, interval, count, callback, state).Start(); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Timer DelayCall(Action callback, T1 t1, T2 t2) => + DelayCall(TimeSpan.Zero, TimeSpan.Zero, 1, callback, t1, t2); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Timer DelayCall(TimeSpan delay, Action callback, T1 t1, T2 t2) => + DelayCall(delay, TimeSpan.Zero, 1, callback, t1, t2); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Timer DelayCall(TimeSpan delay, TimeSpan interval, Action callback, T1 t1, T2 t2) => + DelayCall(delay, interval, 0, callback, t1, t2); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Timer DelayCall( + TimeSpan delay, TimeSpan interval, int count, Action callback, + T1 t1, T2 t2 + ) => new DelayStateCallTimer(delay, interval, count, callback, t1, t2).Start(); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Timer DelayCall(Action callback, T1 t1, T2 t2, T3 t3) => + DelayCall(TimeSpan.Zero, TimeSpan.Zero, 1, callback, t1, t2, t3); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Timer DelayCall( + TimeSpan delay, Action callback, T1 t1, T2 t2, T3 t3 + ) => DelayCall(delay, TimeSpan.Zero, 1, callback, t1, t2, t3); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Timer DelayCall( + TimeSpan delay, TimeSpan interval, Action callback, + T1 t1, T2 t2, T3 t3 + ) => DelayCall(delay, interval, 0, callback, t1, t2, t3); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Timer DelayCall( + TimeSpan delay, TimeSpan interval, int count, + Action callback, T1 t1, T2 t2, T3 t3 + ) => new DelayStateCallTimer(delay, interval, count, callback, t1, t2, t3).Start(); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Timer DelayCall( + Action callback, T1 t1, T2 t2, T3 t3, T4 t4 + ) => DelayCall(TimeSpan.Zero, TimeSpan.Zero, 1, callback, t1, t2, t3, t4); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Timer DelayCall( + TimeSpan delay, Action callback, + T1 t1, T2 t2, T3 t3, T4 t4 + ) => DelayCall(delay, TimeSpan.Zero, 1, callback, t1, t2, t3, t4); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Timer DelayCall( + TimeSpan delay, TimeSpan interval, + Action callback, T1 t1, T2 t2, T3 t3, T4 t4 + ) => DelayCall(delay, interval, 0, callback, t1, t2, t3, t4); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Timer DelayCall( + TimeSpan delay, TimeSpan interval, int count, + Action callback, T1 t1, T2 t2, T3 t3, T4 t4 + ) => new DelayStateCallTimer(delay, interval, count, callback, t1, t2, t3, t4).Start(); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Timer DelayCall( + Action callback, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5 + ) => new DelayStateCallTimer(TimeSpan.Zero, TimeSpan.Zero, 1, callback, t1, t2, t3, t4, t5).Start(); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Timer DelayCall( + TimeSpan delay, + Action callback, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5 + ) => new DelayStateCallTimer(delay, TimeSpan.Zero, 1, callback, t1, t2, t3, t4, t5).Start(); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Timer DelayCall( + TimeSpan delay, TimeSpan interval, + Action callback, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5 + ) => new DelayStateCallTimer(delay, interval, 0, callback, t1, t2, t3, t4, t5).Start(); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Timer DelayCall( + TimeSpan delay, TimeSpan interval, int count, + Action callback, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5 + ) => new DelayStateCallTimer(delay, interval, count, callback, t1, t2, t3, t4, t5).Start(); + + private class DelayStateCallTimer : Timer + { + private readonly T _t1; + + public DelayStateCallTimer(TimeSpan delay, TimeSpan interval, int count, Action callback, T state) + : base(delay, interval, count) + { + Callback = callback; + _t1 = state; + } + + public Action Callback { get; } + + protected override void OnTick() => Callback?.Invoke(_t1); + + public override string ToString() => $"DelayStateCall[{FormatDelegate(Callback)}]"; + } + + private class DelayStateCallTimer : Timer + { + private readonly T1 _t1; + private readonly T2 _t2; + + public DelayStateCallTimer( + TimeSpan delay, TimeSpan interval, int count, Action callback, + T1 t1, T2 t2 + ) : base(delay, interval, count) + { + Callback = callback; + _t1 = t1; + _t2 = t2; + } + + public Action Callback { get; } + + protected override void OnTick() => Callback?.Invoke(_t1, _t2); + + public override string ToString() => $"DelayStateCall[{FormatDelegate(Callback)}]"; + } + + private class DelayStateCallTimer : Timer + { + private readonly T1 _t1; + private readonly T2 _t2; + private readonly T3 _t3; + + public DelayStateCallTimer( + TimeSpan delay, TimeSpan interval, int count, Action callback, + T1 t1, T2 t2, T3 t3 + ) : base(delay, interval, count) + { + Callback = callback; + _t1 = t1; + _t2 = t2; + _t3 = t3; + } + + public Action Callback { get; } + + protected override void OnTick() => Callback?.Invoke(_t1, _t2, _t3); + + public override string ToString() => $"DelayStateCall[{FormatDelegate(Callback)}]"; + } + + private class DelayStateCallTimer : Timer + { + private readonly T1 _t1; + private readonly T2 _t2; + private readonly T3 _t3; + private readonly T4 _t4; + + public DelayStateCallTimer( + TimeSpan delay, TimeSpan interval, int count, Action callback, + T1 t1, T2 t2, T3 t3, T4 t4 + ) : base(delay, interval, count) + { + Callback = callback; + _t1 = t1; + _t2 = t2; + _t3 = t3; + _t4 = t4; + } + + public Action Callback { get; } + + protected override void OnTick() => Callback?.Invoke(_t1, _t2, _t3, _t4); + + public override string ToString() => $"DelayStateCall[{FormatDelegate(Callback)}]"; + } + + private class DelayStateCallTimer : Timer + { + private readonly T1 _t1; + private readonly T2 _t2; + private readonly T3 _t3; + private readonly T4 _t4; + private readonly T5 _t5; + + public DelayStateCallTimer( + TimeSpan delay, TimeSpan interval, int count, Action callback, + T1 t1, T2 t2, T3 t3, T4 t4, T5 t5 + ) : base(delay, interval, count) + { + Callback = callback; + _t1 = t1; + _t2 = t2; + _t3 = t3; + _t4 = t4; + _t5 = t5; + } + + public Action Callback { get; } + + protected override void OnTick() => Callback?.Invoke(_t1, _t2, _t3, _t4, _t5); + + public override string ToString() => $"DelayStateCall[{FormatDelegate(Callback)}]"; + } + } +} From 16f65e59c6efb2cf5f7f8f2ddbf72f93a54650e8 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Tue, 7 Dec 2021 10:20:30 -0800 Subject: [PATCH 037/213] fix: Fixes VS builds by reverting back to nstd20 (#882) --- .../SerializationGenerator.csproj | 10 ++++++---- Projects/Server/Server.csproj | 2 +- Projects/UOContent/UOContent.csproj | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Projects/SerializationGenerator/SerializationGenerator.csproj b/Projects/SerializationGenerator/SerializationGenerator.csproj index 1daae2ff1..10448f42f 100755 --- a/Projects/SerializationGenerator/SerializationGenerator.csproj +++ b/Projects/SerializationGenerator/SerializationGenerator.csproj @@ -1,6 +1,6 @@ - netstandard2.1 + netstandard2.0 preview analyzers @@ -12,6 +12,7 @@ + @@ -21,9 +22,10 @@ - - - + + + + diff --git a/Projects/Server/Server.csproj b/Projects/Server/Server.csproj index 4efc9e1a9..392fccc6f 100755 --- a/Projects/Server/Server.csproj +++ b/Projects/Server/Server.csproj @@ -40,7 +40,7 @@ - TargetFramework=netstandard2.1 + TargetFramework=netstandard2.0 Analyzer false all diff --git a/Projects/UOContent/UOContent.csproj b/Projects/UOContent/UOContent.csproj index c5561de3d..06e297a52 100755 --- a/Projects/UOContent/UOContent.csproj +++ b/Projects/UOContent/UOContent.csproj @@ -47,7 +47,7 @@ - TargetFramework=netstandard2.1 + TargetFramework=netstandard2.0 Analyzer false all From aba34730308a0eb957601ddd300e96f0aaf115a5 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Thu, 9 Dec 2021 11:57:55 -0800 Subject: [PATCH 038/213] fix: Fixes divide by zero in poison spell (#883) --- Projects/UOContent/Spells/Third/Poison.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Projects/UOContent/Spells/Third/Poison.cs b/Projects/UOContent/Spells/Third/Poison.cs index 67d0e3b01..168413f25 100644 --- a/Projects/UOContent/Spells/Third/Poison.cs +++ b/Projects/UOContent/Spells/Third/Poison.cs @@ -43,7 +43,7 @@ namespace Server.Spells.Third { if (Caster.InRange(m, 2)) { - level = (Caster.Skills.Magery.Fixed + Caster.Skills.Poisoning.Fixed) / 2 switch + level = ((Caster.Skills.Magery.Fixed + Caster.Skills.Poisoning.Fixed) / 2) switch { >= 1000 => 3, > 850 => 2, From 61e217701161a5c541fb563da5b30304fe606cd7 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sat, 11 Dec 2021 09:58:24 -0800 Subject: [PATCH 039/213] fix: Fixes damage bonus and makes it easier to read (#885) --- Projects/UOContent/Items/Weapons/BaseWeapon.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Projects/UOContent/Items/Weapons/BaseWeapon.cs b/Projects/UOContent/Items/Weapons/BaseWeapon.cs index 8e183a7b9..055c23e8d 100644 --- a/Projects/UOContent/Items/Weapons/BaseWeapon.cs +++ b/Projects/UOContent/Items/Weapons/BaseWeapon.cs @@ -2395,24 +2395,24 @@ namespace Server.Items public virtual int GetDamageBonus() { - var bonus = VirtualDamageBonus; - - bonus += m_Quality switch + var quality = m_Quality switch { WeaponQuality.Low => -20, WeaponQuality.Exceptional => 20, _ => 0 }; - return bonus + m_DamageLevel switch + var damageLevel = m_DamageLevel switch { WeaponDamageLevel.Ruin => 15, WeaponDamageLevel.Might => 20, WeaponDamageLevel.Force => 25, WeaponDamageLevel.Power => 30, WeaponDamageLevel.Vanq => 35, - _ => bonus + _ => 0 }; + + return VirtualDamageBonus + quality + damageLevel; } public virtual double ScaleDamageAOS(Mobile attacker, double damage, bool checkSkills) From b125146b27b6a2a1beb7a6e6af9b758b6742fbb0 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Mon, 13 Dec 2021 09:31:02 -0800 Subject: [PATCH 040/213] fix: Adds BitArray support with codegen (#888) * Adds a custom BitArray class with the following added features: * ctor for creating BitArray against read only span * ctor for creating BitArray against BinaryReader * CopyTo to copy a BitArray to a Span * Adds BitArray to UO Primitive serialization so it can be codegenned. --- .../Rules/PrimitiveUOTypeMigrationRule.cs | 1 + .../SymbolMetadata/SymbolMetadata.UO.cs | 8 + Projects/Server/Collections/BitArray.cs | 1410 +++++++++++++++++ .../Collections/CollectionThrowStrings.cs | 48 +- .../Server/Serialization/BinaryFileReader.cs | 10 + Projects/Server/Serialization/BufferReader.cs | 14 + Projects/Server/Serialization/BufferWriter.cs | 11 + .../Server/Serialization/IGenericReader.cs | 3 + .../Server/Serialization/IGenericWriter.cs | 3 + 9 files changed, 1489 insertions(+), 19 deletions(-) create mode 100644 Projects/Server/Collections/BitArray.cs diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/PrimitiveUOTypeMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/PrimitiveUOTypeMigrationRule.cs index ec3562317..9d60ca27e 100644 --- a/Projects/SerializationGenerator/SerializableMigration/Rules/PrimitiveUOTypeMigrationRule.cs +++ b/Projects/SerializationGenerator/SerializableMigration/Rules/PrimitiveUOTypeMigrationRule.cs @@ -43,6 +43,7 @@ namespace SerializableMigration _ when symbol.IsRectangle3D(compilation) => new[] { "Rect3D" }, _ when symbol.IsRace(compilation) => new[] { "Race" }, _ when symbol.IsMap(compilation) => new[] { "Map" }, + _ when symbol.IsBitArray(compilation) => new[] { "BitArray" }, _ => null }; diff --git a/Projects/SerializationGenerator/SourceGeneration/SymbolMetadata/SymbolMetadata.UO.cs b/Projects/SerializationGenerator/SourceGeneration/SymbolMetadata/SymbolMetadata.UO.cs index 9b88b7493..2fdf8793c 100644 --- a/Projects/SerializationGenerator/SourceGeneration/SymbolMetadata/SymbolMetadata.UO.cs +++ b/Projects/SerializationGenerator/SourceGeneration/SymbolMetadata/SymbolMetadata.UO.cs @@ -47,6 +47,8 @@ namespace SerializationGenerator public const string SERIALIZABLE_FIELD_SAVE_FLAG_ATTRIBUTE = "Server.SerializableFieldSaveFlagAttribute"; public const string SERIALIZABLE_FIELD_DEFAULT_ATTRIBUTE = "Server.SerializableFieldDefaultAttribute"; public const string RAW_SERIALIZABLE_INTERFACE = "Server.IRawSerializable"; + // ModernUO modified BitArray + public const string SERVER_BITARRAY_CLASS = "Server.Collections.BitArray"; public static bool IsTimerDrift(this AttributeData attr, Compilation compilation) => attr?.IsAttribute(compilation.GetTypeByMetadataName(TIMER_DRIFT_ATTRIBUTE)) == true; @@ -184,6 +186,12 @@ namespace SerializationGenerator SymbolEqualityComparer.Default ); + public static bool IsBitArray(this ISymbol symbol, Compilation compilation) => + symbol.Equals( + compilation.GetTypeByMetadataName(SERVER_BITARRAY_CLASS), + SymbolEqualityComparer.Default + ); + public static AttributeData? GetAttribute(this ISymbol symbol, ISymbol attrSymbol) => symbol .GetAttributes() diff --git a/Projects/Server/Collections/BitArray.cs b/Projects/Server/Collections/BitArray.cs new file mode 100644 index 000000000..9df8f5441 --- /dev/null +++ b/Projects/Server/Collections/BitArray.cs @@ -0,0 +1,1410 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Buffers.Binary; +using System.Diagnostics; +using System.Runtime.CompilerServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; +using System.Runtime.Intrinsics.Arm; +using System.Collections; +using System.IO; + +namespace Server.Collections; + +// A vector of bits. Use this to store bits efficiently, without having to do bit +// shifting yourself. +[System.Serializable] +public sealed class BitArray : ICollection, ICloneable +{ + private int[] m_array; // Do not rename (binary serialization) + private int m_length; // Do not rename (binary serialization) + private int _version; // Do not rename (binary serialization) + + private const int _ShrinkThreshold = 256; + + /*========================================================================= + ** Allocates space to hold length bit values. All of the values in the bit + ** array are set to defaultValue. + ** + ** Exceptions: ArgumentOutOfRangeException if length < 0. + =========================================================================*/ + public BitArray(int length, bool defaultValue = false) + { + if (length < 0) + { + throw new ArgumentOutOfRangeException(nameof(length), length, CollectionThrowStrings.ArgumentOutOfRange_NeedNonNegNum); + } + + m_array = new int[GetInt32ArrayLengthFromBitLength(length)]; + m_length = length; + + if (defaultValue) + { + Array.Fill(m_array, -1); + + // clear high bit values in the last int + Div32Rem(length, out int extraBits); + if (extraBits > 0) + { + m_array[^1] = (1 << extraBits) - 1; + } + } + + _version = 0; + } + + /*========================================================================= + ** Allocates space to hold the bit values in bytes. bytes[0] represents + ** bits 0 - 7, bytes[1] represents bits 8 - 15, etc. The LSB of each byte + ** represents the lowest index value; bytes[0] & 1 represents bit 0, + ** bytes[0] & 2 represents bit 1, bytes[0] & 4 represents bit 2, etc. + ** + ** Exceptions: ArgumentException if bytes == null. + =========================================================================*/ + public BitArray(byte[] bytes) + { + if (bytes == null) + { + throw new ArgumentNullException(nameof(bytes)); + } + + // this value is chosen to prevent overflow when computing m_length. + // m_length is of type int32 and is exposed as a property, so + // type of m_length can't be changed to accommodate. + if (bytes.Length > int.MaxValue / BitsPerByte) + { + throw new ArgumentException(string.Format(CollectionThrowStrings.Argument_ArrayTooLarge, BitsPerByte), nameof(bytes)); + } + + m_array = new int[GetInt32ArrayLengthFromByteLength(bytes.Length)]; + m_length = bytes.Length * BitsPerByte; + + uint totalCount = (uint)bytes.Length / 4; + + ReadOnlySpan byteSpan = bytes; + for (int i = 0; i < totalCount; i++) + { + m_array[i] = BinaryPrimitives.ReadInt32LittleEndian(byteSpan); + byteSpan = byteSpan[4..]; + } + + Debug.Assert(byteSpan.Length >= 0 && byteSpan.Length < 4); + + int last = 0; + switch (byteSpan.Length) + { + case 3: + last = byteSpan[2] << 16; + goto case 2; + // fall through + case 2: + last |= byteSpan[1] << 8; + goto case 1; + // fall through + case 1: + m_array[totalCount] = last | byteSpan[0]; + break; + } + + _version = 0; + } + + /*========================================================================= + ** Allocates space to hold the bit values in bytes. bytes[0] represents + ** bits 0 - 7, bytes[1] represents bits 8 - 15, etc. The LSB of each byte + ** represents the lowest index value; bytes[0] & 1 represents bit 0, + ** bytes[0] & 2 represents bit 1, bytes[0] & 4 represents bit 2, etc. + ** + ** Exceptions: ArgumentException if bytes == null. + =========================================================================*/ + public BitArray(ReadOnlySpan bytes) + { + if (bytes == null) + { + throw new ArgumentNullException(nameof(bytes)); + } + + // this value is chosen to prevent overflow when computing m_length. + // m_length is of type int32 and is exposed as a property, so + // type of m_length can't be changed to accommodate. + if (bytes.Length > int.MaxValue / BitsPerByte) + { + throw new ArgumentException(string.Format(CollectionThrowStrings.Argument_ArrayTooLarge, BitsPerByte), nameof(bytes)); + } + + m_array = new int[GetInt32ArrayLengthFromByteLength(bytes.Length)]; + m_length = bytes.Length * BitsPerByte; + + uint totalCount = (uint)bytes.Length / 4; + + ReadOnlySpan byteSpan = bytes; + for (int i = 0; i < totalCount; i++) + { + m_array[i] = BinaryPrimitives.ReadInt32LittleEndian(byteSpan); + byteSpan = byteSpan[4..]; + } + + Debug.Assert(byteSpan.Length >= 0 && byteSpan.Length < 4); + + int last = 0; + switch (byteSpan.Length) + { + case 3: + last = byteSpan[2] << 16; + goto case 2; + // fall through + case 2: + last |= byteSpan[1] << 8; + goto case 1; + // fall through + case 1: + m_array[totalCount] = last | byteSpan[0]; + break; + } + + _version = 0; + } + + /*========================================================================= + ** Allocates space to hold the bit values in bytes. bytes[0] represents + ** bits 0 - 7, bytes[1] represents bits 8 - 15, etc. The LSB of each byte + ** represents the lowest index value; bytes[0] & 1 represents bit 0, + ** bytes[0] & 2 represents bit 1, bytes[0] & 4 represents bit 2, etc. + ** + ** Exceptions: ArgumentException if bytes == null. + =========================================================================*/ + public BitArray(BinaryReader reader, int length) + { + if (reader == null) + { + throw new ArgumentNullException(nameof(reader)); + } + + // this value is chosen to prevent overflow when computing m_length. + // m_length is of type int32 and is exposed as a property, so + // type of m_length can't be changed to accommodate. + if (length > int.MaxValue / BitsPerByte) + { + throw new ArgumentException(string.Format(CollectionThrowStrings.Argument_ArrayTooLarge, BitsPerByte), nameof(reader)); + } + + m_array = new int[GetInt32ArrayLengthFromByteLength(length)]; + m_length = length * BitsPerByte; + + uint totalCount = (uint)length / 4; + + for (int i = 0; i < totalCount; i++) + { + m_array[i] = reader.ReadInt32(); + length -= 4; + } + + Debug.Assert(length >= 0 && length < 4); + + int last = 0; + switch (length) + { + case 3: + last = reader.ReadInt16(); + goto case 2; + // fall through + case 2: + last |= reader.ReadByte(); + goto case 1; + // fall through + case 1: + m_array[totalCount] = last | reader.ReadByte(); + break; + } + + _version = 0; + } + + private const uint Vector128ByteCount = 16; + private const uint Vector128IntCount = 4; + private const uint Vector256ByteCount = 32; + private const uint Vector256IntCount = 8; + public unsafe BitArray(bool[] values) + { + if (values == null) + { + throw new ArgumentNullException(nameof(values)); + } + + m_array = new int[GetInt32ArrayLengthFromBitLength(values.Length)]; + m_length = values.Length; + + uint i = 0; + + if (values.Length < Vector256.Count) + { + goto LessThan32; + } + + // Comparing with 1s would get rid of the final negation, however this would not work for some CLR bools + // (true for any non-zero values, false for 0) - any values between 2-255 will be interpreted as false. + // Instead, We compare with zeroes (== false) then negate the result to ensure compatibility. + + if (Avx2.IsSupported) + { + // JIT does not support code hoisting for SIMD yet + Vector256 zero = Vector256.Zero; + fixed (bool* ptr = values) + { + for (; i + Vector256ByteCount <= (uint)values.Length; i += Vector256ByteCount) + { + Vector256 vector = Avx.LoadVector256((byte*)ptr + i); + Vector256 isFalse = Avx2.CompareEqual(vector, zero); + int result = Avx2.MoveMask(isFalse); + m_array[i / 32u] = ~result; + } + } + } + else if (Sse2.IsSupported) + { + // JIT does not support code hoisting for SIMD yet + Vector128 zero = Vector128.Zero; + fixed (bool* ptr = values) + { + for (; i + Vector128ByteCount * 2u <= (uint)values.Length; i += Vector128ByteCount * 2u) + { + Vector128 lowerVector = Sse2.LoadVector128((byte*)ptr + i); + Vector128 lowerIsFalse = Sse2.CompareEqual(lowerVector, zero); + int lowerPackedIsFalse = Sse2.MoveMask(lowerIsFalse); + + Vector128 upperVector = Sse2.LoadVector128((byte*)ptr + i + Vector128.Count); + Vector128 upperIsFalse = Sse2.CompareEqual(upperVector, zero); + int upperPackedIsFalse = Sse2.MoveMask(upperIsFalse); + + m_array[i / 32u] = ~((upperPackedIsFalse << 16) | lowerPackedIsFalse); + } + } + } + else if (AdvSimd.Arm64.IsSupported) + { + // JIT does not support code hoisting for SIMD yet + // However comparison against zero can be replaced to cmeq against zero (vceqzq_s8) + // See dotnet/runtime#33972 for details + Vector128 zero = Vector128.Zero; + Vector128 bitMask128 = BitConverter.IsLittleEndian ? + Vector128.Create(0x80402010_08040201).AsByte() : + Vector128.Create(0x01020408_10204080).AsByte(); + + fixed (bool* ptr = values) + { + for (; i + Vector128ByteCount * 2u <= (uint)values.Length; i += Vector128ByteCount * 2u) + { + // Same logic as SSE2 path, however we lack MoveMask (equivalent) instruction + // As a workaround, mask out the relevant bit after comparison + // and combine by ORing all of them together (In this case, adding all of them does the same thing) + Vector128 lowerVector = AdvSimd.LoadVector128((byte*)ptr + i); + Vector128 lowerIsFalse = AdvSimd.CompareEqual(lowerVector, zero); + Vector128 bitsExtracted1 = AdvSimd.And(lowerIsFalse, bitMask128); + bitsExtracted1 = AdvSimd.Arm64.AddPairwise(bitsExtracted1, bitsExtracted1); + bitsExtracted1 = AdvSimd.Arm64.AddPairwise(bitsExtracted1, bitsExtracted1); + bitsExtracted1 = AdvSimd.Arm64.AddPairwise(bitsExtracted1, bitsExtracted1); + Vector128 lowerPackedIsFalse = bitsExtracted1.AsInt16(); + + Vector128 upperVector = AdvSimd.LoadVector128((byte*)ptr + i + Vector128.Count); + Vector128 upperIsFalse = AdvSimd.CompareEqual(upperVector, zero); + Vector128 bitsExtracted2 = AdvSimd.And(upperIsFalse, bitMask128); + bitsExtracted2 = AdvSimd.Arm64.AddPairwise(bitsExtracted2, bitsExtracted2); + bitsExtracted2 = AdvSimd.Arm64.AddPairwise(bitsExtracted2, bitsExtracted2); + bitsExtracted2 = AdvSimd.Arm64.AddPairwise(bitsExtracted2, bitsExtracted2); + Vector128 upperPackedIsFalse = bitsExtracted2.AsInt16(); + + int result = AdvSimd.Arm64.ZipLow(lowerPackedIsFalse, upperPackedIsFalse).AsInt32().ToScalar(); + if (!BitConverter.IsLittleEndian) + { + result = BinaryPrimitives.ReverseEndianness(result); + } + m_array[i / 32u] = ~result; + } + } + } + + LessThan32: + for (; i < (uint)values.Length; i++) + { + if (values[i]) + { + int elementIndex = Div32Rem((int)i, out int extraBits); + m_array[elementIndex] |= 1 << extraBits; + } + } + + _version = 0; + } + + /*========================================================================= + ** Allocates space to hold the bit values in values. values[0] represents + ** bits 0 - 31, values[1] represents bits 32 - 63, etc. The LSB of each + ** integer represents the lowest index value; values[0] & 1 represents bit + ** 0, values[0] & 2 represents bit 1, values[0] & 4 represents bit 2, etc. + ** + ** Exceptions: ArgumentException if values == null. + =========================================================================*/ + public BitArray(int[] values) + { + if (values == null) + { + throw new ArgumentNullException(nameof(values)); + } + + // this value is chosen to prevent overflow when computing m_length + if (values.Length > int.MaxValue / BitsPerInt32) + { + throw new ArgumentException(string.Format(CollectionThrowStrings.Argument_ArrayTooLarge, BitsPerInt32), nameof(values)); + } + + m_array = new int[values.Length]; + Array.Copy(values, m_array, values.Length); + m_length = values.Length * BitsPerInt32; + + _version = 0; + } + + /*========================================================================= + ** Allocates a new BitArray with the same length and bit values as bits. + ** + ** Exceptions: ArgumentException if bits == null. + =========================================================================*/ + public BitArray(BitArray bits) + { + if (bits == null) + { + throw new ArgumentNullException(nameof(bits)); + } + + int arrayLength = GetInt32ArrayLengthFromBitLength(bits.m_length); + + m_array = new int[arrayLength]; + + Debug.Assert(bits.m_array.Length <= arrayLength); + + Array.Copy(bits.m_array, m_array, arrayLength); + m_length = bits.m_length; + + _version = bits._version; + } + + public bool this[int index] + { + get => Get(index); + set => Set(index, value); + } + + /*========================================================================= + ** Returns the bit value at position index. + ** + ** Exceptions: ArgumentOutOfRangeException if index < 0 or + ** index >= GetLength(). + =========================================================================*/ + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Get(int index) + { + if ((uint)index >= (uint)m_length) + { + ThrowArgumentOutOfRangeException(index); + } + + return (m_array[index >> 5] & (1 << index)) != 0; + } + + /*========================================================================= + ** Sets the bit value at position index to value. + ** + ** Exceptions: ArgumentOutOfRangeException if index < 0 or + ** index >= GetLength(). + =========================================================================*/ + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Set(int index, bool value) + { + if ((uint)index >= (uint)m_length) + { + ThrowArgumentOutOfRangeException(index); + } + + int bitMask = 1 << index; + ref int segment = ref m_array[index >> 5]; + + if (value) + { + segment |= bitMask; + } + else + { + segment &= ~bitMask; + } + + _version++; + } + + /*========================================================================= + ** Sets all the bit values to value. + =========================================================================*/ + public void SetAll(bool value) + { + int arrayLength = GetInt32ArrayLengthFromBitLength(Length); + Span span = m_array.AsSpan(0, arrayLength); + if (value) + { + span.Fill(-1); + + // clear high bit values in the last int + Div32Rem(m_length, out int extraBits); + if (extraBits > 0) + { + span[^1] &= (1 << extraBits) - 1; + } + } + else + { + span.Clear(); + } + + _version++; + } + + /*========================================================================= + ** Returns a reference to the current instance ANDed with value. + ** + ** Exceptions: ArgumentException if value == null or + ** value.Length != this.Length. + =========================================================================*/ + public unsafe BitArray And(BitArray value) + { + if (value == null) + { + throw new ArgumentNullException(nameof(value)); + } + + // This method uses unsafe code to manipulate data in the BitArrays. To avoid issues with + // buggy code concurrently mutating these instances in a way that could cause memory corruption, + // we snapshot the arrays from both and then operate only on those snapshots, while also validating + // that the count we iterate to is within the bounds of both arrays. We don't care about such code + // corrupting the BitArray data in a way that produces incorrect answers, since BitArray is not meant + // to be thread-safe; we only care about avoiding buffer overruns. + int[] thisArray = m_array; + int[] valueArray = value.m_array; + + int count = GetInt32ArrayLengthFromBitLength(Length); + if (Length != value.Length || (uint)count > (uint)thisArray.Length || (uint)count > (uint)valueArray.Length) + { + throw new ArgumentException(CollectionThrowStrings.Arg_ArrayLengthsDiffer); + } + + // Unroll loop for count less than Vector256 size. + switch (count) + { + case 7: thisArray[6] &= valueArray[6]; goto case 6; + case 6: thisArray[5] &= valueArray[5]; goto case 5; + case 5: thisArray[4] &= valueArray[4]; goto case 4; + case 4: thisArray[3] &= valueArray[3]; goto case 3; + case 3: thisArray[2] &= valueArray[2]; goto case 2; + case 2: thisArray[1] &= valueArray[1]; goto case 1; + case 1: thisArray[0] &= valueArray[0]; goto Done; + case 0: goto Done; + } + + uint i = 0; + if (Avx2.IsSupported) + { + fixed (int* leftPtr = thisArray) + { + fixed (int* rightPtr = valueArray) + { + for (; i < (uint)count - (Vector256IntCount - 1u); i += Vector256IntCount) + { + Vector256 leftVec = Avx.LoadVector256(leftPtr + i); + Vector256 rightVec = Avx.LoadVector256(rightPtr + i); + Avx.Store(leftPtr + i, Avx2.And(leftVec, rightVec)); + } + } + } + } + else if (Sse2.IsSupported) + { + fixed (int* leftPtr = thisArray) + { + fixed (int* rightPtr = valueArray) + { + for (; i < (uint)count - (Vector128IntCount - 1u); i += Vector128IntCount) + { + Vector128 leftVec = Sse2.LoadVector128(leftPtr + i); + Vector128 rightVec = Sse2.LoadVector128(rightPtr + i); + Sse2.Store(leftPtr + i, Sse2.And(leftVec, rightVec)); + } + } + } + } + else if (AdvSimd.IsSupported) + { + fixed (int* leftPtr = thisArray) + { + fixed (int* rightPtr = valueArray) + { + for (; i < (uint)count - (Vector128IntCount - 1u); i += Vector128IntCount) + { + Vector128 leftVec = AdvSimd.LoadVector128(leftPtr + i); + Vector128 rightVec = AdvSimd.LoadVector128(rightPtr + i); + AdvSimd.Store(leftPtr + i, AdvSimd.And(leftVec, rightVec)); + } + } + } + } + + for (; i < (uint)count; i++) + { + thisArray[i] &= valueArray[i]; + } + + Done: + _version++; + return this; + } + + /*========================================================================= + ** Returns a reference to the current instance ORed with value. + ** + ** Exceptions: ArgumentException if value == null or + ** value.Length != this.Length. + =========================================================================*/ + public unsafe BitArray Or(BitArray value) + { + if (value == null) + { + throw new ArgumentNullException(nameof(value)); + } + + // This method uses unsafe code to manipulate data in the BitArrays. To avoid issues with + // buggy code concurrently mutating these instances in a way that could cause memory corruption, + // we snapshot the arrays from both and then operate only on those snapshots, while also validating + // that the count we iterate to is within the bounds of both arrays. We don't care about such code + // corrupting the BitArray data in a way that produces incorrect answers, since BitArray is not meant + // to be thread-safe; we only care about avoiding buffer overruns. + int[] thisArray = m_array; + int[] valueArray = value.m_array; + + int count = GetInt32ArrayLengthFromBitLength(Length); + if (Length != value.Length || (uint)count > (uint)thisArray.Length || (uint)count > (uint)valueArray.Length) + { + throw new ArgumentException(CollectionThrowStrings.Arg_ArrayLengthsDiffer); + } + + // Unroll loop for count less than Vector256 size. + switch (count) + { + case 7: thisArray[6] |= valueArray[6]; goto case 6; + case 6: thisArray[5] |= valueArray[5]; goto case 5; + case 5: thisArray[4] |= valueArray[4]; goto case 4; + case 4: thisArray[3] |= valueArray[3]; goto case 3; + case 3: thisArray[2] |= valueArray[2]; goto case 2; + case 2: thisArray[1] |= valueArray[1]; goto case 1; + case 1: thisArray[0] |= valueArray[0]; goto Done; + case 0: goto Done; + } + + uint i = 0; + if (Avx2.IsSupported) + { + fixed (int* leftPtr = thisArray) + { + fixed (int* rightPtr = valueArray) + { + for (; i < (uint)count - (Vector256IntCount - 1u); i += Vector256IntCount) + { + Vector256 leftVec = Avx.LoadVector256(leftPtr + i); + Vector256 rightVec = Avx.LoadVector256(rightPtr + i); + Avx.Store(leftPtr + i, Avx2.Or(leftVec, rightVec)); + } + } + } + } + else if (Sse2.IsSupported) + { + fixed (int* leftPtr = thisArray) + { + fixed (int* rightPtr = valueArray) + { + for (; i < (uint)count - (Vector128IntCount - 1u); i += Vector128IntCount) + { + Vector128 leftVec = Sse2.LoadVector128(leftPtr + i); + Vector128 rightVec = Sse2.LoadVector128(rightPtr + i); + Sse2.Store(leftPtr + i, Sse2.Or(leftVec, rightVec)); + } + } + } + } + else if (AdvSimd.IsSupported) + { + fixed (int* leftPtr = thisArray) + { + fixed (int* rightPtr = valueArray) + { + for (; i < (uint)count - (Vector128IntCount - 1u); i += Vector128IntCount) + { + Vector128 leftVec = AdvSimd.LoadVector128(leftPtr + i); + Vector128 rightVec = AdvSimd.LoadVector128(rightPtr + i); + AdvSimd.Store(leftPtr + i, AdvSimd.Or(leftVec, rightVec)); + } + } + } + } + + for (; i < (uint)count; i++) + { + thisArray[i] |= valueArray[i]; + } + + Done: + _version++; + return this; + } + + /*========================================================================= + ** Returns a reference to the current instance XORed with value. + ** + ** Exceptions: ArgumentException if value == null or + ** value.Length != this.Length. + =========================================================================*/ + public unsafe BitArray Xor(BitArray value) + { + if (value == null) + { + throw new ArgumentNullException(nameof(value)); + } + + // This method uses unsafe code to manipulate data in the BitArrays. To avoid issues with + // buggy code concurrently mutating these instances in a way that could cause memory corruption, + // we snapshot the arrays from both and then operate only on those snapshots, while also validating + // that the count we iterate to is within the bounds of both arrays. We don't care about such code + // corrupting the BitArray data in a way that produces incorrect answers, since BitArray is not meant + // to be thread-safe; we only care about avoiding buffer overruns. + int[] thisArray = m_array; + int[] valueArray = value.m_array; + + int count = GetInt32ArrayLengthFromBitLength(Length); + if (Length != value.Length || (uint)count > (uint)thisArray.Length || (uint)count > (uint)valueArray.Length) + { + throw new ArgumentException(CollectionThrowStrings.Arg_ArrayLengthsDiffer); + } + + // Unroll loop for count less than Vector256 size. + switch (count) + { + case 7: thisArray[6] ^= valueArray[6]; goto case 6; + case 6: thisArray[5] ^= valueArray[5]; goto case 5; + case 5: thisArray[4] ^= valueArray[4]; goto case 4; + case 4: thisArray[3] ^= valueArray[3]; goto case 3; + case 3: thisArray[2] ^= valueArray[2]; goto case 2; + case 2: thisArray[1] ^= valueArray[1]; goto case 1; + case 1: thisArray[0] ^= valueArray[0]; goto Done; + case 0: goto Done; + } + + uint i = 0; + if (Avx2.IsSupported) + { + fixed (int* leftPtr = m_array) + { + fixed (int* rightPtr = value.m_array) + { + for (; i < (uint)count - (Vector256IntCount - 1u); i += Vector256IntCount) + { + Vector256 leftVec = Avx.LoadVector256(leftPtr + i); + Vector256 rightVec = Avx.LoadVector256(rightPtr + i); + Avx.Store(leftPtr + i, Avx2.Xor(leftVec, rightVec)); + } + } + } + } + else if (Sse2.IsSupported) + { + fixed (int* leftPtr = thisArray) + { + fixed (int* rightPtr = valueArray) + { + for (; i < (uint)count - (Vector128IntCount - 1u); i += Vector128IntCount) + { + Vector128 leftVec = Sse2.LoadVector128(leftPtr + i); + Vector128 rightVec = Sse2.LoadVector128(rightPtr + i); + Sse2.Store(leftPtr + i, Sse2.Xor(leftVec, rightVec)); + } + } + } + } + else if (AdvSimd.IsSupported) + { + fixed (int* leftPtr = thisArray) + { + fixed (int* rightPtr = valueArray) + { + for (; i < (uint)count - (Vector128IntCount - 1u); i += Vector128IntCount) + { + Vector128 leftVec = AdvSimd.LoadVector128(leftPtr + i); + Vector128 rightVec = AdvSimd.LoadVector128(rightPtr + i); + AdvSimd.Store(leftPtr + i, AdvSimd.Xor(leftVec, rightVec)); + } + } + } + } + + for (; i < (uint)count; i++) + { + thisArray[i] ^= valueArray[i]; + } + + Done: + _version++; + return this; + } + + /*========================================================================= + ** Inverts all the bit values. On/true bit values are converted to + ** off/false. Off/false bit values are turned on/true. The current instance + ** is updated and returned. + =========================================================================*/ + public unsafe BitArray Not() + { + // This method uses unsafe code to manipulate data in the BitArray. To avoid issues with + // buggy code concurrently mutating this instance in a way that could cause memory corruption, + // we snapshot the array then operate only on this snapshot. We don't care about such code + // corrupting the BitArray data in a way that produces incorrect answers, since BitArray is not meant + // to be thread-safe; we only care about avoiding buffer overruns. + int[] thisArray = m_array; + + int count = GetInt32ArrayLengthFromBitLength(Length); + + // Unroll loop for count less than Vector256 size. + switch (count) + { + case 7: thisArray[6] = ~thisArray[6]; goto case 6; + case 6: thisArray[5] = ~thisArray[5]; goto case 5; + case 5: thisArray[4] = ~thisArray[4]; goto case 4; + case 4: thisArray[3] = ~thisArray[3]; goto case 3; + case 3: thisArray[2] = ~thisArray[2]; goto case 2; + case 2: thisArray[1] = ~thisArray[1]; goto case 1; + case 1: thisArray[0] = ~thisArray[0]; goto Done; + case 0: goto Done; + } + + uint i = 0; + if (Avx2.IsSupported) + { + Vector256 ones = Vector256.Create(-1); + fixed (int* ptr = thisArray) + { + for (; i < (uint)count - (Vector256IntCount - 1u); i += Vector256IntCount) + { + Vector256 vec = Avx.LoadVector256(ptr + i); + Avx.Store(ptr + i, Avx2.Xor(vec, ones)); + } + } + } + else if (Sse2.IsSupported) + { + Vector128 ones = Vector128.Create(-1); + fixed (int* ptr = thisArray) + { + for (; i < (uint)count - (Vector128IntCount - 1u); i += Vector128IntCount) + { + Vector128 vec = Sse2.LoadVector128(ptr + i); + Sse2.Store(ptr + i, Sse2.Xor(vec, ones)); + } + } + } + else if (AdvSimd.IsSupported) + { + fixed (int* leftPtr = thisArray) + { + for (; i < (uint)count - (Vector128IntCount - 1u); i += Vector128IntCount) + { + Vector128 leftVec = AdvSimd.LoadVector128(leftPtr + i); + AdvSimd.Store(leftPtr + i, AdvSimd.Not(leftVec)); + } + } + } + + for (; i < (uint)count; i++) + { + thisArray[i] = ~thisArray[i]; + } + + Done: + _version++; + return this; + } + + /*========================================================================= + ** Shift all the bit values to right on count bits. The current instance is + ** updated and returned. + * + ** Exceptions: ArgumentOutOfRangeException if count < 0 + =========================================================================*/ + public BitArray RightShift(int count) + { + if (count <= 0) + { + if (count < 0) + { + throw new ArgumentOutOfRangeException(nameof(count), count, CollectionThrowStrings.ArgumentOutOfRange_NeedNonNegNum); + } + + _version++; + return this; + } + + int toIndex = 0; + int ints = GetInt32ArrayLengthFromBitLength(m_length); + if (count < m_length) + { + // We can not use Math.DivRem without taking a dependency on System.Runtime.Extensions + int fromIndex = Div32Rem(count, out int shiftCount); + Div32Rem(m_length, out int extraBits); + if (shiftCount == 0) + { + unchecked + { + // Cannot use `(1u << extraBits) - 1u` as the mask + // because for extraBits == 0, we need the mask to be 111...111, not 0. + // In that case, we are shifting a uint by 32, which could be considered undefined. + // The result of a shift operation is undefined ... if the right operand + // is greater than or equal to the width in bits of the promoted left operand, + // https://docs.microsoft.com/en-us/cpp/c-language/bitwise-shift-operators?view=vs-2017 + // However, the compiler protects us from undefined behaviour by constraining the + // right operand to between 0 and width - 1 (inclusive), i.e. right_operand = (right_operand % width). + uint mask = uint.MaxValue >> (BitsPerInt32 - extraBits); + m_array[ints - 1] &= (int)mask; + } + Array.Copy(m_array, fromIndex, m_array, 0, ints - fromIndex); + toIndex = ints - fromIndex; + } + else + { + int lastIndex = ints - 1; + unchecked + { + while (fromIndex < lastIndex) + { + uint right = (uint)m_array[fromIndex] >> shiftCount; + int left = m_array[++fromIndex] << (BitsPerInt32 - shiftCount); + m_array[toIndex++] = left | (int)right; + } + uint mask = uint.MaxValue >> (BitsPerInt32 - extraBits); + mask &= (uint)m_array[fromIndex]; + m_array[toIndex++] = (int)(mask >> shiftCount); + } + } + } + + m_array.AsSpan(toIndex, ints - toIndex).Clear(); + _version++; + return this; + } + + /*========================================================================= + ** Shift all the bit values to left on count bits. The current instance is + ** updated and returned. + * + ** Exceptions: ArgumentOutOfRangeException if count < 0 + =========================================================================*/ + public BitArray LeftShift(int count) + { + if (count <= 0) + { + if (count < 0) + { + throw new ArgumentOutOfRangeException(nameof(count), count, CollectionThrowStrings.ArgumentOutOfRange_NeedNonNegNum); + } + + _version++; + return this; + } + + int lengthToClear; + if (count < m_length) + { + int lastIndex = (m_length - 1) >> BitShiftPerInt32; // Divide by 32. + + // We can not use Math.DivRem without taking a dependency on System.Runtime.Extensions + lengthToClear = Div32Rem(count, out int shiftCount); + + if (shiftCount == 0) + { + Array.Copy(m_array, 0, m_array, lengthToClear, lastIndex + 1 - lengthToClear); + } + else + { + int fromindex = lastIndex - lengthToClear; + unchecked + { + while (fromindex > 0) + { + int left = m_array[fromindex] << shiftCount; + uint right = (uint)m_array[--fromindex] >> (BitsPerInt32 - shiftCount); + m_array[lastIndex] = left | (int)right; + lastIndex--; + } + m_array[lastIndex] = m_array[fromindex] << shiftCount; + } + } + } + else + { + lengthToClear = GetInt32ArrayLengthFromBitLength(m_length); // Clear all + } + + m_array.AsSpan(0, lengthToClear).Clear(); + _version++; + return this; + } + + public int Length + { + get + { + return m_length; + } + set + { + if (value < 0) + { + throw new ArgumentOutOfRangeException(nameof(value), value, CollectionThrowStrings.ArgumentOutOfRange_NeedNonNegNum); + } + + int newints = GetInt32ArrayLengthFromBitLength(value); + if (newints > m_array.Length || newints + _ShrinkThreshold < m_array.Length) + { + // grow or shrink (if wasting more than _ShrinkThreshold ints) + Array.Resize(ref m_array, newints); + } + + if (value > m_length) + { + // clear high bit values in the last int + int last = (m_length - 1) >> BitShiftPerInt32; + Div32Rem(m_length, out int bits); + if (bits > 0) + { + m_array[last] &= (1 << bits) - 1; + } + + // clear remaining int values + m_array.AsSpan(last + 1, newints - last - 1).Clear(); + } + + m_length = value; + _version++; + } + } + + public void CopyTo(Span span) + { + int arrayLength = GetByteArrayLengthFromBitLength(m_length); + if (span.Length < arrayLength) + { + throw new ArgumentException(CollectionThrowStrings.Argument_InvalidOffLen); + } + + // equivalent to m_length % BitsPerByte, since BitsPerByte is a power of 2 + uint extraBits = (uint)m_length & (BitsPerByte - 1); + if (extraBits > 0) + { + // last byte is not aligned, we will directly copy one less byte + arrayLength -= 1; + } + + int quotient = Div4Rem(arrayLength, out int remainder); + for (int i = 0; i < quotient; i++) + { + BinaryPrimitives.WriteInt32LittleEndian(span, m_array[i]); + span = span[4..]; + } + + if (extraBits > 0) + { + Debug.Assert(span.Length > 0); + Debug.Assert(m_array.Length > quotient); + // mask the final byte + span[remainder] = (byte)((m_array[quotient] >> (remainder * 8)) & ((1 << (int)extraBits) - 1)); + } + + switch (remainder) + { + case 3: + span[2] = (byte)(m_array[quotient] >> 16); + goto case 2; + // fall through + case 2: + span[1] = (byte)(m_array[quotient] >> 8); + goto case 1; + // fall through + case 1: + span[0] = (byte)m_array[quotient]; + break; + } + } + + public unsafe void CopyTo(Array array, int index) + { + if (array == null) + { + throw new ArgumentNullException(nameof(array)); + } + + if (index < 0) + { + throw new ArgumentOutOfRangeException(nameof(index), index, CollectionThrowStrings.ArgumentOutOfRange_NeedNonNegNum); + } + + if (array.Rank != 1) + { + throw new ArgumentException(CollectionThrowStrings.Arg_RankMultiDimNotSupported, nameof(array)); + } + + if (array is int[] intArray) + { + Div32Rem(m_length, out int extraBits); + + if (extraBits == 0) + { + // we have perfect bit alignment, no need to sanitize, just copy + Array.Copy(m_array, 0, intArray, index, m_array.Length); + } + else + { + int last = (m_length - 1) >> BitShiftPerInt32; + // do not copy the last int, as it is not completely used + Array.Copy(m_array, 0, intArray, index, last); + + // the last int needs to be masked + intArray[index + last] = m_array[last] & unchecked((1 << extraBits) - 1); + } + } + else if (array is byte[] byteArray) + { + int arrayLength = GetByteArrayLengthFromBitLength(m_length); + if (array.Length - index < arrayLength) + { + throw new ArgumentException(CollectionThrowStrings.Argument_InvalidOffLen); + } + + // equivalent to m_length % BitsPerByte, since BitsPerByte is a power of 2 + uint extraBits = (uint)m_length & (BitsPerByte - 1); + if (extraBits > 0) + { + // last byte is not aligned, we will directly copy one less byte + arrayLength -= 1; + } + + Span span = byteArray.AsSpan(index); + + int quotient = Div4Rem(arrayLength, out int remainder); + for (int i = 0; i < quotient; i++) + { + BinaryPrimitives.WriteInt32LittleEndian(span, m_array[i]); + span = span[4..]; + } + + if (extraBits > 0) + { + Debug.Assert(span.Length > 0); + Debug.Assert(m_array.Length > quotient); + // mask the final byte + span[remainder] = (byte)((m_array[quotient] >> (remainder * 8)) & ((1 << (int)extraBits) - 1)); + } + + switch (remainder) + { + case 3: + span[2] = (byte)(m_array[quotient] >> 16); + goto case 2; + // fall through + case 2: + span[1] = (byte)(m_array[quotient] >> 8); + goto case 1; + // fall through + case 1: + span[0] = (byte)m_array[quotient]; + break; + } + } + else if (array is bool[] boolArray) + { + if (array.Length - index < m_length) + { + throw new ArgumentException(CollectionThrowStrings.Argument_InvalidOffLen); + } + + uint i = 0; + + if (m_length < BitsPerInt32) + { + goto LessThan32; + } + + // The mask used when shuffling a single int into Vector128/256. + // On little endian machines, the lower 8 bits of int belong in the first byte, next lower 8 in the second and so on. + // We place the bytes that contain the bits to its respective byte so that we can mask out only the relevant bits later. + Vector128 lowerShuffleMask_CopyToBoolArray = Vector128.Create(0, 0x01010101_01010101).AsByte(); + Vector128 upperShuffleMask_CopyToBoolArray = Vector128.Create(0x02020202_02020202, 0x03030303_03030303).AsByte(); + + if (Avx2.IsSupported) + { + Vector256 shuffleMask = Vector256.Create(lowerShuffleMask_CopyToBoolArray, upperShuffleMask_CopyToBoolArray); + Vector256 bitMask = Vector256.Create(0x80402010_08040201).AsByte(); + Vector256 ones = Vector256.Create((byte)1); + + fixed (bool* destination = &boolArray[index]) + { + for (; i + Vector256ByteCount <= (uint)m_length; i += Vector256ByteCount) + { + int bits = m_array[i / BitsPerInt32]; + Vector256 scalar = Vector256.Create(bits); + Vector256 shuffled = Avx2.Shuffle(scalar.AsByte(), shuffleMask); + Vector256 extracted = Avx2.And(shuffled, bitMask); + + // The extracted bits can be anywhere between 0 and 255, so we normalise the value to either 0 or 1 + // to ensure compatibility with "C# bool" (0 for false, 1 for true, rest undefined) + Vector256 normalized = Avx2.Min(extracted, ones); + Avx.Store((byte*)destination + i, normalized); + } + } + } + else if (Ssse3.IsSupported) + { + Vector128 lowerShuffleMask = lowerShuffleMask_CopyToBoolArray; + Vector128 upperShuffleMask = upperShuffleMask_CopyToBoolArray; + Vector128 ones = Vector128.Create((byte)1); + Vector128 bitMask128 = BitConverter.IsLittleEndian ? + Vector128.Create(0x80402010_08040201).AsByte() : + Vector128.Create(0x01020408_10204080).AsByte(); + + fixed (bool* destination = &boolArray[index]) + { + for (; i + Vector128ByteCount * 2u <= (uint)m_length; i += Vector128ByteCount * 2u) + { + int bits = m_array[i / BitsPerInt32]; + Vector128 scalar = Vector128.CreateScalarUnsafe(bits); + + Vector128 shuffledLower = Ssse3.Shuffle(scalar.AsByte(), lowerShuffleMask); + Vector128 extractedLower = Sse2.And(shuffledLower, bitMask128); + Vector128 normalizedLower = Sse2.Min(extractedLower, ones); + Sse2.Store((byte*)destination + i, normalizedLower); + + Vector128 shuffledHigher = Ssse3.Shuffle(scalar.AsByte(), upperShuffleMask); + Vector128 extractedHigher = Sse2.And(shuffledHigher, bitMask128); + Vector128 normalizedHigher = Sse2.Min(extractedHigher, ones); + Sse2.Store((byte*)destination + i + Vector128.Count, normalizedHigher); + } + } + } + else if (AdvSimd.IsSupported) + { + Vector128 ones = Vector128.Create((byte)1); + Vector128 bitMask128 = BitConverter.IsLittleEndian ? + Vector128.Create(0x80402010_08040201).AsByte() : + Vector128.Create(0x01020408_10204080).AsByte(); + + fixed (bool* destination = &boolArray[index]) + { + for (; i + Vector128ByteCount * 2u <= (uint)m_length; i += Vector128ByteCount * 2u) + { + int bits = m_array[i / BitsPerInt32]; + // Same logic as SSSE3 path, except we do not have Shuffle instruction. + // (TableVectorLookup could be an alternative - dotnet/runtime#1277) + // Instead we use chained ZIP1/2 instructions: + // (A0 is the byte containing LSB, A3 is the byte containing MSB) + // bits (on Big endian) - A3 A2 A1 A0 + // bits (Little endian) / Byte reversal - A0 A1 A2 A3 + // v1 = Vector128.Create - A0 A1 A2 A3 A0 A1 A2 A3 A0 A1 A2 A3 A0 A1 A2 A3 + // v2 = ZipLow(v1, v1) - A0 A0 A1 A1 A2 A2 A3 A3 A0 A0 A1 A1 A2 A2 A3 A3 + // v3 = ZipLow(v2, v2) - A0 A0 A0 A0 A1 A1 A1 A1 A2 A2 A2 A2 A3 A3 A3 A3 + // shuffledLower = ZipLow(v3, v3) - A0 A0 A0 A0 A0 A0 A0 A0 A1 A1 A1 A1 A1 A1 A1 A1 + // shuffledHigher = ZipHigh(v3, v3) - A2 A2 A2 A2 A2 A2 A2 A2 A3 A3 A3 A3 A3 A3 A3 A3 + if (!BitConverter.IsLittleEndian) + { + bits = BinaryPrimitives.ReverseEndianness(bits); + } + Vector128 vector = Vector128.Create(bits).AsByte(); + vector = AdvSimd.Arm64.ZipLow(vector, vector); + vector = AdvSimd.Arm64.ZipLow(vector, vector); + + Vector128 shuffledLower = AdvSimd.Arm64.ZipLow(vector, vector); + Vector128 extractedLower = AdvSimd.And(shuffledLower, bitMask128); + Vector128 normalizedLower = AdvSimd.Min(extractedLower, ones); + AdvSimd.Store((byte*)destination + i, normalizedLower); + + Vector128 shuffledHigher = AdvSimd.Arm64.ZipHigh(vector, vector); + Vector128 extractedHigher = AdvSimd.And(shuffledHigher, bitMask128); + Vector128 normalizedHigher = AdvSimd.Min(extractedHigher, ones); + AdvSimd.Store((byte*)destination + i + Vector128.Count, normalizedHigher); + } + } + } + + LessThan32: + for (; i < (uint)m_length; i++) + { + int elementIndex = Div32Rem((int)i, out int extraBits); + boolArray[(uint)index + i] = ((m_array[elementIndex] >> extraBits) & 0x00000001) != 0; + } + } + else + { + throw new ArgumentException(CollectionThrowStrings.Arg_BitArrayTypeUnsupported, nameof(array)); + } + } + + public int Count => m_length; + + public object SyncRoot => this; + + public bool IsSynchronized => false; + + public bool IsReadOnly => false; + + public object Clone() => new BitArray(this); + + public IEnumerator GetEnumerator() => new BitArrayEnumeratorSimple(this); + + // XPerY=n means that n Xs can be stored in 1 Y. + private const int BitsPerInt32 = 32; + private const int BitsPerByte = 8; + + private const int BitShiftPerInt32 = 5; + private const int BitShiftPerByte = 3; + private const int BitShiftForBytesPerInt32 = 2; + + /// + /// Used for conversion between different representations of bit array. + /// Returns (n + (32 - 1)) / 32, rearranged to avoid arithmetic overflow. + /// For example, in the bit to int case, the straightforward calc would + /// be (n + 31) / 32, but that would cause overflow. So instead it's + /// rearranged to ((n - 1) / 32) + 1. + /// Due to sign extension, we don't need to special case for n == 0, if we use + /// bitwise operations (since ((n - 1) >> 5) + 1 = 0). + /// This doesn't hold true for ((n - 1) / 32) + 1, which equals 1. + /// + /// Usage: + /// GetArrayLength(77): returns how many ints must be + /// allocated to store 77 bits. + /// + /// + /// how many ints are required to store n bytes + private static int GetInt32ArrayLengthFromBitLength(int n) + { + Debug.Assert(n >= 0); + return (int)((uint)(n - 1 + (1 << BitShiftPerInt32)) >> BitShiftPerInt32); + } + + private static int GetInt32ArrayLengthFromByteLength(int n) + { + Debug.Assert(n >= 0); + // Due to sign extension, we don't need to special case for n == 0, since ((n - 1) >> 2) + 1 = 0 + // This doesn't hold true for ((n - 1) / 4) + 1, which equals 1. + return (int)((uint)(n - 1 + (1 << BitShiftForBytesPerInt32)) >> BitShiftForBytesPerInt32); + } + + public static int GetByteArrayLengthFromBitLength(int n) + { + Debug.Assert(n >= 0); + // Due to sign extension, we don't need to special case for n == 0, since ((n - 1) >> 3) + 1 = 0 + // This doesn't hold true for ((n - 1) / 8) + 1, which equals 1. + return (int)((uint)(n - 1 + (1 << BitShiftPerByte)) >> BitShiftPerByte); + } + + private static int Div32Rem(int number, out int remainder) + { + uint quotient = (uint)number / 32; + remainder = number & (32 - 1); // equivalent to number % 32, since 32 is a power of 2 + return (int)quotient; + } + + private static int Div4Rem(int number, out int remainder) + { + uint quotient = (uint)number / 4; + remainder = number & (4 - 1); // equivalent to number % 4, since 4 is a power of 2 + return (int)quotient; + } + + private static void ThrowArgumentOutOfRangeException(int index) + { + throw new ArgumentOutOfRangeException(nameof(index), index, CollectionThrowStrings.ArgumentOutOfRange_Index); + } + + private sealed class BitArrayEnumeratorSimple : IEnumerator, ICloneable + { + private readonly BitArray _bitArray; + private int _index; + private readonly int _version; + private bool _currentElement; + + internal BitArrayEnumeratorSimple(BitArray bitArray) + { + _bitArray = bitArray; + _index = -1; + _version = bitArray._version; + } + + public object Clone() => MemberwiseClone(); + + public bool MoveNext() + { + if (_version != _bitArray._version) + { + throw new InvalidOperationException(CollectionThrowStrings.InvalidOperation_EnumFailedVersion); + } + + if (_index < _bitArray.m_length - 1) + { + _index++; + _currentElement = _bitArray.Get(_index); + return true; + } + else + { + _index = _bitArray.m_length; + } + + return false; + } + + public object Current + { + get + { + if ((uint)_index >= (uint)_bitArray.m_length) + { + throw GetInvalidOperationException(_index); + } + + return _currentElement; + } + } + + public void Reset() + { + if (_version != _bitArray._version) + { + throw new InvalidOperationException(CollectionThrowStrings.InvalidOperation_EnumFailedVersion); + } + + _index = -1; + } + + private InvalidOperationException GetInvalidOperationException(int index) + { + if (index == -1) + { + return new InvalidOperationException(CollectionThrowStrings.InvalidOperation_EnumNotStarted); + } + + Debug.Assert(index >= _bitArray.m_length); + return new InvalidOperationException(CollectionThrowStrings.InvalidOperation_EnumEnded); + } + } +} diff --git a/Projects/Server/Collections/CollectionThrowStrings.cs b/Projects/Server/Collections/CollectionThrowStrings.cs index 41feda828..1730c6334 100644 --- a/Projects/Server/Collections/CollectionThrowStrings.cs +++ b/Projects/Server/Collections/CollectionThrowStrings.cs @@ -13,33 +13,43 @@ * along with this program. If not, see . * *************************************************************************/ -namespace Server.Collections +namespace Server.Collections; + +public static class CollectionThrowStrings { - public static class CollectionThrowStrings - { - public const string ArgumentOutOfRange_Index = - "Index was out of range. Must be non-negative and less than the size of the collection."; + public const string ArgumentOutOfRange_Index = + "Index was out of range. Must be non-negative and less than the size of the collection."; - public const string ArgumentOutOfRange_NeedNonNegNum = "Non-negative number required."; + public const string ArgumentOutOfRange_NeedNonNegNum = "Non-negative number required."; - public const string Argument_InvalidOffLen = - "Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection."; + public const string Argument_InvalidOffLen = + "Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection."; - public const string Argument_AddingDuplicate = "An item with the same value has already been added. Value: {0}"; + public const string Argument_AddingDuplicate = "An item with the same value has already been added. Value: {0}"; - public const string Arg_ArrayPlusOffTooSmall = - "Destination array is not long enough to copy all the items in the collection. Check array index and length."; + public const string Arg_ArrayPlusOffTooSmall = + "Destination array is not long enough to copy all the items in the collection. Check array index and length."; - public const string InvalidOperation_ConcurrentOperationsNotSupported = - "Operations that change non-concurrent collections must have exclusive access. A concurrent update was performed on this collection and corrupted its state. The collection's state is no longer correct."; + public const string InvalidOperation_ConcurrentOperationsNotSupported = + "Operations that change non-concurrent collections must have exclusive access. A concurrent update was performed on this collection and corrupted its state. The collection's state is no longer correct."; - public const string InvalidOperation_EnumFailedVersion = - "Collection was modified after the enumerator was instantiated."; + public const string InvalidOperation_EnumFailedVersion = + "Collection was modified after the enumerator was instantiated."; - public const string InvalidOperation_EmptyQueue = "Queue empty."; + public const string InvalidOperation_EmptyQueue = "Queue empty."; - public const string InvalidOperation_EnumNotStarted = "Enumeration has not started. Call MoveNext."; + public const string InvalidOperation_EnumNotStarted = "Enumeration has not started. Call MoveNext."; - public const string InvalidOperation_EnumEnded = "Enumeration already finished."; - } + public const string InvalidOperation_EnumEnded = "Enumeration already finished."; + + public const string Argument_ArrayTooLarge = + "The input array length must not exceed Int32.MaxValue / {0}. Otherwise BitArray.Length would exceed Int32.MaxValue."; + + public const string Arg_ArrayLengthsDiffer = "Array lengths must be the same."; + + public const string Arg_RankMultiDimNotSupported = + "Only single dimensional arrays are supported for the requested action."; + + public const string Arg_BitArrayTypeUnsupported = + "Only supported array types for CopyTo on BitArrays are Boolean[], Int32[] and Byte[]."; } diff --git a/Projects/Server/Serialization/BinaryFileReader.cs b/Projects/Server/Serialization/BinaryFileReader.cs index 81064faa3..e7ba33642 100644 --- a/Projects/Server/Serialization/BinaryFileReader.cs +++ b/Projects/Server/Serialization/BinaryFileReader.cs @@ -16,6 +16,7 @@ using System; using System.IO; using System.Runtime.CompilerServices; +using Server.Collections; namespace Server { @@ -78,6 +79,15 @@ namespace Server [MethodImpl(MethodImplOptions.AggressiveInlining)] public int Read(Span buffer) => _reader.Read(buffer); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public BitArray ReadBitArray() + { + var length = ((IGenericReader)this).ReadEncodedInt(); + + // BinaryReader doesn't expose a Span slice of the buffer, so we use a custom ctor + return new BitArray(_reader, length); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public long Seek(long offset, SeekOrigin origin) => _reader.BaseStream.Seek(offset, origin); diff --git a/Projects/Server/Serialization/BufferReader.cs b/Projects/Server/Serialization/BufferReader.cs index 309ac26f4..91641c343 100644 --- a/Projects/Server/Serialization/BufferReader.cs +++ b/Projects/Server/Serialization/BufferReader.cs @@ -19,6 +19,7 @@ using System.Diagnostics; using System.IO; using System.Runtime.CompilerServices; using System.Text; +using Server.Collections; using Server.Text; namespace Server @@ -156,6 +157,19 @@ namespace Server return length; } + public BitArray ReadBitArray() + { + var length = ((IGenericReader)this).ReadEncodedInt(); + if (length > _buffer.Length - _position) + { + throw new OutOfMemoryException(); + } + + var bitArray = new BitArray(_buffer.AsSpan(_position, length)); + _position += length; + return bitArray; + } + public virtual long Seek(long offset, SeekOrigin origin) { Debug.Assert( diff --git a/Projects/Server/Serialization/BufferWriter.cs b/Projects/Server/Serialization/BufferWriter.cs index 208039916..167d24edb 100644 --- a/Projects/Server/Serialization/BufferWriter.cs +++ b/Projects/Server/Serialization/BufferWriter.cs @@ -18,6 +18,7 @@ using System.Diagnostics; using System.IO; using System.Runtime.CompilerServices; using System.Text; +using Server.Collections; using Server.Text; namespace Server @@ -134,6 +135,16 @@ namespace Server } } + public void Write(BitArray bitArray) + { + var byteLength = BitArray.GetByteArrayLengthFromBitLength(bitArray.Length); + FlushIfNeeded(byteLength + 4); + + ((IGenericWriter)this).WriteEncodedInt(byteLength); + bitArray.CopyTo(_buffer.AsSpan((int)Index, byteLength)); + Index += byteLength; + } + public virtual long Seek(long offset, SeekOrigin origin) { Debug.Assert( diff --git a/Projects/Server/Serialization/IGenericReader.cs b/Projects/Server/Serialization/IGenericReader.cs index 67e27764e..5abf069aa 100644 --- a/Projects/Server/Serialization/IGenericReader.cs +++ b/Projects/Server/Serialization/IGenericReader.cs @@ -16,6 +16,7 @@ using System; using System.IO; using System.Net; +using Server.Collections; namespace Server { @@ -116,6 +117,8 @@ namespace Server return new Guid(bytes); } + BitArray ReadBitArray(); + long Seek(long offset, SeekOrigin origin); } } diff --git a/Projects/Server/Serialization/IGenericWriter.cs b/Projects/Server/Serialization/IGenericWriter.cs index 95aa9d92f..8eeec249f 100644 --- a/Projects/Server/Serialization/IGenericWriter.cs +++ b/Projects/Server/Serialization/IGenericWriter.cs @@ -16,6 +16,7 @@ using System; using System.IO; using System.Net; +using Server.Collections; namespace Server { @@ -160,6 +161,8 @@ namespace Server Write(stack); } + void Write(BitArray bitArray); + long Seek(long offset, SeekOrigin origin); } } From f634ee27483ac52e2c864848f21ba96f759128ca Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 19 Dec 2021 19:58:59 -0800 Subject: [PATCH 041/213] fix: Changes spells so they register during configuration (#889) --- Projects/UOContent/Spells/Initializer.cs | 28 ++++++++++++------------ 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Projects/UOContent/Spells/Initializer.cs b/Projects/UOContent/Spells/Initializer.cs index 7fa5657d8..418e81da7 100644 --- a/Projects/UOContent/Spells/Initializer.cs +++ b/Projects/UOContent/Spells/Initializer.cs @@ -18,7 +18,7 @@ namespace Server.Spells { public static class Initializer { - public static void Initialize() + public static void Configure() { // First circle Register(00, typeof(ClumsySpell)); @@ -169,34 +169,34 @@ namespace Server.Spells Register(606, typeof(SummonFeySpell)); Register(607, typeof(SummonFiendSpell)); Register(608, typeof(ReaperFormSpell)); - // Register( 609, typeof( Spellweaving.WildfireSpell ) ); + // Register(609, typeof(WildfireSpell)); Register(610, typeof(EssenceOfWindSpell)); - // Register( 611, typeof( Spellweaving.DryadAllureSpell ) ); + // Register(611, typeof(DryadAllureSpell)); Register(612, typeof(EtherealVoyageSpell)); Register(613, typeof(WordOfDeathSpell)); Register(614, typeof(GiftOfLifeSpell)); - // Register( 615, typeof( Spellweaving.ArcaneEmpowermentSpell ) ); + // Register(615, typeof(ArcaneEmpowermentSpell)); } if (Core.SA) { // Mysticism spells - // Register( 677, typeof( Mysticism.NetherBoltSpell ) ); - // Register( 678, typeof( Mysticism.HealingStoneSpell ) ); - // Register( 679, typeof( Mysticism.PurgeMagicSpell ) ); - // Register( 680, typeof( Mysticism.EnchantSpell ) ); - // Register( 681, typeof( Mysticism.SleepSpell ) ); + // Register(677, typeof(NetherBoltSpell)); + // Register(678, typeof(HealingStoneSpell)); + // Register(679, typeof(PurgeMagicSpell)); + // Register(680, typeof(EnchantSpell)); + // Register(681, typeof(SleepSpell)); Register(682, typeof(EagleStrikeSpell)); Register(683, typeof(AnimatedWeaponSpell)); Register(684, typeof(StoneFormSpell)); - // Register( 685, typeof( Mysticism.SpellTriggerSpell ) ); - // Register( 686, typeof( Mysticism.MassSleepSpell ) ); - // Register( 687, typeof( Mysticism.CleansingWindsSpell ) ); - // Register( 688, typeof( Mysticism.BombardSpell ) ); + // Register(685, typeof(SpellTriggerSpell)); + // Register(686, typeof(MassSleepSpell)); + // Register(687, typeof(CleansingWindsSpell)); + // Register(688, typeof(BombardSpell)); Register(689, typeof(SpellPlagueSpell)); Register(690, typeof(HailStormSpell)); Register(691, typeof(NetherCycloneSpell)); - // Register( 692, typeof( Mysticism.RisingColossusSpell ) ); + // Register(692, typeof(RisingColossusSpell)); } } } From 171df322576329dc24788c314f8ec81dcd25436d Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Fri, 24 Dec 2021 15:26:12 -0800 Subject: [PATCH 042/213] fix: Fixes first/second scrolls crashing (#891) * Fixes first/second circle scrolls crashing * Consolidates some resistance logic * Removes unnecessary multiple lookups for items on layer --- Projects/UOContent/Spells/Base/MagerySpell.cs | 32 ++++++++----------- .../UOContent/Spells/Bushido/CounterAttack.cs | 7 +--- Projects/UOContent/Spells/Bushido/Evasion.cs | 21 ++++++------ .../Spells/Chivalry/ConsecrateWeapon.cs | 2 +- .../Spells/Chivalry/NobleSacrifice.cs | 2 +- .../UOContent/Spells/Fifth/DispelField.cs | 2 +- Projects/UOContent/Spells/Fourth/ArchCure.cs | 2 +- .../Spells/Necromancy/AnimateDeadSpell.cs | 2 +- .../Spells/Necromancy/BloodOathSpell.cs | 2 +- .../Spells/Necromancy/CurseWeapon.cs | 2 +- .../UOContent/Spells/Necromancy/EvilOmen.cs | 2 +- .../UOContent/Spells/Seventh/EnergyField.cs | 2 +- Projects/UOContent/Spells/Third/MagicLock.cs | 2 +- Projects/UOContent/Spells/Third/Teleport.cs | 4 +-- Projects/UOContent/Spells/Third/Unlock.cs | 2 +- .../UOContent/Spells/Third/WallOfStone.cs | 2 +- 16 files changed, 39 insertions(+), 49 deletions(-) diff --git a/Projects/UOContent/Spells/Base/MagerySpell.cs b/Projects/UOContent/Spells/Base/MagerySpell.cs index 68c261e8e..7905a7d65 100644 --- a/Projects/UOContent/Spells/Base/MagerySpell.cs +++ b/Projects/UOContent/Spells/Base/MagerySpell.cs @@ -6,9 +6,11 @@ namespace Server.Spells public abstract class MagerySpell : Spell { private static readonly int[] _manaTable = { 4, 6, 9, 11, 14, 20, 40, 50 }; + + // Starts at Circle -2 to account for scrolls private static readonly double[] _requiredSkill = Core.ML ? - new[] { 0.0, -4.0, 10.0, 24.0, 38.0, 52.0, 66.0, 80.0 } : - new[] { 0.0, 10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0 }; + new[] { -46.0, -32.0, 0.0, -4.0, 10.0, 24.0, 38.0, 52.0, 66.0, 80.0 } : + new[] { -50.0, -30.0, 0.0, 10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0 }; public MagerySpell(Mobile caster, Item scroll, SpellInfo info) : base(caster, scroll, info) { @@ -23,13 +25,6 @@ namespace Server.Spells public override void GetCastSkills(out double min, out double max) { - var circle = (int)Circle; - - if (Scroll != null) - { - circle -= 2; - } - // Original RunUO algorithm for required skill // const double chanceOffset = 20.0 // const double chanceLength = 100.0 / 7.0 @@ -37,9 +32,9 @@ namespace Server.Spells // min = avg - chanceOffset; // max = avg + chanceOffset; - // Correct algorithm according to OSI. + // Correct algorithm according to OSI for UOR/UOML // TODO: Verify this algorithm on OSI for latest expansion. - min = _requiredSkill[circle]; + min = _requiredSkill[(int)(Scroll == null ? Circle + 2 : Circle)]; max = min + 40; } @@ -47,8 +42,9 @@ namespace Server.Spells public override double GetResistSkill(Mobile m) { - var maxSkill = (1 + (int)Circle) * 10; - maxSkill += (1 + (int)Circle / 6) * 25; + var circle = (int)Circle; + + var maxSkill = 1 + circle * 10 + (1 + circle / 6) * 25; if (m.Skills.MagicResist.Value < maxSkill) { @@ -60,9 +56,7 @@ namespace Server.Spells public virtual bool CheckResisted(Mobile target) { - var n = GetResistPercent(target); - - n /= 100.0; + var n = GetResistPercent(target) / 100.0; if (n <= 0.0) { @@ -74,8 +68,10 @@ namespace Server.Spells return true; } - var maxSkill = (1 + (int)Circle) * 10; - maxSkill += (1 + (int)Circle / 6) * 25; + // Even though this calculation matches AOS+, we don't combine with GetResistSkills because of an assumption + // about how it is used. + var circle = (int)Circle; + var maxSkill = (1 + circle) * 10 + (1 + circle / 6) * 25; if (target.Skills.MagicResist.Value < maxSkill) { diff --git a/Projects/UOContent/Spells/Bushido/CounterAttack.cs b/Projects/UOContent/Spells/Bushido/CounterAttack.cs index ea3c07e22..6dacc8e27 100644 --- a/Projects/UOContent/Spells/Bushido/CounterAttack.cs +++ b/Projects/UOContent/Spells/Bushido/CounterAttack.cs @@ -31,17 +31,12 @@ namespace Server.Spells.Bushido return false; } - if (Caster.FindItemOnLayer(Layer.TwoHanded) is BaseShield) - { - return true; - } - if (Caster.FindItemOnLayer(Layer.OneHanded) is BaseWeapon) { return true; } - if (Caster.FindItemOnLayer(Layer.TwoHanded) is BaseWeapon) + if (Caster.FindItemOnLayer(Layer.TwoHanded) is BaseShield or BaseWeapon) { return true; } diff --git a/Projects/UOContent/Spells/Bushido/Evasion.cs b/Projects/UOContent/Spells/Bushido/Evasion.cs index a5eab88e2..ec9a77b52 100644 --- a/Projects/UOContent/Spells/Bushido/Evasion.cs +++ b/Projects/UOContent/Spells/Bushido/Evasion.cs @@ -33,7 +33,7 @@ namespace Server.Spells.Bushido return false; } - if (!(caster.FindItemOnLayer(Layer.OneHanded) is BaseWeapon weap)) + if (caster.FindItemOnLayer(Layer.OneHanded) is not BaseWeapon weap) { weap = caster.FindItemOnLayer(Layer.TwoHanded) as BaseWeapon; } @@ -44,15 +44,14 @@ namespace Server.Spells.Bushido { if (messages) { - caster.SendLocalizedMessage( - 1076206 - ); // Your skill with your equipped weapon must be 50 or higher to use Evasion. + // Your skill with your equipped weapon must be 50 or higher to use Evasion. + caster.SendLocalizedMessage(1076206); } return false; } } - else if (!(caster.FindItemOnLayer(Layer.TwoHanded) is BaseShield)) + else if (caster.FindItemOnLayer(Layer.TwoHanded) is not BaseShield) { if (messages) { @@ -77,7 +76,7 @@ namespace Server.Spells.Bushido public static bool CheckSpellEvasion(Mobile defender) { - if (!(defender.FindItemOnLayer(Layer.OneHanded) is BaseWeapon weap)) + if (defender.FindItemOnLayer(Layer.OneHanded) is not BaseWeapon weap) { weap = defender.FindItemOnLayer(Layer.TwoHanded) as BaseWeapon; } @@ -96,7 +95,7 @@ namespace Server.Spells.Bushido return false; } } - else if (!(defender.FindItemOnLayer(Layer.TwoHanded) is BaseShield)) + else if (defender.FindItemOnLayer(Layer.TwoHanded) is not BaseShield) { return false; } @@ -162,8 +161,8 @@ namespace Server.Spells.Bushido seconds += (m.Skills.Bushido.Value - 60) / 20; } - if (m.Skills.Anatomy.Value >= 100.0 && m.Skills.Tactics.Value >= 100.0 && m.Skills.Bushido.Value > 100.0 - ) // Bushido being HIGHER than 100 for bonus is intended + // Bushido being HIGHER than 100 for bonus is intended + if (m.Skills.Anatomy.Value >= 100.0 && m.Skills.Tactics.Value >= 100.0 && m.Skills.Bushido.Value > 100.0) { seconds++; } @@ -194,8 +193,8 @@ namespace Server.Spells.Bushido bonus += (m.Skills.Bushido.Value - 60) * .004 + 0.16; } - if (m.Skills.Anatomy.Value >= 100 && m.Skills.Tactics.Value >= 100 && m.Skills.Bushido.Value > 100 - ) // Bushido being HIGHER than 100 for bonus is intended + // Bushido being HIGHER than 100 for bonus is intended + if (m.Skills.Anatomy.Value >= 100 && m.Skills.Tactics.Value >= 100 && m.Skills.Bushido.Value > 100) { bonus += 0.10; } diff --git a/Projects/UOContent/Spells/Chivalry/ConsecrateWeapon.cs b/Projects/UOContent/Spells/Chivalry/ConsecrateWeapon.cs index 01eea62a2..a204fe57c 100644 --- a/Projects/UOContent/Spells/Chivalry/ConsecrateWeapon.cs +++ b/Projects/UOContent/Spells/Chivalry/ConsecrateWeapon.cs @@ -29,7 +29,7 @@ namespace Server.Spells.Chivalry public override void OnCast() { - if (!(Caster.Weapon is BaseWeapon weapon) || weapon is Fists) + if (Caster.Weapon is not (BaseWeapon weapon and not Fists)) { Caster.SendLocalizedMessage(501078); // You must be holding a weapon. } diff --git a/Projects/UOContent/Spells/Chivalry/NobleSacrifice.cs b/Projects/UOContent/Spells/Chivalry/NobleSacrifice.cs index 8009e46de..9e8e4e4c7 100644 --- a/Projects/UOContent/Spells/Chivalry/NobleSacrifice.cs +++ b/Projects/UOContent/Spells/Chivalry/NobleSacrifice.cs @@ -40,7 +40,7 @@ namespace Server.Spells.Chivalry continue; } - if (Caster != m && m.InLOS(Caster) && Caster.CanBeBeneficial(m, false, true) && !(m is Golem)) + if (Caster != m && m.InLOS(Caster) && Caster.CanBeBeneficial(m, false, true) && m is not Golem) { targets.Add(m); } diff --git a/Projects/UOContent/Spells/Fifth/DispelField.cs b/Projects/UOContent/Spells/Fifth/DispelField.cs index ac0bfe41e..2db3e4f5b 100644 --- a/Projects/UOContent/Spells/Fifth/DispelField.cs +++ b/Projects/UOContent/Spells/Fifth/DispelField.cs @@ -28,7 +28,7 @@ namespace Server.Spells.Fifth { Caster.SendLocalizedMessage(1005049); // That cannot be dispelled. } - else if (item is Moongate moongate && !moongate.Dispellable) + else if (item is Moongate { Dispellable: false }) { Caster.SendLocalizedMessage(1005047); // That magic is too chaotic } diff --git a/Projects/UOContent/Spells/Fourth/ArchCure.cs b/Projects/UOContent/Spells/Fourth/ArchCure.cs index 9cacd8790..841c03d6d 100644 --- a/Projects/UOContent/Spells/Fourth/ArchCure.cs +++ b/Projects/UOContent/Spells/Fourth/ArchCure.cs @@ -127,7 +127,7 @@ namespace Server.Spells.Fourth return false; } - if (feluccaRules && !(target is PlayerMobile)) + if (feluccaRules && target is not PlayerMobile) { return false; } diff --git a/Projects/UOContent/Spells/Necromancy/AnimateDeadSpell.cs b/Projects/UOContent/Spells/Necromancy/AnimateDeadSpell.cs index f67cdeb78..13172b7ce 100644 --- a/Projects/UOContent/Spells/Necromancy/AnimateDeadSpell.cs +++ b/Projects/UOContent/Spells/Necromancy/AnimateDeadSpell.cs @@ -142,7 +142,7 @@ namespace Server.Spells.Necromancy return; } - if (!(item is Corpse c)) + if (item is not Corpse c) { Caster.SendLocalizedMessage(1061084); // You cannot animate that. } diff --git a/Projects/UOContent/Spells/Necromancy/BloodOathSpell.cs b/Projects/UOContent/Spells/Necromancy/BloodOathSpell.cs index 0d7969f7d..0b6b1aadf 100644 --- a/Projects/UOContent/Spells/Necromancy/BloodOathSpell.cs +++ b/Projects/UOContent/Spells/Necromancy/BloodOathSpell.cs @@ -34,7 +34,7 @@ namespace Server.Spells.Necromancy Caster.SendLocalizedMessage(1060508); // You can't curse that. } // only PlayerMobile and BaseCreature implement blood oath checking - else if (Caster == m || !(m is PlayerMobile || m is BaseCreature)) + else if (Caster == m || m is not (PlayerMobile or BaseCreature)) { Caster.SendLocalizedMessage(1060508); // You can't curse that. } diff --git a/Projects/UOContent/Spells/Necromancy/CurseWeapon.cs b/Projects/UOContent/Spells/Necromancy/CurseWeapon.cs index 96b5fd3ea..737645f75 100644 --- a/Projects/UOContent/Spells/Necromancy/CurseWeapon.cs +++ b/Projects/UOContent/Spells/Necromancy/CurseWeapon.cs @@ -27,7 +27,7 @@ namespace Server.Spells.Necromancy public override void OnCast() { - if (!(Caster.Weapon is BaseWeapon weapon) || weapon is Fists) + if (Caster.Weapon is not BaseWeapon weapon || weapon is Fists) { Caster.SendLocalizedMessage(501078); // You must be holding a weapon. } diff --git a/Projects/UOContent/Spells/Necromancy/EvilOmen.cs b/Projects/UOContent/Spells/Necromancy/EvilOmen.cs index ea3cd5335..c9fd172a7 100644 --- a/Projects/UOContent/Spells/Necromancy/EvilOmen.cs +++ b/Projects/UOContent/Spells/Necromancy/EvilOmen.cs @@ -30,7 +30,7 @@ namespace Server.Spells.Necromancy public void Target(Mobile m) { - if (!(m is BaseCreature || m is PlayerMobile)) + if (m is not (BaseCreature or PlayerMobile)) { Caster.SendLocalizedMessage(1060508); // You can't curse that. } diff --git a/Projects/UOContent/Spells/Seventh/EnergyField.cs b/Projects/UOContent/Spells/Seventh/EnergyField.cs index abb0895ef..bf5c5c019 100644 --- a/Projects/UOContent/Spells/Seventh/EnergyField.cs +++ b/Projects/UOContent/Spells/Seventh/EnergyField.cs @@ -140,7 +140,7 @@ namespace Server.Spells.Seventh public override bool OnMoveOver(Mobile m) { - if (!(m is PlayerMobile)) + if (m is not PlayerMobile) { return base.OnMoveOver(m); } diff --git a/Projects/UOContent/Spells/Third/MagicLock.cs b/Projects/UOContent/Spells/Third/MagicLock.cs index 76b0ef7a6..c9cfef434 100644 --- a/Projects/UOContent/Spells/Third/MagicLock.cs +++ b/Projects/UOContent/Spells/Third/MagicLock.cs @@ -24,7 +24,7 @@ namespace Server.Spells.Third public void Target(Item item) { - if (!(item is LockableContainer cont)) + if (item is not LockableContainer cont) { Caster.SendLocalizedMessage(501762); // Target must be an unlocked chest. } diff --git a/Projects/UOContent/Spells/Third/Teleport.cs b/Projects/UOContent/Spells/Third/Teleport.cs index 9e2b2236a..eda47e8fc 100644 --- a/Projects/UOContent/Spells/Third/Teleport.cs +++ b/Projects/UOContent/Spells/Third/Teleport.cs @@ -98,8 +98,8 @@ namespace Server.Spells.Third foreach (var item in eable) { - if (item is ParalyzeFieldSpell.InternalItem || item is PoisonFieldSpell.InternalItem || - item is FireFieldSpell.FireFieldItem) + if (item is ParalyzeFieldSpell.InternalItem or + PoisonFieldSpell.InternalItem or FireFieldSpell.FireFieldItem) { item.OnMoveOver(m); } diff --git a/Projects/UOContent/Spells/Third/Unlock.cs b/Projects/UOContent/Spells/Third/Unlock.cs index 715cf1e82..a29040d06 100644 --- a/Projects/UOContent/Spells/Third/Unlock.cs +++ b/Projects/UOContent/Spells/Third/Unlock.cs @@ -42,7 +42,7 @@ namespace Server.Spells.Third { Caster.LocalOverheadMessage(MessageType.Regular, 0x3B2, 503101); // That did not need to be unlocked. } - else if (!(p is LockableContainer cont)) + else if (p is not LockableContainer cont) { Caster.SendLocalizedMessage(501666); // You can't unlock that! } diff --git a/Projects/UOContent/Spells/Third/WallOfStone.cs b/Projects/UOContent/Spells/Third/WallOfStone.cs index 0be6b4b9c..98d239a07 100644 --- a/Projects/UOContent/Spells/Third/WallOfStone.cs +++ b/Projects/UOContent/Spells/Third/WallOfStone.cs @@ -149,7 +149,7 @@ namespace Server.Spells.Third if (m is PlayerMobile) { var noto = Notoriety.Compute(m_Caster, m); - if (noto == Notoriety.Enemy || noto == Notoriety.Ally) + if (noto is Notoriety.Enemy or Notoriety.Ally) { return false; } From 63e1b02d93e7262f6b4274334c7765aef86896e3 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Fri, 24 Dec 2021 15:53:59 -0800 Subject: [PATCH 043/213] chore: Cleans up pattern checks. (#892) --- .../Packets/Outgoing/VendorBuyPackets.cs | 2 +- Projects/Server/Attributes.cs | 2 +- Projects/Server/Collections/PooledRefQueue.cs | 2 +- Projects/Server/ContextMenus/ContextMenu.cs | 2 +- Projects/Server/Items/Container.cs | 6 +- Projects/Server/Items/Item.cs | 2 +- .../Json/Converters/Rectangle3DConverter.cs | 4 +- Projects/Server/Maps/Map.cs | 6 +- Projects/Server/Mobiles/Mobile.cs | 4 +- Projects/Server/Network/NetState/NetState.cs | 8 +- .../Network/Packets/IncomingMessagePackets.cs | 6 +- Projects/Server/Skills.cs | 4 +- Projects/Server/Utilities/Utility.cs | 2 +- Projects/UOContent/Accounting/Account.cs | 2 +- .../UOContent/Accounting/AccountHandler.cs | 6 +- .../UOContent/Commands/BoundingBoxPicker.cs | 2 +- Projects/UOContent/Commands/ExportWSC.cs | 2 +- .../Commands/Generic/Commands/Commands.cs | 13 +-- .../Commands/Generic/Commands/DesignInsert.cs | 2 +- .../Compilers/ConditionalCompiler.cs | 2 +- .../ContainedCommandImplementor.cs | 2 +- .../Implementors/MultiCommandImplementor.cs | 6 +- .../Implementors/SerialCommandImplementor.cs | 4 +- .../Implementors/SingleCommandImplementor.cs | 6 +- Projects/UOContent/Commands/Handlers.cs | 6 +- Projects/UOContent/Commands/HelpInfo.cs | 2 +- .../UOContent/Commands/LocationCommand.cs | 4 +- Projects/UOContent/Commands/Logging.cs | 2 +- .../Commands/Object Creation/Decorate.cs | 2 +- .../Commands/Object Creation/DecorateMag.cs | 2 +- .../Commands/Object Creation/GenTeleporter.cs | 2 +- Projects/UOContent/Commands/Properties.cs | 2 +- Projects/UOContent/Commands/Statics.cs | 6 +- Projects/UOContent/Commands/Wipe.cs | 2 +- .../Engines/Bulk Orders/Books/BOBGump.cs | 2 +- .../Engines/Bulk Orders/Books/BODBuyGump.cs | 2 +- .../UOContent/Engines/Bulk Orders/Rewards.cs | 6 +- .../UOContent/Engines/Bulk Orders/SmallBOD.cs | 2 +- .../Engines/ConPVP/AcceptDuelGump.cs | 2 +- .../UOContent/Engines/ConPVP/DuelContext.cs | 22 ++-- .../Engines/ConPVP/Games/BombingRun.cs | 4 +- .../UOContent/Engines/ConPVP/Games/CTF.cs | 2 +- .../Engines/ConPVP/Games/DoubleDom.cs | 2 +- .../Engines/ConPVP/Games/KingOfTheHill.cs | 2 +- .../Engines/ConPVP/Gumps/AcceptTeamGump.cs | 2 +- .../Engines/ConPVP/Gumps/ConfirmSignupGump.cs | 4 +- .../Engines/ConPVP/Gumps/ParticipantGump.cs | 4 +- .../Engines/ConPVP/Gumps/ReadyUpGump.cs | 2 +- .../ConPVP/Gumps/TournamentBracketGump.cs | 20 ++-- Projects/UOContent/Engines/ConPVP/Ladder.cs | 2 +- .../Engines/ConPVP/TournamentPyramid.cs | 2 +- .../UOContent/Engines/Craft/Core/CraftItem.cs | 6 +- .../UOContent/Engines/Craft/Core/Enhance.cs | 2 +- .../UOContent/Engines/Craft/Core/Repair.cs | 62 ++-------- .../UOContent/Engines/Craft/DefCarpentry.cs | 2 +- .../UOContent/Engines/Doom/GauntletSpawner.cs | 2 +- .../Doom/LeverPuzzle/LeverPuzzleRegions.cs | 2 +- .../UOContent/Engines/Ethics/Core/Ethic.cs | 2 +- .../UOContent/Engines/Ethics/Evil/Ethic.cs | 2 +- .../Engines/Ethics/Evil/Powers/Blight.cs | 2 +- .../Engines/Ethics/Evil/Powers/UnholyItem.cs | 4 +- .../UOContent/Engines/Ethics/Hero/Ethic.cs | 2 +- .../Engines/Ethics/Hero/Powers/Bless.cs | 2 +- .../Engines/Ethics/Hero/Powers/HolyItem.cs | 4 +- .../Engines/Factions/Core/Faction.cs | 8 +- .../Engines/Factions/Core/FactionItem.cs | 2 +- .../Factions/Gumps/LeaveFactionGump.cs | 2 +- .../Items/Power Faction Items/StormsEye.cs | 2 +- .../Factions/Mobiles/Guards/GuardAI.cs | 2 +- .../Engines/Harvest/Core/HarvestTarget.cs | 5 +- Projects/UOContent/Engines/Harvest/Fishing.cs | 6 +- .../Engines/Harvest/Lumberjacking.cs | 2 +- Projects/UOContent/Engines/Help/PageQueue.cs | 2 +- Projects/UOContent/Engines/Help/SpeechLog.cs | 2 +- .../Engines/ML Quests/Gumps/QuestOfferGump.cs | 2 +- .../Engines/ML Quests/Gumps/RaceChangeGump.cs | 4 +- .../ML Quests/Items/PrismaticCrystal.cs | 2 +- .../Engines/ML Quests/Items/Teleporters.cs | 2 +- .../Engines/ML Quests/MLQuestSystem.cs | 8 +- .../ML Quests/Objectives/CollectObjective.cs | 2 +- .../ML Quests/Objectives/DeliverObjective.cs | 2 +- .../Engines/Pathing/PathAlgorithm.cs | 2 +- .../UOContent/Engines/Plants/MainPlantGump.cs | 4 +- .../Engines/Plants/MiscItems/GreenThorns.cs | 2 +- .../Engines/Plants/MiscItems/RedLeaves.cs | 4 +- Projects/UOContent/Engines/Plants/PlantHue.cs | 2 +- .../UOContent/Engines/Plants/PlantItem.cs | 10 +- .../UOContent/Engines/Plants/PlantSystem.cs | 2 +- .../Engines/Plants/PollinateTarget.cs | 3 +- .../Engines/Plants/ReproductionGump.cs | 3 +- Projects/UOContent/Engines/Plants/Seed.cs | 2 +- .../Quests/Collector/Items/EnchantedPaints.cs | 4 +- .../Quests/Collector/Items/Obsidian.cs | 2 +- .../Quests/Collector/Mobiles/Impresario.cs | 4 +- .../Engines/Quests/Core/QuestSystem.cs | 2 +- .../Quests/Dark Tides/DarkTidesQuest.cs | 2 +- .../Dark Tides/Items/CrystalCaveBarrier.cs | 2 +- .../Quests/Dark Tides/Items/KronusScroll.cs | 4 +- .../Dark Tides/Items/ScrollOfAbraxus.cs | 2 +- .../Quests/Dark Tides/Mobiles/Mardoth.cs | 2 +- .../Engines/Quests/Dark Tides/Objectives.cs | 2 +- .../EminosUndertakingQuest.cs | 6 +- .../Emino's Undertaking/Items/EminosKatana.cs | 2 +- .../Emino's Undertaking/Items/NoteForZoel.cs | 2 +- .../Haochi's Trials/HaochisTrialsQuest.cs | 4 +- .../Haochi's Trials/Items/HaochisKatana.cs | 2 +- .../Haochi's Trials/Items/HonorCandle.cs | 2 +- .../Quests/Solen Matriarch/Objectives.cs | 8 +- .../Uzeraan Turmoil/Items/QuestDaemonBlood.cs | 2 +- .../Uzeraan Turmoil/Items/QuestDaemonBone.cs | 2 +- .../Uzeraan Turmoil/Items/QuestFertileDirt.cs | 2 +- .../Quests/Uzeraan Turmoil/Objectives.cs | 4 +- .../Uzeraan Turmoil/UzeraanTurmoilQuest.cs | 10 +- .../BasePigmentsOfTokuno.cs | 2 +- .../Treasures of Tokuno/GreaterArtifacts.cs | 2 +- .../Treasures of Tokuno/TreasuresOfTokuno.cs | 8 +- .../Character Statue Maker/CharacterStatue.cs | 2 +- .../Veteran Rewards/RewardDemolitionGump.cs | 2 +- .../Engines/Veteran Rewards/RewardSystem.cs | 13 +-- .../UOContent/Engines/Virtues/Sacrifice.cs | 3 +- Projects/UOContent/Gumps/AdminGump.cs | 62 +++++----- Projects/UOContent/Gumps/CommentsGump.cs | 2 +- .../Guilds/New Guild System/BaseGuildGump.cs | 8 +- .../New Guild System/BaseGuildListGump.cs | 2 +- .../New Guild System/Create Guild Gump.cs | 2 +- .../Guilds/New Guild System/DiplomacyGump.cs | 13 +-- .../New Guild System/GuildMemberInfoGump.cs | 6 +- .../New Guild System/GuildRosterGump.cs | 2 +- .../Guilds/New Guild System/OtherGuildInfo.cs | 2 +- Projects/UOContent/Gumps/PlayerVendorGumps.cs | 2 +- Projects/UOContent/Gumps/Props/PropsGump.cs | 2 +- Projects/UOContent/Gumps/ReportMurderer.cs | 2 +- Projects/UOContent/Gumps/VendorRentalGumps.cs | 12 +- Projects/UOContent/Gumps/ViewHousesGump.cs | 2 +- .../Halloween/2006/Engines/TrickOrTreat.cs | 2 +- .../Halloween/2006/Items/HalloweenPumpkin.cs | 2 +- Projects/UOContent/Items/Addons/DartBoard.cs | 6 +- Projects/UOContent/Items/Armor/BaseArmor.cs | 4 +- Projects/UOContent/Items/Books/BookPackets.cs | 6 +- .../Items/Construction/Doors/BaseDoor.cs | 10 +- .../Items/Construction/Misc/Vines.cs | 2 +- .../UOContent/Items/Containers/Container.cs | 2 +- .../Items/Containers/FillableContainers.cs | 4 +- .../Items/Containers/FurnitureContainer.cs | 4 +- .../UOContent/Items/Containers/SalvageBag.cs | 7 +- .../Items/Deeds/DragonBardingDeed.cs | 2 +- .../Items/Deeds/HairRestylingDeed.cs | 2 +- .../UOContent/Items/Deeds/HolidayTreeDeed.cs | 2 +- .../Items/Deeds/VendorRentalContract.cs | 2 +- Projects/UOContent/Items/Food/Beverage.cs | 12 +- Projects/UOContent/Items/Food/Cooking.cs | 6 +- Projects/UOContent/Items/Games/BaseBoard.cs | 2 +- .../Games/Mahjong/MahjongDealerIndicator.cs | 2 +- .../Items/Games/Mahjong/MahjongTile.cs | 2 +- Projects/UOContent/Items/Guilds/Guildstone.cs | 2 +- Projects/UOContent/Items/Jewels/BaseJewel.cs | 2 +- .../Items/Lights/BaseEquippableLight.cs | 2 +- .../UOContent/Items/Lights/CandleSkull.cs | 4 +- Projects/UOContent/Items/Lights/Lantern.cs | 2 +- .../UOContent/Items/Maps/MapItemPackets.cs | 2 +- Projects/UOContent/Items/Misc/Bola.cs | 4 +- .../Items/Misc/CommunicationCrystals.cs | 2 +- .../UOContent/Items/Misc/Corpses/Corpse.cs | 7 +- Projects/UOContent/Items/Misc/Guillotine.cs | 10 +- Projects/UOContent/Items/Misc/KeyRing.cs | 4 +- Projects/UOContent/Items/Misc/PoolOfAcid.cs | 2 +- .../UOContent/Items/Quivers/BaseQuiver.cs | 2 +- .../UOContent/Items/Shields/ChaosShield.cs | 2 +- .../UOContent/Items/Shields/OrderShield.cs | 2 +- .../Items/Skill Items/Camping/Bedroll.cs | 2 +- .../Fishing/Misc/SpecialFishingNet.cs | 6 +- .../Harvest Tools/BaseHarvestTool.cs | 2 +- .../Skill Items/Magical/Misc/PotionKeg.cs | 2 +- .../Skill Items/Magical/Potions/BasePotion.cs | 2 +- .../BaseConfusionBlastPotion.cs | 2 +- .../Items/Skill Items/Magical/Runebook.cs | 2 +- .../Items/Skill Items/Magical/Spellbook.cs | 2 +- .../Items/Skill Items/Misc/Bandage.cs | 2 +- .../Musical Instruments/BaseInstrument.cs | 4 +- .../Tailor Items/Dyetubs/DyeTub.cs | 6 +- .../Skill Items/Tailor Items/Misc/Scissors.cs | 4 +- .../Items/Skill Items/Thief/LockPick.cs | 2 +- .../Items/Skill Items/Tinkering/Spyglass.cs | 4 +- .../Items/Skill Items/Tools/BaseTool.cs | 4 +- .../Items/Skill Items/Tools/RunicSewingKit.cs | 2 +- .../Dawn's Music Box/DawnsMusicBox.cs | 2 +- .../AwesomeDisturbingPortrait.cs | 2 +- .../CreepyPortrait.cs | 4 +- .../HauntedMirror.cs | 4 +- .../Special/Heritage Items/Guillotine.cs | 2 +- .../Special/Heritage Items/HouseLadder.cs | 2 +- .../UOContent/Items/Special/Holiday/Wreath.cs | 2 +- .../Special/House Raffle/HouseRaffleStone.cs | 4 +- .../Mutation Core/PlagueBeastBackpack.cs | 4 +- .../Items/Special/Solen Items/BagOfSending.cs | 2 +- .../Special/Solen Items/BraceletOfBinding.cs | 2 +- Projects/UOContent/Items/Special/SoulStone.cs | 4 +- .../Special/Special Scrolls/PowerScroll.cs | 6 +- .../Special/Special Scrolls/SpecialScroll.cs | 2 +- .../Veteran Rewards/AnkhOfSacrifice.cs | 2 +- .../Items/Special/Veteran Rewards/Banner.cs | 2 +- .../Items/Special/Veteran Rewards/Cannon.cs | 2 +- .../Veteran Rewards/CommodityDeedBox.cs | 2 +- .../Veteran Rewards/DecorativeShield.cs | 5 +- .../Veteran Rewards/HangingSkeleton.cs | 3 +- .../Special/Veteran Rewards/PottedCactus.cs | 2 +- .../Special/Veteran Rewards/WallBanner.cs | 2 +- Projects/UOContent/Items/Suits/BaseSuit.cs | 2 +- .../UOContent/Items/Talismans/BaseTalisman.cs | 4 +- Projects/UOContent/Items/Wands/BaseWand.cs | 2 +- .../Items/Weapons/Abilities/Dismount.cs | 2 +- .../UOContent/Items/Weapons/Axes/BaseAxe.cs | 2 +- Projects/UOContent/Items/Weapons/Fists.cs | 2 +- .../Items/Weapons/Ranged/BaseRanged.cs | 2 +- .../UOContent/Items/Weapons/Ranged/JukaBow.cs | 2 +- Projects/UOContent/Misc/AccountPrompt.cs | 2 +- Projects/UOContent/Misc/Geometry.cs | 4 +- .../Misc/Gifts/Winter2004/Mistletoe.cs | 2 +- Projects/UOContent/Misc/Guild.cs | 2 +- Projects/UOContent/Misc/LootPack.cs | 2 +- Projects/UOContent/Misc/Notoriety.cs | 14 +-- Projects/UOContent/Misc/PacketThrottles.cs | 4 +- Projects/UOContent/Misc/Profile.cs | 2 +- Projects/UOContent/Misc/ResourceInfo.cs | 6 +- Projects/UOContent/Mobiles/AI/BaseAI.cs | 29 ++--- Projects/UOContent/Mobiles/AI/MageAI.cs | 4 +- .../Mobiles/Animals/Mounts/Ethereals.cs | 2 +- Projects/UOContent/Mobiles/BaseCreature.cs | 5 +- .../UOContent/Mobiles/Healers/EvilHealer.cs | 5 +- .../Mobiles/Healers/EvilWanderingHealer.cs | 6 +- .../Mobiles/Healers/FortuneTeller.cs | 5 +- Projects/UOContent/Mobiles/Healers/Healer.cs | 5 +- .../Mobiles/Healers/WanderingHealer.cs | 6 +- .../Monsters/Humanoid/Magic/SavageShaman.cs | 9 +- .../Mobiles/Monsters/Humanoid/Melee/Savage.cs | 3 +- .../Monsters/Humanoid/Melee/SavageRider.cs | 3 +- .../Monsters/LBR/Jukas/ChaosDragoon.cs | 3 +- .../Monsters/LBR/Jukas/ChaosDragoonElite.cs | 3 +- .../Mobiles/Monsters/LBR/Meers/MeerCaptain.cs | 2 +- .../Monsters/Misc/Melee/BladeSpirits.cs | 2 +- .../Monsters/Misc/Melee/EnergyVortex.cs | 2 +- .../Monsters/Misc/Melee/PlagueBeastLord.cs | 2 +- .../UOContent/Mobiles/Monsters/SE/Yamandon.cs | 2 +- Projects/UOContent/Mobiles/PlayerMobile.cs | 23 ++-- .../UOContent/Mobiles/Special/Barracoon.cs | 2 +- .../UOContent/Mobiles/Special/BaseChampion.cs | 4 +- .../Mobiles/Special/BaseShieldGuard.cs | 2 +- .../Mobiles/Special/HarrowerTentacles.cs | 2 +- Projects/UOContent/Mobiles/Special/Paragon.cs | 3 +- Projects/UOContent/Mobiles/Special/Rikktor.cs | 2 +- Projects/UOContent/Mobiles/Special/Semidar.cs | 2 +- Projects/UOContent/Mobiles/Special/Serado.cs | 2 +- .../Mobiles/Townfolk/BaseEscortable.cs | 2 +- .../UOContent/Mobiles/Vendors/BaseVendor.cs | 2 +- .../Mobiles/Vendors/NPC/AnimalTrainer.cs | 2 +- .../Mobiles/Vendors/NPC/Blacksmith.cs | 2 +- .../UOContent/Mobiles/Vendors/NPC/Tailor.cs | 2 +- .../Mobiles/Vendors/NPC/Weaponsmith.cs | 2 +- .../UOContent/Mobiles/Vendors/NPC/Weaver.cs | 2 +- .../Mobiles/Vendors/PlayerBarkeeper.cs | 5 +- .../UOContent/Mobiles/Vendors/PlayerVendor.cs | 8 +- Projects/UOContent/Multis/Boats/BaseBoat.cs | 2 +- Projects/UOContent/Multis/Boats/Plank.cs | 2 +- Projects/UOContent/Multis/Houses/BaseHouse.cs | 36 +++--- .../Multis/Houses/HouseFoundation.cs | 12 +- .../UOContent/Multis/Houses/HousePlacement.cs | 2 +- .../UOContent/Multis/Houses/MovingCrate.cs | 2 +- Projects/UOContent/Regions/GuardedRegion.cs | 6 +- Projects/UOContent/Skills/Inscribe.cs | 4 +- Projects/UOContent/Skills/Peacemaking.cs | 2 +- Projects/UOContent/Skills/Poisoning.cs | 4 +- Projects/UOContent/Skills/Provocation.cs | 2 +- Projects/UOContent/Skills/Snooping.cs | 109 +++++++++--------- Projects/UOContent/Skills/SpiritSpeak.cs | 2 +- .../Special Systems/Engines/GiftGiving.cs | 2 +- Projects/UOContent/Spells/Base/SpellHelper.cs | 4 +- .../UOContent/Spells/Ninjitsu/FocusAttack.cs | 4 +- .../UOContent/Spells/Seventh/GateTravel.cs | 2 +- .../Spells/Spellweaving/ArcaneCircle.cs | 4 +- .../Spells/Spellweaving/ArcanistSpell.cs | 2 +- .../Spells/Spellweaving/ImmolatingWeapon.cs | 4 +- .../UOContent/Targets/BladedItemTarget.cs | 2 +- Projects/UOContent/Targets/PickMoveTarget.cs | 2 +- 283 files changed, 587 insertions(+), 702 deletions(-) diff --git a/Projects/Server.Tests/Tests/Network/Packets/Outgoing/VendorBuyPackets.cs b/Projects/Server.Tests/Tests/Network/Packets/Outgoing/VendorBuyPackets.cs index 0573d3263..d7414ea4c 100644 --- a/Projects/Server.Tests/Tests/Network/Packets/Outgoing/VendorBuyPackets.cs +++ b/Projects/Server.Tests/Tests/Network/Packets/Outgoing/VendorBuyPackets.cs @@ -50,7 +50,7 @@ namespace Server.Network { EnsureCapacity(256); - Stream.Write(!(vendor.FindItemOnLayer(Layer.ShopBuy) is Container buyPack) ? Serial.MinusOne : buyPack.Serial); + Stream.Write(vendor.FindItemOnLayer(Layer.ShopBuy) is not Container buyPack ? Serial.MinusOne : buyPack.Serial); Stream.Write((byte)list.Count); diff --git a/Projects/Server/Attributes.cs b/Projects/Server/Attributes.cs index e81a91bed..000e50bd7 100644 --- a/Projects/Server/Attributes.cs +++ b/Projects/Server/Attributes.cs @@ -71,7 +71,7 @@ namespace Server return 50; } - if (!(objs[0] is CallPriorityAttribute attr)) + if (objs[0] is not CallPriorityAttribute attr) { return 50; } diff --git a/Projects/Server/Collections/PooledRefQueue.cs b/Projects/Server/Collections/PooledRefQueue.cs index b3a1b3937..577e7f6f4 100644 --- a/Projects/Server/Collections/PooledRefQueue.cs +++ b/Projects/Server/Collections/PooledRefQueue.cs @@ -451,7 +451,7 @@ namespace Server.Collections private void ThrowEnumerationNotStartedOrEnded() { - Debug.Assert(_index == -1 || _index == -2); + Debug.Assert(_index is -1 or -2); throw new InvalidOperationException(_index == -1 ? CollectionThrowStrings.InvalidOperation_EnumNotStarted : CollectionThrowStrings.InvalidOperation_EnumEnded); } diff --git a/Projects/Server/ContextMenus/ContextMenu.cs b/Projects/Server/ContextMenus/ContextMenu.cs index a58a4d0a5..c6493334d 100644 --- a/Projects/Server/ContextMenus/ContextMenu.cs +++ b/Projects/Server/ContextMenus/ContextMenu.cs @@ -70,7 +70,7 @@ namespace Server.ContextMenus for (var i = 0; i < Entries.Length; ++i) { var number = Entries[i].Number; - if (number < 3000000 || number > 3032767) + if (number is < 3000000 or > 3032767) { return true; } diff --git a/Projects/Server/Items/Container.cs b/Projects/Server/Items/Container.cs index 43a2ba939..1b8375553 100644 --- a/Projects/Server/Items/Container.cs +++ b/Projects/Server/Items/Container.cs @@ -231,7 +231,7 @@ namespace Server.Items return container.CheckHold(m, item, message, checkItems, plusItems, plusWeight); } - if (!(parent is Item parentItem)) + if (parent is not Item parentItem) { break; } @@ -504,7 +504,7 @@ namespace Server.Items { var item = list[i]; - if (!(item is Container) && CheckHold(from, dropped, false, false) && + if (item is not Container && CheckHold(from, dropped, false, false) && item.StackWith(from, dropped, playSound)) { return true; @@ -540,7 +540,7 @@ namespace Server.Items { var item = list[j]; - if (!(item is Container) && CheckHold(from, dropped, false, false, 0, extraWeight) && + if (item is not Container && CheckHold(from, dropped, false, false, 0, extraWeight) && item.CanStackWith(dropped)) { stackItems.Add(new ItemStackEntry(item, dropped)); diff --git a/Projects/Server/Items/Item.cs b/Projects/Server/Items/Item.cs index 0e49d5568..8531c5a86 100644 --- a/Projects/Server/Items/Item.cs +++ b/Projects/Server/Items/Item.cs @@ -443,7 +443,7 @@ namespace Server var weight = TileData.ItemTable[m_ItemID].Weight; - if (weight == 255 || weight == 0) + if (weight is 255 or 0) { weight = 1; } diff --git a/Projects/Server/Json/Converters/Rectangle3DConverter.cs b/Projects/Server/Json/Converters/Rectangle3DConverter.cs index 1401ad874..f957337e5 100644 --- a/Projects/Server/Json/Converters/Rectangle3DConverter.cs +++ b/Projects/Server/Json/Converters/Rectangle3DConverter.cs @@ -78,7 +78,7 @@ namespace Server.Json reader.Read(); - if (key == "start" || key == "end") + if (key is "start" or "end") { if (objType > -1 && objType != 2) { @@ -140,7 +140,7 @@ namespace Server.Json objType = 1; data[i - 10] = reader.GetInt32(); - if (i == 12 || i == 15) + if (i is 12 or 15) { hasZ = true; } diff --git a/Projects/Server/Maps/Map.cs b/Projects/Server/Maps/Map.cs index 8dfe26e66..5593ee918 100644 --- a/Projects/Server/Maps/Map.cs +++ b/Projects/Server/Maps/Map.cs @@ -520,7 +520,7 @@ namespace Server var eable = map.GetItemsInRange(new Point3D(x, y, 0), 0); pool.AddRange( - eable.Where(item => item.ItemID <= TileData.MaxItemValue && !(item is BaseMulti)) + eable.Where(item => item.ItemID <= TileData.MaxItemValue && item is not BaseMulti) .OrderBy(item => item.Z) .Take(pool.Capacity) ); @@ -715,7 +715,7 @@ namespace Server { var item = sector.Items[i]; - if (!(item is BaseMulti) && item.ItemID <= TileData.MaxItemValue && item.AtWorldPoint(p.X, p.Y) && + if (item is not BaseMulti && item.ItemID <= TileData.MaxItemValue && item.AtWorldPoint(p.X, p.Y) && !item.Movable) { var id = item.ItemData; @@ -1145,7 +1145,7 @@ namespace Server { var item = items[i]; - if (!(item is BaseMulti) && item.ItemID <= TileData.MaxItemValue && item.AtWorldPoint(x, y)) + if (item is not BaseMulti && item.ItemID <= TileData.MaxItemValue && item.AtWorldPoint(x, y)) { var id = item.ItemData; surface = id.Surface; diff --git a/Projects/Server/Mobiles/Mobile.cs b/Projects/Server/Mobiles/Mobile.cs index 5e259a849..0e1f21fd4 100644 --- a/Projects/Server/Mobiles/Mobile.cs +++ b/Projects/Server/Mobiles/Mobile.cs @@ -1888,7 +1888,7 @@ namespace Server item ??= FindItemOnLayer(Layer.Mount); - if (!(item is IMountItem mountItem)) + if (item is not IMountItem mountItem) { return null; } @@ -8397,7 +8397,7 @@ namespace Server var n = Notoriety.Compute(this, target); - return n == Notoriety.Criminal || n == Notoriety.Murderer; + return n is Notoriety.Criminal or Notoriety.Murderer; } /// diff --git a/Projects/Server/Network/NetState/NetState.cs b/Projects/Server/Network/NetState/NetState.cs index 46a9622aa..b1916bf7b 100755 --- a/Projects/Server/Network/NetState/NetState.cs +++ b/Projects/Server/Network/NetState/NetState.cs @@ -223,7 +223,7 @@ namespace Server.Network private void SetPacketTime(int packetID) { - if (packetID < 0 || packetID >= 0x100) + if (packetID is < 0 or >= 0x100) { return; } @@ -233,7 +233,7 @@ namespace Server.Network public long GetPacketDelay(int packetID) { - if (packetID < 0 || packetID >= 0x100) + if (packetID is < 0 or >= 0x100) { return 0; } @@ -243,7 +243,7 @@ namespace Server.Network private void UpdatePacketCount(int packetID) { - if (packetID < 0 || packetID >= 0x100) + if (packetID is < 0 or >= 0x100) { return; } @@ -728,7 +728,7 @@ namespace Server.Network { reader.Advance((uint)packetLength); } - else if (_parserState == ParserState.AwaitingPartialPacket || _parserState == ParserState.Throttled) + else if (_parserState is ParserState.AwaitingPartialPacket or ParserState.Throttled) { break; } diff --git a/Projects/Server/Network/Packets/IncomingMessagePackets.cs b/Projects/Server/Network/Packets/IncomingMessagePackets.cs index 249bf4ea5..a40355498 100644 --- a/Projects/Server/Network/Packets/IncomingMessagePackets.cs +++ b/Projects/Server/Network/Packets/IncomingMessagePackets.cs @@ -60,7 +60,7 @@ namespace Server.Network reader.ReadInt16(); // font var text = reader.ReadAsciiSafe().Trim(); - if (text.Length <= 0 || text.Length > 128) + if (text.Length is <= 0 or > 128) { return; } @@ -97,7 +97,7 @@ namespace Server.Network var count = (value & 0xFFF0) >> 4; var hold = value & 0xF; - if (count < 0 || count > 50) + if (count is < 0 or > 50) { return; } @@ -141,7 +141,7 @@ namespace Server.Network text = text.Trim(); - if (text.Length <= 0 || text.Length > 128) + if (text.Length is <= 0 or > 128) { return; } diff --git a/Projects/Server/Skills.cs b/Projects/Server/Skills.cs index 077205507..75bfaf0c9 100644 --- a/Projects/Server/Skills.cs +++ b/Projects/Server/Skills.cs @@ -135,7 +135,7 @@ namespace Server } } - if (Lock < SkillLock.Up || Lock > SkillLock.Locked) + if (Lock is < SkillLock.Up or > SkillLock.Locked) { Console.WriteLine("Bad skill lock -> {0}.{1}", owner.Owner, Lock); Lock = SkillLock.Up; @@ -323,7 +323,7 @@ namespace Server public void SetLockNoRelay(SkillLock skillLock) { - if (skillLock < SkillLock.Up || skillLock > SkillLock.Locked) + if (skillLock is < SkillLock.Up or > SkillLock.Locked) { return; } diff --git a/Projects/Server/Utilities/Utility.cs b/Projects/Server/Utilities/Utility.cs index d3a780a4f..faba17ece 100644 --- a/Projects/Server/Utilities/Utility.cs +++ b/Projects/Server/Utilities/Utility.cs @@ -343,7 +343,7 @@ namespace Server if (endOfSection || i + 1 == end) { - if (number < 0 || number > 255) + if (number is < 0 or > 255) { valid = false; return false; diff --git a/Projects/UOContent/Accounting/Account.cs b/Projects/UOContent/Accounting/Account.cs index 43a1f8fb8..81538bf8b 100644 --- a/Projects/UOContent/Accounting/Account.cs +++ b/Projects/UOContent/Accounting/Account.cs @@ -758,7 +758,7 @@ namespace Server.Accounting private static void EventSink_Connected(Mobile m) { - if (!(m.Account is Account acc)) + if (m.Account is not Account acc) { return; } diff --git a/Projects/UOContent/Accounting/AccountHandler.cs b/Projects/UOContent/Accounting/AccountHandler.cs index a115d993a..55c6a7598 100644 --- a/Projects/UOContent/Accounting/AccountHandler.cs +++ b/Projects/UOContent/Accounting/AccountHandler.cs @@ -110,7 +110,7 @@ namespace Server.Misc { var from = e.Mobile; - if (!(from.Account is Account acct)) + if (@from.Account is not Account acct) { return; } @@ -217,7 +217,7 @@ namespace Server.Misc private static void EventSink_DeleteRequest(NetState state, int index) { - if (!(state.Account is Account acct)) + if (state.Account is not Account acct) { state.Disconnect("Attempted to delete a character but the account could not be found."); return; @@ -349,7 +349,7 @@ namespace Server.Misc e.Accepted = false; - if (!(Accounts.GetAccount(un) is Account acct)) + if (Accounts.GetAccount(un) is not Account acct) { // To prevent someone from making an account of just '' or a bunch of meaningless spaces if (AutoAccountCreation && un.Trim().Length > 0) diff --git a/Projects/UOContent/Commands/BoundingBoxPicker.cs b/Projects/UOContent/Commands/BoundingBoxPicker.cs index 40566bb6e..fa6c1028b 100644 --- a/Projects/UOContent/Commands/BoundingBoxPicker.cs +++ b/Projects/UOContent/Commands/BoundingBoxPicker.cs @@ -37,7 +37,7 @@ namespace Server protected override void OnTarget(Mobile from, object targeted) { - if (!(targeted is IPoint3D p)) + if (targeted is not IPoint3D p) { return; } diff --git a/Projects/UOContent/Commands/ExportWSC.cs b/Projects/UOContent/Commands/ExportWSC.cs index 2ab02bbe8..f032e80fd 100644 --- a/Projects/UOContent/Commands/ExportWSC.cs +++ b/Projects/UOContent/Commands/ExportWSC.cs @@ -24,7 +24,7 @@ namespace Server.Commands foreach (var item in World.Items.Values) { - if ((item is Static || item is BaseFloor || item is BaseWall) + if (item is Static or BaseFloor or BaseWall && item.RootParent == null) { w.WriteLine("SECTION WORLDITEM {0}", count); diff --git a/Projects/UOContent/Commands/Generic/Commands/Commands.cs b/Projects/UOContent/Commands/Generic/Commands/Commands.cs index 752c2e116..944b267b1 100644 --- a/Projects/UOContent/Commands/Generic/Commands/Commands.cs +++ b/Projects/UOContent/Commands/Generic/Commands/Commands.cs @@ -347,9 +347,7 @@ namespace Server.Commands.Generic { var result = Properties.IncreaseValue(e.Mobile, obj, e.Arguments); - if (result == "The property has been increased." || result == "The properties have been increased." || - result == "The property has been decreased." || result == "The properties have been decreased." || - result == "The properties have been changed.") + if (result is "The property has been increased." or "The properties have been increased." or "The property has been decreased." or "The properties have been decreased." or "The properties have been changed.") { AddResponse(result); } @@ -556,7 +554,7 @@ namespace Server.Commands.Generic public override void Execute(CommandEventArgs e, object obj) { - if (!(obj is IPoint3D p)) + if (obj is not IPoint3D p) { return; } @@ -588,7 +586,7 @@ namespace Server.Commands.Generic public override void Execute(CommandEventArgs e, object obj) { - if (!(obj is IPoint3D p)) + if (obj is not IPoint3D p) { return; } @@ -787,8 +785,7 @@ namespace Server.Commands.Generic { var result = Properties.GetValue(e.Mobile, obj, e.GetString(i)); - if (result == "Property not found." || result == "Property is write only." || - result.StartsWithOrdinal("Getting this property")) + if (result is "Property not found." or "Property is write only." || result.StartsWithOrdinal("Getting this property")) { LogFailure(result); } @@ -1285,7 +1282,7 @@ namespace Server.Commands.Generic public override void Execute(CommandEventArgs e, object obj) { - if (!(obj is Item item)) + if (obj is not Item item) { return; } diff --git a/Projects/UOContent/Commands/Generic/Commands/DesignInsert.cs b/Projects/UOContent/Commands/Generic/Commands/DesignInsert.cs index 7b31e855f..0a048ef51 100644 --- a/Projects/UOContent/Commands/Generic/Commands/DesignInsert.cs +++ b/Projects/UOContent/Commands/Generic/Commands/DesignInsert.cs @@ -35,7 +35,7 @@ namespace Server.Commands.Generic { house = null; - if (item == null || item is BaseMulti || item is HouseSign || staticsOnly && !(item is Static)) + if (item is null or BaseMulti or HouseSign || staticsOnly && item is not Static) { return DesignInsertResult.InvalidItem; } diff --git a/Projects/UOContent/Commands/Generic/Extensions/Compilers/ConditionalCompiler.cs b/Projects/UOContent/Commands/Generic/Extensions/Compilers/ConditionalCompiler.cs index 4343d359b..58ea93f35 100644 --- a/Projects/UOContent/Commands/Generic/Extensions/Compilers/ConditionalCompiler.cs +++ b/Projects/UOContent/Commands/Generic/Extensions/Compilers/ConditionalCompiler.cs @@ -325,7 +325,7 @@ namespace Server.Commands.Generic throw new InvalidOperationException("Invalid string comparison operator."); } - if (m_Operator == StringOperator.Equal || m_Operator == StringOperator.NotEqual) + if (m_Operator is StringOperator.Equal or StringOperator.NotEqual) { emitter.BeginCall( type.GetMethod( diff --git a/Projects/UOContent/Commands/Generic/Implementors/ContainedCommandImplementor.cs b/Projects/UOContent/Commands/Generic/Implementors/ContainedCommandImplementor.cs index f7598fb5a..bf0fcdb8b 100644 --- a/Projects/UOContent/Commands/Generic/Implementors/ContainedCommandImplementor.cs +++ b/Projects/UOContent/Commands/Generic/Implementors/ContainedCommandImplementor.cs @@ -44,7 +44,7 @@ namespace Server.Commands.Generic return; // sanity check } - if (!(targeted is Container cont)) + if (targeted is not Container cont) { from.SendMessage("That is not a container."); return; diff --git a/Projects/UOContent/Commands/Generic/Implementors/MultiCommandImplementor.cs b/Projects/UOContent/Commands/Generic/Implementors/MultiCommandImplementor.cs index 87a030a61..45558d8f7 100644 --- a/Projects/UOContent/Commands/Generic/Implementors/MultiCommandImplementor.cs +++ b/Projects/UOContent/Commands/Generic/Implementors/MultiCommandImplementor.cs @@ -46,7 +46,7 @@ namespace Server.Commands.Generic { case ObjectTypes.Both: { - if (!(targeted is Item || targeted is Mobile)) + if (!(targeted is Item or Mobile)) { from.SendMessage("This command does not work on that."); return; @@ -56,7 +56,7 @@ namespace Server.Commands.Generic } case ObjectTypes.Items: { - if (!(targeted is Item)) + if (targeted is not Item) { from.SendMessage("This command only works on items."); return; @@ -66,7 +66,7 @@ namespace Server.Commands.Generic } case ObjectTypes.Mobiles: { - if (!(targeted is Mobile)) + if (targeted is not Mobile) { from.SendMessage("This command only works on mobiles."); return; diff --git a/Projects/UOContent/Commands/Generic/Implementors/SerialCommandImplementor.cs b/Projects/UOContent/Commands/Generic/Implementors/SerialCommandImplementor.cs index 6ee458ea4..fca4324dd 100644 --- a/Projects/UOContent/Commands/Generic/Implementors/SerialCommandImplementor.cs +++ b/Projects/UOContent/Commands/Generic/Implementors/SerialCommandImplementor.cs @@ -52,7 +52,7 @@ namespace Server.Commands.Generic { case ObjectTypes.Items: { - if (!(obj is Item)) + if (obj is not Item) { e.Mobile.SendMessage("This command only works on items."); return; @@ -62,7 +62,7 @@ namespace Server.Commands.Generic } case ObjectTypes.Mobiles: { - if (!(obj is Mobile)) + if (obj is not Mobile) { e.Mobile.SendMessage("This command only works on mobiles."); return; diff --git a/Projects/UOContent/Commands/Generic/Implementors/SingleCommandImplementor.cs b/Projects/UOContent/Commands/Generic/Implementors/SingleCommandImplementor.cs index 11aeb43bb..3220cd28b 100644 --- a/Projects/UOContent/Commands/Generic/Implementors/SingleCommandImplementor.cs +++ b/Projects/UOContent/Commands/Generic/Implementors/SingleCommandImplementor.cs @@ -68,7 +68,7 @@ namespace Server.Commands.Generic { case ObjectTypes.Both: { - if (!(targeted is Item) && !(targeted is Mobile)) + if (targeted is not Item && targeted is not Mobile) { from.SendMessage("This command does not work on that."); return; @@ -78,7 +78,7 @@ namespace Server.Commands.Generic } case ObjectTypes.Items: { - if (!(targeted is Item)) + if (targeted is not Item) { from.SendMessage("This command only works on items."); return; @@ -88,7 +88,7 @@ namespace Server.Commands.Generic } case ObjectTypes.Mobiles: { - if (!(targeted is Mobile)) + if (targeted is not Mobile) { from.SendMessage("This command only works on mobiles."); return; diff --git a/Projects/UOContent/Commands/Handlers.cs b/Projects/UOContent/Commands/Handlers.cs index b289f9acd..94a7f9395 100644 --- a/Projects/UOContent/Commands/Handlers.cs +++ b/Projects/UOContent/Commands/Handlers.cs @@ -566,7 +566,7 @@ namespace Server.Commands { map = Map.AllMaps[i]; - if (map.MapIndex == 0x7F || map.MapIndex == 0xFF) + if (map.MapIndex is 0x7F or 0xFF) { continue; } @@ -595,7 +595,7 @@ namespace Server.Commands { map = Map.AllMaps[i]; - if (map.MapIndex == 0x7F || map.MapIndex == 0xFF || from.Map == map) + if (map.MapIndex is 0x7F or 0xFF || @from.Map == map) { continue; } @@ -629,7 +629,7 @@ namespace Server.Commands from.SendMessage("Region name not found"); } - else if (e.Length == 2 || e.Length == 3) + else if (e.Length is 2 or 3) { var map = from.Map; diff --git a/Projects/UOContent/Commands/HelpInfo.cs b/Projects/UOContent/Commands/HelpInfo.cs index 80ee82720..b85ca8b05 100644 --- a/Projects/UOContent/Commands/HelpInfo.cs +++ b/Projects/UOContent/Commands/HelpInfo.cs @@ -76,7 +76,7 @@ namespace Server.Commands continue; } - if (usage == null || !(attrs[0] is DescriptionAttribute desc)) + if (usage == null || attrs[0] is not DescriptionAttribute desc) { continue; } diff --git a/Projects/UOContent/Commands/LocationCommand.cs b/Projects/UOContent/Commands/LocationCommand.cs index 271dbd233..d74108741 100644 --- a/Projects/UOContent/Commands/LocationCommand.cs +++ b/Projects/UOContent/Commands/LocationCommand.cs @@ -23,14 +23,14 @@ namespace Server.Commands public override void Execute(CommandEventArgs e, object obj) { - if (!(obj is IPoint3D point)) + if (obj is not IPoint3D point) { LogFailure("That cannot be located."); return; } var label = $"(x:{point.X}, y:{point.Y}, z:{point.Z})"; - if (obj is LandTarget || obj is StaticTarget) + if (obj is LandTarget or StaticTarget) { List graphics; if (e.Arguments.Length == 0) diff --git a/Projects/UOContent/Commands/Logging.cs b/Projects/UOContent/Commands/Logging.cs index a1a5ab3d2..94f40d597 100644 --- a/Projects/UOContent/Commands/Logging.cs +++ b/Projects/UOContent/Commands/Logging.cs @@ -73,7 +73,7 @@ namespace Server.Commands var path = Core.BaseDirectory; - var name = !(from.Account is Account acct) ? from.Name : acct.Username; + var name = @from.Account is not Account acct ? from.Name : acct.Username; AppendPath(ref path, "Logs"); AppendPath(ref path, "Commands"); diff --git a/Projects/UOContent/Commands/Object Creation/Decorate.cs b/Projects/UOContent/Commands/Object Creation/Decorate.cs index 314bc011b..f8a14b4f2 100644 --- a/Projects/UOContent/Commands/Object Creation/Decorate.cs +++ b/Projects/UOContent/Commands/Object Creation/Decorate.cs @@ -1107,7 +1107,7 @@ namespace Server.Commands } } } - else if (srcItem is Teleporter || srcItem is FillableContainer || srcItem is BaseBook) + else if (srcItem is Teleporter or FillableContainer or BaseBook) { eable = map.GetItemsInRange(new Point3D(x, y, z), 0); diff --git a/Projects/UOContent/Commands/Object Creation/DecorateMag.cs b/Projects/UOContent/Commands/Object Creation/DecorateMag.cs index a1300cef3..fdea8e992 100644 --- a/Projects/UOContent/Commands/Object Creation/DecorateMag.cs +++ b/Projects/UOContent/Commands/Object Creation/DecorateMag.cs @@ -1103,7 +1103,7 @@ namespace Server.Commands } } } - else if (srcItem is Teleporter || srcItem is FillableContainer || srcItem is BaseBook) + else if (srcItem is Teleporter or FillableContainer or BaseBook) { eable = map.GetItemsInRange(new Point3D(x, y, z), 0); diff --git a/Projects/UOContent/Commands/Object Creation/GenTeleporter.cs b/Projects/UOContent/Commands/Object Creation/GenTeleporter.cs index f2542a731..daa84d9b0 100644 --- a/Projects/UOContent/Commands/Object Creation/GenTeleporter.cs +++ b/Projects/UOContent/Commands/Object Creation/GenTeleporter.cs @@ -124,7 +124,7 @@ namespace Server.Commands var count = 0; foreach (var item in eable) { - if (!(item is KeywordTeleporter || item is SkillTeleporter) && IsWithinZ(item.Z - worldLocation.Z)) + if (!(item is KeywordTeleporter or SkillTeleporter) && IsWithinZ(item.Z - worldLocation.Z)) { count++; item.Delete(); diff --git a/Projects/UOContent/Commands/Properties.cs b/Projects/UOContent/Commands/Properties.cs index 29d92e594..21a3e25b0 100644 --- a/Projects/UOContent/Commands/Properties.cs +++ b/Projects/UOContent/Commands/Properties.cs @@ -263,7 +263,7 @@ namespace Server.Commands { var obj = realProps[i].GetValue(realObjs[i], null); - if (!(obj is IConvertible)) + if (obj is not IConvertible) { return "Property is not IConvertable."; } diff --git a/Projects/UOContent/Commands/Statics.cs b/Projects/UOContent/Commands/Statics.cs index 015136f82..839bd0ec3 100644 --- a/Projects/UOContent/Commands/Statics.cs +++ b/Projects/UOContent/Commands/Statics.cs @@ -168,7 +168,7 @@ namespace Server continue; } - if (item is Static || item is BaseFloor || item is BaseWall) + if (item is Static or BaseFloor or BaseWall) { var itemMap = item.Map; @@ -212,7 +212,7 @@ namespace Server foreach (var item in eable) { - if (item is Static || item is BaseFloor || item is BaseWall) + if (item is Static or BaseFloor or BaseWall) { var itemMap = item.Map; @@ -306,7 +306,7 @@ namespace Server var xOffset = item.X - state.m_X * 8; var yOffset = item.Y - state.m_Y * 8; - if (xOffset < 0 || xOffset >= 8 || yOffset < 0 || yOffset >= 8) + if (xOffset is < 0 or >= 8 || yOffset is < 0 or >= 8) { continue; } diff --git a/Projects/UOContent/Commands/Wipe.cs b/Projects/UOContent/Commands/Wipe.cs index 693f4f3f5..bc066fbde 100644 --- a/Projects/UOContent/Commands/Wipe.cs +++ b/Projects/UOContent/Commands/Wipe.cs @@ -85,7 +85,7 @@ namespace Server.Commands foreach (var obj in eable) { - if (items && obj is Item && !(obj is BaseMulti || obj is HouseSign)) + if (items && obj is Item && !(obj is BaseMulti or HouseSign)) { toDelete.Add(obj); } diff --git a/Projects/UOContent/Engines/Bulk Orders/Books/BOBGump.cs b/Projects/UOContent/Engines/Bulk Orders/Books/BOBGump.cs index 71b5d4c54..442c1a2f3 100644 --- a/Projects/UOContent/Engines/Bulk Orders/Books/BOBGump.cs +++ b/Projects/UOContent/Engines/Bulk Orders/Books/BOBGump.cs @@ -709,7 +709,7 @@ namespace Server.Engines.BulkOrders var price = Utility.ToInt32(text); - if (price < 0 || price > 250000000) + if (price is < 0 or > 250000000) { from.SendLocalizedMessage(1062390); // The price you requested is outrageous! } diff --git a/Projects/UOContent/Engines/Bulk Orders/Books/BODBuyGump.cs b/Projects/UOContent/Engines/Bulk Orders/Books/BODBuyGump.cs index a9c3dc3ce..4b8a13b5c 100644 --- a/Projects/UOContent/Engines/Bulk Orders/Books/BODBuyGump.cs +++ b/Projects/UOContent/Engines/Bulk Orders/Books/BODBuyGump.cs @@ -46,7 +46,7 @@ namespace Server.Engines.BulkOrders return; } - if (!(m_Book.RootParent is PlayerVendor pv)) + if (m_Book.RootParent is not PlayerVendor pv) { m_From.SendLocalizedMessage(1062382); // The deed selected is not available. return; diff --git a/Projects/UOContent/Engines/Bulk Orders/Rewards.cs b/Projects/UOContent/Engines/Bulk Orders/Rewards.cs index 4aaae3152..627682830 100644 --- a/Projects/UOContent/Engines/Bulk Orders/Rewards.cs +++ b/Projects/UOContent/Engines/Bulk Orders/Rewards.cs @@ -533,7 +533,7 @@ namespace Server.Engines.BulkOrders private static Item CreatePowerScroll(int type) { - if (type == 5 || type == 10 || type == 15 || type == 20) + if (type is 5 or 10 or 15 or 20) { return new PowerScroll(SkillName.Blacksmith, 100 + type); } @@ -545,7 +545,7 @@ namespace Server.Engines.BulkOrders private static Item CreateAncientHammer(int type) { - if (type == 10 || type == 15 || type == 30 || type == 60) + if (type is 10 or 15 or 30 or 60) { return new AncientSmithyHammer(type); } @@ -848,7 +848,7 @@ namespace Server.Engines.BulkOrders private static Item CreatePowerScroll(int type) { - if (type == 5 || type == 10 || type == 15 || type == 20) + if (type is 5 or 10 or 15 or 20) { return new PowerScroll(SkillName.Tailoring, 100 + type); } diff --git a/Projects/UOContent/Engines/Bulk Orders/SmallBOD.cs b/Projects/UOContent/Engines/Bulk Orders/SmallBOD.cs index 15cb5d622..8f0489aa1 100644 --- a/Projects/UOContent/Engines/Bulk Orders/SmallBOD.cs +++ b/Projects/UOContent/Engines/Bulk Orders/SmallBOD.cs @@ -132,7 +132,7 @@ namespace Server.Engines.BulkOrders from.SendLocalizedMessage(1045166); } else if (Type == null || objectType != Type && !objectType.IsSubclassOf(Type) || - !(item is BaseWeapon) && !(item is BaseArmor) && !(item is BaseClothing)) + item is not BaseWeapon && item is not BaseArmor && item is not BaseClothing) { from.SendLocalizedMessage(1045169); // The item is not in the request. } diff --git a/Projects/UOContent/Engines/ConPVP/AcceptDuelGump.cs b/Projects/UOContent/Engines/ConPVP/AcceptDuelGump.cs index 50e6d845f..0203b4959 100644 --- a/Projects/UOContent/Engines/ConPVP/AcceptDuelGump.cs +++ b/Projects/UOContent/Engines/ConPVP/AcceptDuelGump.cs @@ -186,7 +186,7 @@ namespace Server.Engines.ConPVP if (info.IsSwitched(1)) { - if (!(m_Challenged is PlayerMobile pm)) + if (m_Challenged is not PlayerMobile pm) { return; } diff --git a/Projects/UOContent/Engines/ConPVP/DuelContext.cs b/Projects/UOContent/Engines/ConPVP/DuelContext.cs index 162d8fa4f..b745ad9af 100644 --- a/Projects/UOContent/Engines/ConPVP/DuelContext.cs +++ b/Projects/UOContent/Engines/ConPVP/DuelContext.cs @@ -99,7 +99,7 @@ namespace Server.Engines.ConPVP public static bool IsFreeConsume(Mobile mob) { - if (!(mob is PlayerMobile pm) || pm.DuelContext?.m_EventGame == null) + if (mob is not PlayerMobile pm || pm.DuelContext?.m_EventGame == null) { return false; } @@ -257,7 +257,7 @@ namespace Server.Engines.ConPVP public static bool AllowSpecialAbility(Mobile from, string name, bool message) { - if (!(from is PlayerMobile pm)) + if (@from is not PlayerMobile pm) { return true; } @@ -345,7 +345,7 @@ namespace Server.Engines.ConPVP return false; } - if (!(weapon is BaseRanged) && !Ruleset.GetOption("Weapons", "Melee")) + if (weapon is not BaseRanged && !Ruleset.GetOption("Weapons", "Melee")) { return false; } @@ -411,7 +411,7 @@ namespace Server.Engines.ConPVP return true; } - if (!(item is BaseRefreshPotion)) + if (item is not BaseRefreshPotion) { if (CantDoAnything(from)) { @@ -513,7 +513,7 @@ namespace Server.Engines.ConPVP return false; } - if (item is BasePotion && !(item is BaseExplosionPotion) && !(item is BaseRefreshPotion) && IsSuddenDeath) + if (item is BasePotion && item is not BaseExplosionPotion && item is not BaseRefreshPotion && IsSuddenDeath) { from.SendMessage(0x22, "You may not drink potions in sudden death."); return false; @@ -655,7 +655,7 @@ namespace Server.Engines.ConPVP public void Requip(Mobile from, Container cont) { - if (!(cont is Corpse corpse)) + if (cont is not Corpse corpse) { return; } @@ -670,7 +670,7 @@ namespace Server.Engines.ConPVP { var item = items[i]; - if (item.Layer == Layer.Hair || item.Layer == Layer.FacialHair || !item.Movable) + if (item.Layer is Layer.Hair or Layer.FacialHair || !item.Movable) { continue; } @@ -1295,7 +1295,7 @@ namespace Server.Engines.ConPVP private static void EventSink_Login(Mobile m) { - if (!(m is PlayerMobile pm)) + if (m is not PlayerMobile pm) { return; } @@ -1385,7 +1385,7 @@ namespace Server.Engines.ConPVP return; } - if (!(e.Mobile is PlayerMobile pm)) + if (e.Mobile is not PlayerMobile pm) { return; } @@ -2048,7 +2048,7 @@ namespace Server.Engines.ConPVP int number = item switch { BaseWeapon _ => 1062001, // You can no longer wield your ~1_WEAPON~ - _ when !(item is BaseShield) && (item is BaseArmor || item is BaseClothing) => 1062002, // You can no longer wear your ~1_ARMOR~ + not BaseShield when item is BaseArmor or BaseClothing => 1062002, // You can no longer wear your ~1_ARMOR~ _ => 1062003 // You can no longer equip your ~1_SHIELD~ }; @@ -2403,7 +2403,7 @@ namespace Server.Engines.ConPVP m_GateFacet = Initiator.Map; } - if (!(arena.Teleporter is ExitTeleporter tp)) + if (arena.Teleporter is not ExitTeleporter tp) { arena.Teleporter = tp = new ExitTeleporter(); tp.MoveToWorld(arena.GateOut == Point3D.Zero ? arena.Outside : arena.GateOut, arena.Facet); diff --git a/Projects/UOContent/Engines/ConPVP/Games/BombingRun.cs b/Projects/UOContent/Engines/ConPVP/Games/BombingRun.cs index 04921fc64..6d764eb62 100644 --- a/Projects/UOContent/Engines/ConPVP/Games/BombingRun.cs +++ b/Projects/UOContent/Engines/ConPVP/Games/BombingRun.cs @@ -210,7 +210,7 @@ namespace Server.Engines.ConPVP return false; } - if (!(obj is IPoint3D)) + if (obj is not IPoint3D) { return false; } @@ -1680,7 +1680,7 @@ namespace Server.Engines.ConPVP public int GetTeamID(Mobile mob) { - if (!(mob is PlayerMobile pm)) + if (mob is not PlayerMobile pm) { return mob is BaseCreature creature ? creature.Team - 1 : -1; } diff --git a/Projects/UOContent/Engines/ConPVP/Games/CTF.cs b/Projects/UOContent/Engines/ConPVP/Games/CTF.cs index ac45f1a4c..cd1a1fec8 100644 --- a/Projects/UOContent/Engines/ConPVP/Games/CTF.cs +++ b/Projects/UOContent/Engines/ConPVP/Games/CTF.cs @@ -953,7 +953,7 @@ namespace Server.Engines.ConPVP public int GetTeamID(Mobile mob) { - if (!(mob is PlayerMobile pm)) + if (mob is not PlayerMobile pm) { return -1; } diff --git a/Projects/UOContent/Engines/ConPVP/Games/DoubleDom.cs b/Projects/UOContent/Engines/ConPVP/Games/DoubleDom.cs index e248a8487..e40af18e0 100644 --- a/Projects/UOContent/Engines/ConPVP/Games/DoubleDom.cs +++ b/Projects/UOContent/Engines/ConPVP/Games/DoubleDom.cs @@ -553,7 +553,7 @@ namespace Server.Engines.ConPVP public int GetTeamID(Mobile mob) { - if (!(mob is PlayerMobile pm)) + if (mob is not PlayerMobile pm) { return -1; } diff --git a/Projects/UOContent/Engines/ConPVP/Games/KingOfTheHill.cs b/Projects/UOContent/Engines/ConPVP/Games/KingOfTheHill.cs index 6d95d1630..3202e5b98 100644 --- a/Projects/UOContent/Engines/ConPVP/Games/KingOfTheHill.cs +++ b/Projects/UOContent/Engines/ConPVP/Games/KingOfTheHill.cs @@ -924,7 +924,7 @@ namespace Server.Engines.ConPVP public int GetTeamID(Mobile mob) { - if (!(mob is PlayerMobile pm)) + if (mob is not PlayerMobile pm) { return mob is BaseCreature creature ? creature.Team - 1 : -1; } diff --git a/Projects/UOContent/Engines/ConPVP/Gumps/AcceptTeamGump.cs b/Projects/UOContent/Engines/ConPVP/Gumps/AcceptTeamGump.cs index d05be1836..28a6c2794 100644 --- a/Projects/UOContent/Engines/ConPVP/Gumps/AcceptTeamGump.cs +++ b/Projects/UOContent/Engines/ConPVP/Gumps/AcceptTeamGump.cs @@ -318,7 +318,7 @@ namespace Server.Engines.ConPVP if (info.IsSwitched(1)) { - if (!(mob is PlayerMobile pm)) + if (mob is not PlayerMobile pm) { return; } diff --git a/Projects/UOContent/Engines/ConPVP/Gumps/ConfirmSignupGump.cs b/Projects/UOContent/Engines/ConPVP/Gumps/ConfirmSignupGump.cs index 40554a6b4..04e235ac6 100644 --- a/Projects/UOContent/Engines/ConPVP/Gumps/ConfirmSignupGump.cs +++ b/Projects/UOContent/Engines/ConPVP/Gumps/ConfirmSignupGump.cs @@ -565,7 +565,7 @@ namespace Server.Engines.ConPVP private void AddPlayer_OnTarget(Mobile from, object obj) { - if (!(obj is Mobile mob) || mob == from) + if (obj is not Mobile mob || mob == from) { m_From.SendGump(new ConfirmSignupGump(m_From, m_Registrar, m_Tournament, m_Players)); @@ -604,7 +604,7 @@ namespace Server.Engines.ConPVP } else { - if (!(mob is PlayerMobile pm)) + if (mob is not PlayerMobile pm) { return; } diff --git a/Projects/UOContent/Engines/ConPVP/Gumps/ParticipantGump.cs b/Projects/UOContent/Engines/ConPVP/Gumps/ParticipantGump.cs index 390a3a7f3..3c89caa3b 100644 --- a/Projects/UOContent/Engines/ConPVP/Gumps/ParticipantGump.cs +++ b/Projects/UOContent/Engines/ConPVP/Gumps/ParticipantGump.cs @@ -217,7 +217,7 @@ namespace Server.Engines.ConPVP return; } - if (!(targeted is Mobile mob)) + if (targeted is not Mobile mob) { from.SendMessage("That is not a player."); } @@ -238,7 +238,7 @@ namespace Server.Engines.ConPVP } else { - if (!(mob is PlayerMobile pm)) + if (mob is not PlayerMobile pm) { return; } diff --git a/Projects/UOContent/Engines/ConPVP/Gumps/ReadyUpGump.cs b/Projects/UOContent/Engines/ConPVP/Gumps/ReadyUpGump.cs index afc9acd46..735379d2e 100644 --- a/Projects/UOContent/Engines/ConPVP/Gumps/ReadyUpGump.cs +++ b/Projects/UOContent/Engines/ConPVP/Gumps/ReadyUpGump.cs @@ -211,7 +211,7 @@ namespace Server.Engines.ConPVP { case 1: // okay { - if (!(m_From is PlayerMobile pm)) + if (m_From is not PlayerMobile pm) { break; } diff --git a/Projects/UOContent/Engines/ConPVP/Gumps/TournamentBracketGump.cs b/Projects/UOContent/Engines/ConPVP/Gumps/TournamentBracketGump.cs index 8da52acff..9dc149ce8 100644 --- a/Projects/UOContent/Engines/ConPVP/Gumps/TournamentBracketGump.cs +++ b/Projects/UOContent/Engines/ConPVP/Gumps/TournamentBracketGump.cs @@ -306,7 +306,7 @@ namespace Server.Engines.ConPVP } case TourneyBracketGumpType.Participant_Info: { - if (!(obj is TourneyParticipant part)) + if (obj is not TourneyParticipant part) { break; } @@ -380,7 +380,7 @@ namespace Server.Engines.ConPVP AddLeftArrow(25, 11, ToButtonID(0, 3)); AddHtml(25, 35, 250, 20, Center("Participants")); - if (!(obj is Mobile mob)) + if (obj is not Mobile mob) { break; } @@ -428,7 +428,7 @@ namespace Server.Engines.ConPVP AddLeftArrow(25, 11, ToButtonID(0, 2)); AddHtml(25, 35, 250, 20, Center("Rounds")); - if (!(m_Object is PyramidLevel level)) + if (m_Object is not PyramidLevel level) { break; } @@ -490,9 +490,7 @@ namespace Server.Engines.ConPVP } } else if (m_Tournament.EventController != null || - m_Tournament.TourneyType == TourneyType.RandomTeam || - m_Tournament.TourneyType == TourneyType.RedVsBlue || - m_Tournament.TourneyType == TourneyType.Faction) + m_Tournament.TourneyType is TourneyType.RandomTeam or TourneyType.RedVsBlue or TourneyType.Faction) { for (var j = 0; j < match.Participants.Count; ++j) { @@ -572,7 +570,7 @@ namespace Server.Engines.ConPVP } case TourneyBracketGumpType.Match_Info: { - if (!(obj is TourneyMatch match)) + if (obj is not TourneyMatch match) { break; } @@ -605,9 +603,7 @@ namespace Server.Engines.ConPVP } } else if (m_Tournament.EventController != null || - m_Tournament.TourneyType == TourneyType.RandomTeam || - m_Tournament.TourneyType == TourneyType.RedVsBlue || - m_Tournament.TourneyType == TourneyType.Faction) + m_Tournament.TourneyType is TourneyType.RandomTeam or TourneyType.RedVsBlue or TourneyType.Faction) { for (var i = 0; i < match.Participants.Count; ++i) { @@ -840,7 +836,7 @@ namespace Server.Engines.ConPVP } case 5: { - if (!(m_Object is TourneyMatch match)) + if (m_Object is not TourneyMatch match) { break; } @@ -990,7 +986,7 @@ namespace Server.Engines.ConPVP break; } - if (!(m_Object is PyramidLevel level)) + if (m_Object is not PyramidLevel level) { break; } diff --git a/Projects/UOContent/Engines/ConPVP/Ladder.cs b/Projects/UOContent/Engines/ConPVP/Ladder.cs index ca42ee278..5e76003e7 100644 --- a/Projects/UOContent/Engines/ConPVP/Ladder.cs +++ b/Projects/UOContent/Engines/ConPVP/Ladder.cs @@ -211,7 +211,7 @@ namespace Server.Engines.ConPVP { var x = ourLevel - theirLevel; - if (x < -6 || x > +6) + if (x is < -6 or > +6) { return 0; } diff --git a/Projects/UOContent/Engines/ConPVP/TournamentPyramid.cs b/Projects/UOContent/Engines/ConPVP/TournamentPyramid.cs index 8c73047d4..0f1e9d646 100644 --- a/Projects/UOContent/Engines/ConPVP/TournamentPyramid.cs +++ b/Projects/UOContent/Engines/ConPVP/TournamentPyramid.cs @@ -16,7 +16,7 @@ namespace Server.Engines.ConPVP { var copy = new List(participants); - if (groupType == GroupingType.Nearest || groupType == GroupingType.HighVsLow) + if (groupType is GroupingType.Nearest or GroupingType.HighVsLow) { copy.Sort(); } diff --git a/Projects/UOContent/Engines/Craft/Core/CraftItem.cs b/Projects/UOContent/Engines/Craft/Core/CraftItem.cs index f108acaa8..cece9b8dd 100644 --- a/Projects/UOContent/Engines/Craft/Core/CraftItem.cs +++ b/Projects/UOContent/Engines/Craft/Core/CraftItem.cs @@ -483,7 +483,7 @@ namespace Server.Engines.Craft for (var j = 0; j < items[i].Length; ++j) { - if (!(items[i][j] is IHasQuantity hq)) + if (items[i][j] is not IHasQuantity hq) { totals[i] += items[i][j].Amount; } @@ -512,7 +512,7 @@ namespace Server.Engines.Craft { var item = items[i][j]; - if (!(item is IHasQuantity hq)) + if (item is not IHasQuantity hq) { var theirAmount = item.Amount; @@ -561,7 +561,7 @@ namespace Server.Engines.Craft for (var i = 0; i < items.Length; ++i) { - if (!(items[i] is IHasQuantity hq)) + if (items[i] is not IHasQuantity hq) { amount += items[i].Amount; } diff --git a/Projects/UOContent/Engines/Craft/Core/Enhance.cs b/Projects/UOContent/Engines/Craft/Core/Enhance.cs index a9a160098..c5a6c0377 100644 --- a/Projects/UOContent/Engines/Craft/Core/Enhance.cs +++ b/Projects/UOContent/Engines/Craft/Core/Enhance.cs @@ -35,7 +35,7 @@ namespace Server.Engines.Craft return EnhanceResult.NotInBackpack; } - if (!(item is BaseArmor) && !(item is BaseWeapon)) + if (item is not BaseArmor && item is not BaseWeapon) { return EnhanceResult.BadItem; } diff --git a/Projects/UOContent/Engines/Craft/Core/Repair.cs b/Projects/UOContent/Engines/Craft/Core/Repair.cs index a967556f2..391b76382 100644 --- a/Projects/UOContent/Engines/Craft/Core/Repair.cs +++ b/Projects/UOContent/Engines/Craft/Core/Repair.cs @@ -90,11 +90,7 @@ namespace Server.Engines.Craft if (m_CraftSystem is DefTailoring) { - return clothing is BearMask - || clothing is DeerMask - || clothing is TheMostKnowledgePerson - || clothing is TheRobeOfBritanniaAri - || clothing is EmbroideredOakLeafCloak; + return clothing is BearMask or DeerMask or TheMostKnowledgePerson or TheRobeOfBritanniaAri or EmbroideredOakLeafCloak; } return false; @@ -106,44 +102,23 @@ namespace Server.Engines.Craft if (m_CraftSystem is DefTinkering) { - return weapon is Cleaver - || weapon is Hatchet - || weapon is Pickaxe - || weapon is ButcherKnife - || weapon is SkinningKnife; + return weapon is Cleaver or Hatchet or Pickaxe or ButcherKnife or SkinningKnife; } if (m_CraftSystem is DefCarpentry) { - return weapon is Club - || weapon is BlackStaff - || weapon is MagicWand - - // TODO: Make these items craftable - || weapon is WildStaff; + return weapon is Club or BlackStaff or MagicWand or WildStaff; } if (m_CraftSystem is DefBlacksmithy) { - return weapon is Pitchfork - - // TODO: Make these items craftable - || weapon is RadiantScimitar - || weapon is WarCleaver - || weapon is ElvenSpellblade - || weapon is AssassinSpike - || weapon is Leafblade - || weapon is RuneBlade - || weapon is ElvenMachete - || weapon is OrnateAxe - || weapon is DiamondMace; + return weapon is Pitchfork or RadiantScimitar or WarCleaver or ElvenSpellblade or AssassinSpike or Leafblade or RuneBlade or ElvenMachete or OrnateAxe or DiamondMace; } // TODO: Make these items craftable if (m_CraftSystem is DefBowFletching) { - return weapon is ElvenCompositeLongbow - || weapon is MagicalShortbow; + return weapon is ElvenCompositeLongbow or MagicalShortbow; } return false; @@ -156,36 +131,17 @@ namespace Server.Engines.Craft // TODO: Make these items craftable if (m_CraftSystem is DefTailoring) { - return armor is LeafTonlet - || armor is LeafArms - || armor is LeafChest - || armor is LeafGloves - || armor is LeafGorget - || armor is LeafLegs - || armor is HideChest - || armor is HideGloves - || armor is HideGorget - || armor is HidePants - || armor is HidePauldrons; + return armor is LeafTonlet or LeafArms or LeafChest or LeafGloves or LeafGorget or LeafLegs or HideChest or HideGloves or HideGorget or HidePants or HidePauldrons; } if (m_CraftSystem is DefCarpentry) { - return armor is WingedHelm - || armor is RavenHelm - || armor is VultureHelm - || armor is WoodlandArms - || armor is WoodlandChest - || armor is WoodlandGloves - || armor is WoodlandGorget - || armor is WoodlandLegs; + return armor is WingedHelm or RavenHelm or VultureHelm or WoodlandArms or WoodlandChest or WoodlandGloves or WoodlandGorget or WoodlandLegs; } if (m_CraftSystem is DefBlacksmithy) { - return armor is Circlet - || armor is RoyalCirclet - || armor is GemmedCirclet; + return armor is Circlet or RoyalCirclet or GemmedCirclet; } return false; @@ -448,7 +404,7 @@ namespace Server.Engines.Craft } if (m_CraftSystem.CraftItems.SearchForSubclass(clothing.GetType()) == null && - !IsSpecialClothing(clothing) && !(clothing is TribalMask || clothing is HornedTribalMask)) + !IsSpecialClothing(clothing) && !(clothing is TribalMask or HornedTribalMask)) { number = usingDeed ? 1061136 diff --git a/Projects/UOContent/Engines/Craft/DefCarpentry.cs b/Projects/UOContent/Engines/Craft/DefCarpentry.cs index 23d303a68..95e1a76f6 100644 --- a/Projects/UOContent/Engines/Craft/DefCarpentry.cs +++ b/Projects/UOContent/Engines/Craft/DefCarpentry.cs @@ -87,7 +87,7 @@ namespace Server.Engines.Craft int index; // Other Items - if (Core.Expansion == Expansion.AOS || Core.Expansion == Expansion.SE) + if (Core.Expansion is Expansion.AOS or Expansion.SE) { index = AddCraft(typeof(Board), 1044294, 1027127, 0.0, 0.0, typeof(Log), 1044466, 1, 1044465); SetUseAllRes(index, true); diff --git a/Projects/UOContent/Engines/Doom/GauntletSpawner.cs b/Projects/UOContent/Engines/Doom/GauntletSpawner.cs index 705a9ca67..76d27f205 100644 --- a/Projects/UOContent/Engines/Doom/GauntletSpawner.cs +++ b/Projects/UOContent/Engines/Doom/GauntletSpawner.cs @@ -235,7 +235,7 @@ namespace Server.Engines.Doom _ => new MushroomTrap() }; - if (trap is FireColumnTrap || trap is MushroomTrap) + if (trap is FireColumnTrap or MushroomTrap) { trap.Hue = 0x451; } diff --git a/Projects/UOContent/Engines/Doom/LeverPuzzle/LeverPuzzleRegions.cs b/Projects/UOContent/Engines/Doom/LeverPuzzle/LeverPuzzleRegions.cs index 781cf752d..37745ce61 100644 --- a/Projects/UOContent/Engines/Doom/LeverPuzzle/LeverPuzzleRegions.cs +++ b/Projects/UOContent/Engines/Doom/LeverPuzzle/LeverPuzzleRegions.cs @@ -31,7 +31,7 @@ namespace Server.Engines.Doom public override void OnEnter(Mobile m) { - if (m == null || m is WandererOfTheVoid) + if (m is null or WandererOfTheVoid) { return; } diff --git a/Projects/UOContent/Engines/Ethics/Core/Ethic.cs b/Projects/UOContent/Engines/Ethics/Core/Ethic.cs index e14ea51bf..59e2da0f5 100644 --- a/Projects/UOContent/Engines/Ethics/Core/Ethic.cs +++ b/Projects/UOContent/Engines/Ethics/Core/Ethic.cs @@ -160,7 +160,7 @@ namespace Server.Ethics foreach (var item in eable) { - if (item is AnkhNorth || item is AnkhWest) + if (item is AnkhNorth or AnkhWest) { found = true; break; diff --git a/Projects/UOContent/Engines/Ethics/Evil/Ethic.cs b/Projects/UOContent/Engines/Ethics/Evil/Ethic.cs index e895cad31..211cfa42a 100644 --- a/Projects/UOContent/Engines/Ethics/Evil/Ethic.cs +++ b/Projects/UOContent/Engines/Ethics/Evil/Ethic.cs @@ -29,7 +29,7 @@ namespace Server.Ethics.Evil { var fac = Faction.Find(mob); - return fac is Minax || fac is Shadowlords; + return fac is Minax or Shadowlords; } } } diff --git a/Projects/UOContent/Engines/Ethics/Evil/Powers/Blight.cs b/Projects/UOContent/Engines/Ethics/Evil/Powers/Blight.cs index 0d3cfc296..0dddf0575 100644 --- a/Projects/UOContent/Engines/Ethics/Evil/Powers/Blight.cs +++ b/Projects/UOContent/Engines/Ethics/Evil/Powers/Blight.cs @@ -23,7 +23,7 @@ namespace Server.Ethics.Evil private void Power_OnTarget(Mobile fromMobile, object obj, Player from) { - if (!(obj is IPoint3D p)) + if (obj is not IPoint3D p) { return; } diff --git a/Projects/UOContent/Engines/Ethics/Evil/Powers/UnholyItem.cs b/Projects/UOContent/Engines/Ethics/Evil/Powers/UnholyItem.cs index 59259b19e..a46e3cbb0 100644 --- a/Projects/UOContent/Engines/Ethics/Evil/Powers/UnholyItem.cs +++ b/Projects/UOContent/Engines/Ethics/Evil/Powers/UnholyItem.cs @@ -22,7 +22,7 @@ namespace Server.Ethics.Evil private void Power_OnTarget(Mobile fromMobile, object obj, Player from) { - if (!(obj is Item item)) + if (obj is not Item item) { from.Mobile.LocalOverheadMessage(MessageType.Regular, 0x3B2, false, "You may not imbue that."); return; @@ -45,7 +45,7 @@ namespace Server.Ethics.Evil return; } - var canImbue = (item is Spellbook || item is BaseClothing || item is BaseArmor || item is BaseWeapon) && + var canImbue = item is Spellbook or BaseClothing or BaseArmor or BaseWeapon && item.Name == null; if (canImbue) diff --git a/Projects/UOContent/Engines/Ethics/Hero/Ethic.cs b/Projects/UOContent/Engines/Ethics/Hero/Ethic.cs index 0a8275be5..e473b00d9 100644 --- a/Projects/UOContent/Engines/Ethics/Hero/Ethic.cs +++ b/Projects/UOContent/Engines/Ethics/Hero/Ethic.cs @@ -34,7 +34,7 @@ namespace Server.Ethics.Hero var fac = Faction.Find(mob); - return fac is TrueBritannians || fac is CouncilOfMages; + return fac is TrueBritannians or CouncilOfMages; } } } diff --git a/Projects/UOContent/Engines/Ethics/Hero/Powers/Bless.cs b/Projects/UOContent/Engines/Ethics/Hero/Powers/Bless.cs index 2c341a2da..f0c23cb73 100644 --- a/Projects/UOContent/Engines/Ethics/Hero/Powers/Bless.cs +++ b/Projects/UOContent/Engines/Ethics/Hero/Powers/Bless.cs @@ -23,7 +23,7 @@ namespace Server.Ethics.Hero private void Power_OnTarget(Mobile fromMobile, object obj, Player from) { - if (!(obj is IPoint3D p)) + if (obj is not IPoint3D p) { return; } diff --git a/Projects/UOContent/Engines/Ethics/Hero/Powers/HolyItem.cs b/Projects/UOContent/Engines/Ethics/Hero/Powers/HolyItem.cs index 9e85c4444..e927651ef 100644 --- a/Projects/UOContent/Engines/Ethics/Hero/Powers/HolyItem.cs +++ b/Projects/UOContent/Engines/Ethics/Hero/Powers/HolyItem.cs @@ -22,7 +22,7 @@ namespace Server.Ethics.Hero private void Power_OnTarget(Mobile fromMobile, object obj, Player from) { - if (!(obj is Item item)) + if (obj is not Item item) { from.Mobile.LocalOverheadMessage(MessageType.Regular, 0x3B2, false, "You may not imbue that."); return; @@ -45,7 +45,7 @@ namespace Server.Ethics.Hero return; } - var canImbue = (item is Spellbook || item is BaseClothing || item is BaseArmor || item is BaseWeapon) && + var canImbue = item is Spellbook or BaseClothing or BaseArmor or BaseWeapon && item.Name == null; if (canImbue) diff --git a/Projects/UOContent/Engines/Factions/Core/Faction.cs b/Projects/UOContent/Engines/Factions/Core/Faction.cs index 967951e57..43d67c6ca 100644 --- a/Projects/UOContent/Engines/Factions/Core/Faction.cs +++ b/Projects/UOContent/Engines/Factions/Core/Faction.cs @@ -502,7 +502,7 @@ namespace Server.Factions public static bool IsFactionBanned(Mobile mob) { - if (!(mob.Account is Account acct)) + if (mob.Account is not Account acct) { return false; } @@ -512,7 +512,7 @@ namespace Server.Factions public void OnJoinAccepted(Mobile mob) { - if (!(mob is PlayerMobile pm)) + if (mob is not PlayerMobile pm) { return; // sanity } @@ -571,7 +571,7 @@ namespace Server.Factions for (var i = 0; i < members.Count; ++i) { - if (!(members[i] is PlayerMobile member)) + if (members[i] is not PlayerMobile member) { continue; } @@ -767,7 +767,7 @@ namespace Server.Factions foreach (var item in World.Items.Values) { - if (item is IFactionItem && !(item is HoodedShroudOfShadows)) + if (item is IFactionItem && item is not HoodedShroudOfShadows) { items.Add(item); } diff --git a/Projects/UOContent/Engines/Factions/Core/FactionItem.cs b/Projects/UOContent/Engines/Factions/Core/FactionItem.cs index f84925ed2..6d02f0948 100644 --- a/Projects/UOContent/Engines/Factions/Core/FactionItem.cs +++ b/Projects/UOContent/Engines/Factions/Core/FactionItem.cs @@ -129,7 +129,7 @@ namespace Server.Factions public static Item Imbue(Item item, Faction faction, bool expire, int hue) { - if (!(item is IFactionItem)) + if (item is not IFactionItem) { return item; } diff --git a/Projects/UOContent/Engines/Factions/Gumps/LeaveFactionGump.cs b/Projects/UOContent/Engines/Factions/Gumps/LeaveFactionGump.cs index f13ffa4b8..9e3a5b667 100644 --- a/Projects/UOContent/Engines/Factions/Gumps/LeaveFactionGump.cs +++ b/Projects/UOContent/Engines/Factions/Gumps/LeaveFactionGump.cs @@ -50,7 +50,7 @@ namespace Server.Factions { case 1: // continue { - if (!(m_From.Guild is Guild guild)) + if (m_From.Guild is not Guild guild) { var pl = PlayerState.Find(m_From); diff --git a/Projects/UOContent/Engines/Factions/Items/Power Faction Items/StormsEye.cs b/Projects/UOContent/Engines/Factions/Items/Power Faction Items/StormsEye.cs index fef72f966..5d6d2729b 100644 --- a/Projects/UOContent/Engines/Factions/Items/Power Faction Items/StormsEye.cs +++ b/Projects/UOContent/Engines/Factions/Items/Power Faction Items/StormsEye.cs @@ -32,7 +32,7 @@ namespace Server TargetFlags.None, (from, obj, stormsEye) => { - if (!stormsEye.Movable || stormsEye.Deleted || !(obj is IPoint3D pt)) + if (!stormsEye.Movable || stormsEye.Deleted || obj is not IPoint3D pt) { return; } diff --git a/Projects/UOContent/Engines/Factions/Mobiles/Guards/GuardAI.cs b/Projects/UOContent/Engines/Factions/Mobiles/Guards/GuardAI.cs index 1b437d591..83ff2454b 100644 --- a/Projects/UOContent/Engines/Factions/Mobiles/Guards/GuardAI.cs +++ b/Projects/UOContent/Engines/Factions/Mobiles/Guards/GuardAI.cs @@ -156,7 +156,7 @@ namespace Server.Factions return false; } - if (m_Guard.Weapon is Item weapon && weapon.Parent == m_Guard && !(weapon is Fists)) + if (m_Guard.Weapon is Item weapon && weapon.Parent == m_Guard && weapon is not Fists) { pack.DropItem(weapon); return true; diff --git a/Projects/UOContent/Engines/Harvest/Core/HarvestTarget.cs b/Projects/UOContent/Engines/Harvest/Core/HarvestTarget.cs index c5790a8ac..a5a8a4a80 100644 --- a/Projects/UOContent/Engines/Harvest/Core/HarvestTarget.cs +++ b/Projects/UOContent/Engines/Harvest/Core/HarvestTarget.cs @@ -25,13 +25,12 @@ namespace Server.Engines.Harvest var itemID = target.ItemID; // grave - if (itemID == 0xED3 || itemID == 0xEDF || itemID == 0xEE0 || itemID == 0xEE1 || itemID == 0xEE2 || - itemID == 0xEE8) + if (itemID is 0xED3 or 0xEDF or 0xEE0 or 0xEE1 or 0xEE2 or 0xEE8) { if (from is PlayerMobile player) { var qs = player.Quest; - if (!(qs is WitchApprenticeQuest)) + if (qs is not WitchApprenticeQuest) { return; } diff --git a/Projects/UOContent/Engines/Harvest/Fishing.cs b/Projects/UOContent/Engines/Harvest/Fishing.cs index a4847df90..035f21e4d 100644 --- a/Projects/UOContent/Engines/Harvest/Fishing.cs +++ b/Projects/UOContent/Engines/Harvest/Fishing.cs @@ -350,7 +350,7 @@ namespace Server.Engines.Harvest public override bool Give(Mobile m, Item item, bool placeAtFeet) { - if (item is TreasureMap || item is MessageInABottle || item is SpecialFishingNet) + if (item is TreasureMap or MessageInABottle or SpecialFishingNet) { BaseCreature serp; @@ -395,7 +395,7 @@ namespace Server.Engines.Harvest return true; // we don't want to give the item to the player, it's on the serpent } - return base.Give(m, item, placeAtFeet || item is BigFish || item is WoodenChest || item is MetalGoldenChest); + return base.Give(m, item, placeAtFeet || item is BigFish or WoodenChest or MetalGoldenChest); } public override void SendSuccessTo(Mobile from, Item item, HarvestResource resource) @@ -405,7 +405,7 @@ namespace Server.Engines.Harvest from.SendLocalizedMessage(1042635); // Your fishing pole bends as you pull a big fish from the depths! fish.Fisher = from; } - else if (item is WoodenChest || item is MetalGoldenChest) + else if (item is WoodenChest or MetalGoldenChest) { from.SendLocalizedMessage(503175); // You pull up a heavy chest from the depths of the ocean! } diff --git a/Projects/UOContent/Engines/Harvest/Lumberjacking.cs b/Projects/UOContent/Engines/Harvest/Lumberjacking.cs index dd4c3c2a7..3e046f494 100644 --- a/Projects/UOContent/Engines/Harvest/Lumberjacking.cs +++ b/Projects/UOContent/Engines/Harvest/Lumberjacking.cs @@ -169,7 +169,7 @@ namespace Server.Engines.Harvest { item.LabelTo(from, 500464); // Use this on corpses to carve away meat and hide } - else if (toHarvest is StaticTarget || toHarvest is LandTarget) + else if (toHarvest is StaticTarget or LandTarget) { from.SendLocalizedMessage(500489); // You can't use an axe on that. } diff --git a/Projects/UOContent/Engines/Help/PageQueue.cs b/Projects/UOContent/Engines/Help/PageQueue.cs index 176337323..dee5f13ad 100644 --- a/Projects/UOContent/Engines/Help/PageQueue.cs +++ b/Projects/UOContent/Engines/Help/PageQueue.cs @@ -128,7 +128,7 @@ namespace Server.Engines.Help public static bool CheckAllowedToPage(Mobile from) { - if (!(from is PlayerMobile pm)) + if (@from is not PlayerMobile pm) { return true; } diff --git a/Projects/UOContent/Engines/Help/SpeechLog.cs b/Projects/UOContent/Engines/Help/SpeechLog.cs index 15b3f7848..a83940620 100644 --- a/Projects/UOContent/Engines/Help/SpeechLog.cs +++ b/Projects/UOContent/Engines/Help/SpeechLog.cs @@ -90,7 +90,7 @@ namespace Server.Engines.Help protected override void OnTarget(Mobile from, object targeted) { - if (!(targeted is PlayerMobile pm)) + if (targeted is not PlayerMobile pm) { from.SendMessage("Speech logs aren't supported on that target."); } diff --git a/Projects/UOContent/Engines/ML Quests/Gumps/QuestOfferGump.cs b/Projects/UOContent/Engines/ML Quests/Gumps/QuestOfferGump.cs index 45ade8384..69e9e2376 100644 --- a/Projects/UOContent/Engines/ML Quests/Gumps/QuestOfferGump.cs +++ b/Projects/UOContent/Engines/ML Quests/Gumps/QuestOfferGump.cs @@ -36,7 +36,7 @@ namespace Server.Engines.MLQuests.Gumps public override void OnResponse(NetState sender, RelayInfo info) { - if (!(sender.Mobile is PlayerMobile pm)) + if (sender.Mobile is not PlayerMobile pm) { return; } diff --git a/Projects/UOContent/Engines/ML Quests/Gumps/RaceChangeGump.cs b/Projects/UOContent/Engines/ML Quests/Gumps/RaceChangeGump.cs index 4bd855321..b6759c71c 100644 --- a/Projects/UOContent/Engines/ML Quests/Gumps/RaceChangeGump.cs +++ b/Projects/UOContent/Engines/ML Quests/Gumps/RaceChangeGump.cs @@ -202,7 +202,7 @@ namespace Server.Engines.MLQuests.Gumps CloseCurrent(state); - if (!(state.Mobile is PlayerMobile pm)) + if (state.Mobile is not PlayerMobile pm) { return; } @@ -325,7 +325,7 @@ namespace Server.Engines.MLQuests.Gumps public override void OnDoubleClick(Mobile from) { - if (!(from is PlayerMobile pm)) + if (@from is not PlayerMobile pm) { return; } diff --git a/Projects/UOContent/Engines/ML Quests/Items/PrismaticCrystal.cs b/Projects/UOContent/Engines/ML Quests/Items/PrismaticCrystal.cs index 791eb6dcf..64978b443 100644 --- a/Projects/UOContent/Engines/ML Quests/Items/PrismaticCrystal.cs +++ b/Projects/UOContent/Engines/ML Quests/Items/PrismaticCrystal.cs @@ -22,7 +22,7 @@ namespace Server.Items public override void OnDoubleClick(Mobile from) { - if (!(from is PlayerMobile pm) || pm.Backpack == null) + if (@from is not PlayerMobile pm || pm.Backpack == null) { return; } diff --git a/Projects/UOContent/Engines/ML Quests/Items/Teleporters.cs b/Projects/UOContent/Engines/ML Quests/Items/Teleporters.cs index a1dd82869..dc7262333 100644 --- a/Projects/UOContent/Engines/ML Quests/Items/Teleporters.cs +++ b/Projects/UOContent/Engines/ML Quests/Items/Teleporters.cs @@ -55,7 +55,7 @@ namespace Server.Engines.MLQuests.Items return true; } - if (!(m is PlayerMobile pm)) + if (m is not PlayerMobile pm) { return false; } diff --git a/Projects/UOContent/Engines/ML Quests/MLQuestSystem.cs b/Projects/UOContent/Engines/ML Quests/MLQuestSystem.cs index 658ac3a58..41b71a98a 100644 --- a/Projects/UOContent/Engines/ML Quests/MLQuestSystem.cs +++ b/Projects/UOContent/Engines/ML Quests/MLQuestSystem.cs @@ -210,7 +210,7 @@ namespace Server.Engines.MLQuests { var m = e.Mobile; - if (e.Length == 0 || e.Length > 2) + if (e.Length is 0 or > 2) { m.SendMessage("Syntax: SaveQuest [saveEnabled=true]"); return; @@ -638,7 +638,7 @@ namespace Server.Engines.MLQuests public static void EventSink_QuestGumpRequest(Mobile m) { - if (!Enabled || !(m is PlayerMobile pm)) + if (!Enabled || m is not PlayerMobile pm) { return; } @@ -809,7 +809,7 @@ namespace Server.Engines.MLQuests { var from = e.Mobile; - if (!(obj is PlayerMobile pm)) + if (obj is not PlayerMobile pm) { LogFailure("That is not a player."); return; @@ -840,7 +840,7 @@ namespace Server.Engines.MLQuests public override void Execute(CommandEventArgs e, object obj) { - if (!(obj is PlayerMobile pm)) + if (obj is not PlayerMobile pm) { LogFailure("They have no ML quest context."); } diff --git a/Projects/UOContent/Engines/ML Quests/Objectives/CollectObjective.cs b/Projects/UOContent/Engines/ML Quests/Objectives/CollectObjective.cs index f6891a3c6..0ea76721b 100644 --- a/Projects/UOContent/Engines/ML Quests/Objectives/CollectObjective.cs +++ b/Projects/UOContent/Engines/ML Quests/Objectives/CollectObjective.cs @@ -16,7 +16,7 @@ namespace Server.Engines.MLQuests.Objectives { var itemid = LabelToItemID(name.Number); - if (itemid <= 0 || itemid > 0x4000) + if (itemid is <= 0 or > 0x4000) { Console.WriteLine("Warning: cliloc {0} is likely giving the wrong item ID", name.Number); } diff --git a/Projects/UOContent/Engines/ML Quests/Objectives/DeliverObjective.cs b/Projects/UOContent/Engines/ML Quests/Objectives/DeliverObjective.cs index 5aa9d7e43..25e9ef729 100644 --- a/Projects/UOContent/Engines/ML Quests/Objectives/DeliverObjective.cs +++ b/Projects/UOContent/Engines/ML Quests/Objectives/DeliverObjective.cs @@ -24,7 +24,7 @@ namespace Server.Engines.MLQuests.Objectives { var itemid = CollectObjective.LabelToItemID(name.Number); - if (itemid <= 0 || itemid > 0x4000) + if (itemid is <= 0 or > 0x4000) { logger.Warning("Cliloc {0} is likely giving the wrong item ID", name.Number); } diff --git a/Projects/UOContent/Engines/Pathing/PathAlgorithm.cs b/Projects/UOContent/Engines/Pathing/PathAlgorithm.cs index b655dcff3..40ec83fcd 100644 --- a/Projects/UOContent/Engines/Pathing/PathAlgorithm.cs +++ b/Projects/UOContent/Engines/Pathing/PathAlgorithm.cs @@ -24,7 +24,7 @@ namespace Server.PathAlgorithms var y = yDest + 1 - ySource; var v = y * 3 + x; - if (v < 0 || v >= 9) + if (v is < 0 or >= 9) { return Direction.North; } diff --git a/Projects/UOContent/Engines/Plants/MainPlantGump.cs b/Projects/UOContent/Engines/Plants/MainPlantGump.cs index 5593d3787..a1b730ee7 100644 --- a/Projects/UOContent/Engines/Plants/MainPlantGump.cs +++ b/Projects/UOContent/Engines/Plants/MainPlantGump.cs @@ -101,7 +101,7 @@ namespace Server.Engines.Plants AddItem(127, 112, 0xC62); } - if (status == PlantStatus.Stage3 || status == PlantStatus.Stage4) + if (status is PlantStatus.Stage3 or PlantStatus.Stage4) { AddItem(129, 85, 0xC7E); } @@ -134,7 +134,7 @@ namespace Server.Engines.Plants var hueInfo = PlantHueInfo.GetInfo(m_Plant.PlantHue); // The large images for these trees trigger a client crash, so use a smaller, generic tree. - if (m_Plant.PlantType == PlantType.CypressTwisted || m_Plant.PlantType == PlantType.CypressStraight) + if (m_Plant.PlantType is PlantType.CypressTwisted or PlantType.CypressStraight) { AddItem(130 + typeInfo.OffsetX, 96 + typeInfo.OffsetY, 0x0CCA, hueInfo.Hue); } diff --git a/Projects/UOContent/Engines/Plants/MiscItems/GreenThorns.cs b/Projects/UOContent/Engines/Plants/MiscItems/GreenThorns.cs index 4e75a1f2a..882545bb2 100644 --- a/Projects/UOContent/Engines/Plants/MiscItems/GreenThorns.cs +++ b/Projects/UOContent/Engines/Plants/MiscItems/GreenThorns.cs @@ -99,7 +99,7 @@ namespace Server.Items return; } - if (!(targeted is LandTarget land)) + if (targeted is not LandTarget land) { from.LocalOverheadMessage( MessageType.Regular, diff --git a/Projects/UOContent/Engines/Plants/MiscItems/RedLeaves.cs b/Projects/UOContent/Engines/Plants/MiscItems/RedLeaves.cs index 38a6666b4..75d161148 100644 --- a/Projects/UOContent/Engines/Plants/MiscItems/RedLeaves.cs +++ b/Projects/UOContent/Engines/Plants/MiscItems/RedLeaves.cs @@ -65,11 +65,11 @@ namespace Server.Items return; } - if (!(targeted is Item item) || !item.IsChildOf(from.Backpack)) + if (targeted is not Item item || !item.IsChildOf(from.Backpack)) { from.SendLocalizedMessage(1042664); // You must have the object in your backpack to use it. } - else if (!(item is BaseBook)) + else if (item is not BaseBook) { item.LabelTo(from, 1061911); // You can only use red leaves to seal the ink into book pages! } diff --git a/Projects/UOContent/Engines/Plants/PlantHue.cs b/Projects/UOContent/Engines/Plants/PlantHue.cs index b3c3fb03d..0f5d899af 100644 --- a/Projects/UOContent/Engines/Plants/PlantHue.cs +++ b/Projects/UOContent/Engines/Plants/PlantHue.cs @@ -108,7 +108,7 @@ namespace Server.Engines.Plants public static PlantHue GetNotBright(PlantHue plantHue) => plantHue & ~PlantHue.Bright; public static bool IsPrimary(PlantHue plantHue) => - plantHue == PlantHue.Red || plantHue == PlantHue.Blue || plantHue == PlantHue.Yellow; + plantHue is PlantHue.Red or PlantHue.Blue or PlantHue.Yellow; public static PlantHue Cross(PlantHue first, PlantHue second) { diff --git a/Projects/UOContent/Engines/Plants/PlantItem.cs b/Projects/UOContent/Engines/Plants/PlantItem.cs index edf59eab2..b99a0f7c7 100644 --- a/Projects/UOContent/Engines/Plants/PlantItem.cs +++ b/Projects/UOContent/Engines/Plants/PlantItem.cs @@ -67,7 +67,7 @@ namespace Server.Engines.Plants get => m_PlantStatus; set { - if (m_PlantStatus == value || value < PlantStatus.BowlOfDirt || value > PlantStatus.DeadTwigs) + if (m_PlantStatus == value || value is < PlantStatus.BowlOfDirt or > PlantStatus.DeadTwigs) { return; } @@ -151,7 +151,7 @@ namespace Server.Engines.Plants return true; } - if (!(RootParent is Mobile owner)) + if (RootParent is not Mobile owner) { return false; } @@ -491,7 +491,7 @@ namespace Server.Engines.Plants var full = false; - if (effect == PotionEffect.PoisonGreater || effect == PotionEffect.PoisonDeadly) + if (effect is PotionEffect.PoisonGreater or PotionEffect.PoisonDeadly) { if (PlantSystem.IsFullPoisonPotion) { @@ -535,9 +535,7 @@ namespace Server.Engines.Plants PlantSystem.StrengthPotion++; } } - else if (effect == PotionEffect.PoisonLesser || effect == PotionEffect.Poison || - effect == PotionEffect.CureLesser || effect == PotionEffect.Cure || - effect == PotionEffect.HealLesser || effect == PotionEffect.Heal || effect == PotionEffect.Strength) + else if (effect is PotionEffect.PoisonLesser or PotionEffect.Poison or PotionEffect.CureLesser or PotionEffect.Cure or PotionEffect.HealLesser or PotionEffect.Heal or PotionEffect.Strength) { message = 1053068; // This potion is not powerful enough to use on a plant! return false; diff --git a/Projects/UOContent/Engines/Plants/PlantSystem.cs b/Projects/UOContent/Engines/Plants/PlantSystem.cs index abecd633c..a99b425d9 100644 --- a/Projects/UOContent/Engines/Plants/PlantSystem.cs +++ b/Projects/UOContent/Engines/Plants/PlantSystem.cs @@ -393,7 +393,7 @@ namespace Server.Engines.Plants { var plant = plants[i]; - if (plant.IsGrowable && !(plant.RootParent is Mobile) && now >= plant.PlantSystem.NextGrowth) + if (plant.IsGrowable && plant.RootParent is not Mobile && now >= plant.PlantSystem.NextGrowth) { plant.PlantSystem.DoGrowthCheck(); } diff --git a/Projects/UOContent/Engines/Plants/PollinateTarget.cs b/Projects/UOContent/Engines/Plants/PollinateTarget.cs index a63727f5a..2c383557a 100644 --- a/Projects/UOContent/Engines/Plants/PollinateTarget.cs +++ b/Projects/UOContent/Engines/Plants/PollinateTarget.cs @@ -34,8 +34,7 @@ namespace Server.Engines.Plants } else { - if (!(targeted is PlantItem targ) || targ.PlantStatus >= PlantStatus.DecorativePlant || - targ.PlantStatus <= PlantStatus.BowlOfDirt) + if (targeted is not PlantItem targ || targ.PlantStatus is >= PlantStatus.DecorativePlant or <= PlantStatus.BowlOfDirt) { m_Plant.LabelTo(from, 1053070); // You can only pollinate other specially grown plants! } diff --git a/Projects/UOContent/Engines/Plants/ReproductionGump.cs b/Projects/UOContent/Engines/Plants/ReproductionGump.cs index 63439407f..f5699bc4b 100644 --- a/Projects/UOContent/Engines/Plants/ReproductionGump.cs +++ b/Projects/UOContent/Engines/Plants/ReproductionGump.cs @@ -129,8 +129,7 @@ namespace Server.Engines.Plants { var from = sender.Mobile; - if (info.ButtonID == 0 || m_Plant.Deleted || m_Plant.PlantStatus >= PlantStatus.DecorativePlant || - m_Plant.PlantStatus == PlantStatus.BowlOfDirt) + if (info.ButtonID == 0 || m_Plant.Deleted || m_Plant.PlantStatus is >= PlantStatus.DecorativePlant or PlantStatus.BowlOfDirt) { return; } diff --git a/Projects/UOContent/Engines/Plants/Seed.cs b/Projects/UOContent/Engines/Plants/Seed.cs index 98727af42..bb67f9e4b 100644 --- a/Projects/UOContent/Engines/Plants/Seed.cs +++ b/Projects/UOContent/Engines/Plants/Seed.cs @@ -152,7 +152,7 @@ namespace Server.Engines.Plants public override void OnAfterDuped(Item newItem) { - if (!(newItem is Seed newSeed)) + if (newItem is not Seed newSeed) { return; } diff --git a/Projects/UOContent/Engines/Quests/Collector/Items/EnchantedPaints.cs b/Projects/UOContent/Engines/Quests/Collector/Items/EnchantedPaints.cs index 1a46f0360..aa5eeedb8 100644 --- a/Projects/UOContent/Engines/Quests/Collector/Items/EnchantedPaints.cs +++ b/Projects/UOContent/Engines/Quests/Collector/Items/EnchantedPaints.cs @@ -17,7 +17,7 @@ namespace Server.Engines.Quests.Collector { } - public override bool CanDrop(PlayerMobile player) => !(player.Quest is CollectorQuest); + public override bool CanDrop(PlayerMobile player) => player.Quest is not CollectorQuest; public override void OnDoubleClick(Mobile from) { @@ -75,7 +75,7 @@ namespace Server.Engines.Quests.Collector { var qs = player.Quest; - if (!(qs is CollectorQuest)) + if (qs is not CollectorQuest) { return; } diff --git a/Projects/UOContent/Engines/Quests/Collector/Items/Obsidian.cs b/Projects/UOContent/Engines/Quests/Collector/Items/Obsidian.cs index c59401bf6..7806d403d 100644 --- a/Projects/UOContent/Engines/Quests/Collector/Items/Obsidian.cs +++ b/Projects/UOContent/Engines/Quests/Collector/Items/Obsidian.cs @@ -255,7 +255,7 @@ namespace Server.Engines.Quests.Collector protected override void OnTarget(Mobile from, object targeted) { - if (m_Obsidian.Deleted || m_Obsidian.Quantity >= m_Completed || !(targeted is Item targ)) + if (m_Obsidian.Deleted || m_Obsidian.Quantity >= m_Completed || targeted is not Item targ) { return; } diff --git a/Projects/UOContent/Engines/Quests/Collector/Mobiles/Impresario.cs b/Projects/UOContent/Engines/Quests/Collector/Mobiles/Impresario.cs index 561bfadfc..b72ba2f39 100644 --- a/Projects/UOContent/Engines/Quests/Collector/Mobiles/Impresario.cs +++ b/Projects/UOContent/Engines/Quests/Collector/Mobiles/Impresario.cs @@ -53,7 +53,7 @@ namespace Server.Engines.Quests.Collector { var qs = player.Quest; - if (!(qs is CollectorQuest)) + if (qs is not CollectorQuest) { return; } @@ -149,7 +149,7 @@ namespace Server.Engines.Quests.Collector { var qs = player.Quest; - if (!(qs is CollectorQuest)) + if (qs is not CollectorQuest) { return; } diff --git a/Projects/UOContent/Engines/Quests/Core/QuestSystem.cs b/Projects/UOContent/Engines/Quests/Core/QuestSystem.cs index 3ea47a4c3..02d648734 100644 --- a/Projects/UOContent/Engines/Quests/Core/QuestSystem.cs +++ b/Projects/UOContent/Engines/Quests/Core/QuestSystem.cs @@ -431,7 +431,7 @@ namespace Server.Engines.Quests { inRestartPeriod = false; - if (!(check is PlayerMobile pm)) + if (check is not PlayerMobile pm) { return false; } diff --git a/Projects/UOContent/Engines/Quests/Dark Tides/DarkTidesQuest.cs b/Projects/UOContent/Engines/Quests/Dark Tides/DarkTidesQuest.cs index b6a490e08..5ce3407d6 100644 --- a/Projects/UOContent/Engines/Quests/Dark Tides/DarkTidesQuest.cs +++ b/Projects/UOContent/Engines/Quests/Dark Tides/DarkTidesQuest.cs @@ -83,7 +83,7 @@ namespace Server.Engines.Quests.Necro public static bool HasLostCallingScroll(Mobile from) { - if (!(from is PlayerMobile pm)) + if (@from is not PlayerMobile pm) { return false; } diff --git a/Projects/UOContent/Engines/Quests/Dark Tides/Items/CrystalCaveBarrier.cs b/Projects/UOContent/Engines/Quests/Dark Tides/Items/CrystalCaveBarrier.cs index c02bdb619..0097997fa 100644 --- a/Projects/UOContent/Engines/Quests/Dark Tides/Items/CrystalCaveBarrier.cs +++ b/Projects/UOContent/Engines/Quests/Dark Tides/Items/CrystalCaveBarrier.cs @@ -25,7 +25,7 @@ namespace Server.Engines.Quests.Necro mob = creature.ControlMaster; } - if (!(mob is PlayerMobile pm)) + if (mob is not PlayerMobile pm) { return false; } diff --git a/Projects/UOContent/Engines/Quests/Dark Tides/Items/KronusScroll.cs b/Projects/UOContent/Engines/Quests/Dark Tides/Items/KronusScroll.cs index e893f2ff7..8c91b6a3f 100644 --- a/Projects/UOContent/Engines/Quests/Dark Tides/Items/KronusScroll.cs +++ b/Projects/UOContent/Engines/Quests/Dark Tides/Items/KronusScroll.cs @@ -22,7 +22,7 @@ namespace Server.Engines.Quests.Necro public override int LabelNumber => 1060149; // Calling of Kronus - public override bool CanDrop(PlayerMobile player) => !(player.Quest is DarkTidesQuest); + public override bool CanDrop(PlayerMobile player) => player.Quest is not DarkTidesQuest; public override void OnDoubleClick(Mobile from) { @@ -31,7 +31,7 @@ namespace Server.Engines.Quests.Necro return; } - if (!(from is PlayerMobile pm)) + if (@from is not PlayerMobile pm) { return; } diff --git a/Projects/UOContent/Engines/Quests/Dark Tides/Items/ScrollOfAbraxus.cs b/Projects/UOContent/Engines/Quests/Dark Tides/Items/ScrollOfAbraxus.cs index e372f9c17..01e24fbd7 100644 --- a/Projects/UOContent/Engines/Quests/Dark Tides/Items/ScrollOfAbraxus.cs +++ b/Projects/UOContent/Engines/Quests/Dark Tides/Items/ScrollOfAbraxus.cs @@ -14,7 +14,7 @@ namespace Server.Engines.Quests.Necro public override int LabelNumber => 1028827; // Scroll of Abraxus - public override bool CanDrop(PlayerMobile player) => !(player.Quest is DarkTidesQuest); + public override bool CanDrop(PlayerMobile player) => player.Quest is not DarkTidesQuest; public override void OnAdded(IEntity parent) { diff --git a/Projects/UOContent/Engines/Quests/Dark Tides/Mobiles/Mardoth.cs b/Projects/UOContent/Engines/Quests/Dark Tides/Mobiles/Mardoth.cs index 7cadf48bd..2af0da317 100644 --- a/Projects/UOContent/Engines/Quests/Dark Tides/Mobiles/Mardoth.cs +++ b/Projects/UOContent/Engines/Quests/Dark Tides/Mobiles/Mardoth.cs @@ -86,7 +86,7 @@ namespace Server.Engines.Quests.Necro public override bool CanTalkTo(PlayerMobile to) { - if (!(to.Quest is DarkTidesQuest qs)) + if (to.Quest is not DarkTidesQuest qs) { return to.Quest == null && QuestSystem.CanOfferQuest(to, typeof(DarkTidesQuest)); } diff --git a/Projects/UOContent/Engines/Quests/Dark Tides/Objectives.cs b/Projects/UOContent/Engines/Quests/Dark Tides/Objectives.cs index 7719b2d7f..68a2241e9 100644 --- a/Projects/UOContent/Engines/Quests/Dark Tides/Objectives.cs +++ b/Projects/UOContent/Engines/Quests/Dark Tides/Objectives.cs @@ -127,7 +127,7 @@ namespace Server.Engines.Quests.Necro public override void CheckProgress() { if (System.From.Map != Map.Malas || !System.From.InRange(new Point3D(1076, 450, -84), 5) || - !SummonFamiliarSpell.Table.TryGetValue(System.From, out var bc) || !(bc is HordeMinionFamiliar hmf) || + !SummonFamiliarSpell.Table.TryGetValue(System.From, out var bc) || bc is not HordeMinionFamiliar hmf || !hmf.InRange(System.From, 5) || hmf.TargetLocation != null) { return; diff --git a/Projects/UOContent/Engines/Quests/Emino's Undertaking/EminosUndertakingQuest.cs b/Projects/UOContent/Engines/Quests/Emino's Undertaking/EminosUndertakingQuest.cs index 19e7930ed..bf03061c2 100644 --- a/Projects/UOContent/Engines/Quests/Emino's Undertaking/EminosUndertakingQuest.cs +++ b/Projects/UOContent/Engines/Quests/Emino's Undertaking/EminosUndertakingQuest.cs @@ -74,7 +74,7 @@ namespace Server.Engines.Quests.Ninja public override void Slice() { if (!m_SentRadarConversion && - (From.Map != Map.Malas || From.X < 407 || From.X > 431 || From.Y < 801 || From.Y > 830)) + (From.Map != Map.Malas || From.X is < 407 or > 431 || From.Y is < 801 or > 830)) { m_SentRadarConversion = true; AddConversation(new RadarConversation()); @@ -99,7 +99,7 @@ namespace Server.Engines.Quests.Ninja public static bool HasLostNoteForZoel(Mobile from) { - if (!(from is PlayerMobile pm)) + if (@from is not PlayerMobile pm) { return false; } @@ -119,7 +119,7 @@ namespace Server.Engines.Quests.Ninja public static bool HasLostEminosKatana(Mobile from) { - if (!(from is PlayerMobile pm)) + if (@from is not PlayerMobile pm) { return false; } diff --git a/Projects/UOContent/Engines/Quests/Emino's Undertaking/Items/EminosKatana.cs b/Projects/UOContent/Engines/Quests/Emino's Undertaking/Items/EminosKatana.cs index b3ae1d647..a1e5a6e17 100644 --- a/Projects/UOContent/Engines/Quests/Emino's Undertaking/Items/EminosKatana.cs +++ b/Projects/UOContent/Engines/Quests/Emino's Undertaking/Items/EminosKatana.cs @@ -13,7 +13,7 @@ namespace Server.Engines.Quests.Ninja public override int LabelNumber => 1063214; // Daimyo Emino's Katana - public override bool CanDrop(PlayerMobile player) => !(player.Quest is EminosUndertakingQuest); + public override bool CanDrop(PlayerMobile player) => player.Quest is not EminosUndertakingQuest; public override void Serialize(IGenericWriter writer) { diff --git a/Projects/UOContent/Engines/Quests/Emino's Undertaking/Items/NoteForZoel.cs b/Projects/UOContent/Engines/Quests/Emino's Undertaking/Items/NoteForZoel.cs index cd1d0dc6e..5aab1c067 100644 --- a/Projects/UOContent/Engines/Quests/Emino's Undertaking/Items/NoteForZoel.cs +++ b/Projects/UOContent/Engines/Quests/Emino's Undertaking/Items/NoteForZoel.cs @@ -17,7 +17,7 @@ namespace Server.Engines.Quests.Ninja public override int LabelNumber => 1063186; // A Note for Zoel - public override bool CanDrop(PlayerMobile player) => !(player.Quest is EminosUndertakingQuest); + public override bool CanDrop(PlayerMobile player) => player.Quest is not EminosUndertakingQuest; public override void Serialize(IGenericWriter writer) { diff --git a/Projects/UOContent/Engines/Quests/Haochi's Trials/HaochisTrialsQuest.cs b/Projects/UOContent/Engines/Quests/Haochi's Trials/HaochisTrialsQuest.cs index 38946c006..bc66e7b7c 100644 --- a/Projects/UOContent/Engines/Quests/Haochi's Trials/HaochisTrialsQuest.cs +++ b/Projects/UOContent/Engines/Quests/Haochi's Trials/HaochisTrialsQuest.cs @@ -77,7 +77,7 @@ namespace Server.Engines.Quests.Samurai public override void Slice() { if (!m_SentRadarConversion && - (From.Map != Map.Malas || From.X < 360 || From.X > 400 || From.Y < 760 || From.Y > 780)) + (From.Map != Map.Malas || From.X is < 360 or > 400 || From.Y is < 760 or > 780)) { m_SentRadarConversion = true; AddConversation(new RadarConversation()); @@ -102,7 +102,7 @@ namespace Server.Engines.Quests.Samurai public static bool HasLostHaochisKatana(Mobile from) { - if (!(from is PlayerMobile pm)) + if (@from is not PlayerMobile pm) { return false; } diff --git a/Projects/UOContent/Engines/Quests/Haochi's Trials/Items/HaochisKatana.cs b/Projects/UOContent/Engines/Quests/Haochi's Trials/Items/HaochisKatana.cs index b9992bcde..810ad0182 100644 --- a/Projects/UOContent/Engines/Quests/Haochi's Trials/Items/HaochisKatana.cs +++ b/Projects/UOContent/Engines/Quests/Haochi's Trials/Items/HaochisKatana.cs @@ -13,7 +13,7 @@ namespace Server.Engines.Quests.Samurai public override int LabelNumber => 1063165; // Daimyo Haochi's Katana - public override bool CanDrop(PlayerMobile player) => !(player.Quest is HaochisTrialsQuest); + public override bool CanDrop(PlayerMobile player) => player.Quest is not HaochisTrialsQuest; public override void Serialize(IGenericWriter writer) { diff --git a/Projects/UOContent/Engines/Quests/Haochi's Trials/Items/HonorCandle.cs b/Projects/UOContent/Engines/Quests/Haochi's Trials/Items/HonorCandle.cs index 07e015e56..ce08640bb 100644 --- a/Projects/UOContent/Engines/Quests/Haochi's Trials/Items/HonorCandle.cs +++ b/Projects/UOContent/Engines/Quests/Haochi's Trials/Items/HonorCandle.cs @@ -30,7 +30,7 @@ namespace Server.Engines.Quests.Samurai if (!wasBurning && Burning) { - if (!(from is PlayerMobile player)) + if (@from is not PlayerMobile player) { return; } diff --git a/Projects/UOContent/Engines/Quests/Solen Matriarch/Objectives.cs b/Projects/UOContent/Engines/Quests/Solen Matriarch/Objectives.cs index e2140a2ca..dc889d0f4 100644 --- a/Projects/UOContent/Engines/Quests/Solen Matriarch/Objectives.cs +++ b/Projects/UOContent/Engines/Quests/Solen Matriarch/Objectives.cs @@ -43,10 +43,10 @@ namespace Server.Engines.Quests.Matriarch if (redSolen) { - return from is BlackSolenInfiltratorWarrior || from is BlackSolenInfiltratorQueen; + return @from is BlackSolenInfiltratorWarrior or BlackSolenInfiltratorQueen; } - return from is RedSolenInfiltratorWarrior || from is RedSolenInfiltratorQueen; + return @from is RedSolenInfiltratorWarrior or RedSolenInfiltratorQueen; } public override void OnKill(BaseCreature creature, Container corpse) @@ -55,14 +55,14 @@ namespace Server.Engines.Quests.Matriarch if (redSolen) { - if (creature is BlackSolenInfiltratorWarrior || creature is BlackSolenInfiltratorQueen) + if (creature is BlackSolenInfiltratorWarrior or BlackSolenInfiltratorQueen) { CurProgress++; } } else { - if (creature is RedSolenInfiltratorWarrior || creature is RedSolenInfiltratorQueen) + if (creature is RedSolenInfiltratorWarrior or RedSolenInfiltratorQueen) { CurProgress++; } diff --git a/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Items/QuestDaemonBlood.cs b/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Items/QuestDaemonBlood.cs index a1e7faaa7..f6bdda528 100644 --- a/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Items/QuestDaemonBlood.cs +++ b/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Items/QuestDaemonBlood.cs @@ -11,7 +11,7 @@ namespace Server.Engines.Quests.Haven { } - public override bool CanDrop(PlayerMobile player) => !(player.Quest is UzeraanTurmoilQuest); + public override bool CanDrop(PlayerMobile player) => player.Quest is not UzeraanTurmoilQuest; public override void Serialize(IGenericWriter writer) { diff --git a/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Items/QuestDaemonBone.cs b/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Items/QuestDaemonBone.cs index d1da95128..a4dfbf561 100644 --- a/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Items/QuestDaemonBone.cs +++ b/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Items/QuestDaemonBone.cs @@ -11,7 +11,7 @@ namespace Server.Engines.Quests.Haven { } - public override bool CanDrop(PlayerMobile player) => !(player.Quest is UzeraanTurmoilQuest); + public override bool CanDrop(PlayerMobile player) => player.Quest is not UzeraanTurmoilQuest; public override void Serialize(IGenericWriter writer) { diff --git a/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Items/QuestFertileDirt.cs b/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Items/QuestFertileDirt.cs index c596f15cb..1f459e7c6 100644 --- a/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Items/QuestFertileDirt.cs +++ b/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Items/QuestFertileDirt.cs @@ -11,7 +11,7 @@ namespace Server.Engines.Quests.Haven { } - public override bool CanDrop(PlayerMobile player) => !(player.Quest is UzeraanTurmoilQuest); + public override bool CanDrop(PlayerMobile player) => player.Quest is not UzeraanTurmoilQuest; public override void Serialize(IGenericWriter writer) { diff --git a/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Objectives.cs b/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Objectives.cs index f59e7b3cd..91d2997b4 100644 --- a/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Objectives.cs +++ b/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Objectives.cs @@ -395,7 +395,7 @@ namespace Server.Engines.Quests.Haven public override bool IgnoreYoungProtection(Mobile from) { // This restriction continues until the end of the quest - if ((from is Zombie || from is Skeleton) && from.Map == Map.Trammel && from.X >= 3391 && from.X <= 3424 && + if (@from is Zombie or Skeleton && from.Map == Map.Trammel && from.X >= 3391 && from.X <= 3424 && from.Y >= 2639 && from.Y <= 2664) // Haven graveyard { return true; @@ -416,7 +416,7 @@ namespace Server.Engines.Quests.Haven public override void OnKill(BaseCreature creature, Container corpse) { - if ((creature is Zombie || creature is Skeleton) && corpse.Map == Map.Trammel && corpse.X >= 3391 && + if (creature is Zombie or Skeleton && corpse.Map == Map.Trammel && corpse.X >= 3391 && corpse.X <= 3424 && corpse.Y >= 2639 && corpse.Y <= 2664) // Haven graveyard { if (Utility.RandomDouble() < 0.25) diff --git a/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/UzeraanTurmoilQuest.cs b/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/UzeraanTurmoilQuest.cs index a0cd9ba56..28b56908f 100644 --- a/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/UzeraanTurmoilQuest.cs +++ b/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/UzeraanTurmoilQuest.cs @@ -78,7 +78,7 @@ namespace Server.Engines.Quests.Haven public override void Slice() { if (!m_HasLeftTheMansion && - (From.Map != Map.Trammel || From.X < 3573 || From.X > 3611 || From.Y < 2568 || From.Y > 2606)) + (From.Map != Map.Trammel || From.X is < 3573 or > 3611 || From.Y is < 2568 or > 2606)) { m_HasLeftTheMansion = true; AddConversation(new RadarConversation()); @@ -110,7 +110,7 @@ namespace Server.Engines.Quests.Haven public static bool HasLostScrollOfPower(Mobile from) { - if (!(from is PlayerMobile pm)) + if (@from is not PlayerMobile pm) { return false; } @@ -130,7 +130,7 @@ namespace Server.Engines.Quests.Haven public static bool HasLostFertileDirt(Mobile from) { - if (!(from is PlayerMobile pm)) + if (@from is not PlayerMobile pm) { return false; } @@ -150,7 +150,7 @@ namespace Server.Engines.Quests.Haven public static bool HasLostDaemonBlood(Mobile from) { - if (!(from is PlayerMobile pm)) + if (@from is not PlayerMobile pm) { return false; } @@ -170,7 +170,7 @@ namespace Server.Engines.Quests.Haven public static bool HasLostDaemonBone(Mobile from) { - if (!(from is PlayerMobile pm)) + if (@from is not PlayerMobile pm) { return false; } diff --git a/Projects/UOContent/Engines/Treasures of Tokuno/BasePigmentsOfTokuno.cs b/Projects/UOContent/Engines/Treasures of Tokuno/BasePigmentsOfTokuno.cs index 916bab5f1..2051ab96c 100644 --- a/Projects/UOContent/Engines/Treasures of Tokuno/BasePigmentsOfTokuno.cs +++ b/Projects/UOContent/Engines/Treasures of Tokuno/BasePigmentsOfTokuno.cs @@ -145,7 +145,7 @@ namespace Server.Items return; } - if (!(targeted is Item i)) + if (targeted is not Item i) { from.SendLocalizedMessage(1070931); // You can only dye artifacts and enhanced magic items with this tub. } diff --git a/Projects/UOContent/Engines/Treasures of Tokuno/GreaterArtifacts.cs b/Projects/UOContent/Engines/Treasures of Tokuno/GreaterArtifacts.cs index 57f412128..7603968e8 100644 --- a/Projects/UOContent/Engines/Treasures of Tokuno/GreaterArtifacts.cs +++ b/Projects/UOContent/Engines/Treasures of Tokuno/GreaterArtifacts.cs @@ -487,7 +487,7 @@ namespace Server.Items [Constructible] public PigmentsOfTokuno(PigmentType type = PigmentType.None) : this( type, - type == PigmentType.None || type >= PigmentType.FadedCoal ? 10 : 50 + type is PigmentType.None or >= PigmentType.FadedCoal ? 10 : 50 ) { } diff --git a/Projects/UOContent/Engines/Treasures of Tokuno/TreasuresOfTokuno.cs b/Projects/UOContent/Engines/Treasures of Tokuno/TreasuresOfTokuno.cs index 676d4dd06..a4d2ede01 100644 --- a/Projects/UOContent/Engines/Treasures of Tokuno/TreasuresOfTokuno.cs +++ b/Projects/UOContent/Engines/Treasures of Tokuno/TreasuresOfTokuno.cs @@ -135,7 +135,7 @@ namespace Server.Misc public static void HandleKill(Mobile victim, Mobile killer) { - if (DropEra == TreasuresOfTokunoEra.None || !(killer is PlayerMobile pm) || !(victim is BaseCreature bc) || + if (DropEra == TreasuresOfTokunoEra.None || killer is not PlayerMobile pm || victim is not BaseCreature bc || !CheckLocation(bc) || !CheckLocation(pm) || !killer.InRange(victim, 18)) { return; @@ -433,7 +433,7 @@ namespace Server.Gumps public override void HandleCancel(NetState sender) { - if (!(sender.Mobile is PlayerMobile pm) || !pm.InRange(m_Collector.Location, 7)) + if (sender.Mobile is not PlayerMobile pm || !pm.InRange(m_Collector.Location, 7)) { return; } @@ -565,7 +565,7 @@ namespace Server.Gumps public override void HandleButtonResponse(NetState sender, int adjustedButton, ImageTileButtonInfo buttonInfo) { - if (!(sender.Mobile is PlayerMobile pm) || !pm.InRange(m_Collector.Location, 7) || + if (sender.Mobile is not PlayerMobile pm || !pm.InRange(m_Collector.Location, 7) || !(pm.ToTItemsTurnedIn >= TreasuresOfTokuno.ItemsPerReward)) { return; @@ -627,7 +627,7 @@ namespace Server.Gumps public override void HandleCancel(NetState sender) { - if (!(sender.Mobile is PlayerMobile pm) || !pm.InRange(m_Collector.Location, 7)) + if (sender.Mobile is not PlayerMobile pm || !pm.InRange(m_Collector.Location, 7)) { return; } diff --git a/Projects/UOContent/Engines/Veteran Rewards/Character Statue Maker/CharacterStatue.cs b/Projects/UOContent/Engines/Veteran Rewards/Character Statue Maker/CharacterStatue.cs index eeb92baa8..1ce3132cb 100644 --- a/Projects/UOContent/Engines/Veteran Rewards/Character Statue Maker/CharacterStatue.cs +++ b/Projects/UOContent/Engines/Veteran Rewards/Character Statue Maker/CharacterStatue.cs @@ -613,7 +613,7 @@ namespace Server.Mobiles BaseHouse house = null; var loc = new Point3D(p); - if (targeted is Item item && !item.IsLockedDown && !item.IsSecure && !(item is AddonComponent)) + if (targeted is Item item && !item.IsLockedDown && !item.IsSecure && item is not AddonComponent) { from.SendLocalizedMessage(1076191); // Statues can only be placed in houses. return; diff --git a/Projects/UOContent/Engines/Veteran Rewards/RewardDemolitionGump.cs b/Projects/UOContent/Engines/Veteran Rewards/RewardDemolitionGump.cs index 39de782c7..d88dbf38f 100644 --- a/Projects/UOContent/Engines/Veteran Rewards/RewardDemolitionGump.cs +++ b/Projects/UOContent/Engines/Veteran Rewards/RewardDemolitionGump.cs @@ -31,7 +31,7 @@ namespace Server.Gumps public override void OnResponse(NetState sender, RelayInfo info) { - if (!(m_Addon is Item item) || item.Deleted) + if (m_Addon is not Item item || item.Deleted) { return; } diff --git a/Projects/UOContent/Engines/Veteran Rewards/RewardSystem.cs b/Projects/UOContent/Engines/Veteran Rewards/RewardSystem.cs index 504de1247..3b6045386 100644 --- a/Projects/UOContent/Engines/Veteran Rewards/RewardSystem.cs +++ b/Projects/UOContent/Engines/Veteran Rewards/RewardSystem.cs @@ -83,7 +83,7 @@ namespace Server.Engines.VeteranRewards public static int GetRewardLevel(Mobile mob) { - if (!(mob.Account is Account acct)) + if (mob.Account is not Account acct) { return 0; } @@ -96,7 +96,7 @@ namespace Server.Engines.VeteranRewards public static bool HasHalfLevel(Mobile mob) { - if (!(mob.Account is Account acct)) + if (mob.Account is not Account acct) { return false; } @@ -115,7 +115,7 @@ namespace Server.Engines.VeteranRewards return false; } - if (!(mob.Account is Account acct)) + if (mob.Account is not Account acct) { return false; } @@ -133,7 +133,7 @@ namespace Server.Engines.VeteranRewards public static void ComputeRewardInfo(Mobile mob, out int cur, out int max, out int level) { - if (!(mob.Account is Account acct)) + if (mob.Account is not Account acct) { cur = max = level = 0; return; @@ -170,7 +170,7 @@ namespace Server.Engines.VeteranRewards public static bool CheckIsUsableBy(Mobile from, Item item, object[] args = null) { - var isRelaxedRules = item is DyeTub || item is MonsterStatuette; + var isRelaxedRules = item is DyeTub or MonsterStatuette; var type = item.GetType(); @@ -578,8 +578,7 @@ namespace Server.Engines.VeteranRewards ComputeRewardInfo(m, out var cur, out var max, out var level); - if (m.SkillsCap == 7000 || m.SkillsCap == 7050 || m.SkillsCap == 7100 || - m.SkillsCap == 7150 || m.SkillsCap == 7200) + if (m.SkillsCap is 7000 or 7050 or 7100 or 7150 or 7200) { level = Math.Clamp(level, 0, 4); diff --git a/Projects/UOContent/Engines/Virtues/Sacrifice.cs b/Projects/UOContent/Engines/Virtues/Sacrifice.cs index 9ce3c9be8..8679a0b06 100644 --- a/Projects/UOContent/Engines/Virtues/Sacrifice.cs +++ b/Projects/UOContent/Engines/Virtues/Sacrifice.cs @@ -190,8 +190,7 @@ namespace Server return false; } - return m is Lich || m is Succubus || m is Daemon || m is EvilMage || m is EnslavedGargoyle || - m is GargoyleEnforcer; + return m is Lich or Succubus or Daemon or EvilMage or EnslavedGargoyle or GargoyleEnforcer; } private class InternalTarget : Target diff --git a/Projects/UOContent/Gumps/AdminGump.cs b/Projects/UOContent/Gumps/AdminGump.cs index 25777e491..7f1b1deb6 100644 --- a/Projects/UOContent/Gumps/AdminGump.cs +++ b/Projects/UOContent/Gumps/AdminGump.cs @@ -476,7 +476,7 @@ namespace Server.Gumps for (int i = 0, index = listPage * 12; i < 12 && index >= 0 && index < m_List.Count; ++i, ++index) { - if (!(m_List[index] is NetState ns)) + if (m_List[index] is not NetState ns) { continue; } @@ -517,7 +517,7 @@ namespace Server.Gumps } case AdminGumpPage.ClientInfo: { - if (!(state is Mobile m)) + if (state is not Mobile m) { break; } @@ -738,7 +738,7 @@ namespace Server.Gumps for (int i = 0, index = listPage * 12; i < 12 && index >= 0 && index < m_List.Count; ++i, ++index) { - if (!(m_List[index] is Account a)) + if (m_List[index] is not Account a) { continue; } @@ -804,7 +804,7 @@ namespace Server.Gumps } case AdminGumpPage.AccountDetails_ChangePassword: { - if (!(state is Account a)) + if (state is not Account a) { break; } @@ -826,7 +826,7 @@ namespace Server.Gumps } case AdminGumpPage.AccountDetails_ChangeAccess: { - if (!(state is Account a)) + if (state is not Account a) { break; } @@ -863,7 +863,7 @@ namespace Server.Gumps } case AdminGumpPage.AccountDetails_Information: { - if (!(state is Account a)) + if (state is not Account a) { break; } @@ -948,7 +948,7 @@ namespace Server.Gumps } case AdminGumpPage.AccountDetails_Access: { - if (!(state is Account a)) + if (state is not Account a) { break; } @@ -974,7 +974,7 @@ namespace Server.Gumps } case AdminGumpPage.AccountDetails_Access_ClientIPs: { - if (!(state is Account a)) + if (state is not Account a) { break; } @@ -1046,7 +1046,7 @@ namespace Server.Gumps } case AdminGumpPage.AccountDetails_Access_Restrictions: { - if (!(state is Account a)) + if (state is not Account a) { break; } @@ -1120,7 +1120,7 @@ namespace Server.Gumps } case AdminGumpPage.AccountDetails_Characters: { - if (!(state is Account a)) + if (state is not Account a) { break; } @@ -1170,7 +1170,7 @@ namespace Server.Gumps } case AdminGumpPage.AccountDetails_Comments: { - if (!(state is Account a)) + if (state is not Account a) { break; } @@ -1209,7 +1209,7 @@ namespace Server.Gumps } case AdminGumpPage.AccountDetails_Tags: { - if (!(state is Account a)) + if (state is not Account a) { break; } @@ -1308,7 +1308,7 @@ namespace Server.Gumps { AddFirewallHeader(); - if (!(state is Firewall.IFirewallEntry firewallEntry)) + if (state is not Firewall.IFirewallEntry firewallEntry) { break; } @@ -2657,7 +2657,7 @@ namespace Server.Gumps if (m_List != null && index >= 0 && index < m_List.Count) { - if (!(m_List[index] is NetState ns)) + if (m_List[index] is not NetState ns) { break; } @@ -2926,7 +2926,7 @@ namespace Server.Gumps case 10: case 11: { - if (!(m_State is Account a)) + if (m_State is not Account a) { break; } @@ -2961,7 +2961,7 @@ namespace Server.Gumps } case 12: { - if (!(m_State is Account a)) + if (m_State is not Account a) { break; } @@ -3004,7 +3004,7 @@ namespace Server.Gumps } case 16: // view shared { - if (!(m_State is Account a)) + if (m_State is not Account a) { break; } @@ -3055,7 +3055,7 @@ namespace Server.Gumps } case 17: // ban shared { - if (!(m_State is Account a)) + if (m_State is not Account a) { break; } @@ -3119,7 +3119,7 @@ namespace Server.Gumps } case 18: // firewall all { - if (!(m_State is Account a)) + if (m_State is not Account a) { break; } @@ -3156,7 +3156,7 @@ namespace Server.Gumps } case 19: // add { - if (!(m_State is Account a)) + if (m_State is not Account a) { break; } @@ -3220,7 +3220,7 @@ namespace Server.Gumps case 23: case 24: { - if (!(m_State is Account a)) + if (m_State is not Account a) { break; } @@ -3264,7 +3264,7 @@ namespace Server.Gumps } case 25: { - if (!(m_State is Account a)) + if (m_State is not Account a) { break; } @@ -3291,7 +3291,7 @@ namespace Server.Gumps { var list = m_List; - if (list == null || !(m_State is List rads)) + if (list == null || m_State is not List rads) { break; } @@ -3331,7 +3331,7 @@ namespace Server.Gumps { var list = m_List; - if (list == null || !(m_State is List rads)) + if (list == null || m_State is not List rads) { break; } @@ -3373,7 +3373,7 @@ namespace Server.Gumps } case 29: // Mark all { - if (m_List == null || !(m_State is List)) + if (m_List == null || m_State is not List) { break; } @@ -3564,7 +3564,7 @@ namespace Server.Gumps } case 36: // Clear login addresses { - if (!(m_State is Account a)) + if (m_State is not Account a) { break; } @@ -3844,7 +3844,7 @@ namespace Server.Gumps } case 7: { - if (!(m_State is Mobile m)) + if (m_State is not Mobile m) { break; } @@ -4039,7 +4039,7 @@ namespace Server.Gumps { if (index < m_List?.Count) { - if (!(m_State is Account a)) + if (m_State is not Account a) { break; } @@ -4087,12 +4087,12 @@ namespace Server.Gumps { var obj = m_List[index]; - if (!(obj is IPAddress ip)) + if (obj is not IPAddress ip) { break; } - if (!(m_State is Account a)) + if (m_State is not Account a) { break; } @@ -4143,7 +4143,7 @@ namespace Server.Gumps break; } - if (!(m_State is Account a)) + if (m_State is not Account a) { break; } diff --git a/Projects/UOContent/Gumps/CommentsGump.cs b/Projects/UOContent/Gumps/CommentsGump.cs index 1a31e3ecc..24504383c 100644 --- a/Projects/UOContent/Gumps/CommentsGump.cs +++ b/Projects/UOContent/Gumps/CommentsGump.cs @@ -71,7 +71,7 @@ namespace Server.Gumps private static void OnTarget(Mobile from, object target) { - if (!(target is Mobile m) || !m.Player) + if (target is not Mobile m || !m.Player) { from.SendMessage("You must target a player."); return; diff --git a/Projects/UOContent/Gumps/Guilds/New Guild System/BaseGuildGump.cs b/Projects/UOContent/Gumps/Guilds/New Guild System/BaseGuildGump.cs index e3ef78fac..7c8052025 100644 --- a/Projects/UOContent/Gumps/Guilds/New Guild System/BaseGuildGump.cs +++ b/Projects/UOContent/Gumps/Guilds/New Guild System/BaseGuildGump.cs @@ -40,7 +40,7 @@ namespace Server.Guilds public override void OnResponse(NetState sender, RelayInfo info) { - if (!(sender.Mobile is PlayerMobile pm)) + if (sender.Mobile is not PlayerMobile pm) { return; } @@ -71,11 +71,11 @@ namespace Server.Guilds } public static bool IsLeader(Mobile m, Guild g) => - !(m.Deleted || g.Disbanded || !(m is PlayerMobile) || + !(m.Deleted || g.Disbanded || m is not PlayerMobile || m.AccessLevel < AccessLevel.GameMaster && g.Leader != m); public static bool IsMember(Mobile m, Guild g) => - !(m.Deleted || g.Disbanded || !(m is PlayerMobile) || + !(m.Deleted || g.Disbanded || m is not PlayerMobile || m.AccessLevel < AccessLevel.GameMaster && !g.IsMember(m)); public static bool CheckProfanity(string s, int maxLength = 50) @@ -96,7 +96,7 @@ namespace Server.Guilds { var c = s[i]; - if ((c < 'a' || c > 'z') && (c < '0' || c > '9')) + if (c is < 'a' or > 'z' && c is < '0' or > '9') { var except = false; diff --git a/Projects/UOContent/Gumps/Guilds/New Guild System/BaseGuildListGump.cs b/Projects/UOContent/Gumps/Guilds/New Guild System/BaseGuildListGump.cs index 7271b31ab..8b09c06b2 100644 --- a/Projects/UOContent/Gumps/Guilds/New Guild System/BaseGuildListGump.cs +++ b/Projects/UOContent/Gumps/Guilds/New Guild System/BaseGuildListGump.cs @@ -164,7 +164,7 @@ namespace Server.Guilds { base.OnResponse(sender, info); - if (!(sender.Mobile is PlayerMobile pm) || !IsMember(pm, guild)) + if (sender.Mobile is not PlayerMobile pm || !IsMember(pm, guild)) { return; } diff --git a/Projects/UOContent/Gumps/Guilds/New Guild System/Create Guild Gump.cs b/Projects/UOContent/Gumps/Guilds/New Guild System/Create Guild Gump.cs index 55368bca9..022ba2651 100644 --- a/Projects/UOContent/Gumps/Guilds/New Guild System/Create Guild Gump.cs +++ b/Projects/UOContent/Gumps/Guilds/New Guild System/Create Guild Gump.cs @@ -48,7 +48,7 @@ namespace Server.Guilds public override void OnResponse(NetState sender, RelayInfo info) { - if (!(sender.Mobile is PlayerMobile pm) || pm.Guild != null) + if (sender.Mobile is not PlayerMobile pm || pm.Guild != null) { return; // Sanity } diff --git a/Projects/UOContent/Gumps/Guilds/New Guild System/DiplomacyGump.cs b/Projects/UOContent/Gumps/Guilds/New Guild System/DiplomacyGump.cs index 18f16b1d7..79e11341d 100644 --- a/Projects/UOContent/Gumps/Guilds/New Guild System/DiplomacyGump.cs +++ b/Projects/UOContent/Gumps/Guilds/New Guild System/DiplomacyGump.cs @@ -208,15 +208,8 @@ namespace Server.Guilds { case GuildDisplayType.Relations: { - // if (!( guild.IsWar( g ) || guild.IsAlly( g ) )) - - if (!(guild.FindActiveWar(g) != null || guild.IsAlly(g)) - ) // As per OSI, only the guild leader wars show up under the sorting by relation - { - return true; - } - - return false; + // As per OSI, only the guild leader wars show up under the sorting by relation + return !(guild.FindActiveWar(g) != null || guild.IsAlly(g)); } case GuildDisplayType.AwaitingAction: { @@ -247,7 +240,7 @@ namespace Server.Guilds { base.OnResponse(sender, info); - if (!(sender.Mobile is PlayerMobile pm) || !IsMember(pm, guild)) + if (sender.Mobile is not PlayerMobile pm || !IsMember(pm, guild)) { return; } diff --git a/Projects/UOContent/Gumps/Guilds/New Guild System/GuildMemberInfoGump.cs b/Projects/UOContent/Gumps/Guilds/New Guild System/GuildMemberInfoGump.cs index a23357827..c5bf35787 100644 --- a/Projects/UOContent/Gumps/Guilds/New Guild System/GuildMemberInfoGump.cs +++ b/Projects/UOContent/Gumps/Guilds/New Guild System/GuildMemberInfoGump.cs @@ -68,7 +68,7 @@ namespace Server.Guilds public override void OnResponse(NetState sender, RelayInfo info) { - if (!(sender.Mobile is PlayerMobile pm) || !IsMember(pm, guild) || !IsMember(m_Member, guild)) + if (sender.Mobile is not PlayerMobile pm || !IsMember(pm, guild) || !IsMember(m_Member, guild)) { return; } @@ -244,12 +244,12 @@ namespace Server.Guilds public void SetTitle_Callback(Mobile from, string text) { - if (!(from is PlayerMobile pm) || m_Member == null) + if (@from is not PlayerMobile pm || m_Member == null) { return; } - if (!(m_Member.Guild is Guild g) || !IsMember(pm, g) || + if (m_Member.Guild is not Guild g || !IsMember(pm, g) || !(pm.GuildRank.GetFlag(RankFlags.CanSetGuildTitle) && (pm.GuildRank.Rank > m_Member.GuildRank.Rank || pm == m_Member))) { diff --git a/Projects/UOContent/Gumps/Guilds/New Guild System/GuildRosterGump.cs b/Projects/UOContent/Gumps/Guilds/New Guild System/GuildRosterGump.cs index c31e443db..eedea7a6b 100644 --- a/Projects/UOContent/Gumps/Guilds/New Guild System/GuildRosterGump.cs +++ b/Projects/UOContent/Gumps/Guilds/New Guild System/GuildRosterGump.cs @@ -101,7 +101,7 @@ namespace Server.Guilds { base.OnResponse(sender, info); - if (!(sender.Mobile is PlayerMobile pm) || !IsMember(pm, guild)) + if (sender.Mobile is not PlayerMobile pm || !IsMember(pm, guild)) { return; } diff --git a/Projects/UOContent/Gumps/Guilds/New Guild System/OtherGuildInfo.cs b/Projects/UOContent/Gumps/Guilds/New Guild System/OtherGuildInfo.cs index 9e5dca714..b92cd52aa 100644 --- a/Projects/UOContent/Gumps/Guilds/New Guild System/OtherGuildInfo.cs +++ b/Projects/UOContent/Gumps/Guilds/New Guild System/OtherGuildInfo.cs @@ -715,7 +715,7 @@ namespace Server.Guilds public void CreateAlliance_Callback(Mobile from, string text) { - if (!(from is PlayerMobile pm)) + if (@from is not PlayerMobile pm) { return; } diff --git a/Projects/UOContent/Gumps/PlayerVendorGumps.cs b/Projects/UOContent/Gumps/PlayerVendorGumps.cs index c12a8589d..b525b59d6 100644 --- a/Projects/UOContent/Gumps/PlayerVendorGumps.cs +++ b/Projects/UOContent/Gumps/PlayerVendorGumps.cs @@ -258,7 +258,7 @@ namespace Server.Gumps { var from = sender.Mobile; - if (info.ButtonID == 1 || info.ButtonID == 2) // See goods or Customize + if (info.ButtonID is 1 or 2) // See goods or Customize { m_Vendor.CheckTeleport(from); } diff --git a/Projects/UOContent/Gumps/Props/PropsGump.cs b/Projects/UOContent/Gumps/Props/PropsGump.cs index b0be1bdfb..e7b43f0fc 100644 --- a/Projects/UOContent/Gumps/Props/PropsGump.cs +++ b/Projects/UOContent/Gumps/Props/PropsGump.cs @@ -458,7 +458,7 @@ namespace Server.Gumps return Array.Empty(); } - if (!(attrs[0] is CustomEnumAttribute ce)) + if (attrs[0] is not CustomEnumAttribute ce) { return Array.Empty(); } diff --git a/Projects/UOContent/Gumps/ReportMurderer.cs b/Projects/UOContent/Gumps/ReportMurderer.cs index 1a96ca70f..6394a76bd 100644 --- a/Projects/UOContent/Gumps/ReportMurderer.cs +++ b/Projects/UOContent/Gumps/ReportMurderer.cs @@ -63,7 +63,7 @@ namespace Server.Gumps var ourKarma = g.Karma; var innocent = n == Notoriety.Innocent; - var criminal = n == Notoriety.Criminal || n == Notoriety.Murderer; + var criminal = n is Notoriety.Criminal or Notoriety.Murderer; var fameAward = m.Fame / 200; var karmaAward = 0; diff --git a/Projects/UOContent/Gumps/VendorRentalGumps.cs b/Projects/UOContent/Gumps/VendorRentalGumps.cs index 84872e6a0..255bb1ce9 100644 --- a/Projects/UOContent/Gumps/VendorRentalGumps.cs +++ b/Projects/UOContent/Gumps/VendorRentalGumps.cs @@ -45,7 +45,7 @@ namespace Server.Gumps AddImageTiled(70, 80, 230, 2, 0x23C5); } - if (type == GumpType.UnlockedContract || type == GumpType.LockedContract) + if (type is GumpType.UnlockedContract or GumpType.LockedContract) { AddButton(30, 96, 0x15E1, 0x15E5, 0, GumpButtonType.Page, 2); } @@ -53,7 +53,7 @@ namespace Server.Gumps AddHtmlLocalized(50, 95, 150, 20, 1062354, 0x1); // Contract Length AddHtmlLocalized(230, 95, 270, 20, duration.Name, 0x1); - if (type == GumpType.UnlockedContract || type == GumpType.LockedContract) + if (type is GumpType.UnlockedContract or GumpType.LockedContract) { AddButton(30, 116, 0x15E1, 0x15E5, 1); } @@ -76,7 +76,7 @@ namespace Server.Gumps AddImage(49, 170, 0x61); AddHtmlLocalized(60, 170, 250, 20, 1062355, 0x1); // Renew On Expiration? - if (type == GumpType.LockedContract || type == GumpType.UnlockedContract || type == GumpType.VendorLandlord) + if (type is GumpType.LockedContract or GumpType.UnlockedContract or GumpType.VendorLandlord) { AddButton(30, 192, 0x15E1, 0x15E5, 3); } @@ -113,7 +113,7 @@ namespace Server.Gumps AddButton(67, 295, 0x15E1, 0x15E5, 5); AddHtmlLocalized(85, 294, 270, 20, 1062358, 0x28); // Offer Contract To Someone } - else if (type == GumpType.VendorLandlord || type == GumpType.VendorRenter) + else if (type is GumpType.VendorLandlord or GumpType.VendorRenter) { if (type == GumpType.VendorLandlord) { @@ -127,7 +127,7 @@ namespace Server.Gumps AddLabel(120, 293, 0x64, renter != null ? renter.Name : ""); } - if (type == GumpType.UnlockedContract || type == GumpType.LockedContract) + if (type is GumpType.UnlockedContract or GumpType.LockedContract) { AddPage(2); @@ -348,7 +348,7 @@ namespace Server.Gumps return; } - if (!(targeted is Mobile mob) || !mob.Player || !mob.Alive || mob == from) + if (targeted is not Mobile mob || !mob.Player || !mob.Alive || mob == from) { from.SendLocalizedMessage(1071984); // That is not a valid target for a rental contract! } diff --git a/Projects/UOContent/Gumps/ViewHousesGump.cs b/Projects/UOContent/Gumps/ViewHousesGump.cs index b140102de..09078026a 100644 --- a/Projects/UOContent/Gumps/ViewHousesGump.cs +++ b/Projects/UOContent/Gumps/ViewHousesGump.cs @@ -180,7 +180,7 @@ namespace Server.Gumps { var list = new List(); - if (!(owner.Account is Account acct)) + if (owner.Account is not Account acct) { list.AddRange(BaseHouse.GetHouses(owner)); } diff --git a/Projects/UOContent/Holiday Stuff/Halloween/2006/Engines/TrickOrTreat.cs b/Projects/UOContent/Holiday Stuff/Halloween/2006/Engines/TrickOrTreat.cs index 8841ab65e..3384eec0f 100644 --- a/Projects/UOContent/Holiday Stuff/Halloween/2006/Engines/TrickOrTreat.cs +++ b/Projects/UOContent/Holiday Stuff/Halloween/2006/Engines/TrickOrTreat.cs @@ -153,7 +153,7 @@ namespace Server.Engines.Events return; } - if (!(targ is Mobile)) + if (targ is not Mobile) { from.SendLocalizedMessage(1076781); /* There is little chance of getting candy from that! */ return; diff --git a/Projects/UOContent/Holiday Stuff/Halloween/2006/Items/HalloweenPumpkin.cs b/Projects/UOContent/Holiday Stuff/Halloween/2006/Items/HalloweenPumpkin.cs index 8acec3394..7197c531e 100644 --- a/Projects/UOContent/Holiday Stuff/Halloween/2006/Items/HalloweenPumpkin.cs +++ b/Projects/UOContent/Holiday Stuff/Halloween/2006/Items/HalloweenPumpkin.cs @@ -62,7 +62,7 @@ namespace Server.Items public override bool OnDragLift(Mobile from) { - if (Name == null && (ItemID == 0x4694 || ItemID == 0x4691 || ItemID == 0x4698 || ItemID == 0x4695)) + if (Name == null && ItemID is 0x4694 or 0x4691 or 0x4698 or 0x4695) { if (Utility.RandomBool()) { diff --git a/Projects/UOContent/Items/Addons/DartBoard.cs b/Projects/UOContent/Items/Addons/DartBoard.cs index 52c4cbd55..967b27fd8 100644 --- a/Projects/UOContent/Items/Addons/DartBoard.cs +++ b/Projects/UOContent/Items/Addons/DartBoard.cs @@ -41,11 +41,11 @@ namespace Server.Items } else if (East) { - canThrow = dir == Direction.Left || dir == Direction.West || dir == Direction.Up; + canThrow = dir is Direction.Left or Direction.West or Direction.Up; } else { - canThrow = dir == Direction.Up || dir == Direction.North || dir == Direction.Right; + canThrow = dir is Direction.Up or Direction.North or Direction.Right; } if (canThrow) @@ -60,7 +60,7 @@ namespace Server.Items public void Throw(Mobile from) { - if (!(from.Weapon is BaseKnife knife)) + if (@from.Weapon is not BaseKnife knife) { from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 500751); // Try holding a knife... return; diff --git a/Projects/UOContent/Items/Armor/BaseArmor.cs b/Projects/UOContent/Items/Armor/BaseArmor.cs index 55bbe8a65..dd79ac923 100644 --- a/Projects/UOContent/Items/Armor/BaseArmor.cs +++ b/Projects/UOContent/Items/Armor/BaseArmor.cs @@ -598,7 +598,7 @@ namespace Server.Items ); // Not sure since when, but right now 15 points are added, not 14. } - if (Core.ML && !(this is BaseShield)) + if (Core.ML && this is not BaseShield) { var bonus = (int)(from.Skills.ArmsLore.Value / 20); @@ -820,7 +820,7 @@ namespace Server.Items public override void OnAfterDuped(Item newItem) { - if (!(newItem is BaseArmor armor)) + if (newItem is not BaseArmor armor) { return; } diff --git a/Projects/UOContent/Items/Books/BookPackets.cs b/Projects/UOContent/Items/Books/BookPackets.cs index 303bb34e0..6eee9c451 100644 --- a/Projects/UOContent/Items/Books/BookPackets.cs +++ b/Projects/UOContent/Items/Books/BookPackets.cs @@ -33,7 +33,7 @@ namespace Server.Items { var from = state.Mobile; - if (!(World.FindItem((Serial)reader.ReadUInt32()) is BaseBook book) || !book.Writable || + if (World.FindItem((Serial)reader.ReadUInt32()) is not BaseBook book || !book.Writable || !from.InRange(book.GetWorldLocation(), 1) || !book.IsAccessibleTo(from)) { return; @@ -52,7 +52,7 @@ namespace Server.Items { var from = state.Mobile; - if (!(World.FindItem((Serial)reader.ReadUInt32()) is BaseBook book) || !book.Writable || + if (World.FindItem((Serial)reader.ReadUInt32()) is not BaseBook book || !book.Writable || !from.InRange(book.GetWorldLocation(), 1) || !book.IsAccessibleTo(from)) { return; @@ -88,7 +88,7 @@ namespace Server.Items { var from = state.Mobile; - if (!(World.FindItem((Serial)reader.ReadUInt32()) is BaseBook book) || !book.Writable || + if (World.FindItem((Serial)reader.ReadUInt32()) is not BaseBook book || !book.Writable || !from.InRange(book.GetWorldLocation(), 1) || !book.IsAccessibleTo(from)) { return; diff --git a/Projects/UOContent/Items/Construction/Doors/BaseDoor.cs b/Projects/UOContent/Items/Construction/Doors/BaseDoor.cs index 1992b7c68..bd44f0a7f 100644 --- a/Projects/UOContent/Items/Construction/Doors/BaseDoor.cs +++ b/Projects/UOContent/Items/Construction/Doors/BaseDoor.cs @@ -144,7 +144,7 @@ namespace Server.Items private static void Link_OnFirstTarget(Mobile from, object targeted) { - if (!(targeted is BaseDoor door)) + if (targeted is not BaseDoor door) { from.BeginTarget(-1, false, TargetFlags.None, Link_OnFirstTarget); from.SendMessage("That is not a door. Try again."); @@ -158,7 +158,7 @@ namespace Server.Items private static void Link_OnSecondTarget(Mobile from, object targeted, BaseDoor first) { - if (!(targeted is BaseDoor second)) + if (targeted is not BaseDoor second) { from.BeginTarget(-1, false, TargetFlags.None, Link_OnSecondTarget, first); from.SendMessage("That is not a door. Try again."); @@ -180,7 +180,7 @@ namespace Server.Items private static void ChainLink_OnTarget(Mobile from, object targeted, List list) { - if (!(targeted is BaseDoor door)) + if (targeted is not BaseDoor door) { from.BeginTarget(-1, false, TargetFlags.None, ChainLink_OnTarget, list); from.SendMessage("That is not a door. Try again."); @@ -328,8 +328,8 @@ namespace Server.Items { var item = items[i]; - if (!(item is BaseMulti) && item.ItemID <= TileData.MaxItemValue && item.AtWorldPoint(x, y) && - !(item is BaseDoor)) + 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; diff --git a/Projects/UOContent/Items/Construction/Misc/Vines.cs b/Projects/UOContent/Items/Construction/Misc/Vines.cs index e45923ebd..f561050c2 100644 --- a/Projects/UOContent/Items/Construction/Misc/Vines.cs +++ b/Projects/UOContent/Items/Construction/Misc/Vines.cs @@ -10,7 +10,7 @@ namespace Server.Items [Constructible] public Vines(int v) : base(0xCEB) { - if (v < 0 || v > 7) + if (v is < 0 or > 7) { v = 0; } diff --git a/Projects/UOContent/Items/Containers/Container.cs b/Projects/UOContent/Items/Containers/Container.cs index f9c92bbcc..1fce1751a 100644 --- a/Projects/UOContent/Items/Containers/Container.cs +++ b/Projects/UOContent/Items/Containers/Container.cs @@ -76,7 +76,7 @@ namespace Server.Items { var item = list[i]; - if (!(item is Container) && item.StackWith(from, dropped, false)) + if (item is not Container && item.StackWith(from, dropped, false)) { return true; } diff --git a/Projects/UOContent/Items/Containers/FillableContainers.cs b/Projects/UOContent/Items/Containers/FillableContainers.cs index 72d371803..54ccdd410 100644 --- a/Projects/UOContent/Items/Containers/FillableContainers.cs +++ b/Projects/UOContent/Items/Containers/FillableContainers.cs @@ -646,11 +646,11 @@ namespace Server.Items (int)KeyType.Rusty ); } - else if (item is Arrow || item is Bolt) + else if (item is Arrow or Bolt) { item.Amount = Utility.RandomMinMax(2, 6); } - else if (item is Bandage || item is Lockpick) + else if (item is Bandage or Lockpick) { item.Amount = Utility.RandomMinMax(1, 3); } diff --git a/Projects/UOContent/Items/Containers/FurnitureContainer.cs b/Projects/UOContent/Items/Containers/FurnitureContainer.cs index ea41f73d3..07dbe1597 100644 --- a/Projects/UOContent/Items/Containers/FurnitureContainer.cs +++ b/Projects/UOContent/Items/Containers/FurnitureContainer.cs @@ -356,7 +356,7 @@ namespace Server.Items return false; } - if (c is Armoire || c is FancyArmoire) + if (c is Armoire or FancyArmoire) { Timer t = new FurnitureTimer(c, m); t.Start(); @@ -382,7 +382,7 @@ namespace Server.Items t.Stop(); } - if (c is Armoire || c is FancyArmoire) + if (c is Armoire or FancyArmoire) { c.ItemID = c.ItemID switch { diff --git a/Projects/UOContent/Items/Containers/SalvageBag.cs b/Projects/UOContent/Items/Containers/SalvageBag.cs index da47e9740..3d8be35dc 100644 --- a/Projects/UOContent/Items/Containers/SalvageBag.cs +++ b/Projects/UOContent/Items/Containers/SalvageBag.cs @@ -157,13 +157,12 @@ namespace Server.Items { foreach (var i in Items) { - if (!(i is IScissorable) || i.Deleted) + if (i is not IScissorable || i.Deleted) { continue; } - if (i is BaseClothing || i is Cloth || i is BoltOfCloth || i is Hides || i is BonePile || - i is BaseArmor armor && CraftResources.GetType(armor.Resource) == CraftResourceType.Leather) + if (i is BaseClothing or Cloth or BoltOfCloth or Hides or BonePile || i is BaseArmor armor && CraftResources.GetType(armor.Resource) == CraftResourceType.Leather) { return true; } @@ -249,7 +248,7 @@ namespace Server.Items { var item = scissorables[i]; - if (!(item is IScissorable scissorable)) + if (item is not IScissorable scissorable) { continue; } diff --git a/Projects/UOContent/Items/Deeds/DragonBardingDeed.cs b/Projects/UOContent/Items/Deeds/DragonBardingDeed.cs index acd638366..cf3e814a4 100644 --- a/Projects/UOContent/Items/Deeds/DragonBardingDeed.cs +++ b/Projects/UOContent/Items/Deeds/DragonBardingDeed.cs @@ -110,7 +110,7 @@ namespace Server.Items return; } - if (!(obj is SwampDragon pet) || pet.HasBarding) + if (obj is not SwampDragon pet || pet.HasBarding) { from.SendLocalizedMessage(1053025); // That is not an unarmored swamp dragon. } diff --git a/Projects/UOContent/Items/Deeds/HairRestylingDeed.cs b/Projects/UOContent/Items/Deeds/HairRestylingDeed.cs index a6b999b71..847536294 100644 --- a/Projects/UOContent/Items/Deeds/HairRestylingDeed.cs +++ b/Projects/UOContent/Items/Deeds/HairRestylingDeed.cs @@ -146,7 +146,7 @@ namespace Server.Items return; } - if (info.ButtonID < 1 || info.ButtonID > 10) + if (info.ButtonID is < 1 or > 10) { return; } diff --git a/Projects/UOContent/Items/Deeds/HolidayTreeDeed.cs b/Projects/UOContent/Items/Deeds/HolidayTreeDeed.cs index ea3fec3b1..9f3eb7962 100644 --- a/Projects/UOContent/Items/Deeds/HolidayTreeDeed.cs +++ b/Projects/UOContent/Items/Deeds/HolidayTreeDeed.cs @@ -89,7 +89,7 @@ namespace Server.Items public void Placement_OnTarget(Mobile from, object targeted, HolidayTreeType type) { - if (!(targeted is IPoint3D p)) + if (targeted is not IPoint3D p) { return; } diff --git a/Projects/UOContent/Items/Deeds/VendorRentalContract.cs b/Projects/UOContent/Items/Deeds/VendorRentalContract.cs index 437d4d0f4..6c37f9f55 100644 --- a/Projects/UOContent/Items/Deeds/VendorRentalContract.cs +++ b/Projects/UOContent/Items/Deeds/VendorRentalContract.cs @@ -274,7 +274,7 @@ namespace Server.Items return; } - if (!(targeted is IPoint3D location)) + if (targeted is not IPoint3D location) { return; } diff --git a/Projects/UOContent/Items/Food/Beverage.cs b/Projects/UOContent/Items/Food/Beverage.cs index b3c02eb83..91edd8426 100644 --- a/Projects/UOContent/Items/Food/Beverage.cs +++ b/Projects/UOContent/Items/Food/Beverage.cs @@ -262,7 +262,7 @@ namespace Server.Items public override int ComputeItemID() { - if (ItemID == 0x99A || ItemID == 0x9B3 || ItemID == 0x9BF || ItemID == 0x9CB) + if (ItemID is 0x99A or 0x9B3 or 0x9BF or 0x9CB) { return ItemID; } @@ -420,7 +420,7 @@ namespace Server.Items { if (IsEmpty) { - if (ItemID == 0x9A7 || ItemID == 0xFF7) + if (ItemID is 0x9A7 or 0xFF7) { return ItemID; } @@ -477,7 +477,7 @@ namespace Server.Items } case BeverageType.Water: { - if (ItemID == 0xFF8 || ItemID == 0xFF9 || ItemID == 0x1F9E) + if (ItemID is 0xFF8 or 0xFF9 or 0x1F9E) { return ItemID; } @@ -854,7 +854,7 @@ namespace Server.Items { var qs = player.Quest; - if (!(qs is WitchApprenticeQuest)) + if (qs is not WitchApprenticeQuest) { return; } @@ -986,7 +986,7 @@ namespace Server.Items item.Pour(from, this); } else if (targ is AddonComponent component && - (component.Addon is WaterVatEast || component.Addon is WaterVatSouth) && + component.Addon is WaterVatEast or WaterVatSouth && Content == BeverageType.Water) { if (from is PlayerMobile player) @@ -1070,7 +1070,7 @@ namespace Server.Items for (var i = 0; i < items.Length; ++i) { - if (!(items[i] is BaseBeverage bev) || bev.Content != content || bev.IsEmpty) + if (items[i] is not BaseBeverage bev || bev.Content != content || bev.IsEmpty) { continue; } diff --git a/Projects/UOContent/Items/Food/Cooking.cs b/Projects/UOContent/Items/Food/Cooking.cs index 8b17e5a8f..1d74d028c 100644 --- a/Projects/UOContent/Items/Food/Cooking.cs +++ b/Projects/UOContent/Items/Food/Cooking.cs @@ -44,7 +44,7 @@ namespace Server.Items return; } - if (!(targeted is Item targetItem) || targetItem.Deleted) + if (targeted is not Item targetItem || targetItem.Deleted) { return; } @@ -390,7 +390,7 @@ namespace Server.Items { Delete(); } - else if (m_Quantity < 20 && (ItemID == 0x1039 || ItemID == 0x1045)) + else if (m_Quantity < 20 && ItemID is 0x1039 or 0x1045) { ++ItemID; } @@ -440,7 +440,7 @@ namespace Server.Items return; } - if (ItemID == 0x1039 || ItemID == 0x1045) + if (ItemID is 0x1039 or 0x1045) { ++ItemID; } diff --git a/Projects/UOContent/Items/Games/BaseBoard.cs b/Projects/UOContent/Items/Games/BaseBoard.cs index f9f75c2a5..8426bcb84 100644 --- a/Projects/UOContent/Items/Games/BaseBoard.cs +++ b/Projects/UOContent/Items/Games/BaseBoard.cs @@ -116,7 +116,7 @@ namespace Server.Items public static bool ValidateDefault(Mobile from, BaseBoard board) => !board.Deleted && (from.AccessLevel >= AccessLevel.GameMaster || from.Alive && - (board.IsChildOf(from.Backpack) || !(board.RootParent is Mobile) && + (board.IsChildOf(from.Backpack) || board.RootParent is not Mobile && board.Map == from.Map && from.InRange(board.GetWorldLocation(), 1) && BaseHouse.FindHouseAt(board)?.IsOwner(from) == true)); diff --git a/Projects/UOContent/Items/Games/Mahjong/MahjongDealerIndicator.cs b/Projects/UOContent/Items/Games/Mahjong/MahjongDealerIndicator.cs index 9f022e998..2d9d694be 100644 --- a/Projects/UOContent/Items/Games/Mahjong/MahjongDealerIndicator.cs +++ b/Projects/UOContent/Items/Games/Mahjong/MahjongDealerIndicator.cs @@ -33,7 +33,7 @@ namespace Server.Engines.Mahjong public static MahjongPieceDim GetDimensions(Point2D position, MahjongPieceDirection direction) { - if (direction == MahjongPieceDirection.Up || direction == MahjongPieceDirection.Down) + if (direction is MahjongPieceDirection.Up or MahjongPieceDirection.Down) { return new MahjongPieceDim(position, 40, 20); } diff --git a/Projects/UOContent/Items/Games/Mahjong/MahjongTile.cs b/Projects/UOContent/Items/Games/Mahjong/MahjongTile.cs index ddc373d55..e9d3bf628 100644 --- a/Projects/UOContent/Items/Games/Mahjong/MahjongTile.cs +++ b/Projects/UOContent/Items/Games/Mahjong/MahjongTile.cs @@ -51,7 +51,7 @@ namespace Server.Engines.Mahjong public static MahjongPieceDim GetDimensions(Point2D position, MahjongPieceDirection direction) { - if (direction == MahjongPieceDirection.Up || direction == MahjongPieceDirection.Down) + if (direction is MahjongPieceDirection.Up or MahjongPieceDirection.Down) { return new MahjongPieceDim(position, 20, 30); } diff --git a/Projects/UOContent/Items/Guilds/Guildstone.cs b/Projects/UOContent/Items/Guilds/Guildstone.cs index 8191d8505..f002a89b2 100644 --- a/Projects/UOContent/Items/Guilds/Guildstone.cs +++ b/Projects/UOContent/Items/Guilds/Guildstone.cs @@ -431,7 +431,7 @@ namespace Server.Items public void Placement_OnTarget(Mobile from, object targeted) { - if (!(targeted is IPoint3D p) || Deleted) + if (targeted is not IPoint3D p || Deleted) { return; } diff --git a/Projects/UOContent/Items/Jewels/BaseJewel.cs b/Projects/UOContent/Items/Jewels/BaseJewel.cs index b049b8876..ac7503be4 100644 --- a/Projects/UOContent/Items/Jewels/BaseJewel.cs +++ b/Projects/UOContent/Items/Jewels/BaseJewel.cs @@ -195,7 +195,7 @@ namespace Server.Items public override void OnAfterDuped(Item newItem) { - if (!(newItem is BaseJewel jewel)) + if (newItem is not BaseJewel jewel) { return; } diff --git a/Projects/UOContent/Items/Lights/BaseEquippableLight.cs b/Projects/UOContent/Items/Lights/BaseEquippableLight.cs index 3894733cd..5310b457c 100644 --- a/Projects/UOContent/Items/Lights/BaseEquippableLight.cs +++ b/Projects/UOContent/Items/Lights/BaseEquippableLight.cs @@ -11,7 +11,7 @@ namespace Server.Items public override void Ignite() { - if (!(Parent is Mobile) && RootParent is Mobile holder) + if (Parent is not Mobile && RootParent is Mobile holder) { if (holder.EquipItem(this)) { diff --git a/Projects/UOContent/Items/Lights/CandleSkull.cs b/Projects/UOContent/Items/Lights/CandleSkull.cs index f82c6fb0f..049a426a3 100644 --- a/Projects/UOContent/Items/Lights/CandleSkull.cs +++ b/Projects/UOContent/Items/Lights/CandleSkull.cs @@ -29,7 +29,7 @@ namespace Server.Items { get { - if (ItemID == 0x1583 || ItemID == 0x1854) + if (ItemID is 0x1583 or 0x1854) { return 0x1854; } @@ -42,7 +42,7 @@ namespace Server.Items { get { - if (ItemID == 0x1853 || ItemID == 0x1584) + if (ItemID is 0x1853 or 0x1584) { return 0x1853; } diff --git a/Projects/UOContent/Items/Lights/Lantern.cs b/Projects/UOContent/Items/Lights/Lantern.cs index a925cf884..50635bda3 100644 --- a/Projects/UOContent/Items/Lights/Lantern.cs +++ b/Projects/UOContent/Items/Lights/Lantern.cs @@ -29,7 +29,7 @@ namespace Server.Items { get { - if (ItemID == 0xA15 || ItemID == 0xA17) + if (ItemID is 0xA15 or 0xA17) { return ItemID; } diff --git a/Projects/UOContent/Items/Maps/MapItemPackets.cs b/Projects/UOContent/Items/Maps/MapItemPackets.cs index a413e6213..08229830c 100644 --- a/Projects/UOContent/Items/Maps/MapItemPackets.cs +++ b/Projects/UOContent/Items/Maps/MapItemPackets.cs @@ -29,7 +29,7 @@ namespace Server.Network { var from = state.Mobile; - if (!(World.FindItem((Serial)reader.ReadUInt32()) is MapItem map)) + if (World.FindItem((Serial)reader.ReadUInt32()) is not MapItem map) { return; } diff --git a/Projects/UOContent/Items/Misc/Bola.cs b/Projects/UOContent/Items/Misc/Bola.cs index 67bac32f3..69ab24beb 100644 --- a/Projects/UOContent/Items/Misc/Bola.cs +++ b/Projects/UOContent/Items/Misc/Bola.cs @@ -68,13 +68,13 @@ namespace Server.Items new Bola().MoveToWorld(to.Location, to.Map); } - if (to is ChaosDragoon || to is ChaosDragoonElite) + if (to is ChaosDragoon or ChaosDragoonElite) { from.SendLocalizedMessage(1042047); // You fail to knock the rider from its mount. } var mt = to.Mount; - if (mt != null && !(to is ChaosDragoon || to is ChaosDragoonElite)) + if (mt != null && !(to is ChaosDragoon or ChaosDragoonElite)) { mt.Rider = null; } diff --git a/Projects/UOContent/Items/Misc/CommunicationCrystals.cs b/Projects/UOContent/Items/Misc/CommunicationCrystals.cs index a8605de49..357720994 100644 --- a/Projects/UOContent/Items/Misc/CommunicationCrystals.cs +++ b/Projects/UOContent/Items/Misc/CommunicationCrystals.cs @@ -121,7 +121,7 @@ namespace Server.Items public override void OnSpeech(SpeechEventArgs e) { - if (!Active || Receivers.Count == 0 || RootParent != null && !(RootParent is Mobile)) + if (!Active || Receivers.Count == 0 || RootParent != null && RootParent is not Mobile) { return; } diff --git a/Projects/UOContent/Items/Misc/Corpses/Corpse.cs b/Projects/UOContent/Items/Misc/Corpses/Corpse.cs index 3960d6383..766b5989e 100644 --- a/Projects/UOContent/Items/Misc/Corpses/Corpse.cs +++ b/Projects/UOContent/Items/Misc/Corpses/Corpse.cs @@ -789,7 +789,7 @@ namespace Server.Items public bool DevourCorpse() { - if (Devoured || Deleted || Killer?.Deleted != false || !Killer.Alive || !(Killer is IDevourer devourer) || + if (Devoured || Deleted || Killer?.Deleted != false || !Killer.Alive || Killer is not IDevourer devourer || Owner?.Deleted != false) { return false; @@ -1003,8 +1003,7 @@ namespace Server.Items var item = items[i]; var loc = item.Location; - if (item.Layer == Layer.Hair || item.Layer == Layer.FacialHair || !item.Movable || - !GetRestoreInfo(item, ref loc)) + if (item.Layer is Layer.Hair or Layer.FacialHair || !item.Movable || !GetRestoreInfo(item, ref loc)) { continue; } @@ -1055,7 +1054,7 @@ namespace Server.Items return; } - if (!(from is PlayerMobile player)) + if (@from is not PlayerMobile player) { return; } diff --git a/Projects/UOContent/Items/Misc/Guillotine.cs b/Projects/UOContent/Items/Misc/Guillotine.cs index b1195cb88..3b65f5a63 100644 --- a/Projects/UOContent/Items/Misc/Guillotine.cs +++ b/Projects/UOContent/Items/Misc/Guillotine.cs @@ -24,7 +24,7 @@ namespace Server.Items { from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that } - else if (Visible && (ItemID == 4656 || ItemID == 4702) && Core.Now >= m_NextUse) + else if (Visible && ItemID is 4656 or 4702 && Core.Now >= m_NextUse) { var p = GetWorldLocation(); @@ -89,11 +89,11 @@ namespace Server.Items private void BackUp() { - if (ItemID == 4678 || ItemID == 4679) + if (ItemID is 4678 or 4679) { ItemID = 4656; } - else if (ItemID == 4712 || ItemID == 4713) + else if (ItemID is 4712 or 4713) { ItemID = 4702; } @@ -112,11 +112,11 @@ namespace Server.Items int version = reader.ReadByte(); - if (ItemID == 4678 || ItemID == 4679) + if (ItemID is 4678 or 4679) { ItemID = 4656; } - else if (ItemID == 4712 || ItemID == 4713) + else if (ItemID is 4712 or 4713) { ItemID = 4702; } diff --git a/Projects/UOContent/Items/Misc/KeyRing.cs b/Projects/UOContent/Items/Misc/KeyRing.cs index 3ea0e1502..9260e7f26 100644 --- a/Projects/UOContent/Items/Misc/KeyRing.cs +++ b/Projects/UOContent/Items/Misc/KeyRing.cs @@ -29,7 +29,7 @@ namespace Server.Items return false; } - if (!(dropped is Key key) || key.KeyValue == 0) + if (dropped is not Key key || key.KeyValue == 0) { from.SendLocalizedMessage(501689); // Only non-blank keys can be put on a keyring. return false; @@ -80,7 +80,7 @@ namespace Server.Items public void Open(Mobile from) { - if (!(Parent is Container cont)) + if (Parent is not Container cont) { return; } diff --git a/Projects/UOContent/Items/Misc/PoolOfAcid.cs b/Projects/UOContent/Items/Misc/PoolOfAcid.cs index c5ceb1d96..db2511df9 100644 --- a/Projects/UOContent/Items/Misc/PoolOfAcid.cs +++ b/Projects/UOContent/Items/Misc/PoolOfAcid.cs @@ -66,7 +66,7 @@ namespace Server.Items foreach (var m in GetMobilesInRange(0)) { - if (m.Alive && !m.IsDeadBondedPet && (!(m is BaseCreature bc) || bc.Controlled || bc.Summoned)) + if (m.Alive && !m.IsDeadBondedPet && (m is not BaseCreature bc || bc.Controlled || bc.Summoned)) { toDamage.Add(m); } diff --git a/Projects/UOContent/Items/Quivers/BaseQuiver.cs b/Projects/UOContent/Items/Quivers/BaseQuiver.cs index 02a832003..6234087bd 100644 --- a/Projects/UOContent/Items/Quivers/BaseQuiver.cs +++ b/Projects/UOContent/Items/Quivers/BaseQuiver.cs @@ -126,7 +126,7 @@ namespace Server.Items public override void OnAfterDuped(Item newItem) { - if (!(newItem is BaseQuiver quiver)) + if (newItem is not BaseQuiver quiver) { return; } diff --git a/Projects/UOContent/Items/Shields/ChaosShield.cs b/Projects/UOContent/Items/Shields/ChaosShield.cs index 055b1a245..bbc80947c 100644 --- a/Projects/UOContent/Items/Shields/ChaosShield.cs +++ b/Projects/UOContent/Items/Shields/ChaosShield.cs @@ -63,7 +63,7 @@ namespace Server.Items return true; } - if (!(m.Guild is Guild g) || g.Type != GuildType.Chaos) + if (m.Guild is not Guild g || g.Type != GuildType.Chaos) { m.FixedEffect(0x3728, 10, 13); Delete(); diff --git a/Projects/UOContent/Items/Shields/OrderShield.cs b/Projects/UOContent/Items/Shields/OrderShield.cs index 7d5307737..1547c85aa 100644 --- a/Projects/UOContent/Items/Shields/OrderShield.cs +++ b/Projects/UOContent/Items/Shields/OrderShield.cs @@ -68,7 +68,7 @@ namespace Server.Items return true; } - if (!(m.Guild is Guild g) || g.Type != GuildType.Order) + if (m.Guild is not Guild g || g.Type != GuildType.Order) { m.FixedEffect(0x3728, 10, 13); Delete(); diff --git a/Projects/UOContent/Items/Skill Items/Camping/Bedroll.cs b/Projects/UOContent/Items/Skill Items/Camping/Bedroll.cs index 53bc96d55..78fcbe3eb 100644 --- a/Projects/UOContent/Items/Skill Items/Camping/Bedroll.cs +++ b/Projects/UOContent/Items/Skill Items/Camping/Bedroll.cs @@ -32,7 +32,7 @@ namespace Server.Items { var dir = PlayerMobile.GetDirection4(from.Location, Location); - if (dir == Direction.North || dir == Direction.South) + if (dir is Direction.North or Direction.South) { ItemID = 0xA55; } diff --git a/Projects/UOContent/Items/Skill Items/Fishing/Misc/SpecialFishingNet.cs b/Projects/UOContent/Items/Skill Items/Fishing/Misc/SpecialFishingNet.cs index 741864073..8d3f3e515 100644 --- a/Projects/UOContent/Items/Skill Items/Fishing/Misc/SpecialFishingNet.cs +++ b/Projects/UOContent/Items/Skill Items/Fishing/Misc/SpecialFishingNet.cs @@ -133,7 +133,7 @@ namespace Server.Items return; } - if (!(obj is IPoint3D p3D)) + if (obj is not IPoint3D p3D) { return; } @@ -216,7 +216,7 @@ namespace Server.Items Effects.SendLocationEffect(p, Map, 0x352D, 16, 4); Effects.PlaySound(p, Map, 0x364); } - else if (index <= 7 || index == 14) + else if (index is <= 7 or 14) { if (RequireDeepWater) { @@ -397,7 +397,7 @@ namespace Server.Items private static bool ValidateUndeepWater(Map map, object obj, ref int z) { - if (!(obj is StaticTarget)) + if (obj is not StaticTarget) { return false; } diff --git a/Projects/UOContent/Items/Skill Items/Harvest Tools/BaseHarvestTool.cs b/Projects/UOContent/Items/Skill Items/Harvest Tools/BaseHarvestTool.cs index 264147b2c..8fffda490 100644 --- a/Projects/UOContent/Items/Skill Items/Harvest Tools/BaseHarvestTool.cs +++ b/Projects/UOContent/Items/Skill Items/Harvest Tools/BaseHarvestTool.cs @@ -168,7 +168,7 @@ namespace Server.Items return; } - if (!(from is PlayerMobile pm)) + if (@from is not PlayerMobile pm) { return; } diff --git a/Projects/UOContent/Items/Skill Items/Magical/Misc/PotionKeg.cs b/Projects/UOContent/Items/Skill Items/Magical/Misc/PotionKeg.cs index 3f352c762..e8a633fab 100644 --- a/Projects/UOContent/Items/Skill Items/Magical/Misc/PotionKeg.cs +++ b/Projects/UOContent/Items/Skill Items/Magical/Misc/PotionKeg.cs @@ -258,7 +258,7 @@ namespace Server.Items public override bool OnDragDrop(Mobile from, Item item) { - if (!(item is BasePotion pot)) + if (item is not BasePotion pot) { from.SendLocalizedMessage(502232); // The keg is not designed to hold that type of object. return false; diff --git a/Projects/UOContent/Items/Skill Items/Magical/Potions/BasePotion.cs b/Projects/UOContent/Items/Skill Items/Magical/Potions/BasePotion.cs index 030a86745..e6f2bb93a 100644 --- a/Projects/UOContent/Items/Skill Items/Magical/Potions/BasePotion.cs +++ b/Projects/UOContent/Items/Skill Items/Magical/Potions/BasePotion.cs @@ -103,7 +103,7 @@ namespace Server.Items // if (keg == null) // continue; - if (keg.Held <= 0 || keg.Held >= 100) + if (keg.Held is <= 0 or >= 100) { continue; } diff --git a/Projects/UOContent/Items/Skill Items/Magical/Potions/Confusion Blast Potions/BaseConfusionBlastPotion.cs b/Projects/UOContent/Items/Skill Items/Magical/Potions/Confusion Blast Potions/BaseConfusionBlastPotion.cs index 63909ee5c..f65db4499 100644 --- a/Projects/UOContent/Items/Skill Items/Magical/Potions/Confusion Blast Potions/BaseConfusionBlastPotion.cs +++ b/Projects/UOContent/Items/Skill Items/Magical/Potions/Confusion Blast Potions/BaseConfusionBlastPotion.cs @@ -162,7 +162,7 @@ namespace Server.Items return; } - if (!(targeted is IPoint3D p) || from.Map == null) + if (targeted is not IPoint3D p || from.Map == null) { return; } diff --git a/Projects/UOContent/Items/Skill Items/Magical/Runebook.cs b/Projects/UOContent/Items/Skill Items/Magical/Runebook.cs index 97e16e150..2088180cb 100644 --- a/Projects/UOContent/Items/Skill Items/Magical/Runebook.cs +++ b/Projects/UOContent/Items/Skill Items/Magical/Runebook.cs @@ -365,7 +365,7 @@ namespace Server.Items public override void OnAfterDuped(Item newItem) { - if (!(newItem is Runebook book)) + if (newItem is not Runebook book) { return; } diff --git a/Projects/UOContent/Items/Skill Items/Magical/Spellbook.cs b/Projects/UOContent/Items/Skill Items/Magical/Spellbook.cs index f4d3f636d..18d0dc042 100644 --- a/Projects/UOContent/Items/Skill Items/Magical/Spellbook.cs +++ b/Projects/UOContent/Items/Skill Items/Magical/Spellbook.cs @@ -600,7 +600,7 @@ namespace Server.Items public override void OnAfterDuped(Item newItem) { - if (!(newItem is Spellbook book)) + if (newItem is not Spellbook book) { return; } diff --git a/Projects/UOContent/Items/Skill Items/Misc/Bandage.cs b/Projects/UOContent/Items/Skill Items/Misc/Bandage.cs index 058cfa1b1..aaab0407f 100644 --- a/Projects/UOContent/Items/Skill Items/Misc/Bandage.cs +++ b/Projects/UOContent/Items/Skill Items/Misc/Bandage.cs @@ -74,7 +74,7 @@ namespace Server.Items private static void EventSink_BandageTargetRequest(Mobile from, Item item, Mobile target) { - if (!(item is Bandage b) || b.Deleted) + if (item is not Bandage b || b.Deleted) { return; } diff --git a/Projects/UOContent/Items/Skill Items/Musical Instruments/BaseInstrument.cs b/Projects/UOContent/Items/Skill Items/Musical Instruments/BaseInstrument.cs index 52fc69dd1..d0faa631e 100644 --- a/Projects/UOContent/Items/Skill Items/Musical Instruments/BaseInstrument.cs +++ b/Projects/UOContent/Items/Skill Items/Musical Instruments/BaseInstrument.cs @@ -234,7 +234,7 @@ namespace Server.Items public static void OnPickedInstrument(Mobile from, object targeted, InstrumentPickedCallback callback) { - if (!(targeted is BaseInstrument instrument)) + if (targeted is not BaseInstrument instrument) { from.SendLocalizedMessage(500619); // That is not a musical instrument. } @@ -286,7 +286,7 @@ namespace Server.Items val += 100; } - if (targ is VampireBat || targ is VampireBatFamiliar) + if (targ is VampireBat or VampireBatFamiliar) { val += 100; } diff --git a/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/DyeTub.cs b/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/DyeTub.cs index 1f422cd94..be13e0150 100644 --- a/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/DyeTub.cs +++ b/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/DyeTub.cs @@ -178,7 +178,7 @@ namespace Server.Items } } } - else if ((item is Runebook || item is RecallRune) && m_Tub.AllowRunebooks) + else if (item is Runebook or RecallRune && m_Tub.AllowRunebooks) { if (!from.InRange(m_Tub.GetWorldLocation(), 1) || !from.InRange(item.GetWorldLocation(), 1)) { @@ -211,9 +211,7 @@ namespace Server.Items } } else if ((item is BaseArmor armor && - (armor.MaterialType == ArmorMaterialType.Leather || - armor.MaterialType == ArmorMaterialType.Studded) || item is ElvenBoots || - item is WoodlandBelt) && m_Tub.AllowLeather) + armor.MaterialType is ArmorMaterialType.Leather or ArmorMaterialType.Studded || item is ElvenBoots or WoodlandBelt) && m_Tub.AllowLeather) { if (!from.InRange(m_Tub.GetWorldLocation(), 1) || !from.InRange(item.GetWorldLocation(), 1)) { diff --git a/Projects/UOContent/Items/Skill Items/Tailor Items/Misc/Scissors.cs b/Projects/UOContent/Items/Skill Items/Tailor Items/Misc/Scissors.cs index 4a8c962e4..756505c08 100644 --- a/Projects/UOContent/Items/Skill Items/Tailor Items/Misc/Scissors.cs +++ b/Projects/UOContent/Items/Skill Items/Tailor Items/Misc/Scissors.cs @@ -84,7 +84,7 @@ namespace Server.Items } else if (targeted is Item item && !item.Movable) { - if (item is IScissorable obj && (obj is PlagueBeastInnard || obj is PlagueBeastMutationCore)) + if (item is IScissorable obj && obj is PlagueBeastInnard or PlagueBeastMutationCore) { if (CanScissor(from, obj) && obj.Scissor(from, m_Item)) { @@ -107,7 +107,7 @@ namespace Server.Items protected override void OnNonlocalTarget(Mobile from, object targeted) { - if (targeted is IScissorable obj && (obj is PlagueBeastInnard || obj is PlagueBeastMutationCore)) + if (targeted is IScissorable obj && obj is PlagueBeastInnard or PlagueBeastMutationCore) { if (CanScissor(from, obj) && obj.Scissor(from, m_Item)) { diff --git a/Projects/UOContent/Items/Skill Items/Thief/LockPick.cs b/Projects/UOContent/Items/Skill Items/Thief/LockPick.cs index e72c7f7cb..e94194e44 100644 --- a/Projects/UOContent/Items/Skill Items/Thief/LockPick.cs +++ b/Projects/UOContent/Items/Skill Items/Thief/LockPick.cs @@ -126,7 +126,7 @@ namespace Server.Items return; } - if (m_Item.LockLevel == 0 || m_Item.LockLevel == -255) + if (m_Item.LockLevel is 0 or -255) { // LockLevel of 0 means that the door can't be picklocked // LockLevel of -255 means it's magic locked diff --git a/Projects/UOContent/Items/Skill Items/Tinkering/Spyglass.cs b/Projects/UOContent/Items/Skill Items/Tinkering/Spyglass.cs index 46b5004a5..45881715f 100644 --- a/Projects/UOContent/Items/Skill Items/Tinkering/Spyglass.cs +++ b/Projects/UOContent/Items/Skill Items/Tinkering/Spyglass.cs @@ -50,7 +50,7 @@ namespace Server.Items { var qs = player.Quest; - if (!(qs is WitchApprenticeQuest)) + if (qs is not WitchApprenticeQuest) { return; } @@ -61,7 +61,7 @@ namespace Server.Items { Clock.GetTime(from.Map, from.X, from.Y, out var hours, out int _); - if (hours < 5 || hours > 17) + if (hours is < 5 or > 17) { player.SendLocalizedMessage( 1055040 diff --git a/Projects/UOContent/Items/Skill Items/Tools/BaseTool.cs b/Projects/UOContent/Items/Skill Items/Tools/BaseTool.cs index 271899878..e484fc193 100644 --- a/Projects/UOContent/Items/Skill Items/Tools/BaseTool.cs +++ b/Projects/UOContent/Items/Skill Items/Tools/BaseTool.cs @@ -141,14 +141,14 @@ namespace Server.Items { var check = m.FindItemOnLayer(Layer.OneHanded); - if (check is BaseTool && check != tool && !(check is AncientSmithyHammer)) + if (check is BaseTool && check != tool && check is not AncientSmithyHammer) { return false; } check = m.FindItemOnLayer(Layer.TwoHanded); - return !(check is BaseTool) || check == tool || check is AncientSmithyHammer; + return check is not BaseTool || check == tool || check is AncientSmithyHammer; } public override void OnSingleClick(Mobile from) diff --git a/Projects/UOContent/Items/Skill Items/Tools/RunicSewingKit.cs b/Projects/UOContent/Items/Skill Items/Tools/RunicSewingKit.cs index ae5d9449b..f980d2391 100644 --- a/Projects/UOContent/Items/Skill Items/Tools/RunicSewingKit.cs +++ b/Projects/UOContent/Items/Skill Items/Tools/RunicSewingKit.cs @@ -79,7 +79,7 @@ namespace Server.Items var version = reader.ReadInt(); - if (ItemID == 0x13E4 || ItemID == 0x13E3) + if (ItemID is 0x13E4 or 0x13E3) { ItemID = 0xF9D; } diff --git a/Projects/UOContent/Items/Special/8th Anniversary Items/Dawn's Music Box/DawnsMusicBox.cs b/Projects/UOContent/Items/Special/8th Anniversary Items/Dawn's Music Box/DawnsMusicBox.cs index 3e89229a0..bff115f2b 100644 --- a/Projects/UOContent/Items/Special/8th Anniversary Items/Dawn's Music Box/DawnsMusicBox.cs +++ b/Projects/UOContent/Items/Special/8th Anniversary Items/Dawn's Music Box/DawnsMusicBox.cs @@ -132,7 +132,7 @@ namespace Server.Items public override void OnAfterDuped(Item newItem) { - if (!(newItem is DawnsMusicBox box)) + if (newItem is not DawnsMusicBox box) { return; } diff --git a/Projects/UOContent/Items/Special/Evil Home Decor Collection/AwesomeDisturbingPortrait.cs b/Projects/UOContent/Items/Special/Evil Home Decor Collection/AwesomeDisturbingPortrait.cs index ad870ab43..4d311bd72 100644 --- a/Projects/UOContent/Items/Special/Evil Home Decor Collection/AwesomeDisturbingPortrait.cs +++ b/Projects/UOContent/Items/Special/Evil Home Decor Collection/AwesomeDisturbingPortrait.cs @@ -27,7 +27,7 @@ namespace Server.Items { Clock.GetTime(Map, X, Y, out var hours, out int _); - if (hours < 4 || hours > 20) + if (hours is < 4 or > 20) { Effects.PlaySound(Location, Map, 0x569); } diff --git a/Projects/UOContent/Items/Special/Evil Home Decor Collection/CreepyPortrait.cs b/Projects/UOContent/Items/Special/Evil Home Decor Collection/CreepyPortrait.cs index a8f1a198e..294e8dd00 100644 --- a/Projects/UOContent/Items/Special/Evil Home Decor Collection/CreepyPortrait.cs +++ b/Projects/UOContent/Items/Special/Evil Home Decor Collection/CreepyPortrait.cs @@ -35,7 +35,7 @@ namespace Server.Items { if (!Utility.InRange(old, Location, 2) && Utility.InRange(m.Location, Location, 2)) { - if (ItemID == 0x2A69 || ItemID == 0x2A6D) + if (ItemID is 0x2A69 or 0x2A6D) { Up(); Timer.StartTimer(TimeSpan.FromSeconds(0.5), TimeSpan.FromSeconds(0.5), 2, Up); @@ -43,7 +43,7 @@ namespace Server.Items } else if (Utility.InRange(old, Location, 2) && !Utility.InRange(m.Location, Location, 2)) { - if (ItemID == 0x2A6C || ItemID == 0x2A70) + if (ItemID is 0x2A6C or 0x2A70) { Down(); Timer.StartTimer(TimeSpan.FromSeconds(0.5), TimeSpan.FromSeconds(0.5), 2, Down); diff --git a/Projects/UOContent/Items/Special/Evil Home Decor Collection/HauntedMirror.cs b/Projects/UOContent/Items/Special/Evil Home Decor Collection/HauntedMirror.cs index f43857563..f77ca1d8f 100644 --- a/Projects/UOContent/Items/Special/Evil Home Decor Collection/HauntedMirror.cs +++ b/Projects/UOContent/Items/Special/Evil Home Decor Collection/HauntedMirror.cs @@ -22,7 +22,7 @@ namespace Server.Items { if (!Utility.InRange(old, Location, 2) && Utility.InRange(m.Location, Location, 2)) { - if (ItemID == 0x2A7B || ItemID == 0x2A7D) + if (ItemID is 0x2A7B or 0x2A7D) { Effects.PlaySound(Location, Map, Utility.RandomMinMax(0x551, 0x553)); ItemID += 1; @@ -30,7 +30,7 @@ namespace Server.Items } else if (Utility.InRange(old, Location, 2) && !Utility.InRange(m.Location, Location, 2)) { - if (ItemID == 0x2A7C || ItemID == 0x2A7E) + if (ItemID is 0x2A7C or 0x2A7E) { ItemID -= 1; } diff --git a/Projects/UOContent/Items/Special/Heritage Items/Guillotine.cs b/Projects/UOContent/Items/Special/Heritage Items/Guillotine.cs index 9612bb558..914ecba4a 100644 --- a/Projects/UOContent/Items/Special/Heritage Items/Guillotine.cs +++ b/Projects/UOContent/Items/Special/Heritage Items/Guillotine.cs @@ -87,7 +87,7 @@ namespace Server.Items public virtual void Activate(AddonComponent c, Mobile from) { - if (c.ItemID == 0x125E || c.ItemID == 0x1269 || c.ItemID == 0x1260) + if (c.ItemID is 0x125E or 0x1269 or 0x1260) { c.ItemID = 0x1269; } diff --git a/Projects/UOContent/Items/Special/Heritage Items/HouseLadder.cs b/Projects/UOContent/Items/Special/Heritage Items/HouseLadder.cs index bb610e8d8..da1364a98 100644 --- a/Projects/UOContent/Items/Special/Heritage Items/HouseLadder.cs +++ b/Projects/UOContent/Items/Special/Heritage Items/HouseLadder.cs @@ -160,7 +160,7 @@ namespace Server.Items public override void OnResponse(NetState sender, RelayInfo info) { - if (m_Deed?.Deleted != false || info.ButtonID == 0 || info.ButtonID < 1 || info.ButtonID > 8) + if (m_Deed?.Deleted != false || info.ButtonID is 0 or < 1 or > 8) { return; } diff --git a/Projects/UOContent/Items/Special/Holiday/Wreath.cs b/Projects/UOContent/Items/Special/Holiday/Wreath.cs index ebc3cad6c..14e5a9e7b 100644 --- a/Projects/UOContent/Items/Special/Holiday/Wreath.cs +++ b/Projects/UOContent/Items/Special/Holiday/Wreath.cs @@ -227,7 +227,7 @@ namespace Server.Items public void Placement_OnTarget(Mobile from, object targeted) { - if (!(targeted is IPoint3D p)) + if (targeted is not IPoint3D p) { return; } diff --git a/Projects/UOContent/Items/Special/House Raffle/HouseRaffleStone.cs b/Projects/UOContent/Items/Special/House Raffle/HouseRaffleStone.cs index 8e6f99915..deb7f74a5 100644 --- a/Projects/UOContent/Items/Special/House Raffle/HouseRaffleStone.cs +++ b/Projects/UOContent/Items/Special/House Raffle/HouseRaffleStone.cs @@ -299,7 +299,7 @@ namespace Server.Items private bool HasEntered(Mobile from) { - if (!(from.Account is Account acc)) + if (@from.Account is not Account acc) { return false; } @@ -509,7 +509,7 @@ namespace Server.Items return; } - if (!(from.Account is Account)) + if (@from.Account is not Account) { return; } diff --git a/Projects/UOContent/Items/Special/Mutation Core/PlagueBeastBackpack.cs b/Projects/UOContent/Items/Special/Mutation Core/PlagueBeastBackpack.cs index 672285179..a52de68c3 100644 --- a/Projects/UOContent/Items/Special/Mutation Core/PlagueBeastBackpack.cs +++ b/Projects/UOContent/Items/Special/Mutation Core/PlagueBeastBackpack.cs @@ -113,7 +113,7 @@ namespace Server.Items public override bool TryDropItem(Mobile from, Item dropped, bool sendFullMessage) { - if (dropped is PlagueBeastInnard || dropped is PlagueBeastGland) + if (dropped is PlagueBeastInnard or PlagueBeastGland) { return base.TryDropItem(from, dropped, sendFullMessage); } @@ -123,7 +123,7 @@ namespace Server.Items public override bool OnDragDropInto(Mobile from, Item item, Point3D p) { - if (IsAccessibleTo(from) && (item is PlagueBeastInnard || item is PlagueBeastGland)) + if (IsAccessibleTo(from) && item is PlagueBeastInnard or PlagueBeastGland) { var ir = ItemBounds.Table[item.ItemID]; int x, y; diff --git a/Projects/UOContent/Items/Special/Solen Items/BagOfSending.cs b/Projects/UOContent/Items/Special/Solen Items/BagOfSending.cs index e4af5f581..6deb51f52 100644 --- a/Projects/UOContent/Items/Special/Solen Items/BagOfSending.cs +++ b/Projects/UOContent/Items/Special/Solen Items/BagOfSending.cs @@ -258,7 +258,7 @@ namespace Server.Items 0x59 ); // You may only send items from your backpack to your bank box. } - else if (item is BagOfSending || item is Container) + else if (item is BagOfSending or Container) { from.NetState.SendMessage( m_Bag.Serial, diff --git a/Projects/UOContent/Items/Special/Solen Items/BraceletOfBinding.cs b/Projects/UOContent/Items/Special/Solen Items/BraceletOfBinding.cs index 3fdf40e66..8cd5832cf 100644 --- a/Projects/UOContent/Items/Special/Solen Items/BraceletOfBinding.cs +++ b/Projects/UOContent/Items/Special/Solen Items/BraceletOfBinding.cs @@ -412,7 +412,7 @@ namespace Server.Items if (m_Bracelet.Deleted || m_From.Deleted || !m_Bracelet.CheckUse(m_From, false) || - !(m_Bracelet.Bound.RootParent is Mobile boundRoot)) + m_Bracelet.Bound.RootParent is not Mobile boundRoot) { return; } diff --git a/Projects/UOContent/Items/Special/SoulStone.cs b/Projects/UOContent/Items/Special/SoulStone.cs index 7bba3a90a..e170157f7 100644 --- a/Projects/UOContent/Items/Special/SoulStone.cs +++ b/Projects/UOContent/Items/Special/SoulStone.cs @@ -167,7 +167,7 @@ namespace Server.Items return false; } - if (Account != null && (!(from.Account is Account) || from.Account.Username != Account)) + if (Account != null && (@from.Account is not Accounting.Account || from.Account.Username != Account)) { from.SendLocalizedMessage( 1070714 @@ -993,7 +993,7 @@ namespace Server.Items if (version <= 1) { - if (ItemID == 0x2A93 || ItemID == 0x2A94) + if (ItemID is 0x2A93 or 0x2A94) { ActiveItemID = Utility.Random(0x2AA1, 9); } diff --git a/Projects/UOContent/Items/Special/Special Scrolls/PowerScroll.cs b/Projects/UOContent/Items/Special/Special Scrolls/PowerScroll.cs index 50273d2ff..1dd35b8f3 100644 --- a/Projects/UOContent/Items/Special/Special Scrolls/PowerScroll.cs +++ b/Projects/UOContent/Items/Special/Special Scrolls/PowerScroll.cs @@ -72,7 +72,7 @@ namespace Server.Items { Hue = 0x481; - if (Value == 105.0 || skill == SkillName.Blacksmith || skill == SkillName.Tailoring) + if (Value == 105.0 || skill is SkillName.Blacksmith or SkillName.Tailoring) { LootType = LootType.Regular; } @@ -155,7 +155,7 @@ namespace Server.Items do { skillName = Skills.RandomElement(); - } while (skillName == SkillName.Blacksmith || skillName == SkillName.Tailoring); + } while (skillName is SkillName.Blacksmith or SkillName.Tailoring); return new PowerScroll(skillName, 100 + Utility.RandomMinMax(min, max) * 5); } @@ -312,7 +312,7 @@ namespace Server.Items var version = InheritsItem ? 0 : reader.ReadInt(); // Required for SpecialScroll insertion - if (Value == 105.0 || Skill == SkillName.Blacksmith || Skill == SkillName.Tailoring) + if (Value == 105.0 || Skill is SkillName.Blacksmith or SkillName.Tailoring) { LootType = LootType.Regular; } diff --git a/Projects/UOContent/Items/Special/Special Scrolls/SpecialScroll.cs b/Projects/UOContent/Items/Special/Special Scrolls/SpecialScroll.cs index 52416304c..77073a835 100644 --- a/Projects/UOContent/Items/Special/Special Scrolls/SpecialScroll.cs +++ b/Projects/UOContent/Items/Special/Special Scrolls/SpecialScroll.cs @@ -106,7 +106,7 @@ namespace Server.Items { InheritsItem = true; - if (!(this is StatCapScroll)) + if (this is not StatCapScroll) { Skill = (SkillName)reader.ReadInt(); } diff --git a/Projects/UOContent/Items/Special/Veteran Rewards/AnkhOfSacrifice.cs b/Projects/UOContent/Items/Special/Veteran Rewards/AnkhOfSacrifice.cs index 6d451fa81..1bd7ce1bc 100644 --- a/Projects/UOContent/Items/Special/Veteran Rewards/AnkhOfSacrifice.cs +++ b/Projects/UOContent/Items/Special/Veteran Rewards/AnkhOfSacrifice.cs @@ -157,7 +157,7 @@ namespace Server.Items { var from = state.Mobile; - if (info.ButtonID == 1 || info.ButtonID == 2) + if (info.ButtonID is 1 or 2) { if (from.Map?.CanFit(from.Location, 16, false, false) != true) { diff --git a/Projects/UOContent/Items/Special/Veteran Rewards/Banner.cs b/Projects/UOContent/Items/Special/Veteran Rewards/Banner.cs index e20d52477..f102d7441 100644 --- a/Projects/UOContent/Items/Special/Veteran Rewards/Banner.cs +++ b/Projects/UOContent/Items/Special/Veteran Rewards/Banner.cs @@ -264,7 +264,7 @@ namespace Server.Items var m = sender.Mobile; - if (info.ButtonID < Start || info.ButtonID > End || (info.ButtonID & 0x1) != 0) + if (info.ButtonID is < Start or > End || (info.ButtonID & 0x1) != 0) { return; } diff --git a/Projects/UOContent/Items/Special/Veteran Rewards/Cannon.cs b/Projects/UOContent/Items/Special/Veteran Rewards/Cannon.cs index 37246e4f6..4f55b12a1 100644 --- a/Projects/UOContent/Items/Special/Veteran Rewards/Cannon.cs +++ b/Projects/UOContent/Items/Special/Veteran Rewards/Cannon.cs @@ -273,7 +273,7 @@ namespace Server.Items return; } - if (!(targeted is IPoint3D p)) + if (targeted is not IPoint3D p) { return; } diff --git a/Projects/UOContent/Items/Special/Veteran Rewards/CommodityDeedBox.cs b/Projects/UOContent/Items/Special/Veteran Rewards/CommodityDeedBox.cs index 9c8224e06..a9d99e5a0 100644 --- a/Projects/UOContent/Items/Special/Veteran Rewards/CommodityDeedBox.cs +++ b/Projects/UOContent/Items/Special/Veteran Rewards/CommodityDeedBox.cs @@ -64,7 +64,7 @@ namespace Server.Items { var parent = deed; - while (parent != null && !(parent is CommodityDeedBox)) + while (parent != null && parent is not CommodityDeedBox) { parent = parent.Parent as Item; } diff --git a/Projects/UOContent/Items/Special/Veteran Rewards/DecorativeShield.cs b/Projects/UOContent/Items/Special/Veteran Rewards/DecorativeShield.cs index 08670eb85..71f5da8f8 100644 --- a/Projects/UOContent/Items/Special/Veteran Rewards/DecorativeShield.cs +++ b/Projects/UOContent/Items/Special/Veteran Rewards/DecorativeShield.cs @@ -255,9 +255,8 @@ namespace Server.Items public override void OnResponse(NetState sender, RelayInfo info) { - if (m_Shield?.Deleted != false || info.ButtonID < Start || info.ButtonID > End || - ((info.ButtonID & 0x1) != 0 || info.ButtonID >= 0x1582) && - (info.ButtonID < 0x1582 || info.ButtonID > 0x1585)) + if (m_Shield?.Deleted != false || info.ButtonID is < Start or > End || ((info.ButtonID & 0x1) != 0 || info.ButtonID >= 0x1582) && + info.ButtonID is < 0x1582 or > 0x1585) { return; } diff --git a/Projects/UOContent/Items/Special/Veteran Rewards/HangingSkeleton.cs b/Projects/UOContent/Items/Special/Veteran Rewards/HangingSkeleton.cs index 4ac2c0228..b46114ff2 100644 --- a/Projects/UOContent/Items/Special/Veteran Rewards/HangingSkeleton.cs +++ b/Projects/UOContent/Items/Special/Veteran Rewards/HangingSkeleton.cs @@ -27,8 +27,7 @@ namespace Server.Items { get { - if (ItemID == 0x1A03 || ItemID == 0x1A05 || ItemID == 0x1A09 || - ItemID == 0x1B1E || ItemID == 0x1B7F) + if (ItemID is 0x1A03 or 0x1A05 or 0x1A09 or 0x1B1E or 0x1B7F) { return true; } diff --git a/Projects/UOContent/Items/Special/Veteran Rewards/PottedCactus.cs b/Projects/UOContent/Items/Special/Veteran Rewards/PottedCactus.cs index c933063b5..80647576c 100644 --- a/Projects/UOContent/Items/Special/Veteran Rewards/PottedCactus.cs +++ b/Projects/UOContent/Items/Special/Veteran Rewards/PottedCactus.cs @@ -170,7 +170,7 @@ namespace Server.Items public override void OnResponse(NetState sender, RelayInfo info) { - if (m_Cactus?.Deleted != false || info.ButtonID < 0x1E0F || info.ButtonID > 0x1E14) + if (m_Cactus?.Deleted != false || info.ButtonID is < 0x1E0F or > 0x1E14) { return; } diff --git a/Projects/UOContent/Items/Special/Veteran Rewards/WallBanner.cs b/Projects/UOContent/Items/Special/Veteran Rewards/WallBanner.cs index 17503ade3..cced8f9cb 100644 --- a/Projects/UOContent/Items/Special/Veteran Rewards/WallBanner.cs +++ b/Projects/UOContent/Items/Special/Veteran Rewards/WallBanner.cs @@ -503,7 +503,7 @@ namespace Server.Items public override void OnResponse(NetState sender, RelayInfo info) { - if (m_WallBanner?.Deleted != false || info.ButtonID <= 0 || info.ButtonID >= 31) + if (m_WallBanner?.Deleted != false || info.ButtonID is <= 0 or >= 31) { return; } diff --git a/Projects/UOContent/Items/Suits/BaseSuit.cs b/Projects/UOContent/Items/Suits/BaseSuit.cs index 8e0475f59..19976269c 100644 --- a/Projects/UOContent/Items/Suits/BaseSuit.cs +++ b/Projects/UOContent/Items/Suits/BaseSuit.cs @@ -47,7 +47,7 @@ namespace Server.Items public bool Validate() { - if (!(RootParent is Mobile mobile) || mobile.AccessLevel >= AccessLevel) + if (RootParent is not Mobile mobile || mobile.AccessLevel >= AccessLevel) { return true; } diff --git a/Projects/UOContent/Items/Talismans/BaseTalisman.cs b/Projects/UOContent/Items/Talismans/BaseTalisman.cs index 84f159dc1..fe338037f 100644 --- a/Projects/UOContent/Items/Talismans/BaseTalisman.cs +++ b/Projects/UOContent/Items/Talismans/BaseTalisman.cs @@ -345,7 +345,7 @@ namespace Server.Items public override void OnAfterDuped(Item newItem) { - if (!(newItem is BaseTalisman talisman)) + if (newItem is not BaseTalisman talisman) { return; } @@ -1190,7 +1190,7 @@ namespace Server.Items return; } - if (!(o is Mobile target)) + if (o is not Mobile target) { from.SendLocalizedMessage(1046439); // That is not a valid target. return; diff --git a/Projects/UOContent/Items/Wands/BaseWand.cs b/Projects/UOContent/Items/Wands/BaseWand.cs index 448985af1..3e030dcd8 100644 --- a/Projects/UOContent/Items/Wands/BaseWand.cs +++ b/Projects/UOContent/Items/Wands/BaseWand.cs @@ -244,7 +244,7 @@ namespace Server.Items public virtual void DoWandTarget(Mobile from, object o) { - if (Deleted || _charges <= 0 || Parent != from || o is StaticTarget || o is LandTarget) + if (Deleted || _charges <= 0 || Parent != @from || o is StaticTarget or LandTarget) { return; } diff --git a/Projects/UOContent/Items/Weapons/Abilities/Dismount.cs b/Projects/UOContent/Items/Weapons/Abilities/Dismount.cs index 903803d19..069b5b3a0 100644 --- a/Projects/UOContent/Items/Weapons/Abilities/Dismount.cs +++ b/Projects/UOContent/Items/Weapons/Abilities/Dismount.cs @@ -39,7 +39,7 @@ namespace Server.Items return; } - if (defender is ChaosDragoon || defender is ChaosDragoonElite) + if (defender is ChaosDragoon or ChaosDragoonElite) { return; } diff --git a/Projects/UOContent/Items/Weapons/Axes/BaseAxe.cs b/Projects/UOContent/Items/Weapons/Axes/BaseAxe.cs index 595ec181c..05087567e 100644 --- a/Projects/UOContent/Items/Weapons/Axes/BaseAxe.cs +++ b/Projects/UOContent/Items/Weapons/Axes/BaseAxe.cs @@ -87,7 +87,7 @@ namespace Server.Items return; } - if (!(HarvestSystem is Mining)) + if (HarvestSystem is not Mining) { from.SendLocalizedMessage(1010018); // What do you want to use this item on? } diff --git a/Projects/UOContent/Items/Weapons/Fists.cs b/Projects/UOContent/Items/Weapons/Fists.cs index b2fe3fc93..e20c66c77 100644 --- a/Projects/UOContent/Items/Weapons/Fists.cs +++ b/Projects/UOContent/Items/Weapons/Fists.cs @@ -199,7 +199,7 @@ namespace Server.Items { var item = m.FindItemOnLayer(Layer.OneHanded); - return (item == null || item is Spellbook) && m.FindItemOnLayer(Layer.TwoHanded) == null; + return item is null or Spellbook && m.FindItemOnLayer(Layer.TwoHanded) == null; } private static void EventSink_DisarmRequest(Mobile m) diff --git a/Projects/UOContent/Items/Weapons/Ranged/BaseRanged.cs b/Projects/UOContent/Items/Weapons/Ranged/BaseRanged.cs index a3a393a33..05f3bf3da 100644 --- a/Projects/UOContent/Items/Weapons/Ranged/BaseRanged.cs +++ b/Projects/UOContent/Items/Weapons/Ranged/BaseRanged.cs @@ -53,7 +53,7 @@ namespace Server.Items if (canSwing) { - canSwing = !(attacker.Spell is Spell sp) || !sp.IsCasting || !sp.BlocksMovement; + canSwing = attacker.Spell is not Spell sp || !sp.IsCasting || !sp.BlocksMovement; } } diff --git a/Projects/UOContent/Items/Weapons/Ranged/JukaBow.cs b/Projects/UOContent/Items/Weapons/Ranged/JukaBow.cs index 09c372c7e..658c9d39c 100644 --- a/Projects/UOContent/Items/Weapons/Ranged/JukaBow.cs +++ b/Projects/UOContent/Items/Weapons/Ranged/JukaBow.cs @@ -43,7 +43,7 @@ namespace Server.Items public void OnTargetGears(Mobile from, object targ) { - if (!(targ is Gears g) || !g.IsChildOf(from.Backpack)) + if (targ is not Gears g || !g.IsChildOf(from.Backpack)) { from.SendMessage( "Those are not gears." diff --git a/Projects/UOContent/Misc/AccountPrompt.cs b/Projects/UOContent/Misc/AccountPrompt.cs index 12c6f39de..0e537c0d5 100644 --- a/Projects/UOContent/Misc/AccountPrompt.cs +++ b/Projects/UOContent/Misc/AccountPrompt.cs @@ -13,7 +13,7 @@ namespace Server.Misc Console.Write("Do you want to create the owner account now? (y/n): "); var answer = Console.ReadLine(); - if (answer == "y" || answer == "Y") + if (answer is "y" or "Y") { Console.WriteLine(); diff --git a/Projects/UOContent/Misc/Geometry.cs b/Projects/UOContent/Misc/Geometry.cs index 5af881d2b..d6a20b883 100644 --- a/Projects/UOContent/Misc/Geometry.cs +++ b/Projects/UOContent/Misc/Geometry.cs @@ -36,12 +36,12 @@ namespace Server.Misc public static void Circle2D(Point3D loc, Map map, int radius, DoEffect_Callback effect, int angleStart, int angleEnd) { - if (angleStart < 0 || angleStart > 360) + if (angleStart is < 0 or > 360) { angleStart = 0; } - if (angleEnd > 360 || angleEnd < 0) + if (angleEnd is > 360 or < 0) { angleEnd = 360; } diff --git a/Projects/UOContent/Misc/Gifts/Winter2004/Mistletoe.cs b/Projects/UOContent/Misc/Gifts/Winter2004/Mistletoe.cs index 6edd5a673..004f2fb43 100644 --- a/Projects/UOContent/Misc/Gifts/Winter2004/Mistletoe.cs +++ b/Projects/UOContent/Misc/Gifts/Winter2004/Mistletoe.cs @@ -233,7 +233,7 @@ namespace Server.Items public void Placement_OnTarget(Mobile from, object targeted) { - if (!(targeted is IPoint3D p)) + if (targeted is not IPoint3D p) { return; } diff --git a/Projects/UOContent/Misc/Guild.cs b/Projects/UOContent/Misc/Guild.cs index bccad8bb9..89e1ce4c5 100644 --- a/Projects/UOContent/Misc/Guild.cs +++ b/Projects/UOContent/Misc/Guild.cs @@ -937,7 +937,7 @@ namespace Server.Guilds public static void EventSink_GuildGumpRequest(Mobile m) { - if (!NewGuildSystem || !(m is PlayerMobile pm)) + if (!NewGuildSystem || m is not PlayerMobile pm) { return; } diff --git a/Projects/UOContent/Misc/LootPack.cs b/Projects/UOContent/Misc/LootPack.cs index 027e1ffb7..4e71aa7d9 100644 --- a/Projects/UOContent/Misc/LootPack.cs +++ b/Projects/UOContent/Misc/LootPack.cs @@ -750,7 +750,7 @@ namespace Server return item; } - if (item is BaseWeapon || item is BaseArmor || item is BaseJewel || item is BaseHat) + if (item is BaseWeapon or BaseArmor or BaseJewel or BaseHat) { if (Core.AOS) { diff --git a/Projects/UOContent/Misc/Notoriety.cs b/Projects/UOContent/Misc/Notoriety.cs index 33e2a8169..3579e988b 100644 --- a/Projects/UOContent/Misc/Notoriety.cs +++ b/Projects/UOContent/Misc/Notoriety.cs @@ -278,8 +278,7 @@ namespace Server.Misc { c.DisplayGuildTitle = false; - if (c.Map != Map.Internal && (Core.AOS || Guild.NewGuildSystem || c.ControlOrder == OrderType.Attack || - c.ControlOrder == OrderType.Guard)) + if (c.Map != Map.Internal && (Core.AOS || Guild.NewGuildSystem || c.ControlOrder is OrderType.Attack or OrderType.Guard)) { g = (Guild)(c.Guild = c.ControlMaster.Guild); } @@ -385,7 +384,7 @@ namespace Server.Misc return Notoriety.CanBeAttacked; } - if (!(target.Owner is PlayerMobile)) + if (target.Owner is not PlayerMobile) { return Notoriety.CanBeAttacked; } @@ -406,8 +405,7 @@ namespace Server.Misc { var bcTarg = target as BaseCreature; - if (Core.AOS && (target.Blessed || bcTarg?.IsInvulnerable == true || target is PlayerVendor || - target is TownCrier)) + if (Core.AOS && (target.Blessed || bcTarg?.IsInvulnerable == true || target is PlayerVendor or TownCrier)) { return Notoriety.Invulnerable; } @@ -458,8 +456,8 @@ namespace Server.Misc } if (target.Kills >= 5 || - target.Body.IsMonster && IsSummoned(bcTarg) && !(target is BaseFamiliar) && !(target is ArcaneFey) && - !(target is Golem) || bcTarg?.AlwaysMurderer == true || bcTarg?.IsAnimatedDead == true) + target.Body.IsMonster && IsSummoned(bcTarg) && target is not BaseFamiliar && target is not ArcaneFey && + target is not Golem || bcTarg?.AlwaysMurderer == true || bcTarg?.IsAnimatedDead == true) { return Notoriety.Murderer; } @@ -561,7 +559,7 @@ namespace Server.Misc return false; } - return !(m is BaseCreature c) || c.Deleted || !c.Controlled || c.ControlMaster == null || + return m is not BaseCreature c || c.Deleted || !c.Controlled || c.ControlMaster == null || !house.IsFriend(c.ControlMaster); } diff --git a/Projects/UOContent/Misc/PacketThrottles.cs b/Projects/UOContent/Misc/PacketThrottles.cs index b0459647b..d2b666ed9 100644 --- a/Projects/UOContent/Misc/PacketThrottles.cs +++ b/Projects/UOContent/Misc/PacketThrottles.cs @@ -66,7 +66,7 @@ namespace Server.Network int packetID = e.GetInt32(0); - if (packetID < 0 || packetID > 0x100) + if (packetID is < 0 or > 0x100) { e.Mobile.SendMessage("Invalid Command Format. PacketID must be between 0 and 0x100."); return; @@ -88,7 +88,7 @@ namespace Server.Network int packetID = e.GetInt32(0); int delay = e.GetInt32(1); - if (packetID < 0 || packetID > 0x100) + if (packetID is < 0 or > 0x100) { e.Mobile.SendMessage("Invalid Command Format. PacketID must be between 0 and 0x100."); return; diff --git a/Projects/UOContent/Misc/Profile.cs b/Projects/UOContent/Misc/Profile.cs index 04ceddea5..674ae7b81 100644 --- a/Projects/UOContent/Misc/Profile.cs +++ b/Projects/UOContent/Misc/Profile.cs @@ -64,7 +64,7 @@ namespace Server.Misc private static string GetAccountDuration(Mobile m) { - if (!(m.Account is Account a)) + if (m.Account is not Account a) { return ""; } diff --git a/Projects/UOContent/Misc/ResourceInfo.cs b/Projects/UOContent/Misc/ResourceInfo.cs index 778de771e..601436d56 100644 --- a/Projects/UOContent/Misc/ResourceInfo.cs +++ b/Projects/UOContent/Misc/ResourceInfo.cs @@ -713,10 +713,8 @@ namespace Server.Items /// /// Returns true if '' is None, Iron, RegularLeather or RegularWood. False if otherwise. /// - public static bool IsStandard(CraftResource resource) => resource == CraftResource.None || - resource == CraftResource.Iron || - resource == CraftResource.RegularLeather || - resource == CraftResource.RegularWood; + public static bool IsStandard(CraftResource resource) => + resource is CraftResource.None or CraftResource.Iron or CraftResource.RegularLeather or CraftResource.RegularWood; /// /// Registers that '' uses '' so that it can later be queried by diff --git a/Projects/UOContent/Mobiles/AI/BaseAI.cs b/Projects/UOContent/Mobiles/AI/BaseAI.cs index 42f74c24f..af010e7c4 100644 --- a/Projects/UOContent/Mobiles/AI/BaseAI.cs +++ b/Projects/UOContent/Mobiles/AI/BaseAI.cs @@ -178,7 +178,7 @@ namespace Server.Mobiles list.Add(new InternalEntry(from, 6112, 14, m_Mobile, this, OrderType.Stop)); // Command: Stop list.Add(new InternalEntry(from, 6114, 14, m_Mobile, this, OrderType.Stay)); // Command: Stay - if (!m_Mobile.Summoned && !(m_Mobile is GrizzledMare)) + if (!m_Mobile.Summoned && m_Mobile is not GrizzledMare) { list.Add(new InternalEntry(from, 6110, 14, m_Mobile, this, OrderType.Friend)); // Add Friend list.Add(new InternalEntry(from, 6099, 14, m_Mobile, this, OrderType.Unfriend)); // Remove Friend @@ -283,17 +283,9 @@ namespace Server.Mobiles } if (SolenHelper.CheckRedFriendship(from) && - (target is RedSolenInfiltratorQueen - || target is RedSolenInfiltratorWarrior - || target is RedSolenQueen - || target is RedSolenWarrior - || target is RedSolenWorker) + target is RedSolenInfiltratorQueen or RedSolenInfiltratorWarrior or RedSolenQueen or RedSolenWarrior or RedSolenWorker || SolenHelper.CheckBlackFriendship(from) && - (target is BlackSolenInfiltratorQueen - || target is BlackSolenInfiltratorWarrior - || target is BlackSolenQueen - || target is BlackSolenWarrior - || target is BlackSolenWorker)) + target is BlackSolenInfiltratorQueen or BlackSolenInfiltratorWarrior or BlackSolenQueen or BlackSolenWarrior or BlackSolenWorker) { from.SendAsciiMessage("You can not force your pet to attack a creature you are protected from."); return; @@ -1256,7 +1248,7 @@ namespace Server.Mobiles var distance = m_Mobile.GetDistanceToSqrt(target); - if (!(distance < 1 || distance > 15)) + if (!(distance is < 1 or > 15)) { DoMove(m_Mobile.GetDirectionTo(target)); return true; @@ -1550,7 +1542,7 @@ namespace Server.Mobiles m_Mobile.ControlOrder = OrderType.None; } - if (m_Mobile.FightMode == FightMode.Closest || m_Mobile.FightMode == FightMode.Aggressor) + if (m_Mobile.FightMode is FightMode.Closest or FightMode.Aggressor) { Mobile newCombatant = null; var newScore = 0.0; @@ -1962,8 +1954,7 @@ namespace Server.Mobiles { var res = DoMoveImpl(d); - return res == MoveResult.Success || res == MoveResult.SuccessAutoTurn || - badStateOk && res == MoveResult.BadState; + return res is MoveResult.Success or MoveResult.SuccessAutoTurn || badStateOk && res == MoveResult.BadState; } public virtual MoveResult DoMoveImpl(Direction d) @@ -2540,7 +2531,7 @@ namespace Server.Mobiles continue; } - if (acqType == FightMode.Aggressor || acqType == FightMode.Evil) + if (acqType is FightMode.Aggressor or FightMode.Evil) { var bValid = IsHostile(m); @@ -2741,8 +2732,7 @@ namespace Server.Mobiles m_AI = ai; m_Order = order; - if (mobile.IsDeadPet && (order == OrderType.Guard || order == OrderType.Attack || - order == OrderType.Transfer || order == OrderType.Drop)) + if (mobile.IsDeadPet && order is OrderType.Guard or OrderType.Attack or OrderType.Transfer or OrderType.Drop) { Enabled = false; } @@ -2752,8 +2742,7 @@ namespace Server.Mobiles { if (!m_Mobile.Deleted && m_Mobile.Controlled && m_From.CheckAlive()) { - if (m_Mobile.IsDeadPet && (m_Order == OrderType.Guard || m_Order == OrderType.Attack || - m_Order == OrderType.Transfer || m_Order == OrderType.Drop)) + if (m_Mobile.IsDeadPet && m_Order is OrderType.Guard or OrderType.Attack or OrderType.Transfer or OrderType.Drop) { return; } diff --git a/Projects/UOContent/Mobiles/AI/MageAI.cs b/Projects/UOContent/Mobiles/AI/MageAI.cs index 8fe1f2c7a..9088e27f3 100644 --- a/Projects/UOContent/Mobiles/AI/MageAI.cs +++ b/Projects/UOContent/Mobiles/AI/MageAI.cs @@ -61,7 +61,7 @@ namespace Server.Mobiles { } - public virtual bool SmartAI => m_Mobile is BaseVendor || m_Mobile is BaseEscortable || m_Mobile is Changeling; + public virtual bool SmartAI => m_Mobile is BaseVendor or BaseEscortable or Changeling; public virtual bool IsNecromancer => Core.AOS && m_Mobile.Skills.Necromancy.Value > 50; @@ -792,7 +792,7 @@ namespace Server.Mobiles { spell = DoCombo(c); } - else if (SmartAI && (c.Spell is HealSpell || c.Spell is GreaterHealSpell) && !c.Poisoned + else if (SmartAI && c.Spell is HealSpell or GreaterHealSpell && !c.Poisoned ) // They have a heal spell out { spell = new PoisonSpell(m_Mobile); diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/Ethereals.cs b/Projects/UOContent/Mobiles/Animals/Mounts/Ethereals.cs index 98f8be9b1..d97216fce 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/Ethereals.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/Ethereals.cs @@ -389,7 +389,7 @@ namespace Server.Mobiles public override bool CheckDisturb(DisturbType type, bool checkFirst, bool resistable) { - if (type == DisturbType.EquipRequest || type == DisturbType.UseRequest /* || type == DisturbType.Hurt*/) + if (type is DisturbType.EquipRequest or DisturbType.UseRequest /* || type == DisturbType.Hurt*/) { return false; } diff --git a/Projects/UOContent/Mobiles/BaseCreature.cs b/Projects/UOContent/Mobiles/BaseCreature.cs index 1debdd3cd..1c0b91b4e 100644 --- a/Projects/UOContent/Mobiles/BaseCreature.cs +++ b/Projects/UOContent/Mobiles/BaseCreature.cs @@ -2436,8 +2436,7 @@ namespace Server.Mobiles } if (aggressor.ChangingCombatant && (m_Controlled || _summoned) && - (ct == OrderType.Come || !Core.ML && ct == OrderType.Stay || ct == OrderType.Stop || ct == OrderType.None || - ct == OrderType.Follow)) + (ct == OrderType.Come || !Core.ML && ct == OrderType.Stay || ct is OrderType.Stop or OrderType.None or OrderType.Follow)) { ControlTarget = aggressor; ControlOrder = OrderType.Attack; @@ -3384,7 +3383,7 @@ namespace Server.Mobiles return false; } - if (target is BaseCreature creature && creature.IsInvulnerable || target is PlayerVendor || target is TownCrier) + if (target is BaseCreature creature && creature.IsInvulnerable || target is PlayerVendor or TownCrier) { if (message) { diff --git a/Projects/UOContent/Mobiles/Healers/EvilHealer.cs b/Projects/UOContent/Mobiles/Healers/EvilHealer.cs index 0fd51e5e8..02fcbeb7d 100644 --- a/Projects/UOContent/Mobiles/Healers/EvilHealer.cs +++ b/Projects/UOContent/Mobiles/Healers/EvilHealer.cs @@ -30,10 +30,7 @@ namespace Server.Mobiles return false; } - return skill == SkillName.Forensics - || skill == SkillName.Healing - || skill == SkillName.SpiritSpeak - || skill == SkillName.Swords; + return skill is SkillName.Forensics or SkillName.Healing or SkillName.SpiritSpeak or SkillName.Swords; } public override void InitSBInfo() diff --git a/Projects/UOContent/Mobiles/Healers/EvilWanderingHealer.cs b/Projects/UOContent/Mobiles/Healers/EvilWanderingHealer.cs index 20be43369..ff5a4454b 100644 --- a/Projects/UOContent/Mobiles/Healers/EvilWanderingHealer.cs +++ b/Projects/UOContent/Mobiles/Healers/EvilWanderingHealer.cs @@ -33,11 +33,7 @@ namespace Server.Mobiles return false; } - return skill == SkillName.Anatomy - || skill == SkillName.Camping - || skill == SkillName.Forensics - || skill == SkillName.Healing - || skill == SkillName.SpiritSpeak; + return skill is SkillName.Anatomy or SkillName.Camping or SkillName.Forensics or SkillName.Healing or SkillName.SpiritSpeak; } public override bool CheckResurrect(Mobile m) diff --git a/Projects/UOContent/Mobiles/Healers/FortuneTeller.cs b/Projects/UOContent/Mobiles/Healers/FortuneTeller.cs index fcc41d01f..fbd3a3fed 100644 --- a/Projects/UOContent/Mobiles/Healers/FortuneTeller.cs +++ b/Projects/UOContent/Mobiles/Healers/FortuneTeller.cs @@ -31,10 +31,7 @@ namespace Server.Mobiles return false; } - return skill == SkillName.Anatomy - || skill == SkillName.Healing - || skill == SkillName.Forensics - || skill == SkillName.SpiritSpeak; + return skill is SkillName.Anatomy or SkillName.Healing or SkillName.Forensics or SkillName.SpiritSpeak; } public override void InitSBInfo() diff --git a/Projects/UOContent/Mobiles/Healers/Healer.cs b/Projects/UOContent/Mobiles/Healers/Healer.cs index 88b135812..47eecff5c 100644 --- a/Projects/UOContent/Mobiles/Healers/Healer.cs +++ b/Projects/UOContent/Mobiles/Healers/Healer.cs @@ -33,10 +33,7 @@ namespace Server.Mobiles return false; } - return skill == SkillName.Forensics - || skill == SkillName.Healing - || skill == SkillName.SpiritSpeak - || skill == SkillName.Swords; + return skill is SkillName.Forensics or SkillName.Healing or SkillName.SpiritSpeak or SkillName.Swords; } public override void InitSBInfo() diff --git a/Projects/UOContent/Mobiles/Healers/WanderingHealer.cs b/Projects/UOContent/Mobiles/Healers/WanderingHealer.cs index cad541e0e..036b8741c 100644 --- a/Projects/UOContent/Mobiles/Healers/WanderingHealer.cs +++ b/Projects/UOContent/Mobiles/Healers/WanderingHealer.cs @@ -31,11 +31,7 @@ namespace Server.Mobiles return false; } - return skill == SkillName.Anatomy - || skill == SkillName.Camping - || skill == SkillName.Forensics - || skill == SkillName.Healing - || skill == SkillName.SpiritSpeak; + return skill is SkillName.Anatomy or SkillName.Camping or SkillName.Forensics or SkillName.Healing or SkillName.SpiritSpeak; } public override bool CheckResurrect(Mobile m) diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/SavageShaman.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/SavageShaman.cs index d7ad5c249..29904bf35 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/SavageShaman.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/SavageShaman.cs @@ -110,8 +110,7 @@ namespace Server.Mobiles public override void AlterMeleeDamageTo(Mobile to, ref int damage) { - if (to is Dragon || to is WhiteWyrm || to is SwampDragon || to is Drake || to is Nightmare || to is Hiryu || - to is LesserHiryu || to is Daemon) + if (to is Dragon or WhiteWyrm or SwampDragon or Drake or Nightmare or Hiryu or LesserHiryu or Daemon) { damage *= 3; } @@ -184,7 +183,7 @@ namespace Server.Mobiles { foreach (var m in eable) { - var isFriendly = m is Savage || m is SavageRider || m is SavageShaman || m is SavageRidgeback; + var isFriendly = m is Savage or SavageRider or SavageShaman or SavageRidgeback; if (!isFriendly) { @@ -215,7 +214,7 @@ namespace Server.Mobiles { foreach (var m in eable) { - var isFriendly = m is Savage || m is SavageRider || m is SavageShaman || m is SavageRidgeback; + var isFriendly = m is Savage or SavageRider or SavageShaman or SavageRidgeback; if (isFriendly) { @@ -253,7 +252,7 @@ namespace Server.Mobiles { foreach (var m in eable) { - var isFriendly = m is Savage || m is SavageRider || m is SavageShaman || m is SavageRidgeback; + var isFriendly = m is Savage or SavageRider or SavageShaman or SavageRidgeback; if (isFriendly) { diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Savage.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Savage.cs index 100dc84e7..54e899533 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Savage.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Savage.cs @@ -111,8 +111,7 @@ namespace Server.Mobiles public override void AlterMeleeDamageTo(Mobile to, ref int damage) { - if (to is Dragon || to is WhiteWyrm || to is SwampDragon || to is Drake || to is Nightmare || to is Hiryu || - to is LesserHiryu || to is Daemon) + if (to is Dragon or WhiteWyrm or SwampDragon or Drake or Nightmare or Hiryu or LesserHiryu or Daemon) { damage *= 3; } diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/SavageRider.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/SavageRider.cs index bfa2b98b1..ad74f08ae 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/SavageRider.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/SavageRider.cs @@ -119,8 +119,7 @@ namespace Server.Mobiles public override void AlterMeleeDamageTo(Mobile to, ref int damage) { - if (to is Dragon || to is WhiteWyrm || to is SwampDragon || to is Drake || to is Nightmare || to is Hiryu || - to is LesserHiryu || to is Daemon) + if (to is Dragon or WhiteWyrm or SwampDragon or Drake or Nightmare or Hiryu or LesserHiryu or Daemon) { damage *= 3; } diff --git a/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/ChaosDragoon.cs b/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/ChaosDragoon.cs index d64dc7a4f..c139720cb 100644 --- a/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/ChaosDragoon.cs +++ b/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/ChaosDragoon.cs @@ -129,8 +129,7 @@ namespace Server.Mobiles public override void AlterMeleeDamageTo(Mobile to, ref int damage) { - if (to is Dragon || to is WhiteWyrm || to is SwampDragon || to is Drake || to is Nightmare || to is Hiryu || - to is LesserHiryu || to is Daemon) + if (to is Dragon or WhiteWyrm or SwampDragon or Drake or Nightmare or Hiryu or LesserHiryu or Daemon) { damage *= 3; } diff --git a/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/ChaosDragoonElite.cs b/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/ChaosDragoonElite.cs index 9e1aab189..839f9b117 100644 --- a/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/ChaosDragoonElite.cs +++ b/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/ChaosDragoonElite.cs @@ -151,8 +151,7 @@ namespace Server.Mobiles public override void AlterMeleeDamageTo(Mobile to, ref int damage) { - if (to is Dragon || to is WhiteWyrm || to is SwampDragon || to is Drake || to is Nightmare || to is Hiryu || - to is LesserHiryu || to is Daemon) + if (to is Dragon or WhiteWyrm or SwampDragon or Drake or Nightmare or Hiryu or LesserHiryu or Daemon) { damage *= 3; } diff --git a/Projects/UOContent/Mobiles/Monsters/LBR/Meers/MeerCaptain.cs b/Projects/UOContent/Mobiles/Monsters/LBR/Meers/MeerCaptain.cs index 24cbc389d..0cbe3214b 100644 --- a/Projects/UOContent/Mobiles/Monsters/LBR/Meers/MeerCaptain.cs +++ b/Projects/UOContent/Mobiles/Monsters/LBR/Meers/MeerCaptain.cs @@ -124,7 +124,7 @@ namespace Server.Mobiles foreach (var m in eable) { - if (!(m is MeerWarrior) || !IsFriend(m) || !CanBeBeneficial(m) || m.Hits >= m.HitsMax || m.Poisoned || + if (m is not MeerWarrior || !IsFriend(m) || !CanBeBeneficial(m) || m.Hits >= m.HitsMax || m.Poisoned || MortalStrike.IsWounded(m)) { continue; diff --git a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/BladeSpirits.cs b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/BladeSpirits.cs index d0c70f67f..bcd9ed8ba 100644 --- a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/BladeSpirits.cs +++ b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/BladeSpirits.cs @@ -73,7 +73,7 @@ namespace Server.Mobiles { var eable = GetMobilesInRange(5); var spiritsOrVortexes = eable - .Where(m => (m is EnergyVortex || m is BladeSpirits) && ((BaseCreature)m).Summoned) + .Where(m => m is EnergyVortex or BladeSpirits && ((BaseCreature)m).Summoned) .ToList(); eable.Free(); diff --git a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/EnergyVortex.cs b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/EnergyVortex.cs index a1505e2a0..a69586bc3 100644 --- a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/EnergyVortex.cs +++ b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/EnergyVortex.cs @@ -80,7 +80,7 @@ namespace Server.Mobiles { var eable = GetMobilesInRange(5); var spiritsOrVortexes = eable - .Where(m => (m is EnergyVortex || m is BladeSpirits) && ((BaseCreature)m).Summoned) + .Where(m => m is EnergyVortex or BladeSpirits && ((BaseCreature)m).Summoned) .ToList(); eable.Free(); diff --git a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/PlagueBeastLord.cs b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/PlagueBeastLord.cs index a96c23de2..0e69a4bb1 100644 --- a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/PlagueBeastLord.cs +++ b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/PlagueBeastLord.cs @@ -156,7 +156,7 @@ namespace Server.Mobiles public override bool OnDragDrop(Mobile from, Item dropped) { - if (IsAccessibleTo(from) && (dropped is PlagueBeastInnard || dropped is PlagueBeastGland)) + if (IsAccessibleTo(from) && dropped is PlagueBeastInnard or PlagueBeastGland) { return base.OnDragDrop(from, dropped); } diff --git a/Projects/UOContent/Mobiles/Monsters/SE/Yamandon.cs b/Projects/UOContent/Mobiles/Monsters/SE/Yamandon.cs index af50366b0..7e7856efb 100644 --- a/Projects/UOContent/Mobiles/Monsters/SE/Yamandon.cs +++ b/Projects/UOContent/Mobiles/Monsters/SE/Yamandon.cs @@ -131,7 +131,7 @@ namespace Server.Mobiles continue; } - if (!(m is BaseCreature bc) || !(bc.Controlled || bc.Summoned || bc.Team != Team)) + if (m is not BaseCreature bc || !(bc.Controlled || bc.Summoned || bc.Team != Team)) { continue; } diff --git a/Projects/UOContent/Mobiles/PlayerMobile.cs b/Projects/UOContent/Mobiles/PlayerMobile.cs index 17e7da183..59a605d5b 100644 --- a/Projects/UOContent/Mobiles/PlayerMobile.cs +++ b/Projects/UOContent/Mobiles/PlayerMobile.cs @@ -1252,7 +1252,7 @@ namespace Server.Mobiles { string notice; - if (!(from.Account is Account acct) || !acct.HasAccess(from.NetState)) + if (@from.Account is not Account acct || !acct.HasAccess(from.NetState)) { if (from.AccessLevel == AccessLevel.Player) { @@ -1665,7 +1665,7 @@ namespace Server.Mobiles return false; } - if (target is BaseCreature creature && creature.IsInvulnerable || target is PlayerVendor || target is TownCrier) + if (target is BaseCreature creature && creature.IsInvulnerable || target is PlayerVendor or TownCrier) { if (message) { @@ -1701,7 +1701,7 @@ namespace Server.Mobiles { base.OnItemAdded(item); - if (item is BaseArmor || item is BaseWeapon) + if (item is BaseArmor or BaseWeapon) { CheckStatTimers(); } @@ -1716,7 +1716,7 @@ namespace Server.Mobiles { base.OnItemRemoved(item); - if (item is BaseArmor || item is BaseWeapon) + if (item is BaseArmor or BaseWeapon) { CheckStatTimers(); } @@ -2763,9 +2763,9 @@ namespace Server.Mobiles public override void DoSpeech(string text, int[] keywords, MessageType type, int hue) { - if (Guilds.Guild.NewGuildSystem && (type == MessageType.Guild || type == MessageType.Alliance)) + if (Guilds.Guild.NewGuildSystem && type is MessageType.Guild or MessageType.Alliance) { - if (!(Guild is Guild g)) + if (Guild is not Guild g) { SendLocalizedMessage(1063142); // You are not in a guild! } @@ -3662,7 +3662,7 @@ namespace Server.Mobiles { for (var i = m_AllFollowers.Count - 1; i >= 0; --i) { - if (!(AllFollowers[i] is BaseCreature pet) || pet.ControlMaster == null) + if (AllFollowers[i] is not BaseCreature pet || pet.ControlMaster == null) { continue; } @@ -3683,7 +3683,7 @@ namespace Server.Mobiles continue; } - if ((pet is PackLlama || pet is PackHorse || pet is Beetle) && pet.Backpack?.Items.Count > 0) + if (pet is PackLlama or PackHorse or Beetle && pet.Backpack?.Items.Count > 0) { continue; } @@ -3728,7 +3728,7 @@ namespace Server.Mobiles for (var i = AutoStabled.Count - 1; i >= 0; --i) { - if (!(AutoStabled[i] is BaseCreature pet)) + if (AutoStabled[i] is not BaseCreature pet) { continue; } @@ -3841,8 +3841,7 @@ namespace Server.Mobiles private bool CanInsure(Item item) { - if (item is Container && !(item is BaseQuiver) || item is BagOfSending || item is KeyRing || item is PotionKeg || - item is Sigil) + if (item is Container && item is not BaseQuiver || item is BagOfSending or KeyRing or PotionKeg or Sigil) { return false; } @@ -4068,7 +4067,7 @@ namespace Server.Mobiles return; } - if (!(obj is Item item)) + if (obj is not Item item) { return; } diff --git a/Projects/UOContent/Mobiles/Special/Barracoon.cs b/Projects/UOContent/Mobiles/Special/Barracoon.cs index 71cba9da7..53e88897c 100644 --- a/Projects/UOContent/Mobiles/Special/Barracoon.cs +++ b/Projects/UOContent/Mobiles/Special/Barracoon.cs @@ -145,7 +145,7 @@ namespace Server.Mobiles foreach (var m in eable) { - if (m is Ratman || m is RatmanArcher || m is RatmanMage) + if (m is Ratman or RatmanArcher or RatmanMage) { rats++; if (rats >= 16) diff --git a/Projects/UOContent/Mobiles/Special/BaseChampion.cs b/Projects/UOContent/Mobiles/Special/BaseChampion.cs index b387c7eff..732016313 100644 --- a/Projects/UOContent/Mobiles/Special/BaseChampion.cs +++ b/Projects/UOContent/Mobiles/Special/BaseChampion.cs @@ -132,7 +132,7 @@ namespace Server.Mobiles { var m = toGive[i]; - if (!(m is PlayerMobile)) + if (m is not PlayerMobile) { continue; } @@ -194,7 +194,7 @@ namespace Server.Mobiles } } - if (!(m is PlayerMobile pm)) + if (m is not PlayerMobile pm) { return; } diff --git a/Projects/UOContent/Mobiles/Special/BaseShieldGuard.cs b/Projects/UOContent/Mobiles/Special/BaseShieldGuard.cs index 908d47c1a..7c1cb745c 100644 --- a/Projects/UOContent/Mobiles/Special/BaseShieldGuard.cs +++ b/Projects/UOContent/Mobiles/Special/BaseShieldGuard.cs @@ -116,7 +116,7 @@ namespace Server.Mobiles var from = e.Mobile; - if (!(from.Guild is Guild g) || g.Type != Type) + if (@from.Guild is not Guild g || g.Type != Type) { Say(SignupNumber); } diff --git a/Projects/UOContent/Mobiles/Special/HarrowerTentacles.cs b/Projects/UOContent/Mobiles/Special/HarrowerTentacles.cs index c86bf35e2..d0521bb08 100644 --- a/Projects/UOContent/Mobiles/Special/HarrowerTentacles.cs +++ b/Projects/UOContent/Mobiles/Special/HarrowerTentacles.cs @@ -151,7 +151,7 @@ namespace Server.Mobiles continue; } - if (!(m is BaseCreature bc) || !(bc.Controlled || bc.Summoned || bc.Team != m_Owner.Team)) + if (m is not BaseCreature bc || !(bc.Controlled || bc.Summoned || bc.Team != m_Owner.Team)) { continue; } diff --git a/Projects/UOContent/Mobiles/Special/Paragon.cs b/Projects/UOContent/Mobiles/Special/Paragon.cs index 784c32d61..feb1c4b84 100644 --- a/Projects/UOContent/Mobiles/Special/Paragon.cs +++ b/Projects/UOContent/Mobiles/Special/Paragon.cs @@ -174,8 +174,7 @@ namespace Server.Mobiles return false; } - if (bc is BaseChampion || bc is Harrower || bc is BaseVendor || bc is BaseEscortable || bc is Clone || - bc.IsParagon) + if (bc is BaseChampion or Harrower or BaseVendor or BaseEscortable or Clone || bc.IsParagon) { return false; } diff --git a/Projects/UOContent/Mobiles/Special/Rikktor.cs b/Projects/UOContent/Mobiles/Special/Rikktor.cs index dc00a7381..47a8327fe 100644 --- a/Projects/UOContent/Mobiles/Special/Rikktor.cs +++ b/Projects/UOContent/Mobiles/Special/Rikktor.cs @@ -109,7 +109,7 @@ namespace Server.Mobiles continue; } - if (!(m is BaseCreature bc) || !(bc.Controlled || bc.Summoned || bc.Team != Team)) + if (m is not BaseCreature bc || !(bc.Controlled || bc.Summoned || bc.Team != Team)) { continue; } diff --git a/Projects/UOContent/Mobiles/Special/Semidar.cs b/Projects/UOContent/Mobiles/Special/Semidar.cs index b14259708..e6092bd43 100644 --- a/Projects/UOContent/Mobiles/Special/Semidar.cs +++ b/Projects/UOContent/Mobiles/Special/Semidar.cs @@ -101,7 +101,7 @@ namespace Server.Mobiles continue; } - if (!(m is BaseCreature bc) || !(bc.Controlled || bc.Summoned || bc.Team != Team)) + if (m is not BaseCreature bc || !(bc.Controlled || bc.Summoned || bc.Team != Team)) { continue; } diff --git a/Projects/UOContent/Mobiles/Special/Serado.cs b/Projects/UOContent/Mobiles/Special/Serado.cs index 20c680008..39d204493 100644 --- a/Projects/UOContent/Mobiles/Special/Serado.cs +++ b/Projects/UOContent/Mobiles/Special/Serado.cs @@ -163,7 +163,7 @@ namespace Server.Mobiles continue; } - if (!(m is BaseCreature bc) || !(bc.Controlled || bc.Summoned || bc.Team != Team)) + if (m is not BaseCreature bc || !(bc.Controlled || bc.Summoned || bc.Team != Team)) { continue; } diff --git a/Projects/UOContent/Mobiles/Townfolk/BaseEscortable.cs b/Projects/UOContent/Mobiles/Townfolk/BaseEscortable.cs index b6e60df77..21dbb152b 100644 --- a/Projects/UOContent/Mobiles/Townfolk/BaseEscortable.cs +++ b/Projects/UOContent/Mobiles/Townfolk/BaseEscortable.cs @@ -746,7 +746,7 @@ namespace Server.Mobiles foreach (Region r in list) { - if (r.Name != null && (r is DungeonRegion || r is TownRegion)) + if (r.Name != null && r is DungeonRegion or TownRegion) { m_Table[r.Name] = new EscortDestinationInfo(r.Name, r); } diff --git a/Projects/UOContent/Mobiles/Vendors/BaseVendor.cs b/Projects/UOContent/Mobiles/Vendors/BaseVendor.cs index aaeb542aa..8cb8eb5c2 100644 --- a/Projects/UOContent/Mobiles/Vendors/BaseVendor.cs +++ b/Projects/UOContent/Mobiles/Vendors/BaseVendor.cs @@ -757,7 +757,7 @@ namespace Server.Mobiles for (var i = 0; i < Items.Count; ++i) { var item = Items[i]; - if (item is BaseClothing || item is BaseWeapon || item is BaseArmor || item is BaseTool) + if (item is BaseClothing or BaseWeapon or BaseArmor or BaseTool) { item.Hue = GetRandomNecromancerHue(); } diff --git a/Projects/UOContent/Mobiles/Vendors/NPC/AnimalTrainer.cs b/Projects/UOContent/Mobiles/Vendors/NPC/AnimalTrainer.cs index 844645099..a1f8af86a 100644 --- a/Projects/UOContent/Mobiles/Vendors/NPC/AnimalTrainer.cs +++ b/Projects/UOContent/Mobiles/Vendors/NPC/AnimalTrainer.cs @@ -230,7 +230,7 @@ namespace Server.Mobiles SayTo( from, 1048053 ); // You can't stable that! } */ - else if ((pet is PackLlama || pet is PackHorse || pet is Beetle) && pet.Backpack?.Items.Count > 0) + else if (pet is PackLlama or PackHorse or Beetle && pet.Backpack?.Items.Count > 0) { SayTo(from, 1042563); // You need to unload your pet. } diff --git a/Projects/UOContent/Mobiles/Vendors/NPC/Blacksmith.cs b/Projects/UOContent/Mobiles/Vendors/NPC/Blacksmith.cs index fc643c672..74641de39 100644 --- a/Projects/UOContent/Mobiles/Vendors/NPC/Blacksmith.cs +++ b/Projects/UOContent/Mobiles/Vendors/NPC/Blacksmith.cs @@ -126,7 +126,7 @@ namespace Server.Mobiles return null; } - public override bool IsValidBulkOrder(Item item) => item is SmallSmithBOD || item is LargeSmithBOD; + public override bool IsValidBulkOrder(Item item) => item is SmallSmithBOD or LargeSmithBOD; public override bool SupportsBulkOrders(Mobile from) => from is PlayerMobile && from.Skills.Blacksmith.Base > 0; diff --git a/Projects/UOContent/Mobiles/Vendors/NPC/Tailor.cs b/Projects/UOContent/Mobiles/Vendors/NPC/Tailor.cs index 6b9e90375..5cb0c9214 100644 --- a/Projects/UOContent/Mobiles/Vendors/NPC/Tailor.cs +++ b/Projects/UOContent/Mobiles/Vendors/NPC/Tailor.cs @@ -68,7 +68,7 @@ namespace Server.Mobiles return null; } - public override bool IsValidBulkOrder(Item item) => item is SmallTailorBOD || item is LargeTailorBOD; + public override bool IsValidBulkOrder(Item item) => item is SmallTailorBOD or LargeTailorBOD; public override bool SupportsBulkOrders(Mobile from) => from is PlayerMobile && from.Skills.Tailoring.Base > 0; diff --git a/Projects/UOContent/Mobiles/Vendors/NPC/Weaponsmith.cs b/Projects/UOContent/Mobiles/Vendors/NPC/Weaponsmith.cs index 3f3bed4ca..635877993 100644 --- a/Projects/UOContent/Mobiles/Vendors/NPC/Weaponsmith.cs +++ b/Projects/UOContent/Mobiles/Vendors/NPC/Weaponsmith.cs @@ -92,7 +92,7 @@ namespace Server.Mobiles return null; } - public override bool IsValidBulkOrder(Item item) => item is SmallSmithBOD || item is LargeSmithBOD; + public override bool IsValidBulkOrder(Item item) => item is SmallSmithBOD or LargeSmithBOD; public override bool SupportsBulkOrders(Mobile from) => from is PlayerMobile && Core.AOS && from.Skills.Blacksmith.Base > 0; diff --git a/Projects/UOContent/Mobiles/Vendors/NPC/Weaver.cs b/Projects/UOContent/Mobiles/Vendors/NPC/Weaver.cs index 6a6a82c9e..bda5cf958 100644 --- a/Projects/UOContent/Mobiles/Vendors/NPC/Weaver.cs +++ b/Projects/UOContent/Mobiles/Vendors/NPC/Weaver.cs @@ -74,7 +74,7 @@ namespace Server.Mobiles return null; } - public override bool IsValidBulkOrder(Item item) => item is SmallTailorBOD || item is LargeTailorBOD; + public override bool IsValidBulkOrder(Item item) => item is SmallTailorBOD or LargeTailorBOD; public override bool SupportsBulkOrders(Mobile from) => from is PlayerMobile && from.Skills.Tailoring.Base > 0; diff --git a/Projects/UOContent/Mobiles/Vendors/PlayerBarkeeper.cs b/Projects/UOContent/Mobiles/Vendors/PlayerBarkeeper.cs index 8f31ed70f..c2f12b988 100644 --- a/Projects/UOContent/Mobiles/Vendors/PlayerBarkeeper.cs +++ b/Projects/UOContent/Mobiles/Vendors/PlayerBarkeeper.cs @@ -315,7 +315,7 @@ namespace Server.Mobiles public override bool CheckGold(Mobile from, Item dropped) { - if (!(dropped is Gold g)) + if (dropped is not Gold g) { return false; } @@ -541,8 +541,7 @@ namespace Server.Mobiles public override void InitSBInfo() { - if (Title == "the waiter" || Title == "the barkeeper" || Title == "the baker" || Title == "the innkeeper" || - Title == "the chef") + if (Title is "the waiter" or "the barkeeper" or "the baker" or "the innkeeper" or "the chef") { if (m_SBInfos.Count == 0) { diff --git a/Projects/UOContent/Mobiles/Vendors/PlayerVendor.cs b/Projects/UOContent/Mobiles/Vendors/PlayerVendor.cs index 8bb6fdcb7..11c3e340d 100644 --- a/Projects/UOContent/Mobiles/Vendors/PlayerVendor.cs +++ b/Projects/UOContent/Mobiles/Vendors/PlayerVendor.cs @@ -124,7 +124,7 @@ namespace Server.Mobiles return false; } - if (item is Container || item is BulkOrderBook) + if (item is Container or BulkOrderBook) { return true; } @@ -142,7 +142,7 @@ namespace Server.Mobiles { base.GetChildContextMenuEntries(from, list, item); - if (!(RootParent is PlayerVendor pv) || pv.IsOwner(from)) + if (RootParent is not PlayerVendor pv || pv.IsOwner(from)) { return; } @@ -1043,7 +1043,7 @@ namespace Server.Mobiles public static void TryToBuy(Item item, Mobile from) { - if (!(item.RootParent is PlayerVendor vendor) || !vendor.CanInteractWith(from, false)) + if (item.RootParent is not PlayerVendor vendor || !vendor.CanInteractWith(from, false)) { return; } @@ -1493,7 +1493,7 @@ namespace Server.Mobiles setPrice = true; } } - else if (item is BaseBook || item is BulkOrderBook) + else if (item is BaseBook or BulkOrderBook) { setPrice = true; } diff --git a/Projects/UOContent/Multis/Boats/BaseBoat.cs b/Projects/UOContent/Multis/Boats/BaseBoat.cs index ff86aa515..409d7e31f 100644 --- a/Projects/UOContent/Multis/Boats/BaseBoat.cs +++ b/Projects/UOContent/Multis/Boats/BaseBoat.cs @@ -1749,7 +1749,7 @@ namespace Server.Multis { item.NoMoveHS = true; - if (!(item is TillerMan || item is Hold || item is Plank)) + if (!(item is Server.Items.TillerMan or Server.Items.Hold or Plank)) { item.Location = new Point3D(item.X + xOffset, item.Y + yOffset, item.Z); } diff --git a/Projects/UOContent/Multis/Boats/Plank.cs b/Projects/UOContent/Multis/Boats/Plank.cs index e6c0811e4..7c838fab4 100644 --- a/Projects/UOContent/Multis/Boats/Plank.cs +++ b/Projects/UOContent/Multis/Boats/Plank.cs @@ -37,7 +37,7 @@ namespace Server.Items public PlankSide Side { get; set; } [CommandProperty(AccessLevel.GameMaster)] - public bool IsOpen => ItemID == 0x3ED5 || ItemID == 0x3ED4 || ItemID == 0x3E84 || ItemID == 0x3E89; + public bool IsOpen => ItemID is 0x3ED5 or 0x3ED4 or 0x3E84 or 0x3E89; [CommandProperty(AccessLevel.GameMaster)] public bool Starboard => Side == PlankSide.Starboard; diff --git a/Projects/UOContent/Multis/Houses/BaseHouse.cs b/Projects/UOContent/Multis/Houses/BaseHouse.cs index eef3a3b15..66cef968e 100644 --- a/Projects/UOContent/Multis/Houses/BaseHouse.cs +++ b/Projects/UOContent/Multis/Houses/BaseHouse.cs @@ -116,7 +116,7 @@ namespace Server.Multis return Core.AOS ? DecayType.Condemned : DecayType.ManualRefresh; } - if (!(m_Owner.Account is Account acct)) + if (m_Owner.Account is not Account acct) { return Core.AOS ? DecayType.Condemned : DecayType.ManualRefresh; } @@ -185,7 +185,7 @@ namespace Server.Multis { var type = DecayType; - return type == DecayType.Condemned || type == DecayType.ManualRefresh; + return type is DecayType.Condemned or DecayType.ManualRefresh; } } @@ -258,7 +258,7 @@ namespace Server.Multis { foreach (var vendor in PlayerVendors) { - if (!(vendor is RentedVendor)) + if (vendor is not RentedVendor) { return true; } @@ -463,7 +463,7 @@ namespace Server.Multis continue; } - if (!(info.Item is StrongBox)) + if (info.Item is not StrongBox) { count += 1; } @@ -756,7 +756,7 @@ namespace Server.Multis { if ((location.Z - entity.Z).Abs() <= 16) { - if (entity is PlayerVendor || entity is PlayerBarkeeper || entity is PlayerVendorPlaceholder) + if (entity is PlayerVendor or PlayerBarkeeper or PlayerVendorPlaceholder) { vendor = true; break; @@ -1495,7 +1495,7 @@ namespace Server.Multis public SecureAccessResult CheckSecureAccess(Mobile m, Item item) { - if (Secures == null || !(item is Container)) + if (Secures == null || item is not Container) { return SecureAccessResult.Insecure; } @@ -1770,7 +1770,7 @@ namespace Server.Multis { door = new GenericHouseDoor(DoorFacing.NorthCW, 0x2D46, 0xEA, 0xF1, false); } - else if (itemID == 0x2D48 || itemID == 0x2FE2) + else if (itemID is 0x2D48 or 0x2FE2) { door = new GenericHouseDoor(DoorFacing.SouthCCW, itemID, 0xEA, 0xF1, false); } @@ -1783,7 +1783,7 @@ namespace Server.Multis door = new GenericHouseDoor(facing, 0x2D63 + 4 * type + mod * 2, 0xEA, 0xF1, false); } - else if (itemID == 0x2FE4 || itemID == 0x31AE) + else if (itemID is 0x2FE4 or 0x31AE) { door = new GenericHouseDoor(DoorFacing.WestCCW, itemID, 0xEA, 0xF1, false); } @@ -2057,7 +2057,7 @@ namespace Server.Multis i.SetLastMoved(); } - if (i is Container && (!locked || !(i is BaseBoard || i is Aquarium || i is FishBowl))) + if (i is Container && (!locked || !(i is BaseBoard or Aquarium or FishBowl))) { foreach (var c in i.Items) { @@ -2102,7 +2102,7 @@ namespace Server.Multis { m.SendLocalizedMessage(501736); // You must lockdown the container first! } - else if (!(item is VendorRentalContract) && (IsAosRules + else if (item is not VendorRentalContract && (IsAosRules ? !CheckAosLockdowns(amt) || !CheckAosStorage(amt) : LockDownCount + amt > MaxLockDowns)) { @@ -2119,7 +2119,7 @@ namespace Server.Multis m.LocalOverheadMessage(MessageType.Regular, 0x3E9, 1005526); // That is already locked down return true; } - else if (item is HouseSign || item is Static) + else if (item is HouseSign or Static) { m.LocalOverheadMessage(MessageType.Regular, 0x3E9, 1005526); // This is already locked down. } @@ -2363,7 +2363,7 @@ namespace Server.Multis { m.SendLocalizedMessage(1010550); // This is already locked down and cannot be secured. } - else if (!(item is Container)) + else if (item is not Container) { LockDown(m, item); } @@ -2389,7 +2389,7 @@ namespace Server.Multis m.SendLocalizedMessage(1010423); // You cannot secure this, place it on the ground first. } // Mondain's Legacy mod - else if (!(item is BaseAddonContainer) && !item.Movable) + else if (item is not BaseAddonContainer && !item.Movable) { m.SendLocalizedMessage(1010424); // You cannot secure this. } @@ -2437,7 +2437,7 @@ namespace Server.Multis if (info.Defender.Player && info.Defender.Alive && Core.Now - info.LastCombatTime < HouseRegion.CombatHeatDelay && - (!(m.Guild is Guild attackerGuild) || !(info.Defender.Guild is Guild defenderGuild) || + (m.Guild is not Guild attackerGuild || info.Defender.Guild is not Guild defenderGuild || defenderGuild != attackerGuild && !defenderGuild.IsEnemy(attackerGuild))) { return true; @@ -2946,7 +2946,7 @@ namespace Server.Multis { var item = LockDowns[i]; - if (item is Container cont && !(cont is BaseBoard || cont is Aquarium || cont is FishBowl)) + if (item is Container cont && !(cont is BaseBoard or Aquarium or FishBowl)) { var children = cont.Items; @@ -3290,7 +3290,7 @@ namespace Server.Multis { var item = LockDowns[i]; - if (!(item is Container)) + if (item is not Container) { count += item.TotalItems; } @@ -3486,7 +3486,7 @@ namespace Server.Multis public static bool HasAccountHouse(Mobile m) { - if (!(m.Account is Account a)) + if (m.Account is not Account a) { return false; } @@ -3596,7 +3596,7 @@ namespace Server.Multis return true; } - if (!(m is BaseCreature bc)) + if (m is not BaseCreature bc) { return false; } diff --git a/Projects/UOContent/Multis/Houses/HouseFoundation.cs b/Projects/UOContent/Multis/Houses/HouseFoundation.cs index 45a1a5925..bd63938ec 100644 --- a/Projects/UOContent/Multis/Houses/HouseFoundation.cs +++ b/Projects/UOContent/Multis/Houses/HouseFoundation.cs @@ -430,7 +430,7 @@ namespace Server.Multis { door = new GenericHouseDoor(DoorFacing.NorthCW, 0x2D46, 0xEA, 0xF1, false); } - else if (itemID == 0x2D48 || itemID == 0x2FE2) + else if (itemID is 0x2D48 or 0x2FE2) { door = new GenericHouseDoor(DoorFacing.SouthCCW, itemID, 0xEA, 0xF1, false); } @@ -443,7 +443,7 @@ namespace Server.Multis door = new GenericHouseDoor(facing, 0x2D63 + 4 * type + mod * 2, 0xEA, 0xF1, false); } - else if (itemID == 0x2FE4 || itemID == 0x31AE) + else if (itemID is 0x2FE4 or 0x31AE) { door = new GenericHouseDoor(DoorFacing.WestCCW, itemID, 0xEA, 0xF1, false); } @@ -453,11 +453,11 @@ namespace Server.Multis var mod = (itemID - 0x319C) / 2 % 2; - var specialCase = itemID == 0x31AA || itemID == 0x31A8; + var specialCase = itemID is 0x31AA or 0x31A8; DoorFacing facing; - if (itemID == 0x31AA || itemID == 0x31A8) + if (itemID is 0x31AA or 0x31A8) { facing = mod == 0 ? DoorFacing.NorthCW : DoorFacing.EastCW; } @@ -1809,7 +1809,7 @@ namespace Server.Multis var mcl = design.Components; - if (z < -3 || z > 12 || z % 3 != 0) + if (z is < -3 or > 12 || z % 3 != 0) { z = -3; } @@ -2082,7 +2082,7 @@ namespace Server.Multis } // ML doors - if (itemID == 0x2D46 || itemID == 0x2D48 || itemID == 0x2FE2 || itemID == 0x2FE4) + if (itemID is 0x2D46 or 0x2D48 or 0x2FE2 or 0x2FE4) { return true; } diff --git a/Projects/UOContent/Multis/Houses/HousePlacement.cs b/Projects/UOContent/Multis/Houses/HousePlacement.cs index 3f452ad67..5a5640bb9 100644 --- a/Projects/UOContent/Multis/Houses/HousePlacement.cs +++ b/Projects/UOContent/Multis/Houses/HousePlacement.cs @@ -58,7 +58,7 @@ namespace Server.Multis return HousePlacementResult.BadRegion; // No houses in Ilshenar/T2A } - if (map == Map.Malas && (multiID == 0x007C || multiID == 0x007E)) + if (map == Map.Malas && multiID is 0x007C or 0x007E) { return HousePlacementResult.InvalidCastleKeep; } diff --git a/Projects/UOContent/Multis/Houses/MovingCrate.cs b/Projects/UOContent/Multis/Houses/MovingCrate.cs index 6ef37c309..7388323fd 100644 --- a/Projects/UOContent/Multis/Houses/MovingCrate.cs +++ b/Projects/UOContent/Multis/Houses/MovingCrate.cs @@ -59,7 +59,7 @@ namespace Server.Multis { var subItem = subItems[i]; - if (!(subItem is Container) && subItem.StackWith(null, dropped, false)) + if (subItem is not Container && subItem.StackWith(null, dropped, false)) { return; } diff --git a/Projects/UOContent/Regions/GuardedRegion.cs b/Projects/UOContent/Regions/GuardedRegion.cs index 09af983db..d714c1719 100644 --- a/Projects/UOContent/Regions/GuardedRegion.cs +++ b/Projects/UOContent/Regions/GuardedRegion.cs @@ -245,7 +245,7 @@ namespace Server.Regions var noto = Notoriety.Compute(helper, helped); - if (helper != helped && (noto == Notoriety.Criminal || noto == Notoriety.Murderer)) + if (helper != helped && noto is Notoriety.Criminal or Notoriety.Murderer) { CheckGuardCandidate(helper); } @@ -358,8 +358,8 @@ namespace Server.Regions } public bool IsGuardCandidate(Mobile m) => - !(m is BaseGuard) && m.Alive && m.AccessLevel <= AccessLevel.Player && !m.Blessed && - (!(m is BaseCreature creature) || !creature.IsInvulnerable) && !IsDisabled() && + m is not BaseGuard && m.Alive && m.AccessLevel <= AccessLevel.Player && !m.Blessed && + (m is not BaseCreature creature || !creature.IsInvulnerable) && !IsDisabled() && (!AllowReds && m.Kills >= 5 || m.Criminal); private class GuardTimer : Timer diff --git a/Projects/UOContent/Skills/Inscribe.cs b/Projects/UOContent/Skills/Inscribe.cs index dbcca17e8..84c47de5f 100644 --- a/Projects/UOContent/Skills/Inscribe.cs +++ b/Projects/UOContent/Skills/Inscribe.cs @@ -86,7 +86,7 @@ namespace Server.SkillHandlers protected override void OnTarget(Mobile from, object targeted) { - if (!(targeted is BaseBook book)) + if (targeted is not BaseBook book) { from.SendLocalizedMessage(1046296); // That is not a book } @@ -131,7 +131,7 @@ namespace Server.SkillHandlers return; } - if (!(targeted is BaseBook bookDst)) + if (targeted is not BaseBook bookDst) { from.SendLocalizedMessage(1046296); // That is not a book } diff --git a/Projects/UOContent/Skills/Peacemaking.cs b/Projects/UOContent/Skills/Peacemaking.cs index 1101c7b21..d6f479a1e 100644 --- a/Projects/UOContent/Skills/Peacemaking.cs +++ b/Projects/UOContent/Skills/Peacemaking.cs @@ -54,7 +54,7 @@ namespace Server.SkillHandlers { from.RevealingAction(); - if (!(targeted is Mobile targ)) + if (targeted is not Mobile targ) { from.SendLocalizedMessage(1049528); // You cannot calm that! } diff --git a/Projects/UOContent/Skills/Poisoning.cs b/Projects/UOContent/Skills/Poisoning.cs index 1c8d0ead2..6e920360b 100644 --- a/Projects/UOContent/Skills/Poisoning.cs +++ b/Projects/UOContent/Skills/Poisoning.cs @@ -56,7 +56,7 @@ namespace Server.SkillHandlers var startTimer = false; - if (targeted is Food || targeted is FukiyaDarts || targeted is Shuriken) + if (targeted is Food or FukiyaDarts or Shuriken) { startTimer = true; } @@ -69,7 +69,7 @@ namespace Server.SkillHandlers } else if (weapon.Layer == Layer.OneHanded) { - startTimer = weapon.Type == WeaponType.Slashing || weapon.Type == WeaponType.Piercing; + startTimer = weapon.Type is WeaponType.Slashing or WeaponType.Piercing; } } diff --git a/Projects/UOContent/Skills/Provocation.cs b/Projects/UOContent/Skills/Provocation.cs index 7078aef11..ad5571005 100644 --- a/Projects/UOContent/Skills/Provocation.cs +++ b/Projects/UOContent/Skills/Provocation.cs @@ -107,7 +107,7 @@ namespace Server.SkillHandlers { from.SendLocalizedMessage(1049446); // You have no chance of provoking those creatures. } - else if (creature.Unprovokable && !(creature is DemonKnight)) + else if (creature.Unprovokable && creature is not DemonKnight) { from.SendLocalizedMessage(1049446); // You have no chance of provoking those creatures. } diff --git a/Projects/UOContent/Skills/Snooping.cs b/Projects/UOContent/Skills/Snooping.cs index 43f894fe3..73b03bffc 100644 --- a/Projects/UOContent/Skills/Snooping.cs +++ b/Projects/UOContent/Skills/Snooping.cs @@ -38,77 +38,76 @@ namespace Server.SkillHandlers public static void Container_Snoop(Container cont, Mobile from) { - if (from.AccessLevel > AccessLevel.Player || from.InRange(cont.GetWorldLocation(), 1)) + if (from.AccessLevel <= AccessLevel.Player && !from.InRange(cont.GetWorldLocation(), 1)) { - var root = cont.RootParent as Mobile; + from.SendLocalizedMessage(500446); // That is too far away. + return; + } - if (root?.Alive == false) + var root = cont.RootParent as Mobile; + + if (root?.Alive == false) + { + return; + } + + if (root?.AccessLevel > AccessLevel.Player && from.AccessLevel == AccessLevel.Player) + { + from.SendLocalizedMessage(500209); // You can not peek into the container. + return; + } + + if (root?.AccessLevel == AccessLevel.Player && !CheckSnoopAllowed(from, root)) + { + from.SendLocalizedMessage(1001018); // You cannot perform negative acts on your target. + return; + } + + if (root?.AccessLevel == AccessLevel.Player && + from.Skills.Snooping.Value < Utility.Random(100)) + { + var map = from.Map; + + if (map != null) { - return; - } + var message = $"You notice {from.Name} attempting to peek into {root.Name}'s belongings."; - if (root?.AccessLevel > AccessLevel.Player && from.AccessLevel == AccessLevel.Player) - { - from.SendLocalizedMessage(500209); // You can not peek into the container. - return; - } + var eable = map.GetClientsInRange(from.Location, 8); - if (root?.AccessLevel == AccessLevel.Player && !CheckSnoopAllowed(from, root)) - { - from.SendLocalizedMessage(1001018); // You cannot perform negative acts on your target. - return; - } - - if (root?.AccessLevel == AccessLevel.Player && - from.Skills.Snooping.Value < Utility.Random(100)) - { - var map = from.Map; - - if (map != null) + foreach (var ns in eable) { - var message = $"You notice {from.Name} attempting to peek into {root.Name}'s belongings."; - - var eable = map.GetClientsInRange(from.Location, 8); - - foreach (var ns in eable) + if (ns.Mobile != from) { - if (ns.Mobile != from) - { - ns.Mobile.SendMessage(message); - } + ns.Mobile.SendMessage(message); } - - eable.Free(); - } - } - - if (from.AccessLevel == AccessLevel.Player) - { - Titles.AwardKarma(from, -4, true); - } - - if (from.AccessLevel > AccessLevel.Player || from.CheckTargetSkill(SkillName.Snooping, cont, 0.0, 100.0)) - { - if (cont is TrappableContainer container && container.ExecuteTrap(from)) - { - return; } - cont.DisplayTo(from); + eable.Free(); } - else - { - from.SendLocalizedMessage(500210); // You failed to peek into the container. + } - if (from.Skills.Hiding.Value / 2 < Utility.Random(100)) - { - from.RevealingAction(); - } + if (from.AccessLevel == AccessLevel.Player) + { + Titles.AwardKarma(from, -4, true); + } + + if (from.AccessLevel > AccessLevel.Player || from.CheckTargetSkill(SkillName.Snooping, cont, 0.0, 100.0)) + { + if (cont is TrappableContainer container && container.ExecuteTrap(from)) + { + return; } + + cont.DisplayTo(from); } else { - from.SendLocalizedMessage(500446); // That is too far away. + from.SendLocalizedMessage(500210); // You failed to peek into the container. + + if (from.Skills.Hiding.Value / 2 < Utility.Random(100)) + { + from.RevealingAction(); + } } } } diff --git a/Projects/UOContent/Skills/SpiritSpeak.cs b/Projects/UOContent/Skills/SpiritSpeak.cs index 7bc04ddab..69b40fcf8 100644 --- a/Projects/UOContent/Skills/SpiritSpeak.cs +++ b/Projects/UOContent/Skills/SpiritSpeak.cs @@ -116,7 +116,7 @@ namespace Server.SkillHandlers public override bool CheckDisturb(DisturbType type, bool checkFirst, bool resistable) { - if (type == DisturbType.EquipRequest || type == DisturbType.UseRequest) + if (type is DisturbType.EquipRequest or DisturbType.UseRequest) { return false; } diff --git a/Projects/UOContent/Special Systems/Engines/GiftGiving.cs b/Projects/UOContent/Special Systems/Engines/GiftGiving.cs index 14634063b..5cfc1a06a 100644 --- a/Projects/UOContent/Special Systems/Engines/GiftGiving.cs +++ b/Projects/UOContent/Special Systems/Engines/GiftGiving.cs @@ -26,7 +26,7 @@ namespace Server.Misc private static void EventSink_Login(Mobile m) { - if (!(m.Account is Account acct)) + if (m.Account is not Account acct) { return; } diff --git a/Projects/UOContent/Spells/Base/SpellHelper.cs b/Projects/UOContent/Spells/Base/SpellHelper.cs index 383228b49..ea9ec4131 100644 --- a/Projects/UOContent/Spells/Base/SpellHelper.cs +++ b/Projects/UOContent/Spells/Base/SpellHelper.cs @@ -623,7 +623,7 @@ namespace Server.Spells public static void SendInvalidMessage(Mobile caster, TravelCheckType type) { - if (type == TravelCheckType.RecallTo || type == TravelCheckType.GateTo) + if (type is TravelCheckType.RecallTo or TravelCheckType.GateTo) { caster.SendLocalizedMessage(1019004); // You are not allowed to travel there. } @@ -754,7 +754,7 @@ namespace Server.Spells public static bool IsSafeZone(Map map, Point3D loc) => Region.Find(loc, map).IsPartOf() && - (m_TravelType == TravelCheckType.TeleportTo || m_TravelType == TravelCheckType.TeleportFrom) + m_TravelType is TravelCheckType.TeleportTo or TravelCheckType.TeleportFrom && (m_TravelCaster as PlayerMobile)?.DuelPlayer?.Eliminated == false; public static bool IsFactionStronghold(Map map, Point3D loc) => Region.Find(loc, map).IsPartOf(); diff --git a/Projects/UOContent/Spells/Ninjitsu/FocusAttack.cs b/Projects/UOContent/Spells/Ninjitsu/FocusAttack.cs index ec88fd711..658eee2e6 100644 --- a/Projects/UOContent/Spells/Ninjitsu/FocusAttack.cs +++ b/Projects/UOContent/Spells/Ninjitsu/FocusAttack.cs @@ -20,14 +20,14 @@ namespace Server.Spells.Ninjitsu Item handOne = from.FindItemOnLayer(Layer.OneHanded) as BaseWeapon; - if (handOne != null && !(handOne is BaseRanged)) + if (handOne != null && handOne is not BaseRanged) { return base.Validate(from); } Item handTwo = from.FindItemOnLayer(Layer.TwoHanded) as BaseWeapon; - if (handTwo != null && !(handTwo is BaseRanged)) + if (handTwo != null && handTwo is not BaseRanged) { return base.Validate(from); } diff --git a/Projects/UOContent/Spells/Seventh/GateTravel.cs b/Projects/UOContent/Spells/Seventh/GateTravel.cs index 258dce8a3..13a171c04 100644 --- a/Projects/UOContent/Spells/Seventh/GateTravel.cs +++ b/Projects/UOContent/Spells/Seventh/GateTravel.cs @@ -129,7 +129,7 @@ namespace Server.Spells.Seventh foreach (var item in eable) { - if (item is Moongate || item is PublicMoongate) + if (item is Moongate or PublicMoongate) { return true; } diff --git a/Projects/UOContent/Spells/Spellweaving/ArcaneCircle.cs b/Projects/UOContent/Spells/Spellweaving/ArcaneCircle.cs index 5399efdec..de4e854ee 100644 --- a/Projects/UOContent/Spells/Spellweaving/ArcaneCircle.cs +++ b/Projects/UOContent/Spells/Spellweaving/ArcaneCircle.cs @@ -118,9 +118,7 @@ namespace Server.Spells.Spellweaving } public static bool IsValidTile(int itemID) => - itemID == 0xFEA || itemID == 0x1216 || itemID == 0x307F || itemID == 0x1D10 || itemID == 0x1D0F || - itemID == 0x1D1F || - itemID == 0x1D12; + itemID is 0xFEA or 0x1216 or 0x307F or 0x1D10 or 0x1D0F or 0x1D1F or 0x1D12; private List GetArcanists() { diff --git a/Projects/UOContent/Spells/Spellweaving/ArcanistSpell.cs b/Projects/UOContent/Spells/Spellweaving/ArcanistSpell.cs index 919abb461..4ebe0f2aa 100644 --- a/Projects/UOContent/Spells/Spellweaving/ArcanistSpell.cs +++ b/Projects/UOContent/Spells/Spellweaving/ArcanistSpell.cs @@ -34,7 +34,7 @@ namespace Server.Spells.Spellweaving from.Holding as ArcaneFocus ?? from.Backpack?.FindItemByType(); public static bool CheckExpansion(Mobile from) => - !(from is PlayerMobile) || from.NetState?.SupportsExpansion(Expansion.ML) == true; + @from is not PlayerMobile || from.NetState?.SupportsExpansion(Expansion.ML) == true; public override bool CheckCast() { diff --git a/Projects/UOContent/Spells/Spellweaving/ImmolatingWeapon.cs b/Projects/UOContent/Spells/Spellweaving/ImmolatingWeapon.cs index 33b1a58cc..f1b6059d8 100644 --- a/Projects/UOContent/Spells/Spellweaving/ImmolatingWeapon.cs +++ b/Projects/UOContent/Spells/Spellweaving/ImmolatingWeapon.cs @@ -26,7 +26,7 @@ namespace Server.Spells.Spellweaving public override bool CheckCast() { - if (!(Caster.Weapon is BaseWeapon weapon) || weapon is Fists || weapon is BaseRanged) + if (Caster.Weapon is not BaseWeapon weapon || weapon is Fists or BaseRanged) { Caster.SendLocalizedMessage(1060179); // You must be wielding a weapon to use this ability! return false; @@ -37,7 +37,7 @@ namespace Server.Spells.Spellweaving public override void OnCast() { - if (!(Caster.Weapon is BaseWeapon weapon) || weapon is Fists || weapon is BaseRanged) + if (Caster.Weapon is not BaseWeapon weapon || weapon is Fists or BaseRanged) { Caster.SendLocalizedMessage(1060179); // You must be wielding a weapon to use this ability! } diff --git a/Projects/UOContent/Targets/BladedItemTarget.cs b/Projects/UOContent/Targets/BladedItemTarget.cs index fd2dba71c..8cef72166 100644 --- a/Projects/UOContent/Targets/BladedItemTarget.cs +++ b/Projects/UOContent/Targets/BladedItemTarget.cs @@ -52,7 +52,7 @@ namespace Server.Targets { var itemID = target.ItemID; - if (itemID == 0xD15 || itemID == 0xD16) // red mushroom + if (itemID is 0xD15 or 0xD16) // red mushroom { var player = from as PlayerMobile; diff --git a/Projects/UOContent/Targets/PickMoveTarget.cs b/Projects/UOContent/Targets/PickMoveTarget.cs index 433eb5652..595f1ffd1 100644 --- a/Projects/UOContent/Targets/PickMoveTarget.cs +++ b/Projects/UOContent/Targets/PickMoveTarget.cs @@ -17,7 +17,7 @@ namespace Server.Targets return; } - if (o is Item || o is Mobile) + if (o is Item or Mobile) { from.Target = new MoveTarget(o); } From 3cba8c43f8bea35e30eeb5b294508edabc43c16d Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Fri, 24 Dec 2021 15:56:07 -0800 Subject: [PATCH 044/213] fix: Removes from literals (#893) --- Projects/UOContent/Accounting/AccountHandler.cs | 2 +- Projects/UOContent/Commands/Handlers.cs | 2 +- Projects/UOContent/Commands/Logging.cs | 2 +- Projects/UOContent/Engines/ConPVP/DuelContext.cs | 2 +- Projects/UOContent/Engines/Help/PageQueue.cs | 2 +- .../UOContent/Engines/ML Quests/Gumps/RaceChangeGump.cs | 2 +- .../UOContent/Engines/ML Quests/Items/PrismaticCrystal.cs | 2 +- .../UOContent/Engines/Quests/Dark Tides/DarkTidesQuest.cs | 2 +- .../Engines/Quests/Dark Tides/Items/KronusScroll.cs | 2 +- .../Quests/Emino's Undertaking/EminosUndertakingQuest.cs | 4 ++-- .../Engines/Quests/Haochi's Trials/HaochisTrialsQuest.cs | 2 +- .../Engines/Quests/Haochi's Trials/Items/HonorCandle.cs | 2 +- .../Engines/Quests/Solen Matriarch/Objectives.cs | 4 ++-- .../Engines/Quests/Uzeraan Turmoil/Objectives.cs | 2 +- .../Engines/Quests/Uzeraan Turmoil/UzeraanTurmoilQuest.cs | 8 ++++---- .../Gumps/Guilds/New Guild System/GuildMemberInfoGump.cs | 2 +- .../Gumps/Guilds/New Guild System/OtherGuildInfo.cs | 2 +- Projects/UOContent/Items/Addons/DartBoard.cs | 2 +- Projects/UOContent/Items/Misc/Corpses/Corpse.cs | 2 +- .../Items/Skill Items/Harvest Tools/BaseHarvestTool.cs | 2 +- .../Items/Special/House Raffle/HouseRaffleStone.cs | 4 ++-- Projects/UOContent/Items/Special/SoulStone.cs | 2 +- Projects/UOContent/Items/Wands/BaseWand.cs | 2 +- Projects/UOContent/Mobiles/PlayerMobile.cs | 2 +- Projects/UOContent/Mobiles/Special/BaseShieldGuard.cs | 2 +- Projects/UOContent/Spells/Spellweaving/ArcanistSpell.cs | 2 +- 26 files changed, 32 insertions(+), 32 deletions(-) diff --git a/Projects/UOContent/Accounting/AccountHandler.cs b/Projects/UOContent/Accounting/AccountHandler.cs index 55c6a7598..642660d05 100644 --- a/Projects/UOContent/Accounting/AccountHandler.cs +++ b/Projects/UOContent/Accounting/AccountHandler.cs @@ -110,7 +110,7 @@ namespace Server.Misc { var from = e.Mobile; - if (@from.Account is not Account acct) + if (from.Account is not Account acct) { return; } diff --git a/Projects/UOContent/Commands/Handlers.cs b/Projects/UOContent/Commands/Handlers.cs index 94a7f9395..98279f8ed 100644 --- a/Projects/UOContent/Commands/Handlers.cs +++ b/Projects/UOContent/Commands/Handlers.cs @@ -595,7 +595,7 @@ namespace Server.Commands { map = Map.AllMaps[i]; - if (map.MapIndex is 0x7F or 0xFF || @from.Map == map) + if (map.MapIndex is 0x7F or 0xFF || from.Map == map) { continue; } diff --git a/Projects/UOContent/Commands/Logging.cs b/Projects/UOContent/Commands/Logging.cs index 94f40d597..1ba8401d8 100644 --- a/Projects/UOContent/Commands/Logging.cs +++ b/Projects/UOContent/Commands/Logging.cs @@ -73,7 +73,7 @@ namespace Server.Commands var path = Core.BaseDirectory; - var name = @from.Account is not Account acct ? from.Name : acct.Username; + var name = from.Account is not Account acct ? from.Name : acct.Username; AppendPath(ref path, "Logs"); AppendPath(ref path, "Commands"); diff --git a/Projects/UOContent/Engines/ConPVP/DuelContext.cs b/Projects/UOContent/Engines/ConPVP/DuelContext.cs index b745ad9af..9e763c767 100644 --- a/Projects/UOContent/Engines/ConPVP/DuelContext.cs +++ b/Projects/UOContent/Engines/ConPVP/DuelContext.cs @@ -257,7 +257,7 @@ namespace Server.Engines.ConPVP public static bool AllowSpecialAbility(Mobile from, string name, bool message) { - if (@from is not PlayerMobile pm) + if (from is not PlayerMobile pm) { return true; } diff --git a/Projects/UOContent/Engines/Help/PageQueue.cs b/Projects/UOContent/Engines/Help/PageQueue.cs index dee5f13ad..07c4b9509 100644 --- a/Projects/UOContent/Engines/Help/PageQueue.cs +++ b/Projects/UOContent/Engines/Help/PageQueue.cs @@ -128,7 +128,7 @@ namespace Server.Engines.Help public static bool CheckAllowedToPage(Mobile from) { - if (@from is not PlayerMobile pm) + if (from is not PlayerMobile pm) { return true; } diff --git a/Projects/UOContent/Engines/ML Quests/Gumps/RaceChangeGump.cs b/Projects/UOContent/Engines/ML Quests/Gumps/RaceChangeGump.cs index b6759c71c..d5b6a0555 100644 --- a/Projects/UOContent/Engines/ML Quests/Gumps/RaceChangeGump.cs +++ b/Projects/UOContent/Engines/ML Quests/Gumps/RaceChangeGump.cs @@ -325,7 +325,7 @@ namespace Server.Engines.MLQuests.Gumps public override void OnDoubleClick(Mobile from) { - if (@from is not PlayerMobile pm) + if (from is not PlayerMobile pm) { return; } diff --git a/Projects/UOContent/Engines/ML Quests/Items/PrismaticCrystal.cs b/Projects/UOContent/Engines/ML Quests/Items/PrismaticCrystal.cs index 64978b443..430506447 100644 --- a/Projects/UOContent/Engines/ML Quests/Items/PrismaticCrystal.cs +++ b/Projects/UOContent/Engines/ML Quests/Items/PrismaticCrystal.cs @@ -22,7 +22,7 @@ namespace Server.Items public override void OnDoubleClick(Mobile from) { - if (@from is not PlayerMobile pm || pm.Backpack == null) + if (from is not PlayerMobile pm || pm.Backpack == null) { return; } diff --git a/Projects/UOContent/Engines/Quests/Dark Tides/DarkTidesQuest.cs b/Projects/UOContent/Engines/Quests/Dark Tides/DarkTidesQuest.cs index 5ce3407d6..6cbf52433 100644 --- a/Projects/UOContent/Engines/Quests/Dark Tides/DarkTidesQuest.cs +++ b/Projects/UOContent/Engines/Quests/Dark Tides/DarkTidesQuest.cs @@ -83,7 +83,7 @@ namespace Server.Engines.Quests.Necro public static bool HasLostCallingScroll(Mobile from) { - if (@from is not PlayerMobile pm) + if (from is not PlayerMobile pm) { return false; } diff --git a/Projects/UOContent/Engines/Quests/Dark Tides/Items/KronusScroll.cs b/Projects/UOContent/Engines/Quests/Dark Tides/Items/KronusScroll.cs index 8c91b6a3f..9fa4a5b48 100644 --- a/Projects/UOContent/Engines/Quests/Dark Tides/Items/KronusScroll.cs +++ b/Projects/UOContent/Engines/Quests/Dark Tides/Items/KronusScroll.cs @@ -31,7 +31,7 @@ namespace Server.Engines.Quests.Necro return; } - if (@from is not PlayerMobile pm) + if (from is not PlayerMobile pm) { return; } diff --git a/Projects/UOContent/Engines/Quests/Emino's Undertaking/EminosUndertakingQuest.cs b/Projects/UOContent/Engines/Quests/Emino's Undertaking/EminosUndertakingQuest.cs index bf03061c2..6ca8c0a1a 100644 --- a/Projects/UOContent/Engines/Quests/Emino's Undertaking/EminosUndertakingQuest.cs +++ b/Projects/UOContent/Engines/Quests/Emino's Undertaking/EminosUndertakingQuest.cs @@ -99,7 +99,7 @@ namespace Server.Engines.Quests.Ninja public static bool HasLostNoteForZoel(Mobile from) { - if (@from is not PlayerMobile pm) + if (from is not PlayerMobile pm) { return false; } @@ -119,7 +119,7 @@ namespace Server.Engines.Quests.Ninja public static bool HasLostEminosKatana(Mobile from) { - if (@from is not PlayerMobile pm) + if (from is not PlayerMobile pm) { return false; } diff --git a/Projects/UOContent/Engines/Quests/Haochi's Trials/HaochisTrialsQuest.cs b/Projects/UOContent/Engines/Quests/Haochi's Trials/HaochisTrialsQuest.cs index bc66e7b7c..778c24a1f 100644 --- a/Projects/UOContent/Engines/Quests/Haochi's Trials/HaochisTrialsQuest.cs +++ b/Projects/UOContent/Engines/Quests/Haochi's Trials/HaochisTrialsQuest.cs @@ -102,7 +102,7 @@ namespace Server.Engines.Quests.Samurai public static bool HasLostHaochisKatana(Mobile from) { - if (@from is not PlayerMobile pm) + if (from is not PlayerMobile pm) { return false; } diff --git a/Projects/UOContent/Engines/Quests/Haochi's Trials/Items/HonorCandle.cs b/Projects/UOContent/Engines/Quests/Haochi's Trials/Items/HonorCandle.cs index ce08640bb..af6cef5fa 100644 --- a/Projects/UOContent/Engines/Quests/Haochi's Trials/Items/HonorCandle.cs +++ b/Projects/UOContent/Engines/Quests/Haochi's Trials/Items/HonorCandle.cs @@ -30,7 +30,7 @@ namespace Server.Engines.Quests.Samurai if (!wasBurning && Burning) { - if (@from is not PlayerMobile player) + if (from is not PlayerMobile player) { return; } diff --git a/Projects/UOContent/Engines/Quests/Solen Matriarch/Objectives.cs b/Projects/UOContent/Engines/Quests/Solen Matriarch/Objectives.cs index dc889d0f4..6a4bf5b37 100644 --- a/Projects/UOContent/Engines/Quests/Solen Matriarch/Objectives.cs +++ b/Projects/UOContent/Engines/Quests/Solen Matriarch/Objectives.cs @@ -43,10 +43,10 @@ namespace Server.Engines.Quests.Matriarch if (redSolen) { - return @from is BlackSolenInfiltratorWarrior or BlackSolenInfiltratorQueen; + return from is BlackSolenInfiltratorWarrior or BlackSolenInfiltratorQueen; } - return @from is RedSolenInfiltratorWarrior or RedSolenInfiltratorQueen; + return from is RedSolenInfiltratorWarrior or RedSolenInfiltratorQueen; } public override void OnKill(BaseCreature creature, Container corpse) diff --git a/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Objectives.cs b/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Objectives.cs index 91d2997b4..1de4f00ab 100644 --- a/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Objectives.cs +++ b/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Objectives.cs @@ -395,7 +395,7 @@ namespace Server.Engines.Quests.Haven public override bool IgnoreYoungProtection(Mobile from) { // This restriction continues until the end of the quest - if (@from is Zombie or Skeleton && from.Map == Map.Trammel && from.X >= 3391 && from.X <= 3424 && + if (from is Zombie or Skeleton && from.Map == Map.Trammel && from.X >= 3391 && from.X <= 3424 && from.Y >= 2639 && from.Y <= 2664) // Haven graveyard { return true; diff --git a/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/UzeraanTurmoilQuest.cs b/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/UzeraanTurmoilQuest.cs index 28b56908f..42236d5de 100644 --- a/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/UzeraanTurmoilQuest.cs +++ b/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/UzeraanTurmoilQuest.cs @@ -110,7 +110,7 @@ namespace Server.Engines.Quests.Haven public static bool HasLostScrollOfPower(Mobile from) { - if (@from is not PlayerMobile pm) + if (from is not PlayerMobile pm) { return false; } @@ -130,7 +130,7 @@ namespace Server.Engines.Quests.Haven public static bool HasLostFertileDirt(Mobile from) { - if (@from is not PlayerMobile pm) + if (from is not PlayerMobile pm) { return false; } @@ -150,7 +150,7 @@ namespace Server.Engines.Quests.Haven public static bool HasLostDaemonBlood(Mobile from) { - if (@from is not PlayerMobile pm) + if (from is not PlayerMobile pm) { return false; } @@ -170,7 +170,7 @@ namespace Server.Engines.Quests.Haven public static bool HasLostDaemonBone(Mobile from) { - if (@from is not PlayerMobile pm) + if (from is not PlayerMobile pm) { return false; } diff --git a/Projects/UOContent/Gumps/Guilds/New Guild System/GuildMemberInfoGump.cs b/Projects/UOContent/Gumps/Guilds/New Guild System/GuildMemberInfoGump.cs index c5bf35787..706035ed1 100644 --- a/Projects/UOContent/Gumps/Guilds/New Guild System/GuildMemberInfoGump.cs +++ b/Projects/UOContent/Gumps/Guilds/New Guild System/GuildMemberInfoGump.cs @@ -244,7 +244,7 @@ namespace Server.Guilds public void SetTitle_Callback(Mobile from, string text) { - if (@from is not PlayerMobile pm || m_Member == null) + if (from is not PlayerMobile pm || m_Member == null) { return; } diff --git a/Projects/UOContent/Gumps/Guilds/New Guild System/OtherGuildInfo.cs b/Projects/UOContent/Gumps/Guilds/New Guild System/OtherGuildInfo.cs index b92cd52aa..761bff0d4 100644 --- a/Projects/UOContent/Gumps/Guilds/New Guild System/OtherGuildInfo.cs +++ b/Projects/UOContent/Gumps/Guilds/New Guild System/OtherGuildInfo.cs @@ -715,7 +715,7 @@ namespace Server.Guilds public void CreateAlliance_Callback(Mobile from, string text) { - if (@from is not PlayerMobile pm) + if (from is not PlayerMobile pm) { return; } diff --git a/Projects/UOContent/Items/Addons/DartBoard.cs b/Projects/UOContent/Items/Addons/DartBoard.cs index 967b27fd8..18333c337 100644 --- a/Projects/UOContent/Items/Addons/DartBoard.cs +++ b/Projects/UOContent/Items/Addons/DartBoard.cs @@ -60,7 +60,7 @@ namespace Server.Items public void Throw(Mobile from) { - if (@from.Weapon is not BaseKnife knife) + if (from.Weapon is not BaseKnife knife) { from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 500751); // Try holding a knife... return; diff --git a/Projects/UOContent/Items/Misc/Corpses/Corpse.cs b/Projects/UOContent/Items/Misc/Corpses/Corpse.cs index 766b5989e..f3ea9e7b6 100644 --- a/Projects/UOContent/Items/Misc/Corpses/Corpse.cs +++ b/Projects/UOContent/Items/Misc/Corpses/Corpse.cs @@ -1054,7 +1054,7 @@ namespace Server.Items return; } - if (@from is not PlayerMobile player) + if (from is not PlayerMobile player) { return; } diff --git a/Projects/UOContent/Items/Skill Items/Harvest Tools/BaseHarvestTool.cs b/Projects/UOContent/Items/Skill Items/Harvest Tools/BaseHarvestTool.cs index 8fffda490..66a98318f 100644 --- a/Projects/UOContent/Items/Skill Items/Harvest Tools/BaseHarvestTool.cs +++ b/Projects/UOContent/Items/Skill Items/Harvest Tools/BaseHarvestTool.cs @@ -168,7 +168,7 @@ namespace Server.Items return; } - if (@from is not PlayerMobile pm) + if (from is not PlayerMobile pm) { return; } diff --git a/Projects/UOContent/Items/Special/House Raffle/HouseRaffleStone.cs b/Projects/UOContent/Items/Special/House Raffle/HouseRaffleStone.cs index deb7f74a5..248b24751 100644 --- a/Projects/UOContent/Items/Special/House Raffle/HouseRaffleStone.cs +++ b/Projects/UOContent/Items/Special/House Raffle/HouseRaffleStone.cs @@ -299,7 +299,7 @@ namespace Server.Items private bool HasEntered(Mobile from) { - if (@from.Account is not Account acc) + if (from.Account is not Account acc) { return false; } @@ -509,7 +509,7 @@ namespace Server.Items return; } - if (@from.Account is not Account) + if (from.Account is not Account) { return; } diff --git a/Projects/UOContent/Items/Special/SoulStone.cs b/Projects/UOContent/Items/Special/SoulStone.cs index e170157f7..a951f169f 100644 --- a/Projects/UOContent/Items/Special/SoulStone.cs +++ b/Projects/UOContent/Items/Special/SoulStone.cs @@ -167,7 +167,7 @@ namespace Server.Items return false; } - if (Account != null && (@from.Account is not Accounting.Account || from.Account.Username != Account)) + if (Account != null && (from.Account is not Accounting.Account || from.Account.Username != Account)) { from.SendLocalizedMessage( 1070714 diff --git a/Projects/UOContent/Items/Wands/BaseWand.cs b/Projects/UOContent/Items/Wands/BaseWand.cs index 3e030dcd8..310ffe526 100644 --- a/Projects/UOContent/Items/Wands/BaseWand.cs +++ b/Projects/UOContent/Items/Wands/BaseWand.cs @@ -244,7 +244,7 @@ namespace Server.Items public virtual void DoWandTarget(Mobile from, object o) { - if (Deleted || _charges <= 0 || Parent != @from || o is StaticTarget or LandTarget) + if (Deleted || _charges <= 0 || Parent != from || o is StaticTarget or LandTarget) { return; } diff --git a/Projects/UOContent/Mobiles/PlayerMobile.cs b/Projects/UOContent/Mobiles/PlayerMobile.cs index 59a605d5b..3e9895002 100644 --- a/Projects/UOContent/Mobiles/PlayerMobile.cs +++ b/Projects/UOContent/Mobiles/PlayerMobile.cs @@ -1252,7 +1252,7 @@ namespace Server.Mobiles { string notice; - if (@from.Account is not Account acct || !acct.HasAccess(from.NetState)) + if (from.Account is not Account acct || !acct.HasAccess(from.NetState)) { if (from.AccessLevel == AccessLevel.Player) { diff --git a/Projects/UOContent/Mobiles/Special/BaseShieldGuard.cs b/Projects/UOContent/Mobiles/Special/BaseShieldGuard.cs index 7c1cb745c..85eaaaba4 100644 --- a/Projects/UOContent/Mobiles/Special/BaseShieldGuard.cs +++ b/Projects/UOContent/Mobiles/Special/BaseShieldGuard.cs @@ -116,7 +116,7 @@ namespace Server.Mobiles var from = e.Mobile; - if (@from.Guild is not Guild g || g.Type != Type) + if (from.Guild is not Guild g || g.Type != Type) { Say(SignupNumber); } diff --git a/Projects/UOContent/Spells/Spellweaving/ArcanistSpell.cs b/Projects/UOContent/Spells/Spellweaving/ArcanistSpell.cs index 4ebe0f2aa..bd4e75b5d 100644 --- a/Projects/UOContent/Spells/Spellweaving/ArcanistSpell.cs +++ b/Projects/UOContent/Spells/Spellweaving/ArcanistSpell.cs @@ -34,7 +34,7 @@ namespace Server.Spells.Spellweaving from.Holding as ArcaneFocus ?? from.Backpack?.FindItemByType(); public static bool CheckExpansion(Mobile from) => - @from is not PlayerMobile || from.NetState?.SupportsExpansion(Expansion.ML) == true; + from is not PlayerMobile || from.NetState?.SupportsExpansion(Expansion.ML) == true; public override bool CheckCast() { From a264f2a34ebf1111a77c6a83ba147720912e8c5d Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 26 Dec 2021 00:43:04 -0800 Subject: [PATCH 045/213] readme: Fixes Fedora on README (#894) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1ee0cb293..87a102ff7 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ ModernUO [![Discord](https://img.shields.io/discord/751317910504603701?logo=disc [![Debian 10/11](https://img.shields.io/badge/-bullseye-A81D33?logo=debian)](https://www.debian.org/distrib/) [![Ubuntu 16/18/20 LTS](https://img.shields.io/badge/-20LTS-E95420?logo=ubuntu&logoColor=white)](https://ubuntu.com/download/server) [![CentOS 7/8](https://img.shields.io/badge/-8.5-262577?logo=centos&logoColor=white)](https://www.centos.org/download/) -[![Fedora 32/33/34](https://img.shields.io/badge/-34-0B57A4?logo=fedora&logoColor=white)](https://getfedora.org/en/server/download/) +[![Fedora 32/33/34](https://img.shields.io/badge/-fedora%2034-0B57A4)](https://getfedora.org/en/server/download/) [![RedHat 7/8](https://img.shields.io/badge/-8-BE0000?logo=red%20hat&logoColor=white)](https://access.redhat.com/downloads) #### Running the server From 58190674f9970944d6c15030a5d047de9519d114 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Mon, 27 Dec 2021 01:27:15 -0800 Subject: [PATCH 046/213] feat: Adds StaffAccess and ResetStaffDress commands (#895) --- Projects/Server/Commands.cs | 85 ++------------- Projects/UOContent/Commands/Batch.cs | 3 +- Projects/UOContent/Commands/DragEffects.cs | 3 +- Projects/UOContent/Commands/Dupe.cs | 6 +- Projects/UOContent/Commands/Handlers.cs | 60 ++++++----- Projects/UOContent/Commands/HelpInfo.cs | 5 +- .../Commands/Object Creation/AddGump.cs | 5 +- .../Commands/Object Creation/Decorate.cs | 3 +- .../Commands/Object Creation/DecorateMag.cs | 3 +- .../Commands/Object Creation/GenTeleporter.cs | 6 +- Projects/UOContent/Commands/Profiling.cs | 12 ++- .../UOContent/Commands/ResetStaffDress.cs | 69 ++++++++++++ Projects/UOContent/Commands/ShardTime.cs | 3 +- Projects/UOContent/Commands/SignParser.cs | 3 +- Projects/UOContent/Commands/Skills.cs | 9 +- Projects/UOContent/Commands/SkillsMenu.cs | 3 +- Projects/UOContent/Commands/StaffAccess.cs | 101 ++++++++++++++++++ Projects/UOContent/Commands/Statics.cs | 18 ++-- Projects/UOContent/Commands/VisibilityList.cs | 11 +- Projects/UOContent/Commands/Wipe.cs | 12 ++- 20 files changed, 282 insertions(+), 138 deletions(-) create mode 100644 Projects/UOContent/Commands/ResetStaffDress.cs create mode 100644 Projects/UOContent/Commands/StaffAccess.cs diff --git a/Projects/Server/Commands.cs b/Projects/Server/Commands.cs index 503b24814..6c5de7deb 100644 --- a/Projects/Server/Commands.cs +++ b/Projects/Server/Commands.cs @@ -26,65 +26,20 @@ namespace Server public int Length => Arguments.Length; - public string GetString(int index) - { - if (index < 0 || index >= Arguments.Length) - { - return ""; - } + public string GetString(int index) => index < 0 || index >= Arguments.Length ? "" : Arguments[index]; - return Arguments[index]; - } + public int GetInt32(int index) => index < 0 || index >= Arguments.Length ? 0 : Utility.ToInt32(Arguments[index]); - public int GetInt32(int index) - { - if (index < 0 || index >= Arguments.Length) - { - return 0; - } + public uint GetUInt32(int index) => + index < 0 || index >= Arguments.Length ? 0 : Utility.ToUInt32(Arguments[index]); - return Utility.ToInt32(Arguments[index]); - } + public bool GetBoolean(int index) => index >= 0 && index < Arguments.Length && Utility.ToBoolean(Arguments[index]); - public uint GetUInt32(int index) - { - if (index < 0 || index >= Arguments.Length) - { - return 0; - } + public double GetDouble(int index) => + index < 0 || index >= Arguments.Length ? 0.0 : Utility.ToDouble(Arguments[index]); - return Utility.ToUInt32(Arguments[index]); - } - - public bool GetBoolean(int index) - { - if (index < 0 || index >= Arguments.Length) - { - return false; - } - - return Utility.ToBoolean(Arguments[index]); - } - - public double GetDouble(int index) - { - if (index < 0 || index >= Arguments.Length) - { - return 0.0; - } - - return Utility.ToDouble(Arguments[index]); - } - - public TimeSpan GetTimeSpan(int index) - { - if (index < 0 || index >= Arguments.Length) - { - return TimeSpan.Zero; - } - - return Utility.ToTimeSpan(Arguments[index]); - } + public TimeSpan GetTimeSpan(int index) => + index < 0 || index >= Arguments.Length ? TimeSpan.Zero : Utility.ToTimeSpan(Arguments[index]); } public static partial class EventSink @@ -137,27 +92,7 @@ namespace Server } } - public record CommandInfo - { - public CommandInfo(AccessLevel accessLevel, string name, string[] aliases, string usage, string description) - { - AccessLevel = accessLevel; - Name = name; - Aliases = aliases; - Usage = usage; - Description = description; - } - - public AccessLevel AccessLevel { get; } - - public string Name { get; } - - public string[] Aliases { get; } - - public string Usage { get; } - - public string Description { get; } - } + public record CommandInfo(AccessLevel AccessLevel, string Name, string[] Aliases, string Usage, string Description); public class CommandInfoSorter : IComparer { diff --git a/Projects/UOContent/Commands/Batch.cs b/Projects/UOContent/Commands/Batch.cs index 84aeca315..8e7ce6b73 100644 --- a/Projects/UOContent/Commands/Batch.cs +++ b/Projects/UOContent/Commands/Batch.cs @@ -177,7 +177,8 @@ namespace Server.Commands CommandSystem.Register("Batch", AccessLevel.Counselor, Batch_OnCommand); } - [Usage("Batch"), Description("Allows multiple commands to be run at the same time.")] + [Usage("Batch")] + [Description("Allows multiple commands to be run at the same time.")] public static void Batch_OnCommand(CommandEventArgs e) { e.Mobile.SendGump(new BatchGump(e.Mobile, new Batch())); diff --git a/Projects/UOContent/Commands/DragEffects.cs b/Projects/UOContent/Commands/DragEffects.cs index d9ef33a38..d67d0d393 100644 --- a/Projects/UOContent/Commands/DragEffects.cs +++ b/Projects/UOContent/Commands/DragEffects.cs @@ -7,7 +7,8 @@ namespace Server.Commands CommandSystem.Register("DragEffects", AccessLevel.Developer, DragEffects_OnCommand); } - [Usage("DragEffects [enable=false]"), Description("Enables or disables the item drag and drop effects.")] + [Usage("DragEffects [enable=false]")] + [Description("Enables or disables the item drag and drop effects.")] public static void DragEffects_OnCommand(CommandEventArgs e) { if (e.Length == 0) diff --git a/Projects/UOContent/Commands/Dupe.cs b/Projects/UOContent/Commands/Dupe.cs index db7bfdbde..3cbf9de10 100644 --- a/Projects/UOContent/Commands/Dupe.cs +++ b/Projects/UOContent/Commands/Dupe.cs @@ -13,7 +13,8 @@ namespace Server.Commands CommandSystem.Register("DupeInBag", AccessLevel.GameMaster, DupeInBag_OnCommand); } - [Usage("Dupe [amount]"), Description("Dupes a targeted item.")] + [Usage("Dupe [amount]")] + [Description("Dupes a targeted item.")] private static void Dupe_OnCommand(CommandEventArgs e) { var amount = 1; @@ -26,7 +27,8 @@ namespace Server.Commands e.Mobile.SendMessage("What do you wish to dupe?"); } - [Usage("DupeInBag "), Description("Dupes an item at it's current location (count) number of times.")] + [Usage("DupeInBag ")] + [Description("Dupes an item at it's current location (count) number of times.")] private static void DupeInBag_OnCommand(CommandEventArgs e) { var amount = 1; diff --git a/Projects/UOContent/Commands/Handlers.cs b/Projects/UOContent/Commands/Handlers.cs index 98279f8ed..811bacff9 100644 --- a/Projects/UOContent/Commands/Handlers.cs +++ b/Projects/UOContent/Commands/Handlers.cs @@ -73,7 +73,8 @@ namespace Server.Commands CommandSystem.Register(command, access, handler); } - [Usage("SpeedBoost [true|false]"), Description("Enables a speed boost for the invoker. Disable with parameters.")] + [Usage("SpeedBoost [true|false]")] + [Description("Enables a speed boost for the invoker. Disable with parameters.")] private static void SpeedBoost_OnCommand(CommandEventArgs e) { var from = e.Mobile; @@ -97,7 +98,8 @@ namespace Server.Commands } } - [Usage("Where"), Description("Tells the commanding player his coordinates, region, and facet.")] + [Usage("Where")] + [Description("Tells the commanding player his coordinates, region, and facet.")] public static void Where_OnCommand(CommandEventArgs e) { var from = e.Mobile; @@ -127,9 +129,8 @@ namespace Server.Commands } } - [Usage("DropHolding"), Description( - "Drops the item, if any, that a targeted player is holding. The item is placed into their backpack, or if that's full, at their feet." - )] + [Usage("DropHolding")] + [Description("Drops the item, if any, that a targeted player is holding. The item is placed into their backpack, or if that's full, at their feet.")] public static void DropHolding_OnCommand(CommandEventArgs e) { e.Mobile.BeginTarget(-1, false, TargetFlags.None, DropHolding_OnTarget); @@ -274,7 +275,8 @@ namespace Server.Commands } } - [Usage("GetFollowers"), Description("Teleports all pets of a targeted player to your location.")] + [Usage("GetFollowers")] + [Description("Teleports all pets of a targeted player to your location.")] public static void GetFollowers_OnCommand(CommandEventArgs e) { e.Mobile.BeginTarget(-1, false, TargetFlags.None, GetFollowers_OnTarget); @@ -374,9 +376,8 @@ namespace Server.Commands e.Mobile.Target = new ViewEqTarget(); } - [Usage("Sound [toAll=true]"), Description( - "Plays a sound to players within 12 tiles of you. The (toAll) argument specifies to everyone, or just those who can see you." - )] + [Usage("Sound [toAll=true]")] + [Description("Plays a sound to players within 12 tiles of you. The (toAll) argument specifies to everyone, or just those who can see you.")] public static void Sound_OnCommand(CommandEventArgs e) { if (e.Length == 1) @@ -423,7 +424,8 @@ namespace Server.Commands } } - [Usage("Echo "), Description("Relays (text) as a system message.")] + [Usage("Echo ")] + [Description("Relays (text) as a system message.")] public static void Echo_OnCommand(CommandEventArgs e) { var toEcho = e.ArgString.Trim(); @@ -438,19 +440,22 @@ namespace Server.Commands } } - [Usage("Bank"), Description("Opens the bank box of a given target.")] + [Usage("Bank")] + [Description("Opens the bank box of a given target.")] public static void Bank_OnCommand(CommandEventArgs e) { e.Mobile.Target = new BankTarget(); } - [Usage("Client"), Description("Opens the client gump menu for a given player.")] + [Usage("Client")] + [Description("Opens the client gump menu for a given player.")] private static void Client_OnCommand(CommandEventArgs e) { e.Mobile.Target = new ClientTarget(); } - [Usage("Move"), Description("Repositions a targeted item or mobile.")] + [Usage("Move")] + [Description("Repositions a targeted item or mobile.")] private static void Move_OnCommand(CommandEventArgs e) { e.Mobile.Target = new PickMoveTarget(); @@ -473,9 +478,8 @@ namespace Server.Commands return validMap; } - [Usage("Go [name | serial | (x y [z]) | (deg min (N | S) deg min (E | W))]"), Description( - "With no arguments, this command brings up the go menu. With one argument, (name), you are moved to that regions \"go location.\" Or, if a numerical value is specified for one argument, (serial), you are moved to that object. Two or three arguments, (x y [z]), will move your character to that location. When six arguments are specified, (deg min (N | S) deg min (E | W)), your character will go to an approximate of those sextant coordinates." - )] + [Usage("Go [name | serial | (x y [z]) | (deg min (N | S) deg min (E | W))]")] + [Description("With no arguments, this command brings up the go menu. With one argument, (name), you are moved to that regions \"go location.\" Or, if a numerical value is specified for one argument, (serial), you are moved to that object. Two or three arguments, (x y [z]), will move your character to that location. When six arguments are specified, (deg min (N | S) deg min (E | W)), your character will go to an approximate of those sextant coordinates.")] private static void Go_OnCommand(CommandEventArgs e) { var from = e.Mobile; @@ -685,7 +689,8 @@ namespace Server.Commands } } - [Usage("Help"), Description("Lists all available commands.")] + [Usage("Help")] + [Description("Lists all available commands.")] public static void Help_OnCommand(CommandEventArgs e) { var m = e.Mobile; @@ -732,13 +737,15 @@ namespace Server.Commands } } - [Usage("SMsg "), Aliases("S", "SM"), Description("Broadcasts a message to all online staff.")] + [Usage("SMsg "), Aliases("S", "SM")] + [Description("Broadcasts a message to all online staff.")] public static void StaffMessage_OnCommand(CommandEventArgs e) { BroadcastMessage(AccessLevel.Counselor, e.Mobile.SpeechHue, $"[{e.Mobile.Name}] {e.ArgString}"); } - [Usage("BCast "), Aliases("B", "BC"), Description("Broadcasts a message to everyone online.")] + [Usage("BCast "), Aliases("B", "BC")] + [Description("Broadcasts a message to everyone online.")] public static void BroadcastMessage_OnCommand(CommandEventArgs e) { BroadcastMessage(AccessLevel.Player, 0x482, $"Staff message from {e.Mobile.Name}:"); @@ -758,7 +765,8 @@ namespace Server.Commands } } - [Usage("AutoPageNotify"), Aliases("APN"), Description("Toggles your auto-page-notify status.")] + [Usage("AutoPageNotify"), Aliases("APN")] + [Description("Toggles your auto-page-notify status.")] public static void APN_OnCommand(CommandEventArgs e) { var m = e.Mobile; @@ -789,7 +797,8 @@ namespace Server.Commands } } - [Usage("Cast "), Description("Casts a spell by name.")] + [Usage("Cast ")] + [Description("Casts a spell by name.")] public static void Cast_OnCommand(CommandEventArgs e) { if (e.Length == 1) @@ -816,19 +825,22 @@ namespace Server.Commands } } - [Usage("Stuck"), Description("Opens a menu of towns, used for teleporting stuck mobiles.")] + [Usage("Stuck")] + [Description("Opens a menu of towns, used for teleporting stuck mobiles.")] public static void Stuck_OnCommand(CommandEventArgs e) { e.Mobile.Target = new StuckMenuTarget(); } - [Usage("Light "), Description("Set your local lightlevel.")] + [Usage("Light ")] + [Description("Set your local lightlevel.")] public static void Light_OnCommand(CommandEventArgs e) { e.Mobile.LightLevel = e.GetInt32(0); } - [Usage("Stats"), Description("View some stats about the server.")] + [Usage("Stats")] + [Description("View some stats about the server.")] public static void Stats_OnCommand(CommandEventArgs e) { e.Mobile.SendMessage("Open Connections: {0}", TcpServer.Instances.Count); diff --git a/Projects/UOContent/Commands/HelpInfo.cs b/Projects/UOContent/Commands/HelpInfo.cs index b85ca8b05..3056a75cd 100644 --- a/Projects/UOContent/Commands/HelpInfo.cs +++ b/Projects/UOContent/Commands/HelpInfo.cs @@ -19,9 +19,8 @@ namespace Server.Commands FillTable(); } - [Usage("HelpInfo []"), Description( - "Gives information on a specified command, or when no argument specified, displays a gump containing all commands" - )] + [Usage("HelpInfo []")] + [Description("Gives information on a specified command, or when no argument specified, displays a gump containing all commands")] private static void HelpInfo_OnCommand(CommandEventArgs e) { if (e.Length > 0) diff --git a/Projects/UOContent/Commands/Object Creation/AddGump.cs b/Projects/UOContent/Commands/Object Creation/AddGump.cs index 84e3523a4..bf7890052 100644 --- a/Projects/UOContent/Commands/Object Creation/AddGump.cs +++ b/Projects/UOContent/Commands/Object Creation/AddGump.cs @@ -92,9 +92,8 @@ namespace Server.Gumps CommandSystem.Register("AddMenu", AccessLevel.GameMaster, AddMenu_OnCommand); } - [Usage("AddMenu [searchString]"), Description( - "Opens an add menu, with an optional initial search string. This menu allows you to search for Items or Mobiles and add them interactively." - )] + [Usage("AddMenu [searchString]")] + [Description("Opens an add menu, with an optional initial search string. This menu allows you to search for Items or Mobiles and add them interactively.")] private static void AddMenu_OnCommand(CommandEventArgs e) { var val = e.ArgString.Trim(); diff --git a/Projects/UOContent/Commands/Object Creation/Decorate.cs b/Projects/UOContent/Commands/Object Creation/Decorate.cs index f8a14b4f2..e36944c44 100644 --- a/Projects/UOContent/Commands/Object Creation/Decorate.cs +++ b/Projects/UOContent/Commands/Object Creation/Decorate.cs @@ -20,7 +20,8 @@ namespace Server.Commands CommandSystem.Register("Decorate", AccessLevel.Administrator, Decorate_OnCommand); } - [Usage("Decorate"), Description("Generates world decoration.")] + [Usage("Decorate")] + [Description("Generates world decoration.")] private static void Decorate_OnCommand(CommandEventArgs e) { m_Mobile = e.Mobile; diff --git a/Projects/UOContent/Commands/Object Creation/DecorateMag.cs b/Projects/UOContent/Commands/Object Creation/DecorateMag.cs index fdea8e992..be9d86629 100644 --- a/Projects/UOContent/Commands/Object Creation/DecorateMag.cs +++ b/Projects/UOContent/Commands/Object Creation/DecorateMag.cs @@ -20,7 +20,8 @@ namespace Server.Commands CommandSystem.Register("DecorateMag", AccessLevel.Administrator, DecorateMag_OnCommand); } - [Usage("DecorateMag"), Description("Generates world decoration.")] + [Usage("DecorateMag")] + [Description("Generates world decoration.")] private static void DecorateMag_OnCommand(CommandEventArgs e) { m_Mobile = e.Mobile; diff --git a/Projects/UOContent/Commands/Object Creation/GenTeleporter.cs b/Projects/UOContent/Commands/Object Creation/GenTeleporter.cs index daa84d9b0..b597611d4 100644 --- a/Projects/UOContent/Commands/Object Creation/GenTeleporter.cs +++ b/Projects/UOContent/Commands/Object Creation/GenTeleporter.cs @@ -33,7 +33,8 @@ namespace Server.Commands CommandSystem.Register("TelGenDelete", AccessLevel.Administrator, TelGenDelete_OnCommand); } - [Usage("TelGenDelete"), Description("Destroys world/dungeon teleporters for all facets.")] + [Usage("TelGenDelete")] + [Description("Destroys world/dungeon teleporters for all facets.")] public static void TelGenDelete_OnCommand(CommandEventArgs e) { var from = e.Mobile; @@ -63,7 +64,8 @@ namespace Server.Commands from.SendMessage(WarningHue, $"{count} Teleporters Removed."); } - [Usage("TelGen"), Description("Generates world/dungeon teleporters for all facets.")] + [Usage("TelGen")] + [Description("Generates world/dungeon teleporters for all facets.")] public static void GenTeleporter_OnCommand(CommandEventArgs e) { var from = e.Mobile; diff --git a/Projects/UOContent/Commands/Profiling.cs b/Projects/UOContent/Commands/Profiling.cs index 79f035202..b23f21523 100644 --- a/Projects/UOContent/Commands/Profiling.cs +++ b/Projects/UOContent/Commands/Profiling.cs @@ -19,7 +19,8 @@ namespace Server.Commands CommandSystem.Register("SetProfiles", AccessLevel.Administrator, SetProfiles_OnCommand); } - [Usage("WriteProfiles"), Description("Generates a log files containing performance diagnostic information.")] + [Usage("WriteProfiles")] + [Description("Generates a log files containing performance diagnostic information.")] public static void WriteProfiles_OnCommand(CommandEventArgs e) { try @@ -86,7 +87,8 @@ namespace Server.Commands } } - [Usage("CountObjects"), Description("Generates a log file detailing all item and mobile types in the world.")] + [Usage("CountObjects")] + [Description("Generates a log file detailing all item and mobile types in the world.")] public static void CountObjects_OnCommand(CommandEventArgs e) { using (var op = new StreamWriter("objects.log")) @@ -140,7 +142,8 @@ namespace Server.Commands e.Mobile.SendMessage("Object table has been generated. See the file : objects.log"); } - [Usage("TraceExpanded"), Description("Generates a log file describing all items using expanded memory.")] + [Usage("TraceExpanded")] + [Description("Generates a log file describing all items using expanded memory.")] public static void TraceExpanded_OnCommand(CommandEventArgs e) { var typeTable = new Dictionary(); @@ -251,7 +254,8 @@ namespace Server.Commands } } - [Usage("TraceInternal"), Description("Generates a log file describing all items in the 'internal' map.")] + [Usage("TraceInternal")] + [Description("Generates a log file describing all items in the 'internal' map.")] public static void TraceInternal_OnCommand(CommandEventArgs e) { var totalCount = 0; diff --git a/Projects/UOContent/Commands/ResetStaffDress.cs b/Projects/UOContent/Commands/ResetStaffDress.cs new file mode 100644 index 000000000..4ca756b84 --- /dev/null +++ b/Projects/UOContent/Commands/ResetStaffDress.cs @@ -0,0 +1,69 @@ +using System; +using Server.Items; +using Server.Mobiles; +using Server.Network; +using Server.Utilities; + +namespace Server.Commands; + +public static class StaffDress +{ + private static readonly Type[] _staffRobeTypes = + { + null, + typeof(CounselorRobe), + typeof(GMRobe), + typeof(SeerRobe), + typeof(AdminRobe), + typeof(AdminRobe), + typeof(AdminRobe) + }; + + public static void Initialize() + { + CommandSystem.Register("ResetStaffDress", AccessLevel.Counselor, StaffDress_OnCommand); + } + + [Usage("ResetStaffDress")] + [Description("Resets staff to proper GM")] + public static void StaffDress_OnCommand(CommandEventArgs e) + { + if (e.Mobile is not PlayerMobile pm) + { + return; + } + + pm.Karma = pm.Fame = pm.Kills = pm.ShortTermMurders = pm.BodyMod = 0; + pm.Body = 987; + pm.SolidHueOverride = pm.HueMod = -1; + pm.Blessed = true; + pm.DisplayGuildTitle = false; + pm.DisplayChampionTitle = false; + if (pm.Mount != null) + { + pm.Mount.Rider = null; + } + + pm.NetState.SendSpeedControl(SpeedControlSetting.Mount); + pm.ResetStaffAccess(); + + for (var i = pm.Items.Count - 1; i >= 0; i--) + { + var item = pm.Items[i]; + + if (item.Layer is not Layer.Backpack + and not Layer.Bank + and not Layer.FacialHair + and not Layer.Hair + and not Layer.Mount + and not Layer.ShopBuy + and not Layer.ShopResale + and not Layer.ShopSell) + { + pm.AddToBackpack(item); + } + } + + pm.AddItem(_staffRobeTypes[(int)pm.AccessLevel].CreateInstance()); + } +} diff --git a/Projects/UOContent/Commands/ShardTime.cs b/Projects/UOContent/Commands/ShardTime.cs index a206d1340..17de8d46a 100644 --- a/Projects/UOContent/Commands/ShardTime.cs +++ b/Projects/UOContent/Commands/ShardTime.cs @@ -9,7 +9,8 @@ namespace Server.Commands CommandSystem.Register("Time", AccessLevel.Player, Time_OnCommand); } - [Usage("Time"), Description("Returns the server's local time.")] + [Usage("Time")] + [Description("Returns the server's local time.")] private static void Time_OnCommand(CommandEventArgs e) { e.Mobile.SendMessage(Core.Now.ToString(CultureInfo.InvariantCulture)); diff --git a/Projects/UOContent/Commands/SignParser.cs b/Projects/UOContent/Commands/SignParser.cs index 0fba2d29a..9f96a4f85 100644 --- a/Projects/UOContent/Commands/SignParser.cs +++ b/Projects/UOContent/Commands/SignParser.cs @@ -15,7 +15,8 @@ namespace Server.Commands CommandSystem.Register("SignGen", AccessLevel.Administrator, SignGen_OnCommand); } - [Usage("SignGen"), Description("Generates world/shop signs on all facets.")] + [Usage("SignGen")] + [Description("Generates world/shop signs on all facets.")] public static void SignGen_OnCommand(CommandEventArgs c) { Parse(c.Mobile); diff --git a/Projects/UOContent/Commands/Skills.cs b/Projects/UOContent/Commands/Skills.cs index 04d525257..900c8a90a 100644 --- a/Projects/UOContent/Commands/Skills.cs +++ b/Projects/UOContent/Commands/Skills.cs @@ -12,7 +12,8 @@ namespace Server.Commands CommandSystem.Register("SetAllSkills", AccessLevel.GameMaster, SetAllSkills_OnCommand); } - [Usage("SetSkill "), Description("Sets a skill value by name of a targeted mobile.")] + [Usage("SetSkill ")] + [Description("Sets a skill value by name of a targeted mobile.")] public static void SetSkill_OnCommand(CommandEventArgs arg) { if (arg.Length != 2) @@ -32,7 +33,8 @@ namespace Server.Commands } } - [Usage("SetAllSkills "), Description("Sets all skill values of a targeted mobile.")] + [Usage("SetAllSkills ")] + [Description("Sets all skill values of a targeted mobile.")] public static void SetAllSkills_OnCommand(CommandEventArgs arg) { if (arg.Length != 1) @@ -45,7 +47,8 @@ namespace Server.Commands } } - [Usage("GetSkill "), Description("Gets a skill value by name of a targeted mobile.")] + [Usage("GetSkill ")] + [Description("Gets a skill value by name of a targeted mobile.")] public static void GetSkill_OnCommand(CommandEventArgs arg) { if (arg.Length != 1) diff --git a/Projects/UOContent/Commands/SkillsMenu.cs b/Projects/UOContent/Commands/SkillsMenu.cs index 956a52c4d..a69e55e1e 100644 --- a/Projects/UOContent/Commands/SkillsMenu.cs +++ b/Projects/UOContent/Commands/SkillsMenu.cs @@ -15,7 +15,8 @@ namespace Server.Commands CommandSystem.Register("Skills", AccessLevel.Counselor, Skills_OnCommand); } - [Usage("Skills"), Description("Opens a menu where you can view or edit skills of a targeted mobile.")] + [Usage("Skills")] + [Description("Opens a menu where you can view or edit skills of a targeted mobile.")] private static void Skills_OnCommand(CommandEventArgs e) { e.Mobile.Target = new SkillsTarget(); diff --git a/Projects/UOContent/Commands/StaffAccess.cs b/Projects/UOContent/Commands/StaffAccess.cs new file mode 100644 index 000000000..47ff71daa --- /dev/null +++ b/Projects/UOContent/Commands/StaffAccess.cs @@ -0,0 +1,101 @@ +using System; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using Server.Accounting; +using Server.Mobiles; + +namespace Server.Commands; + +public static class StaffAccess +{ + private static readonly Dictionary _accessLevelByString = new(); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static string AccountTag(Serial serial) => $"OriginalStaffAccess:{serial}"; + + public static void Initialize() + { + CommandSystem.Register("StaffAccess", AccessLevel.Player, StaffAccess_OnCommand); + + foreach (var accessLevel in Enum.GetValues()) + { + _accessLevelByString[accessLevel.ToString().ToLower()] = accessLevel; + } + + _accessLevelByString["gm"] = AccessLevel.GameMaster; + _accessLevelByString["dev"] = AccessLevel.Developer; + _accessLevelByString["admin"] = AccessLevel.Administrator; + } + + public static void ResetStaffAccess(this PlayerMobile m) + { + if (m.Account is not Account account) + { + return; + } + + var accountTag = AccountTag(m.Serial); + var originalAccessLevelString = account.GetTag(accountTag); + if (originalAccessLevelString == null) + { + return; + } + + var accessLevel = _accessLevelByString[originalAccessLevelString]; + account.RemoveTag(accountTag); + m.AccessLevel = accessLevel; + } + + [Usage("StaffAccess ")] + [Description("Overrides your access level.")] + public static void StaffAccess_OnCommand(CommandEventArgs e) + { + var m = e.Mobile; + if (m.Account is not Account account) + { + return; + } + + var accountTag = AccountTag(m.Serial); + var originalAccessLevelString = account.GetTag(accountTag); + AccessLevel? originalAccessLevel = originalAccessLevelString != null ? _accessLevelByString[originalAccessLevelString] : null; + if (originalAccessLevel == null && m.AccessLevel == AccessLevel.Player) + { + return; + } + + var accessLevelArgument = e.GetString(0)?.Trim().ToLower(); + AccessLevel newAccessLevel = AccessLevel.Player; + var validAccessLevel = !string.IsNullOrEmpty(accessLevelArgument) && + _accessLevelByString.TryGetValue(accessLevelArgument, out newAccessLevel); + + if (!validAccessLevel && originalAccessLevel == null) + { + m.SendMessage("Invalid access level specified."); + m.SendMessage("Usage: [staffaccess ."); + return; + } + + if (originalAccessLevel != null && (!validAccessLevel || newAccessLevel == originalAccessLevel)) + { + account.RemoveTag(accountTag); + newAccessLevel = originalAccessLevel.Value; + m.SendMessage("Restoring original staff access..."); + } + + if (newAccessLevel > m.AccessLevel) + { + m.SendMessage($"You cannot set your staff access to {newAccessLevel.ToString()}."); + return; + } + + if (originalAccessLevel == null) + { + // Save the original access level + account.AddTag(accountTag, m.AccessLevel.ToString().ToLower()); + } + + m.AccessLevel = newAccessLevel; + m.SendMessage($"Staff access set to {newAccessLevel.ToString()}."); + } +} diff --git a/Projects/UOContent/Commands/Statics.cs b/Projects/UOContent/Commands/Statics.cs index 839bd0ec3..8a64c3021 100644 --- a/Projects/UOContent/Commands/Statics.cs +++ b/Projects/UOContent/Commands/Statics.cs @@ -48,14 +48,16 @@ namespace Server CommandSystem.Register("UnfreezeWorld", AccessLevel.Administrator, UnfreezeWorld_OnCommand); } - [Usage("Freeze"), Description("Makes a targeted area of dynamic items static.")] + [Usage("Freeze")] + [Description("Makes a targeted area of dynamic items static.")] public static void Freeze_OnCommand(CommandEventArgs e) { var from = e.Mobile; BoundingBoxPicker.Begin(from, (map, start, end) => FreezeBox_Callback(from, map, start, end)); } - [Usage("FreezeMap"), Description("Makes every dynamic item in your map static.")] + [Usage("FreezeMap")] + [Description("Makes every dynamic item in your map static.")] public static void FreezeMap_OnCommand(CommandEventArgs e) { var from = e.Mobile; @@ -75,7 +77,8 @@ namespace Server } } - [Usage("FreezeWorld"), Description("Makes every dynamic item on all maps static.")] + [Usage("FreezeWorld")] + [Description("Makes every dynamic item on all maps static.")] public static void FreezeWorld_OnCommand(CommandEventArgs e) { SendWarning( @@ -404,14 +407,16 @@ namespace Server } } - [Usage("Unfreeze"), Description("Makes a targeted area of static items dynamic.")] + [Usage("Unfreeze")] + [Description("Makes a targeted area of static items dynamic.")] public static void Unfreeze_OnCommand(CommandEventArgs e) { var from = e.Mobile; BoundingBoxPicker.Begin(from, (map, start, end) => UnfreezeBox_Callback(from, map, start, end)); } - [Usage("UnfreezeMap"), Description("Makes every static item in your map dynamic.")] + [Usage("UnfreezeMap")] + [Description("Makes every static item in your map dynamic.")] public static void UnfreezeMap_OnCommand(CommandEventArgs e) { var map = e.Mobile.Map; @@ -430,7 +435,8 @@ namespace Server } } - [Usage("UnfreezeWorld"), Description("Makes every static item on all maps dynamic.")] + [Usage("UnfreezeWorld")] + [Description("Makes every static item on all maps dynamic.")] public static void UnfreezeWorld_OnCommand(CommandEventArgs e) { SendWarning( diff --git a/Projects/UOContent/Commands/VisibilityList.cs b/Projects/UOContent/Commands/VisibilityList.cs index cea19640d..ee871d3dc 100644 --- a/Projects/UOContent/Commands/VisibilityList.cs +++ b/Projects/UOContent/Commands/VisibilityList.cs @@ -22,9 +22,8 @@ namespace Server.Commands (m as PlayerMobile)?.VisibilityList.Clear(); } - [Usage("Vis"), Description( - "Adds or removes a targeted player from your visibility list. Anyone on your visibility list will be able to see you at all times, even when you're hidden." - )] + [Usage("Vis")] + [Description("Adds or removes a targeted player from your visibility list. Anyone on your visibility list will be able to see you at all times, even when you're hidden.")] public static void Vis_OnCommand(CommandEventArgs e) { if (e.Mobile is PlayerMobile) @@ -34,7 +33,8 @@ namespace Server.Commands } } - [Usage("VisList"), Description("Shows the names of everyone in your visibility list.")] + [Usage("VisList")] + [Description("Shows the names of everyone in your visibility list.")] public static void VisList_OnCommand(CommandEventArgs e) { if (e.Mobile is PlayerMobile pm) @@ -57,7 +57,8 @@ namespace Server.Commands } } - [Usage("VisClear"), Description("Removes everyone from your visibility list.")] + [Usage("VisClear")] + [Description("Removes everyone from your visibility list.")] public static void VisClear_OnCommand(CommandEventArgs e) { if (e.Mobile is PlayerMobile pm) diff --git a/Projects/UOContent/Commands/Wipe.cs b/Projects/UOContent/Commands/Wipe.cs index bc066fbde..806ad6a61 100644 --- a/Projects/UOContent/Commands/Wipe.cs +++ b/Projects/UOContent/Commands/Wipe.cs @@ -24,25 +24,29 @@ namespace Server.Commands CommandSystem.Register("WipeMultis", AccessLevel.GameMaster, WipeMultis_OnCommand); } - [Usage("Wipe"), Description("Wipes all items and npcs in a targeted bounding box.")] + [Usage("Wipe")] + [Description("Wipes all items and npcs in a targeted bounding box.")] private static void WipeAll_OnCommand(CommandEventArgs e) { BeginWipe(e.Mobile, WipeType.Items | WipeType.Mobiles); } - [Usage("WipeItems"), Description("Wipes all items in a targeted bounding box.")] + [Usage("WipeItems")] + [Description("Wipes all items in a targeted bounding box.")] private static void WipeItems_OnCommand(CommandEventArgs e) { BeginWipe(e.Mobile, WipeType.Items); } - [Usage("WipeNPCs"), Description("Wipes all npcs in a targeted bounding box.")] + [Usage("WipeNPCs")] + [Description("Wipes all npcs in a targeted bounding box.")] private static void WipeNPCs_OnCommand(CommandEventArgs e) { BeginWipe(e.Mobile, WipeType.Mobiles); } - [Usage("WipeMultis"), Description("Wipes all multis in a targeted bounding box.")] + [Usage("WipeMultis")] + [Description("Wipes all multis in a targeted bounding box.")] private static void WipeMultis_OnCommand(CommandEventArgs e) { BeginWipe(e.Mobile, WipeType.Multis); From 48232829add0268f18ecc0bf9560ba694e2fdadd Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Mon, 27 Dec 2021 01:41:35 -0800 Subject: [PATCH 047/213] fix: Reset body hue and facial hair (#896) --- Projects/UOContent/Commands/ResetStaffDress.cs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Projects/UOContent/Commands/ResetStaffDress.cs b/Projects/UOContent/Commands/ResetStaffDress.cs index 4ca756b84..3d78b2649 100644 --- a/Projects/UOContent/Commands/ResetStaffDress.cs +++ b/Projects/UOContent/Commands/ResetStaffDress.cs @@ -33,9 +33,11 @@ public static class StaffDress return; } + pm.Race = Race.Human; pm.Karma = pm.Fame = pm.Kills = pm.ShortTermMurders = pm.BodyMod = 0; pm.Body = 987; pm.SolidHueOverride = pm.HueMod = -1; + pm.FacialHairItemID = 0; pm.Blessed = true; pm.DisplayGuildTitle = false; pm.DisplayChampionTitle = false; @@ -47,13 +49,22 @@ public static class StaffDress pm.NetState.SendSpeedControl(SpeedControlSetting.Mount); pm.ResetStaffAccess(); + if (pm.AccessLevel < AccessLevel.Administrator) + { + pm.Hue = Race.Human.ClipSkinHue(pm.Hue & 0x3FFF); + } + for (var i = pm.Items.Count - 1; i >= 0; i--) { var item = pm.Items[i]; + if (item.Layer is Layer.FacialHair) + { + item.Delete(); + } + if (item.Layer is not Layer.Backpack and not Layer.Bank - and not Layer.FacialHair and not Layer.Hair and not Layer.Mount and not Layer.ShopBuy From a87aab19d09f505a7d496f55a9bde00bcb2820cd Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Mon, 27 Dec 2021 01:45:13 -0800 Subject: [PATCH 048/213] fix: Fixes setting body hue for resetstaffdress (#897) --- Projects/UOContent/Commands/ResetStaffDress.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Projects/UOContent/Commands/ResetStaffDress.cs b/Projects/UOContent/Commands/ResetStaffDress.cs index 3d78b2649..cd94e0350 100644 --- a/Projects/UOContent/Commands/ResetStaffDress.cs +++ b/Projects/UOContent/Commands/ResetStaffDress.cs @@ -51,7 +51,7 @@ public static class StaffDress if (pm.AccessLevel < AccessLevel.Administrator) { - pm.Hue = Race.Human.ClipSkinHue(pm.Hue & 0x3FFF); + pm.Hue = Race.Human.ClipSkinHue((pm.Hue + 1) & 0x3FFF); } for (var i = pm.Items.Count - 1; i >= 0; i--) From 93f09ba8312f835b41cdf923808a0430cff0c595 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Mon, 27 Dec 2021 17:17:45 -0800 Subject: [PATCH 049/213] fix: Fixes account gold settings (#898) --- Projects/Server/Items/SecureTradeContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Projects/Server/Items/SecureTradeContainer.cs b/Projects/Server/Items/SecureTradeContainer.cs index 2cc4f39c9..3c28e8089 100644 --- a/Projects/Server/Items/SecureTradeContainer.cs +++ b/Projects/Server/Items/SecureTradeContainer.cs @@ -93,7 +93,7 @@ namespace Server.Items public override bool IsChildVisibleTo(Mobile m, Item child) => child is VirtualCheck - ? !AccountGold.Enabled || m.NetState?.NewSecureTrading != true + ? AccountGold.Enabled && m.NetState is not { NewSecureTrading: true } : base.IsChildVisibleTo(m, child); public override void Serialize(IGenericWriter writer) From dc6caf576629155fcd602c7882e3850ac68e59b1 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Mon, 27 Dec 2021 19:38:03 -0800 Subject: [PATCH 050/213] fix: Fixes setting staff access (#899) --- Projects/UOContent/Commands/StaffAccess.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Projects/UOContent/Commands/StaffAccess.cs b/Projects/UOContent/Commands/StaffAccess.cs index 47ff71daa..b853de0e5 100644 --- a/Projects/UOContent/Commands/StaffAccess.cs +++ b/Projects/UOContent/Commands/StaffAccess.cs @@ -83,7 +83,7 @@ public static class StaffAccess m.SendMessage("Restoring original staff access..."); } - if (newAccessLevel > m.AccessLevel) + if ((originalAccessLevel ?? m.AccessLevel) < newAccessLevel) { m.SendMessage($"You cannot set your staff access to {newAccessLevel.ToString()}."); return; From 79dc9fa0f713b339c1011f4bc4dd1371b6ff0785 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Tue, 28 Dec 2021 02:09:25 -0800 Subject: [PATCH 051/213] fix: Fixes snooping staff (#900) * Not allowed to snoop staff * Staff that snoop won't broadcast messages * Benchmarks RNG for double vs fixed int --- .../Benchmarks/Rng/BenchmarkDoubleVsFixed.cs | 28 ++++ Projects/Benchmarks/Program.cs | 3 +- Projects/UOContent/Skills/Snooping.cs | 123 +++++++++--------- 3 files changed, 88 insertions(+), 66 deletions(-) create mode 100644 Projects/Benchmarks/Benchmarks/Rng/BenchmarkDoubleVsFixed.cs diff --git a/Projects/Benchmarks/Benchmarks/Rng/BenchmarkDoubleVsFixed.cs b/Projects/Benchmarks/Benchmarks/Rng/BenchmarkDoubleVsFixed.cs new file mode 100644 index 000000000..53b079cb5 --- /dev/null +++ b/Projects/Benchmarks/Benchmarks/Rng/BenchmarkDoubleVsFixed.cs @@ -0,0 +1,28 @@ +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Jobs; +using Server.Random; + +namespace Benchmarks.Benchmarks.Rng +{ + [MemoryDiagnoser] + [SimpleJob(RuntimeMoniker.Net60)] + public class BenchmarkDoubleVsFixed + { + private Xoshiro256PlusPlus _xoshiro256PlusPlus; + + [GlobalSetup] + public void Setup() + { + _xoshiro256PlusPlus = new Xoshiro256PlusPlus(); + } + + [Benchmark] + public bool NextDouble() => 50.1 < _xoshiro256PlusPlus.NextDouble() * 100; + + [Benchmark] + public bool NextFixedInt() => 501 < _xoshiro256PlusPlus.Next(1000); + + [Benchmark] + public bool NextHighResDouble() => 50.1 < _xoshiro256PlusPlus.NextDoubleHighRes() * 100; + } +} diff --git a/Projects/Benchmarks/Program.cs b/Projects/Benchmarks/Program.cs index 845354d56..4b5671c0f 100644 --- a/Projects/Benchmarks/Program.cs +++ b/Projects/Benchmarks/Program.cs @@ -15,7 +15,8 @@ namespace Benchmarks // var textEncoding = BenchmarkRunner.Run(); // var logging = BenchmarkRunner.Run(); // var gumpPacket = BenchmarkRunner.Run(); - var rngTest = BenchmarkRunner.Run(); + // var rngTest = BenchmarkRunner.Run(); + var doubleRngText = BenchmarkRunner.Run(); } } } diff --git a/Projects/UOContent/Skills/Snooping.cs b/Projects/UOContent/Skills/Snooping.cs index 73b03bffc..58b28ee24 100644 --- a/Projects/UOContent/Skills/Snooping.cs +++ b/Projects/UOContent/Skills/Snooping.cs @@ -3,68 +3,64 @@ using Server.Misc; using Server.Mobiles; using Server.Regions; -namespace Server.SkillHandlers +namespace Server.SkillHandlers; + +public static class Snooping { - public static class Snooping + public static void Configure() { - public static void Configure() + Container.SnoopHandler = Container_Snoop; + } + + public static bool CheckSnoopAllowed(Mobile from, Mobile to) + { + var map = from.Map; + + if (to.Player) { - Container.SnoopHandler = Container_Snoop; + return from.CanBeHarmful(to, false, true); // normal restrictions } - public static bool CheckSnoopAllowed(Mobile from, Mobile to) + if ((map?.Rules & MapRules.HarmfulRestrictions) == 0) { - var map = from.Map; - - if (to.Player) - { - return from.CanBeHarmful(to, false, true); // normal restrictions - } - - if ((map?.Rules & MapRules.HarmfulRestrictions) == 0) - { - return true; // felucca you can snoop anybody - } - - var reg = to.Region.GetRegion(); - - if (reg?.IsDisabled() != true) - { - return true; // not in town? we can snoop any npc - } - - return !to.Body.IsHuman || to is BaseCreature cret && (cret.AlwaysAttackable || cret.AlwaysMurderer); + return true; // felucca you can snoop anybody } - public static void Container_Snoop(Container cont, Mobile from) + var reg = to.Region.GetRegion(); + + if (reg?.IsDisabled() != true) { - if (from.AccessLevel <= AccessLevel.Player && !from.InRange(cont.GetWorldLocation(), 1)) - { - from.SendLocalizedMessage(500446); // That is too far away. - return; - } + return true; // not in town? we can snoop any npc + } - var root = cont.RootParent as Mobile; + return !to.Body.IsHuman || to is BaseCreature cret && (cret.AlwaysAttackable || cret.AlwaysMurderer); + } - if (root?.Alive == false) - { - return; - } + public static void Container_Snoop(Container cont, Mobile from) + { + if (from.AccessLevel <= AccessLevel.Player && !from.InRange(cont.GetWorldLocation(), 1)) + { + from.SendLocalizedMessage(500446); // That is too far away. + return; + } - if (root?.AccessLevel > AccessLevel.Player && from.AccessLevel == AccessLevel.Player) - { - from.SendLocalizedMessage(500209); // You can not peek into the container. - return; - } + var root = cont.RootParent as Mobile; - if (root?.AccessLevel == AccessLevel.Player && !CheckSnoopAllowed(from, root)) - { - from.SendLocalizedMessage(1001018); // You cannot perform negative acts on your target. - return; - } + if (root?.Alive == false) + { + return; + } - if (root?.AccessLevel == AccessLevel.Player && - from.Skills.Snooping.Value < Utility.Random(100)) + if (root?.AccessLevel > AccessLevel.Player || !CheckSnoopAllowed(from, root)) + { + from.SendLocalizedMessage(1001018); // You cannot perform negative acts on your target. + return; + } + + if (from.AccessLevel == AccessLevel.Player) + { + var snooping = from.Skills.Snooping.Value; + if (root != null && snooping < 100.0 && snooping < Utility.RandomDouble() * 100) { var map = from.Map; @@ -86,28 +82,25 @@ namespace Server.SkillHandlers } } - if (from.AccessLevel == AccessLevel.Player) + Titles.AwardKarma(from, -4, true); + } + + if (from.AccessLevel > AccessLevel.Player || from.CheckTargetSkill(SkillName.Snooping, cont, 0.0, 100.0)) + { + if ((cont as TrappableContainer)?.ExecuteTrap(from) == true) { - Titles.AwardKarma(from, -4, true); + return; } - if (from.AccessLevel > AccessLevel.Player || from.CheckTargetSkill(SkillName.Snooping, cont, 0.0, 100.0)) - { - if (cont is TrappableContainer container && container.ExecuteTrap(from)) - { - return; - } + cont.DisplayTo(from); + } + else + { + from.SendLocalizedMessage(500210); // You failed to peek into the container. - cont.DisplayTo(from); - } - else + if (from.Skills.Hiding.Value / 2 < Utility.RandomDouble() * 100) { - from.SendLocalizedMessage(500210); // You failed to peek into the container. - - if (from.Skills.Hiding.Value / 2 < Utility.Random(100)) - { - from.RevealingAction(); - } + from.RevealingAction(); } } } From d0aa6320f75b597c87f890f8a1101588da21170e Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Tue, 28 Dec 2021 02:42:36 -0800 Subject: [PATCH 052/213] feat: Adds instahit option (#901) Enable instahit by adding the setting `"melee.enableInstaHit": "True"` to modernuo.json --- .../UOContent/Items/Weapons/BaseWeapon.cs | 86 +++++++++++-------- 1 file changed, 48 insertions(+), 38 deletions(-) diff --git a/Projects/UOContent/Items/Weapons/BaseWeapon.cs b/Projects/UOContent/Items/Weapons/BaseWeapon.cs index 055c23e8d..2b7b4fd06 100644 --- a/Projects/UOContent/Items/Weapons/BaseWeapon.cs +++ b/Projects/UOContent/Items/Weapons/BaseWeapon.cs @@ -25,6 +25,13 @@ namespace Server.Items public abstract class BaseWeapon : Item, IWeapon, IFactionItem, ICraftable, ISlayer, IDurability { + private static bool _enableInstaHit; + + public static void Configure() + { + _enableInstaHit = ServerConfiguration.GetSetting("melee.enableInstaHit", !Core.UOR); + } + private WeaponAccuracyLevel m_AccuracyLevel; private WeaponAnimation m_Animation; private Mobile m_Crafter; @@ -950,7 +957,10 @@ namespace Server.Items } } - from.NextCombatTime = Core.TickCount + (int)GetDelay(from).TotalMilliseconds; + if (!_enableInstaHit) + { + from.NextCombatTime = Core.TickCount + (int)GetDelay(from).TotalMilliseconds; + } if (UseSkillMod && m_AccuracyLevel != WeaponAccuracyLevel.Regular) { @@ -989,45 +999,45 @@ namespace Server.Items public override void OnRemoved(IEntity parent) { - if (parent is Mobile m) + if (parent is not Mobile m) { - var weapon = m.Weapon as BaseWeapon; - - var modName = Serial.ToString(); - - m.RemoveStatMod($"{modName}Str"); - m.RemoveStatMod($"{modName}Dex"); - m.RemoveStatMod($"{modName}Int"); - - if (weapon != null) - { - m.NextCombatTime = Core.TickCount + (int)weapon.GetDelay(m).TotalMilliseconds; - } - - if (UseSkillMod && m_SkillMod != null) - { - m_SkillMod.Remove(); - m_SkillMod = null; - } - - if (m_MageMod != null) - { - m_MageMod.Remove(); - m_MageMod = null; - } - - if (Core.AOS) - { - SkillBonuses.Remove(); - } - - ImmolatingWeaponSpell.StopImmolating(this); - ForceOfNature.Remove(m); - - m.CheckStatTimers(); - - m.Delta(MobileDelta.WeaponDamage); + return; } + + var modName = Serial.ToString(); + + m.RemoveStatMod($"{modName}Str"); + m.RemoveStatMod($"{modName}Dex"); + m.RemoveStatMod($"{modName}Int"); + + if (!_enableInstaHit && m.Weapon is BaseWeapon weapon) + { + m.NextCombatTime = Core.TickCount + (long)weapon.GetDelay(m).TotalMilliseconds; + } + + if (UseSkillMod && m_SkillMod != null) + { + m_SkillMod.Remove(); + m_SkillMod = null; + } + + if (m_MageMod != null) + { + m_MageMod.Remove(); + m_MageMod = null; + } + + if (Core.AOS) + { + SkillBonuses.Remove(); + } + + ImmolatingWeaponSpell.StopImmolating(this); + ForceOfNature.Remove(m); + + m.CheckStatTimers(); + + m.Delta(MobileDelta.WeaponDamage); } public virtual SkillName GetUsedSkill(Mobile m, bool checkSkillAttrs) From 5019ce9694997300d8ce004f64fb7dec94618499 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Tue, 28 Dec 2021 13:48:48 -0800 Subject: [PATCH 053/213] fix: Fixes timer migrations not compiling (#902) --- ...alizationEntityGeneration.ContentStruct.cs | 15 +- .../ISerializableMigrationRule.cs | 10 +- .../Rules/ArrayMigrationRule.cs | 205 ++++----- .../Rules/DictionaryMigrationRule.cs | 431 +++++++++--------- .../Rules/EnumMigrationRule.cs | 79 ++-- .../Rules/HashSetMigrationRule.cs | 273 +++++------ .../Rules/KeyValuePairMigrationRule.cs | 383 ++++++++-------- .../Rules/ListMigrationRule.cs | 275 +++++------ .../Rules/MigrationRule.cs | 36 ++ .../Rules/PrimitiveTypeMigrationRule.cs | 223 ++++----- .../Rules/PrimitiveUOTypeMigrationRule.cs | 95 ++-- .../Rules/RawSerializableMigrationRule.cs | 97 ++-- .../SerializableInterfaceMigrationRule.cs | 83 ++-- ...rializationMethodSignatureMigrationRule.cs | 103 ++--- .../Rules/TimerMigrationRule.cs | 174 +++---- 15 files changed, 1273 insertions(+), 1209 deletions(-) create mode 100644 Projects/SerializationGenerator/SerializableMigration/Rules/MigrationRule.cs diff --git a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializationEntityGeneration.ContentStruct.cs b/Projects/SerializationGenerator/SerializableEntityGeneration/SerializationEntityGeneration.ContentStruct.cs index 7e664920e..56544ed60 100644 --- a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializationEntityGeneration.ContentStruct.cs +++ b/Projects/SerializationGenerator/SerializableEntityGeneration/SerializationEntityGeneration.ContentStruct.cs @@ -37,12 +37,9 @@ namespace SerializationGenerator foreach (var serializableProperty in properties) { - var propertyType = serializableProperty.Type; - var type = compilation.GetTypeByMetadataName(propertyType)?.IsValueType == true - || SymbolMetadata.IsPrimitiveFromTypeDisplayString(propertyType) && propertyType != "bool" - ? $"{propertyType}{(serializableProperty.UsesSaveFlag == true ? "?" : "")}" : propertyType; - - source.AppendLine($"{indent} internal readonly {type} {serializableProperty.Name};"); + SerializableMigrationRulesEngine.Rules[serializableProperty.Rule].GenerateMigrationProperty( + source, compilation, $"{indent} ", serializableProperty + ); } var innerIndent = $"{indent} "; @@ -100,7 +97,8 @@ namespace SerializationGenerator source, $"{innerIndent} ", property, - "entity" + "entity", + true ); source.AppendLine($"{innerIndent}}}\n{innerIndent}else\n{innerIndent}{{"); @@ -114,7 +112,8 @@ namespace SerializationGenerator source, innerIndent, property, - "entity" + "entity", + true ); } } diff --git a/Projects/SerializationGenerator/SerializableMigration/ISerializableMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/ISerializableMigrationRule.cs index 1f944c4fa..a64453e33 100644 --- a/Projects/SerializationGenerator/SerializableMigration/ISerializableMigrationRule.cs +++ b/Projects/SerializationGenerator/SerializableMigration/ISerializableMigrationRule.cs @@ -23,6 +23,13 @@ namespace SerializableMigration { string RuleName { get; } + void GenerateMigrationProperty( + StringBuilder source, + Compilation compilation, + string indent, + SerializableProperty serializableProperty + ); + bool GenerateRuleState( Compilation compilation, ISymbol symbol, @@ -37,7 +44,8 @@ namespace SerializableMigration StringBuilder source, string indent, SerializableProperty property, - string? parentReference + string? parentReference, + bool isMigration = false ); void GenerateSerializationMethod( diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/ArrayMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/ArrayMigrationRule.cs index 54b63cc1c..99a1e911e 100644 --- a/Projects/SerializationGenerator/SerializableMigration/Rules/ArrayMigrationRule.cs +++ b/Projects/SerializationGenerator/SerializableMigration/Rules/ArrayMigrationRule.cs @@ -18,117 +18,118 @@ using System.Collections.Immutable; using System.Text; using Microsoft.CodeAnalysis; -namespace SerializableMigration +namespace SerializableMigration; + +public class ArrayMigrationRule : MigrationRule { - public class ArrayMigrationRule : ISerializableMigrationRule + public override string RuleName => nameof(ArrayMigrationRule); + + public override bool GenerateRuleState( + Compilation compilation, + ISymbol symbol, + ImmutableArray attributes, + ImmutableArray serializableTypes, + ImmutableArray embeddedSerializableTypes, + ISymbol? parentSymbol, + out string[] ruleArguments + ) { - public string RuleName => nameof(ArrayMigrationRule); - - public bool GenerateRuleState( - Compilation compilation, - ISymbol symbol, - ImmutableArray attributes, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes, - ISymbol? parentSymbol, - out string[] ruleArguments - ) + if (symbol is not IArrayTypeSymbol arrayTypeSymbol) { - if (symbol is not IArrayTypeSymbol arrayTypeSymbol) - { - ruleArguments = null; - return false; - } - - var serializableArrayType = SerializableMigrationRulesEngine.GenerateSerializableProperty( - compilation, - "ArrayEntry", - arrayTypeSymbol.ElementType, - 0, - attributes, - serializableTypes, - embeddedSerializableTypes, - parentSymbol, - null - ); - - var length = serializableArrayType.RuleArguments?.Length?? 0; - ruleArguments = new string[length + 2]; - ruleArguments[0] = arrayTypeSymbol.ElementType.ToDisplayString(); - ruleArguments[1] = serializableArrayType.Rule; - if (length > 0) - { - Array.Copy(serializableArrayType.RuleArguments!, 0, ruleArguments, 2, length); - } - - return true; + ruleArguments = null; + return false; } - public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference) + var serializableArrayType = SerializableMigrationRulesEngine.GenerateSerializableProperty( + compilation, + "ArrayEntry", + arrayTypeSymbol.ElementType, + 0, + attributes, + serializableTypes, + embeddedSerializableTypes, + parentSymbol, + null + ); + + var length = serializableArrayType.RuleArguments?.Length?? 0; + ruleArguments = new string[length + 2]; + ruleArguments[0] = arrayTypeSymbol.ElementType.ToDisplayString(); + ruleArguments[1] = serializableArrayType.Rule; + if (length > 0) { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } - var ruleArguments = property.RuleArguments; - var arrayElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments![1]]; - var arrayElementRuleArguments = new string[ruleArguments.Length - 2]; - Array.Copy(ruleArguments, 2, arrayElementRuleArguments, 0, ruleArguments.Length - 2); - - var propertyIndex = $"{property.Name}Index"; - source.AppendLine($"{indent}{property.Name} = new {ruleArguments[0]}[reader.ReadEncodedInt()];"); - source.AppendLine($"{indent}for (var {propertyIndex} = 0; {propertyIndex} < {property.Name}.Length; {propertyIndex}++)"); - source.AppendLine($"{indent}{{"); - - var serializableArrayElement = new SerializableProperty - { - Name = $"{property.Name}[{propertyIndex}]", - Type = ruleArguments[0], - Rule = arrayElementRule.RuleName, - RuleArguments = arrayElementRuleArguments - }; - - arrayElementRule.GenerateDeserializationMethod(source, $"{indent} ", serializableArrayElement, parentReference); - - source.AppendLine($"{indent}}}"); + Array.Copy(serializableArrayType.RuleArguments!, 0, ruleArguments, 2, length); } - public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property) + return true; + } + + public override void GenerateDeserializationMethod( + StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false + ) + { + var expectedRule = RuleName; + var ruleName = property.Rule; + if (expectedRule != ruleName) { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } - - var ruleArguments = property.RuleArguments; - var arrayElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments![1]]; - var arrayElementRuleArguments = new string[ruleArguments.Length - 2]; - Array.Copy(ruleArguments, 2, arrayElementRuleArguments, 0, ruleArguments.Length - 2); - - var propertyName = property.Name; - var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}"; - var propertyIndex = $"{propertyVarPrefix}Index"; - var propertyLength = $"{propertyVarPrefix}Length"; - source.AppendLine($"{indent}var {propertyLength} = {property.Name}?.Length ?? 0;"); - source.AppendLine($"{indent}writer.WriteEncodedInt({propertyLength});"); - source.AppendLine($"{indent}for (var {propertyIndex} = 0; {propertyIndex} < {propertyLength}; {propertyIndex}++)"); - source.AppendLine($"{indent}{{"); - - var serializableArrayElement = new SerializableProperty - { - Name = $"{property.Name}![{propertyIndex}]", - Type = ruleArguments[0], - Rule = arrayElementRule.RuleName, - RuleArguments = arrayElementRuleArguments - }; - - arrayElementRule.GenerateSerializationMethod(source, $"{indent} ", serializableArrayElement); - - source.AppendLine($"{indent}}}"); + throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); } + var ruleArguments = property.RuleArguments; + var arrayElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments![1]]; + var arrayElementRuleArguments = new string[ruleArguments.Length - 2]; + Array.Copy(ruleArguments, 2, arrayElementRuleArguments, 0, ruleArguments.Length - 2); + + var propertyIndex = $"{property.Name}Index"; + source.AppendLine($"{indent}{property.Name} = new {ruleArguments[0]}[reader.ReadEncodedInt()];"); + source.AppendLine($"{indent}for (var {propertyIndex} = 0; {propertyIndex} < {property.Name}.Length; {propertyIndex}++)"); + source.AppendLine($"{indent}{{"); + + var serializableArrayElement = new SerializableProperty + { + Name = $"{property.Name}[{propertyIndex}]", + Type = ruleArguments[0], + Rule = arrayElementRule.RuleName, + RuleArguments = arrayElementRuleArguments + }; + + arrayElementRule.GenerateDeserializationMethod(source, $"{indent} ", serializableArrayElement, parentReference); + + source.AppendLine($"{indent}}}"); + } + + public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property) + { + var expectedRule = RuleName; + var ruleName = property.Rule; + if (expectedRule != ruleName) + { + throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); + } + + var ruleArguments = property.RuleArguments; + var arrayElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments![1]]; + var arrayElementRuleArguments = new string[ruleArguments.Length - 2]; + Array.Copy(ruleArguments, 2, arrayElementRuleArguments, 0, ruleArguments.Length - 2); + + var propertyName = property.Name; + var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}"; + var propertyIndex = $"{propertyVarPrefix}Index"; + var propertyLength = $"{propertyVarPrefix}Length"; + source.AppendLine($"{indent}var {propertyLength} = {property.Name}?.Length ?? 0;"); + source.AppendLine($"{indent}writer.WriteEncodedInt({propertyLength});"); + source.AppendLine($"{indent}for (var {propertyIndex} = 0; {propertyIndex} < {propertyLength}; {propertyIndex}++)"); + source.AppendLine($"{indent}{{"); + + var serializableArrayElement = new SerializableProperty + { + Name = $"{property.Name}![{propertyIndex}]", + Type = ruleArguments[0], + Rule = arrayElementRule.RuleName, + RuleArguments = arrayElementRuleArguments + }; + + arrayElementRule.GenerateSerializationMethod(source, $"{indent} ", serializableArrayElement); + + source.AppendLine($"{indent}}}"); } } diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/DictionaryMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/DictionaryMigrationRule.cs index 309e4c461..caf0d1dc8 100644 --- a/Projects/SerializationGenerator/SerializableMigration/Rules/DictionaryMigrationRule.cs +++ b/Projects/SerializationGenerator/SerializableMigration/Rules/DictionaryMigrationRule.cs @@ -20,230 +20,231 @@ using System.Text; using Microsoft.CodeAnalysis; using SerializationGenerator; -namespace SerializableMigration +namespace SerializableMigration; + +public class DictionaryMigrationRule : MigrationRule { - public class DictionaryMigrationRule : ISerializableMigrationRule + public override string RuleName => nameof(DictionaryMigrationRule); + + public override bool GenerateRuleState( + Compilation compilation, + ISymbol symbol, + ImmutableArray attributes, + ImmutableArray serializableTypes, + ImmutableArray embeddedSerializableTypes, + ISymbol? parentSymbol, + out string[] ruleArguments + ) { - public string RuleName => nameof(DictionaryMigrationRule); - - public bool GenerateRuleState( - Compilation compilation, - ISymbol symbol, - ImmutableArray attributes, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes, - ISymbol? parentSymbol, - out string[] ruleArguments - ) + if (symbol is not INamedTypeSymbol namedTypeSymbol || !symbol.IsDictionary(compilation)) { - if (symbol is not INamedTypeSymbol namedTypeSymbol || !symbol.IsDictionary(compilation)) - { - ruleArguments = null; - return false; - } - - var keySymbolType = namedTypeSymbol.TypeArguments[0]; - - var serializableKeyProperty = SerializableMigrationRulesEngine.GenerateSerializableProperty( - compilation, - "KeyEntry", - keySymbolType, - 0, - attributes, - serializableTypes, - embeddedSerializableTypes, - parentSymbol, - null - ); - - var valueSymbolType = namedTypeSymbol.TypeArguments[1]; - - var serializableValueProperty = SerializableMigrationRulesEngine.GenerateSerializableProperty( - compilation, - "ValueEntry", - valueSymbolType, - 0, - attributes, - serializableTypes, - embeddedSerializableTypes, - parentSymbol, - null - ); - - var extraOptions = ""; - if (attributes.Any(a => a.IsTidy(compilation))) - { - extraOptions += "@Tidy"; - } - - var keyArgumentsLength = serializableKeyProperty.RuleArguments?.Length ?? 0; - var valueArgumentsLength = serializableValueProperty.RuleArguments?.Length ?? 0; - var index = 0; - - ruleArguments = new string[7 + keyArgumentsLength + valueArgumentsLength]; - ruleArguments[index++] = extraOptions; - ruleArguments[index++] = keySymbolType.ToDisplayString(); - ruleArguments[index++] = serializableKeyProperty.Rule; - ruleArguments[index++] = keyArgumentsLength.ToString(); - - if (keyArgumentsLength > 0) - { - Array.Copy(serializableKeyProperty.RuleArguments!, 0, ruleArguments, index, keyArgumentsLength); - index += keyArgumentsLength; - } - - ruleArguments[index++] = valueSymbolType.ToDisplayString(); - ruleArguments[index++] = serializableValueProperty.Rule; - ruleArguments[index++] = valueArgumentsLength.ToString(); - - if (valueArgumentsLength > 0) - { - Array.Copy(serializableValueProperty.RuleArguments!, 0, ruleArguments, index, valueArgumentsLength); - } - - return true; + ruleArguments = null; + return false; } - public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference) + var keySymbolType = namedTypeSymbol.TypeArguments[0]; + + var serializableKeyProperty = SerializableMigrationRulesEngine.GenerateSerializableProperty( + compilation, + "KeyEntry", + keySymbolType, + 0, + attributes, + serializableTypes, + embeddedSerializableTypes, + parentSymbol, + null + ); + + var valueSymbolType = namedTypeSymbol.TypeArguments[1]; + + var serializableValueProperty = SerializableMigrationRulesEngine.GenerateSerializableProperty( + compilation, + "ValueEntry", + valueSymbolType, + 0, + attributes, + serializableTypes, + embeddedSerializableTypes, + parentSymbol, + null + ); + + var extraOptions = ""; + if (attributes.Any(a => a.IsTidy(compilation))) { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } - - var ruleArguments = property.RuleArguments; - var index = 1; - var keyType = ruleArguments![index++]; - - var keyElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]]; - var keyRuleArguments = new string[int.Parse(ruleArguments[index++])]; - - if (keyRuleArguments.Length > 0) - { - Array.Copy(ruleArguments, index, keyRuleArguments, 0, keyRuleArguments.Length); - index += keyRuleArguments.Length; - } - - var valueType = ruleArguments[index++]; - var valueElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]]; - var valueRuleArguments = new string[int.Parse(ruleArguments[index++])]; - - if (valueRuleArguments.Length > 0) - { - Array.Copy(ruleArguments, index, valueRuleArguments, 0, valueRuleArguments.Length); - } - - var propertyName = property.Name; - var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}"; - var propertyIndex = $"{propertyVarPrefix}Index"; - var propertyKeyEntry = $"{propertyVarPrefix}Key"; - var propertyValueEntry = $"{propertyVarPrefix}Value"; - var propertyCount = $"{propertyVarPrefix}Count"; - - source.AppendLine($"{indent}{ruleArguments[1]} {propertyKeyEntry};"); - source.AppendLine($"{indent}{valueType} {propertyValueEntry};"); - source.AppendLine($"{indent}var {propertyCount} = reader.ReadEncodedInt();"); - source.AppendLine($"{indent}{propertyName} = new System.Collections.Generic.Dictionary<{keyType}, {valueType}>({propertyCount});"); - source.AppendLine($"{indent}for (var {propertyIndex} = 0; {propertyIndex} < {propertyCount}; {propertyIndex}++)"); - source.AppendLine($"{indent}{{"); - - var serializableKeyElement = new SerializableProperty - { - Name = propertyKeyEntry, - Type = keyType, - Rule = keyElementRule.RuleName, - RuleArguments = keyRuleArguments - }; - - keyElementRule.GenerateDeserializationMethod(source, $"{indent} ", serializableKeyElement, parentReference); - - var serializableValueElement = new SerializableProperty - { - Name = propertyValueEntry, - Type = valueType, - Rule = valueElementRule.RuleName, - RuleArguments = valueRuleArguments - }; - - valueElementRule.GenerateDeserializationMethod(source, $"{indent} ", serializableValueElement, parentReference); - source.AppendLine($"{indent} {propertyName}.Add({propertyKeyEntry}, {propertyValueEntry});"); - - source.AppendLine($"{indent}}}"); + extraOptions += "@Tidy"; } - public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property) + var keyArgumentsLength = serializableKeyProperty.RuleArguments?.Length ?? 0; + var valueArgumentsLength = serializableValueProperty.RuleArguments?.Length ?? 0; + var index = 0; + + ruleArguments = new string[7 + keyArgumentsLength + valueArgumentsLength]; + ruleArguments[index++] = extraOptions; + ruleArguments[index++] = keySymbolType.ToDisplayString(); + ruleArguments[index++] = serializableKeyProperty.Rule; + ruleArguments[index++] = keyArgumentsLength.ToString(); + + if (keyArgumentsLength > 0) { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } - - var ruleArguments = property.RuleArguments; - var index = 0; - var shouldTidy = ruleArguments![index++].Contains("@Tidy"); - var keyType = ruleArguments![index++]; - - var keyElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments![index++]]; - var keyRuleArguments = new string[int.Parse(ruleArguments[index++])]; - - if (keyRuleArguments.Length > 0) - { - Array.Copy(ruleArguments, index, keyRuleArguments, 0, keyRuleArguments.Length); - index += keyRuleArguments.Length; - } - - var valueType = ruleArguments[index++]; - var valueElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]]; - var valueRuleArguments = new string[int.Parse(ruleArguments[index++])]; - - if (valueRuleArguments.Length > 0) - { - Array.Copy(ruleArguments, index, valueRuleArguments, 0, valueRuleArguments.Length); - } - - var propertyName = property.Name; - var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}"; - var propertyKeyEntry = $"{propertyVarPrefix}Key"; - var propertyValueEntry = $"{propertyVarPrefix}Value"; - var propertyCount = $"{propertyVarPrefix}Count"; - - if (shouldTidy) - { - source.AppendLine($"{indent}{property.Name}?.Tidy();"); - } - source.AppendLine($"{indent}var {propertyCount} = {property.Name}?.Count ?? 0;"); - source.AppendLine($"{indent}writer.WriteEncodedInt({propertyCount});"); - source.AppendLine($"{indent}if ({propertyCount} > 0)"); - source.AppendLine($"{indent}{{"); - source.AppendLine($"{indent} foreach (var ({propertyKeyEntry}, {propertyValueEntry}) in {property.Name}!)"); - source.AppendLine($"{indent} {{"); - - var serializableKeyElement = new SerializableProperty - { - Name = propertyKeyEntry, - Type = keyType, - Rule = keyElementRule.RuleName, - RuleArguments = keyRuleArguments - }; - - keyElementRule.GenerateSerializationMethod(source, $"{indent} ", serializableKeyElement); - - var serializableValueElement = new SerializableProperty - { - Name = propertyValueEntry, - Type = valueType, - Rule = valueElementRule.RuleName, - RuleArguments = valueRuleArguments - }; - - valueElementRule.GenerateSerializationMethod(source, $"{indent} ", serializableValueElement); - - source.AppendLine($"{indent} }}"); - source.AppendLine($"{indent}}}"); + Array.Copy(serializableKeyProperty.RuleArguments!, 0, ruleArguments, index, keyArgumentsLength); + index += keyArgumentsLength; } + + ruleArguments[index++] = valueSymbolType.ToDisplayString(); + ruleArguments[index++] = serializableValueProperty.Rule; + ruleArguments[index++] = valueArgumentsLength.ToString(); + + if (valueArgumentsLength > 0) + { + Array.Copy(serializableValueProperty.RuleArguments!, 0, ruleArguments, index, valueArgumentsLength); + } + + return true; + } + + public override void GenerateDeserializationMethod( + StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false + ) + { + var expectedRule = RuleName; + var ruleName = property.Rule; + if (expectedRule != ruleName) + { + throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); + } + + var ruleArguments = property.RuleArguments; + var index = 1; + var keyType = ruleArguments![index++]; + + var keyElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]]; + var keyRuleArguments = new string[int.Parse(ruleArguments[index++])]; + + if (keyRuleArguments.Length > 0) + { + Array.Copy(ruleArguments, index, keyRuleArguments, 0, keyRuleArguments.Length); + index += keyRuleArguments.Length; + } + + var valueType = ruleArguments[index++]; + var valueElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]]; + var valueRuleArguments = new string[int.Parse(ruleArguments[index++])]; + + if (valueRuleArguments.Length > 0) + { + Array.Copy(ruleArguments, index, valueRuleArguments, 0, valueRuleArguments.Length); + } + + var propertyName = property.Name; + var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}"; + var propertyIndex = $"{propertyVarPrefix}Index"; + var propertyKeyEntry = $"{propertyVarPrefix}Key"; + var propertyValueEntry = $"{propertyVarPrefix}Value"; + var propertyCount = $"{propertyVarPrefix}Count"; + + source.AppendLine($"{indent}{ruleArguments[1]} {propertyKeyEntry};"); + source.AppendLine($"{indent}{valueType} {propertyValueEntry};"); + source.AppendLine($"{indent}var {propertyCount} = reader.ReadEncodedInt();"); + source.AppendLine($"{indent}{propertyName} = new System.Collections.Generic.Dictionary<{keyType}, {valueType}>({propertyCount});"); + source.AppendLine($"{indent}for (var {propertyIndex} = 0; {propertyIndex} < {propertyCount}; {propertyIndex}++)"); + source.AppendLine($"{indent}{{"); + + var serializableKeyElement = new SerializableProperty + { + Name = propertyKeyEntry, + Type = keyType, + Rule = keyElementRule.RuleName, + RuleArguments = keyRuleArguments + }; + + keyElementRule.GenerateDeserializationMethod(source, $"{indent} ", serializableKeyElement, parentReference); + + var serializableValueElement = new SerializableProperty + { + Name = propertyValueEntry, + Type = valueType, + Rule = valueElementRule.RuleName, + RuleArguments = valueRuleArguments + }; + + valueElementRule.GenerateDeserializationMethod(source, $"{indent} ", serializableValueElement, parentReference); + source.AppendLine($"{indent} {propertyName}.Add({propertyKeyEntry}, {propertyValueEntry});"); + + source.AppendLine($"{indent}}}"); + } + + public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property) + { + var expectedRule = RuleName; + var ruleName = property.Rule; + if (expectedRule != ruleName) + { + throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); + } + + var ruleArguments = property.RuleArguments; + var index = 0; + var shouldTidy = ruleArguments![index++].Contains("@Tidy"); + var keyType = ruleArguments![index++]; + + var keyElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments![index++]]; + var keyRuleArguments = new string[int.Parse(ruleArguments[index++])]; + + if (keyRuleArguments.Length > 0) + { + Array.Copy(ruleArguments, index, keyRuleArguments, 0, keyRuleArguments.Length); + index += keyRuleArguments.Length; + } + + var valueType = ruleArguments[index++]; + var valueElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]]; + var valueRuleArguments = new string[int.Parse(ruleArguments[index++])]; + + if (valueRuleArguments.Length > 0) + { + Array.Copy(ruleArguments, index, valueRuleArguments, 0, valueRuleArguments.Length); + } + + var propertyName = property.Name; + var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}"; + var propertyKeyEntry = $"{propertyVarPrefix}Key"; + var propertyValueEntry = $"{propertyVarPrefix}Value"; + var propertyCount = $"{propertyVarPrefix}Count"; + + if (shouldTidy) + { + source.AppendLine($"{indent}{property.Name}?.Tidy();"); + } + source.AppendLine($"{indent}var {propertyCount} = {property.Name}?.Count ?? 0;"); + source.AppendLine($"{indent}writer.WriteEncodedInt({propertyCount});"); + source.AppendLine($"{indent}if ({propertyCount} > 0)"); + source.AppendLine($"{indent}{{"); + source.AppendLine($"{indent} foreach (var ({propertyKeyEntry}, {propertyValueEntry}) in {property.Name}!)"); + source.AppendLine($"{indent} {{"); + + var serializableKeyElement = new SerializableProperty + { + Name = propertyKeyEntry, + Type = keyType, + Rule = keyElementRule.RuleName, + RuleArguments = keyRuleArguments + }; + + keyElementRule.GenerateSerializationMethod(source, $"{indent} ", serializableKeyElement); + + var serializableValueElement = new SerializableProperty + { + Name = propertyValueEntry, + Type = valueType, + Rule = valueElementRule.RuleName, + RuleArguments = valueRuleArguments + }; + + valueElementRule.GenerateSerializationMethod(source, $"{indent} ", serializableValueElement); + + source.AppendLine($"{indent} }}"); + source.AppendLine($"{indent}}}"); } } diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/EnumMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/EnumMigrationRule.cs index 18ebc3678..5e8d7fd45 100644 --- a/Projects/SerializationGenerator/SerializableMigration/Rules/EnumMigrationRule.cs +++ b/Projects/SerializationGenerator/SerializableMigration/Rules/EnumMigrationRule.cs @@ -19,54 +19,55 @@ using System.Text; using Microsoft.CodeAnalysis; using SerializationGenerator; -namespace SerializableMigration +namespace SerializableMigration; + +public class EnumMigrationRule : MigrationRule { - public class EnumMigrationRule : ISerializableMigrationRule + public override string RuleName => nameof(EnumMigrationRule); + + public override bool GenerateRuleState( + Compilation compilation, + ISymbol symbol, + ImmutableArray attributes, + ImmutableArray serializableTypes, + ImmutableArray embeddedSerializableTypes, + ISymbol? parentSymbol, + out string[] ruleArguments + ) { - public string RuleName => nameof(EnumMigrationRule); - - public bool GenerateRuleState( - Compilation compilation, - ISymbol symbol, - ImmutableArray attributes, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes, - ISymbol? parentSymbol, - out string[] ruleArguments - ) + if (symbol is not ITypeSymbol typeSymbol || !typeSymbol.IsEnum()) { - if (symbol is not ITypeSymbol typeSymbol || !typeSymbol.IsEnum()) - { - ruleArguments = null; - return false; - } - - ruleArguments = Array.Empty(); - return true; + ruleArguments = null; + return false; } - public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference) - { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } + ruleArguments = Array.Empty(); + return true; + } - source.AppendLine($"{indent}{property.Name} = reader.ReadEnum<{property.Type}>();"); + public override void GenerateDeserializationMethod( + StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false + ) + { + var expectedRule = RuleName; + var ruleName = property.Rule; + if (expectedRule != ruleName) + { + throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); } - public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property) - { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } + source.AppendLine($"{indent}{property.Name} = reader.ReadEnum<{property.Type}>();"); + } - source.AppendLine($"{indent}writer.WriteEnum<{property.Type}>({property.Name});"); + public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property) + { + var expectedRule = RuleName; + var ruleName = property.Rule; + if (expectedRule != ruleName) + { + throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); } + + source.AppendLine($"{indent}writer.WriteEnum<{property.Type}>({property.Name});"); } } diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/HashSetMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/HashSetMigrationRule.cs index d670ae01f..20fe03d08 100644 --- a/Projects/SerializationGenerator/SerializableMigration/Rules/HashSetMigrationRule.cs +++ b/Projects/SerializationGenerator/SerializableMigration/Rules/HashSetMigrationRule.cs @@ -20,151 +20,152 @@ using System.Text; using Microsoft.CodeAnalysis; using SerializationGenerator; -namespace SerializableMigration +namespace SerializableMigration; + +public class HashSetMigrationRule : MigrationRule { - public class HashSetMigrationRule : ISerializableMigrationRule + public override string RuleName => nameof(HashSetMigrationRule); + + public override bool GenerateRuleState( + Compilation compilation, + ISymbol symbol, + ImmutableArray attributes, + ImmutableArray serializableTypes, + ImmutableArray embeddedSerializableTypes, + ISymbol? parentSymbol, + out string[] ruleArguments + ) { - public string RuleName => nameof(HashSetMigrationRule); - - public bool GenerateRuleState( - Compilation compilation, - ISymbol symbol, - ImmutableArray attributes, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes, - ISymbol? parentSymbol, - out string[] ruleArguments - ) + if (symbol is not INamedTypeSymbol namedTypeSymbol || !symbol.IsHashSet(compilation)) { - if (symbol is not INamedTypeSymbol namedTypeSymbol || !symbol.IsHashSet(compilation)) - { - ruleArguments = null; - return false; - } - - var setTypeSymbol = namedTypeSymbol.TypeArguments[0]; - - var serializableSetType = SerializableMigrationRulesEngine.GenerateSerializableProperty( - compilation, - "SetEntry", - setTypeSymbol, - 0, - attributes, - serializableTypes, - embeddedSerializableTypes, - parentSymbol, - null - ); - - var extraOptions = ""; - if (attributes.Any(a => a.IsTidy(compilation))) - { - extraOptions += "@Tidy"; - } - - var length = serializableSetType.RuleArguments?.Length ?? 0; - ruleArguments = new string[length + 3]; - ruleArguments[0] = extraOptions; - ruleArguments[1] = setTypeSymbol.ToDisplayString(); - ruleArguments[2] = serializableSetType.Rule; - - if (length > 0) - { - Array.Copy(serializableSetType.RuleArguments, 0, ruleArguments, 3, length); - } - - return true; + ruleArguments = null; + return false; } - public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference) + var setTypeSymbol = namedTypeSymbol.TypeArguments[0]; + + var serializableSetType = SerializableMigrationRulesEngine.GenerateSerializableProperty( + compilation, + "SetEntry", + setTypeSymbol, + 0, + attributes, + serializableTypes, + embeddedSerializableTypes, + parentSymbol, + null + ); + + var extraOptions = ""; + if (attributes.Any(a => a.IsTidy(compilation))) { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } - - var ruleArguments = property.RuleArguments; - var hasExtraOptions = ruleArguments![0] == "" || ruleArguments[0].StartsWith("@", StringComparison.Ordinal); - var argumentsOffset = hasExtraOptions ? 1 : 0; - - var setElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[1 + argumentsOffset]]; - var setElementRuleArguments = new string[ruleArguments.Length - 2 - argumentsOffset]; - Array.Copy(ruleArguments, 2 + argumentsOffset, setElementRuleArguments, 0, ruleArguments.Length - 2 - argumentsOffset); - - var propertyName = property.Name; - var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}"; - var propertyIndex = $"{propertyVarPrefix}Index"; - var propertyEntry = $"{propertyVarPrefix}Entry"; - var propertyCount = $"{propertyVarPrefix}Count"; - - source.AppendLine($"{indent}{ruleArguments[argumentsOffset]} {propertyEntry};"); - source.AppendLine($"{indent}var {propertyCount} = reader.ReadEncodedInt();"); - source.AppendLine($"{indent}{property.Name} = new System.Collections.Generic.HashSet<{ruleArguments[argumentsOffset]}>({propertyCount});"); - source.AppendLine($"{indent}for (var {propertyIndex} = 0; {propertyIndex} < {propertyCount}; {propertyIndex}++)"); - source.AppendLine($"{indent}{{"); - - var serializableSetElement = new SerializableProperty - { - Name = propertyEntry, - Type = ruleArguments[argumentsOffset], - Rule = setElementRule.RuleName, - RuleArguments = setElementRuleArguments - }; - - setElementRule.GenerateDeserializationMethod(source, $"{indent} ", serializableSetElement, parentReference); - source.AppendLine($"{indent} {property.Name}.Add({propertyEntry});"); - - source.AppendLine($"{indent}}}"); + extraOptions += "@Tidy"; } - public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property) + var length = serializableSetType.RuleArguments?.Length ?? 0; + ruleArguments = new string[length + 3]; + ruleArguments[0] = extraOptions; + ruleArguments[1] = setTypeSymbol.ToDisplayString(); + ruleArguments[2] = serializableSetType.Rule; + + if (length > 0) { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } - - var ruleArguments = property.RuleArguments; - var hasExtraOptions = ruleArguments![0] == "" || ruleArguments[0].StartsWith("@", StringComparison.Ordinal); - var shouldTidy = hasExtraOptions && ruleArguments[0].Contains("@Tidy"); - var argumentsOffset = hasExtraOptions ? 1 : 0; - - var setElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[1 + argumentsOffset]]; - var setElementRuleArguments = new string[ruleArguments.Length - 2 - argumentsOffset]; - Array.Copy(ruleArguments, 2 + argumentsOffset, setElementRuleArguments, 0, ruleArguments.Length - 2 - argumentsOffset); - - var propertyName = property.Name; - var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}"; - var propertyEntry = $"{propertyVarPrefix}Entry"; - var propertyCount = $"{propertyVarPrefix}Count"; - - if (shouldTidy) - { - source.AppendLine($"{indent}{property.Name}?.Tidy();"); - } - source.AppendLine($"{indent}var {propertyCount} = {property.Name}?.Count ?? 0;"); - source.AppendLine($"{indent}writer.WriteEncodedInt({propertyCount});"); - source.AppendLine($"{indent}if ({propertyCount} > 0)"); - source.AppendLine($"{indent}{{"); - source.AppendLine($"{indent} foreach (var {propertyEntry} in {property.Name}!)"); - source.AppendLine($"{indent} {{"); - - var serializableSetElement = new SerializableProperty - { - Name = propertyEntry, - Type = ruleArguments[argumentsOffset], - Rule = setElementRule.RuleName, - RuleArguments = setElementRuleArguments - }; - - setElementRule.GenerateSerializationMethod(source, $"{indent} ", serializableSetElement); - - source.AppendLine($"{indent} }}"); - source.AppendLine($"{indent}}}"); + Array.Copy(serializableSetType.RuleArguments, 0, ruleArguments, 3, length); } + + return true; + } + + public override void GenerateDeserializationMethod( + StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false + ) + { + var expectedRule = RuleName; + var ruleName = property.Rule; + if (expectedRule != ruleName) + { + throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); + } + + var ruleArguments = property.RuleArguments; + var hasExtraOptions = ruleArguments![0] == "" || ruleArguments[0].StartsWith("@", StringComparison.Ordinal); + var argumentsOffset = hasExtraOptions ? 1 : 0; + + var setElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[1 + argumentsOffset]]; + var setElementRuleArguments = new string[ruleArguments.Length - 2 - argumentsOffset]; + Array.Copy(ruleArguments, 2 + argumentsOffset, setElementRuleArguments, 0, ruleArguments.Length - 2 - argumentsOffset); + + var propertyName = property.Name; + var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}"; + var propertyIndex = $"{propertyVarPrefix}Index"; + var propertyEntry = $"{propertyVarPrefix}Entry"; + var propertyCount = $"{propertyVarPrefix}Count"; + + source.AppendLine($"{indent}{ruleArguments[argumentsOffset]} {propertyEntry};"); + source.AppendLine($"{indent}var {propertyCount} = reader.ReadEncodedInt();"); + source.AppendLine($"{indent}{property.Name} = new System.Collections.Generic.HashSet<{ruleArguments[argumentsOffset]}>({propertyCount});"); + source.AppendLine($"{indent}for (var {propertyIndex} = 0; {propertyIndex} < {propertyCount}; {propertyIndex}++)"); + source.AppendLine($"{indent}{{"); + + var serializableSetElement = new SerializableProperty + { + Name = propertyEntry, + Type = ruleArguments[argumentsOffset], + Rule = setElementRule.RuleName, + RuleArguments = setElementRuleArguments + }; + + setElementRule.GenerateDeserializationMethod(source, $"{indent} ", serializableSetElement, parentReference); + source.AppendLine($"{indent} {property.Name}.Add({propertyEntry});"); + + source.AppendLine($"{indent}}}"); + } + + public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property) + { + var expectedRule = RuleName; + var ruleName = property.Rule; + if (expectedRule != ruleName) + { + throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); + } + + var ruleArguments = property.RuleArguments; + var hasExtraOptions = ruleArguments![0] == "" || ruleArguments[0].StartsWith("@", StringComparison.Ordinal); + var shouldTidy = hasExtraOptions && ruleArguments[0].Contains("@Tidy"); + var argumentsOffset = hasExtraOptions ? 1 : 0; + + var setElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[1 + argumentsOffset]]; + var setElementRuleArguments = new string[ruleArguments.Length - 2 - argumentsOffset]; + Array.Copy(ruleArguments, 2 + argumentsOffset, setElementRuleArguments, 0, ruleArguments.Length - 2 - argumentsOffset); + + var propertyName = property.Name; + var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}"; + var propertyEntry = $"{propertyVarPrefix}Entry"; + var propertyCount = $"{propertyVarPrefix}Count"; + + if (shouldTidy) + { + source.AppendLine($"{indent}{property.Name}?.Tidy();"); + } + source.AppendLine($"{indent}var {propertyCount} = {property.Name}?.Count ?? 0;"); + source.AppendLine($"{indent}writer.WriteEncodedInt({propertyCount});"); + source.AppendLine($"{indent}if ({propertyCount} > 0)"); + source.AppendLine($"{indent}{{"); + source.AppendLine($"{indent} foreach (var {propertyEntry} in {property.Name}!)"); + source.AppendLine($"{indent} {{"); + + var serializableSetElement = new SerializableProperty + { + Name = propertyEntry, + Type = ruleArguments[argumentsOffset], + Rule = setElementRule.RuleName, + RuleArguments = setElementRuleArguments + }; + + setElementRule.GenerateSerializationMethod(source, $"{indent} ", serializableSetElement); + + source.AppendLine($"{indent} }}"); + source.AppendLine($"{indent}}}"); } } diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/KeyValuePairMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/KeyValuePairMigrationRule.cs index 1797764c1..5b7c4fbef 100644 --- a/Projects/SerializationGenerator/SerializableMigration/Rules/KeyValuePairMigrationRule.cs +++ b/Projects/SerializationGenerator/SerializableMigration/Rules/KeyValuePairMigrationRule.cs @@ -19,206 +19,207 @@ using System.Text; using Microsoft.CodeAnalysis; using SerializationGenerator; -namespace SerializableMigration +namespace SerializableMigration; + +public class KeyValuePairMigrationRule : MigrationRule { - public class KeyValuePairMigrationRule : ISerializableMigrationRule + public override string RuleName => nameof(KeyValuePairMigrationRule); + + public override bool GenerateRuleState( + Compilation compilation, + ISymbol symbol, + ImmutableArray attributes, + ImmutableArray serializableTypes, + ImmutableArray embeddedSerializableTypes, + ISymbol? parentSymbol, + out string[] ruleArguments + ) { - public string RuleName => nameof(KeyValuePairMigrationRule); - - public bool GenerateRuleState( - Compilation compilation, - ISymbol symbol, - ImmutableArray attributes, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes, - ISymbol? parentSymbol, - out string[] ruleArguments - ) + if (symbol is not INamedTypeSymbol namedTypeSymbol || !symbol.IsKeyValuePair(compilation)) { - if (symbol is not INamedTypeSymbol namedTypeSymbol || !symbol.IsKeyValuePair(compilation)) - { - ruleArguments = null; - return false; - } - - var keySymbolType = namedTypeSymbol.TypeArguments[0]; - - var keySerializedProperty = SerializableMigrationRulesEngine.GenerateSerializableProperty( - compilation, - "key", - keySymbolType, - 0, - attributes, - serializableTypes, - embeddedSerializableTypes, - parentSymbol, - null - ); - - var valueSymbolType = namedTypeSymbol.TypeArguments[1]; - - var valueSerializedProperty = SerializableMigrationRulesEngine.GenerateSerializableProperty( - compilation, - "value", - valueSymbolType, - 1, - attributes, - serializableTypes, - embeddedSerializableTypes, - parentSymbol, - null - ); - - var keyArgumentsLength = keySerializedProperty.RuleArguments?.Length ?? 0; - var valueArgumentsLength = valueSerializedProperty.RuleArguments?.Length ?? 0; - var index = 0; - - // Key - ruleArguments = new string[6 + keyArgumentsLength + valueArgumentsLength]; - ruleArguments[index++] = ""; // Extra options - ruleArguments[index++] = keySymbolType.ToDisplayString(); - ruleArguments[index++] = keySerializedProperty.Rule; - ruleArguments[index++] = keyArgumentsLength.ToString(); - if (keyArgumentsLength > 0) - { - Array.Copy(keySerializedProperty.RuleArguments!, 0, ruleArguments, index, keyArgumentsLength); - index += keyArgumentsLength; - } - - // Value - ruleArguments[index++] = valueSymbolType.ToDisplayString(); - ruleArguments[index++] = valueSerializedProperty.Rule; - - if (valueArgumentsLength > 0) - { - Array.Copy(valueSerializedProperty.RuleArguments!, 0, ruleArguments, index, valueArgumentsLength); - } - - return true; + ruleArguments = null; + return false; } - public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference) + var keySymbolType = namedTypeSymbol.TypeArguments[0]; + + var keySerializedProperty = SerializableMigrationRulesEngine.GenerateSerializableProperty( + compilation, + "key", + keySymbolType, + 0, + attributes, + serializableTypes, + embeddedSerializableTypes, + parentSymbol, + null + ); + + var valueSymbolType = namedTypeSymbol.TypeArguments[1]; + + var valueSerializedProperty = SerializableMigrationRulesEngine.GenerateSerializableProperty( + compilation, + "value", + valueSymbolType, + 1, + attributes, + serializableTypes, + embeddedSerializableTypes, + parentSymbol, + null + ); + + var keyArgumentsLength = keySerializedProperty.RuleArguments?.Length ?? 0; + var valueArgumentsLength = valueSerializedProperty.RuleArguments?.Length ?? 0; + var index = 0; + + // Key + ruleArguments = new string[6 + keyArgumentsLength + valueArgumentsLength]; + ruleArguments[index++] = ""; // Extra options + ruleArguments[index++] = keySymbolType.ToDisplayString(); + ruleArguments[index++] = keySerializedProperty.Rule; + ruleArguments[index++] = keyArgumentsLength.ToString(); + if (keyArgumentsLength > 0) { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } - - var ruleArguments = property.RuleArguments; - var index = 1; // skip extra options - var keyType = ruleArguments![index++]; - var keyRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]]; - var keyRuleArguments = new string[int.Parse(ruleArguments[index++])]; - - if (keyRuleArguments.Length > 0) - { - Array.Copy(ruleArguments, index, keyRuleArguments, 0, keyRuleArguments.Length); - index += keyRuleArguments.Length; - } - - var serializableKeyProperty = new SerializableProperty - { - Name = "key", - Type = keyType, - Rule = keyRule.RuleName, - RuleArguments = keyRuleArguments - }; - - keyRule.GenerateDeserializationMethod( - source, - indent, - serializableKeyProperty, - parentReference - ); - - var valueType = ruleArguments[index++]; - var valueRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]]; - var valueRuleArguments = new string[int.Parse(ruleArguments[index++])]; - - if (valueRuleArguments.Length > 0) - { - Array.Copy(ruleArguments, index, valueRuleArguments, 0, valueRuleArguments.Length); - } - - var serializableValueProperty = new SerializableProperty - { - Name = "value", - Type = valueType, - Rule = valueRule.RuleName, - RuleArguments = valueRuleArguments - }; - - valueRule.GenerateDeserializationMethod( - source, - indent, - serializableValueProperty, - parentReference - ); - - source.AppendLine( - $"{indent}{property.Name} = new {SymbolMetadata.KEYVALUEPAIR_STRUCT}<{keyType}, {valueType}>(key, value);" - ); + Array.Copy(keySerializedProperty.RuleArguments!, 0, ruleArguments, index, keyArgumentsLength); + index += keyArgumentsLength; } - public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property) + // Value + ruleArguments[index++] = valueSymbolType.ToDisplayString(); + ruleArguments[index++] = valueSerializedProperty.Rule; + + if (valueArgumentsLength > 0) { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } - - var ruleArguments = property.RuleArguments; - var index = 1; // skip extra options - var keyType = ruleArguments![index++]; - var keyRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]]; - var keyRuleArguments = new string[int.Parse(ruleArguments[index++])]; - - if (keyRuleArguments.Length > 0) - { - Array.Copy(ruleArguments, index, keyRuleArguments, 0, keyRuleArguments.Length); - index += keyRuleArguments.Length; - } - - var serializableKeyProperty = new SerializableProperty - { - Name = $"{property.Name}.Key", - Type = keyType, - Rule = keyRule.RuleName, - RuleArguments = keyRuleArguments - }; - - keyRule.GenerateSerializationMethod( - source, - indent, - serializableKeyProperty - ); - - var valueType = ruleArguments[index++]; - var valueRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]]; - var valueRuleArguments = new string[int.Parse(ruleArguments[index++])]; - - if (valueRuleArguments.Length > 0) - { - Array.Copy(ruleArguments, index, valueRuleArguments, 0, valueRuleArguments.Length); - } - - var serializableValueProperty = new SerializableProperty - { - Name = $"{property.Name}.Value", - Type = valueType, - Rule = valueRule.RuleName, - RuleArguments = valueRuleArguments - }; - - valueRule.GenerateSerializationMethod( - source, - indent, - serializableValueProperty - ); + Array.Copy(valueSerializedProperty.RuleArguments!, 0, ruleArguments, index, valueArgumentsLength); } + + return true; + } + + public override void GenerateDeserializationMethod( + StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false + ) + { + var expectedRule = RuleName; + var ruleName = property.Rule; + if (expectedRule != ruleName) + { + throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); + } + + var ruleArguments = property.RuleArguments; + var index = 1; // skip extra options + var keyType = ruleArguments![index++]; + var keyRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]]; + var keyRuleArguments = new string[int.Parse(ruleArguments[index++])]; + + if (keyRuleArguments.Length > 0) + { + Array.Copy(ruleArguments, index, keyRuleArguments, 0, keyRuleArguments.Length); + index += keyRuleArguments.Length; + } + + var serializableKeyProperty = new SerializableProperty + { + Name = "key", + Type = keyType, + Rule = keyRule.RuleName, + RuleArguments = keyRuleArguments + }; + + keyRule.GenerateDeserializationMethod( + source, + indent, + serializableKeyProperty, + parentReference + ); + + var valueType = ruleArguments[index++]; + var valueRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]]; + var valueRuleArguments = new string[int.Parse(ruleArguments[index++])]; + + if (valueRuleArguments.Length > 0) + { + Array.Copy(ruleArguments, index, valueRuleArguments, 0, valueRuleArguments.Length); + } + + var serializableValueProperty = new SerializableProperty + { + Name = "value", + Type = valueType, + Rule = valueRule.RuleName, + RuleArguments = valueRuleArguments + }; + + valueRule.GenerateDeserializationMethod( + source, + indent, + serializableValueProperty, + parentReference + ); + + source.AppendLine( + $"{indent}{property.Name} = new {SymbolMetadata.KEYVALUEPAIR_STRUCT}<{keyType}, {valueType}>(key, value);" + ); + } + + public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property) + { + var expectedRule = RuleName; + var ruleName = property.Rule; + if (expectedRule != ruleName) + { + throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); + } + + var ruleArguments = property.RuleArguments; + var index = 1; // skip extra options + var keyType = ruleArguments![index++]; + var keyRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]]; + var keyRuleArguments = new string[int.Parse(ruleArguments[index++])]; + + if (keyRuleArguments.Length > 0) + { + Array.Copy(ruleArguments, index, keyRuleArguments, 0, keyRuleArguments.Length); + index += keyRuleArguments.Length; + } + + var serializableKeyProperty = new SerializableProperty + { + Name = $"{property.Name}.Key", + Type = keyType, + Rule = keyRule.RuleName, + RuleArguments = keyRuleArguments + }; + + keyRule.GenerateSerializationMethod( + source, + indent, + serializableKeyProperty + ); + + var valueType = ruleArguments[index++]; + var valueRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]]; + var valueRuleArguments = new string[int.Parse(ruleArguments[index++])]; + + if (valueRuleArguments.Length > 0) + { + Array.Copy(ruleArguments, index, valueRuleArguments, 0, valueRuleArguments.Length); + } + + var serializableValueProperty = new SerializableProperty + { + Name = $"{property.Name}.Value", + Type = valueType, + Rule = valueRule.RuleName, + RuleArguments = valueRuleArguments + }; + + valueRule.GenerateSerializationMethod( + source, + indent, + serializableValueProperty + ); } } diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/ListMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/ListMigrationRule.cs index f11e3f369..53d2d2c44 100644 --- a/Projects/SerializationGenerator/SerializableMigration/Rules/ListMigrationRule.cs +++ b/Projects/SerializationGenerator/SerializableMigration/Rules/ListMigrationRule.cs @@ -20,152 +20,153 @@ using System.Text; using Microsoft.CodeAnalysis; using SerializationGenerator; -namespace SerializableMigration +namespace SerializableMigration; + +public class ListMigrationRule : MigrationRule { - public class ListMigrationRule : ISerializableMigrationRule + public override string RuleName => nameof(ListMigrationRule); + + public override bool GenerateRuleState( + Compilation compilation, + ISymbol symbol, + ImmutableArray attributes, + ImmutableArray serializableTypes, + ImmutableArray embeddedSerializableTypes, + ISymbol? parentSymbol, + out string[] ruleArguments + ) { - public string RuleName => nameof(ListMigrationRule); - - public bool GenerateRuleState( - Compilation compilation, - ISymbol symbol, - ImmutableArray attributes, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes, - ISymbol? parentSymbol, - out string[] ruleArguments - ) + if (symbol is not INamedTypeSymbol namedTypeSymbol || !symbol.IsList(compilation)) { - if (symbol is not INamedTypeSymbol namedTypeSymbol || !symbol.IsList(compilation)) - { - ruleArguments = null; - return false; - } - - var listTypeSymbol = namedTypeSymbol.TypeArguments[0]; - - var serializableListType = SerializableMigrationRulesEngine.GenerateSerializableProperty( - compilation, - "ListEntry", - listTypeSymbol, - 0, - attributes, - serializableTypes, - embeddedSerializableTypes, - parentSymbol, - null - ); - - var extraOptions = ""; - if (attributes.Any(a => a.IsTidy(compilation))) - { - extraOptions += "@Tidy"; - } - - var length = serializableListType.RuleArguments?.Length ?? 0; - ruleArguments = new string[length + 3]; - ruleArguments[0] = extraOptions; - ruleArguments[1] = listTypeSymbol.ToDisplayString(); - ruleArguments[2] = serializableListType.Rule; - - if (length > 0) - { - Array.Copy(serializableListType.RuleArguments!, 0, ruleArguments, 3, length); - } - - return true; + ruleArguments = null; + return false; } - public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference) + var listTypeSymbol = namedTypeSymbol.TypeArguments[0]; + + var serializableListType = SerializableMigrationRulesEngine.GenerateSerializableProperty( + compilation, + "ListEntry", + listTypeSymbol, + 0, + attributes, + serializableTypes, + embeddedSerializableTypes, + parentSymbol, + null + ); + + var extraOptions = ""; + if (attributes.Any(a => a.IsTidy(compilation))) { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } - - var ruleArguments = property.RuleArguments; - var hasExtraOptions = ruleArguments![0] == "" || ruleArguments[0].StartsWith("@", StringComparison.Ordinal); - var argumentsOffset = hasExtraOptions ? 1 : 0; - - var listElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[argumentsOffset + 1]]; - - var listElementRuleArguments = new string[ruleArguments.Length - 2 - argumentsOffset]; - Array.Copy(ruleArguments, 2 + argumentsOffset, listElementRuleArguments, 0, ruleArguments.Length - 2 - argumentsOffset); - - var propertyName = property.Name; - var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}"; - var propertyIndex = $"{propertyVarPrefix}Index"; - var propertyEntry = $"{propertyVarPrefix}Entry"; - var propertyCount = $"{propertyVarPrefix}Count"; - - source.AppendLine($"{indent}{ruleArguments[argumentsOffset]} {propertyEntry};"); - source.AppendLine($"{indent}var {propertyCount} = reader.ReadEncodedInt();"); - source.AppendLine($"{indent}{propertyName} = new System.Collections.Generic.List<{ruleArguments[argumentsOffset]}>({propertyCount});"); - source.AppendLine($"{indent}for (var {propertyIndex} = 0; {propertyIndex} < {propertyCount}; {propertyIndex}++)"); - source.AppendLine($"{indent}{{"); - - var serializableListElement = new SerializableProperty - { - Name = propertyEntry, - Type = ruleArguments[argumentsOffset], - Rule = listElementRule.RuleName, - RuleArguments = listElementRuleArguments - }; - - listElementRule.GenerateDeserializationMethod(source, $"{indent} ", serializableListElement, parentReference); - source.AppendLine($"{indent} {propertyName}.Add({propertyEntry});"); - - source.AppendLine($"{indent}}}"); + extraOptions += "@Tidy"; } - public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property) + var length = serializableListType.RuleArguments?.Length ?? 0; + ruleArguments = new string[length + 3]; + ruleArguments[0] = extraOptions; + ruleArguments[1] = listTypeSymbol.ToDisplayString(); + ruleArguments[2] = serializableListType.Rule; + + if (length > 0) { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } - - var ruleArguments = property.RuleArguments; - var hasExtraOptions = ruleArguments![0] == "" || ruleArguments[0].StartsWith("@", StringComparison.Ordinal); - var shouldTidy = hasExtraOptions && ruleArguments[0].Contains("@Tidy"); - var argumentsOffset = hasExtraOptions ? 1 : 0; - - var listElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[1 + argumentsOffset]]; - var listElementRuleArguments = new string[ruleArguments.Length - 2 - argumentsOffset]; - Array.Copy(ruleArguments, 2 + argumentsOffset, listElementRuleArguments, 0, ruleArguments.Length - 2 - argumentsOffset); - - var propertyName = property.Name; - var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}"; - var propertyEntry = $"{propertyVarPrefix}Entry"; - var propertyCount = $"{propertyVarPrefix}Count"; - - if (shouldTidy) - { - source.AppendLine($"{indent}{property.Name}?.Tidy();"); - } - source.AppendLine($"{indent}var {propertyCount} = {property.Name}?.Count ?? 0;"); - source.AppendLine($"{indent}writer.WriteEncodedInt({propertyCount});"); - source.AppendLine($"{indent}if ({propertyCount} > 0)"); - source.AppendLine($"{indent}{{"); - source.AppendLine($"{indent} foreach (var {propertyEntry} in {property.Name}!)"); - source.AppendLine($"{indent} {{"); - - var serializableListElement = new SerializableProperty - { - Name = propertyEntry, - Type = ruleArguments[argumentsOffset], - Rule = listElementRule.RuleName, - RuleArguments = listElementRuleArguments - }; - - listElementRule.GenerateSerializationMethod(source, $"{indent} ", serializableListElement); - - source.AppendLine($"{indent} }}"); - source.AppendLine($"{indent}}}"); + Array.Copy(serializableListType.RuleArguments!, 0, ruleArguments, 3, length); } + + return true; + } + + public override void GenerateDeserializationMethod( + StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false + ) + { + var expectedRule = RuleName; + var ruleName = property.Rule; + if (expectedRule != ruleName) + { + throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); + } + + var ruleArguments = property.RuleArguments; + var hasExtraOptions = ruleArguments![0] == "" || ruleArguments[0].StartsWith("@", StringComparison.Ordinal); + var argumentsOffset = hasExtraOptions ? 1 : 0; + + var listElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[argumentsOffset + 1]]; + + var listElementRuleArguments = new string[ruleArguments.Length - 2 - argumentsOffset]; + Array.Copy(ruleArguments, 2 + argumentsOffset, listElementRuleArguments, 0, ruleArguments.Length - 2 - argumentsOffset); + + var propertyName = property.Name; + var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}"; + var propertyIndex = $"{propertyVarPrefix}Index"; + var propertyEntry = $"{propertyVarPrefix}Entry"; + var propertyCount = $"{propertyVarPrefix}Count"; + + source.AppendLine($"{indent}{ruleArguments[argumentsOffset]} {propertyEntry};"); + source.AppendLine($"{indent}var {propertyCount} = reader.ReadEncodedInt();"); + source.AppendLine($"{indent}{propertyName} = new System.Collections.Generic.List<{ruleArguments[argumentsOffset]}>({propertyCount});"); + source.AppendLine($"{indent}for (var {propertyIndex} = 0; {propertyIndex} < {propertyCount}; {propertyIndex}++)"); + source.AppendLine($"{indent}{{"); + + var serializableListElement = new SerializableProperty + { + Name = propertyEntry, + Type = ruleArguments[argumentsOffset], + Rule = listElementRule.RuleName, + RuleArguments = listElementRuleArguments + }; + + listElementRule.GenerateDeserializationMethod(source, $"{indent} ", serializableListElement, parentReference); + source.AppendLine($"{indent} {propertyName}.Add({propertyEntry});"); + + source.AppendLine($"{indent}}}"); + } + + public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property) + { + var expectedRule = RuleName; + var ruleName = property.Rule; + if (expectedRule != ruleName) + { + throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); + } + + var ruleArguments = property.RuleArguments; + var hasExtraOptions = ruleArguments![0] == "" || ruleArguments[0].StartsWith("@", StringComparison.Ordinal); + var shouldTidy = hasExtraOptions && ruleArguments[0].Contains("@Tidy"); + var argumentsOffset = hasExtraOptions ? 1 : 0; + + var listElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[1 + argumentsOffset]]; + var listElementRuleArguments = new string[ruleArguments.Length - 2 - argumentsOffset]; + Array.Copy(ruleArguments, 2 + argumentsOffset, listElementRuleArguments, 0, ruleArguments.Length - 2 - argumentsOffset); + + var propertyName = property.Name; + var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}"; + var propertyEntry = $"{propertyVarPrefix}Entry"; + var propertyCount = $"{propertyVarPrefix}Count"; + + if (shouldTidy) + { + source.AppendLine($"{indent}{property.Name}?.Tidy();"); + } + source.AppendLine($"{indent}var {propertyCount} = {property.Name}?.Count ?? 0;"); + source.AppendLine($"{indent}writer.WriteEncodedInt({propertyCount});"); + source.AppendLine($"{indent}if ({propertyCount} > 0)"); + source.AppendLine($"{indent}{{"); + source.AppendLine($"{indent} foreach (var {propertyEntry} in {property.Name}!)"); + source.AppendLine($"{indent} {{"); + + var serializableListElement = new SerializableProperty + { + Name = propertyEntry, + Type = ruleArguments[argumentsOffset], + Rule = listElementRule.RuleName, + RuleArguments = listElementRuleArguments + }; + + listElementRule.GenerateSerializationMethod(source, $"{indent} ", serializableListElement); + + source.AppendLine($"{indent} }}"); + source.AppendLine($"{indent}}}"); } } diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/MigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/MigrationRule.cs new file mode 100644 index 000000000..848812b54 --- /dev/null +++ b/Projects/SerializationGenerator/SerializableMigration/Rules/MigrationRule.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Immutable; +using System.Text; +using Microsoft.CodeAnalysis; +using SerializationGenerator; + +namespace SerializableMigration; + +public abstract class MigrationRule : ISerializableMigrationRule +{ + public abstract string RuleName { get; } + + public virtual void GenerateMigrationProperty( + StringBuilder source, Compilation compilation, string indent, SerializableProperty serializableProperty + ) + { + var propertyType = serializableProperty.Type; + var type = compilation.GetTypeByMetadataName(propertyType)?.IsValueType == true + || SymbolMetadata.IsPrimitiveFromTypeDisplayString(propertyType) && propertyType != "bool" + ? $"{propertyType}{(serializableProperty.UsesSaveFlag == true ? "?" : "")}" : propertyType; + + source.AppendLine($"{indent}internal readonly {type} {serializableProperty.Name};"); + } + + public abstract bool GenerateRuleState( + Compilation compilation, ISymbol symbol, ImmutableArray attributes, + ImmutableArray serializableTypes, + ImmutableArray embeddedSerializableTypes, ISymbol? parentSymbol, out string[] ruleArguments + ); + + public abstract void GenerateDeserializationMethod( + StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false + ); + + public abstract void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property); +} diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/PrimitiveTypeMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/PrimitiveTypeMigrationRule.cs index f3d8135bd..70b34ce06 100644 --- a/Projects/SerializationGenerator/SerializableMigration/Rules/PrimitiveTypeMigrationRule.cs +++ b/Projects/SerializationGenerator/SerializableMigration/Rules/PrimitiveTypeMigrationRule.cs @@ -20,129 +20,130 @@ using System.Text; using Microsoft.CodeAnalysis; using SerializationGenerator; -namespace SerializableMigration +namespace SerializableMigration; + +public class PrimitiveTypeMigrationRule : MigrationRule { - public class PrimitiveTypeMigrationRule : ISerializableMigrationRule + public override string RuleName => nameof(PrimitiveTypeMigrationRule); + + public override bool GenerateRuleState( + Compilation compilation, + ISymbol symbol, + ImmutableArray attributes, + ImmutableArray serializableTypes, + ImmutableArray embeddedSerializableTypes, + ISymbol? parentSymbol, + out string[] ruleArguments + ) { - public string RuleName => nameof(PrimitiveTypeMigrationRule); - - public bool GenerateRuleState( - Compilation compilation, - ISymbol symbol, - ImmutableArray attributes, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes, - ISymbol? parentSymbol, - out string[] ruleArguments - ) + if (symbol.IsIpAddress(compilation) || symbol.IsTimeSpan(compilation)) { - if (symbol.IsIpAddress(compilation) || symbol.IsTimeSpan(compilation)) - { - ruleArguments = Array.Empty(); - return true; - } - - if ( - symbol is not ITypeSymbol { - SpecialType: not (not - SpecialType.System_Boolean and not - SpecialType.System_SByte and not - SpecialType.System_Int16 and not - SpecialType.System_Int32 and not - SpecialType.System_Int64 and not - SpecialType.System_Byte and not - SpecialType.System_UInt16 and not - SpecialType.System_UInt32 and not - SpecialType.System_UInt64 and not - SpecialType.System_Single and not - SpecialType.System_Double and not - SpecialType.System_String and not - SpecialType.System_Decimal and not - SpecialType.System_DateTime) - } typeSymbol - ) - { - ruleArguments = null; - return false; - } - - ruleArguments = typeSymbol.SpecialType switch - { - SpecialType.System_Int32 when attributes.Any(a => a.IsEncodedInt(compilation)) => - new[] { "EncodedInt" }, - SpecialType.System_DateTime when attributes.Any(a => a.IsDeltaDateTime(compilation)) => - new[] { "DeltaTime" }, - SpecialType.System_String when attributes.Any(a => a.IsInternString(compilation)) => - new[] { "InternString" }, - _ => new[] { "" } - }; - + ruleArguments = Array.Empty(); return true; } - public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference) + if ( + symbol is not ITypeSymbol { + SpecialType: not (not + SpecialType.System_Boolean and not + SpecialType.System_SByte and not + SpecialType.System_Int16 and not + SpecialType.System_Int32 and not + SpecialType.System_Int64 and not + SpecialType.System_Byte and not + SpecialType.System_UInt16 and not + SpecialType.System_UInt32 and not + SpecialType.System_UInt64 and not + SpecialType.System_Single and not + SpecialType.System_Double and not + SpecialType.System_String and not + SpecialType.System_Decimal and not + SpecialType.System_DateTime) + } typeSymbol + ) { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } - - var propertyName = property.Name; - var argument = property.RuleArguments?.Length >= 1 ? property.RuleArguments[0] : null; - - const string ipAddress = SymbolMetadata.IPADDRESS_CLASS; - const string timeSpan = SymbolMetadata.TIMESPAN_STRUCT; - const string date = "System.DateTime"; - - var readMethod = property.Type switch - { - "bool" => "ReadBool", - "sbyte" => "ReadSByte", - "short" => "ReadShort", - "int" when argument == "EncodedInt" => "ReadEncodedInt", - "int" => "ReadInt", - "long" => "ReadLong", - "byte" => "ReadByte", - "ushort" => "ReadUShort", - "uint" => "ReadUInt", - "ulong" => "ReadULong", - "float" => "ReadFloat", - "double" => "ReadDouble", - "string" => "ReadString", - "decimal" => "ReadDecimal", - date when argument == "DeltaTime" => "ReadDeltaTime", - date => "ReadDateTime", - ipAddress => "ReadIPAddress", - timeSpan => "ReadTimeSpan" - }; - - var readArgument = readMethod == "ReadString" && argument == "InternString" ? "true" : ""; - - source.AppendLine($"{indent}{propertyName} = reader.{readMethod}({readArgument});"); + ruleArguments = null; + return false; } - public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property) + ruleArguments = typeSymbol.SpecialType switch { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } + SpecialType.System_Int32 when attributes.Any(a => a.IsEncodedInt(compilation)) => + new[] { "EncodedInt" }, + SpecialType.System_DateTime when attributes.Any(a => a.IsDeltaDateTime(compilation)) => + new[] { "DeltaTime" }, + SpecialType.System_String when attributes.Any(a => a.IsInternString(compilation)) => + new[] { "InternString" }, + _ => new[] { "" } + }; - var propertyName = property.Name; - var argument = property.RuleArguments?.Length >= 1 ? property.RuleArguments[0] : null; + return true; + } - var writeMethod = property.Type switch - { - "System.DateTime" when argument == "DeltaTime" => "WriteDeltaTime", - "int" when argument == "EncodedInt" => "WriteEncodedInt", - _ => "Write" - }; - - source.AppendLine($"{indent}writer.{writeMethod}({propertyName});"); + public override void GenerateDeserializationMethod( + StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false + ) + { + var expectedRule = RuleName; + var ruleName = property.Rule; + if (expectedRule != ruleName) + { + throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); } + + var propertyName = property.Name; + var argument = property.RuleArguments?.Length >= 1 ? property.RuleArguments[0] : null; + + const string ipAddress = SymbolMetadata.IPADDRESS_CLASS; + const string timeSpan = SymbolMetadata.TIMESPAN_STRUCT; + const string date = "System.DateTime"; + + var readMethod = property.Type switch + { + "bool" => "ReadBool", + "sbyte" => "ReadSByte", + "short" => "ReadShort", + "int" when argument == "EncodedInt" => "ReadEncodedInt", + "int" => "ReadInt", + "long" => "ReadLong", + "byte" => "ReadByte", + "ushort" => "ReadUShort", + "uint" => "ReadUInt", + "ulong" => "ReadULong", + "float" => "ReadFloat", + "double" => "ReadDouble", + "string" => "ReadString", + "decimal" => "ReadDecimal", + date when argument == "DeltaTime" => "ReadDeltaTime", + date => "ReadDateTime", + ipAddress => "ReadIPAddress", + timeSpan => "ReadTimeSpan" + }; + + var readArgument = readMethod == "ReadString" && argument == "InternString" ? "true" : ""; + + source.AppendLine($"{indent}{propertyName} = reader.{readMethod}({readArgument});"); + } + + public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property) + { + var expectedRule = RuleName; + var ruleName = property.Rule; + if (expectedRule != ruleName) + { + throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); + } + + var propertyName = property.Name; + var argument = property.RuleArguments?.Length >= 1 ? property.RuleArguments[0] : null; + + var writeMethod = property.Type switch + { + "System.DateTime" when argument == "DeltaTime" => "WriteDeltaTime", + "int" when argument == "EncodedInt" => "WriteEncodedInt", + _ => "Write" + }; + + source.AppendLine($"{indent}writer.{writeMethod}({propertyName});"); } } diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/PrimitiveUOTypeMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/PrimitiveUOTypeMigrationRule.cs index 9d60ca27e..ec2ea15d3 100644 --- a/Projects/SerializationGenerator/SerializableMigration/Rules/PrimitiveUOTypeMigrationRule.cs +++ b/Projects/SerializationGenerator/SerializableMigration/Rules/PrimitiveUOTypeMigrationRule.cs @@ -19,61 +19,62 @@ using System.Text; using Microsoft.CodeAnalysis; using SerializationGenerator; -namespace SerializableMigration +namespace SerializableMigration; + +public class PrimitiveUOTypeMigrationRule : MigrationRule { - public class PrimitiveUOTypeMigrationRule : ISerializableMigrationRule + public override string RuleName => nameof(PrimitiveUOTypeMigrationRule); + + public override bool GenerateRuleState( + Compilation compilation, + ISymbol symbol, + ImmutableArray attributes, + ImmutableArray serializableTypes, + ImmutableArray embeddedSerializableTypes, + ISymbol? parentSymbol, + out string[] ruleArguments + ) { - public string RuleName => nameof(PrimitiveUOTypeMigrationRule); - - public bool GenerateRuleState( - Compilation compilation, - ISymbol symbol, - ImmutableArray attributes, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes, - ISymbol? parentSymbol, - out string[] ruleArguments - ) + ruleArguments = symbol switch { - ruleArguments = symbol switch - { - _ when symbol.IsPoint2D(compilation) => new[] { "Point2D" }, - _ when symbol.IsPoint3D(compilation) => new[] { "Point3D" }, - _ when symbol.IsRectangle2D(compilation) => new[] { "Rect2D" }, - _ when symbol.IsRectangle3D(compilation) => new[] { "Rect3D" }, - _ when symbol.IsRace(compilation) => new[] { "Race" }, - _ when symbol.IsMap(compilation) => new[] { "Map" }, - _ when symbol.IsBitArray(compilation) => new[] { "BitArray" }, - _ => null - }; + _ when symbol.IsPoint2D(compilation) => new[] { "Point2D" }, + _ when symbol.IsPoint3D(compilation) => new[] { "Point3D" }, + _ when symbol.IsRectangle2D(compilation) => new[] { "Rect2D" }, + _ when symbol.IsRectangle3D(compilation) => new[] { "Rect3D" }, + _ when symbol.IsRace(compilation) => new[] { "Race" }, + _ when symbol.IsMap(compilation) => new[] { "Map" }, + _ when symbol.IsBitArray(compilation) => new[] { "BitArray" }, + _ => null + }; - return ruleArguments != null; + return ruleArguments != null; + } + + public override void GenerateDeserializationMethod( + StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false + ) + { + var expectedRule = RuleName; + var ruleName = property.Rule; + if (expectedRule != ruleName) + { + throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); } - public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference) - { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } + var propertyName = property.Name; + source.AppendLine($"{indent}{propertyName} = reader.Read{property.RuleArguments?[0] ?? ""}();"); + } - var propertyName = property.Name; - source.AppendLine($"{indent}{propertyName} = reader.Read{property.RuleArguments?[0] ?? ""}();"); + public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property) + { + var expectedRule = RuleName; + var ruleName = property.Rule; + if (expectedRule != ruleName) + { + throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); } - public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property) - { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } - - var propertyName = property.Name; - source.AppendLine($"{indent}writer.Write({propertyName});"); - } + var propertyName = property.Name; + source.AppendLine($"{indent}writer.Write({propertyName});"); } } diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/RawSerializableMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/RawSerializableMigrationRule.cs index e5ee8c725..8f0944f1d 100644 --- a/Projects/SerializationGenerator/SerializableMigration/Rules/RawSerializableMigrationRule.cs +++ b/Projects/SerializationGenerator/SerializableMigration/Rules/RawSerializableMigrationRule.cs @@ -19,63 +19,64 @@ using System.Text; using Microsoft.CodeAnalysis; using SerializationGenerator; -namespace SerializableMigration +namespace SerializableMigration; + +public class RawSerializableMigrationRule : MigrationRule { - public class RawSerializableMigrationRule : ISerializableMigrationRule + public override string RuleName => nameof(RawSerializableMigrationRule); + + public override bool GenerateRuleState( + Compilation compilation, + ISymbol symbol, + ImmutableArray attributes, + ImmutableArray serializableTypes, + ImmutableArray embeddedSerializableTypes, + ISymbol? parentSymbol, + out string[] ruleArguments + ) { - public string RuleName => nameof(RawSerializableMigrationRule); - - public bool GenerateRuleState( - Compilation compilation, - ISymbol symbol, - ImmutableArray attributes, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes, - ISymbol? parentSymbol, - out string[] ruleArguments - ) + if (symbol is not ITypeSymbol typeSymbol) { - if (symbol is not ITypeSymbol typeSymbol) - { - ruleArguments = null; - return false; - } - - if (!typeSymbol.HasRawSerializableInterface(compilation, embeddedSerializableTypes)) - { - ruleArguments = null; - return false; - } - - ruleArguments = new[] { "" }; - return true; + ruleArguments = null; + return false; } - public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference) + if (!typeSymbol.HasRawSerializableInterface(compilation, embeddedSerializableTypes)) { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } - - var propertyName = property.Name; - source.AppendLine($"{indent}{propertyName} = new {property.Type}({parentReference ?? "this"});"); - source.AppendLine($"{indent}{propertyName}.Deserialize(reader);"); + ruleArguments = null; + return false; } - public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property) - { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } + ruleArguments = new[] { "" }; + return true; + } - var propertyName = property.Name; - source.AppendLine($"{indent}{propertyName}.Serialize(writer);"); + public override void GenerateDeserializationMethod( + StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false + ) + { + var expectedRule = RuleName; + var ruleName = property.Rule; + if (expectedRule != ruleName) + { + throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); } + + var propertyName = property.Name; + source.AppendLine($"{indent}{propertyName} = new {property.Type}({parentReference ?? "this"});"); + source.AppendLine($"{indent}{propertyName}.Deserialize(reader);"); + } + + public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property) + { + var expectedRule = RuleName; + var ruleName = property.Rule; + if (expectedRule != ruleName) + { + throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); + } + + var propertyName = property.Name; + source.AppendLine($"{indent}{propertyName}.Serialize(writer);"); } } diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/SerializableInterfaceMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/SerializableInterfaceMigrationRule.cs index 3cc932c80..2326af110 100644 --- a/Projects/SerializationGenerator/SerializableMigration/Rules/SerializableInterfaceMigrationRule.cs +++ b/Projects/SerializationGenerator/SerializableMigration/Rules/SerializableInterfaceMigrationRule.cs @@ -19,56 +19,57 @@ using System.Text; using Microsoft.CodeAnalysis; using SerializationGenerator; -namespace SerializableMigration +namespace SerializableMigration; + +public class SerializableInterfaceMigrationRule : MigrationRule { - public class SerializableInterfaceMigrationRule : ISerializableMigrationRule + public override string RuleName => nameof(SerializableInterfaceMigrationRule); + + public override bool GenerateRuleState( + Compilation compilation, + ISymbol symbol, + ImmutableArray attributes, + ImmutableArray serializableTypes, + ImmutableArray embeddedSerializableTypes, + ISymbol? parentSymbol, + out string[] ruleArguments + ) { - public string RuleName => nameof(SerializableInterfaceMigrationRule); - - public bool GenerateRuleState( - Compilation compilation, - ISymbol symbol, - ImmutableArray attributes, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes, - ISymbol? parentSymbol, - out string[] ruleArguments - ) + if (symbol is ITypeSymbol typeSymbol && typeSymbol.HasSerializableInterface(compilation, serializableTypes)) { - if (symbol is ITypeSymbol typeSymbol && typeSymbol.HasSerializableInterface(compilation, serializableTypes)) - { - ruleArguments = Array.Empty(); - return true; - } - - ruleArguments = null; - return false; + ruleArguments = Array.Empty(); + return true; } - public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference) - { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } + ruleArguments = null; + return false; + } - var propertyName = property.Name; - source.AppendLine($"{indent}{propertyName} = reader.ReadEntity<{property.Type}>();"); + public override void GenerateDeserializationMethod( + StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false + ) + { + var expectedRule = RuleName; + var ruleName = property.Rule; + if (expectedRule != ruleName) + { + throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); } - public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property) - { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } + var propertyName = property.Name; + source.AppendLine($"{indent}{propertyName} = reader.ReadEntity<{property.Type}>();"); + } - var propertyName = property.Name; - source.AppendLine($"{indent}writer.Write({propertyName});"); + public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property) + { + var expectedRule = RuleName; + var ruleName = property.Rule; + if (expectedRule != ruleName) + { + throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); } + + var propertyName = property.Name; + source.AppendLine($"{indent}writer.Write({propertyName});"); } } diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/SerializationMethodSignatureMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/SerializationMethodSignatureMigrationRule.cs index 1cd17971b..4e9859170 100644 --- a/Projects/SerializationGenerator/SerializableMigration/Rules/SerializationMethodSignatureMigrationRule.cs +++ b/Projects/SerializationGenerator/SerializableMigration/Rules/SerializationMethodSignatureMigrationRule.cs @@ -19,66 +19,67 @@ using System.Text; using Microsoft.CodeAnalysis; using SerializationGenerator; -namespace SerializableMigration +namespace SerializableMigration; + +public class SerializationMethodSignatureMigrationRule : MigrationRule { - public class SerializationMethodSignatureMigrationRule : ISerializableMigrationRule + public override string RuleName => nameof(SerializationMethodSignatureMigrationRule); + + public override bool GenerateRuleState( + Compilation compilation, + ISymbol symbol, + ImmutableArray attributes, + ImmutableArray serializableTypes, + ImmutableArray embeddedSerializableTypes, + ISymbol? parentSymbol, + out string[] ruleArguments + ) { - public string RuleName => nameof(SerializationMethodSignatureMigrationRule); - - public bool GenerateRuleState( - Compilation compilation, - ISymbol symbol, - ImmutableArray attributes, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes, - ISymbol? parentSymbol, - out string[] ruleArguments - ) + if ((symbol as ITypeSymbol)?.HasPublicSerializeMethod(compilation, serializableTypes) != true) { - if ((symbol as ITypeSymbol)?.HasPublicSerializeMethod(compilation, serializableTypes) != true) - { - ruleArguments = null; - return false; - } - - if (symbol is not INamedTypeSymbol namedTypeSymbol || - !namedTypeSymbol.HasGenericReaderCtor(compilation, parentSymbol, out var requiresParent)) - { - ruleArguments = null; - return false; - } - - ruleArguments = new[] { requiresParent ? "DeserializationRequiresParent" : "" }; - return true; + ruleArguments = null; + return false; } - public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference) + if (symbol is not INamedTypeSymbol namedTypeSymbol || + !namedTypeSymbol.HasGenericReaderCtor(compilation, parentSymbol, out var requiresParent)) { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } - - var propertyName = property.Name; - var argument = property.RuleArguments?.Length >= 1 && - property.RuleArguments[0] == "DeserializationRequiresParent" ? ", this" : ""; - - source.AppendLine($"{indent}{propertyName} = new {property.Type}(reader{argument});"); + ruleArguments = null; + return false; } - public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property) - { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } + ruleArguments = new[] { requiresParent ? "DeserializationRequiresParent" : "" }; + return true; + } - var propertyName = property.Name; - source.AppendLine($"{indent}{propertyName}.Serialize(writer);"); + public override void GenerateDeserializationMethod( + StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false + ) + { + var expectedRule = RuleName; + var ruleName = property.Rule; + if (expectedRule != ruleName) + { + throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); } + + var propertyName = property.Name; + var argument = property.RuleArguments?.Length >= 1 && + property.RuleArguments[0] == "DeserializationRequiresParent" ? ", this" : ""; + + source.AppendLine($"{indent}{propertyName} = new {property.Type}(reader{argument});"); + } + + public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property) + { + var expectedRule = RuleName; + var ruleName = property.Rule; + if (expectedRule != ruleName) + { + throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); + } + + var propertyName = property.Name; + source.AppendLine($"{indent}{propertyName}.Serialize(writer);"); } } diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/TimerMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/TimerMigrationRule.cs index 9fba1913a..7d97dfd6e 100644 --- a/Projects/SerializationGenerator/SerializableMigration/Rules/TimerMigrationRule.cs +++ b/Projects/SerializationGenerator/SerializableMigration/Rules/TimerMigrationRule.cs @@ -20,107 +20,117 @@ using System.Text; using Microsoft.CodeAnalysis; using SerializationGenerator; -namespace SerializableMigration +namespace SerializableMigration; + +public class TimerMigrationRule : MigrationRule, IPostDeserializeMethod { - public class TimerMigrationRule : ISerializableMigrationRule, IPostDeserializeMethod + public override string RuleName => nameof(TimerMigrationRule); + + public override bool GenerateRuleState( + Compilation compilation, + ISymbol symbol, + ImmutableArray attributes, + ImmutableArray serializableTypes, + ImmutableArray embeddedSerializableTypes, + ISymbol? parentSymbol, + out string[] ruleArguments + ) { - public string RuleName => nameof(TimerMigrationRule); - - public bool GenerateRuleState( - Compilation compilation, - ISymbol symbol, - ImmutableArray attributes, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes, - ISymbol? parentSymbol, - out string[] ruleArguments - ) + if (!(symbol is ITypeSymbol typeSymbol && typeSymbol.IsTimer(compilation))) { - if (!(symbol is ITypeSymbol typeSymbol && typeSymbol.IsTimer(compilation))) - { - ruleArguments = null; - return false; - } - - ruleArguments = attributes.Any(a => a.IsTimerDrift(compilation)) - ? new[] { "@TimerDrift" } - : new[] { "" }; - - return true; + ruleArguments = null; + return false; } - public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference) + ruleArguments = attributes.Any(a => a.IsTimerDrift(compilation)) + ? new[] { "@TimerDrift" } + : new[] { "" }; + + return true; + } + + public override void GenerateMigrationProperty( + StringBuilder source, Compilation compilation, string indent, SerializableProperty serializableProperty + ) + { + source.AppendLine($"{indent}internal readonly System.DateTime {serializableProperty.Name}Next;"); + source.AppendLine($"{indent}internal readonly System.TimeSpan {serializableProperty.Name}Delay;"); + } + + public override void GenerateDeserializationMethod( + StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false + ) + { + var expectedRule = RuleName; + var ruleName = property.Rule; + if (expectedRule != ruleName) { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } - - var propertyName = property.Name; - var ruleArguments = property.RuleArguments; - var driftTimer = ruleArguments![0].Contains("@TimerDrift"); - - var readTimer = driftTimer ? "reader.ReadDeltaTime()" : "reader.ReadDateTime()"; - source.AppendLine($"{indent}var {propertyName}Next = {readTimer};"); - source.AppendLine($"{indent}var {propertyName}Delay = {propertyName}Next == System.DateTime.MinValue ? System.TimeSpan.MinValue : {propertyName}Next - Core.Now;"); + throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); } - public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property) + var propertyName = property.Name; + var ruleArguments = property.RuleArguments; + var driftTimer = ruleArguments![0].Contains("@TimerDrift"); + + var readTimer = driftTimer ? "reader.ReadDeltaTime()" : "reader.ReadDateTime()"; + var useVar = isMigration ? "" : "var "; + source.AppendLine($"{indent}{useVar}{propertyName}Next = {readTimer};"); + source.AppendLine($"{indent}{useVar}{propertyName}Delay = {propertyName}Next == System.DateTime.MinValue ? System.TimeSpan.MinValue : {propertyName}Next - Core.Now;"); + } + + public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property) + { + var expectedRule = RuleName; + var ruleName = property.Rule; + if (expectedRule != ruleName) { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } - - var propertyName = property.Name; - var ruleArguments = property.RuleArguments; - var driftTimer = ruleArguments![0].Contains("@TimerDrift"); - - var writerMethod = driftTimer ? "WriteDeltaTime" : "Write"; - source.AppendLine($"{indent}writer.{writerMethod}({propertyName}?.Next ?? System.DateTime.MinValue);"); + throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); } - public void PostDeserializeMethod( - StringBuilder source, string indent, SerializableProperty property, Compilation compilation, INamedTypeSymbol classSymbol - ) - { - var deserializeTimerMethod = classSymbol - .GetMembers() - .OfType() - .FirstOrDefault( - m => + var propertyName = property.Name; + var ruleArguments = property.RuleArguments; + var driftTimer = ruleArguments![0].Contains("@TimerDrift"); + + var writerMethod = driftTimer ? "WriteDeltaTime" : "Write"; + source.AppendLine($"{indent}writer.{writerMethod}({propertyName}?.Next ?? System.DateTime.MinValue);"); + } + + public void PostDeserializeMethod( + StringBuilder source, string indent, SerializableProperty property, Compilation compilation, INamedTypeSymbol classSymbol + ) + { + var deserializeTimerMethod = classSymbol + .GetMembers() + .OfType() + .FirstOrDefault( + m => + { + if (!m.ReturnsVoid || m.Parameters.Length != 1 || !m.Parameters[0].Type.IsTimeSpan(compilation)) { - if (!m.ReturnsVoid || m.Parameters.Length != 1 || !m.Parameters[0].Type.IsTimeSpan(compilation)) - { - return false; - } + return false; + } - return m.GetAttributes() - .FirstOrDefault( - attr => - { - if (!SymbolEqualityComparer.Default.Equals( + return m.GetAttributes() + .FirstOrDefault( + attr => + { + if (!SymbolEqualityComparer.Default.Equals( attr.AttributeClass, compilation.GetTypeByMetadataName( SymbolMetadata.DESERIALIZE_TIMER_FIELD_ATTRIBUTE ) )) - { - return false; - } - - var order = (int)attr.ConstructorArguments[0].Value!; - return order == property.Order; + { + return false; } - ) != null; - } - ) ?? throw new Exception("Serializing a timer requires a method with the DeserializeTimerField attribute to handle creating the timer itself."); - source.AppendLine($"{indent}{deserializeTimerMethod.Name}({property.Name}Delay);"); - } + var order = (int)attr.ConstructorArguments[0].Value!; + return order == property.Order; + } + ) != null; + } + ) ?? throw new Exception("Serializing a timer requires a method with the DeserializeTimerField attribute to handle creating the timer itself."); + + source.AppendLine($"{indent}{deserializeTimerMethod.Name}({property.Name}Delay);"); } } From 284c3d0f34c70fab470c71ef37b4ec753a9fd72b Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Tue, 28 Dec 2021 14:32:45 -0800 Subject: [PATCH 054/213] fix: Removes LINQ from Map.cs (#834) * Removes LINQ from Map * Removes broken GetObjectsInRange with items/mobile flags. --- .../Benchmarks/Benchmarks/Map/MapSelectors.cs | 665 ++++++++++++++++++ Projects/Benchmarks/Program.cs | 2 + Projects/Server/Maps/Map.cs | 233 +++--- .../Implementors/AreaCommandImplementor.cs | 9 +- .../Engines/Factions/Core/Faction.cs | 7 +- .../Explosion Potions/BaseExplosionPotion.cs | 4 +- 6 files changed, 833 insertions(+), 87 deletions(-) create mode 100644 Projects/Benchmarks/Benchmarks/Map/MapSelectors.cs diff --git a/Projects/Benchmarks/Benchmarks/Map/MapSelectors.cs b/Projects/Benchmarks/Benchmarks/Map/MapSelectors.cs new file mode 100644 index 000000000..4c47b7189 --- /dev/null +++ b/Projects/Benchmarks/Benchmarks/Map/MapSelectors.cs @@ -0,0 +1,665 @@ +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Jobs; +using Server; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Benchmarks +{ + [SimpleJob(RuntimeMoniker.NetCoreApp50)] + public class MapSelectors + { + static readonly Sector sector = new Sector(); + static Server.Rectangle2D bounds = new Server.Rectangle2D(0, 0, 100, 100); + + public static void Init() + { + for (int i = 0; i < 50; ++i) + { + sector.Multis.Add(new BaseMulti()); + } + for (int i = 0; i < 1000; ++i) + { + sector.BItems.Add(new BItem()); + } + for (int i = 0; i < 1000; ++i) + { + sector.Mobiles.Add(new Mobile()); + } + } + + #region MultiTiles + [Benchmark] + public void SelectMultiTilesNew() + { + foreach(StaticTile[] tiles in SelectMultiTiles(sector, bounds)) + { + for(int i = 0; i < tiles.Length; ++i) + { + int id = tiles[i].ID; + } + } + } + + [Benchmark] + public void SelectMultiTilesLinq() + { + foreach(StaticTile[] tiles in SelectMultiTilesLinq(sector, bounds)) + { + for(int i = 0; i < tiles.Length; ++i) + { + int id = tiles[i].ID; + } + } + } + + public IEnumerable SelectMultiTilesLinq(Sector s, Server.Rectangle2D bounds) + { + foreach (var o in s.Multis.Where(o => o != null && !o.Deleted)) + { + var c = o.Components; + + int x, y, xo, yo; + StaticTile[] t, r; + + for (x = bounds.Start.X; x < bounds.End.X; x++) + { + xo = x - (o.X + c.Min.X); + + if (xo < 0 || xo >= c.Width) + { + continue; + } + + for (y = bounds.Start.Y; y < bounds.End.Y; y++) + { + yo = y - (o.Y + c.Min.Y); + + if (yo < 0 || yo >= c.Height) + { + continue; + } + + t = c.Tiles[xo][yo]; + + if (t.Length <= 0) + { + continue; + } + + r = new StaticTile[t.Length]; + + for (var i = 0; i < t.Length; i++) + { + r[i] = t[i]; + r[i].Z += o.Z; + } + + yield return r; + } + } + } + } + + public IEnumerable SelectMultiTiles(Sector s, Server.Rectangle2D bounds) + { + for (int l = s.Multis.Count - 1; l >= 0; --l) + { + BaseMulti o = s.Multis[l]; + if (o != null && !o.Deleted) + { + MultiComponentList c = o.Components; + + int x, y, xo, yo; + StaticTile[] t, r; + + for (x = bounds.Start.X; x < bounds.End.X; x++) + { + xo = x - (o.X + c.Min.X); + + if (xo < 0 || xo >= c.Width) + { + continue; + } + + for (y = bounds.Start.Y; y < bounds.End.Y; y++) + { + yo = y - (o.Y + c.Min.Y); + + if (yo < 0 || yo >= c.Height) + { + continue; + } + + t = c.Tiles[xo][yo]; + + if (t.Length <= 0) + { + continue; + } + + r = new StaticTile[t.Length]; + + for (var i = 0; i < t.Length; i++) + { + r[i] = t[i]; + r[i].Z += o.Z; + } + + yield return r; + } + } + } + } + } + + #endregion + + #region Multis + [Benchmark] + public void SelectMultisNew() + { + SelectMultis(sector, bounds); + } + + [Benchmark] + public void SelectMultisLinq() + { + SelectMultisLinq(sector, bounds); + } + + public IEnumerable SelectMultisLinq(Sector s, Server.Rectangle2D bounds) + { + return s.Multis.Where(o => o != null && !o.Deleted && bounds.Contains(o.Location)); + } + + public IEnumerable SelectMultis(Sector s, Server.Rectangle2D bounds) + { + List entities = new List(s.Multis.Count); + for (int i = s.Multis.Count - 1; i >= 0; --i) + { + BaseMulti BItem = s.Multis[i]; + if (BItem != null && !BItem.Deleted && bounds.Contains(BItem.Location)) + entities.Add(BItem); + } + return entities; + } + #endregion + + #region BItems + [Benchmark] + public void SelectBItemsNew() + { + SelectBItems(sector, bounds); + } + + [Benchmark] + public void SelectBItemsLinq() + { + SelectBItemsLinq(sector, bounds); + } + + public IEnumerable SelectBItemsLinq(Sector s, Server.Rectangle2D bounds) where T : BItem + { + return s.BItems.OfType().Where(o => o != null && !o.Deleted && o.Parent == null && bounds.Contains(o.Location)); + } + + public IEnumerable SelectBItems(Sector s, Server.Rectangle2D bounds) where T : BItem + { + List entities = new List(s.BItems.Count); + Type type = typeof(T); + for (int i = s.BItems.Count - 1; i >= 0; --i) + { + BItem BItem = s.BItems[i]; + if (BItem != null && !BItem.Deleted && BItem.Parent == null && bounds.Contains(BItem.Location) && type.IsAssignableFrom(BItem.GetType())) + entities.Add(BItem as T); + } + return entities; + } + #endregion + + #region Mobiles + [Benchmark] + public void SelectMobilesNew() + { + SelectMobiles(sector, bounds); + } + + [Benchmark] + public void SelectMobilesLinq() + { + SelectMobilesLinq(sector, bounds); + } + + public IEnumerable SelectMobilesLinq(Sector s, Server.Rectangle2D bounds) where T : Mobile + { + return s.Mobiles.OfType().Where(o => o != null && !o.Deleted && bounds.Contains(o.Location)); + } + + public IEnumerable SelectMobiles(Sector s, Server.Rectangle2D bounds) where T : Mobile + { + List entities = new List(s.Mobiles.Count); + Type type = typeof(T); + for (int i = s.Mobiles.Count - 1; i >= 0; --i) + { + Mobile mob = s.Mobiles[i]; + if (mob != null && !mob.Deleted && bounds.Contains(mob.Location) && type.IsAssignableFrom(mob.GetType())) + entities.Add(mob as T); + } + return entities; + } + #endregion + + #region Entities + [Benchmark] + public void SelectEntitiesNew() + { + SelectEntities(sector, bounds); + } + + [Benchmark] + public void SelectEntitiesLinq() + { + SelectEntitiesLinq(sector, bounds); + } + + public IEnumerable SelectEntitiesLinq(Sector s, Server.Rectangle2D bounds) + { + return Enumerable.Empty() + .Union(s.Mobiles.Where(o => o != null && !o.Deleted)) + .Union(s.BItems.Where(o => o != null && !o.Deleted && o.Parent == null)) + .Where(o => bounds.Contains(o.Location)); + } + + private readonly List entities = new (10); + public IEnumerable SelectEntities(Sector s, Server.Rectangle2D bounds) + { + entities.Clear(); + entities.Capacity = s.Mobiles.Count + s.BItems.Count; + for (int i = s.Mobiles.Count - 1, j = s.BItems.Count - 1; i >= 0 || j >= 0; --i, --j) + { + if (j >= 0) + { + BItem BItem = s.BItems[j]; + if (BItem != null && !BItem.Deleted && BItem.Parent == null && bounds.Contains(BItem.Location)) + entities.Add(BItem); + } + if (i >= 0) + { + Mobile mob = s.Mobiles[i]; + if (mob != null && !mob.Deleted && bounds.Contains(mob.Location)) + entities.Add(mob); + } + } + return entities; + } + #endregion + } + public class BItem : Server.IPoint3D, IEntity + { + public object Parent { get; set; } = null; + + public bool Deleted { get; set; } = false; + + public int Z { get; set; } = 1; + + public int X { get; set; } = 1; + + public int Y { get; set; } = 1; + + public Serial Serial => throw new System.NotImplementedException(); + + public Point3D Location { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); } + public Map Map { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); } + + public Region Region => throw new System.NotImplementedException(); + + public string Name { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); } + public int Hue { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); } + public Direction Direction { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); } + public DateTime Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public int TypeRef => throw new NotImplementedException(); + + Point3D IEntity.Location => throw new NotImplementedException(); + + Map IEntity.Map => throw new NotImplementedException(); + + int IPoint3D.Z => throw new NotImplementedException(); + + int IPoint2D.X => throw new NotImplementedException(); + + int IPoint2D.Y => throw new NotImplementedException(); + + DateTime ISerializable.Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + DateTime ISerializable.LastSerialized { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + long ISerializable.SavePosition { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + BufferWriter ISerializable.SaveBuffer { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + int ISerializable.TypeRef => throw new NotImplementedException(); + + Serial ISerializable.Serial => throw new NotImplementedException(); + + bool ISerializable.Deleted => throw new NotImplementedException(); + + public BItem() + { + + } + + public void Delete() + { + throw new System.NotImplementedException(); + } + + public void ProcessDelta() + { + throw new System.NotImplementedException(); + } + + public void OnStatsQuery(Server.Mobile m) + { + throw new System.NotImplementedException(); + } + + public void InvalidateProperties() + { + throw new System.NotImplementedException(); + } + + public int CompareTo(object obj) + { + throw new System.NotImplementedException(); + } + + public int CompareTo(IEntity other) + { + throw new System.NotImplementedException(); + } + + public void MoveToWorld(Point3D location, Map map) + { + throw new NotImplementedException(); + } + + public bool InRange(Point2D p, int range) + { + throw new NotImplementedException(); + } + + public bool InRange(Point3D p, int range) + { + throw new NotImplementedException(); + } + + public void RemoveBItem(BItem BItem) + { + throw new NotImplementedException(); + } + + public void BeforeSerialize() + { + throw new NotImplementedException(); + } + + public void Deserialize(IGenericReader reader) + { + throw new NotImplementedException(); + } + + public void Serialize(IGenericWriter writer) + { + throw new NotImplementedException(); + } + + public void SetTypeRef(Type type) + { + throw new NotImplementedException(); + } + + void IEntity.MoveToWorld(Point3D location, Map map) + { + throw new NotImplementedException(); + } + + void IEntity.ProcessDelta() + { + throw new NotImplementedException(); + } + + bool IEntity.InRange(Point2D p, int range) + { + throw new NotImplementedException(); + } + + bool IEntity.InRange(Point3D p, int range) + { + throw new NotImplementedException(); + } + + void ISerializable.BeforeSerialize() + { + throw new NotImplementedException(); + } + + void ISerializable.Deserialize(IGenericReader reader) + { + throw new NotImplementedException(); + } + + void ISerializable.Serialize(IGenericWriter writer) + { + throw new NotImplementedException(); + } + + void ISerializable.Delete() + { + throw new NotImplementedException(); + } + + void ISerializable.SetTypeRef(Type type) + { + throw new NotImplementedException(); + } + + public void RemoveItem(Item item) + { + throw new NotImplementedException(); + } + } + + public class Mobile : Server.IPoint3D, IEntity + { + public bool Deleted { get; set; } = false; + + public int Z { get; set; } = 1; + + public int X { get; set; } = 1; + + public int Y { get; set; } = 1; + + public Serial Serial => throw new System.NotImplementedException(); + + public Point3D Location { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); } + public Map Map { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); } + + public Region Region => throw new System.NotImplementedException(); + + public string Name { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); } + public int Hue { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); } + public Direction Direction { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); } + public DateTime Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public int TypeRef => throw new NotImplementedException(); + + Point3D IEntity.Location => throw new NotImplementedException(); + + Map IEntity.Map => throw new NotImplementedException(); + + int IPoint3D.Z => throw new NotImplementedException(); + + int IPoint2D.X => throw new NotImplementedException(); + + int IPoint2D.Y => throw new NotImplementedException(); + + DateTime ISerializable.Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + DateTime ISerializable.LastSerialized { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + long ISerializable.SavePosition { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + BufferWriter ISerializable.SaveBuffer { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + int ISerializable.TypeRef => throw new NotImplementedException(); + + Serial ISerializable.Serial => throw new NotImplementedException(); + + bool ISerializable.Deleted => throw new NotImplementedException(); + + public Mobile() + { + + } + + public void Delete() + { + throw new System.NotImplementedException(); + } + + public void ProcessDelta() + { + throw new System.NotImplementedException(); + } + + public void OnStatsQuery(Server.Mobile m) + { + throw new System.NotImplementedException(); + } + + public void InvalidateProperties() + { + throw new System.NotImplementedException(); + } + + public int CompareTo(object obj) + { + throw new System.NotImplementedException(); + } + + public int CompareTo(IEntity other) + { + throw new System.NotImplementedException(); + } + + public void MoveToWorld(Point3D location, Map map) + { + throw new NotImplementedException(); + } + + public bool InRange(Point2D p, int range) + { + throw new NotImplementedException(); + } + + public bool InRange(Point3D p, int range) + { + throw new NotImplementedException(); + } + + public void RemoveBItem(BItem BItem) + { + throw new NotImplementedException(); + } + + public void BeforeSerialize() + { + throw new NotImplementedException(); + } + + public void Deserialize(IGenericReader reader) + { + throw new NotImplementedException(); + } + + public void Serialize(IGenericWriter writer) + { + throw new NotImplementedException(); + } + + public void SetTypeRef(Type type) + { + throw new NotImplementedException(); + } + + void IEntity.MoveToWorld(Point3D location, Map map) + { + throw new NotImplementedException(); + } + + void IEntity.ProcessDelta() + { + throw new NotImplementedException(); + } + + bool IEntity.InRange(Point2D p, int range) + { + throw new NotImplementedException(); + } + + bool IEntity.InRange(Point3D p, int range) + { + throw new NotImplementedException(); + } + + void ISerializable.BeforeSerialize() + { + throw new NotImplementedException(); + } + + void ISerializable.Deserialize(IGenericReader reader) + { + throw new NotImplementedException(); + } + + void ISerializable.Serialize(IGenericWriter writer) + { + throw new NotImplementedException(); + } + + void ISerializable.Delete() + { + throw new NotImplementedException(); + } + + void ISerializable.SetTypeRef(Type type) + { + throw new NotImplementedException(); + } + + public void RemoveItem(Item item) + { + throw new NotImplementedException(); + } + } + + public class BaseMulti : BItem + { + public MultiComponentList Components = MultiComponentList.Empty; + + public BaseMulti() + { + for (int i = 0; i < 20; ++i) + for (int j = 0; j < 20; ++j) + for (int z = 0; z < 20; ++z) + Components.Add(123, i, j, z); + } + + } + + public class Sector + { + public List BItems { get; set; } = new List(); + public List Mobiles { get; set; } = new List(); + public List Multis { get; set; } = new List(); + } +} diff --git a/Projects/Benchmarks/Program.cs b/Projects/Benchmarks/Program.cs index 4b5671c0f..bfdadb1bc 100644 --- a/Projects/Benchmarks/Program.cs +++ b/Projects/Benchmarks/Program.cs @@ -15,6 +15,8 @@ namespace Benchmarks // var textEncoding = BenchmarkRunner.Run(); // var logging = BenchmarkRunner.Run(); // var gumpPacket = BenchmarkRunner.Run(); + // MapSelectors.Init(); + // var mapSelectors = BenchmarkRunner.Run(); // var rngTest = BenchmarkRunner.Run(); var doubleRngText = BenchmarkRunner.Run(); } diff --git a/Projects/Server/Maps/Map.cs b/Projects/Server/Maps/Map.cs index 5593ee918..f24ca663a 100644 --- a/Projects/Server/Maps/Map.cs +++ b/Projects/Server/Maps/Map.cs @@ -1,4 +1,5 @@ using System; +using System.Buffers; using System.Collections; using System.Collections.Generic; using System.Diagnostics; @@ -54,49 +55,97 @@ namespace Server public static IEnumerable SelectClients(Sector s, Rectangle2D bounds) { - return s.Clients.Where(o => o?.Mobile?.Deleted == false && bounds.Contains(o.Mobile.Location)); + var clients = new List(s.Clients.Count); + foreach (var client in s.Clients) + { + var m = client.Mobile; + + if (m?.Deleted == false && bounds.Contains(m.Location)) + { + clients.Add(client); + } + } + + return clients; } - public static IEnumerable SelectEntities(Sector s, Rectangle2D bounds) => - SelectEntities(s, true, true, bounds); - - public static IEnumerable SelectEntities(Sector s, bool items, bool mobiles, Rectangle2D bounds) + public static IEnumerable SelectEntities(Sector s, Rectangle2D bounds) { - var eable = Enumerable.Empty(); - if (mobiles) + var entities = new List(s.Mobiles.Count + s.Items.Count); + for (int i = s.Mobiles.Count - 1, j = s.Items.Count - 1; i >= 0 || j >= 0; --i, --j) { - eable = eable.Union(s.Mobiles.Where(o => o?.Deleted == false)); - } + if (j >= 0) + { + Item item = s.Items[j]; + if (item is { Deleted: false, Parent: null } && bounds.Contains(item.Location)) + { + entities.Add(item); + } + } - if (items) - { - eable = eable.Union(s.Items.Where(o => o?.Deleted == false && o.Parent == null)); + if (i >= 0) + { + Mobile mob = s.Mobiles[i]; + if (mob is { Deleted: false } && bounds.Contains(mob.Location)) + { + entities.Add(mob); + } + } } - - return eable.Where(o => bounds.Contains(o.Location)); + return entities; } public static IEnumerable SelectMobiles(Sector s, Rectangle2D bounds) where T : Mobile { - return s.Mobiles.OfType().Where(o => !o.Deleted && bounds.Contains(o.Location)); + var entities = new List(s.Mobiles.Count); + for (int i = s.Mobiles.Count - 1; i >= 0; --i) + { + if (s.Mobiles[i] is T { Deleted: false } mob && bounds.Contains(mob.Location)) + { + entities.Add(mob); + } + } + return entities; } public static IEnumerable SelectItems(Sector s, Rectangle2D bounds) where T : Item { - return s.Items.OfType() - .Where(o => o.Deleted == false && o.Parent == null && bounds.Contains(o.Location)); + var entities = new List(s.Items.Count); + for (int i = s.Items.Count - 1; i >= 0; --i) + { + if (s.Items[i] is T { Deleted: false, Parent: null } item && bounds.Contains(item.Location)) + { + entities.Add(item); + } + } + return entities; } public static IEnumerable SelectMultis(Sector s, Rectangle2D bounds) { - return s.Multis.Where(o => o?.Deleted == false && bounds.Contains(o.Location)); + var entities = new List(s.Multis.Count); + for (int i = s.Multis.Count - 1; i >= 0; --i) + { + BaseMulti multi = s.Multis[i]; + if (multi is { Deleted: false } && bounds.Contains(multi.Location)) + { + entities.Add(multi); + } + } + return entities; } public static IEnumerable SelectMultiTiles(Sector s, Rectangle2D bounds) { - foreach (var o in s.Multis.Where(o => o?.Deleted == false)) + for (int l = s.Multis.Count - 1; l >= 0; --l) { - var c = o.Components; + BaseMulti o = s.Multis[l]; + if (o?.Deleted != false) + { + continue; + } + + MultiComponentList c = o.Components; int x, y, xo, yo; StaticTile[] t, r; @@ -143,10 +192,8 @@ namespace Server public static Map.PooledEnumerable GetClients(Map map, Rectangle2D bounds) => Map.PooledEnumerable.Instantiate(map, bounds, ClientSelector ?? SelectClients); - public static Map.PooledEnumerable GetEntities( - Map map, Rectangle2D bounds, bool items = true, - bool mobiles = true - ) => Map.PooledEnumerable.Instantiate(map, bounds, EntitySelector ?? SelectEntities); + public static Map.PooledEnumerable GetEntities(Map map, Rectangle2D bounds) => + Map.PooledEnumerable.Instantiate(map, bounds, EntitySelector ?? SelectEntities); public static Map.PooledEnumerable GetMobiles(Map map, Rectangle2D bounds) => GetMobiles(map, bounds); @@ -272,9 +319,6 @@ namespace Server public const int SectorShift = 4; public const int SectorActiveRange = 2; - private static readonly Queue> m_FixPool = new(128); - private static readonly List m_EmptyFixItems = new(); - private static ILogger _logger; private static ILogger Logger => _logger ??= LogFactory.GetLogger(typeof(Map)); @@ -389,9 +433,55 @@ namespace Server public int CompareTo(Map other) => other == null ? -1 : MapID.CompareTo(other.MapID); - public static string[] GetMapNames() => Maps.Where(m => m != null).Select(m => m.Name).ToArray(); + public static string[] GetMapNames() + { + var mapCount = 0; + for (var i = 0; i < Maps.Length; i++) + { + var map = Maps[i]; + if (map != null) + { + mapCount++; + } + } - public static Map[] GetMapValues() => Maps.Where(m => m != null).ToArray(); + var mapNames = new string[mapCount]; + for (int i = 0, mIndex = 0; i < Maps.Length; i++) + { + var map = Maps[i]; + if (map != null) + { + mapNames[mIndex++] = map.Name; + } + } + + return mapNames; + } + + public static Map[] GetMapValues() + { + var mapCount = 0; + for (var i = 0; i < Maps.Length; i++) + { + var map = Maps[i]; + if (map != null) + { + mapCount++; + } + } + + var mapValues = new Map[mapCount]; + for (int i = 0, mIndex = 0; i < Maps.Length; i++) + { + var map = Maps[i]; + if (map != null) + { + mapValues[mIndex++] = map; + } + } + + return mapValues; + } public static Map Parse(string value) { @@ -498,54 +588,31 @@ namespace Server public IPooledEnumerable GetMultiTilesAt(int x, int y) => PooledEnumeration.GetMultiTiles(this, new Rectangle2D(x, y, 1, 1)); - private static List AcquireFixItems(Map map, int x, int y) + private static void AcquireFixItems(Map map, int x, int y, Item[] pool, out int length) { + length = 0; if (map == null || map == Internal || x < 0 || x > map.Width || y < 0 || y > map.Height) - { - return m_EmptyFixItems; - } - - List pool = null; - - lock (m_FixPool) - { - if (m_FixPool.Count > 0) - { - pool = m_FixPool.Dequeue(); - } - } - - pool ??= new List(128); // Arbitrary limit - - var eable = map.GetItemsInRange(new Point3D(x, y, 0), 0); - - pool.AddRange( - eable.Where(item => item.ItemID <= TileData.MaxItemValue && item is not BaseMulti) - .OrderBy(item => item.Z) - .Take(pool.Capacity) - ); - - eable.Free(); - - return pool; - } - - private static void FreeFixItems(List pool) - { - if (pool == m_EmptyFixItems) { return; } - pool.Clear(); - - lock (m_FixPool) + var eable = map.GetItemsInRange(new Point3D(x, y, 0), 0); + foreach (var item in eable) { - if (m_FixPool.Count < 128) + if (item is not BaseMulti && item.ItemID <= TileData.MaxItemValue) { - m_FixPool.Enqueue(pool); + if (length == 128) + { + break; + } + + pool[length++] = item; } } + + eable.Free(); + + Array.Sort(pool, ZComparer.Default); } public void FixColumn(int x, int y) @@ -555,9 +622,10 @@ namespace Server GetAverageZ(x, y, out _, out var landAvg, out _); - var items = AcquireFixItems(this, x, y); + var items = ArrayPool.Shared.Rent(128); + AcquireFixItems(this, x, y, items, out var length); - for (var i = 0; i < items.Count; i++) + for (var i = 0; i < length; i++) { var toFix = items[i]; @@ -592,7 +660,7 @@ namespace Server } } - for (var j = 0; j < items.Count; ++j) + for (var j = 0; j < length; ++j) { if (j == i) { @@ -622,7 +690,7 @@ namespace Server } } - FreeFixItems(items); + ArrayPool.Shared.Return(items); } /* This could probably be re-implemented if necessary (perhaps via an ITile interface?). @@ -1031,15 +1099,11 @@ namespace Server public IPooledEnumerable GetObjectsInRange(Point3D p) => GetObjectsInRange(p, Core.GlobalMaxUpdateRange); - public IPooledEnumerable GetObjectsInRange(Point3D p, int range, bool items = true, bool mobiles = true) => - GetObjectsInBounds( - new Rectangle2D(p.m_X - range, p.m_Y - range, range * 2 + 1, range * 2 + 1), - items, - mobiles - ); + public IPooledEnumerable GetObjectsInRange(Point3D p, int range) => + GetObjectsInBounds(new Rectangle2D(p.m_X - range, p.m_Y - range, range * 2 + 1, range * 2 + 1)); - public IPooledEnumerable GetObjectsInBounds(Rectangle2D bounds, bool items = true, bool mobiles = true) => - PooledEnumeration.GetEntities(this, bounds, items, mobiles); + public IPooledEnumerable GetObjectsInBounds(Rectangle2D bounds) => + PooledEnumeration.GetEntities(this, bounds); public IPooledEnumerable GetClientsInRange(Point3D p) => GetClientsInRange(p, Core.GlobalMaxUpdateRange); @@ -1188,6 +1252,13 @@ namespace Server public bool CanSpawnMobile(int x, int y, int z) => Region.Find(new Point3D(x, y, z), this).AllowSpawn() && CanFit(x, y, z, 16); + private class ZComparer : IComparer + { + public static readonly ZComparer Default = new(); + + public int Compare(Item x, Item y) => x!.Z.CompareTo(y!.Z); + } + public Sector GetSector(Point3D p) => InternalGetSector(p.m_X >> SectorShift, p.m_Y >> SectorShift); public Sector GetSector(Point2D p) => InternalGetSector(p.m_X >> SectorShift, p.m_Y >> SectorShift); @@ -1529,9 +1600,7 @@ namespace Server { public static readonly NullEnumerable Instance = new(); - private readonly IEnumerable m_Empty; - - private NullEnumerable() => m_Empty = Enumerable.Empty(); + private readonly IEnumerable m_Empty = Enumerable.Empty(); IEnumerator IEnumerable.GetEnumerator() => m_Empty.GetEnumerator(); diff --git a/Projects/UOContent/Commands/Generic/Implementors/AreaCommandImplementor.cs b/Projects/UOContent/Commands/Generic/Implementors/AreaCommandImplementor.cs index 12a3694a1..e203e988a 100644 --- a/Projects/UOContent/Commands/Generic/Implementors/AreaCommandImplementor.cs +++ b/Projects/UOContent/Commands/Generic/Implementors/AreaCommandImplementor.cs @@ -43,13 +43,18 @@ namespace Server.Commands.Generic return; } - var eable = map.GetObjectsInBounds(rect, items, mobiles); + var eable = map.GetObjectsInBounds(rect); var objs = new List(); foreach (var obj in eable) { - if ((!mobiles || obj is not Mobile || BaseCommand.IsAccessible(from, obj)) && ext.IsValid(obj)) + if (!mobiles && obj is Mobile || !items && obj is Item) + { + continue; + } + + if (BaseCommand.IsAccessible(from, obj) && ext.IsValid(obj)) { objs.Add(obj); } diff --git a/Projects/UOContent/Engines/Factions/Core/Faction.cs b/Projects/UOContent/Engines/Factions/Core/Faction.cs index 43d67c6ca..9345a7328 100644 --- a/Projects/UOContent/Engines/Factions/Core/Faction.cs +++ b/Projects/UOContent/Engines/Factions/Core/Faction.cs @@ -273,9 +273,14 @@ namespace Server.Factions return false; } - var eable = mob.Map.GetObjectsInRange(mob.Location, range, items, mobs); + var eable = mob.Map.GetObjectsInRange(mob.Location, range); foreach (var obj in eable) { + if (!mobs && obj is Mobile || !items && obj is Item) + { + continue; + } + if (type.IsInstanceOfType(obj)) { eable.Free(); diff --git a/Projects/UOContent/Items/Skill Items/Magical/Potions/Explosion Potions/BaseExplosionPotion.cs b/Projects/UOContent/Items/Skill Items/Magical/Potions/Explosion Potions/BaseExplosionPotion.cs index 01de15b12..a08b6a557 100644 --- a/Projects/UOContent/Items/Skill Items/Magical/Potions/Explosion Potions/BaseExplosionPotion.cs +++ b/Projects/UOContent/Items/Skill Items/Magical/Potions/Explosion Potions/BaseExplosionPotion.cs @@ -215,7 +215,7 @@ namespace Server.Items alchemyBonus = (int)(from.Skills.Alchemy.Value / (Core.AOS ? 5 : 10)); } - var eable = map.GetObjectsInRange(loc, ExplosionRange, LeveledExplosion); + var eable = map.GetObjectsInRange(loc, ExplosionRange); using var queue = PooledRefQueue.Create(); var toDamage = 0; @@ -234,7 +234,7 @@ namespace Server.Items queue.Enqueue(entity); } } - else if (entity is BaseExplosionPotion) + else if (LeveledExplosion && entity is BaseExplosionPotion) { queue.Enqueue(entity); } From 529fd90005dcab2f3fd8663df3f0c5cebfba375f Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Tue, 28 Dec 2021 19:00:16 -0800 Subject: [PATCH 055/213] chore: Cleanup enchanted sextant (#904) --- .../Quests/Core/Items/EnchantedSextant.cs | 54 +++++-------------- 1 file changed, 14 insertions(+), 40 deletions(-) diff --git a/Projects/UOContent/Engines/Quests/Core/Items/EnchantedSextant.cs b/Projects/UOContent/Engines/Quests/Core/Items/EnchantedSextant.cs index b671b2960..e30038aed 100644 --- a/Projects/UOContent/Engines/Quests/Core/Items/EnchantedSextant.cs +++ b/Projects/UOContent/Engines/Quests/Core/Items/EnchantedSextant.cs @@ -102,14 +102,8 @@ namespace Server.Items banks = m_IlshenarBanks; moongates = PMList.Ilshenar; #else - from.NetState.SendMessageLocalized( - Serial, - ItemID, - MessageType.Label, - 0x482, - 3, - 1061684 - ); // The magic of the sextant fails... + // The magic of the sextant fails... + from.NetState.SendMessageLocalized(Serial, ItemID, MessageType.Label, 0x482, 3, 1061684); return; #endif @@ -155,43 +149,23 @@ namespace Server.Items } } - int moonMsg; - if (moongateDistance == double.MaxValue) + int moonMsg = moongateDistance switch { - moonMsg = 1048021; // The sextant fails to find a Moongate nearby. - } - else if (moongateDistance > m_LongDistance) - { - moonMsg = 1046449 + (int)from.GetDirectionTo(closestMoongate); // A moongate is * from here - } - else if (moongateDistance > m_ShortDistance) - { - moonMsg = 1048010 + (int)from.GetDirectionTo(closestMoongate); // There is a Moongate * of here. - } - else - { - moonMsg = 1048018; // You are next to a Moongate at the moment. - } + double.MaxValue => 1048021, // The sextant fails to find a Moongate nearby. + > m_LongDistance => 1046449 + (int)from.GetDirectionTo(closestMoongate), // A moongate is * from here + > m_ShortDistance => 1048010 + (int)from.GetDirectionTo(closestMoongate), // There is a Moongate * of here. + _ => 1048018 // You are next to a Moongate at the moment. + }; from.NetState.SendMessageLocalized(Serial, ItemID, MessageType.Label, 0x482, 3, moonMsg); - int bankMsg; - if (bankDistance == double.MaxValue) + int bankMsg = bankDistance switch { - bankMsg = 1048020; // The sextant fails to find a Bank nearby. - } - else if (bankDistance > m_LongDistance) - { - bankMsg = 1046462 + (int)from.GetDirectionTo(closestBank); // A town is * from here - } - else if (bankDistance > m_ShortDistance) - { - bankMsg = 1048002 + (int)from.GetDirectionTo(closestBank); // There is a city Bank * of here. - } - else - { - bankMsg = 1048019; // You are next to a Bank at the moment. - } + double.MaxValue => 1048020, // The sextant fails to find a Bank nearby. + > m_LongDistance => 1046462 + (int)from.GetDirectionTo(closestBank), // A town is * from here + > m_ShortDistance => 1048002 + (int)from.GetDirectionTo(closestBank), // There is a city Bank * of here. + _ => 1048019 // You are next to a Bank at the moment. + }; from.NetState.SendMessageLocalized(Serial, ItemID, MessageType.Label, 0x5AA, 3, bankMsg); } From c1134c526fb91c2987ed7e8e973ab8d8bd4ea8fa Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Wed, 29 Dec 2021 10:10:53 -0800 Subject: [PATCH 056/213] fix: Fixes sorting (#905) --- Projects/Server/Maps/Map.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Projects/Server/Maps/Map.cs b/Projects/Server/Maps/Map.cs index f24ca663a..7f5e87d1f 100644 --- a/Projects/Server/Maps/Map.cs +++ b/Projects/Server/Maps/Map.cs @@ -612,7 +612,7 @@ namespace Server eable.Free(); - Array.Sort(pool, ZComparer.Default); + Array.Sort(pool, 0, length, ZComparer.Default); } public void FixColumn(int x, int y) From 752407d6f4ffcca49638959c47f1551c93096116 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Wed, 29 Dec 2021 10:18:27 -0800 Subject: [PATCH 057/213] fix: Fixes guild roster crash (#906) --- .../Gumps/Guilds/New Guild System/BaseGuildListGump.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Projects/UOContent/Gumps/Guilds/New Guild System/BaseGuildListGump.cs b/Projects/UOContent/Gumps/Guilds/New Guild System/BaseGuildListGump.cs index 8b09c06b2..f157ea4c9 100644 --- a/Projects/UOContent/Gumps/Guilds/New Guild System/BaseGuildListGump.cs +++ b/Projects/UOContent/Gumps/Guilds/New Guild System/BaseGuildListGump.cs @@ -31,7 +31,7 @@ namespace Server.Guilds m_List = list; } - public virtual bool WillFilter => m_Filter.Length >= 0; + public virtual bool WillFilter => m_Filter.Length > 0; public override void PopulateGump() { @@ -55,7 +55,7 @@ namespace Server.Guilds } m_List.Sort(m_Comparer); - m_StartNumber = Math.Clamp(m_StartNumber, 0, m_List.Count - 1); + m_StartNumber = Math.Max(Math.Min(m_StartNumber, m_List.Count - 1), 0); AddBackground(130, 75, 385, 30, 0xBB8); AddTextEntry(135, 80, 375, 30, 0x481, 1, m_Filter); @@ -109,8 +109,8 @@ namespace Server.Guilds else // descending, go from bottom of list to the top { for (var i = m_List.Count - 1 - m_StartNumber; - i >= 0 && i >= m_List.Count - itemsPerPage - m_StartNumber; - i--) + i >= 0 && i >= m_List.Count - itemsPerPage - m_StartNumber; + i--) { DrawEntry(m_List[i], i, itemNumber++); } From ba378fc5f279b71d91e2ebf6993f236dbc93480b Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Mon, 3 Jan 2022 14:19:39 -0800 Subject: [PATCH 058/213] fix: Adds Ubuntu 14 and Linux Mint 17/18/19 support specifically (#908) --- Directory.Build.props | 2 +- Projects/Server.Tests/Server.Tests.csproj | 2 +- Projects/Server/Server.csproj | 2 +- Projects/UOContent/UOContent.csproj | 8 ++++---- publish.cmd | 16 +++++++++++----- 5 files changed, 18 insertions(+), 12 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index be723978b..d0e008643 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -11,7 +11,7 @@ true true NU1603 - win-x64;debian.10-x64;debian.11-x64;ubuntu.16.04-x64;ubuntu.18.04-x64;ubuntu.20.04-x64;centos.7-x64;centos.8-x64;fedora.32-x64;fedora.33-x64;fedora.34-x64;rhel.7-x64;rhel.8-x64;osx-x64 + win-x64;debian.10-x64;debian.11-x64;ubuntu.16.04-x64;ubuntu.18.04-x64;ubuntu.20.04-x64;centos.7-x64;centos.8-x64;fedora.32-x64;fedora.33-x64;fedora.34-x64;rhel.7-x64;rhel.8-x64;linuxmint.17-x64;linuxmint.18-x64;linuxmint.19-x64;osx-x64 Debug;Release;Analyze false true diff --git a/Projects/Server.Tests/Server.Tests.csproj b/Projects/Server.Tests/Server.Tests.csproj index 6536e8cab..b33bf4c7d 100644 --- a/Projects/Server.Tests/Server.Tests.csproj +++ b/Projects/Server.Tests/Server.Tests.csproj @@ -7,7 +7,7 @@ - + diff --git a/Projects/Server/Server.csproj b/Projects/Server/Server.csproj index 392fccc6f..5293d55e6 100755 --- a/Projects/Server/Server.csproj +++ b/Projects/Server/Server.csproj @@ -36,7 +36,7 @@ - + diff --git a/Projects/UOContent/UOContent.csproj b/Projects/UOContent/UOContent.csproj index 06e297a52..f260b9a4c 100755 --- a/Projects/UOContent/UOContent.csproj +++ b/Projects/UOContent/UOContent.csproj @@ -38,12 +38,12 @@ false - + - - - + + + diff --git a/publish.cmd b/publish.cmd index e0f9fe6df..0490b16a8 100755 --- a/publish.cmd +++ b/publish.cmd @@ -12,7 +12,7 @@ elif [[ $(uname) = "Darwin" ]]; then os="-r osx-x64" elif [[ -f /etc/os-release ]]; then . /etc/os-release - NAME="$(tr '[:upper:]' '[:lower:]' <<< $NAME)" + NAME="$(tr '[:upper:]' '[:lower:]' <<< $NAME | tr -d [:blank:])" os="-r $NAME.$VERSION_ID-x64" fi @@ -32,8 +32,11 @@ dotnet clean --verbosity quiet echo dotnet restore --force-evaluate --source https://api.nuget.org/v3/index.json dotnet restore --force-evaluate --source https://api.nuget.org/v3/index.json -echo dotnet publish ${config} ${os} --framework net6.0 --no-restore --self-contained=false -o Distribution/Assemblies Projects/UOContent/UOContent.csproj -dotnet publish ${config} ${os} --framework net6.0 --no-restore --self-contained=false -o Distribution/Assemblies Projects/UOContent/UOContent.csproj +echo dotnet build -c Release Projects/SerializationGenerator/SerializationGenerator.csproj +dotnet build -c Release Projects/SerializationGenerator/SerializationGenerator.csproj + +echo dotnet publish ${config} ${os} --no-restore --self-contained=false -o Distribution/Assemblies Projects/UOContent/UOContent.csproj +dotnet publish ${config} ${os} --no-restore --self-contained=false -o Distribution/Assemblies Projects/UOContent/UOContent.csproj echo dotnet build -c Release Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj dotnet build -c Release Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj @@ -65,8 +68,11 @@ dotnet clean --verbosity quiet echo dotnet restore --force-evaluate --source https://api.nuget.org/v3/index.json dotnet restore --force-evaluate --source https://api.nuget.org/v3/index.json -echo dotnet publish %config% %os% --framework net6.0 --no-restore --self-contained=false -o Distribution\Assemblies Projects\UOContent\UOContent.csproj -dotnet publish %config% %os% --framework net6.0 --no-restore --self-contained=false -o Distribution\Assemblies Projects\UOContent\UOContent.csproj +echo dotnet build -c Release Projects/SerializationGenerator/SerializationGenerator.csproj +dotnet build -c Release Projects/SerializationGenerator/SerializationGenerator.csproj + +echo dotnet publish %config% %os% --no-restore --self-contained=false -o Distribution\Assemblies Projects\UOContent\UOContent.csproj +dotnet publish %config% %os% --no-restore --self-contained=false -o Distribution\Assemblies Projects\UOContent\UOContent.csproj echo dotnet build -c Release Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj dotnet build -c Release Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj From 4fd8b4d30749509999d510eed207e62405601478 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Mon, 3 Jan 2022 14:22:58 -0800 Subject: [PATCH 059/213] fix: Fixes crash from bad input in TC (#909) --- Projects/UOContent/Special Systems/Engines/TestCenter.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Projects/UOContent/Special Systems/Engines/TestCenter.cs b/Projects/UOContent/Special Systems/Engines/TestCenter.cs index 2c84bc177..d8d2505e4 100644 --- a/Projects/UOContent/Special Systems/Engines/TestCenter.cs +++ b/Projects/UOContent/Special Systems/Engines/TestCenter.cs @@ -52,10 +52,10 @@ namespace Server.Misc return; } - var value = double.Parse(valueStr); - try { + var value = double.Parse(valueStr); + if (name.InsensitiveEquals("str")) { ChangeStrength(from, (int)value); From 573ddfa27b5fa4ac301261dc351e7c0afe33a820 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Mon, 3 Jan 2022 19:05:28 -0800 Subject: [PATCH 060/213] docs: Updates installation docs for the main site. (#911) --- README.md | 11 ++++++++--- docs/assets/stylesheets/extra.css | 4 ++++ docs/building-server.md | 4 +++- docs/installation.md | 6 +++--- docs/overrides/.icons/brands/linuxmint.svg | 1 + docs/quick-start.md | 17 +++++++++++------ 6 files changed, 30 insertions(+), 13 deletions(-) create mode 100644 docs/overrides/.icons/brands/linuxmint.svg diff --git a/README.md b/README.md index 87a102ff7..0983a8826 100644 --- a/README.md +++ b/README.md @@ -19,16 +19,17 @@ ModernUO [![Discord](https://img.shields.io/discord/751317910504603701?logo=disc ![MacOS 10.15/11/12](https://img.shields.io/badge/-monterey-222222?logo=apple&logoColor=white) [![Debian 10/11](https://img.shields.io/badge/-bullseye-A81D33?logo=debian)](https://www.debian.org/distrib/) [![Ubuntu 16/18/20 LTS](https://img.shields.io/badge/-20LTS-E95420?logo=ubuntu&logoColor=white)](https://ubuntu.com/download/server) +[![Linux Mint 17/18/19/20](https://img.shields.io/badge/-20-87CF3E?logo=linux%20mint&logoColor=white)](https://linuxmint.com/download.php) [![CentOS 7/8](https://img.shields.io/badge/-8.5-262577?logo=centos&logoColor=white)](https://www.centos.org/download/) [![Fedora 32/33/34](https://img.shields.io/badge/-fedora%2034-0B57A4)](https://getfedora.org/en/server/download/) [![RedHat 7/8](https://img.shields.io/badge/-8-BE0000?logo=red%20hat&logoColor=white)](https://access.redhat.com/downloads) #### Running the server -[![.NET](https://img.shields.io/badge/.NET-%206.0-5C2D91)](https://dotnet.microsoft.com/download/dotnet/6.0) +[![.NET](https://img.shields.io/badge/-6.0-5C2D91?logo=.NET)](https://dotnet.microsoft.com/download/dotnet/6.0) #### Development [![git](https://img.shields.io/badge/-git-F05032?logo=git&logoColor=white)](https://git-scm.com/downloads) -[![.NET](https://img.shields.io/badge/.NET-%206.0%20SDK-5C2D91)](https://dotnet.microsoft.com/download/dotnet/6.0) +[![.NET](https://img.shields.io/badge/-%206.0%20SDK-5C2D91?logo=.NET)](https://dotnet.microsoft.com/download/dotnet/6.0) #### Supported IDEs     @@ -51,11 +52,12 @@ Rider 2021.3+           & - `win` - Windows 10/11/2016/2019/2022 - `osx` - MacOS 10.15/11.0+/12.0+ (Catalina, Big Sur, Monterey) - `ubuntu.16.04`, `ubuntu.18.04` `ubuntu.20.04` - Ubuntu LTS + - `linuxmint.17`, `linuxmint.18`, `linuxmint.19` - Linux Mint - `debian.10`, `debian.11` - Debian - `centos.7`, `centos.8` - CentOS - `fedora.32`, `fedora.33`, `fedora.34` - Fedora - `rhel.7`, `rhel.8` - Redhat - - If blank, the operating system running the build is used + - If blank, the operating system running the build is used. Linux Mint 20 is not supported directly yet, so build explicitly against `ubuntu.20.04` instead. **Note:** Building in Visual Studio (or Rider) will not run the schema migration. The schema migration ensures future changes to the code will be backward compatible. @@ -64,6 +66,9 @@ to the code will be backward compatible. - Follow the [publish](https://github.com/modernuo/ModernUO#publishing-builds) instructions - Run `ModernUO.exe` or `dotnet ModernUO.dll` from the `Distribution` directory on the server +**Note:** If you are running a version of linux that isn't listed above, then you may have to install the following using a package manager: + * `libargon2-dev`, `libz-dev`, and `zstd` + ## Thanks - RunUO Team & Community - ServUO Team & Community diff --git a/docs/assets/stylesheets/extra.css b/docs/assets/stylesheets/extra.css index 361f284ce..73389904f 100644 --- a/docs/assets/stylesheets/extra.css +++ b/docs/assets/stylesheets/extra.css @@ -82,6 +82,10 @@ html .md-footer-meta.md-typeset a:hover { color: #e95420; } +.linuxmint { + color: #87CF3E; +} + .debian { color: #d70a53; } diff --git a/docs/building-server.md b/docs/building-server.md index b167e1c6a..232f1f930 100644 --- a/docs/building-server.md +++ b/docs/building-server.md @@ -23,6 +23,8 @@ The operating system to build the server against. If not specified then the serv :fontawesome-brands-windows:{: .windows } `win`
:fontawesome-brands-apple:{: .apple } `osx`
-:fontawesome-brands-ubuntu:{: .ubuntu } `ubuntu.16.04`, `ubuntu.18.04` `ubuntu.20.04`
+:fontawesome-brands-ubuntu:{: .ubuntu } `ubuntu.14.04` `ubuntu.16.04`, `ubuntu.18.04` `ubuntu.20.04`
+:brands-linuxmint:{: .linuxmint } `linuxmint.17` `linuxmint.18`, `linuxmint.19`
:brands-debian:{: .debian } `debian.9`, `debian.10`
:fontawesome-brands-centos:{: .centos } `centos.7`, `centos.8` +:fontawesome-brands-redhat:{: .redhat } `redhat.7`, `redhat.8` diff --git a/docs/installation.md b/docs/installation.md index a6bd079ec..6fcb6d794 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -6,7 +6,7 @@ title: Installation === "Windows" ### Prerequisites - 1. Download and install the latest [.NET 5 SDK](https://dotnet.microsoft.com/download/dotnet/5.0) + 1. Download and install the latest [.NET 6 SDK](https://dotnet.microsoft.com/download/dotnet/6.0) 1. Download and install from [here](https://git-scm.com/download/win) !!! Tip @@ -22,7 +22,7 @@ title: Installation === "OSX"

Prerequisites

- 1. Download and install the latest [.NET 5 SDK](https://dotnet.microsoft.com/download/dotnet/5.0) + 1. Download and install the latest [.NET 6 SDK](https://dotnet.microsoft.com/download/dotnet/6.0) 1. Using _terminal_, install [homebrew](https://brew.sh) and git: ```bash /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)" @@ -37,7 +37,7 @@ title: Installation === "Linux"

Prerequisites

- 1. Download and install the latest [.NET Core SDK](instructions [here](https://docs.microsoft.com/en-us/dotnet/core/install/linux)) + 1. Download and install the latest [.NET 6 SDK](instructions [here](https://docs.microsoft.com/en-us/dotnet/core/install/linux)) 1. Using _bash_, install git: ```bash sudo apt update && sudo apt install git diff --git a/docs/overrides/.icons/brands/linuxmint.svg b/docs/overrides/.icons/brands/linuxmint.svg new file mode 100644 index 000000000..a9dcf1131 --- /dev/null +++ b/docs/overrides/.icons/brands/linuxmint.svg @@ -0,0 +1 @@ +Linux Mint \ No newline at end of file diff --git a/docs/quick-start.md b/docs/quick-start.md index 189b4841e..bd14b4f75 100644 --- a/docs/quick-start.md +++ b/docs/quick-start.md @@ -7,20 +7,25 @@ title: Quick Start If you are familiar with RunUO, then follow these steps to get your ModernUO server running in less than 10 minutes: === "Windows" - 1. Download and install the [.NET 5 Runtime](https://dotnet.microsoft.com/download/dotnet/5.0) - 1. Download and extract [ModernUO](https://github.com/modernuo/ModernUO/releases/latest) to a folder. + 1. Download and install the [.NET 6 Runtime](https://dotnet.microsoft.com/download/dotnet/6.0) + 1. Using [git](https://git-scm.com/downloads), clone the ModernUO repository to a folder. + 1. Run publish.cmd 1. Navigate to the _Distribution_ folder. 1. Run `ModernUO.exe` === "OSX" - 1. Download and install the [.NET 5 Runtime](https://dotnet.microsoft.com/download/dotnet/5.0) - 1. Download and extract [ModernUO](https://github.com/modernuo/ModernUO/releases/latest) to a folder. + 1. Download and install the [.NET 6 Runtime](https://dotnet.microsoft.com/download/dotnet/6.0) + 1. Using [git](https://git-scm.com/downloads), clone the ModernUO repository to a folder. + 1. Using _terminal_, navigate to the _ModernUO_ folder. + 1. Run `./publish.cmd` 1. Using _terminal_, navigate to the _Distribution_ folder. 1. Run `dotnet ModernUO.dll` === "Linux" - 1. Download and install the [.NET 5 Runtime](instructions [here](https://docs.microsoft.com/en-us/dotnet/core/install/linux)) - 1. Download and extract [ModernUO](https://github.com/modernuo/ModernUO/releases/latest) to a folder. + 1. Download and install the [.NET 6 Runtime](https://docs.microsoft.com/en-us/dotnet/core/install/linux) + 1. Using [git](https://git-scm.com/downloads), clone the ModernUO repository to a folder. + 1. Using _bash_, navigate to the _ModernUO_ folder. + 1. Run `./publish.cmd` 1. Using _bash_, navigate to the _Distribution_ folder. 1. Run `dotnet ModernUO.dll` From 08df0307e58fe7fe1e8a8a0cfa11fcc92625b634 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Mon, 3 Jan 2022 19:08:50 -0800 Subject: [PATCH 061/213] docs: Adds workflow dispatch --- .github/workflows/update-docs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/update-docs.yml b/.github/workflows/update-docs.yml index ccd2c2280..62b080225 100644 --- a/.github/workflows/update-docs.yml +++ b/.github/workflows/update-docs.yml @@ -3,6 +3,7 @@ name: Updates Docs on: repository_dispatch: types: [docs] + workflow_dispatch: jobs: update-docs: From 24c683870d24ddf50dd23041c1f1b68af2f9c181 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Mon, 3 Jan 2022 22:10:29 -0800 Subject: [PATCH 062/213] docs: Updates markdown docs (#912) --- docs/assets/stylesheets/extra.css | 10 +++++++++- docs/building-server.md | 5 +++-- docs/installation.md | 12 +++++------ docs/quick-start.md | 33 ------------------------------- mkdocs.yml | 7 ++++--- 5 files changed, 22 insertions(+), 45 deletions(-) delete mode 100644 docs/quick-start.md diff --git a/docs/assets/stylesheets/extra.css b/docs/assets/stylesheets/extra.css index 73389904f..dfe2e4d38 100644 --- a/docs/assets/stylesheets/extra.css +++ b/docs/assets/stylesheets/extra.css @@ -83,17 +83,25 @@ html .md-footer-meta.md-typeset a:hover { } .linuxmint { - color: #87CF3E; + color: #87cF3e; } .debian { color: #d70a53; } +.fedora { + color: #3c6eb4; +} + .centos { color: #212078; } +.redhat { + color: #be0000; +} + .codehilitetable .linenodiv pre, .highlighttable .linenodiv pre { color: var(--md-default-bg-color); } diff --git a/docs/building-server.md b/docs/building-server.md index 232f1f930..9e2e63b71 100644 --- a/docs/building-server.md +++ b/docs/building-server.md @@ -24,7 +24,8 @@ The operating system to build the server against. If not specified then the serv :fontawesome-brands-windows:{: .windows } `win`
:fontawesome-brands-apple:{: .apple } `osx`
:fontawesome-brands-ubuntu:{: .ubuntu } `ubuntu.14.04` `ubuntu.16.04`, `ubuntu.18.04` `ubuntu.20.04`
-:brands-linuxmint:{: .linuxmint } `linuxmint.17` `linuxmint.18`, `linuxmint.19`
+:brands-linuxmint:{: .linuxmint } `linuxmint.17` `linuxmint.18`, `linuxmint.19`, `ubuntu.20.04` for v20
:brands-debian:{: .debian } `debian.9`, `debian.10`
-:fontawesome-brands-centos:{: .centos } `centos.7`, `centos.8` +:fontawesome-brands-fedora:{: .fedora } `fedora.32`, `fedora.33`, `fedora.34`
+:fontawesome-brands-centos:{: .centos } `centos.7`, `centos.8`
:fontawesome-brands-redhat:{: .redhat } `redhat.7`, `redhat.8` diff --git a/docs/installation.md b/docs/installation.md index 6fcb6d794..edf4c673b 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -21,14 +21,14 @@ title: Installation ``` === "OSX" -

Prerequisites

- 1. Download and install the latest [.NET 6 SDK](https://dotnet.microsoft.com/download/dotnet/6.0) + ### Prerequisites + 1. Download and install the latest [.NET 6 SDK](https://dotnet.microsoft.com/download/dotnet/6.0). 1. Using _terminal_, install [homebrew](https://brew.sh) and git: ```bash /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)" brew install git ``` -

Install ModernUO

+ ### Install ModernUO 1. Using _terminal_, navigate to the folder where you want to install ModernUO and run: ```bash git clone https://github.com/modernuo/modernuo @@ -36,8 +36,8 @@ title: Installation ``` === "Linux" -

Prerequisites

- 1. Download and install the latest [.NET 6 SDK](instructions [here](https://docs.microsoft.com/en-us/dotnet/core/install/linux)) + ### Prerequisites + 1. Download and install the latest [.NET 6 SDK](https://docs.microsoft.com/en-us/dotnet/core/install/linux). 1. Using _bash_, install git: ```bash sudo apt update && sudo apt install git @@ -46,7 +46,7 @@ title: Installation !!! Note The command to install git might be different for your flavor of linux. Consult your local Google search for answers. -

Install ModernUO

+ ### Install ModernUO 1. Using _bash_, navigate to the folder where you want to install ModernUO and run: ```bash git clone https://github.com/modernuo/modernuo diff --git a/docs/quick-start.md b/docs/quick-start.md deleted file mode 100644 index bd14b4f75..000000000 --- a/docs/quick-start.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: Quick Start ---- - -# Quick Start - -If you are familiar with RunUO, then follow these steps to get your ModernUO server running in less than 10 minutes: - -=== "Windows" - 1. Download and install the [.NET 6 Runtime](https://dotnet.microsoft.com/download/dotnet/6.0) - 1. Using [git](https://git-scm.com/downloads), clone the ModernUO repository to a folder. - 1. Run publish.cmd - 1. Navigate to the _Distribution_ folder. - 1. Run `ModernUO.exe` - -=== "OSX" - 1. Download and install the [.NET 6 Runtime](https://dotnet.microsoft.com/download/dotnet/6.0) - 1. Using [git](https://git-scm.com/downloads), clone the ModernUO repository to a folder. - 1. Using _terminal_, navigate to the _ModernUO_ folder. - 1. Run `./publish.cmd` - 1. Using _terminal_, navigate to the _Distribution_ folder. - 1. Run `dotnet ModernUO.dll` - -=== "Linux" - 1. Download and install the [.NET 6 Runtime](https://docs.microsoft.com/en-us/dotnet/core/install/linux) - 1. Using [git](https://git-scm.com/downloads), clone the ModernUO repository to a folder. - 1. Using _bash_, navigate to the _ModernUO_ folder. - 1. Run `./publish.cmd` - 1. Using _bash_, navigate to the _Distribution_ folder. - 1. Run `dotnet ModernUO.dll` - -!!! Note - Follow the rest of the [Get Started](../installation) guide to learn how to connect, configure, and customize, your server. diff --git a/mkdocs.yml b/mkdocs.yml index d0dbbf9f4..58cee9c59 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -41,14 +41,16 @@ markdown_extensions: - admonition - footnotes - meta - - markdown.extensions.toc: + - toc: + toc_depth: "1-1" permalink: true - attr_list - pymdownx.highlight - pymdownx.inlinehilite - pymdownx.superfences - pymdownx.snippets - - pymdownx.tabbed + - pymdownx.tabbed: + alternate_style: true - pymdownx.caret - pymdownx.mark - pymdownx.tilde @@ -67,6 +69,5 @@ markdown_extensions: nav: - Home: 'index.md' - 'Get Started': - - 'quick-start.md' - 'installation.md' - 'building-server.md' From 2f13dfebedc146ad7a108fcdc7521f17722f0741 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Mon, 3 Jan 2022 22:16:56 -0800 Subject: [PATCH 063/213] docs: Fixes edit uri for docs (#913) --- mkdocs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/mkdocs.yml b/mkdocs.yml index 58cee9c59..dcb2d826d 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -3,6 +3,7 @@ site_name: ModernUO site_author: Kamron Batman site_url: https://modernuo.com +edit_uri: edit/main/docs/ # Repository repo_name: modernuo/modernuo From 51169ddbb09b229374ae7791373e656473bd26bf Mon Sep 17 00:00:00 2001 From: Stefano Merotta <97297186+stefanomerotta@users.noreply.github.com> Date: Sat, 8 Jan 2022 07:42:37 +0100 Subject: [PATCH 064/213] Refactored map selector benchmarks (#914) --- Projects/Benchmarks/Benchmarks.csproj | 2 + .../Benchmarks/Map/MapEntitiesSelectors.cs | 545 ++++++++++++++ .../Benchmarks/Map/MapItemSelectors.cs | 403 +++++++++++ .../Benchmarks/Map/MapMobileSelectors.cs | 255 +++++++ .../Benchmarks/Map/MapMultiSelectors.cs | 311 ++++++++ .../Benchmarks/Map/MapMultiTilesSelectors.cs | 352 +++++++++ .../Benchmarks/Benchmarks/Map/MapSelectors.cs | 665 ------------------ Projects/Benchmarks/Program.cs | 16 +- 8 files changed, 1880 insertions(+), 669 deletions(-) create mode 100644 Projects/Benchmarks/Benchmarks/Map/MapEntitiesSelectors.cs create mode 100644 Projects/Benchmarks/Benchmarks/Map/MapItemSelectors.cs create mode 100644 Projects/Benchmarks/Benchmarks/Map/MapMobileSelectors.cs create mode 100644 Projects/Benchmarks/Benchmarks/Map/MapMultiSelectors.cs create mode 100644 Projects/Benchmarks/Benchmarks/Map/MapMultiTilesSelectors.cs delete mode 100644 Projects/Benchmarks/Benchmarks/Map/MapSelectors.cs diff --git a/Projects/Benchmarks/Benchmarks.csproj b/Projects/Benchmarks/Benchmarks.csproj index eff9ed660..ca226bba4 100644 --- a/Projects/Benchmarks/Benchmarks.csproj +++ b/Projects/Benchmarks/Benchmarks.csproj @@ -10,6 +10,8 @@ + + diff --git a/Projects/Benchmarks/Benchmarks/Map/MapEntitiesSelectors.cs b/Projects/Benchmarks/Benchmarks/Map/MapEntitiesSelectors.cs new file mode 100644 index 000000000..7348824c8 --- /dev/null +++ b/Projects/Benchmarks/Benchmarks/Map/MapEntitiesSelectors.cs @@ -0,0 +1,545 @@ +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Jobs; +using NetFabric.Hyperlinq; +using Server; +using System; +using System.Collections.Generic; +using System.Linq; +using static NetFabric.Hyperlinq.ArrayExtensions; + +namespace Benchmarks.EntitiesSelectors +{ + [SimpleJob(RuntimeMoniker.Net60)] + [MemoryDiagnoser] + public class MapEntitiesSelectors + { + private static readonly Sector sector = new(); + private static readonly Point3D[] locations = new[] { new Point3D(0, 0, 0), new Point3D(50, 50, 0) }; + + public static Rectangle2D[] BoundsArray() => new[] + { + new Rectangle2D(70, 70, 100, 100), + new Rectangle2D(30, 30, 100, 100), + new Rectangle2D(0, 0, 100, 100), + }; + + [GlobalSetup] + public static void Init() + { + for (int j = 0; j < locations.Length; j++) + { + Point3D loc = locations[j]; + + for (int i = 0; i < 500; ++i) + { + sector.BItems.Add(new BItem(loc)); + } + + for (int i = 0; i < 25; ++i) + { + sector.Mobiles.Add(new Mobile(loc)); + } + } + } + + [ParamsSource(nameof(BoundsArray))] + public Rectangle2D bounds; + + [Benchmark(Baseline = true)] + public IEntity SelectEntitiesFor() + { + IEntity toRet = null; + for (int i = sector.Mobiles.Count - 1; i >= 0; --i) + { + Mobile mob = sector.Mobiles[i]; + if (mob is { Deleted: false } tMob && bounds.Contains(mob.Location)) + { + toRet = tMob; + } + } + + for (int i = sector.BItems.Count - 1; i >= 0; --i) + { + BItem item = sector.BItems[i]; + if (item is { Deleted: false, Parent: null } tItem && bounds.Contains(item.Location)) + { + toRet = tItem; + } + } + + return toRet; + } + + [Benchmark] + public IEntity SelectEntitiesNew() + { + IEntity toRet = null; + foreach (IEntity e in SelectEntitiesNew(sector, bounds)) + { + toRet = e; + } + + return toRet; + } + + [Benchmark] + public IEntity SelectEntitiesLinq() + { + IEntity toRet = null; + foreach (IEntity e in SelectEntitiesLinq(sector, bounds)) + { + toRet = e; + } + + return toRet; + } + + [Benchmark] + public IEntity SelectMobilesHyperLinq() + { + IEntity toRet = null; + foreach (IEntity e in SelectEntitiesHyperlinq(sector, bounds)) + { + toRet = e; + } + + return toRet; + } + + + public IEnumerable SelectEntitiesLinq(Sector s, Rectangle2D bounds) + { + return Enumerable.Empty() + .Union(s.Mobiles.Where(o => o is { Deleted: false } && bounds.Contains(o.Location))) + .Union(s.BItems.Where(o => o is { Deleted: false, Parent: null } && bounds.Contains(o.Location))); + } + + private readonly List entities = new(10); + + public IEnumerable SelectEntitiesNew(Sector s, Rectangle2D bounds) + { + entities.Clear(); + entities.EnsureCapacity(s.Mobiles.Count + s.BItems.Count); + + for (int i = s.Mobiles.Count - 1, j = s.BItems.Count - 1; i >= 0 || j >= 0; --i, --j) + { + if (j >= 0) + { + BItem BItem = s.BItems[j]; + if (BItem is { Deleted: false, Parent: null } && bounds.Contains(BItem.Location)) + { + entities.Add(BItem); + } + } + if (i >= 0) + { + Mobile mob = s.Mobiles[i]; + if (mob is { Deleted: false } && bounds.Contains(mob.Location)) + { + entities.Add(mob); + } + } + } + return entities; + } + + public IEnumerable SelectEntitiesHyperlinq(Sector s, Rectangle2D bounds) + { + ArraySegmentWhereSelectEnumerable> mobiles = + s.Mobiles.AsValueEnumerable().Where(new MobileWhereHyper(bounds)).Select>(); + + ArraySegmentWhereSelectEnumerable> items = + s.BItems.AsValueEnumerable().Where(new BItemWhereHyper(bounds)).Select>(); + + return mobiles.Concat(items); + } + } + + public class BItem : IPoint3D, IEntity + { + public object Parent { get; set; } = null; + + public bool Deleted { get; set; } = false; + + public int Z { get; set; } = 1; + + public int X { get; set; } = 1; + + public int Y { get; set; } = 1; + + public Serial Serial => throw new NotImplementedException(); + + public Point3D Location { get; } + public Map Map { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public Region Region => throw new NotImplementedException(); + + public string Name { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public int Hue { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public Direction Direction { get => throw new System.NotImplementedException(); set => throw new NotImplementedException(); } + public DateTime Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public int TypeRef => throw new NotImplementedException(); + + Point3D IEntity.Location => Location; + + Map IEntity.Map => throw new NotImplementedException(); + + int IPoint3D.Z => throw new NotImplementedException(); + + int IPoint2D.X => throw new NotImplementedException(); + + int IPoint2D.Y => throw new NotImplementedException(); + + DateTime ISerializable.Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + DateTime ISerializable.LastSerialized { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + long ISerializable.SavePosition { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + BufferWriter ISerializable.SaveBuffer { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + int ISerializable.TypeRef => throw new NotImplementedException(); + + Serial ISerializable.Serial => throw new NotImplementedException(); + + bool ISerializable.Deleted => throw new NotImplementedException(); + + public BItem(Point3D location) + { + Location = location; + } + + public void Delete() + { + throw new NotImplementedException(); + } + + public void ProcessDelta() + { + throw new NotImplementedException(); + } + + public void OnStatsQuery(Server.Mobile m) + { + throw new NotImplementedException(); + } + + public void InvalidateProperties() + { + throw new NotImplementedException(); + } + + public int CompareTo(object obj) + { + throw new NotImplementedException(); + } + + public int CompareTo(IEntity other) + { + throw new NotImplementedException(); + } + + public void MoveToWorld(Point3D location, Map map) + { + throw new NotImplementedException(); + } + + public bool InRange(Point2D p, int range) + { + throw new NotImplementedException(); + } + + public bool InRange(Point3D p, int range) + { + throw new NotImplementedException(); + } + + public void RemoveBItem(BItem BItem) + { + throw new NotImplementedException(); + } + + public void BeforeSerialize() + { + throw new NotImplementedException(); + } + + public void Deserialize(IGenericReader reader) + { + throw new NotImplementedException(); + } + + public void Serialize(IGenericWriter writer) + { + throw new NotImplementedException(); + } + + public void SetTypeRef(Type type) + { + throw new NotImplementedException(); + } + + void IEntity.MoveToWorld(Point3D location, Map map) + { + throw new NotImplementedException(); + } + + void IEntity.ProcessDelta() + { + throw new NotImplementedException(); + } + + bool IEntity.InRange(Point2D p, int range) + { + throw new NotImplementedException(); + } + + bool IEntity.InRange(Point3D p, int range) + { + throw new NotImplementedException(); + } + + void ISerializable.BeforeSerialize() + { + throw new NotImplementedException(); + } + + void ISerializable.Deserialize(IGenericReader reader) + { + throw new NotImplementedException(); + } + + void ISerializable.Serialize(IGenericWriter writer) + { + throw new NotImplementedException(); + } + + void ISerializable.Delete() + { + throw new NotImplementedException(); + } + + void ISerializable.SetTypeRef(Type type) + { + throw new NotImplementedException(); + } + + public void RemoveItem(Item item) + { + throw new NotImplementedException(); + } + } + + public class Mobile : IPoint3D, IEntity + { + public bool Deleted { get; set; } = false; + + public int Z { get; set; } = 1; + + public int X { get; set; } = 1; + + public int Y { get; set; } = 1; + + public Serial Serial => throw new NotImplementedException(); + + public Point3D Location { get; } + public Map Map { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public Region Region => throw new NotImplementedException(); + + public string Name { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public int Hue { get => throw new System.NotImplementedException(); set => throw new NotImplementedException(); } + public Direction Direction { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public DateTime Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public int TypeRef => throw new NotImplementedException(); + + Point3D IEntity.Location => Location; + + Map IEntity.Map => throw new NotImplementedException(); + + int IPoint3D.Z => throw new NotImplementedException(); + + int IPoint2D.X => throw new NotImplementedException(); + + int IPoint2D.Y => throw new NotImplementedException(); + + DateTime ISerializable.Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + DateTime ISerializable.LastSerialized { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + long ISerializable.SavePosition { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + BufferWriter ISerializable.SaveBuffer { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + int ISerializable.TypeRef => throw new NotImplementedException(); + + Serial ISerializable.Serial => throw new NotImplementedException(); + + bool ISerializable.Deleted => throw new NotImplementedException(); + + public Mobile(Point3D location) + { + Location = location; + } + + public void Delete() + { + throw new NotImplementedException(); + } + + public void ProcessDelta() + { + throw new NotImplementedException(); + } + + public void OnStatsQuery(Server.Mobile m) + { + throw new NotImplementedException(); + } + + public void InvalidateProperties() + { + throw new NotImplementedException(); + } + + public int CompareTo(object obj) + { + throw new NotImplementedException(); + } + + public int CompareTo(IEntity other) + { + throw new NotImplementedException(); + } + + public void MoveToWorld(Point3D location, Map map) + { + throw new NotImplementedException(); + } + + public bool InRange(Point2D p, int range) + { + throw new NotImplementedException(); + } + + public bool InRange(Point3D p, int range) + { + throw new NotImplementedException(); + } + + public void RemoveBItem(BItem BItem) + { + throw new NotImplementedException(); + } + + public void BeforeSerialize() + { + throw new NotImplementedException(); + } + + public void Deserialize(IGenericReader reader) + { + throw new NotImplementedException(); + } + + public void Serialize(IGenericWriter writer) + { + throw new NotImplementedException(); + } + + public void SetTypeRef(Type type) + { + throw new NotImplementedException(); + } + + void IEntity.MoveToWorld(Point3D location, Map map) + { + throw new NotImplementedException(); + } + + void IEntity.ProcessDelta() + { + throw new NotImplementedException(); + } + + bool IEntity.InRange(Point2D p, int range) + { + throw new NotImplementedException(); + } + + bool IEntity.InRange(Point3D p, int range) + { + throw new NotImplementedException(); + } + + void ISerializable.BeforeSerialize() + { + throw new NotImplementedException(); + } + + void ISerializable.Deserialize(IGenericReader reader) + { + throw new NotImplementedException(); + } + + void ISerializable.Serialize(IGenericWriter writer) + { + throw new NotImplementedException(); + } + + void ISerializable.Delete() + { + throw new NotImplementedException(); + } + + void ISerializable.SetTypeRef(Type type) + { + throw new NotImplementedException(); + } + + public void RemoveItem(Item item) + { + throw new NotImplementedException(); + } + } + + public class Sector + { + public List BItems { get; set; } = new List(); + public List Mobiles { get; set; } = new List(); + } + + public struct BItemWhereHyper : NetFabric.Hyperlinq.IFunction + { + private readonly Rectangle2D bounds; + + public BItemWhereHyper(Rectangle2D bounds) + { + this.bounds = bounds; + } + + public bool Invoke(BItem element) + { + return element is { Deleted: false, Parent: null } && bounds.Contains(element.Location); + } + } + + public struct MobileWhereHyper : NetFabric.Hyperlinq.IFunction + { + private readonly Rectangle2D bounds; + + public MobileWhereHyper(Rectangle2D bounds) + { + this.bounds = bounds; + } + + public bool Invoke(Mobile element) + { + return element is { Deleted: false } && bounds.Contains(element.Location); + } + } + + public struct SelectHyper : NetFabric.Hyperlinq.IFunction where TSource : TDest + { + public TDest Invoke(TSource arg) + { + return arg; + } + } +} diff --git a/Projects/Benchmarks/Benchmarks/Map/MapItemSelectors.cs b/Projects/Benchmarks/Benchmarks/Map/MapItemSelectors.cs new file mode 100644 index 000000000..8eb1758d2 --- /dev/null +++ b/Projects/Benchmarks/Benchmarks/Map/MapItemSelectors.cs @@ -0,0 +1,403 @@ +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Jobs; +using NetFabric.Hyperlinq; +using Server; +using StructLinq; +using StructLinq.Array; +using StructLinq.List; +using StructLinq.Select; +using StructLinq.Where; +using System; +using System.Buffers; +using System.Collections.Generic; +using System.Linq; +using static NetFabric.Hyperlinq.ArrayExtensions; + +namespace Benchmarks.ItemSelectors +{ + [SimpleJob(RuntimeMoniker.Net60)] + [MemoryDiagnoser] + public class MapItemSelectors + { + private static readonly Sector sector = new(); + private static readonly Point3D[] locations = new[] { new Point3D(0, 0, 0), new Point3D(50, 50, 0) }; + + public static Rectangle2D[] BoundsArray() => new[] + { + new Rectangle2D(70, 70, 100, 100), + new Rectangle2D(30, 30, 100, 100), + new Rectangle2D(0, 0, 100, 100), + }; + + [GlobalSetup] + public static void Init() + { + for (int j = 0; j < locations.Length; j++) + { + Point3D loc = locations[j]; + + for (int i = 0; i < 500; ++i) + { + sector.BItems.Add(new BItemDerived(loc)); + } + } + } + + [ParamsSource(nameof(BoundsArray))] + public Rectangle2D bounds; + + [Benchmark(Baseline = true)] + public BItemDerived SelectBItemsFor() + { + BItemDerived toRet = null; + for (int i = sector.BItems.Count - 1; i >= 0; --i) + { + BItem BItem = sector.BItems[i]; + if (BItem is BItemDerived { Deleted: false, Parent: null } tItem && bounds.Contains(BItem.Location)) + { + toRet = tItem; + } + } + + return toRet; + } + + [Benchmark] + public BItemDerived SelectBItemsNew() + { + BItemDerived toRet = null; + foreach (BItemDerived i in SelectBItems(sector, bounds)) + { + toRet = i; + } + + return toRet; + } + + [Benchmark] + public BItemDerived SelectBItemsLinq() + { + BItemDerived toRet = null; + foreach (BItemDerived i in SelectBItemsLinq(sector, bounds)) + { + toRet = i; + } + + return toRet; + } + + [Benchmark] + public BItemDerived SelectBItemsLinqStruct() + { + BItemDerived toRet = null; + foreach (BItemDerived i in SelectBItemsLinqStruct(sector, bounds)) + { + toRet = i; + } + + return toRet; + } + + [Benchmark] + public BItemDerived SelectBItemsLinqStructInterface() + { + BItemDerived toRet = null; + IEnumerable enumerable = SelectBItemsLinqStruct(sector, bounds).ToEnumerable(); + + foreach (BItemDerived i in enumerable) + { + toRet = i; + } + + return toRet; + } + + [Benchmark] + public BItemDerived SelectBItemsHyperLinq() + { + BItemDerived toRet = null; + foreach (BItemDerived i in SelectBItemsHyperlinq(sector, bounds)) + { + toRet = i; + } + + return toRet; + } + + [Benchmark] + public BItemDerived SelectBItemsHyperLinqInterface() + { + BItemDerived toRet = null; + IEnumerable enumerable = SelectBItemsHyperlinq(sector, bounds); + + foreach (BItemDerived i in enumerable) + { + toRet = i; + } + + return toRet; + } + + [Benchmark] + public BItemDerived SelectBItemsHyperLinqArrayPool() + { + BItemDerived toRet = null; + using Lease lease = SelectBItemsHyperlinq(sector, bounds).ToArray(ArrayPool.Shared); + + foreach (BItemDerived i in lease) + { + toRet = i; + } + + return toRet; + } + + public IEnumerable SelectBItemsLinq(Sector s, Rectangle2D bounds) where T : BItem + { + return s.BItems.OfType().Where(o => o is { Deleted: false, Parent: null } && bounds.Contains(o.Location)); + } + + public IEnumerable SelectBItems(Sector s, Rectangle2D bounds) where T : BItem + { + List items = s.BItems; + List entities = new(items.Count); + + for (int i = items.Count - 1; i >= 0; --i) + { + if (items[i] is T { Deleted: false, Parent: null } tItem && bounds.Contains(tItem.Location)) + { + entities.Add(tItem); + } + } + return entities; + } + + public SelectEnumerable, ArrayStructEnumerator, BItemWhere>, + WhereEnumerator, BItemWhere>, BItemSelect> + SelectBItemsLinqStruct(Sector s, Rectangle2D bounds) where T : BItem + { + BItemWhere bitemWhere = new(bounds); + BItemSelect bitemSelect = new(); + + return s.BItems.ToStructEnumerable() + .Where(ref bitemWhere, x => x) + .Select(ref bitemSelect, x => x, x => x); + } + + public ArraySegmentWhereSelectEnumerable, SelectHyper> + SelectBItemsHyperlinq(Sector s, Rectangle2D bounds) where T : BItem + { + return s.BItems.AsValueEnumerable() + .Where(new BItemWhereHyper(bounds)) + .Select>(); + } + } + + public class BItem : IPoint3D, IEntity + { + public object Parent { get; set; } = null; + + public bool Deleted { get; set; } = false; + + public int Z { get; set; } = 1; + + public int X { get; set; } = 1; + + public int Y { get; set; } = 1; + + public Serial Serial => throw new NotImplementedException(); + + public Point3D Location { get; } + + public Map Map { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public Region Region => throw new NotImplementedException(); + + public string Name { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public int Hue { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public Direction Direction { get => throw new System.NotImplementedException(); set => throw new NotImplementedException(); } + public DateTime Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public int TypeRef => throw new NotImplementedException(); + + Point3D IEntity.Location => Location; + + int IPoint3D.Z => throw new NotImplementedException(); + + int IPoint2D.X => throw new NotImplementedException(); + + int IPoint2D.Y => throw new NotImplementedException(); + + DateTime ISerializable.Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + DateTime ISerializable.LastSerialized { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + long ISerializable.SavePosition { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + BufferWriter ISerializable.SaveBuffer { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + int ISerializable.TypeRef => throw new NotImplementedException(); + + Serial ISerializable.Serial => throw new NotImplementedException(); + + bool ISerializable.Deleted => throw new NotImplementedException(); + + public BItem(Point3D location) + { + Location = location; + } + + public void Delete() + { + throw new NotImplementedException(); + } + + public void ProcessDelta() + { + throw new NotImplementedException(); + } + + public void OnStatsQuery(Server.Mobile m) + { + throw new NotImplementedException(); + } + + public void InvalidateProperties() + { + throw new NotImplementedException(); + } + + public int CompareTo(object obj) + { + throw new NotImplementedException(); + } + + public int CompareTo(IEntity other) + { + throw new NotImplementedException(); + } + + public void MoveToWorld(Point3D location, Map map) + { + throw new NotImplementedException(); + } + + public bool InRange(Point2D p, int range) + { + throw new NotImplementedException(); + } + + public bool InRange(Point3D p, int range) + { + throw new NotImplementedException(); + } + + public void RemoveBItem(BItem BItem) + { + throw new NotImplementedException(); + } + + public void BeforeSerialize() + { + throw new NotImplementedException(); + } + + public void Deserialize(IGenericReader reader) + { + throw new NotImplementedException(); + } + + public void Serialize(IGenericWriter writer) + { + throw new NotImplementedException(); + } + + public void SetTypeRef(Type type) + { + throw new NotImplementedException(); + } + + void ISerializable.BeforeSerialize() + { + throw new NotImplementedException(); + } + + void ISerializable.Deserialize(IGenericReader reader) + { + throw new NotImplementedException(); + } + + void ISerializable.Serialize(IGenericWriter writer) + { + throw new NotImplementedException(); + } + + void ISerializable.Delete() + { + throw new NotImplementedException(); + } + + void ISerializable.SetTypeRef(Type type) + { + throw new NotImplementedException(); + } + + public void RemoveItem(Item item) + { + throw new NotImplementedException(); + } + } + + public class BItemDerived : BItem + { + public BItemDerived(Point3D location) : base(location) { } + } + + public class Sector + { + public List BItems { get; set; } = new List(); + } + + public struct BItemWhere : StructLinq.IFunction where T : BItem + { + private readonly Rectangle2D bounds; + + public BItemWhere(Rectangle2D bounds) + { + this.bounds = bounds; + } + + public bool Eval(BItem element) + { + return element is T { Deleted: false, Parent: null } && bounds.Contains(element.Location); + } + } + + public struct BItemSelect : StructLinq.IFunction where T : BItem + { + public T Eval(BItem element) + { + return (T)element; + } + } + + public struct BItemWhereHyper : NetFabric.Hyperlinq.IFunction where T : BItem + { + private readonly Rectangle2D bounds; + + public BItemWhereHyper(Rectangle2D bounds) + { + this.bounds = bounds; + } + + public bool Invoke(BItem element) + { + return element is T { Deleted: false, Parent: null } && bounds.Contains(element.Location); + } + } + + public struct SelectHyper : NetFabric.Hyperlinq.IFunction where TDest : TSource + { + public TDest Invoke(TSource arg) + { + return (TDest)arg; + } + } +} diff --git a/Projects/Benchmarks/Benchmarks/Map/MapMobileSelectors.cs b/Projects/Benchmarks/Benchmarks/Map/MapMobileSelectors.cs new file mode 100644 index 000000000..c9932070f --- /dev/null +++ b/Projects/Benchmarks/Benchmarks/Map/MapMobileSelectors.cs @@ -0,0 +1,255 @@ +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Jobs; +using NetFabric.Hyperlinq; +using Server; +using StructLinq; +using System; +using System.Collections.Generic; +using System.Linq; +using static NetFabric.Hyperlinq.ArrayExtensions; + +namespace Benchmarks.MobileSelectors +{ + [SimpleJob(RuntimeMoniker.Net60)] + [MemoryDiagnoser] + public class MapMobileSelectors + { + private static readonly Sector sector = new(); + private static readonly Point3D[] locations = new[] { new Point3D(0, 0, 0), new Point3D(50, 50, 0) }; + + public static Rectangle2D[] BoundsArray() => new[] + { + new Rectangle2D(70, 70, 100, 100), + new Rectangle2D(30, 30, 100, 100), + new Rectangle2D(0, 0, 100, 100), + }; + + [GlobalSetup] + public static void Init() + { + for (int j = 0; j < locations.Length; j++) + { + Point3D loc = locations[j]; + + for (int i = 0; i < 500; ++i) + { + sector.Mobiles.Add(new MobileDerived(loc)); + } + } + } + + [ParamsSource(nameof(BoundsArray))] + public Rectangle2D bounds; + + [Benchmark(Baseline = true)] + public MobileDerived SelectMobilesFor() + { + MobileDerived toRet = null; + for (int i = sector.Mobiles.Count - 1; i >= 0; --i) + { + Mobile mob = sector.Mobiles[i]; + if (mob is MobileDerived { Deleted: false } tMob && bounds.Contains(mob.Location)) + { + toRet = tMob; + } + } + + return toRet; + } + + [Benchmark] + public MobileDerived SelectMobilesNew() + { + MobileDerived toRet = null; + foreach (MobileDerived m in SelectMobiles(sector, bounds)) + { + toRet = m; + } + + return toRet; + } + + [Benchmark] + public MobileDerived SelectMobilesLinq() + { + MobileDerived toRet = null; + foreach (MobileDerived m in SelectMobilesLinq(sector, bounds)) + { + toRet = m; + } + + return toRet; + } + + [Benchmark] + public MobileDerived SelectMobilesHyperLinq() + { + MobileDerived toRet = null; + foreach (MobileDerived m in SelectMobilesHyperlinq(sector, bounds)) + { + toRet = m; + } + + return toRet; + } + + public IEnumerable SelectMobilesLinq(Sector s, Rectangle2D bounds) where T : Mobile + { + return s.Mobiles.OfType().Where(o => o is { Deleted: false } && bounds.Contains(o.Location)); + } + + public IEnumerable SelectMobiles(Sector s, Rectangle2D bounds) where T : Mobile + { + List mobiles = s.Mobiles; + List entities = new(mobiles.Count); + + for (int i = mobiles.Count - 1; i >= 0; --i) + { + if (mobiles[i] is T { Deleted: false } tMob && bounds.Contains(tMob.Location)) + { + entities.Add(tMob); + } + } + return entities; + } + + public ArraySegmentWhereSelectEnumerable, SelectHyper> + SelectMobilesHyperlinq(Sector s, Rectangle2D bounds) where T : Mobile + { + return s.Mobiles.AsValueEnumerable() + .Where(new MobileWhereHyper(bounds)) + .Select>(); + } + } + + public class Mobile : IPoint3D, IEntity + { + public bool Deleted { get; set; } = false; + + public int Z { get; set; } = 1; + + public int X { get; set; } = 1; + + public int Y { get; set; } = 1; + + public Serial Serial => throw new NotImplementedException(); + + public Point3D Location { get; } + + public Map Map { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public Region Region => throw new NotImplementedException(); + + public string Name { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public int Hue { get => throw new System.NotImplementedException(); set => throw new NotImplementedException(); } + public Direction Direction { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public DateTime Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public int TypeRef => throw new NotImplementedException(); + + int IPoint3D.Z => throw new NotImplementedException(); + + int IPoint2D.X => throw new NotImplementedException(); + + int IPoint2D.Y => throw new NotImplementedException(); + + DateTime ISerializable.Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + DateTime ISerializable.LastSerialized { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + long ISerializable.SavePosition { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + BufferWriter ISerializable.SaveBuffer { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + int ISerializable.TypeRef => throw new NotImplementedException(); + + Serial ISerializable.Serial => throw new NotImplementedException(); + + bool ISerializable.Deleted => throw new NotImplementedException(); + + public Mobile(Point3D location) + { + Location = location; + } + + public void MoveToWorld(Point3D location, Map map) + { + throw new NotImplementedException(); + } + + public void ProcessDelta() + { + throw new NotImplementedException(); + } + + public bool InRange(Point2D p, int range) + { + throw new NotImplementedException(); + } + + public bool InRange(Point3D p, int range) + { + throw new NotImplementedException(); + } + + public void RemoveItem(Item item) + { + throw new NotImplementedException(); + } + + public void BeforeSerialize() + { + throw new NotImplementedException(); + } + + public void Deserialize(IGenericReader reader) + { + throw new NotImplementedException(); + } + + public void Serialize(IGenericWriter writer) + { + throw new NotImplementedException(); + } + + public void Delete() + { + throw new NotImplementedException(); + } + + public void SetTypeRef(Type type) + { + throw new NotImplementedException(); + } + } + + public class MobileDerived : Mobile + { + public MobileDerived(Point3D location) : base(location) { } + } + + public class Sector + { + public List Mobiles { get; set; } = new List(); + } + + public struct MobileWhereHyper : NetFabric.Hyperlinq.IFunction where T : Mobile + { + private readonly Rectangle2D bounds; + + public MobileWhereHyper(Rectangle2D bounds) + { + this.bounds = bounds; + } + + public bool Invoke(Mobile element) + { + return element is T { Deleted: false } && bounds.Contains(element.Location); + } + } + + public struct SelectHyper : NetFabric.Hyperlinq.IFunction where TDest : TSource + { + public TDest Invoke(TSource arg) + { + return (TDest)arg; + } + } +} diff --git a/Projects/Benchmarks/Benchmarks/Map/MapMultiSelectors.cs b/Projects/Benchmarks/Benchmarks/Map/MapMultiSelectors.cs new file mode 100644 index 000000000..e5c6605f5 --- /dev/null +++ b/Projects/Benchmarks/Benchmarks/Map/MapMultiSelectors.cs @@ -0,0 +1,311 @@ +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Jobs; +using NetFabric.Hyperlinq; +using Server; +using StructLinq; +using System; +using System.Collections.Generic; +using System.Linq; +using static NetFabric.Hyperlinq.ArrayExtensions; + +namespace Benchmarks.MultiSelectors +{ + [SimpleJob(RuntimeMoniker.Net60)] + [MemoryDiagnoser] + public class MapMultiSelectors + { + private static readonly Sector sector = new(); + private static readonly Point3D[] locations = new[] { new Point3D(0, 0, 0), new Point3D(50, 50, 0) }; + + public static Rectangle2D[] BoundsArray() => new[] + { + new Rectangle2D(70, 70, 100, 100), + new Rectangle2D(30, 30, 100, 100), + new Rectangle2D(0, 0, 100, 100), + }; + + [GlobalSetup] + public static void Init() + { + for (int j = 0; j < locations.Length; j++) + { + Point3D loc = locations[j]; + + for (int i = 0; i < 25; ++i) + { + sector.Multis.Add(new BaseMulti(loc)); + } + } + } + + [ParamsSource(nameof(BoundsArray))] + public Rectangle2D bounds; + + [Benchmark(Baseline = true)] + public BaseMulti SelectMultiFor() + { + BaseMulti toRet = null; + for (int i = sector.Multis.Count - 1; i >= 0; --i) + { + BaseMulti multi = sector.Multis[i]; + if (multi is { Deleted: false } tMulti && bounds.Contains(multi.Location)) + { + toRet = tMulti; + } + } + + return toRet; + } + + [Benchmark] + public BaseMulti SelectMultiNew() + { + BaseMulti toRet = null; + foreach (BaseMulti m in SelectMultiNew(sector, bounds)) + { + toRet = m; + } + + return toRet; + } + + [Benchmark] + public BaseMulti SelectMultiLinq() + { + BaseMulti toRet = null; + foreach (BaseMulti m in SelectMultiLinq(sector, bounds)) + { + toRet = m; + } + + return toRet; + } + + [Benchmark] + public BaseMulti SelectMultiHyperLinq() + { + BaseMulti toRet = null; + foreach (BaseMulti m in SelectMultiHyperlinq(sector, bounds)) + { + toRet = m; + } + + return toRet; + } + + public IEnumerable SelectMultiLinq(Sector s, Rectangle2D bounds) + { + return s.Multis.Where(o => o is { Deleted: false } && bounds.Contains(o.Location)); + } + + public IEnumerable SelectMultiNew(Sector s, Rectangle2D bounds) + { + List entities = new(s.Multis.Count); + + for (int i = s.Multis.Count - 1; i >= 0; --i) + { + BaseMulti multiItem = s.Multis[i]; + if (multiItem is { Deleted: false } && bounds.Contains(multiItem.Location)) + { + entities.Add(multiItem); + } + } + return entities; + } + + public ArraySegmentWhereEnumerable + SelectMultiHyperlinq(Sector s, Rectangle2D bounds) + { + return s.Multis.AsValueEnumerable().Where(new MultiWhereHyper(bounds)); + } + } + + public class BItem : IPoint3D, IEntity + { + public object Parent { get; set; } = null; + + public bool Deleted { get; set; } = false; + + public int Z { get; set; } = 1; + + public int X { get; set; } = 1; + + public int Y { get; set; } = 1; + + public Serial Serial => throw new NotImplementedException(); + + public Point3D Location { get; } + + public Map Map { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public Region Region => throw new NotImplementedException(); + + public string Name { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public int Hue { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public Direction Direction { get => throw new System.NotImplementedException(); set => throw new NotImplementedException(); } + public DateTime Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public int TypeRef => throw new NotImplementedException(); + + int IPoint3D.Z => throw new NotImplementedException(); + + int IPoint2D.X => throw new NotImplementedException(); + + int IPoint2D.Y => throw new NotImplementedException(); + + DateTime ISerializable.Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + DateTime ISerializable.LastSerialized { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + long ISerializable.SavePosition { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + BufferWriter ISerializable.SaveBuffer { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + int ISerializable.TypeRef => throw new NotImplementedException(); + + Serial ISerializable.Serial => throw new NotImplementedException(); + + bool ISerializable.Deleted => throw new NotImplementedException(); + + public BItem(Point3D location) + { + Location = location; + } + + public void Delete() + { + throw new NotImplementedException(); + } + + public void ProcessDelta() + { + throw new NotImplementedException(); + } + + public void OnStatsQuery(Server.Mobile m) + { + throw new NotImplementedException(); + } + + public void InvalidateProperties() + { + throw new NotImplementedException(); + } + + public int CompareTo(object obj) + { + throw new NotImplementedException(); + } + + public int CompareTo(IEntity other) + { + throw new NotImplementedException(); + } + + public void MoveToWorld(Point3D location, Map map) + { + throw new NotImplementedException(); + } + + public bool InRange(Point2D p, int range) + { + throw new NotImplementedException(); + } + + public bool InRange(Point3D p, int range) + { + throw new NotImplementedException(); + } + + public void RemoveBItem(BItem BItem) + { + throw new NotImplementedException(); + } + + public void BeforeSerialize() + { + throw new NotImplementedException(); + } + + public void Deserialize(IGenericReader reader) + { + throw new NotImplementedException(); + } + + public void Serialize(IGenericWriter writer) + { + throw new NotImplementedException(); + } + + public void SetTypeRef(Type type) + { + throw new NotImplementedException(); + } + + void ISerializable.BeforeSerialize() + { + throw new NotImplementedException(); + } + + void ISerializable.Deserialize(IGenericReader reader) + { + throw new NotImplementedException(); + } + + void ISerializable.Serialize(IGenericWriter writer) + { + throw new NotImplementedException(); + } + + void ISerializable.Delete() + { + throw new NotImplementedException(); + } + + void ISerializable.SetTypeRef(Type type) + { + throw new NotImplementedException(); + } + + public void RemoveItem(Item item) + { + throw new NotImplementedException(); + } + } + + public class BaseMulti : BItem + { + public MultiComponentList Components = MultiComponentList.Empty; + + public BaseMulti(Point3D location) : base(location) + { + for (int i = 0; i < 20; ++i) + { + for (int j = 0; j < 20; ++j) + { + for (int z = 0; z < 20; ++z) + { + Components.Add(123, i, j, z); + } + } + } + } + } + + public class Sector + { + public List Multis { get; set; } = new List(); + } + + public struct MultiWhereHyper : NetFabric.Hyperlinq.IFunction + { + private readonly Rectangle2D bounds; + + public MultiWhereHyper(Rectangle2D bounds) + { + this.bounds = bounds; + } + + public bool Invoke(BaseMulti element) + { + return element is { Deleted: false } && bounds.Contains(element.Location); + } + } +} diff --git a/Projects/Benchmarks/Benchmarks/Map/MapMultiTilesSelectors.cs b/Projects/Benchmarks/Benchmarks/Map/MapMultiTilesSelectors.cs new file mode 100644 index 000000000..553016f93 --- /dev/null +++ b/Projects/Benchmarks/Benchmarks/Map/MapMultiTilesSelectors.cs @@ -0,0 +1,352 @@ +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Jobs; +using NetFabric.Hyperlinq; +using Server; +using StructLinq; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Benchmarks.MultiTilesSelectors +{ + [SimpleJob(RuntimeMoniker.Net60)] + [MemoryDiagnoser] + public class MapMultiTilesSelectors + { + private static readonly Sector sector = new(); + private static readonly Point3D[] locations = new[] { new Point3D(0, 0, 0), new Point3D(50, 50, 0) }; + + public static Rectangle2D[] BoundsArray() => new[] + { + new Rectangle2D(70, 70, 100, 100), + new Rectangle2D(30, 30, 100, 100), + new Rectangle2D(0, 0, 100, 100), + }; + + [GlobalSetup] + public static void Init() + { + for (int j = 0; j < locations.Length; j++) + { + Point3D loc = locations[j]; + + for (int i = 0; i < 25; ++i) + { + sector.Multis.Add(new BaseMulti(loc)); + } + } + } + + [ParamsSource(nameof(BoundsArray))] + public Rectangle2D bounds; + + [Benchmark] + public int SelectMultiTilesNew() + { + int toRet = 0; + + foreach (StaticTile[] tiles in SelectMultiTilesNew(sector, bounds)) + { + for (int i = 0; i < tiles.Length; ++i) + { + toRet = tiles[i].ID; + } + } + + return toRet; + } + + [Benchmark(Baseline = true)] + public int SelectMultiTilesLinq() + { + int toRet = 0; + + foreach (StaticTile[] tiles in SelectMultiTilesLinq(sector, bounds)) + { + for (int i = 0; i < tiles.Length; ++i) + { + toRet = tiles[i].ID; + } + } + + return toRet; + } + + public IEnumerable SelectMultiTilesLinq(Sector s, Rectangle2D bounds) + { + foreach (var o in s.Multis.Where(o => o != null && !o.Deleted)) + { + var c = o.Components; + + int x, y, xo, yo; + StaticTile[] t, r; + + for (x = bounds.Start.X; x < bounds.End.X; x++) + { + xo = x - (o.X + c.Min.X); + + if (xo < 0 || xo >= c.Width) + { + continue; + } + + for (y = bounds.Start.Y; y < bounds.End.Y; y++) + { + yo = y - (o.Y + c.Min.Y); + + if (yo < 0 || yo >= c.Height) + { + continue; + } + + t = c.Tiles[xo][yo]; + + if (t.Length <= 0) + { + continue; + } + + r = new StaticTile[t.Length]; + + for (var i = 0; i < t.Length; i++) + { + r[i] = t[i]; + r[i].Z += o.Z; + } + + yield return r; + } + } + } + } + + public IEnumerable SelectMultiTilesNew(Sector s, Rectangle2D bounds) + { + List multis = s.Multis; + + for (int l = multis.Count - 1; l >= 0; --l) + { + if (multis[l] is not { Deleted: false } o) + { + continue; + } + + MultiComponentList c = o.Components; + + int x, y, xo, yo; + StaticTile[] t, r; + + for (x = bounds.Start.X; x < bounds.End.X; x++) + { + xo = x - (o.X + c.Min.X); + + if (xo < 0 || xo >= c.Width) + { + continue; + } + + for (y = bounds.Start.Y; y < bounds.End.Y; y++) + { + yo = y - (o.Y + c.Min.Y); + + if (yo < 0 || yo >= c.Height) + { + continue; + } + + t = c.Tiles[xo][yo]; + + if (t.Length <= 0) + { + continue; + } + + r = new StaticTile[t.Length]; + + for (var i = 0; i < t.Length; i++) + { + r[i] = t[i]; + r[i].Z += o.Z; + } + + yield return r; + } + } + } + } + } + + public class BItem : IPoint3D, IEntity + { + public object Parent { get; set; } = null; + + public bool Deleted { get; set; } = false; + + public int Z { get; set; } = 1; + + public int X { get; set; } = 1; + + public int Y { get; set; } = 1; + + public Serial Serial => throw new NotImplementedException(); + + public Point3D Location { get; } + + public Map Map { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public Region Region => throw new NotImplementedException(); + + public string Name { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public int Hue { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public Direction Direction { get => throw new System.NotImplementedException(); set => throw new NotImplementedException(); } + public DateTime Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public int TypeRef => throw new NotImplementedException(); + + int IPoint3D.Z => throw new NotImplementedException(); + + int IPoint2D.X => throw new NotImplementedException(); + + int IPoint2D.Y => throw new NotImplementedException(); + + DateTime ISerializable.Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + DateTime ISerializable.LastSerialized { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + long ISerializable.SavePosition { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + BufferWriter ISerializable.SaveBuffer { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + int ISerializable.TypeRef => throw new NotImplementedException(); + + Serial ISerializable.Serial => throw new NotImplementedException(); + + bool ISerializable.Deleted => throw new NotImplementedException(); + + public BItem(Point3D location) + { + Location = location; + } + + public void Delete() + { + throw new NotImplementedException(); + } + + public void ProcessDelta() + { + throw new NotImplementedException(); + } + + public void OnStatsQuery(Server.Mobile m) + { + throw new NotImplementedException(); + } + + public void InvalidateProperties() + { + throw new NotImplementedException(); + } + + public int CompareTo(object obj) + { + throw new NotImplementedException(); + } + + public int CompareTo(IEntity other) + { + throw new NotImplementedException(); + } + + public void MoveToWorld(Point3D location, Map map) + { + throw new NotImplementedException(); + } + + public bool InRange(Point2D p, int range) + { + throw new NotImplementedException(); + } + + public bool InRange(Point3D p, int range) + { + throw new NotImplementedException(); + } + + public void RemoveBItem(BItem BItem) + { + throw new NotImplementedException(); + } + + public void BeforeSerialize() + { + throw new NotImplementedException(); + } + + public void Deserialize(IGenericReader reader) + { + throw new NotImplementedException(); + } + + public void Serialize(IGenericWriter writer) + { + throw new NotImplementedException(); + } + + public void SetTypeRef(Type type) + { + throw new NotImplementedException(); + } + + void ISerializable.BeforeSerialize() + { + throw new NotImplementedException(); + } + + void ISerializable.Deserialize(IGenericReader reader) + { + throw new NotImplementedException(); + } + + void ISerializable.Serialize(IGenericWriter writer) + { + throw new NotImplementedException(); + } + + void ISerializable.Delete() + { + throw new NotImplementedException(); + } + + void ISerializable.SetTypeRef(Type type) + { + throw new NotImplementedException(); + } + + public void RemoveItem(Item item) + { + throw new NotImplementedException(); + } + } + + public class BaseMulti : BItem + { + public MultiComponentList Components = MultiComponentList.Empty; + + public BaseMulti(Point3D location) : base(location) + { + for (int i = 0; i < 20; ++i) + { + for (int j = 0; j < 20; ++j) + { + for (int z = 0; z < 20; ++z) + { + Components.Add(123, i, j, z); + } + } + } + } + } + + public class Sector + { + public List Multis { get; set; } = new List(); + } +} diff --git a/Projects/Benchmarks/Benchmarks/Map/MapSelectors.cs b/Projects/Benchmarks/Benchmarks/Map/MapSelectors.cs deleted file mode 100644 index 4c47b7189..000000000 --- a/Projects/Benchmarks/Benchmarks/Map/MapSelectors.cs +++ /dev/null @@ -1,665 +0,0 @@ -using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Jobs; -using Server; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Benchmarks -{ - [SimpleJob(RuntimeMoniker.NetCoreApp50)] - public class MapSelectors - { - static readonly Sector sector = new Sector(); - static Server.Rectangle2D bounds = new Server.Rectangle2D(0, 0, 100, 100); - - public static void Init() - { - for (int i = 0; i < 50; ++i) - { - sector.Multis.Add(new BaseMulti()); - } - for (int i = 0; i < 1000; ++i) - { - sector.BItems.Add(new BItem()); - } - for (int i = 0; i < 1000; ++i) - { - sector.Mobiles.Add(new Mobile()); - } - } - - #region MultiTiles - [Benchmark] - public void SelectMultiTilesNew() - { - foreach(StaticTile[] tiles in SelectMultiTiles(sector, bounds)) - { - for(int i = 0; i < tiles.Length; ++i) - { - int id = tiles[i].ID; - } - } - } - - [Benchmark] - public void SelectMultiTilesLinq() - { - foreach(StaticTile[] tiles in SelectMultiTilesLinq(sector, bounds)) - { - for(int i = 0; i < tiles.Length; ++i) - { - int id = tiles[i].ID; - } - } - } - - public IEnumerable SelectMultiTilesLinq(Sector s, Server.Rectangle2D bounds) - { - foreach (var o in s.Multis.Where(o => o != null && !o.Deleted)) - { - var c = o.Components; - - int x, y, xo, yo; - StaticTile[] t, r; - - for (x = bounds.Start.X; x < bounds.End.X; x++) - { - xo = x - (o.X + c.Min.X); - - if (xo < 0 || xo >= c.Width) - { - continue; - } - - for (y = bounds.Start.Y; y < bounds.End.Y; y++) - { - yo = y - (o.Y + c.Min.Y); - - if (yo < 0 || yo >= c.Height) - { - continue; - } - - t = c.Tiles[xo][yo]; - - if (t.Length <= 0) - { - continue; - } - - r = new StaticTile[t.Length]; - - for (var i = 0; i < t.Length; i++) - { - r[i] = t[i]; - r[i].Z += o.Z; - } - - yield return r; - } - } - } - } - - public IEnumerable SelectMultiTiles(Sector s, Server.Rectangle2D bounds) - { - for (int l = s.Multis.Count - 1; l >= 0; --l) - { - BaseMulti o = s.Multis[l]; - if (o != null && !o.Deleted) - { - MultiComponentList c = o.Components; - - int x, y, xo, yo; - StaticTile[] t, r; - - for (x = bounds.Start.X; x < bounds.End.X; x++) - { - xo = x - (o.X + c.Min.X); - - if (xo < 0 || xo >= c.Width) - { - continue; - } - - for (y = bounds.Start.Y; y < bounds.End.Y; y++) - { - yo = y - (o.Y + c.Min.Y); - - if (yo < 0 || yo >= c.Height) - { - continue; - } - - t = c.Tiles[xo][yo]; - - if (t.Length <= 0) - { - continue; - } - - r = new StaticTile[t.Length]; - - for (var i = 0; i < t.Length; i++) - { - r[i] = t[i]; - r[i].Z += o.Z; - } - - yield return r; - } - } - } - } - } - - #endregion - - #region Multis - [Benchmark] - public void SelectMultisNew() - { - SelectMultis(sector, bounds); - } - - [Benchmark] - public void SelectMultisLinq() - { - SelectMultisLinq(sector, bounds); - } - - public IEnumerable SelectMultisLinq(Sector s, Server.Rectangle2D bounds) - { - return s.Multis.Where(o => o != null && !o.Deleted && bounds.Contains(o.Location)); - } - - public IEnumerable SelectMultis(Sector s, Server.Rectangle2D bounds) - { - List entities = new List(s.Multis.Count); - for (int i = s.Multis.Count - 1; i >= 0; --i) - { - BaseMulti BItem = s.Multis[i]; - if (BItem != null && !BItem.Deleted && bounds.Contains(BItem.Location)) - entities.Add(BItem); - } - return entities; - } - #endregion - - #region BItems - [Benchmark] - public void SelectBItemsNew() - { - SelectBItems(sector, bounds); - } - - [Benchmark] - public void SelectBItemsLinq() - { - SelectBItemsLinq(sector, bounds); - } - - public IEnumerable SelectBItemsLinq(Sector s, Server.Rectangle2D bounds) where T : BItem - { - return s.BItems.OfType().Where(o => o != null && !o.Deleted && o.Parent == null && bounds.Contains(o.Location)); - } - - public IEnumerable SelectBItems(Sector s, Server.Rectangle2D bounds) where T : BItem - { - List entities = new List(s.BItems.Count); - Type type = typeof(T); - for (int i = s.BItems.Count - 1; i >= 0; --i) - { - BItem BItem = s.BItems[i]; - if (BItem != null && !BItem.Deleted && BItem.Parent == null && bounds.Contains(BItem.Location) && type.IsAssignableFrom(BItem.GetType())) - entities.Add(BItem as T); - } - return entities; - } - #endregion - - #region Mobiles - [Benchmark] - public void SelectMobilesNew() - { - SelectMobiles(sector, bounds); - } - - [Benchmark] - public void SelectMobilesLinq() - { - SelectMobilesLinq(sector, bounds); - } - - public IEnumerable SelectMobilesLinq(Sector s, Server.Rectangle2D bounds) where T : Mobile - { - return s.Mobiles.OfType().Where(o => o != null && !o.Deleted && bounds.Contains(o.Location)); - } - - public IEnumerable SelectMobiles(Sector s, Server.Rectangle2D bounds) where T : Mobile - { - List entities = new List(s.Mobiles.Count); - Type type = typeof(T); - for (int i = s.Mobiles.Count - 1; i >= 0; --i) - { - Mobile mob = s.Mobiles[i]; - if (mob != null && !mob.Deleted && bounds.Contains(mob.Location) && type.IsAssignableFrom(mob.GetType())) - entities.Add(mob as T); - } - return entities; - } - #endregion - - #region Entities - [Benchmark] - public void SelectEntitiesNew() - { - SelectEntities(sector, bounds); - } - - [Benchmark] - public void SelectEntitiesLinq() - { - SelectEntitiesLinq(sector, bounds); - } - - public IEnumerable SelectEntitiesLinq(Sector s, Server.Rectangle2D bounds) - { - return Enumerable.Empty() - .Union(s.Mobiles.Where(o => o != null && !o.Deleted)) - .Union(s.BItems.Where(o => o != null && !o.Deleted && o.Parent == null)) - .Where(o => bounds.Contains(o.Location)); - } - - private readonly List entities = new (10); - public IEnumerable SelectEntities(Sector s, Server.Rectangle2D bounds) - { - entities.Clear(); - entities.Capacity = s.Mobiles.Count + s.BItems.Count; - for (int i = s.Mobiles.Count - 1, j = s.BItems.Count - 1; i >= 0 || j >= 0; --i, --j) - { - if (j >= 0) - { - BItem BItem = s.BItems[j]; - if (BItem != null && !BItem.Deleted && BItem.Parent == null && bounds.Contains(BItem.Location)) - entities.Add(BItem); - } - if (i >= 0) - { - Mobile mob = s.Mobiles[i]; - if (mob != null && !mob.Deleted && bounds.Contains(mob.Location)) - entities.Add(mob); - } - } - return entities; - } - #endregion - } - public class BItem : Server.IPoint3D, IEntity - { - public object Parent { get; set; } = null; - - public bool Deleted { get; set; } = false; - - public int Z { get; set; } = 1; - - public int X { get; set; } = 1; - - public int Y { get; set; } = 1; - - public Serial Serial => throw new System.NotImplementedException(); - - public Point3D Location { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); } - public Map Map { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); } - - public Region Region => throw new System.NotImplementedException(); - - public string Name { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); } - public int Hue { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); } - public Direction Direction { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); } - public DateTime Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - public int TypeRef => throw new NotImplementedException(); - - Point3D IEntity.Location => throw new NotImplementedException(); - - Map IEntity.Map => throw new NotImplementedException(); - - int IPoint3D.Z => throw new NotImplementedException(); - - int IPoint2D.X => throw new NotImplementedException(); - - int IPoint2D.Y => throw new NotImplementedException(); - - DateTime ISerializable.Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - DateTime ISerializable.LastSerialized { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - long ISerializable.SavePosition { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - BufferWriter ISerializable.SaveBuffer { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - int ISerializable.TypeRef => throw new NotImplementedException(); - - Serial ISerializable.Serial => throw new NotImplementedException(); - - bool ISerializable.Deleted => throw new NotImplementedException(); - - public BItem() - { - - } - - public void Delete() - { - throw new System.NotImplementedException(); - } - - public void ProcessDelta() - { - throw new System.NotImplementedException(); - } - - public void OnStatsQuery(Server.Mobile m) - { - throw new System.NotImplementedException(); - } - - public void InvalidateProperties() - { - throw new System.NotImplementedException(); - } - - public int CompareTo(object obj) - { - throw new System.NotImplementedException(); - } - - public int CompareTo(IEntity other) - { - throw new System.NotImplementedException(); - } - - public void MoveToWorld(Point3D location, Map map) - { - throw new NotImplementedException(); - } - - public bool InRange(Point2D p, int range) - { - throw new NotImplementedException(); - } - - public bool InRange(Point3D p, int range) - { - throw new NotImplementedException(); - } - - public void RemoveBItem(BItem BItem) - { - throw new NotImplementedException(); - } - - public void BeforeSerialize() - { - throw new NotImplementedException(); - } - - public void Deserialize(IGenericReader reader) - { - throw new NotImplementedException(); - } - - public void Serialize(IGenericWriter writer) - { - throw new NotImplementedException(); - } - - public void SetTypeRef(Type type) - { - throw new NotImplementedException(); - } - - void IEntity.MoveToWorld(Point3D location, Map map) - { - throw new NotImplementedException(); - } - - void IEntity.ProcessDelta() - { - throw new NotImplementedException(); - } - - bool IEntity.InRange(Point2D p, int range) - { - throw new NotImplementedException(); - } - - bool IEntity.InRange(Point3D p, int range) - { - throw new NotImplementedException(); - } - - void ISerializable.BeforeSerialize() - { - throw new NotImplementedException(); - } - - void ISerializable.Deserialize(IGenericReader reader) - { - throw new NotImplementedException(); - } - - void ISerializable.Serialize(IGenericWriter writer) - { - throw new NotImplementedException(); - } - - void ISerializable.Delete() - { - throw new NotImplementedException(); - } - - void ISerializable.SetTypeRef(Type type) - { - throw new NotImplementedException(); - } - - public void RemoveItem(Item item) - { - throw new NotImplementedException(); - } - } - - public class Mobile : Server.IPoint3D, IEntity - { - public bool Deleted { get; set; } = false; - - public int Z { get; set; } = 1; - - public int X { get; set; } = 1; - - public int Y { get; set; } = 1; - - public Serial Serial => throw new System.NotImplementedException(); - - public Point3D Location { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); } - public Map Map { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); } - - public Region Region => throw new System.NotImplementedException(); - - public string Name { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); } - public int Hue { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); } - public Direction Direction { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); } - public DateTime Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - public int TypeRef => throw new NotImplementedException(); - - Point3D IEntity.Location => throw new NotImplementedException(); - - Map IEntity.Map => throw new NotImplementedException(); - - int IPoint3D.Z => throw new NotImplementedException(); - - int IPoint2D.X => throw new NotImplementedException(); - - int IPoint2D.Y => throw new NotImplementedException(); - - DateTime ISerializable.Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - DateTime ISerializable.LastSerialized { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - long ISerializable.SavePosition { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - BufferWriter ISerializable.SaveBuffer { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - int ISerializable.TypeRef => throw new NotImplementedException(); - - Serial ISerializable.Serial => throw new NotImplementedException(); - - bool ISerializable.Deleted => throw new NotImplementedException(); - - public Mobile() - { - - } - - public void Delete() - { - throw new System.NotImplementedException(); - } - - public void ProcessDelta() - { - throw new System.NotImplementedException(); - } - - public void OnStatsQuery(Server.Mobile m) - { - throw new System.NotImplementedException(); - } - - public void InvalidateProperties() - { - throw new System.NotImplementedException(); - } - - public int CompareTo(object obj) - { - throw new System.NotImplementedException(); - } - - public int CompareTo(IEntity other) - { - throw new System.NotImplementedException(); - } - - public void MoveToWorld(Point3D location, Map map) - { - throw new NotImplementedException(); - } - - public bool InRange(Point2D p, int range) - { - throw new NotImplementedException(); - } - - public bool InRange(Point3D p, int range) - { - throw new NotImplementedException(); - } - - public void RemoveBItem(BItem BItem) - { - throw new NotImplementedException(); - } - - public void BeforeSerialize() - { - throw new NotImplementedException(); - } - - public void Deserialize(IGenericReader reader) - { - throw new NotImplementedException(); - } - - public void Serialize(IGenericWriter writer) - { - throw new NotImplementedException(); - } - - public void SetTypeRef(Type type) - { - throw new NotImplementedException(); - } - - void IEntity.MoveToWorld(Point3D location, Map map) - { - throw new NotImplementedException(); - } - - void IEntity.ProcessDelta() - { - throw new NotImplementedException(); - } - - bool IEntity.InRange(Point2D p, int range) - { - throw new NotImplementedException(); - } - - bool IEntity.InRange(Point3D p, int range) - { - throw new NotImplementedException(); - } - - void ISerializable.BeforeSerialize() - { - throw new NotImplementedException(); - } - - void ISerializable.Deserialize(IGenericReader reader) - { - throw new NotImplementedException(); - } - - void ISerializable.Serialize(IGenericWriter writer) - { - throw new NotImplementedException(); - } - - void ISerializable.Delete() - { - throw new NotImplementedException(); - } - - void ISerializable.SetTypeRef(Type type) - { - throw new NotImplementedException(); - } - - public void RemoveItem(Item item) - { - throw new NotImplementedException(); - } - } - - public class BaseMulti : BItem - { - public MultiComponentList Components = MultiComponentList.Empty; - - public BaseMulti() - { - for (int i = 0; i < 20; ++i) - for (int j = 0; j < 20; ++j) - for (int z = 0; z < 20; ++z) - Components.Add(123, i, j, z); - } - - } - - public class Sector - { - public List BItems { get; set; } = new List(); - public List Mobiles { get; set; } = new List(); - public List Multis { get; set; } = new List(); - } -} diff --git a/Projects/Benchmarks/Program.cs b/Projects/Benchmarks/Program.cs index bfdadb1bc..e86c18d19 100644 --- a/Projects/Benchmarks/Program.cs +++ b/Projects/Benchmarks/Program.cs @@ -1,5 +1,9 @@ using BenchmarkDotNet.Running; -using Benchmarks.Benchmarks.Rng; +using Benchmarks.EntitiesSelectors; +using Benchmarks.ItemSelectors; +using Benchmarks.MobileSelectors; +using Benchmarks.MultiSelectors; +using Benchmarks.MultiTilesSelectors; namespace Benchmarks { @@ -15,10 +19,14 @@ namespace Benchmarks // var textEncoding = BenchmarkRunner.Run(); // var logging = BenchmarkRunner.Run(); // var gumpPacket = BenchmarkRunner.Run(); - // MapSelectors.Init(); - // var mapSelectors = BenchmarkRunner.Run(); // var rngTest = BenchmarkRunner.Run(); - var doubleRngText = BenchmarkRunner.Run(); + //var doubleRngText = BenchmarkRunner.Run(); + + //var mapEntitiesSelectors = BenchmarkRunner.Run(); + //var mapMobilesSelectors = BenchmarkRunner.Run(); + //var mapMultiTilesSelectors = BenchmarkRunner.Run(); + //var mapMultiSelectors = BenchmarkRunner.Run(); + var mapItemsSelectors = BenchmarkRunner.Run(); } } } From fc51b60cc13c42d721a7719f2d20c93ed7789bd3 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Mon, 10 Jan 2022 23:14:55 -0800 Subject: [PATCH 065/213] fix: Adds server access with protected accounts (#915) Adds a configuration file to specify protected accounts: _Distribution/Configuration/server-access.json_ ```json { "newPasswordOnReset": false, "protectedAccounts": ["admin"] } ``` Protected accounts are unbanned and reset to `AccessLevel.Owner` upon login. The option `newPasswordOnReset` will create a new password for a protected account if it needs to be reset. The password is a random GUID and logged to the console. _**Note:**_ If your player character was accidentally modified, simply make a new character to fix the old one. --- .../UOContent/Accounting/AccountHandler.cs | 9 +- Projects/UOContent/Misc/AccountPrompt.cs | 3 + Projects/UOContent/Misc/PacketThrottles.cs | 2 +- Projects/UOContent/Misc/ServerAccess.cs | 99 +++++++++++++++++++ 4 files changed, 108 insertions(+), 5 deletions(-) create mode 100644 Projects/UOContent/Misc/ServerAccess.cs diff --git a/Projects/UOContent/Accounting/AccountHandler.cs b/Projects/UOContent/Accounting/AccountHandler.cs index 642660d05..583091ed7 100644 --- a/Projects/UOContent/Accounting/AccountHandler.cs +++ b/Projects/UOContent/Accounting/AccountHandler.cs @@ -241,13 +241,15 @@ namespace Server.Misc { res = DeleteResultType.CharBeingPlayed; } - else if (RestrictDeletion && Core.Now < m.Created + DeleteDelay) + else if (acct.AccessLevel == AccessLevel.Player && RestrictDeletion && Core.Now < m.Created + DeleteDelay) { res = DeleteResultType.CharTooYoung; } - else if (m.AccessLevel == AccessLevel.Player && + // Don't need to check current location, if netstate is null, they're logged out + else if ( + m.AccessLevel == AccessLevel.Player && Region.Find(m.LogoutLocation, m.LogoutMap).IsPartOf() - ) // Don't need to check current location, if netstate is null, they're logged out + ) { res = DeleteResultType.BadRequest; } @@ -265,7 +267,6 @@ namespace Server.Misc state.SendCharacterDeleteResult(res); state.SendCharacterListUpdate(acct); - } public static bool CanCreate(IPAddress ip) => diff --git a/Projects/UOContent/Misc/AccountPrompt.cs b/Projects/UOContent/Misc/AccountPrompt.cs index 0e537c0d5..1483f022e 100644 --- a/Projects/UOContent/Misc/AccountPrompt.cs +++ b/Projects/UOContent/Misc/AccountPrompt.cs @@ -27,6 +27,9 @@ namespace Server.Misc a.AccessLevel = AccessLevel.Owner; Console.WriteLine("Account created."); + + ServerAccess.AddProtectedAccount(a, true); + Console.WriteLine("Added {0} to the protected accounts list.", a.Username); } else { diff --git a/Projects/UOContent/Misc/PacketThrottles.cs b/Projects/UOContent/Misc/PacketThrottles.cs index d2b666ed9..dda06aab8 100644 --- a/Projects/UOContent/Misc/PacketThrottles.cs +++ b/Projects/UOContent/Misc/PacketThrottles.cs @@ -10,7 +10,7 @@ namespace Server.Network { // Delay in milliseconds private static readonly int[] Delays = new int[0x100]; - private static string ThrottlesConfiguration = "Configuration/throttles.json"; + private const string ThrottlesConfiguration = "Configuration/throttles.json"; public static void Initialize() { diff --git a/Projects/UOContent/Misc/ServerAccess.cs b/Projects/UOContent/Misc/ServerAccess.cs new file mode 100644 index 000000000..433055b86 --- /dev/null +++ b/Projects/UOContent/Misc/ServerAccess.cs @@ -0,0 +1,99 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text.Json.Serialization; +using Server.Accounting; +using Server.Json; +using Server.Logging; + +namespace Server.Misc; + +public static class ServerAccess +{ + private static readonly ILogger logger = LogFactory.GetLogger(typeof(ServerAccess)); + private const string _serverAccessConfigurationPath = "Configuration/server-access.json"; + public static ServerAccessConfiguration ServerAccessConfiguration { get; private set; } + + public static void SaveConfiguration() + { + var path = Path.Join(Core.BaseDirectory, _serverAccessConfigurationPath); + JsonConfig.Serialize(path, ServerAccessConfiguration); + } + + public static void AddProtectedAccount(Account acct, bool save = false) + { + ServerAccessConfiguration.ProtectedAccounts.Add(acct.Username.ToLower()); + + if (save) + { + SaveConfiguration(); + } + } + + public static void RemoveProtectedAccount(Account acct, bool save = false) + { + ServerAccessConfiguration.ProtectedAccounts.Remove(acct.Username.ToLower()); + + if (save) + { + SaveConfiguration(); + } + } + + public static void Configure() + { + var path = Path.Join(Core.BaseDirectory, _serverAccessConfigurationPath); + + if (!File.Exists(path)) + { + return; + } + + ServerAccessConfiguration = JsonConfig.Deserialize(path); + var protectedAccounts = string.Join(", ", ServerAccessConfiguration.ProtectedAccounts); + logger.Information("Protected accounts registered: {0}", protectedAccounts); + } + + public static void Initialize() + { + EventSink.AccountLogin += EventSink_ResetProtectedAccount; + } + + public static void EventSink_ResetProtectedAccount(AccountLoginEventArgs e) + { + var username = e.Username.ToLower(); + if (!ServerAccessConfiguration.ProtectedAccounts.Contains(username)) + { + return; + } + + var account = Accounts.GetAccount(username); + if (account is not { Banned: true, AccessLevel: >= AccessLevel.Owner }) + { + return; + } + + account.Banned = false; + account.AccessLevel = AccessLevel.Owner; + + logger.Warning("Protected account \"{0}\" has been reset.", username); + + if (ServerAccessConfiguration.NewPasswordOnReset) + { + var password = Guid.NewGuid().ToString(); + logger.Warning("Protected account \"{0}\" password reset to \"{1}\"", username, password); + account.SetPassword(password); + } + + e.Accepted = true; + } +} + +public record ServerAccessConfiguration +{ + [JsonPropertyName("newPasswordOnReset")] + public bool NewPasswordOnReset { get; init; } + + [JsonPropertyName("protectedAccounts")] + public HashSet ProtectedAccounts { get; init; } +} From 1989488638c73817a87a619a7cadf3299b0a5ea0 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Mon, 10 Jan 2022 23:32:12 -0800 Subject: [PATCH 066/213] fix: Fixes server access for owners (#916) * Removes new password on reset option. * Fixes a bug with the feature that would allow an exploit. --- Projects/UOContent/Misc/ServerAccess.cs | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/Projects/UOContent/Misc/ServerAccess.cs b/Projects/UOContent/Misc/ServerAccess.cs index 433055b86..c8278def4 100644 --- a/Projects/UOContent/Misc/ServerAccess.cs +++ b/Projects/UOContent/Misc/ServerAccess.cs @@ -5,6 +5,7 @@ using System.Text.Json.Serialization; using Server.Accounting; using Server.Json; using Server.Logging; +using Server.Network; namespace Server.Misc; @@ -67,33 +68,26 @@ public static class ServerAccess return; } - var account = Accounts.GetAccount(username); - if (account is not { Banned: true, AccessLevel: >= AccessLevel.Owner }) + var acct = Accounts.GetAccount(username); + if (acct == null || !acct.Banned && acct.AccessLevel >= AccessLevel.Owner || !acct.CheckPassword(e.Password)) { return; } - account.Banned = false; - account.AccessLevel = AccessLevel.Owner; + acct.Banned = false; + acct.AccessLevel = AccessLevel.Owner; logger.Warning("Protected account \"{0}\" has been reset.", username); - if (ServerAccessConfiguration.NewPasswordOnReset) + if (e.RejectReason is ALRReason.Blocked or ALRReason.BadPass or ALRReason.BadComm) { - var password = Guid.NewGuid().ToString(); - logger.Warning("Protected account \"{0}\" password reset to \"{1}\"", username, password); - account.SetPassword(password); + e.Accepted = true; } - - e.Accepted = true; } } public record ServerAccessConfiguration { - [JsonPropertyName("newPasswordOnReset")] - public bool NewPasswordOnReset { get; init; } - [JsonPropertyName("protectedAccounts")] public HashSet ProtectedAccounts { get; init; } } From cf5cc247db098d31c8f9927ca5236aa5b159f193 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 16 Jan 2022 22:53:48 -0800 Subject: [PATCH 067/213] fix: Fixes server access NPE error (#919) --- Projects/UOContent/Misc/ServerAccess.cs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/Projects/UOContent/Misc/ServerAccess.cs b/Projects/UOContent/Misc/ServerAccess.cs index c8278def4..9b43d604a 100644 --- a/Projects/UOContent/Misc/ServerAccess.cs +++ b/Projects/UOContent/Misc/ServerAccess.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.IO; using System.Text.Json.Serialization; @@ -18,12 +17,15 @@ public static class ServerAccess public static void SaveConfiguration() { var path = Path.Join(Core.BaseDirectory, _serverAccessConfigurationPath); - JsonConfig.Serialize(path, ServerAccessConfiguration); + + JsonConfig.Serialize(path, ServerAccessConfiguration ??= new ServerAccessConfiguration()); } public static void AddProtectedAccount(Account acct, bool save = false) { - ServerAccessConfiguration.ProtectedAccounts.Add(acct.Username.ToLower()); + var username = acct.Username.ToLower(); + ServerAccessConfiguration.ProtectedAccounts.Add(username); + logger.Information("Protected account added: {0}", username); if (save) { @@ -33,7 +35,9 @@ public static class ServerAccess public static void RemoveProtectedAccount(Account acct, bool save = false) { - ServerAccessConfiguration.ProtectedAccounts.Remove(acct.Username.ToLower()); + var username = acct.Username.ToLower(); + ServerAccessConfiguration.ProtectedAccounts.Remove(username); + logger.Information("Protected account removed: {0}", username); if (save) { @@ -47,6 +51,7 @@ public static class ServerAccess if (!File.Exists(path)) { + SaveConfiguration(); return; } @@ -89,5 +94,5 @@ public static class ServerAccess public record ServerAccessConfiguration { [JsonPropertyName("protectedAccounts")] - public HashSet ProtectedAccounts { get; init; } + public HashSet ProtectedAccounts { get; set; } = new(); } From 6fef622715d19b521c60d5343bb02b5c7eb06bf6 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 30 Jan 2022 14:02:46 -0800 Subject: [PATCH 068/213] fix: Fixes en-us forced pricing culture throwing when bulding in VS (#921) * fix: Fixes en-us forced pricing culture throwing when bulding in VS * Fixes value --- Directory.Build.props | 1 + 1 file changed, 1 insertion(+) diff --git a/Directory.Build.props b/Directory.Build.props index d0e008643..500f44bb9 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -28,6 +28,7 @@ NO_LOCAL_INIT MUO $(SolutionDir) + false true From 01a41732f116974e3d0016349833965978da395a Mon Sep 17 00:00:00 2001 From: Stefano Merotta <97297186+stefanomerotta@users.noreply.github.com> Date: Fri, 4 Feb 2022 18:33:12 +0100 Subject: [PATCH 069/213] fix: Fixes missing EJ houses in catalog (#925) --- .gitignore | 1 + Projects/UOContent/Multis/Houses/HousePlacementTool.cs | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 325476c99..ae6dbf334 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,4 @@ .DS_Store /packages/* +/Distribution/Configuration/server-access.json diff --git a/Projects/UOContent/Multis/Houses/HousePlacementTool.cs b/Projects/UOContent/Multis/Houses/HousePlacementTool.cs index 56817bf22..19eafcb53 100644 --- a/Projects/UOContent/Multis/Houses/HousePlacementTool.cs +++ b/Projects/UOContent/Multis/Houses/HousePlacementTool.cs @@ -103,8 +103,9 @@ namespace Server.Items { case 1: // Classic Houses { - // TODO: Add flag to use ClassicHouses or EJ - m_From.SendGump(new HousePlacementListGump(m_From, HousePlacementEntry.HousesEJ)); + var entry = Core.EJ ? HousePlacementEntry.HousesEJ : HousePlacementEntry.ClassicHouses; + m_From.SendGump(new HousePlacementListGump(m_From, entry)); + break; } case 2: // 2-Story Customizable Houses @@ -318,7 +319,7 @@ namespace Server.Items { m_Table = new Dictionary(); - FillTable(ClassicHouses); + FillTable(Core.EJ ? HousesEJ : ClassicHouses); FillTable(TwoStoryFoundations); FillTable(ThreeStoryFoundations); } From 48f1fe338485d5047aafe1e01b6136f74cd9596c Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sat, 12 Feb 2022 17:58:42 -0800 Subject: [PATCH 070/213] fix: Moves codegen to its own repo (#918) - [X] Replace serialization generator with nuget - [X] Replace schema migration with dotnet bool - [X] Add ability to run migrations in VS/Rider using a project build --- .config/dotnet-tools.json | 12 + Directory.Build.props | 2 +- ModernUO.sln | 22 +- .../Run Schema Migrations.csproj | 13 + .../EntitySerializationGenerator.cs | 91 ---- .../SerializationGenerator/IsExternalInit.cs | 4 - .../SerializableEntityGeneration.Class.cs | 436 ------------------ ...zableEntityGeneration.DeserializeMethod.cs | 213 --------- .../SerializableEntityGeneration.Property.cs | 82 ---- ...SerializableEntityGeneration.SerialCtor.cs | 52 --- ...lizableEntityGeneration.SerializeMethod.cs | 112 ----- .../SerializableFieldSaveFlagMethods.cs | 11 - ...alizationEntityGeneration.ContentStruct.cs | 127 ----- .../IPostDeserializeMethod.cs | 31 -- .../ISerializableMigrationRule.cs | 57 --- .../Rules/ArrayMigrationRule.cs | 135 ------ .../Rules/DictionaryMigrationRule.cs | 250 ---------- .../Rules/EnumMigrationRule.cs | 73 --- .../Rules/HashSetMigrationRule.cs | 171 ------- .../Rules/KeyValuePairMigrationRule.cs | 225 --------- .../Rules/ListMigrationRule.cs | 172 ------- .../Rules/MigrationRule.cs | 36 -- .../Rules/PrimitiveTypeMigrationRule.cs | 149 ------ .../Rules/PrimitiveUOTypeMigrationRule.cs | 80 ---- .../Rules/RawSerializableMigrationRule.cs | 82 ---- .../SerializableInterfaceMigrationRule.cs | 75 --- ...rializationMethodSignatureMigrationRule.cs | 85 ---- .../Rules/TimerMigrationRule.cs | 136 ------ .../SerializableMetadata.cs | 32 -- .../SerializableMetadataComparer.cs | 27 -- .../SerializableMigrationRulesEngine.cs | 133 ------ .../SerializableMigrationSchema.cs | 112 ----- .../SerializableProperty.cs | 40 -- .../SerializablePropertyComparer.cs | 42 -- .../SerializationGenerator.csproj | 31 -- .../SerializerSyntaxReceiver.cs | 133 ------ .../SourceGeneration/Helpers.cs | 65 --- .../SourceGeneration.Arguments.cs | 125 ----- .../SourceGeneration.Attribute.cs | 102 ---- .../SourceGeneration.Class.cs | 72 --- .../SourceGeneration/SourceGeneration.Enum.cs | 50 -- .../SourceGeneration.InstanceModifier.cs | 39 -- .../SourceGeneration.Method.cs | 62 --- .../SourceGeneration.Namespace.cs | 33 -- .../SourceGeneration.Property.cs | 144 ------ .../SymbolMetadata/SymbolMetadata.Builtin.cs | 69 --- .../SymbolMetadata/SymbolMetadata.UO.cs | 228 --------- Projects/SerializationGenerator/Utility.cs | 28 -- .../SerializationSchemaGenerator/.gitignore | 1 - .../Application.cs | 103 ----- .../SerializationSchemaGenerator.csproj | 23 - .../SourceCodeAnalysis.cs | 49 -- .../SyntaxVisitor.cs | 52 --- Projects/Server/Server.csproj | 10 +- Projects/UOContent/UOContent.csproj | 12 +- publish.cmd | 24 +- 56 files changed, 48 insertions(+), 4727 deletions(-) create mode 100644 .config/dotnet-tools.json create mode 100644 Projects/Schema Migrations/Run Schema Migrations.csproj delete mode 100755 Projects/SerializationGenerator/EntitySerializationGenerator.cs delete mode 100644 Projects/SerializationGenerator/IsExternalInit.cs delete mode 100644 Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.Class.cs delete mode 100644 Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.DeserializeMethod.cs delete mode 100644 Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.Property.cs delete mode 100644 Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.SerialCtor.cs delete mode 100644 Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.SerializeMethod.cs delete mode 100644 Projects/SerializationGenerator/SerializableEntityGeneration/SerializableFieldSaveFlagMethods.cs delete mode 100644 Projects/SerializationGenerator/SerializableEntityGeneration/SerializationEntityGeneration.ContentStruct.cs delete mode 100644 Projects/SerializationGenerator/SerializableMigration/IPostDeserializeMethod.cs delete mode 100644 Projects/SerializationGenerator/SerializableMigration/ISerializableMigrationRule.cs delete mode 100644 Projects/SerializationGenerator/SerializableMigration/Rules/ArrayMigrationRule.cs delete mode 100644 Projects/SerializationGenerator/SerializableMigration/Rules/DictionaryMigrationRule.cs delete mode 100644 Projects/SerializationGenerator/SerializableMigration/Rules/EnumMigrationRule.cs delete mode 100644 Projects/SerializationGenerator/SerializableMigration/Rules/HashSetMigrationRule.cs delete mode 100644 Projects/SerializationGenerator/SerializableMigration/Rules/KeyValuePairMigrationRule.cs delete mode 100644 Projects/SerializationGenerator/SerializableMigration/Rules/ListMigrationRule.cs delete mode 100644 Projects/SerializationGenerator/SerializableMigration/Rules/MigrationRule.cs delete mode 100644 Projects/SerializationGenerator/SerializableMigration/Rules/PrimitiveTypeMigrationRule.cs delete mode 100644 Projects/SerializationGenerator/SerializableMigration/Rules/PrimitiveUOTypeMigrationRule.cs delete mode 100644 Projects/SerializationGenerator/SerializableMigration/Rules/RawSerializableMigrationRule.cs delete mode 100644 Projects/SerializationGenerator/SerializableMigration/Rules/SerializableInterfaceMigrationRule.cs delete mode 100644 Projects/SerializationGenerator/SerializableMigration/Rules/SerializationMethodSignatureMigrationRule.cs delete mode 100644 Projects/SerializationGenerator/SerializableMigration/Rules/TimerMigrationRule.cs delete mode 100644 Projects/SerializationGenerator/SerializableMigration/SerializableMetadata.cs delete mode 100644 Projects/SerializationGenerator/SerializableMigration/SerializableMetadataComparer.cs delete mode 100644 Projects/SerializationGenerator/SerializableMigration/SerializableMigrationRulesEngine.cs delete mode 100644 Projects/SerializationGenerator/SerializableMigration/SerializableMigrationSchema.cs delete mode 100644 Projects/SerializationGenerator/SerializableMigration/SerializableProperty.cs delete mode 100644 Projects/SerializationGenerator/SerializableMigration/SerializablePropertyComparer.cs delete mode 100755 Projects/SerializationGenerator/SerializationGenerator.csproj delete mode 100755 Projects/SerializationGenerator/SerializerSyntaxReceiver.cs delete mode 100644 Projects/SerializationGenerator/SourceGeneration/Helpers.cs delete mode 100644 Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Arguments.cs delete mode 100644 Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Attribute.cs delete mode 100644 Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Class.cs delete mode 100644 Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Enum.cs delete mode 100644 Projects/SerializationGenerator/SourceGeneration/SourceGeneration.InstanceModifier.cs delete mode 100644 Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Method.cs delete mode 100644 Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Namespace.cs delete mode 100644 Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Property.cs delete mode 100644 Projects/SerializationGenerator/SourceGeneration/SymbolMetadata/SymbolMetadata.Builtin.cs delete mode 100644 Projects/SerializationGenerator/SourceGeneration/SymbolMetadata/SymbolMetadata.UO.cs delete mode 100644 Projects/SerializationGenerator/Utility.cs delete mode 100644 Projects/SerializationSchemaGenerator/.gitignore delete mode 100644 Projects/SerializationSchemaGenerator/Application.cs delete mode 100755 Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj delete mode 100644 Projects/SerializationSchemaGenerator/SourceCodeAnalysis.cs delete mode 100644 Projects/SerializationSchemaGenerator/SyntaxVisitor.cs diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json new file mode 100644 index 000000000..e0dbc85fc --- /dev/null +++ b/.config/dotnet-tools.json @@ -0,0 +1,12 @@ +{ + "version": 1, + "isRoot": true, + "tools": { + "modernuoschemagenerator": { + "version": "1.0.2", + "commands": [ + "ModernUOSchemaGenerator" + ] + } + } +} diff --git a/Directory.Build.props b/Directory.Build.props index 500f44bb9..4a52a9154 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -59,7 +59,7 @@ - 3.4.244 + 3.4.255 all diff --git a/ModernUO.sln b/ModernUO.sln index 75eb761a4..3251fb4a4 100644 --- a/ModernUO.sln +++ b/ModernUO.sln @@ -12,9 +12,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UOContent.Tests", "Projects EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Benchmarks", "Projects\Benchmarks\Benchmarks.csproj", "{38B7E4A1-FDDD-486C-98EE-BA7B13712528}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SerializationGenerator", "Projects\SerializationGenerator\SerializationGenerator.csproj", "{07DDB8CF-F926-44F4-A584-FF2997D2C9D0}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SerializationSchemaGenerator", "Projects\SerializationSchemaGenerator\SerializationSchemaGenerator.csproj", "{A30150A3-796C-4C6D-B3E4-B7BEB0021701}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Run Schema Migrations", "Projects\Schema Migrations\Run Schema Migrations.csproj", "{75256276-FEAB-416C-9DB8-533FE816A0EF}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -53,18 +51,12 @@ Global {38B7E4A1-FDDD-486C-98EE-BA7B13712528}.Debug|x64.Build.0 = Debug|x64 {38B7E4A1-FDDD-486C-98EE-BA7B13712528}.Release|x64.ActiveCfg = Release|x64 {38B7E4A1-FDDD-486C-98EE-BA7B13712528}.Release|x64.Build.0 = Release|x64 - {07DDB8CF-F926-44F4-A584-FF2997D2C9D0}.Analyze|x64.ActiveCfg = Analyze|x64 - {07DDB8CF-F926-44F4-A584-FF2997D2C9D0}.Analyze|x64.Build.0 = Analyze|x64 - {07DDB8CF-F926-44F4-A584-FF2997D2C9D0}.Debug|x64.ActiveCfg = Debug|x64 - {07DDB8CF-F926-44F4-A584-FF2997D2C9D0}.Debug|x64.Build.0 = Debug|x64 - {07DDB8CF-F926-44F4-A584-FF2997D2C9D0}.Release|x64.ActiveCfg = Release|x64 - {07DDB8CF-F926-44F4-A584-FF2997D2C9D0}.Release|x64.Build.0 = Release|x64 - {A30150A3-796C-4C6D-B3E4-B7BEB0021701}.Analyze|x64.ActiveCfg = Analyze|x64 - {A30150A3-796C-4C6D-B3E4-B7BEB0021701}.Analyze|x64.Build.0 = Analyze|x64 - {A30150A3-796C-4C6D-B3E4-B7BEB0021701}.Debug|x64.ActiveCfg = Debug|x64 - {A30150A3-796C-4C6D-B3E4-B7BEB0021701}.Debug|x64.Build.0 = Debug|x64 - {A30150A3-796C-4C6D-B3E4-B7BEB0021701}.Release|x64.ActiveCfg = Release|x64 - {A30150A3-796C-4C6D-B3E4-B7BEB0021701}.Release|x64.Build.0 = Release|x64 + {75256276-FEAB-416C-9DB8-533FE816A0EF}.Analyze|x64.ActiveCfg = Analyze|x64 + {75256276-FEAB-416C-9DB8-533FE816A0EF}.Analyze|x64.Build.0 = Analyze|x64 + {75256276-FEAB-416C-9DB8-533FE816A0EF}.Debug|x64.ActiveCfg = Debug|x64 + {75256276-FEAB-416C-9DB8-533FE816A0EF}.Debug|x64.Build.0 = Debug|x64 + {75256276-FEAB-416C-9DB8-533FE816A0EF}.Release|x64.ActiveCfg = Release|x64 + {75256276-FEAB-416C-9DB8-533FE816A0EF}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Projects/Schema Migrations/Run Schema Migrations.csproj b/Projects/Schema Migrations/Run Schema Migrations.csproj new file mode 100644 index 000000000..39947e2f9 --- /dev/null +++ b/Projects/Schema Migrations/Run Schema Migrations.csproj @@ -0,0 +1,13 @@ + + + Schema_Migrations + + + + + + + + + + diff --git a/Projects/SerializationGenerator/EntitySerializationGenerator.cs b/Projects/SerializationGenerator/EntitySerializationGenerator.cs deleted file mode 100755 index e5b1e0f0d..000000000 --- a/Projects/SerializationGenerator/EntitySerializationGenerator.cs +++ /dev/null @@ -1,91 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright (C) 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: EntityJsonGenerator.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System.Collections.Immutable; -using System.Text; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Text; -using SerializableMigration; - -namespace SerializationGenerator -{ - [Generator] - public class EntitySerializationGenerator : ISourceGenerator - { - public void Initialize(GeneratorInitializationContext context) - { - context.RegisterForSyntaxNotifications(() => new SerializerSyntaxReceiver()); - } - - public void Execute(GeneratorExecutionContext context) - { - if (context.SyntaxContextReceiver is not SerializerSyntaxReceiver receiver) - { - return; - } - - var jsonOptions = SerializableMigrationSchema.GetJsonSerializerOptions(); - // List of types that _will_ become ISerializable - var serializableList = receiver.SerializableList; - var embeddedSerializableList = receiver.EmbeddedSerializableList; - - foreach (var (classSymbol, (serializableAttr, fieldsList)) in receiver.ClassAndFields) - { - if (serializableAttr == null) - { - continue; - } - - string classSource = context.GenerateSerializationPartialClass( - classSymbol, - serializableAttr, - false, - fieldsList.ToImmutableArray(), - jsonOptions, - serializableList, - embeddedSerializableList - ); - - if (classSource != null) - { - context.AddSource($"{classSymbol.ToDisplayString()}.Serialization.cs", SourceText.From(classSource, Encoding.UTF8)); - } - } - - foreach (var (classSymbol, (embeddedSerializableAttr, fieldsList)) in receiver.EmbeddedClassAndFields) - { - if (embeddedSerializableAttr == null) - { - continue; - } - - string classSource = context.GenerateSerializationPartialClass( - classSymbol, - embeddedSerializableAttr, - true, - fieldsList.ToImmutableArray(), - jsonOptions, - serializableList, - embeddedSerializableList - ); - - if (classSource != null) - { - context.AddSource($"{classSymbol.ToDisplayString()}.Serialization.cs", SourceText.From(classSource, Encoding.UTF8)); - } - } - } - } -} diff --git a/Projects/SerializationGenerator/IsExternalInit.cs b/Projects/SerializationGenerator/IsExternalInit.cs deleted file mode 100644 index eb2da113f..000000000 --- a/Projects/SerializationGenerator/IsExternalInit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace System.Runtime.CompilerServices -{ - internal static class IsExternalInit {} -} diff --git a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.Class.cs b/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.Class.cs deleted file mode 100644 index 7611d5799..000000000 --- a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.Class.cs +++ /dev/null @@ -1,436 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SerializableEntityGeneration.Class.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.IO; -using System.Linq; -using System.Text; -using System.Text.Json; -using Microsoft.CodeAnalysis; -using SerializableMigration; - -namespace SerializationGenerator -{ - public static partial class SerializableEntityGeneration - { - public static string GenerateSerializationPartialClass( - this GeneratorExecutionContext context, - INamedTypeSymbol classSymbol, - AttributeData serializableAttr, - bool embedded, - ImmutableArray fieldsAndProperties, - JsonSerializerOptions jsonSerializerOptions, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes - ) - { - var version = (int)serializableAttr.ConstructorArguments[0].Value!; - - var migrations = context.GetMigrationsByAnalyzerConfig( - classSymbol, - version, - jsonSerializerOptions - ); - - return context.Compilation.GenerateSerializationPartialClass( - classSymbol, - serializableAttr, - null, // Do not generate schema - embedded, - null, - migrations.ToImmutableArray(), - fieldsAndProperties, - serializableTypes, - embeddedSerializableTypes - ); - } - - public static string GenerateSerializationPartialClass( - this Compilation compilation, - INamedTypeSymbol classSymbol, - AttributeData serializableAttr, - string? migrationPath, - bool embedded, - JsonSerializerOptions? jsonSerializerOptions, - ImmutableArray fieldsAndProperties, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes - ) - { - var version = (int)serializableAttr.ConstructorArguments[0].Value!; - - var migrations = SerializableMigrationSchema.GetMigrations( - classSymbol, - version, - migrationPath, - jsonSerializerOptions - ); - - return compilation.GenerateSerializationPartialClass( - classSymbol, - serializableAttr, - migrationPath, - embedded, - jsonSerializerOptions, - migrations.ToImmutableArray(), - fieldsAndProperties, - serializableTypes, - embeddedSerializableTypes - ); - } - - public static string GenerateSerializationPartialClass( - this Compilation compilation, - INamedTypeSymbol classSymbol, - AttributeData serializableAttr, - string? migrationPath, - bool embedded, - JsonSerializerOptions? jsonSerializerOptions, - ImmutableArray migrations, - ImmutableArray fieldsAndProperties, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes - ) - { - var serializableFieldAttribute = - compilation.GetTypeByMetadataName(SymbolMetadata.SERIALIZABLE_FIELD_ATTRIBUTE); - var serializableFieldAttrAttribute = - compilation.GetTypeByMetadataName(SymbolMetadata.SERIALIZABLE_FIELD_ATTR_ATTRIBUTE); - var serializableInterface = - compilation.GetTypeByMetadataName(SymbolMetadata.SERIALIZABLE_INTERFACE); - var parentSerializableAttribute = - compilation.GetTypeByMetadataName(SymbolMetadata.SERIALIZABLE_PARENT_ATTRIBUTE); - var serializableFieldSaveFlagAttribute = - compilation.GetTypeByMetadataName(SymbolMetadata.SERIALIZABLE_FIELD_SAVE_FLAG_ATTRIBUTE); - var serializableFieldDefaultAttribute = - compilation.GetTypeByMetadataName(SymbolMetadata.SERIALIZABLE_FIELD_DEFAULT_ATTRIBUTE); - - // If we have a parent that is or derives from ISerializable, then we are in override - var isOverride = classSymbol.BaseType.ContainsInterface(serializableInterface); - - if (!(embedded || isOverride || classSymbol.ContainsInterface(serializableInterface))) - { - return null; - } - - var isRawSerializable = classSymbol.HasRawSerializableInterface(compilation, ImmutableArray.Empty); - - var version = (int)serializableAttr.ConstructorArguments[0].Value!; - var encodedVersion = (bool)serializableAttr.ConstructorArguments[1].Value!; - - // Let's find out if we need to do serialization flags - var serializableFieldSaveFlags = new SortedDictionary(); - foreach (var m in classSymbol.GetMembers().OfType()) - { - var getSaveFlagAttribute = m.GetAttribute(serializableFieldSaveFlagAttribute); - var getDefaultValueAttribute = m.GetAttribute(serializableFieldDefaultAttribute); - - if (getSaveFlagAttribute == null && getDefaultValueAttribute == null) - { - continue; - } - - var attrCtorArgs = getSaveFlagAttribute?.ConstructorArguments ?? getDefaultValueAttribute.ConstructorArguments; - var order = (int)attrCtorArgs[0].Value!; - - serializableFieldSaveFlags.TryGetValue(order, out var saveFlagMethods); - - serializableFieldSaveFlags[order] = new SerializableFieldSaveFlagMethods - { - DetermineFieldShouldSerialize = getSaveFlagAttribute != null ? m : saveFlagMethods?.DetermineFieldShouldSerialize, - GetFieldDefaultValue = getDefaultValueAttribute != null ? m : saveFlagMethods?.GetFieldDefaultValue - }; - } - - var namespaceName = classSymbol.ContainingNamespace.ToDisplayString(); - var className = classSymbol.Name; - - StringBuilder source = new StringBuilder(); - - source.AppendLine("#pragma warning disable\n"); - source.GenerateNamespaceStart(namespaceName); - - var interfaces = !embedded || isRawSerializable - ? Array.Empty() - : new ITypeSymbol[] { compilation.GetTypeByMetadataName(SymbolMetadata.RAW_SERIALIZABLE_INTERFACE) }; - - var indent = " "; - - source.RecursiveGenerateClassStart(classSymbol, interfaces.ToImmutableArray(), ref indent); - - source.GenerateClassField( - indent, - Accessibility.Private, - InstanceModifier.Const, - "int", - "_version", - version.ToString() - ); - source.AppendLine(); - - var parentFieldOrProperty = embedded ? fieldsAndProperties.FirstOrDefault( - fieldOrPropertySymbol => fieldOrPropertySymbol.GetAttributes() - .FirstOrDefault( - attr => - SymbolEqualityComparer.Default.Equals(attr.AttributeClass, parentSerializableAttribute) - ) != null - ) : null; - - var serializablePropertySet = new SortedDictionary(new SerializablePropertyComparer()); - - foreach (var fieldOrPropertySymbol in fieldsAndProperties) - { - var allAttributes = fieldOrPropertySymbol.GetAttributes(); - - var serializableFieldAttr = allAttributes - .FirstOrDefault( - attr => - SymbolEqualityComparer.Default.Equals(attr.AttributeClass, serializableFieldAttribute) - ); - - if (serializableFieldAttr == null) - { - continue; - } - - foreach (var attr in allAttributes) - { - if (!SymbolEqualityComparer.Default.Equals(attr.AttributeClass, serializableFieldAttrAttribute)) - { - continue; - } - - if (attr.AttributeClass == null) - { - continue; - } - - var ctorArgs = attr.ConstructorArguments; - var attrTypeArg = ctorArgs[0]; - - if (attrTypeArg.Kind == TypedConstantKind.Primitive && attrTypeArg.Value is string attrStr) - { - source.AppendLine($"{indent}{attrStr}"); - } - else - { - var attrType = (ITypeSymbol)attrTypeArg.Value; - source.GenerateAttribute(indent, attrType?.Name, ctorArgs[1].Values); - } - } - - var attrCtorArgs = serializableFieldAttr.ConstructorArguments; - - var order = (int)attrCtorArgs[0].Value!; - var getterAccessor = Helpers.GetAccessibility(attrCtorArgs[1].Value?.ToString()); - var setterAccessor = Helpers.GetAccessibility(attrCtorArgs[2].Value?.ToString()); - var virtualProperty = (bool)attrCtorArgs[3].Value!; - - if (fieldOrPropertySymbol is IFieldSymbol fieldSymbol) - { - source.GenerateSerializableProperty( - compilation, - indent, - fieldSymbol, - getterAccessor, - setterAccessor, - virtualProperty, - parentFieldOrProperty - ); - source.AppendLine(); - } - - serializableFieldSaveFlags.TryGetValue(order, out var serializableFieldSaveFlagMethods); - - var serializableProperty = SerializableMigrationRulesEngine.GenerateSerializableProperty( - compilation, - fieldOrPropertySymbol, - order, - allAttributes, - serializableTypes, - embeddedSerializableTypes, - classSymbol, - serializableFieldSaveFlagMethods - ); - - serializablePropertySet.Add(serializableProperty, fieldOrPropertySymbol); - } - - var serializableFields = serializablePropertySet.Keys.ToImmutableArray(); - var serializableProperties = serializablePropertySet.Select( - kvp => kvp.Key with - { - Name = (kvp.Value as IFieldSymbol)?.GetPropertyName() ?? ((IPropertySymbol)kvp.Value).Name - } - ).ToImmutableArray(); - - // If we are not inheriting ISerializable, then we need to define some stuff - if (!(isOverride || embedded)) - { - // long ISerializable.SavePosition { get; set; } = -1; - source.GenerateAutoProperty( - Accessibility.NotApplicable, - "long", - "ISerializable.SavePosition", - Accessibility.NotApplicable, - Accessibility.NotApplicable, - indent, - defaultValue: "-1" - ); - - // BufferWriter ISerializable.SaveBuffer { get; set; } - source.GenerateAutoProperty( - Accessibility.NotApplicable, - "BufferWriter", - "ISerializable.SaveBuffer", - Accessibility.NotApplicable, - Accessibility.NotApplicable, - indent - ); - } - - if (!embedded) - { - // Serial constructor - source.GenerateSerialCtor(compilation, className, indent, isOverride); - source.AppendLine(); - } - - if (version > 0) - { - for (var i = 0; i < migrations.Length; i++) - { - var migration = migrations[i]; - if (migration.Version < version) - { - source.GenerateMigrationContentStruct(compilation, indent, migration, classSymbol); - source.AppendLine(); - } - } - } - - // Serialize Method - source.GenerateSerializeMethod( - compilation, - indent, - isOverride, - encodedVersion, - serializableFields, - serializableProperties, - serializableFieldSaveFlags - ); - source.AppendLine(); - - // Deserialize Method - source.GenerateDeserializeMethod( - compilation, - classSymbol, - indent, - isOverride, - version, - encodedVersion, - migrations, - serializableFields, - serializableProperties, - parentFieldOrProperty, - serializableFieldSaveFlags - ); - - // Serialize SaveFlag enum class - if (serializableFieldSaveFlags.Count > 0) - { - source.AppendLine(); - source.GenerateEnumStart( - "SaveFlag", - $"{indent} ", - true, - Accessibility.Private - ); - - source.GenerateEnumValue($"{indent} ", true, "None", -1); - int index = 0; - foreach (var (order, _) in serializableFieldSaveFlags) - { - source.GenerateEnumValue($"{indent} ", true, serializableProperties[order].Name, index++); - } - - source.GenerateEnumEnd($"{indent} "); - } - - source.RecursiveGenerateClassEnd(classSymbol, ref indent); - source.GenerateNamespaceEnd(); - - if (migrationPath != null) - { - // Write the migration file - var newMigration = new SerializableMetadata - { - Version = version, - Type = classSymbol.ToDisplayString(), - Properties = serializableProperties.Length > 0 ? serializableProperties : null - }; - - WriteMigration(migrationPath, newMigration, jsonSerializerOptions); - } - - return source.ToString(); - } - - private static void WriteMigration(string migrationPath, SerializableMetadata metadata, JsonSerializerOptions options) - { - Directory.CreateDirectory(migrationPath); - var filePath = Path.Combine(migrationPath, $"{metadata.Type}.v{metadata.Version}.json"); - File.WriteAllText(filePath, JsonSerializer.Serialize(metadata, options)); - } - - private static void RecursiveGenerateClassStart( - this StringBuilder source, - INamedTypeSymbol classSymbol, - ImmutableArray interfaces, - ref string indent - ) - { - var containingSymbolList = new List(); - - do - { - containingSymbolList.Add(classSymbol); - classSymbol = classSymbol.ContainingSymbol as INamedTypeSymbol; - } while (classSymbol != null); - - containingSymbolList.Reverse(); - - for (var i = 0; i < containingSymbolList.Count; i++) - { - var symbol = containingSymbolList[i]; - source.GenerateClassStart(symbol, indent, i == containingSymbolList.Count - 1 ? interfaces : ImmutableArray.Empty); - indent += " "; - } - } - - private static void RecursiveGenerateClassEnd(this StringBuilder source, INamedTypeSymbol classSymbol, ref string indent) - { - do - { - indent = indent.Substring(0, indent.Length - 4); - source.GenerateClassEnd(indent); - - classSymbol = classSymbol.ContainingSymbol as INamedTypeSymbol; - } while (classSymbol != null); - } - } -} diff --git a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.DeserializeMethod.cs b/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.DeserializeMethod.cs deleted file mode 100644 index 59048a125..000000000 --- a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.DeserializeMethod.cs +++ /dev/null @@ -1,213 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SerializableEntityGeneration.DeserializeMethod.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Linq; -using System.Text; -using Microsoft.CodeAnalysis; -using SerializableMigration; - -namespace SerializationGenerator -{ - public static partial class SerializableEntityGeneration - { - public static void GenerateDeserializeMethod( - this StringBuilder source, - Compilation compilation, - INamedTypeSymbol classSymbol, - string indent, - bool isOverride, - int version, - bool encodedVersion, - ImmutableArray migrations, - ImmutableArray fields, - ImmutableArray properties, - ISymbol parentFieldOrProperty, - SortedDictionary serializableFieldSaveFlagMethodsDictionary - ) - { - var genericReaderInterface = compilation.GetTypeByMetadataName(SymbolMetadata.GENERIC_READER_INTERFACE); - - source.GenerateMethodStart( - indent, - "Deserialize", - Accessibility.Public, - isOverride, - "void", - ImmutableArray.Create<(ITypeSymbol, string)>((genericReaderInterface, "reader")) - ); - - var bodyIndent = $"{indent} "; - var innerIndent = $"{bodyIndent} "; - - if (isOverride) - { - source.AppendLine($"{bodyIndent}base.Deserialize(reader);"); - source.AppendLine(); - } - - var afterDeserialization = classSymbol - .GetMembers() - .OfType() - .Select( - m => - { - if (!m.ReturnsVoid || m.Parameters.Length != 0) - { - return (m, null); - } - - return (m, m.GetAttributes() - .FirstOrDefault( - attr => SymbolEqualityComparer.Default.Equals( - attr.AttributeClass, - compilation.GetTypeByMetadataName(SymbolMetadata.AFTERDESERIALIZATION_ATTRIBUTE) - ) - )); - } - ).Where(m => m.Item2 != null).ToList(); - - // Version - source.AppendLine($"{bodyIndent}var version = reader.{(encodedVersion ? "ReadEncodedInt" : "ReadInt")}();"); - - if (version > 0) - { - var parent = parentFieldOrProperty?.Name ?? "this"; - var nextVersion = 0; - - for (var i = 0; i < migrations.Length; i++) - { - var migrationVersion = migrations[i].Version; - if (migrationVersion == nextVersion) - { - nextVersion++; - } - - source.AppendLine(); - source.AppendLine($"{bodyIndent}if (version == {migrationVersion})"); - source.AppendLine($"{bodyIndent}{{"); - source.AppendLine($"{bodyIndent} MigrateFrom(new V{migrationVersion}Content(reader, this));"); - source.AppendLine($"{bodyIndent} {parent}.MarkDirty();"); - source.GenerateAfterDeserialization($"{bodyIndent} ", afterDeserialization); - source.AppendLine($"{bodyIndent} return;"); - source.AppendLine($"{bodyIndent}}}"); - } - - if (nextVersion < version) - { - source.AppendLine(); - source.AppendLine($"{bodyIndent}if (version < _version)"); - source.AppendLine($"{bodyIndent}{{"); - source.AppendLine($"{bodyIndent} Deserialize(reader, version);"); - source.AppendLine($"{bodyIndent} {parent}.MarkDirty();"); - source.GenerateAfterDeserialization($"{bodyIndent} ", afterDeserialization); - source.AppendLine($"{bodyIndent} return;"); - source.AppendLine($"{bodyIndent}}}"); - } - } - - if (serializableFieldSaveFlagMethodsDictionary.Count > 0) - { - source.AppendLine(); - source.AppendLine($"{bodyIndent}var saveFlags = reader.ReadEnum();"); - } - - for (var i = 0; i < properties.Length; i++) - { - var field = fields[i]; - var property = properties[i]; - var rule = SerializableMigrationRulesEngine.Rules[property.Rule]; - - if (serializableFieldSaveFlagMethodsDictionary.TryGetValue( - property.Order, - out var serializableFieldSaveFlagMethods - )) - { - source.AppendLine(); - // Special case - if (property.Type == "bool") - { - source.AppendLine($"{bodyIndent}{field.Name} = (saveFlags & SaveFlag.{property.Name}) != 0;"); - } - else - { - source.AppendLine($"{bodyIndent}if ((saveFlags & SaveFlag.{property.Name}) != 0)\n{bodyIndent}{{"); - rule.GenerateDeserializationMethod( - source, - innerIndent, - field, - parentFieldOrProperty?.Name ?? "this" - ); - (rule as IPostDeserializeMethod)?.PostDeserializeMethod( - source, - innerIndent, - field, - compilation, - classSymbol - ); - - if (serializableFieldSaveFlagMethods.GetFieldDefaultValue != null) - { - source.AppendLine($"{bodyIndent}}}\n{bodyIndent}else\n{bodyIndent}{{"); - source.AppendLine( - $"{bodyIndent} {field.Name} = {serializableFieldSaveFlagMethods.GetFieldDefaultValue.Name}();" - ); - } - - source.AppendLine($"{bodyIndent}}}"); - } - } - else - { - source.AppendLine(); - rule.GenerateDeserializationMethod( - source, - bodyIndent, - field, - parentFieldOrProperty?.Name ?? "this" - ); - (rule as IPostDeserializeMethod)?.PostDeserializeMethod( - source, - bodyIndent, - field, - compilation, - classSymbol - ); - } - } - - source.GenerateAfterDeserialization($"{bodyIndent}", afterDeserialization); - source.GenerateMethodEnd(indent); - } - - private static void GenerateAfterDeserialization( - this StringBuilder source, string indent, IList<(IMethodSymbol, AttributeData?)> afterDeserialization - ) - { - foreach (var (method, attr) in afterDeserialization) - { - if ((bool)attr.ConstructorArguments[0].Value!) - { - source.AppendLine($"{indent}{method.Name}();"); - } - else - { - source.AppendLine($"{indent}Timer.DelayCall({method.Name});"); - } - } - } - } -} diff --git a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.Property.cs b/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.Property.cs deleted file mode 100644 index d2457bb90..000000000 --- a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.Property.cs +++ /dev/null @@ -1,82 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SerializableEntityGeneration.Property.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System.Linq; -using System.Text; -using Microsoft.CodeAnalysis; - -namespace SerializationGenerator -{ - public static partial class SerializableEntityGeneration - { - public static void GenerateSerializableProperty( - this StringBuilder source, - Compilation compilation, - string indent, - IFieldSymbol fieldSymbol, - Accessibility getter, - Accessibility? setter, - bool isVirtual, - ISymbol? parentFieldOrProperty - ) - { - var fieldName = fieldSymbol.Name; - - var invalidatePropertiesAttribute = fieldSymbol - .GetAttributes() - .OfType() - .FirstOrDefault( - attr => attr.AttributeClass?.Equals( - compilation.GetTypeByMetadataName(SymbolMetadata.INVALIDATEPROPERTIES_ATTRIBUTE), - SymbolEqualityComparer.Default - ) ?? false - ); - - var propertyIndent = $"{indent} "; - var innerIndent = $"{propertyIndent} "; - - var propertyAccessor = setter > getter ? setter : getter; - var getterAccessor = getter == propertyAccessor ? Accessibility.NotApplicable : getter; - - source.GeneratePropertyStart(indent, propertyAccessor.Value, isVirtual, fieldSymbol); - - // Getter - source.GeneratePropertyGetterReturnsField(propertyIndent, fieldSymbol, getterAccessor); - - if (setter != null && setter != Accessibility.NotApplicable) - { - var setterAccessor = setter == propertyAccessor ? Accessibility.NotApplicable : setter; - - var parentSymbol = parentFieldOrProperty?.Name ?? "this"; - - // Setter - source.GeneratePropertySetterStart(propertyIndent, false, setterAccessor.Value); - source.AppendLine($"{innerIndent}if (value != {fieldName})"); - source.AppendLine($"{innerIndent}{{"); - source.AppendLine($"{innerIndent} {fieldName} = value;"); - source.AppendLine($"{innerIndent} {parentSymbol}.MarkDirty();"); - - if (invalidatePropertiesAttribute != null) - { - source.AppendLine($"{innerIndent} InvalidateProperties();"); - } - source.AppendLine($"{innerIndent}}}"); - source.GeneratePropertyGetSetEnd(propertyIndent, false); - } - - source.GeneratePropertyEnd(indent); - } - } -} diff --git a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.SerialCtor.cs b/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.SerialCtor.cs deleted file mode 100644 index 7b7ebcb7f..000000000 --- a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.SerialCtor.cs +++ /dev/null @@ -1,52 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SerializableEntityGeneration.SerialCtor.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System.Collections.Immutable; -using System.Text; -using Microsoft.CodeAnalysis; - -namespace SerializationGenerator -{ - public static partial class SerializableEntityGeneration - { - private static readonly ImmutableArray _baseParameters = new[] { "serial" }.ToImmutableArray(); - public static void GenerateSerialCtor( - this StringBuilder source, - Compilation compilation, - string className, - string indent, - bool isOverride - ) - { - var serialType = (ITypeSymbol)compilation.GetTypeByMetadataName("Server.Serial"); - - source.GenerateConstructorStart( - indent, - className, - Accessibility.Public, - new []{ (serialType, "serial") }.ToImmutableArray(), - isOverride ? _baseParameters : ImmutableArray.Empty - ); - - if (!isOverride) - { - source.AppendLine($"{indent} Serial = serial;"); - source.AppendLine($"{indent} SetTypeRef(typeof({className}));"); - } - - source.GenerateMethodEnd(indent); - } - } -} diff --git a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.SerializeMethod.cs b/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.SerializeMethod.cs deleted file mode 100644 index 6aff93f5e..000000000 --- a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.SerializeMethod.cs +++ /dev/null @@ -1,112 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SerializableEntityGeneration.SerializeMethod.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Text; -using Microsoft.CodeAnalysis; -using SerializableMigration; - -namespace SerializationGenerator -{ - public static partial class SerializableEntityGeneration - { - public static void GenerateSerializeMethod( - this StringBuilder source, - Compilation compilation, - string indent, - bool isOverride, - bool encodedVersion, - ImmutableArray fields, - ImmutableArray properties, - SortedDictionary serializableFieldSaveFlagMethodsDictionary - ) - { - var genericWriterInterface = compilation.GetTypeByMetadataName(SymbolMetadata.GENERIC_WRITER_INTERFACE); - - source.GenerateMethodStart( - indent, - "Serialize", - Accessibility.Public, - isOverride, - "void", - ImmutableArray.Create<(ITypeSymbol, string)>((genericWriterInterface, "writer")) - ); - - var bodyIndent = $"{indent} "; - var innerIndent = $"{bodyIndent} "; - - if (isOverride) - { - source.AppendLine($"{bodyIndent}base.Serialize(writer);"); - source.AppendLine(); - } - - // Version - source.AppendLine($"{bodyIndent}writer.{(encodedVersion ? "WriteEncodedInt" : "Write")}(_version);"); - - // Let's collect the flags - if (serializableFieldSaveFlagMethodsDictionary.Count > 0) - { - source.AppendLine($"\n{bodyIndent}var saveFlags = SaveFlag.None;"); - - foreach (var (order, saveFlagMethods) in serializableFieldSaveFlagMethodsDictionary) - { - source.AppendLine($"{bodyIndent}if ({saveFlagMethods.DetermineFieldShouldSerialize!.Name}())\n{bodyIndent}{{"); - - var propertyName = properties[order].Name; - source.AppendLine($"{innerIndent}saveFlags |= SaveFlag.{propertyName};"); - - source.AppendLine($"{bodyIndent}}}"); - } - - source.AppendLine($"{bodyIndent}writer.WriteEnum(saveFlags);"); - } - - for (var i = 0; i < properties.Length; i++) - { - var field = fields[i]; - var property = properties[i]; - if (serializableFieldSaveFlagMethodsDictionary.ContainsKey(property.Order)) - { - // Special case - if (property.Type != "bool") - { - source.AppendLine($"\n{bodyIndent}if ((saveFlags & SaveFlag.{property.Name}) != 0)\n{bodyIndent}{{"); - SerializableMigrationRulesEngine.Rules[property.Rule] - .GenerateSerializationMethod( - source, - innerIndent, - field - ); - source.AppendLine($"{bodyIndent}}}"); - } - } - else - { - source.AppendLine(); - SerializableMigrationRulesEngine.Rules[property.Rule] - .GenerateSerializationMethod( - source, - bodyIndent, - field - ); - } - } - - source.GenerateMethodEnd(indent); - } - } -} diff --git a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableFieldSaveFlagMethods.cs b/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableFieldSaveFlagMethods.cs deleted file mode 100644 index 55a087914..000000000 --- a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableFieldSaveFlagMethods.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Microsoft.CodeAnalysis; - -namespace SerializationGenerator -{ - public record SerializableFieldSaveFlagMethods - { - public IMethodSymbol? DetermineFieldShouldSerialize { get; init; } - - public IMethodSymbol? GetFieldDefaultValue { get; init; } - } -} diff --git a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializationEntityGeneration.ContentStruct.cs b/Projects/SerializationGenerator/SerializableEntityGeneration/SerializationEntityGeneration.ContentStruct.cs deleted file mode 100644 index 56544ed60..000000000 --- a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializationEntityGeneration.ContentStruct.cs +++ /dev/null @@ -1,127 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SerializationEntityGeneration.ContentStruct.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System.Collections.Immutable; -using System.Linq; -using System.Text; -using Microsoft.CodeAnalysis; -using SerializableMigration; - -namespace SerializationGenerator -{ - public static partial class SerializableEntityGeneration - { - public static void GenerateMigrationContentStruct( - this StringBuilder source, - Compilation compilation, - string indent, - SerializableMetadata migration, - INamedTypeSymbol classSymbol - ) - { - source.AppendLine($"{indent}ref struct V{migration.Version}Content"); - source.AppendLine($"{indent}{{"); - var properties = migration.Properties ?? ImmutableArray.Empty; - - foreach (var serializableProperty in properties) - { - SerializableMigrationRulesEngine.Rules[serializableProperty.Rule].GenerateMigrationProperty( - source, compilation, $"{indent} ", serializableProperty - ); - } - - var innerIndent = $"{indent} "; - - var usesSaveFlags = properties.Any(p => p.UsesSaveFlag == true); - - if (usesSaveFlags) - { - source.AppendLine(); - source.GenerateEnumStart( - $"V{migration.Version}SaveFlag", - $"{indent} ", - true, - Accessibility.Private - ); - - source.GenerateEnumValue(innerIndent, true, "None", -1); - int index = 0; - foreach (var property in properties) - { - if (property.UsesSaveFlag == true) - { - source.GenerateEnumValue(innerIndent, true, property.Name, index++); - } - } - - source.GenerateEnumEnd($"{indent} "); - } - - source.AppendLine($"{indent} internal V{migration.Version}Content(IGenericReader reader, {classSymbol.ToDisplayString()} entity)"); - source.AppendLine($"{indent} {{"); - - if (usesSaveFlags) - { - source.AppendLine($"{innerIndent}var saveFlags = reader.ReadEnum();"); - } - - if (properties.Length > 0) - { - foreach (var property in properties) - { - if (property.UsesSaveFlag == true) - { - source.AppendLine(); - // Special case - if (property.Type == "bool") - { - source.AppendLine($"{innerIndent}{property.Name} = (saveFlags & V{migration.Version}SaveFlag.{property.Name}) != 0;"); - } - else - { - source.AppendLine($"{innerIndent}if ((saveFlags & V{migration.Version}SaveFlag.{property.Name}) != 0)\n{innerIndent}{{"); - - SerializableMigrationRulesEngine.Rules[property.Rule].GenerateDeserializationMethod( - source, - $"{innerIndent} ", - property, - "entity", - true - ); - - source.AppendLine($"{innerIndent}}}\n{innerIndent}else\n{innerIndent}{{"); - source.AppendLine($"{innerIndent} {property.Name} = default;"); - source.AppendLine($"{innerIndent}}}"); - } - } - else - { - SerializableMigrationRulesEngine.Rules[property.Rule].GenerateDeserializationMethod( - source, - innerIndent, - property, - "entity", - true - ); - } - } - } - - source.AppendLine($"{indent} }}"); - - source.AppendLine($"{indent}}}"); - } - } -} diff --git a/Projects/SerializationGenerator/SerializableMigration/IPostDeserializeMethod.cs b/Projects/SerializationGenerator/SerializableMigration/IPostDeserializeMethod.cs deleted file mode 100644 index 0a48c0117..000000000 --- a/Projects/SerializationGenerator/SerializableMigration/IPostDeserializeMethod.cs +++ /dev/null @@ -1,31 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: IPostDeserializeMethod.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System.Text; -using Microsoft.CodeAnalysis; - -namespace SerializableMigration -{ - public interface IPostDeserializeMethod - { - public void PostDeserializeMethod( - StringBuilder source, - string indent, - SerializableProperty property, - Compilation compilation, - INamedTypeSymbol classSymbol - ); - } -} diff --git a/Projects/SerializationGenerator/SerializableMigration/ISerializableMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/ISerializableMigrationRule.cs deleted file mode 100644 index a64453e33..000000000 --- a/Projects/SerializationGenerator/SerializableMigration/ISerializableMigrationRule.cs +++ /dev/null @@ -1,57 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SerializableMigrationRule.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System.Collections.Immutable; -using System.Text; -using Microsoft.CodeAnalysis; - -namespace SerializableMigration -{ - public interface ISerializableMigrationRule - { - string RuleName { get; } - - void GenerateMigrationProperty( - StringBuilder source, - Compilation compilation, - string indent, - SerializableProperty serializableProperty - ); - - bool GenerateRuleState( - Compilation compilation, - ISymbol symbol, - ImmutableArray attributes, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes, - ISymbol? parentSymbol, - out string[] ruleArguments - ); - - void GenerateDeserializationMethod( - StringBuilder source, - string indent, - SerializableProperty property, - string? parentReference, - bool isMigration = false - ); - - void GenerateSerializationMethod( - StringBuilder source, - string indent, - SerializableProperty property - ); - } -} diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/ArrayMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/ArrayMigrationRule.cs deleted file mode 100644 index 99a1e911e..000000000 --- a/Projects/SerializationGenerator/SerializableMigration/Rules/ArrayMigrationRule.cs +++ /dev/null @@ -1,135 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: ArrayMigrationRule.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System; -using System.Collections.Immutable; -using System.Text; -using Microsoft.CodeAnalysis; - -namespace SerializableMigration; - -public class ArrayMigrationRule : MigrationRule -{ - public override string RuleName => nameof(ArrayMigrationRule); - - public override bool GenerateRuleState( - Compilation compilation, - ISymbol symbol, - ImmutableArray attributes, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes, - ISymbol? parentSymbol, - out string[] ruleArguments - ) - { - if (symbol is not IArrayTypeSymbol arrayTypeSymbol) - { - ruleArguments = null; - return false; - } - - var serializableArrayType = SerializableMigrationRulesEngine.GenerateSerializableProperty( - compilation, - "ArrayEntry", - arrayTypeSymbol.ElementType, - 0, - attributes, - serializableTypes, - embeddedSerializableTypes, - parentSymbol, - null - ); - - var length = serializableArrayType.RuleArguments?.Length?? 0; - ruleArguments = new string[length + 2]; - ruleArguments[0] = arrayTypeSymbol.ElementType.ToDisplayString(); - ruleArguments[1] = serializableArrayType.Rule; - if (length > 0) - { - Array.Copy(serializableArrayType.RuleArguments!, 0, ruleArguments, 2, length); - } - - return true; - } - - public override void GenerateDeserializationMethod( - StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false - ) - { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } - var ruleArguments = property.RuleArguments; - var arrayElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments![1]]; - var arrayElementRuleArguments = new string[ruleArguments.Length - 2]; - Array.Copy(ruleArguments, 2, arrayElementRuleArguments, 0, ruleArguments.Length - 2); - - var propertyIndex = $"{property.Name}Index"; - source.AppendLine($"{indent}{property.Name} = new {ruleArguments[0]}[reader.ReadEncodedInt()];"); - source.AppendLine($"{indent}for (var {propertyIndex} = 0; {propertyIndex} < {property.Name}.Length; {propertyIndex}++)"); - source.AppendLine($"{indent}{{"); - - var serializableArrayElement = new SerializableProperty - { - Name = $"{property.Name}[{propertyIndex}]", - Type = ruleArguments[0], - Rule = arrayElementRule.RuleName, - RuleArguments = arrayElementRuleArguments - }; - - arrayElementRule.GenerateDeserializationMethod(source, $"{indent} ", serializableArrayElement, parentReference); - - source.AppendLine($"{indent}}}"); - } - - public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property) - { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } - - var ruleArguments = property.RuleArguments; - var arrayElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments![1]]; - var arrayElementRuleArguments = new string[ruleArguments.Length - 2]; - Array.Copy(ruleArguments, 2, arrayElementRuleArguments, 0, ruleArguments.Length - 2); - - var propertyName = property.Name; - var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}"; - var propertyIndex = $"{propertyVarPrefix}Index"; - var propertyLength = $"{propertyVarPrefix}Length"; - source.AppendLine($"{indent}var {propertyLength} = {property.Name}?.Length ?? 0;"); - source.AppendLine($"{indent}writer.WriteEncodedInt({propertyLength});"); - source.AppendLine($"{indent}for (var {propertyIndex} = 0; {propertyIndex} < {propertyLength}; {propertyIndex}++)"); - source.AppendLine($"{indent}{{"); - - var serializableArrayElement = new SerializableProperty - { - Name = $"{property.Name}![{propertyIndex}]", - Type = ruleArguments[0], - Rule = arrayElementRule.RuleName, - RuleArguments = arrayElementRuleArguments - }; - - arrayElementRule.GenerateSerializationMethod(source, $"{indent} ", serializableArrayElement); - - source.AppendLine($"{indent}}}"); - } -} diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/DictionaryMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/DictionaryMigrationRule.cs deleted file mode 100644 index caf0d1dc8..000000000 --- a/Projects/SerializationGenerator/SerializableMigration/Rules/DictionaryMigrationRule.cs +++ /dev/null @@ -1,250 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: DictionaryMigrationRule.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System; -using System.Collections.Immutable; -using System.Linq; -using System.Text; -using Microsoft.CodeAnalysis; -using SerializationGenerator; - -namespace SerializableMigration; - -public class DictionaryMigrationRule : MigrationRule -{ - public override string RuleName => nameof(DictionaryMigrationRule); - - public override bool GenerateRuleState( - Compilation compilation, - ISymbol symbol, - ImmutableArray attributes, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes, - ISymbol? parentSymbol, - out string[] ruleArguments - ) - { - if (symbol is not INamedTypeSymbol namedTypeSymbol || !symbol.IsDictionary(compilation)) - { - ruleArguments = null; - return false; - } - - var keySymbolType = namedTypeSymbol.TypeArguments[0]; - - var serializableKeyProperty = SerializableMigrationRulesEngine.GenerateSerializableProperty( - compilation, - "KeyEntry", - keySymbolType, - 0, - attributes, - serializableTypes, - embeddedSerializableTypes, - parentSymbol, - null - ); - - var valueSymbolType = namedTypeSymbol.TypeArguments[1]; - - var serializableValueProperty = SerializableMigrationRulesEngine.GenerateSerializableProperty( - compilation, - "ValueEntry", - valueSymbolType, - 0, - attributes, - serializableTypes, - embeddedSerializableTypes, - parentSymbol, - null - ); - - var extraOptions = ""; - if (attributes.Any(a => a.IsTidy(compilation))) - { - extraOptions += "@Tidy"; - } - - var keyArgumentsLength = serializableKeyProperty.RuleArguments?.Length ?? 0; - var valueArgumentsLength = serializableValueProperty.RuleArguments?.Length ?? 0; - var index = 0; - - ruleArguments = new string[7 + keyArgumentsLength + valueArgumentsLength]; - ruleArguments[index++] = extraOptions; - ruleArguments[index++] = keySymbolType.ToDisplayString(); - ruleArguments[index++] = serializableKeyProperty.Rule; - ruleArguments[index++] = keyArgumentsLength.ToString(); - - if (keyArgumentsLength > 0) - { - Array.Copy(serializableKeyProperty.RuleArguments!, 0, ruleArguments, index, keyArgumentsLength); - index += keyArgumentsLength; - } - - ruleArguments[index++] = valueSymbolType.ToDisplayString(); - ruleArguments[index++] = serializableValueProperty.Rule; - ruleArguments[index++] = valueArgumentsLength.ToString(); - - if (valueArgumentsLength > 0) - { - Array.Copy(serializableValueProperty.RuleArguments!, 0, ruleArguments, index, valueArgumentsLength); - } - - return true; - } - - public override void GenerateDeserializationMethod( - StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false - ) - { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } - - var ruleArguments = property.RuleArguments; - var index = 1; - var keyType = ruleArguments![index++]; - - var keyElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]]; - var keyRuleArguments = new string[int.Parse(ruleArguments[index++])]; - - if (keyRuleArguments.Length > 0) - { - Array.Copy(ruleArguments, index, keyRuleArguments, 0, keyRuleArguments.Length); - index += keyRuleArguments.Length; - } - - var valueType = ruleArguments[index++]; - var valueElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]]; - var valueRuleArguments = new string[int.Parse(ruleArguments[index++])]; - - if (valueRuleArguments.Length > 0) - { - Array.Copy(ruleArguments, index, valueRuleArguments, 0, valueRuleArguments.Length); - } - - var propertyName = property.Name; - var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}"; - var propertyIndex = $"{propertyVarPrefix}Index"; - var propertyKeyEntry = $"{propertyVarPrefix}Key"; - var propertyValueEntry = $"{propertyVarPrefix}Value"; - var propertyCount = $"{propertyVarPrefix}Count"; - - source.AppendLine($"{indent}{ruleArguments[1]} {propertyKeyEntry};"); - source.AppendLine($"{indent}{valueType} {propertyValueEntry};"); - source.AppendLine($"{indent}var {propertyCount} = reader.ReadEncodedInt();"); - source.AppendLine($"{indent}{propertyName} = new System.Collections.Generic.Dictionary<{keyType}, {valueType}>({propertyCount});"); - source.AppendLine($"{indent}for (var {propertyIndex} = 0; {propertyIndex} < {propertyCount}; {propertyIndex}++)"); - source.AppendLine($"{indent}{{"); - - var serializableKeyElement = new SerializableProperty - { - Name = propertyKeyEntry, - Type = keyType, - Rule = keyElementRule.RuleName, - RuleArguments = keyRuleArguments - }; - - keyElementRule.GenerateDeserializationMethod(source, $"{indent} ", serializableKeyElement, parentReference); - - var serializableValueElement = new SerializableProperty - { - Name = propertyValueEntry, - Type = valueType, - Rule = valueElementRule.RuleName, - RuleArguments = valueRuleArguments - }; - - valueElementRule.GenerateDeserializationMethod(source, $"{indent} ", serializableValueElement, parentReference); - source.AppendLine($"{indent} {propertyName}.Add({propertyKeyEntry}, {propertyValueEntry});"); - - source.AppendLine($"{indent}}}"); - } - - public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property) - { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } - - var ruleArguments = property.RuleArguments; - var index = 0; - var shouldTidy = ruleArguments![index++].Contains("@Tidy"); - var keyType = ruleArguments![index++]; - - var keyElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments![index++]]; - var keyRuleArguments = new string[int.Parse(ruleArguments[index++])]; - - if (keyRuleArguments.Length > 0) - { - Array.Copy(ruleArguments, index, keyRuleArguments, 0, keyRuleArguments.Length); - index += keyRuleArguments.Length; - } - - var valueType = ruleArguments[index++]; - var valueElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]]; - var valueRuleArguments = new string[int.Parse(ruleArguments[index++])]; - - if (valueRuleArguments.Length > 0) - { - Array.Copy(ruleArguments, index, valueRuleArguments, 0, valueRuleArguments.Length); - } - - var propertyName = property.Name; - var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}"; - var propertyKeyEntry = $"{propertyVarPrefix}Key"; - var propertyValueEntry = $"{propertyVarPrefix}Value"; - var propertyCount = $"{propertyVarPrefix}Count"; - - if (shouldTidy) - { - source.AppendLine($"{indent}{property.Name}?.Tidy();"); - } - source.AppendLine($"{indent}var {propertyCount} = {property.Name}?.Count ?? 0;"); - source.AppendLine($"{indent}writer.WriteEncodedInt({propertyCount});"); - source.AppendLine($"{indent}if ({propertyCount} > 0)"); - source.AppendLine($"{indent}{{"); - source.AppendLine($"{indent} foreach (var ({propertyKeyEntry}, {propertyValueEntry}) in {property.Name}!)"); - source.AppendLine($"{indent} {{"); - - var serializableKeyElement = new SerializableProperty - { - Name = propertyKeyEntry, - Type = keyType, - Rule = keyElementRule.RuleName, - RuleArguments = keyRuleArguments - }; - - keyElementRule.GenerateSerializationMethod(source, $"{indent} ", serializableKeyElement); - - var serializableValueElement = new SerializableProperty - { - Name = propertyValueEntry, - Type = valueType, - Rule = valueElementRule.RuleName, - RuleArguments = valueRuleArguments - }; - - valueElementRule.GenerateSerializationMethod(source, $"{indent} ", serializableValueElement); - - source.AppendLine($"{indent} }}"); - source.AppendLine($"{indent}}}"); - } -} diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/EnumMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/EnumMigrationRule.cs deleted file mode 100644 index 5e8d7fd45..000000000 --- a/Projects/SerializationGenerator/SerializableMigration/Rules/EnumMigrationRule.cs +++ /dev/null @@ -1,73 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: EnumMigrationRule.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System; -using System.Collections.Immutable; -using System.Text; -using Microsoft.CodeAnalysis; -using SerializationGenerator; - -namespace SerializableMigration; - -public class EnumMigrationRule : MigrationRule -{ - public override string RuleName => nameof(EnumMigrationRule); - - public override bool GenerateRuleState( - Compilation compilation, - ISymbol symbol, - ImmutableArray attributes, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes, - ISymbol? parentSymbol, - out string[] ruleArguments - ) - { - if (symbol is not ITypeSymbol typeSymbol || !typeSymbol.IsEnum()) - { - ruleArguments = null; - return false; - } - - ruleArguments = Array.Empty(); - return true; - } - - public override void GenerateDeserializationMethod( - StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false - ) - { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } - - source.AppendLine($"{indent}{property.Name} = reader.ReadEnum<{property.Type}>();"); - } - - public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property) - { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } - - source.AppendLine($"{indent}writer.WriteEnum<{property.Type}>({property.Name});"); - } -} diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/HashSetMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/HashSetMigrationRule.cs deleted file mode 100644 index 20fe03d08..000000000 --- a/Projects/SerializationGenerator/SerializableMigration/Rules/HashSetMigrationRule.cs +++ /dev/null @@ -1,171 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: HashSetMigrationRule.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System; -using System.Collections.Immutable; -using System.Linq; -using System.Text; -using Microsoft.CodeAnalysis; -using SerializationGenerator; - -namespace SerializableMigration; - -public class HashSetMigrationRule : MigrationRule -{ - public override string RuleName => nameof(HashSetMigrationRule); - - public override bool GenerateRuleState( - Compilation compilation, - ISymbol symbol, - ImmutableArray attributes, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes, - ISymbol? parentSymbol, - out string[] ruleArguments - ) - { - if (symbol is not INamedTypeSymbol namedTypeSymbol || !symbol.IsHashSet(compilation)) - { - ruleArguments = null; - return false; - } - - var setTypeSymbol = namedTypeSymbol.TypeArguments[0]; - - var serializableSetType = SerializableMigrationRulesEngine.GenerateSerializableProperty( - compilation, - "SetEntry", - setTypeSymbol, - 0, - attributes, - serializableTypes, - embeddedSerializableTypes, - parentSymbol, - null - ); - - var extraOptions = ""; - if (attributes.Any(a => a.IsTidy(compilation))) - { - extraOptions += "@Tidy"; - } - - var length = serializableSetType.RuleArguments?.Length ?? 0; - ruleArguments = new string[length + 3]; - ruleArguments[0] = extraOptions; - ruleArguments[1] = setTypeSymbol.ToDisplayString(); - ruleArguments[2] = serializableSetType.Rule; - - if (length > 0) - { - Array.Copy(serializableSetType.RuleArguments, 0, ruleArguments, 3, length); - } - - return true; - } - - public override void GenerateDeserializationMethod( - StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false - ) - { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } - - var ruleArguments = property.RuleArguments; - var hasExtraOptions = ruleArguments![0] == "" || ruleArguments[0].StartsWith("@", StringComparison.Ordinal); - var argumentsOffset = hasExtraOptions ? 1 : 0; - - var setElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[1 + argumentsOffset]]; - var setElementRuleArguments = new string[ruleArguments.Length - 2 - argumentsOffset]; - Array.Copy(ruleArguments, 2 + argumentsOffset, setElementRuleArguments, 0, ruleArguments.Length - 2 - argumentsOffset); - - var propertyName = property.Name; - var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}"; - var propertyIndex = $"{propertyVarPrefix}Index"; - var propertyEntry = $"{propertyVarPrefix}Entry"; - var propertyCount = $"{propertyVarPrefix}Count"; - - source.AppendLine($"{indent}{ruleArguments[argumentsOffset]} {propertyEntry};"); - source.AppendLine($"{indent}var {propertyCount} = reader.ReadEncodedInt();"); - source.AppendLine($"{indent}{property.Name} = new System.Collections.Generic.HashSet<{ruleArguments[argumentsOffset]}>({propertyCount});"); - source.AppendLine($"{indent}for (var {propertyIndex} = 0; {propertyIndex} < {propertyCount}; {propertyIndex}++)"); - source.AppendLine($"{indent}{{"); - - var serializableSetElement = new SerializableProperty - { - Name = propertyEntry, - Type = ruleArguments[argumentsOffset], - Rule = setElementRule.RuleName, - RuleArguments = setElementRuleArguments - }; - - setElementRule.GenerateDeserializationMethod(source, $"{indent} ", serializableSetElement, parentReference); - source.AppendLine($"{indent} {property.Name}.Add({propertyEntry});"); - - source.AppendLine($"{indent}}}"); - } - - public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property) - { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } - - var ruleArguments = property.RuleArguments; - var hasExtraOptions = ruleArguments![0] == "" || ruleArguments[0].StartsWith("@", StringComparison.Ordinal); - var shouldTidy = hasExtraOptions && ruleArguments[0].Contains("@Tidy"); - var argumentsOffset = hasExtraOptions ? 1 : 0; - - var setElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[1 + argumentsOffset]]; - var setElementRuleArguments = new string[ruleArguments.Length - 2 - argumentsOffset]; - Array.Copy(ruleArguments, 2 + argumentsOffset, setElementRuleArguments, 0, ruleArguments.Length - 2 - argumentsOffset); - - var propertyName = property.Name; - var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}"; - var propertyEntry = $"{propertyVarPrefix}Entry"; - var propertyCount = $"{propertyVarPrefix}Count"; - - if (shouldTidy) - { - source.AppendLine($"{indent}{property.Name}?.Tidy();"); - } - source.AppendLine($"{indent}var {propertyCount} = {property.Name}?.Count ?? 0;"); - source.AppendLine($"{indent}writer.WriteEncodedInt({propertyCount});"); - source.AppendLine($"{indent}if ({propertyCount} > 0)"); - source.AppendLine($"{indent}{{"); - source.AppendLine($"{indent} foreach (var {propertyEntry} in {property.Name}!)"); - source.AppendLine($"{indent} {{"); - - var serializableSetElement = new SerializableProperty - { - Name = propertyEntry, - Type = ruleArguments[argumentsOffset], - Rule = setElementRule.RuleName, - RuleArguments = setElementRuleArguments - }; - - setElementRule.GenerateSerializationMethod(source, $"{indent} ", serializableSetElement); - - source.AppendLine($"{indent} }}"); - source.AppendLine($"{indent}}}"); - } -} diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/KeyValuePairMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/KeyValuePairMigrationRule.cs deleted file mode 100644 index 5b7c4fbef..000000000 --- a/Projects/SerializationGenerator/SerializableMigration/Rules/KeyValuePairMigrationRule.cs +++ /dev/null @@ -1,225 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: KeyValuePairMigrationRule.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System; -using System.Collections.Immutable; -using System.Text; -using Microsoft.CodeAnalysis; -using SerializationGenerator; - -namespace SerializableMigration; - -public class KeyValuePairMigrationRule : MigrationRule -{ - public override string RuleName => nameof(KeyValuePairMigrationRule); - - public override bool GenerateRuleState( - Compilation compilation, - ISymbol symbol, - ImmutableArray attributes, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes, - ISymbol? parentSymbol, - out string[] ruleArguments - ) - { - if (symbol is not INamedTypeSymbol namedTypeSymbol || !symbol.IsKeyValuePair(compilation)) - { - ruleArguments = null; - return false; - } - - var keySymbolType = namedTypeSymbol.TypeArguments[0]; - - var keySerializedProperty = SerializableMigrationRulesEngine.GenerateSerializableProperty( - compilation, - "key", - keySymbolType, - 0, - attributes, - serializableTypes, - embeddedSerializableTypes, - parentSymbol, - null - ); - - var valueSymbolType = namedTypeSymbol.TypeArguments[1]; - - var valueSerializedProperty = SerializableMigrationRulesEngine.GenerateSerializableProperty( - compilation, - "value", - valueSymbolType, - 1, - attributes, - serializableTypes, - embeddedSerializableTypes, - parentSymbol, - null - ); - - var keyArgumentsLength = keySerializedProperty.RuleArguments?.Length ?? 0; - var valueArgumentsLength = valueSerializedProperty.RuleArguments?.Length ?? 0; - var index = 0; - - // Key - ruleArguments = new string[6 + keyArgumentsLength + valueArgumentsLength]; - ruleArguments[index++] = ""; // Extra options - ruleArguments[index++] = keySymbolType.ToDisplayString(); - ruleArguments[index++] = keySerializedProperty.Rule; - ruleArguments[index++] = keyArgumentsLength.ToString(); - if (keyArgumentsLength > 0) - { - Array.Copy(keySerializedProperty.RuleArguments!, 0, ruleArguments, index, keyArgumentsLength); - index += keyArgumentsLength; - } - - // Value - ruleArguments[index++] = valueSymbolType.ToDisplayString(); - ruleArguments[index++] = valueSerializedProperty.Rule; - - if (valueArgumentsLength > 0) - { - Array.Copy(valueSerializedProperty.RuleArguments!, 0, ruleArguments, index, valueArgumentsLength); - } - - return true; - } - - public override void GenerateDeserializationMethod( - StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false - ) - { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } - - var ruleArguments = property.RuleArguments; - var index = 1; // skip extra options - var keyType = ruleArguments![index++]; - var keyRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]]; - var keyRuleArguments = new string[int.Parse(ruleArguments[index++])]; - - if (keyRuleArguments.Length > 0) - { - Array.Copy(ruleArguments, index, keyRuleArguments, 0, keyRuleArguments.Length); - index += keyRuleArguments.Length; - } - - var serializableKeyProperty = new SerializableProperty - { - Name = "key", - Type = keyType, - Rule = keyRule.RuleName, - RuleArguments = keyRuleArguments - }; - - keyRule.GenerateDeserializationMethod( - source, - indent, - serializableKeyProperty, - parentReference - ); - - var valueType = ruleArguments[index++]; - var valueRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]]; - var valueRuleArguments = new string[int.Parse(ruleArguments[index++])]; - - if (valueRuleArguments.Length > 0) - { - Array.Copy(ruleArguments, index, valueRuleArguments, 0, valueRuleArguments.Length); - } - - var serializableValueProperty = new SerializableProperty - { - Name = "value", - Type = valueType, - Rule = valueRule.RuleName, - RuleArguments = valueRuleArguments - }; - - valueRule.GenerateDeserializationMethod( - source, - indent, - serializableValueProperty, - parentReference - ); - - source.AppendLine( - $"{indent}{property.Name} = new {SymbolMetadata.KEYVALUEPAIR_STRUCT}<{keyType}, {valueType}>(key, value);" - ); - } - - public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property) - { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } - - var ruleArguments = property.RuleArguments; - var index = 1; // skip extra options - var keyType = ruleArguments![index++]; - var keyRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]]; - var keyRuleArguments = new string[int.Parse(ruleArguments[index++])]; - - if (keyRuleArguments.Length > 0) - { - Array.Copy(ruleArguments, index, keyRuleArguments, 0, keyRuleArguments.Length); - index += keyRuleArguments.Length; - } - - var serializableKeyProperty = new SerializableProperty - { - Name = $"{property.Name}.Key", - Type = keyType, - Rule = keyRule.RuleName, - RuleArguments = keyRuleArguments - }; - - keyRule.GenerateSerializationMethod( - source, - indent, - serializableKeyProperty - ); - - var valueType = ruleArguments[index++]; - var valueRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]]; - var valueRuleArguments = new string[int.Parse(ruleArguments[index++])]; - - if (valueRuleArguments.Length > 0) - { - Array.Copy(ruleArguments, index, valueRuleArguments, 0, valueRuleArguments.Length); - } - - var serializableValueProperty = new SerializableProperty - { - Name = $"{property.Name}.Value", - Type = valueType, - Rule = valueRule.RuleName, - RuleArguments = valueRuleArguments - }; - - valueRule.GenerateSerializationMethod( - source, - indent, - serializableValueProperty - ); - } -} diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/ListMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/ListMigrationRule.cs deleted file mode 100644 index 53d2d2c44..000000000 --- a/Projects/SerializationGenerator/SerializableMigration/Rules/ListMigrationRule.cs +++ /dev/null @@ -1,172 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: ListMigrationRule.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System; -using System.Collections.Immutable; -using System.Linq; -using System.Text; -using Microsoft.CodeAnalysis; -using SerializationGenerator; - -namespace SerializableMigration; - -public class ListMigrationRule : MigrationRule -{ - public override string RuleName => nameof(ListMigrationRule); - - public override bool GenerateRuleState( - Compilation compilation, - ISymbol symbol, - ImmutableArray attributes, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes, - ISymbol? parentSymbol, - out string[] ruleArguments - ) - { - if (symbol is not INamedTypeSymbol namedTypeSymbol || !symbol.IsList(compilation)) - { - ruleArguments = null; - return false; - } - - var listTypeSymbol = namedTypeSymbol.TypeArguments[0]; - - var serializableListType = SerializableMigrationRulesEngine.GenerateSerializableProperty( - compilation, - "ListEntry", - listTypeSymbol, - 0, - attributes, - serializableTypes, - embeddedSerializableTypes, - parentSymbol, - null - ); - - var extraOptions = ""; - if (attributes.Any(a => a.IsTidy(compilation))) - { - extraOptions += "@Tidy"; - } - - var length = serializableListType.RuleArguments?.Length ?? 0; - ruleArguments = new string[length + 3]; - ruleArguments[0] = extraOptions; - ruleArguments[1] = listTypeSymbol.ToDisplayString(); - ruleArguments[2] = serializableListType.Rule; - - if (length > 0) - { - Array.Copy(serializableListType.RuleArguments!, 0, ruleArguments, 3, length); - } - - return true; - } - - public override void GenerateDeserializationMethod( - StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false - ) - { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } - - var ruleArguments = property.RuleArguments; - var hasExtraOptions = ruleArguments![0] == "" || ruleArguments[0].StartsWith("@", StringComparison.Ordinal); - var argumentsOffset = hasExtraOptions ? 1 : 0; - - var listElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[argumentsOffset + 1]]; - - var listElementRuleArguments = new string[ruleArguments.Length - 2 - argumentsOffset]; - Array.Copy(ruleArguments, 2 + argumentsOffset, listElementRuleArguments, 0, ruleArguments.Length - 2 - argumentsOffset); - - var propertyName = property.Name; - var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}"; - var propertyIndex = $"{propertyVarPrefix}Index"; - var propertyEntry = $"{propertyVarPrefix}Entry"; - var propertyCount = $"{propertyVarPrefix}Count"; - - source.AppendLine($"{indent}{ruleArguments[argumentsOffset]} {propertyEntry};"); - source.AppendLine($"{indent}var {propertyCount} = reader.ReadEncodedInt();"); - source.AppendLine($"{indent}{propertyName} = new System.Collections.Generic.List<{ruleArguments[argumentsOffset]}>({propertyCount});"); - source.AppendLine($"{indent}for (var {propertyIndex} = 0; {propertyIndex} < {propertyCount}; {propertyIndex}++)"); - source.AppendLine($"{indent}{{"); - - var serializableListElement = new SerializableProperty - { - Name = propertyEntry, - Type = ruleArguments[argumentsOffset], - Rule = listElementRule.RuleName, - RuleArguments = listElementRuleArguments - }; - - listElementRule.GenerateDeserializationMethod(source, $"{indent} ", serializableListElement, parentReference); - source.AppendLine($"{indent} {propertyName}.Add({propertyEntry});"); - - source.AppendLine($"{indent}}}"); - } - - public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property) - { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } - - var ruleArguments = property.RuleArguments; - var hasExtraOptions = ruleArguments![0] == "" || ruleArguments[0].StartsWith("@", StringComparison.Ordinal); - var shouldTidy = hasExtraOptions && ruleArguments[0].Contains("@Tidy"); - var argumentsOffset = hasExtraOptions ? 1 : 0; - - var listElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[1 + argumentsOffset]]; - var listElementRuleArguments = new string[ruleArguments.Length - 2 - argumentsOffset]; - Array.Copy(ruleArguments, 2 + argumentsOffset, listElementRuleArguments, 0, ruleArguments.Length - 2 - argumentsOffset); - - var propertyName = property.Name; - var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}"; - var propertyEntry = $"{propertyVarPrefix}Entry"; - var propertyCount = $"{propertyVarPrefix}Count"; - - if (shouldTidy) - { - source.AppendLine($"{indent}{property.Name}?.Tidy();"); - } - source.AppendLine($"{indent}var {propertyCount} = {property.Name}?.Count ?? 0;"); - source.AppendLine($"{indent}writer.WriteEncodedInt({propertyCount});"); - source.AppendLine($"{indent}if ({propertyCount} > 0)"); - source.AppendLine($"{indent}{{"); - source.AppendLine($"{indent} foreach (var {propertyEntry} in {property.Name}!)"); - source.AppendLine($"{indent} {{"); - - var serializableListElement = new SerializableProperty - { - Name = propertyEntry, - Type = ruleArguments[argumentsOffset], - Rule = listElementRule.RuleName, - RuleArguments = listElementRuleArguments - }; - - listElementRule.GenerateSerializationMethod(source, $"{indent} ", serializableListElement); - - source.AppendLine($"{indent} }}"); - source.AppendLine($"{indent}}}"); - } -} diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/MigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/MigrationRule.cs deleted file mode 100644 index 848812b54..000000000 --- a/Projects/SerializationGenerator/SerializableMigration/Rules/MigrationRule.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System; -using System.Collections.Immutable; -using System.Text; -using Microsoft.CodeAnalysis; -using SerializationGenerator; - -namespace SerializableMigration; - -public abstract class MigrationRule : ISerializableMigrationRule -{ - public abstract string RuleName { get; } - - public virtual void GenerateMigrationProperty( - StringBuilder source, Compilation compilation, string indent, SerializableProperty serializableProperty - ) - { - var propertyType = serializableProperty.Type; - var type = compilation.GetTypeByMetadataName(propertyType)?.IsValueType == true - || SymbolMetadata.IsPrimitiveFromTypeDisplayString(propertyType) && propertyType != "bool" - ? $"{propertyType}{(serializableProperty.UsesSaveFlag == true ? "?" : "")}" : propertyType; - - source.AppendLine($"{indent}internal readonly {type} {serializableProperty.Name};"); - } - - public abstract bool GenerateRuleState( - Compilation compilation, ISymbol symbol, ImmutableArray attributes, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes, ISymbol? parentSymbol, out string[] ruleArguments - ); - - public abstract void GenerateDeserializationMethod( - StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false - ); - - public abstract void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property); -} diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/PrimitiveTypeMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/PrimitiveTypeMigrationRule.cs deleted file mode 100644 index 70b34ce06..000000000 --- a/Projects/SerializationGenerator/SerializableMigration/Rules/PrimitiveTypeMigrationRule.cs +++ /dev/null @@ -1,149 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: PrimitiveTypeMigrationRule.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System; -using System.Collections.Immutable; -using System.Linq; -using System.Text; -using Microsoft.CodeAnalysis; -using SerializationGenerator; - -namespace SerializableMigration; - -public class PrimitiveTypeMigrationRule : MigrationRule -{ - public override string RuleName => nameof(PrimitiveTypeMigrationRule); - - public override bool GenerateRuleState( - Compilation compilation, - ISymbol symbol, - ImmutableArray attributes, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes, - ISymbol? parentSymbol, - out string[] ruleArguments - ) - { - if (symbol.IsIpAddress(compilation) || symbol.IsTimeSpan(compilation)) - { - ruleArguments = Array.Empty(); - return true; - } - - if ( - symbol is not ITypeSymbol { - SpecialType: not (not - SpecialType.System_Boolean and not - SpecialType.System_SByte and not - SpecialType.System_Int16 and not - SpecialType.System_Int32 and not - SpecialType.System_Int64 and not - SpecialType.System_Byte and not - SpecialType.System_UInt16 and not - SpecialType.System_UInt32 and not - SpecialType.System_UInt64 and not - SpecialType.System_Single and not - SpecialType.System_Double and not - SpecialType.System_String and not - SpecialType.System_Decimal and not - SpecialType.System_DateTime) - } typeSymbol - ) - { - ruleArguments = null; - return false; - } - - ruleArguments = typeSymbol.SpecialType switch - { - SpecialType.System_Int32 when attributes.Any(a => a.IsEncodedInt(compilation)) => - new[] { "EncodedInt" }, - SpecialType.System_DateTime when attributes.Any(a => a.IsDeltaDateTime(compilation)) => - new[] { "DeltaTime" }, - SpecialType.System_String when attributes.Any(a => a.IsInternString(compilation)) => - new[] { "InternString" }, - _ => new[] { "" } - }; - - return true; - } - - public override void GenerateDeserializationMethod( - StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false - ) - { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } - - var propertyName = property.Name; - var argument = property.RuleArguments?.Length >= 1 ? property.RuleArguments[0] : null; - - const string ipAddress = SymbolMetadata.IPADDRESS_CLASS; - const string timeSpan = SymbolMetadata.TIMESPAN_STRUCT; - const string date = "System.DateTime"; - - var readMethod = property.Type switch - { - "bool" => "ReadBool", - "sbyte" => "ReadSByte", - "short" => "ReadShort", - "int" when argument == "EncodedInt" => "ReadEncodedInt", - "int" => "ReadInt", - "long" => "ReadLong", - "byte" => "ReadByte", - "ushort" => "ReadUShort", - "uint" => "ReadUInt", - "ulong" => "ReadULong", - "float" => "ReadFloat", - "double" => "ReadDouble", - "string" => "ReadString", - "decimal" => "ReadDecimal", - date when argument == "DeltaTime" => "ReadDeltaTime", - date => "ReadDateTime", - ipAddress => "ReadIPAddress", - timeSpan => "ReadTimeSpan" - }; - - var readArgument = readMethod == "ReadString" && argument == "InternString" ? "true" : ""; - - source.AppendLine($"{indent}{propertyName} = reader.{readMethod}({readArgument});"); - } - - public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property) - { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } - - var propertyName = property.Name; - var argument = property.RuleArguments?.Length >= 1 ? property.RuleArguments[0] : null; - - var writeMethod = property.Type switch - { - "System.DateTime" when argument == "DeltaTime" => "WriteDeltaTime", - "int" when argument == "EncodedInt" => "WriteEncodedInt", - _ => "Write" - }; - - source.AppendLine($"{indent}writer.{writeMethod}({propertyName});"); - } -} diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/PrimitiveUOTypeMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/PrimitiveUOTypeMigrationRule.cs deleted file mode 100644 index ec2ea15d3..000000000 --- a/Projects/SerializationGenerator/SerializableMigration/Rules/PrimitiveUOTypeMigrationRule.cs +++ /dev/null @@ -1,80 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: PrimitiveUOTypeMigrationRule.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System; -using System.Collections.Immutable; -using System.Text; -using Microsoft.CodeAnalysis; -using SerializationGenerator; - -namespace SerializableMigration; - -public class PrimitiveUOTypeMigrationRule : MigrationRule -{ - public override string RuleName => nameof(PrimitiveUOTypeMigrationRule); - - public override bool GenerateRuleState( - Compilation compilation, - ISymbol symbol, - ImmutableArray attributes, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes, - ISymbol? parentSymbol, - out string[] ruleArguments - ) - { - ruleArguments = symbol switch - { - _ when symbol.IsPoint2D(compilation) => new[] { "Point2D" }, - _ when symbol.IsPoint3D(compilation) => new[] { "Point3D" }, - _ when symbol.IsRectangle2D(compilation) => new[] { "Rect2D" }, - _ when symbol.IsRectangle3D(compilation) => new[] { "Rect3D" }, - _ when symbol.IsRace(compilation) => new[] { "Race" }, - _ when symbol.IsMap(compilation) => new[] { "Map" }, - _ when symbol.IsBitArray(compilation) => new[] { "BitArray" }, - _ => null - }; - - return ruleArguments != null; - } - - public override void GenerateDeserializationMethod( - StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false - ) - { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } - - var propertyName = property.Name; - source.AppendLine($"{indent}{propertyName} = reader.Read{property.RuleArguments?[0] ?? ""}();"); - } - - public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property) - { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } - - var propertyName = property.Name; - source.AppendLine($"{indent}writer.Write({propertyName});"); - } -} diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/RawSerializableMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/RawSerializableMigrationRule.cs deleted file mode 100644 index 8f0944f1d..000000000 --- a/Projects/SerializationGenerator/SerializableMigration/Rules/RawSerializableMigrationRule.cs +++ /dev/null @@ -1,82 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: RawSerializableMigrationRule.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System; -using System.Collections.Immutable; -using System.Text; -using Microsoft.CodeAnalysis; -using SerializationGenerator; - -namespace SerializableMigration; - -public class RawSerializableMigrationRule : MigrationRule -{ - public override string RuleName => nameof(RawSerializableMigrationRule); - - public override bool GenerateRuleState( - Compilation compilation, - ISymbol symbol, - ImmutableArray attributes, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes, - ISymbol? parentSymbol, - out string[] ruleArguments - ) - { - if (symbol is not ITypeSymbol typeSymbol) - { - ruleArguments = null; - return false; - } - - if (!typeSymbol.HasRawSerializableInterface(compilation, embeddedSerializableTypes)) - { - ruleArguments = null; - return false; - } - - ruleArguments = new[] { "" }; - return true; - } - - public override void GenerateDeserializationMethod( - StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false - ) - { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } - - var propertyName = property.Name; - source.AppendLine($"{indent}{propertyName} = new {property.Type}({parentReference ?? "this"});"); - source.AppendLine($"{indent}{propertyName}.Deserialize(reader);"); - } - - public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property) - { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } - - var propertyName = property.Name; - source.AppendLine($"{indent}{propertyName}.Serialize(writer);"); - } -} diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/SerializableInterfaceMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/SerializableInterfaceMigrationRule.cs deleted file mode 100644 index 2326af110..000000000 --- a/Projects/SerializationGenerator/SerializableMigration/Rules/SerializableInterfaceMigrationRule.cs +++ /dev/null @@ -1,75 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SerializableInterfaceMigrationRule.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System; -using System.Collections.Immutable; -using System.Text; -using Microsoft.CodeAnalysis; -using SerializationGenerator; - -namespace SerializableMigration; - -public class SerializableInterfaceMigrationRule : MigrationRule -{ - public override string RuleName => nameof(SerializableInterfaceMigrationRule); - - public override bool GenerateRuleState( - Compilation compilation, - ISymbol symbol, - ImmutableArray attributes, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes, - ISymbol? parentSymbol, - out string[] ruleArguments - ) - { - if (symbol is ITypeSymbol typeSymbol && typeSymbol.HasSerializableInterface(compilation, serializableTypes)) - { - ruleArguments = Array.Empty(); - return true; - } - - ruleArguments = null; - return false; - } - - public override void GenerateDeserializationMethod( - StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false - ) - { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } - - var propertyName = property.Name; - source.AppendLine($"{indent}{propertyName} = reader.ReadEntity<{property.Type}>();"); - } - - public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property) - { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } - - var propertyName = property.Name; - source.AppendLine($"{indent}writer.Write({propertyName});"); - } -} diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/SerializationMethodSignatureMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/SerializationMethodSignatureMigrationRule.cs deleted file mode 100644 index 4e9859170..000000000 --- a/Projects/SerializationGenerator/SerializableMigration/Rules/SerializationMethodSignatureMigrationRule.cs +++ /dev/null @@ -1,85 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SerializationMethodSignatureMigrationRule.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System; -using System.Collections.Immutable; -using System.Text; -using Microsoft.CodeAnalysis; -using SerializationGenerator; - -namespace SerializableMigration; - -public class SerializationMethodSignatureMigrationRule : MigrationRule -{ - public override string RuleName => nameof(SerializationMethodSignatureMigrationRule); - - public override bool GenerateRuleState( - Compilation compilation, - ISymbol symbol, - ImmutableArray attributes, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes, - ISymbol? parentSymbol, - out string[] ruleArguments - ) - { - if ((symbol as ITypeSymbol)?.HasPublicSerializeMethod(compilation, serializableTypes) != true) - { - ruleArguments = null; - return false; - } - - if (symbol is not INamedTypeSymbol namedTypeSymbol || - !namedTypeSymbol.HasGenericReaderCtor(compilation, parentSymbol, out var requiresParent)) - { - ruleArguments = null; - return false; - } - - ruleArguments = new[] { requiresParent ? "DeserializationRequiresParent" : "" }; - return true; - } - - public override void GenerateDeserializationMethod( - StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false - ) - { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } - - var propertyName = property.Name; - var argument = property.RuleArguments?.Length >= 1 && - property.RuleArguments[0] == "DeserializationRequiresParent" ? ", this" : ""; - - source.AppendLine($"{indent}{propertyName} = new {property.Type}(reader{argument});"); - } - - public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property) - { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } - - var propertyName = property.Name; - source.AppendLine($"{indent}{propertyName}.Serialize(writer);"); - } -} diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/TimerMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/TimerMigrationRule.cs deleted file mode 100644 index 7d97dfd6e..000000000 --- a/Projects/SerializationGenerator/SerializableMigration/Rules/TimerMigrationRule.cs +++ /dev/null @@ -1,136 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: TimerMigrationRule.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System; -using System.Collections.Immutable; -using System.Linq; -using System.Text; -using Microsoft.CodeAnalysis; -using SerializationGenerator; - -namespace SerializableMigration; - -public class TimerMigrationRule : MigrationRule, IPostDeserializeMethod -{ - public override string RuleName => nameof(TimerMigrationRule); - - public override bool GenerateRuleState( - Compilation compilation, - ISymbol symbol, - ImmutableArray attributes, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes, - ISymbol? parentSymbol, - out string[] ruleArguments - ) - { - if (!(symbol is ITypeSymbol typeSymbol && typeSymbol.IsTimer(compilation))) - { - ruleArguments = null; - return false; - } - - ruleArguments = attributes.Any(a => a.IsTimerDrift(compilation)) - ? new[] { "@TimerDrift" } - : new[] { "" }; - - return true; - } - - public override void GenerateMigrationProperty( - StringBuilder source, Compilation compilation, string indent, SerializableProperty serializableProperty - ) - { - source.AppendLine($"{indent}internal readonly System.DateTime {serializableProperty.Name}Next;"); - source.AppendLine($"{indent}internal readonly System.TimeSpan {serializableProperty.Name}Delay;"); - } - - public override void GenerateDeserializationMethod( - StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false - ) - { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } - - var propertyName = property.Name; - var ruleArguments = property.RuleArguments; - var driftTimer = ruleArguments![0].Contains("@TimerDrift"); - - var readTimer = driftTimer ? "reader.ReadDeltaTime()" : "reader.ReadDateTime()"; - var useVar = isMigration ? "" : "var "; - source.AppendLine($"{indent}{useVar}{propertyName}Next = {readTimer};"); - source.AppendLine($"{indent}{useVar}{propertyName}Delay = {propertyName}Next == System.DateTime.MinValue ? System.TimeSpan.MinValue : {propertyName}Next - Core.Now;"); - } - - public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property) - { - var expectedRule = RuleName; - var ruleName = property.Rule; - if (expectedRule != ruleName) - { - throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}."); - } - - var propertyName = property.Name; - var ruleArguments = property.RuleArguments; - var driftTimer = ruleArguments![0].Contains("@TimerDrift"); - - var writerMethod = driftTimer ? "WriteDeltaTime" : "Write"; - source.AppendLine($"{indent}writer.{writerMethod}({propertyName}?.Next ?? System.DateTime.MinValue);"); - } - - public void PostDeserializeMethod( - StringBuilder source, string indent, SerializableProperty property, Compilation compilation, INamedTypeSymbol classSymbol - ) - { - var deserializeTimerMethod = classSymbol - .GetMembers() - .OfType() - .FirstOrDefault( - m => - { - if (!m.ReturnsVoid || m.Parameters.Length != 1 || !m.Parameters[0].Type.IsTimeSpan(compilation)) - { - return false; - } - - return m.GetAttributes() - .FirstOrDefault( - attr => - { - if (!SymbolEqualityComparer.Default.Equals( - attr.AttributeClass, - compilation.GetTypeByMetadataName( - SymbolMetadata.DESERIALIZE_TIMER_FIELD_ATTRIBUTE - ) - )) - { - return false; - } - - var order = (int)attr.ConstructorArguments[0].Value!; - return order == property.Order; - } - ) != null; - } - ) ?? throw new Exception("Serializing a timer requires a method with the DeserializeTimerField attribute to handle creating the timer itself."); - - source.AppendLine($"{indent}{deserializeTimerMethod.Name}({property.Name}Delay);"); - } -} diff --git a/Projects/SerializationGenerator/SerializableMigration/SerializableMetadata.cs b/Projects/SerializationGenerator/SerializableMigration/SerializableMetadata.cs deleted file mode 100644 index a7a8a6b81..000000000 --- a/Projects/SerializationGenerator/SerializableMigration/SerializableMetadata.cs +++ /dev/null @@ -1,32 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SerializableMigration.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System.Collections.Immutable; -using System.Text.Json.Serialization; - -namespace SerializableMigration -{ - public record SerializableMetadata - { - [JsonPropertyName("version")] - public int Version { get; init; } - - [JsonPropertyName("type")] - public string Type { get; init; } - - [JsonPropertyName("properties")] - public ImmutableArray? Properties { get; init; } - } -} diff --git a/Projects/SerializationGenerator/SerializableMigration/SerializableMetadataComparer.cs b/Projects/SerializationGenerator/SerializableMigration/SerializableMetadataComparer.cs deleted file mode 100644 index 13fd600b2..000000000 --- a/Projects/SerializationGenerator/SerializableMigration/SerializableMetadataComparer.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Collections.Generic; - -namespace SerializableMigration -{ - public class SerializableMetadataComparer : IComparer - { - public int Compare(SerializableMetadata x, SerializableMetadata y) - { - if (ReferenceEquals(x, y)) - { - return 0; - } - - if (ReferenceEquals(null, y)) - { - return 1; - } - - if (ReferenceEquals(null, x)) - { - return -1; - } - - return x.Version.CompareTo(y.Version); - } - } -} diff --git a/Projects/SerializationGenerator/SerializableMigration/SerializableMigrationRulesEngine.cs b/Projects/SerializationGenerator/SerializableMigration/SerializableMigrationRulesEngine.cs deleted file mode 100644 index 1fe3e32f5..000000000 --- a/Projects/SerializationGenerator/SerializableMigration/SerializableMigrationRulesEngine.cs +++ /dev/null @@ -1,133 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SerializableMigrationRulesEngine.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using Microsoft.CodeAnalysis; -using SerializationGenerator; - -namespace SerializableMigration -{ - public static class SerializableMigrationRulesEngine - { - public static readonly Dictionary Rules = new(); - - static SerializableMigrationRulesEngine() - { - var rules = new ISerializableMigrationRule[] - { - new EnumMigrationRule(), - new ListMigrationRule(), - new ArrayMigrationRule(), - new HashSetMigrationRule(), - new DictionaryMigrationRule(), - new KeyValuePairMigrationRule(), - new PrimitiveTypeMigrationRule(), - new PrimitiveUOTypeMigrationRule(), - new SerializableInterfaceMigrationRule(), - new SerializationMethodSignatureMigrationRule(), - new RawSerializableMigrationRule(), - new TimerMigrationRule() - }; - - foreach (var rule in rules) - { - Rules.Add(rule.RuleName, rule); - } - } - - public static SerializableProperty? GenerateSerializableProperty( - Compilation compilation, - ISymbol fieldOrPropertySymbol, - int order, - ImmutableArray attributes, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes, - ISymbol? parentSymbol, - SerializableFieldSaveFlagMethods? serializableFieldSaveFlagMethods - ) - { - string propertyName; - ITypeSymbol propertyType; - - if (fieldOrPropertySymbol is IFieldSymbol fieldSymbol) - { - propertyName = fieldSymbol.Name; - propertyType = fieldSymbol.Type; - } - else if (fieldOrPropertySymbol is IPropertySymbol propertySymbol) - { - propertyName = fieldOrPropertySymbol.Name; - propertyType = propertySymbol.Type; - } - else - { - return null; - } - - return GenerateSerializableProperty( - compilation, - propertyName, - propertyType, - order, - attributes, - serializableTypes, - embeddedSerializableTypes, - parentSymbol, - serializableFieldSaveFlagMethods - ); - } - - public static SerializableProperty GenerateSerializableProperty( - Compilation compilation, - string propertyName, - ISymbol propertyType, - int order, - ImmutableArray attributes, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes, - ISymbol? parentSymbol, - SerializableFieldSaveFlagMethods? serializableFieldSaveFlagMethods - ) - { - foreach (var rule in Rules.Values) - { - if (rule.GenerateRuleState( - compilation, - propertyType, - attributes, - serializableTypes, - embeddedSerializableTypes, - parentSymbol, - out var ruleArguments - )) - { - return new SerializableProperty - { - Name = propertyName, - Type = propertyType.ToDisplayString(), - Order = order, - UsesSaveFlag = serializableFieldSaveFlagMethods?.DetermineFieldShouldSerialize != null ? true : null, - Rule = rule.RuleName, - RuleArguments = ruleArguments.Length > 0 ? ruleArguments : null - }; - } - } - - throw new Exception($"No rule found for property {propertyName} of type {propertyType} ({Rules.Count})"); - } - } -} diff --git a/Projects/SerializationGenerator/SerializableMigration/SerializableMigrationSchema.cs b/Projects/SerializationGenerator/SerializableMigration/SerializableMigrationSchema.cs deleted file mode 100644 index 2f8613456..000000000 --- a/Projects/SerializationGenerator/SerializableMigration/SerializableMigrationSchema.cs +++ /dev/null @@ -1,112 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SerializableMigrationSchema.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Text.Json; -using System.Text.Json.Serialization; -using System.Text.RegularExpressions; -using Microsoft.CodeAnalysis; - -namespace SerializableMigration -{ - public static class SerializableMigrationSchema - { - public static JsonSerializerOptions GetJsonSerializerOptions() => - new() - { - WriteIndented = true, - AllowTrailingCommas = true, - DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, - ReadCommentHandling = JsonCommentHandling.Skip - }; - - private static Dictionary _cache = new(); - - private static readonly Regex _fileRegex = new(@"\S+\.v\d+\.json$"); - - public static List GetMigrations( - INamedTypeSymbol typeSymbol, - int version, - string migrationPath, - JsonSerializerOptions options - ) - { - var typeName = typeSymbol.ToDisplayString(); - var migrations = new SortedSet(new SerializableMetadataComparer()); - - var migrationFiles = Directory.GetFiles(migrationPath, $"{typeName}.v*.json"); - - foreach (var file in migrationFiles) - { - var fi = new FileInfo(file); - if (!_cache.TryGetValue(fi.Name, out var migration)) - { - var text = File.ReadAllText(file, Encoding.UTF8); - migration = JsonSerializer.Deserialize(text, options); - _cache[fi.Name] = migration; - } - - if (typeName == migration!.Type && version > migration.Version) - { - migrations.Add(migration); - } - } - - return migrations.ToList(); - } - - public static List GetMigrationsByAnalyzerConfig( - this GeneratorExecutionContext context, - INamedTypeSymbol typeSymbol, - int version, - JsonSerializerOptions options - ) - { - var typeName = typeSymbol.ToDisplayString(); - var migrations = new SortedSet(new SerializableMetadataComparer()); - - foreach (var additionalText in context.AdditionalFiles) - { - var fi = new FileInfo(additionalText.Path); - if (!_fileRegex.IsMatch(fi.Name)) - { - continue; - } - - if (!_cache.TryGetValue(fi.Name, out var migration)) - { - var text = additionalText.GetText(context.CancellationToken)?.ToString(); - if (text == null) - { - continue; - } - - migration = JsonSerializer.Deserialize(text, options); - _cache[fi.Name] = migration; - } - - if (typeName == migration!.Type && version > migration.Version) - { - migrations.Add(migration); - } - } - - return migrations.ToList(); - } - } -} diff --git a/Projects/SerializationGenerator/SerializableMigration/SerializableProperty.cs b/Projects/SerializationGenerator/SerializableMigration/SerializableProperty.cs deleted file mode 100644 index 1f6f0c55e..000000000 --- a/Projects/SerializationGenerator/SerializableMigration/SerializableProperty.cs +++ /dev/null @@ -1,40 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SerializableProperty.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System.Text.Json.Serialization; - -namespace SerializableMigration -{ - public record SerializableProperty - { - [JsonPropertyName("name")] - public string Name { get; init; } - - [JsonPropertyName("type")] - public string Type { get; init; } - - [JsonPropertyName("usesSaveFlag")] - public bool? UsesSaveFlag { get; init; } - - [JsonPropertyName("rule")] - public string Rule { get; init; } - - [JsonPropertyName("ruleArguments")] - public string[]? RuleArguments { get; init; } - - [JsonIgnore] - public int Order { get; init; } - } -} diff --git a/Projects/SerializationGenerator/SerializableMigration/SerializablePropertyComparer.cs b/Projects/SerializationGenerator/SerializableMigration/SerializablePropertyComparer.cs deleted file mode 100644 index d4b736978..000000000 --- a/Projects/SerializationGenerator/SerializableMigration/SerializablePropertyComparer.cs +++ /dev/null @@ -1,42 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SerializablePropertyComparer.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System.Collections.Generic; - -namespace SerializableMigration -{ - public class SerializablePropertyComparer : IComparer - { - public int Compare(SerializableProperty x, SerializableProperty y) - { - if (Equals(x, y)) - { - return 0; - } - - if (Equals(null, y)) - { - return 1; - } - - if (Equals(null, x)) - { - return -1; - } - - return x.Order.CompareTo(y.Order); - } - } -} diff --git a/Projects/SerializationGenerator/SerializationGenerator.csproj b/Projects/SerializationGenerator/SerializationGenerator.csproj deleted file mode 100755 index 10448f42f..000000000 --- a/Projects/SerializationGenerator/SerializationGenerator.csproj +++ /dev/null @@ -1,31 +0,0 @@ - - - netstandard2.0 - preview - analyzers - - - - - - - - - - - - - - $(GetTargetPathDependsOn);GetDependencyTargetPaths - - - - - - - - - - - - diff --git a/Projects/SerializationGenerator/SerializerSyntaxReceiver.cs b/Projects/SerializationGenerator/SerializerSyntaxReceiver.cs deleted file mode 100755 index fea02e69d..000000000 --- a/Projects/SerializationGenerator/SerializerSyntaxReceiver.cs +++ /dev/null @@ -1,133 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright (C) 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SyntaxReceiver.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System.Collections.Generic; -using System.Collections.Immutable; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp.Syntax; - -namespace SerializationGenerator -{ - public class SerializerSyntaxReceiver : ISyntaxContextReceiver - { -#pragma warning disable RS1024 - public Dictionary)> ClassAndFields { get; } = new(SymbolEqualityComparer.Default); - public Dictionary)> EmbeddedClassAndFields { get; } = new(SymbolEqualityComparer.Default); -#pragma warning restore RS1024 - - public ImmutableArray SerializableList => ClassAndFields.Keys.ToImmutableArray(); - - public ImmutableArray EmbeddedSerializableList => EmbeddedClassAndFields.Keys.ToImmutableArray(); - - public void OnVisitSyntaxNode(SyntaxNode node, SemanticModel semanticModel) - { - var compilation = semanticModel.Compilation; - - if (node is ClassDeclarationSyntax { AttributeLists: { Count: > 0 } } classDeclarationSyntax) - { - if (semanticModel.GetDeclaredSymbol(classDeclarationSyntax) is not INamedTypeSymbol classSymbol) - { - return; - } - - if (classSymbol.IsEmbeddedSerializable(compilation, out var attrData)) - { - if (EmbeddedClassAndFields.TryGetValue(classSymbol, out var value)) - { - var (_, fieldsList) = value; - EmbeddedClassAndFields[classSymbol] = (attrData, fieldsList); - } - else - { - EmbeddedClassAndFields.Add(classSymbol, (attrData, new List())); - } - } - else if (classSymbol.WillBeSerializable(compilation, out attrData)) - { - if (ClassAndFields.TryGetValue(classSymbol, out var value)) - { - var (_, fieldsList) = value; - ClassAndFields[classSymbol] = (attrData, fieldsList); - } - else - { - ClassAndFields.Add(classSymbol, (attrData, new List())); - } - } - - return; - } - - if (node is FieldDeclarationSyntax { AttributeLists: { Count: > 0 } } fieldDeclarationSyntax) - { - foreach (var variable in fieldDeclarationSyntax.Declaration.Variables) - { - if (semanticModel.GetDeclaredSymbol(variable) is IFieldSymbol fieldSymbol) - { - AddFieldOrProperty(fieldSymbol, compilation); - } - } - - return; - } - - if (node is PropertyDeclarationSyntax { AttributeLists: { Count: > 0 } } propertyDeclarationSyntax) - { - if (semanticModel.GetDeclaredSymbol(propertyDeclarationSyntax) is IPropertySymbol propertySymbol) - { - AddFieldOrProperty(propertySymbol, compilation); - } - } - } - - public void OnVisitSyntaxNode(GeneratorSyntaxContext context) => - OnVisitSyntaxNode(context.Node, context.SemanticModel); - - private void AddFieldOrProperty(ISymbol symbol, Compilation compilation) - { - var serializableFieldAttr = compilation.GetTypeByMetadataName(SymbolMetadata.SERIALIZABLE_FIELD_ATTRIBUTE); - var parentAttr = compilation.GetTypeByMetadataName(SymbolMetadata.SERIALIZABLE_PARENT_ATTRIBUTE); - - if (symbol.GetAttribute(serializableFieldAttr) == null && symbol.GetAttribute(parentAttr) == null) - { - return; - } - - var classSymbol = symbol.ContainingType; - if (ClassAndFields.TryGetValue(classSymbol, out var value)) - { - var (_, fieldsList) = value; - fieldsList.Add(symbol); - return; - } - - if (EmbeddedClassAndFields.TryGetValue(classSymbol, out value)) - { - var (_, fieldsList) = value; - fieldsList.Add(symbol); - return; - } - - if (classSymbol.WillBeSerializable(compilation, out var attrData)) - { - ClassAndFields.Add(classSymbol, (attrData, new List { symbol })); - } - else if (classSymbol.IsEmbeddedSerializable(compilation, out attrData)) - { - EmbeddedClassAndFields.Add(classSymbol, (attrData, new List { symbol })); - } - } - } -} diff --git a/Projects/SerializationGenerator/SourceGeneration/Helpers.cs b/Projects/SerializationGenerator/SourceGeneration/Helpers.cs deleted file mode 100644 index f1a9a88e5..000000000 --- a/Projects/SerializationGenerator/SourceGeneration/Helpers.cs +++ /dev/null @@ -1,65 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: Helpers.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Linq; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; - -namespace SerializationGenerator -{ - public static class Helpers - { - public static bool ContainsInterface(this ITypeSymbol symbol, ISymbol interfaceSymbol) => - symbol.Interfaces.Any(i => i.ConstructedFrom.Equals(interfaceSymbol, SymbolEqualityComparer.Default)) || - symbol.AllInterfaces.Any(i => i.ConstructedFrom.Equals(interfaceSymbol, SymbolEqualityComparer.Default)); - - public static ImmutableArray GetAllMethods(this ITypeSymbol symbol, string name) - { - var methods = symbol.GetMembers(name).OfType().ToImmutableArray(); - if (symbol.ContainingSymbol is not ITypeSymbol typeSymbol) - { - return methods; - } - - var list = new List(); - list.AddRange(methods.ToList()); - list.AddRange(GetAllMethods(typeSymbol, name).ToList()); - - return list.ToImmutableArray(); - } - - public static string ToFriendlyString(this Accessibility accessibility) => SyntaxFacts.GetText(accessibility); - - public static Accessibility GetAccessibility(string? value) => - value switch - { - "private" => Accessibility.Private, - "protected" => Accessibility.Protected, - "internal" => Accessibility.Internal, - "public" => Accessibility.Public, - "protected internal" => Accessibility.ProtectedOrInternal, - "private protected" => Accessibility.ProtectedAndInternal, - _ => Accessibility.NotApplicable - }; - - public static bool CanBeConstructedFrom(this ITypeSymbol? symbol, ISymbol classSymbol) => - symbol is INamedTypeSymbol namedTypeSymbol && namedTypeSymbol.ConstructedFrom.Equals( - classSymbol, - SymbolEqualityComparer.Default - ) || symbol != null && CanBeConstructedFrom(symbol.BaseType, classSymbol); - } -} diff --git a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Arguments.cs b/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Arguments.cs deleted file mode 100644 index 53dc5823c..000000000 --- a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Arguments.cs +++ /dev/null @@ -1,125 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright (C) 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SourceGeneration.Arguments.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Text; -using Microsoft.CodeAnalysis; - -namespace SerializationGenerator -{ - public static partial class SourceGeneration - { - public static void GetTypesFromTypedConstant(TypedConstant arg, List list) - { - if (arg.Kind == TypedConstantKind.Type) - { - list.Add((ITypeSymbol)arg.Value); - } - else if (arg.Kind == TypedConstantKind.Array) - { - for (var i = 0; i < arg.Values.Length; i++) - { - GetTypesFromTypedConstant(arg.Values[i], list); - } - } - } - - public static void GenerateSignatureArguments(this StringBuilder source, ImmutableArray<(ITypeSymbol, string)> parameters) - { - for (var i = 0; i < parameters.Length; i++) - { - var (t, v) = parameters[i]; - source.AppendFormat("{0} {1}", t.ToDisplayString(), v); - if (i < parameters.Length - 1) - { - source.Append(", "); - } - } - } - - public static void GenerateNamedArgument(this StringBuilder source, KeyValuePair namedArg) - { - source.AppendFormat("{0} = ", namedArg.Key); - source.GenerateTypedConstant(namedArg.Value); - } - - public static void GenerateTypedConstants(this StringBuilder source, ImmutableArray args) - { - source.Append("new []{"); - for (var i = 0; i < args.Length; i++) - { - source.GenerateTypedConstant(args[i]); - if (i < args.Length - 1) - { - source.Append(", "); - } - } - source.Append('}'); - } - - public static void GenerateTypedConstant(this StringBuilder source, TypedConstant arg) - { - if (arg.IsNull) - { - source.Append("null"); - return; - } - - switch (arg.Kind) - { - default: - { - return; - } - case TypedConstantKind.Primitive: - { - - if (arg.Value is string str) - { - source.AppendFormat("\"{0}\"", str); - } - else - { - source.Append(arg.Value); - } - break; - } - case TypedConstantKind.Enum: - { - if (arg.Type == null || arg.Value == null) - { - source.Append("null"); - } - else - { - source.AppendFormat("({0}){1}", arg.Type.ToDisplayString(), arg.Value); - } - break; - } - case TypedConstantKind.Type: - { - source.AppendFormat("typeof({0})", ((ITypeSymbol)arg.Value)?.Name); - break; - } - case TypedConstantKind.Array: - { - source.GenerateTypedConstants(arg.Values); - break; - } - } - } - } -} diff --git a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Attribute.cs b/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Attribute.cs deleted file mode 100644 index eda4cf08c..000000000 --- a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Attribute.cs +++ /dev/null @@ -1,102 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright (C) 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SourceGeneration.Attribute.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System.Collections.Immutable; -using System.Text; -using Microsoft.CodeAnalysis; - -namespace SerializationGenerator -{ - public static partial class SourceGeneration - { - public static void GenerateAttribute( - this StringBuilder source, - string indent, - string attrClassName, - ImmutableArray args - ) - { - source.Append($"{indent}[{attrClassName}"); - var hasArgs = args.Length > 0; - - if (hasArgs) - { - source.Append("("); - } - - for (var i = 0; i < args.Length; i++) - { - var arg = args[i]; - source.GenerateTypedConstant(arg); - if (i < args.Length - 1) - { - source.Append(", "); - } - } - - if (hasArgs) - { - source.Append(")"); - } - - source.AppendLine("]"); - } - - public static void GenerateAttribute(this StringBuilder source, AttributeData attr) - { - source.Append($" [{attr.AttributeClass?.Name}"); - var ctorArgs = attr.ConstructorArguments; - var namedArgs = attr.NamedArguments; - var hasArgs = ctorArgs.Length + namedArgs.Length > 0; - - if (hasArgs) - { - source.Append("("); - } - - for (var i = 0; i < ctorArgs.Length; i++) - { - var arg = ctorArgs[i]; - source.GenerateTypedConstant(arg); - if (i < ctorArgs.Length - 1) - { - source.Append(", "); - } - } - - for (var i = 0; i < namedArgs.Length; i++) - { - var arg = namedArgs[i]; - source.GenerateNamedArgument(arg); - if (i < namedArgs.Length - 1) - { - source.Append(", "); - } - } - - if (hasArgs) - { - source.Append(")"); - } - - source.AppendLine("]"); - } - - public static void AggressiveInline(this StringBuilder source, string indent) => - source.AppendLine( - $"{indent}[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]" - ); - } -} diff --git a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Class.cs b/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Class.cs deleted file mode 100644 index c25999cd8..000000000 --- a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Class.cs +++ /dev/null @@ -1,72 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright (C) 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SourceGeneration.Class.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System.Collections.Immutable; -using System.Text; -using Microsoft.CodeAnalysis; - -namespace SerializationGenerator -{ - public static partial class SourceGeneration - { - public static void GenerateClassStart( - this StringBuilder source, - INamedTypeSymbol classSymbol, - string indent, - ImmutableArray interfaces, - bool isPartial = true - ) - { - var accessor = classSymbol.DeclaredAccessibility; - source.Append($"{indent}{accessor.ToFriendlyString()} {(isPartial ? "partial " : "")}class {classSymbol.Name}"); - if (!interfaces.IsEmpty) - { - source.Append(" : "); - for (var i = 0; i < interfaces.Length; i++) - { - source.Append(interfaces[i].ToDisplayString()); - if (i < interfaces.Length - 1) - { - source.Append(", "); - } - } - } - - source.AppendLine($"\n{indent}{{"); - } - - public static void GenerateClassEnd(this StringBuilder source, string indent) - { - source.AppendLine($"{indent}}}"); - } - - // TODO: Generalize this to any field using dynamic indentation - public static void GenerateClassField( - this StringBuilder source, - string indent, - Accessibility accessors, - InstanceModifier instance, - string type, - string variableName, - string value - ) - { - var instanceStr = instance == InstanceModifier.None ? "" : $"{instance.ToFriendlyString()} "; - var accessorStr = accessors == Accessibility.NotApplicable ? "" : $"{accessors.ToFriendlyString()} "; - var valueStr = value == null ? "" : $" = {value}"; - source.AppendLine($"{indent}{accessorStr}{instanceStr}{type} {variableName}{valueStr};"); - } - } -} diff --git a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Enum.cs b/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Enum.cs deleted file mode 100644 index 6f8213561..000000000 --- a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Enum.cs +++ /dev/null @@ -1,50 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SourceGeneration.Enum.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System.Text; -using Microsoft.CodeAnalysis; - -namespace SerializationGenerator -{ - public static partial class SourceGeneration - { - public static void GenerateEnumStart( - this StringBuilder source, - string enumName, - string indent, - bool useFlags, - Accessibility accessor = Accessibility.Public - ) - { - if (useFlags) - { - source.AppendLine($"{indent}[System.Flags]"); - } - source.AppendLine($"{indent}{accessor.ToFriendlyString()} enum {enumName}\n{indent}{{"); - } - - public static void GenerateEnumValue(this StringBuilder source, string indent, bool isFlag, string name, int value) - { - var number = value < 0 ? 0 : 1 << value; - var valueStr = isFlag ? $"0x{number:X8}" : value.ToString(); - source.AppendLine($"{indent}{name} = {valueStr},"); - } - - public static void GenerateEnumEnd(this StringBuilder source, string indent) - { - source.AppendLine($"{indent}}}"); - } - } -} diff --git a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.InstanceModifier.cs b/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.InstanceModifier.cs deleted file mode 100644 index 2fdfef6da..000000000 --- a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.InstanceModifier.cs +++ /dev/null @@ -1,39 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SourceGeneration.InstanceModifier.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -namespace SerializationGenerator -{ - public enum InstanceModifier - { - None, - Const, - ReadOnly, - Static, - StaticReadOnly - } - - public static partial class SourceGeneration - { - public static string ToFriendlyString(this InstanceModifier modifier) => - modifier switch - { - InstanceModifier.Const => "const", - InstanceModifier.ReadOnly => "readonly", - InstanceModifier.Static => "static", - InstanceModifier.StaticReadOnly => "static readonly", - _ => "" - }; - } -} diff --git a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Method.cs b/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Method.cs deleted file mode 100644 index 407fd3e32..000000000 --- a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Method.cs +++ /dev/null @@ -1,62 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright (C) 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SourceGeneration.Method.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System.Collections.Immutable; -using System.Text; -using Microsoft.CodeAnalysis; - -namespace SerializationGenerator -{ - public static partial class SourceGeneration - { - public static void GenerateMethodStart( - this StringBuilder source, string indent, string methodName, Accessibility accessors, bool isOverride, - string returnType, ImmutableArray<(ITypeSymbol, string)> parameters - ) - { - source.Append($"{indent}{accessors.ToFriendlyString()}{(isOverride ? " override" : "")} {returnType} {methodName}("); - source.GenerateSignatureArguments(parameters); - source.AppendLine($")\n{indent}{{"); - } - - public static void GenerateMethodEnd(this StringBuilder source, string indent) => source.AppendLine($"{indent}}}"); - - public static void GenerateConstructorStart( - this StringBuilder source, string indent, string className, Accessibility accessors, ImmutableArray<(ITypeSymbol, string)> parameters, - ImmutableArray baseParameters, bool isOverload = false - ) - { - source.Append($"{indent}{accessors.ToFriendlyString()} {className}("); - source.GenerateSignatureArguments(parameters); - source.Append(')'); - bool hasBaseParams = baseParameters.Length > 0; - if (hasBaseParams) - { - source.AppendFormat(" : {0}(", isOverload ? "this" : "base"); - for (int i = 0; i < baseParameters.Length; i++) - { - source.Append(baseParameters[i]); - if (i < baseParameters.Length - 1) - { - source.Append(','); - } - } - source.Append(')'); - } - - source.AppendLine($"\n{indent}{{"); - } - } -} diff --git a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Namespace.cs b/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Namespace.cs deleted file mode 100644 index 24ced2544..000000000 --- a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Namespace.cs +++ /dev/null @@ -1,33 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright (C) 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SourceGeneration.Namespace.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System.Text; - -namespace SerializationGenerator -{ - public static partial class SourceGeneration - { - public static void GenerateNamespaceStart(this StringBuilder source, string namespaceName) - { - source.AppendLine($@"namespace {namespaceName} -{{"); - } - - public static void GenerateNamespaceEnd(this StringBuilder source) - { - source.AppendLine("}"); - } - } -} diff --git a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Property.cs b/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Property.cs deleted file mode 100644 index fc66bc985..000000000 --- a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Property.cs +++ /dev/null @@ -1,144 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright (C) 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SourceGeneration.Property.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System; -using System.Text; -using Humanizer; -using Microsoft.CodeAnalysis; - -namespace SerializationGenerator -{ - public static partial class SourceGeneration - { - public static string GetPropertyName(this IFieldSymbol fieldSymbol) - { - var fieldName = fieldSymbol.Name; - - var propertyName = fieldName; - - if (propertyName.StartsWith("m_", StringComparison.OrdinalIgnoreCase)) - { - propertyName = propertyName.Substring(2); - } - else if (propertyName.StartsWith("_", StringComparison.OrdinalIgnoreCase)) - { - propertyName = propertyName.Substring(1); - } - - return propertyName.Dehumanize(); - } - - public static void GeneratePropertyStart( - this StringBuilder source, - string indent, - Accessibility accessors, - bool isVirtual, - IFieldSymbol fieldSymbol - ) - { - var propertyName = fieldSymbol.GetPropertyName(); - var virt = isVirtual ? "virtual " : ""; - - source.AppendLine($"{indent}{accessors.ToFriendlyString()} {virt}{fieldSymbol.Type} {propertyName}"); - source.AppendLine($"{indent}{{"); - } - - public static void GenerateAutoProperty( - this StringBuilder source, - Accessibility accessors, - string type, - string propertyName, - Accessibility? getAccessor, - Accessibility? setAccessor, - string indent, - bool useInit = false, - string defaultValue = null, - bool isOverride = false - ) - { - if (getAccessor == null && setAccessor == null) - { - throw new ArgumentNullException($"Must specify a {nameof(getAccessor)} or {nameof(setAccessor)} parameter"); - } - - var getter = getAccessor == null ? - "" : - $"{(getAccessor != Accessibility.NotApplicable ? $"{getAccessor.Value.ToFriendlyString()} " : "")}get;"; - - var getterSpace = getAccessor != null ? " " : ""; - var setOrInit = useInit ? "init;" : "set;"; - - var setterAccessor = setAccessor is null or Accessibility.NotApplicable - ? "" - : $"{setAccessor.Value.ToFriendlyString() ?? ""} "; - - var setter = setAccessor == null ? "" : $"{getterSpace}{setterAccessor}{setOrInit}"; - - var propertyAccessor = accessors == Accessibility.NotApplicable ? "" : $"{accessors.ToFriendlyString()} "; - var printOverride = isOverride ? "override " : ""; - var printDefaultValue = defaultValue != null ? $"{(setAccessor != null ? " =" : "")} {defaultValue};" : ""; - var printGetterSetter = setAccessor == null ? "=>" : $"{{ {getter}{setter} }}"; - - source.AppendLine($"{indent}{propertyAccessor}{printOverride}{type} {propertyName} {printGetterSetter}{printDefaultValue}"); - } - - public static void GeneratePropertyEnd(this StringBuilder source, string indent) => source.AppendLine($"{indent}}}"); - - public static void GeneratePropertyGetterReturnsField( - this StringBuilder source, - string indent, - IFieldSymbol fieldSymbol, - Accessibility Accessibility - ) - { - var accessor = Accessibility != Accessibility.NotApplicable ? $"{Accessibility.ToFriendlyString()} " : ""; - source.AppendLine($"{indent}{accessor}get => {fieldSymbol.Name};"); - } - - public static void GeneratePropertyGetterStart( - this StringBuilder source, - string indent, - bool useExpression, - Accessibility Accessibility - ) - { - var accessor = Accessibility != Accessibility.NotApplicable ? $"{Accessibility.ToFriendlyString()} " : ""; - var expression = useExpression ? " => " : $"\n{indent}{{"; - source.AppendLine($"{indent}{accessor}get{expression}"); - } - - public static void GeneratePropertyGetSetEnd(this StringBuilder source, string indent, bool useExpression) - { - if (!useExpression) - { - source.AppendLine($"{indent}}}"); - } - } - - public static void GeneratePropertySetterStart( - this StringBuilder source, - string indent, - bool useExpression, - Accessibility Accessibility, - bool useInit = false - ) - { - var init = useInit ? "init" : "set"; - var expression = useExpression ? " => " : $"\n{indent}{{"; - var accessor = Accessibility != Accessibility.NotApplicable ? $"{Accessibility.ToFriendlyString()} " : ""; - source.AppendLine($"{indent}{accessor}{init}{expression}"); - } - } -} diff --git a/Projects/SerializationGenerator/SourceGeneration/SymbolMetadata/SymbolMetadata.Builtin.cs b/Projects/SerializationGenerator/SourceGeneration/SymbolMetadata/SymbolMetadata.Builtin.cs deleted file mode 100644 index 28241d463..000000000 --- a/Projects/SerializationGenerator/SourceGeneration/SymbolMetadata/SymbolMetadata.Builtin.cs +++ /dev/null @@ -1,69 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SymbolMetadata.Builtin.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using Microsoft.CodeAnalysis; - -namespace SerializationGenerator -{ - public static partial class SymbolMetadata - { - public const string DICTIONARY_CLASS = "System.Collections.Generic.Dictionary`2"; - public const string LIST_CLASS = "System.Collections.Generic.List`1"; - public const string HASHSET_CLASS = "System.Collections.Generic.HashSet`1"; - public const string IPADDRESS_CLASS = "System.Net.IPAddress"; - public const string KEYVALUEPAIR_STRUCT = "System.Collections.Generic.KeyValuePair"; - public const string TIMESPAN_STRUCT = "System.TimeSpan"; - - public static bool IsTimeSpan(this ISymbol symbol, Compilation compilation) => - symbol.Equals( - compilation.GetTypeByMetadataName(TIMESPAN_STRUCT), - SymbolEqualityComparer.Default - ); - - public static bool IsIpAddress(this ISymbol symbol, Compilation compilation) => - symbol.Equals( - compilation.GetTypeByMetadataName(IPADDRESS_CLASS), - SymbolEqualityComparer.Default - ); - - public static bool IsKeyValuePair(this ISymbol symbol, Compilation compilation) => - (symbol as INamedTypeSymbol)?.ConstructedFrom.Equals( - compilation.GetTypeByMetadataName(KEYVALUEPAIR_STRUCT), - SymbolEqualityComparer.Default - ) == true; - - public static bool IsDictionary(this ISymbol symbol, Compilation compilation) => - (symbol as INamedTypeSymbol)?.ConstructedFrom.Equals( - compilation.GetTypeByMetadataName(DICTIONARY_CLASS), - SymbolEqualityComparer.Default - ) == true; - - public static bool IsHashSet(this ISymbol symbol, Compilation compilation) => - (symbol as INamedTypeSymbol)?.ConstructedFrom.Equals( - compilation.GetTypeByMetadataName(HASHSET_CLASS), - SymbolEqualityComparer.Default - ) == true; - - public static bool IsList(this ISymbol symbol, Compilation compilation) => - (symbol as INamedTypeSymbol)?.ConstructedFrom.Equals( - compilation.GetTypeByMetadataName(LIST_CLASS), - SymbolEqualityComparer.Default - ) == true; - - public static bool IsPrimitiveFromTypeDisplayString(string type) => - type is "bool" or "sbyte" or "short" or "int" or "long" or "byte" or "ushort" - or "uint" or "ulong" or "float" or "double" or "string" or "decimal"; - } -} diff --git a/Projects/SerializationGenerator/SourceGeneration/SymbolMetadata/SymbolMetadata.UO.cs b/Projects/SerializationGenerator/SourceGeneration/SymbolMetadata/SymbolMetadata.UO.cs deleted file mode 100644 index 2fdf8793c..000000000 --- a/Projects/SerializationGenerator/SourceGeneration/SymbolMetadata/SymbolMetadata.UO.cs +++ /dev/null @@ -1,228 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SymbolMetadata.UO.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System.Collections.Immutable; -using System.Linq; -using Microsoft.CodeAnalysis; - -namespace SerializationGenerator -{ - public static partial class SymbolMetadata - { - public const string INVALIDATEPROPERTIES_ATTRIBUTE = "Server.InvalidatePropertiesAttribute"; - public const string AFTERDESERIALIZATION_ATTRIBUTE = "Server.AfterDeserializationAttribute"; - public const string SERIALIZABLE_ATTRIBUTE = "Server.SerializableAttribute"; - public const string EMBEDDED_SERIALIZABLE_ATTRIBUTE = "Server.EmbeddedSerializableAttribute"; - public const string SERIALIZABLE_PARENT_ATTRIBUTE = "Server.SerializableParentAttribute"; - public const string SERIALIZABLE_FIELD_ATTRIBUTE = "Server.SerializableFieldAttribute"; - public const string SERIALIZABLE_FIELD_ATTR_ATTRIBUTE = "Server.SerializableFieldAttrAttribute"; - public const string SERIALIZABLE_INTERFACE = "Server.ISerializable"; - public const string GENERIC_WRITER_INTERFACE = "Server.IGenericWriter"; - public const string GENERIC_READER_INTERFACE = "Server.IGenericReader"; - public const string DELTA_DATE_TIME_ATTRIBUTE = "Server.DeltaDateTimeAttribute"; - public const string INTERN_STRING_ATTRIBUTE = "Server.InternStringAttribute"; - public const string ENCODED_INT_ATTRIBUTE = "Server.EncodedIntAttribute"; - public const string TIDY_ATTRIBUTE = "Server.TidyAttribute"; - public const string POINT2D_STRUCT = "Server.Point2D"; - public const string POINT3D_STRUCT = "Server.Point3D"; - public const string RECTANGLE2D_STRUCT = "Server.Rectangle2D"; - public const string RECTANGLE3D_STRUCT = "Server.Rectangle3D"; - public const string RACE_CLASS = "Server.Race"; - public const string MAP_CLASS = "Server.Map"; - public const string TIMER_CLASS = "Server.Timer"; - public const string TIMER_DRIFT_ATTRIBUTE = "Server.TimerDriftAttribute"; - public const string DESERIALIZE_TIMER_FIELD_ATTRIBUTE = "Server.DeserializeTimerFieldAttribute"; - public const string SERIALIZABLE_FIELD_SAVE_FLAG_ATTRIBUTE = "Server.SerializableFieldSaveFlagAttribute"; - public const string SERIALIZABLE_FIELD_DEFAULT_ATTRIBUTE = "Server.SerializableFieldDefaultAttribute"; - public const string RAW_SERIALIZABLE_INTERFACE = "Server.IRawSerializable"; - // ModernUO modified BitArray - public const string SERVER_BITARRAY_CLASS = "Server.Collections.BitArray"; - - public static bool IsTimerDrift(this AttributeData attr, Compilation compilation) => - attr?.IsAttribute(compilation.GetTypeByMetadataName(TIMER_DRIFT_ATTRIBUTE)) == true; - - public static bool IsTimer(this ITypeSymbol symbol, Compilation compilation) => - symbol.CanBeConstructedFrom(compilation.GetTypeByMetadataName(TIMER_CLASS)); - - public static bool IsEncodedInt(this AttributeData attr, Compilation compilation) => - attr?.IsAttribute(compilation.GetTypeByMetadataName(ENCODED_INT_ATTRIBUTE)) == true; - - public static bool IsDeltaDateTime(this AttributeData attr, Compilation compilation) => - attr?.IsAttribute(compilation.GetTypeByMetadataName(DELTA_DATE_TIME_ATTRIBUTE)) == true; - - public static bool IsInternString(this AttributeData attr, Compilation compilation) => - attr?.IsAttribute(compilation.GetTypeByMetadataName(INTERN_STRING_ATTRIBUTE)) == true; - - public static bool IsTidy(this AttributeData attr, Compilation compilation) => - attr?.IsAttribute(compilation.GetTypeByMetadataName(TIDY_ATTRIBUTE)) == true; - - public static bool IsAttribute(this AttributeData attr, ISymbol symbol) => - attr?.AttributeClass?.Equals(symbol, SymbolEqualityComparer.Default) == true; - - public static bool IsEnum(this ITypeSymbol symbol) => - symbol.SpecialType == SpecialType.System_Enum || symbol.TypeKind == TypeKind.Enum; - - public static bool HasSerializableInterface( - this ITypeSymbol symbol, - Compilation compilation, - ImmutableArray serializableTypes - ) => - symbol.ContainsInterface(compilation.GetTypeByMetadataName(SERIALIZABLE_INTERFACE)) || - serializableTypes.Contains(symbol); - - public static bool HasRawSerializableInterface( - this ITypeSymbol symbol, - Compilation compilation, - ImmutableArray embeddedSerializableTypes - ) => - symbol.ContainsInterface(compilation.GetTypeByMetadataName(RAW_SERIALIZABLE_INTERFACE)) || - embeddedSerializableTypes.Contains(symbol); - - public static bool Contains(this ImmutableArray symbols, ITypeSymbol? symbol) => - symbol is INamedTypeSymbol namedSymbol && - symbols.Contains(namedSymbol, SymbolEqualityComparer.Default) || symbols.Contains(symbol?.BaseType); - - public static bool HasGenericReaderCtor( - this INamedTypeSymbol symbol, - Compilation compilation, - ISymbol? parentSymbol, - out bool requiresParent - ) - { - var genericReaderInterface = compilation.GetTypeByMetadataName(GENERIC_READER_INTERFACE); - var genericCtor = symbol.Constructors.FirstOrDefault( - m => !m.IsStatic && - m.MethodKind == MethodKind.Constructor && - m.Parameters.Length >= 1 && - m.Parameters.Length <= 2 && - SymbolEqualityComparer.Default.Equals(m.Parameters[0].Type, genericReaderInterface) - ); - - requiresParent = genericCtor?.Parameters.Length == 2 && SymbolEqualityComparer.Default.Equals(genericCtor.Parameters[1].Type, parentSymbol); - return genericCtor != null; - } - - public static bool HasPublicSerializeMethod( - this ITypeSymbol symbol, - Compilation compilation, - ImmutableArray serializableTypes - ) - { - var genericWriterInterface = compilation.GetTypeByMetadataName(GENERIC_WRITER_INTERFACE); - - return symbol.GetAllMethods("Serialize") - .Any( - m => !m.IsStatic && - m.ReturnsVoid && - m.Parameters.Length == 1 && - SymbolEqualityComparer.Default.Equals(m.Parameters[0].Type, genericWriterInterface) && - m.DeclaredAccessibility == Accessibility.Public - ); - } - - public static bool HasPublicDeserializeMethod( - this ITypeSymbol symbol, - Compilation compilation, - ImmutableArray serializableTypes - ) - { - var genericReaderInterface = compilation.GetTypeByMetadataName(GENERIC_READER_INTERFACE); - - return symbol.GetAllMethods("Deserialize") - .Any( - m => !m.IsStatic && - m.ReturnsVoid && - m.Parameters.Length == 1 && - SymbolEqualityComparer.Default.Equals(m.Parameters[0].Type, genericReaderInterface) && - m.DeclaredAccessibility == Accessibility.Public - ); - } - - public static bool IsPoint2D(this ISymbol symbol, Compilation compilation) => - symbol.Equals( - compilation.GetTypeByMetadataName(POINT2D_STRUCT), - SymbolEqualityComparer.Default - ); - - public static bool IsPoint3D(this ISymbol symbol, Compilation compilation) => - symbol.Equals( - compilation.GetTypeByMetadataName(POINT3D_STRUCT), - SymbolEqualityComparer.Default - ); - - public static bool IsRectangle2D(this ISymbol symbol, Compilation compilation) => - symbol.Equals( - compilation.GetTypeByMetadataName(RECTANGLE2D_STRUCT), - SymbolEqualityComparer.Default - ); - - public static bool IsRectangle3D(this ISymbol symbol, Compilation compilation) => - symbol.Equals( - compilation.GetTypeByMetadataName(RECTANGLE3D_STRUCT), - SymbolEqualityComparer.Default - ); - - public static bool IsRace(this ISymbol symbol, Compilation compilation) => - symbol.Equals( - compilation.GetTypeByMetadataName(RACE_CLASS), - SymbolEqualityComparer.Default - ); - - public static bool IsMap(this ISymbol symbol, Compilation compilation) => - symbol.Equals( - compilation.GetTypeByMetadataName(MAP_CLASS), - SymbolEqualityComparer.Default - ); - - public static bool IsBitArray(this ISymbol symbol, Compilation compilation) => - symbol.Equals( - compilation.GetTypeByMetadataName(SERVER_BITARRAY_CLASS), - SymbolEqualityComparer.Default - ); - - public static AttributeData? GetAttribute(this ISymbol symbol, ISymbol attrSymbol) => - symbol - .GetAttributes() - .FirstOrDefault( - ad => ad.AttributeClass != null && SymbolEqualityComparer.Default.Equals(ad.AttributeClass, attrSymbol) - ); - - public static bool WillBeSerializable(this INamedTypeSymbol classSymbol, Compilation compilation, out AttributeData? attributeData) - { - var serializableInterface = compilation.GetTypeByMetadataName(SERIALIZABLE_INTERFACE); - - if (!classSymbol.ContainsInterface(serializableInterface)) - { - attributeData = null; - return false; - } - - var serializableEntityAttribute = - compilation.GetTypeByMetadataName(SERIALIZABLE_ATTRIBUTE); - - attributeData = classSymbol.GetAttribute(serializableEntityAttribute); - return attributeData != null; - } - - public static bool IsEmbeddedSerializable(this INamedTypeSymbol classSymbol, Compilation compilation, out AttributeData? attributeData) - { - var embeddedSerializableEntityAttribute = - compilation.GetTypeByMetadataName(EMBEDDED_SERIALIZABLE_ATTRIBUTE); - - attributeData = classSymbol.GetAttribute(embeddedSerializableEntityAttribute); - return attributeData != null; - } - } -} diff --git a/Projects/SerializationGenerator/Utility.cs b/Projects/SerializationGenerator/Utility.cs deleted file mode 100644 index ad3f9c9c8..000000000 --- a/Projects/SerializationGenerator/Utility.cs +++ /dev/null @@ -1,28 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: Utility.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System.Collections.Generic; - -namespace SerializationGenerator -{ - public static class Utility - { - public static void Deconstruct(this KeyValuePair tuple, out T1 key, out T2 value) - { - key = tuple.Key; - value = tuple.Value; - } - } -} diff --git a/Projects/SerializationSchemaGenerator/.gitignore b/Projects/SerializationSchemaGenerator/.gitignore deleted file mode 100644 index 2fe317a80..000000000 --- a/Projects/SerializationSchemaGenerator/.gitignore +++ /dev/null @@ -1 +0,0 @@ -Output/ diff --git a/Projects/SerializationSchemaGenerator/Application.cs b/Projects/SerializationSchemaGenerator/Application.cs deleted file mode 100644 index eb6946787..000000000 --- a/Projects/SerializationSchemaGenerator/Application.cs +++ /dev/null @@ -1,103 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: Application.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System; -using System.Collections.Immutable; -using System.IO; -using System.Text.Json; -using System.Text.Json.Serialization; -using System.Threading.Tasks; -using SerializationGenerator; - -namespace SerializationSchemaGenerator -{ - public static class Application - { - public static void Main(string[] args) - { - if (args.Length < 1) - { - throw new ArgumentException("Usage: dotnet SerializationSchemaGenerator.dll "); - } - - var solutionPath = args[0]; - - Parallel.ForEach( - SourceCodeAnalysis.GetCompilation(solutionPath), - (projectCompilation) => - { - var (project, compilation) = projectCompilation; - if (project.Name.EndsWith(".Tests", StringComparison.Ordinal) || project.Name == "Benchmarks") - { - return; - } - - var projectFile = new FileInfo(project.FilePath!); - var projectPath = projectFile.Directory?.FullName; - var migrationPath = Path.Join(projectPath, "Migrations"); - Directory.CreateDirectory(migrationPath); - - var syntaxReceiver = new SerializerSyntaxReceiver(); - - foreach (var syntaxTree in compilation.SyntaxTrees) - { - var root = syntaxTree.GetRoot(); - var syntaxVisitor = new SyntaxVisitor(compilation.GetSemanticModel(syntaxTree), syntaxReceiver); - syntaxVisitor.Visit(root); - } - - var jsonOptions = new JsonSerializerOptions - { - WriteIndented = true, - AllowTrailingCommas = true, - DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, - ReadCommentHandling = JsonCommentHandling.Skip - }; - - var serializableTypes = syntaxReceiver.SerializableList; - var embeddedSerializableTypes = syntaxReceiver.EmbeddedSerializableList; - - foreach (var (classSymbol, (attributeData, fieldsList)) in syntaxReceiver.ClassAndFields) - { - var source = compilation.GenerateSerializationPartialClass( - classSymbol, - attributeData, - migrationPath, - false, - jsonOptions, - fieldsList.ToImmutableArray(), - serializableTypes, - embeddedSerializableTypes - ); - } - - foreach (var (classSymbol, (attributeData, fieldsList)) in syntaxReceiver.EmbeddedClassAndFields) - { - var source = compilation.GenerateSerializationPartialClass( - classSymbol, - attributeData, - migrationPath, - true, - jsonOptions, - fieldsList.ToImmutableArray(), - serializableTypes, - embeddedSerializableTypes - ); - } - } - ); - } - } -} diff --git a/Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj b/Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj deleted file mode 100755 index 1df2df68a..000000000 --- a/Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj +++ /dev/null @@ -1,23 +0,0 @@ - - - Exe - Output - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - - - - diff --git a/Projects/SerializationSchemaGenerator/SourceCodeAnalysis.cs b/Projects/SerializationSchemaGenerator/SourceCodeAnalysis.cs deleted file mode 100644 index ac578b406..000000000 --- a/Projects/SerializationSchemaGenerator/SourceCodeAnalysis.cs +++ /dev/null @@ -1,49 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SourceCodeAnalysis.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using Microsoft.Build.Locator; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.MSBuild; - -namespace SerializationSchemaGenerator -{ - public static class SourceCodeAnalysis - { - public static List<(Project, Compilation)> GetCompilation(string solutionPath) - { - if (!File.Exists(solutionPath) || !solutionPath.EndsWith(".sln", StringComparison.Ordinal)) - { - throw new FileNotFoundException($"Could not open a valid solution at location {solutionPath}"); - } - - MSBuildLocator.RegisterDefaults(); - - var workspace = MSBuildWorkspace.Create(); - - var solutionToAnalyze = workspace.OpenSolutionAsync(solutionPath).Result; - - var results = solutionToAnalyze.Projects.AsParallel() - .Select((project) => (project, project?.GetCompilationAsync().Result)) - .Where((value) => value.Result != null) - .ToList(); - - return results; - } - } -} diff --git a/Projects/SerializationSchemaGenerator/SyntaxVisitor.cs b/Projects/SerializationSchemaGenerator/SyntaxVisitor.cs deleted file mode 100644 index 1e47733be..000000000 --- a/Projects/SerializationSchemaGenerator/SyntaxVisitor.cs +++ /dev/null @@ -1,52 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SyntaxVisitor.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.CSharp.Syntax; -using SerializationGenerator; - -namespace SerializationSchemaGenerator -{ - public class SyntaxVisitor : CSharpSyntaxWalker - { - private readonly SemanticModel _semanticModel; - private readonly SerializerSyntaxReceiver _syntaxReceiver; - - public SyntaxVisitor(SemanticModel semanticModel, SerializerSyntaxReceiver syntaxReceiver) - { - _semanticModel = semanticModel; - _syntaxReceiver = syntaxReceiver; - } - - public override void VisitClassDeclaration(ClassDeclarationSyntax node) - { - base.VisitClassDeclaration(node); - _syntaxReceiver.OnVisitSyntaxNode(node, _semanticModel); - } - - public override void VisitFieldDeclaration(FieldDeclarationSyntax node) - { - base.VisitFieldDeclaration(node); - _syntaxReceiver.OnVisitSyntaxNode(node, _semanticModel); - } - - public override void VisitPropertyDeclaration(PropertyDeclarationSyntax node) - { - base.VisitPropertyDeclaration(node); - _syntaxReceiver.OnVisitSyntaxNode(node, _semanticModel); - } - } -} diff --git a/Projects/Server/Server.csproj b/Projects/Server/Server.csproj index 5293d55e6..5f4e998c5 100755 --- a/Projects/Server/Server.csproj +++ b/Projects/Server/Server.csproj @@ -37,14 +37,8 @@ -
- - - TargetFramework=netstandard2.0 - Analyzer - false - all - + + diff --git a/Projects/UOContent/UOContent.csproj b/Projects/UOContent/UOContent.csproj index f260b9a4c..4981eed58 100755 --- a/Projects/UOContent/UOContent.csproj +++ b/Projects/UOContent/UOContent.csproj @@ -38,20 +38,14 @@ false - + - - - - TargetFramework=netstandard2.0 - Analyzer - false - all - + + diff --git a/publish.cmd b/publish.cmd index 0490b16a8..ffe8c6039 100755 --- a/publish.cmd +++ b/publish.cmd @@ -27,21 +27,19 @@ if [[ $os == *'centos'* || $os == *'rhel'* ]]; then export DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1 fi +echo dotnet tool restore +dotnet tool restore + echo dotnet clean --verbosity quiet dotnet clean --verbosity quiet echo dotnet restore --force-evaluate --source https://api.nuget.org/v3/index.json dotnet restore --force-evaluate --source https://api.nuget.org/v3/index.json -echo dotnet build -c Release Projects/SerializationGenerator/SerializationGenerator.csproj -dotnet build -c Release Projects/SerializationGenerator/SerializationGenerator.csproj - echo dotnet publish ${config} ${os} --no-restore --self-contained=false -o Distribution/Assemblies Projects/UOContent/UOContent.csproj dotnet publish ${config} ${os} --no-restore --self-contained=false -o Distribution/Assemblies Projects/UOContent/UOContent.csproj -echo dotnet build -c Release Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj -dotnet build -c Release Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj -echo Generating serialization schemas -dotnet Projects/SerializationSchemaGenerator/Output/SerializationSchemaGenerator.dll ModernUO.sln +echo Generating serialization migration schema... +dotnet tool run ModernUOSchemaGenerator ModernUO.sln exit $? @@ -63,18 +61,16 @@ IF "%~2" == "" ( SET os=-r %~2-x64 ) +echo dotnet tool restore +dotnet tool restore + echo dotnet clean --verbosity quiet dotnet clean --verbosity quiet echo dotnet restore --force-evaluate --source https://api.nuget.org/v3/index.json dotnet restore --force-evaluate --source https://api.nuget.org/v3/index.json -echo dotnet build -c Release Projects/SerializationGenerator/SerializationGenerator.csproj -dotnet build -c Release Projects/SerializationGenerator/SerializationGenerator.csproj - echo dotnet publish %config% %os% --no-restore --self-contained=false -o Distribution\Assemblies Projects\UOContent\UOContent.csproj dotnet publish %config% %os% --no-restore --self-contained=false -o Distribution\Assemblies Projects\UOContent\UOContent.csproj -echo dotnet build -c Release Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj -dotnet build -c Release Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj -echo Generating serialization schemas -dotnet Projects/SerializationSchemaGenerator/Output/SerializationSchemaGenerator.dll ModernUO.sln +echo Generating serialization migration schema... +dotnet tool run ModernUOSchemaGenerator ModernUO.sln From 202c4a99b782d12542374d0878d4a81903b9790e Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sat, 12 Feb 2022 21:22:03 -0800 Subject: [PATCH 071/213] fix: Fixes craft checks (#929) --- .../UOContent/Engines/Craft/Core/CraftItem.cs | 601 ++++++++---------- 1 file changed, 266 insertions(+), 335 deletions(-) diff --git a/Projects/UOContent/Engines/Craft/Core/CraftItem.cs b/Projects/UOContent/Engines/Craft/Core/CraftItem.cs index cece9b8dd..aab182f4c 100644 --- a/Projects/UOContent/Engines/Craft/Core/CraftItem.cs +++ b/Projects/UOContent/Engines/Craft/Core/CraftItem.cs @@ -449,7 +449,7 @@ namespace Server.Engines.Craft return contains; } - public bool IsQuantityType(Type[][] types) + public static bool IsQuantityType(Type[][] types) { for (int i = 0; i < types.Length; ++i) { @@ -487,13 +487,8 @@ namespace Server.Engines.Craft { totals[i] += items[i][j].Amount; } - else + else if (hq is not BaseBeverage beverage || beverage.Content == RequiredBeverage) { - if (hq is BaseBeverage beverage && beverage.Content != RequiredBeverage) - { - continue; - } - totals[i] += hq.Quantity; } } @@ -567,7 +562,7 @@ namespace Server.Engines.Craft } else { - if (hq is BaseBeverage beverage && beverage.Content != RequiredBeverage) + if ((hq as BaseBeverage)?.Content != RequiredBeverage) { continue; } @@ -651,14 +646,10 @@ namespace Server.Engines.Craft } } - if (types[i] == null) - { - types[i] = new[] { baseType }; - } - + types[i] ??= new[] { baseType }; amounts[i] = craftRes.Amount; - // For stackable items that can ben crafted more than one at a time + // For stackable items that can be crafted more than one at a time if (UseAllRes) { var tempAmount = ourPack.GetAmount(types[i]); @@ -725,79 +716,48 @@ namespace Server.Engines.Craft int index; - // Consume ALL - if (consumeType == ConsumeType.All) - { - m_ResHue = 0; - m_ResAmount = 0; - m_System = craftSystem; - - if (IsQuantityType(types)) - { - index = ConsumeQuantity(ourPack, types, amounts); - } - else - { - index = ourPack.ConsumeTotalGrouped(types, amounts, true, OnResourceConsumed, CheckHueGrouping); - } - - resHue = m_ResHue; - } - // Consume Half ( for use all resource craft type ) - else if (consumeType == ConsumeType.Half) - { - for (var i = 0; i < amounts.Length; i++) - { - amounts[i] /= 2; - - if (amounts[i] < 1) - { - amounts[i] = 1; - } - } - - m_ResHue = 0; - m_ResAmount = 0; - m_System = craftSystem; - - if (IsQuantityType(types)) - { - index = ConsumeQuantity(ourPack, types, amounts); - } - else - { - index = ourPack.ConsumeTotalGrouped(types, amounts, true, OnResourceConsumed, CheckHueGrouping); - } - - resHue = m_ResHue; - } - else // ConstumeType.None ( it's basically used to know if the crafter has enough resource before starting the process ) + if (consumeType == ConsumeType.None) { index = -1; // TODO: Optimize this - if (IsQuantityType(types)) + for (var i = 0; i < types.Length; i++) { - for (var i = 0; i < types.Length; i++) + var quantity = IsQuantityType(types) + ? GetQuantity(ourPack, types[i]) + : ourPack.GetBestGroupAmount(types[i], true, CheckHueGrouping); + + if (quantity < amounts[i]) { - if (GetQuantity(ourPack, types[i]) < amounts[i]) + index = i; + break; + } + } + } + else + { + if (consumeType == ConsumeType.Half) + { + for (var i = 0; i < amounts.Length; i++) + { + amounts[i] /= 2; + + if (amounts[i] < 1) { - index = i; - break; - } - else - { - for (var j = 0; j < types.Length; j++) - { - if (ourPack.GetBestGroupAmount(types[j], true, CheckHueGrouping) < amounts[j]) - { - index = j; - break; - } - } + amounts[i] = 1; } } } + + m_ResHue = 0; + m_ResAmount = 0; + m_System = craftSystem; + + index = IsQuantityType(types) + ? ConsumeQuantity(ourPack, types, amounts) + : ourPack.ConsumeTotalGrouped(types, amounts, true, OnResourceConsumed, CheckHueGrouping); + + resHue = m_ResHue; } if (index == -1) @@ -842,7 +802,7 @@ namespace Server.Engines.Craft } } - private int CheckHueGrouping(Item a, Item b) => b.Hue.CompareTo(a.Hue); + private static int CheckHueGrouping(Item a, Item b) => b.Hue.CompareTo(a.Hue); public double GetExceptionalChance(CraftSystem system, double chance, Mobile from) { @@ -859,18 +819,16 @@ namespace Server.Engines.Craft bonus = talisman.ExceptionalBonus / 100.0; } - switch (system.ECA) + chance = system.ECA switch { - default: - chance -= 0.6; - break; - case CraftECA.FiftyPercentChanceMinusTenPercent: - chance = chance * 0.5 - 0.1; - break; - case CraftECA.ChanceMinusSixtyToFourtyFive: - chance -= Math.Clamp(0.60 - (from.Skills[system.MainSkill].Value - 95.0) * 0.03, 0.45, 0.60); - break; - } + CraftECA.FiftyPercentChanceMinusTenPercent => chance * 0.5 - 0.1, + CraftECA.ChanceMinusSixtyToFourtyFive => chance - Math.Clamp( + 0.60 - (from.Skills[system.MainSkill].Value - 95.0) * 0.03, + 0.45, + 0.60 + ), + _ => chance - 0.6 + }; return chance > 0 ? chance + bonus : chance; } @@ -932,24 +890,20 @@ namespace Server.Engines.Craft } } - double chance; + if (!allRequiredSkills) + { + return 0; + } - if (allRequiredSkills) - { - chance = craftSystem.GetChanceAtMin(this) + (valMainSkill - minMainSkill) / (maxMainSkill - minMainSkill) * - (1.0 - craftSystem.GetChanceAtMin(this)); - } - else - { - chance = 0.0; - } + double chance = craftSystem.GetChanceAtMin(this) + (valMainSkill - minMainSkill) / (maxMainSkill - minMainSkill) * + (1.0 - craftSystem.GetChanceAtMin(this)); if (allRequiredSkills && from.Talisman is BaseTalisman talisman && talisman.Skill == craftSystem.MainSkill) { chance += talisman.SuccessBonus / 100.0; } - if (allRequiredSkills && valMainSkill == maxMainSkill) + if (allRequiredSkills && valMainSkill >= maxMainSkill) { chance = 1.0; } @@ -959,113 +913,98 @@ namespace Server.Engines.Craft public void Craft(Mobile from, CraftSystem craftSystem, Type typeRes, BaseTool tool) { - if (from.BeginAction()) - { - if (RequiredExpansion == Expansion.None || - from.NetState?.SupportsExpansion(RequiredExpansion) == true) - { - var chance = GetSuccessChance(from, typeRes, craftSystem, false, out var allRequiredSkills); - - if (allRequiredSkills && chance >= 0.0) - { - if (Recipe == null || (from as PlayerMobile)?.HasRecipe(Recipe) != false) - { - var badCraft = craftSystem.CanCraft(from, tool, ItemType); - - if (badCraft <= 0) - { - var resHue = 0; - var maxAmount = 0; - object message = null; - - if (ConsumeRes( - from, - typeRes, - craftSystem, - ref resHue, - ref maxAmount, - ConsumeType.None, - ref message - )) - { - message = null; - - if (ConsumeAttributes(from, ref message, false)) - { - var context = craftSystem.GetContext(from); - - context?.OnMade(this); - - var iMin = craftSystem.MinCraftEffect; - var iMax = craftSystem.MaxCraftEffect - iMin + 1; - var iRandom = Utility.Random(iMax); - iRandom += iMin + 1; - new InternalTimer(from, craftSystem, this, typeRes, tool, iRandom).Start(); - } - else - { - from.EndAction(); - from.SendGump(new CraftGump(from, craftSystem, tool, message)); - } - } - else - { - from.EndAction(); - from.SendGump(new CraftGump(from, craftSystem, tool, message)); - } - } - else - { - from.EndAction(); - from.SendGump(new CraftGump(from, craftSystem, tool, badCraft)); - } - } - else - { - from.EndAction(); - from.SendGump( - new CraftGump( - from, - craftSystem, - tool, - 1072847 // You must learn that recipe from a scroll. - ) - ); - } - } - else - { - from.EndAction(); - from.SendGump( - new CraftGump( - from, - craftSystem, - tool, - 1044153 // You don't have the required skills to attempt this item. - ) - ); - } - } - else - { - from.EndAction(); - from.SendGump( - new CraftGump( - from, - craftSystem, - tool, - RequiredExpansionMessage(RequiredExpansion) // The {0} expansion is required to attempt this item. - ) - ); - } - } - else + if (!from.BeginAction()) { from.SendLocalizedMessage(500119); // You must wait to perform another action + return; } + + if (RequiredExpansion != Expansion.None && from.NetState?.SupportsExpansion(RequiredExpansion) != true) + { + from.EndAction(); + from.SendGump( + new CraftGump( + from, + craftSystem, + tool, + // The {0} expansion is required to attempt this item. + RequiredExpansionMessage(RequiredExpansion) + ) + ); + return; + } + + var chance = GetSuccessChance(from, typeRes, craftSystem, false, out var allRequiredSkills); + + if (!allRequiredSkills || !(chance >= 0.0)) + { + from.EndAction(); + from.SendGump( + new CraftGump( + from, + craftSystem, + tool, + 1044153 // You don't have the required skills to attempt this item. + ) + ); + return; + } + + if (Recipe != null && (from as PlayerMobile)?.HasRecipe(Recipe) == false) + { + from.EndAction(); + from.SendGump( + new CraftGump( + from, + craftSystem, + tool, + 1072847 // You must learn that recipe from a scroll. + ) + ); + return; + } + + var badCraft = craftSystem.CanCraft(from, tool, ItemType); + + if (badCraft > 0) + { + from.EndAction(); + from.SendGump(new CraftGump(from, craftSystem, tool, badCraft)); + return; + } + + var resHue = 0; + var maxAmount = 0; + object message = null; + + if (!ConsumeRes(from, typeRes, craftSystem, ref resHue, ref maxAmount, ConsumeType.None, ref message)) + { + from.EndAction(); + from.SendGump(new CraftGump(from, craftSystem, tool, message)); + return; + } + + message = null; + + if (!ConsumeAttributes(from, ref message, false)) + { + from.EndAction(); + from.SendGump(new CraftGump(from, craftSystem, tool, message)); + return; + } + + var context = craftSystem.GetContext(from); + + context?.OnMade(this); + + var iMin = craftSystem.MinCraftEffect; + var iMax = craftSystem.MaxCraftEffect - iMin + 1; + var iRandom = Utility.Random(iMax); + iRandom += iMin + 1; + new InternalTimer(from, craftSystem, this, typeRes, tool, iRandom).Start(); } - private TextDefinition RequiredExpansionMessage(Expansion expansion) + private static TextDefinition RequiredExpansionMessage(Expansion expansion) { return expansion switch { @@ -1131,15 +1070,13 @@ namespace Server.Engines.Craft var ignored = 1; var endquality = 1; + var resHue = 0; + var maxAmount = 0; + object message = null; + var num = 0; if (CheckSkills(from, typeRes, craftSystem, ref ignored, out var allRequiredSkills)) { - // Resource - var resHue = 0; - var maxAmount = 0; - - object message = null; - // Not enough resource to craft it if (!(ConsumeRes(from, typeRes, craftSystem, ref resHue, ref maxAmount, ConsumeType.All, ref message) && ConsumeAttributes(from, ref message, true))) @@ -1162,15 +1099,13 @@ namespace Server.Engines.Craft tool.UsesRemaining--; - if (craftSystem is DefBlacksmithy) + if (craftSystem is DefBlacksmithy && + from.FindItemOnLayer(Layer.OneHanded) is AncientSmithyHammer hammer && hammer != tool) { - if (from.FindItemOnLayer(Layer.OneHanded) is AncientSmithyHammer hammer && hammer != tool) + hammer.UsesRemaining--; + if (hammer.UsesRemaining < 1) { - hammer.UsesRemaining--; - if (hammer.UsesRemaining < 1) - { - hammer.Delete(); - } + hammer.Delete(); } } @@ -1184,8 +1119,6 @@ namespace Server.Engines.Craft tool.Delete(); } - var num = 0; - Item item; if (customCraft != null) { @@ -1305,8 +1238,11 @@ namespace Server.Engines.Craft { from.SendLocalizedMessage(num); } + + return; } - else if (!allRequiredSkills) + + if (!allRequiredSkills) { if (tool?.Deleted == false && tool.UsesRemaining > 0) { @@ -1316,57 +1252,53 @@ namespace Server.Engines.Craft { from.SendLocalizedMessage(1044153); // You don't have the required skills to attempt this item. } + + return; } - else + + var consumeType = UseAllRes ? ConsumeType.Half : ConsumeType.All; + + // Not enough resource to craft it + if (!ConsumeRes(from, typeRes, craftSystem, ref resHue, ref maxAmount, consumeType, ref message, true)) { - var consumeType = UseAllRes ? ConsumeType.Half : ConsumeType.All; - var resHue = 0; - var maxAmount = 0; - - object message = null; - - // Not enough resource to craft it - if (!ConsumeRes(from, typeRes, craftSystem, ref resHue, ref maxAmount, consumeType, ref message, true)) + if (tool?.Deleted == false && tool.UsesRemaining > 0) { - if (tool?.Deleted == false && tool.UsesRemaining > 0) - { - from.SendGump(new CraftGump(from, craftSystem, tool, message)); - } - else if (message is int messageInt && messageInt > 0) - { - from.SendLocalizedMessage(messageInt); - } - else - { - from.SendMessage(message.ToString()); - } - - return; + from.SendGump(new CraftGump(from, craftSystem, tool, message)); + } + else if (message is int messageInt && messageInt > 0) + { + from.SendLocalizedMessage(messageInt); + } + else + { + from.SendMessage(message.ToString()); } - tool.UsesRemaining--; + return; + } - if (tool.UsesRemaining < 1 && tool.BreakOnDepletion) - { - toolBroken = true; - } + tool.UsesRemaining--; - if (toolBroken) - { - tool.Delete(); - } + if (tool.UsesRemaining < 1 && tool.BreakOnDepletion) + { + toolBroken = true; + } - // SkillCheck failed. - var num = craftSystem.PlayEndingEffect(from, true, true, toolBroken, endquality, false, this); + if (toolBroken) + { + tool.Delete(); + } - if (!tool.Deleted && tool.UsesRemaining > 0) - { - from.SendGump(new CraftGump(from, craftSystem, tool, num)); - } - else if (num > 0) - { - from.SendLocalizedMessage(num); - } + // SkillCheck failed. + num = craftSystem.PlayEndingEffect(from, true, true, toolBroken, endquality, false, this); + + if (!tool.Deleted && tool.UsesRemaining > 0) + { + from.SendGump(new CraftGump(from, craftSystem, tool, num)); + } + else if (num > 0) + { + from.SendLocalizedMessage(num); } } @@ -1403,88 +1335,87 @@ namespace Server.Engines.Craft if (m_iCount < m_iCountMax) { m_CraftSystem.PlayCraftEffect(m_From); + return; } - else + + m_From.EndAction(); + + var badCraft = m_CraftSystem.CanCraft(m_From, m_Tool, m_CraftItem.ItemType); + + if (badCraft > 0) { - m_From.EndAction(); - - var badCraft = m_CraftSystem.CanCraft(m_From, m_Tool, m_CraftItem.ItemType); - - if (badCraft > 0) + if (m_Tool?.Deleted == false && m_Tool.UsesRemaining > 0) { - if (m_Tool?.Deleted == false && m_Tool.UsesRemaining > 0) - { - m_From.SendGump(new CraftGump(m_From, m_CraftSystem, m_Tool, badCraft)); - } - else - { - m_From.SendLocalizedMessage(badCraft); - } - - return; - } - - var quality = 1; - - m_CraftItem.CheckSkills(m_From, m_TypeRes, m_CraftSystem, ref quality, out _, false); - - var context = m_CraftSystem.GetContext(m_From); - - if (context == null) - { - return; - } - - if (typeof(CustomCraft).IsAssignableFrom(m_CraftItem.ItemType)) - { - try - { - m_CraftItem.ItemType.CreateInstance( - m_From, - m_CraftItem, - m_CraftSystem, - m_TypeRes, - m_Tool, - quality - )?.EndCraftAction(); - } - catch (Exception e) - { - Console.WriteLine(e); - } - - return; - } - - var makersMark = false; - - if (quality == 2 && m_From.Skills[m_CraftSystem.MainSkill].Base >= 100.0) - { - makersMark = m_CraftItem.IsMarkable(m_CraftItem.ItemType); - } - - if (makersMark && context.MarkOption == CraftMarkOption.PromptForMark) - { - m_From.SendGump( - new QueryMakersMarkGump( - quality, - m_From, - m_CraftItem, - m_CraftSystem, - m_TypeRes, - m_Tool - ) - ); + m_From.SendGump(new CraftGump(m_From, m_CraftSystem, m_Tool, badCraft)); } else { - if (context.MarkOption == CraftMarkOption.DoNotMark) - { - makersMark = false; - } - - m_CraftItem.CompleteCraft(quality, makersMark, m_From, m_CraftSystem, m_TypeRes, m_Tool, null); + m_From.SendLocalizedMessage(badCraft); } + + return; + } + + var quality = 1; + + m_CraftItem.CheckSkills(m_From, m_TypeRes, m_CraftSystem, ref quality, out _, false); + + var context = m_CraftSystem.GetContext(m_From); + + if (context == null) + { + return; + } + + if (typeof(CustomCraft).IsAssignableFrom(m_CraftItem.ItemType)) + { + try + { + m_CraftItem.ItemType.CreateInstance( + m_From, + m_CraftItem, + m_CraftSystem, + m_TypeRes, + m_Tool, + quality + )?.EndCraftAction(); + } + catch (Exception e) + { + Console.WriteLine(e); + } + + return; + } + + var makersMark = false; + + if (quality == 2 && m_From.Skills[m_CraftSystem.MainSkill].Base >= 100.0) + { + makersMark = m_CraftItem.IsMarkable(m_CraftItem.ItemType); + } + + if (makersMark && context.MarkOption == CraftMarkOption.PromptForMark) + { + m_From.SendGump( + new QueryMakersMarkGump( + quality, + m_From, + m_CraftItem, + m_CraftSystem, + m_TypeRes, + m_Tool + ) + ); + } + else + { + if (context.MarkOption == CraftMarkOption.DoNotMark) + { + makersMark = false; + } + + m_CraftItem.CompleteCraft(quality, makersMark, m_From, m_CraftSystem, m_TypeRes, m_Tool, null); } } } From d7786ce586bcfdcf91d40200fe339b2376e9b3a8 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sat, 12 Feb 2022 22:42:50 -0800 Subject: [PATCH 072/213] fix: Fixes TextDefinition and optimizes CraftItem (#930) --- .../Data/Decoration/Britannia/wind.cfg | 2 +- .../UOContent/Engines/ConPVP/DuelContext.cs | 2 +- .../UOContent/Engines/Craft/Core/CraftGump.cs | 38 ++++++------- .../Engines/Craft/Core/CraftGumpItem.cs | 20 +++---- .../UOContent/Engines/Craft/Core/CraftItem.cs | 53 ++++++++++--------- .../UOContent/Engines/Craft/Core/CraftRes.cs | 23 +++----- .../Engines/Craft/Core/CraftSubRes.cs | 13 ++--- .../Engines/Craft/Core/CraftSubResCol.cs | 4 +- .../Engines/Craft/Core/CraftSystem.cs | 45 ++++------------ .../UOContent/Engines/Craft/Core/Enhance.cs | 4 +- .../UOContent/Engines/Craft/DefAlchemy.cs | 2 +- .../UOContent/Engines/Craft/DefBlacksmithy.cs | 2 +- .../Engines/Craft/DefBowFletching.cs | 2 +- .../UOContent/Engines/Craft/DefCarpentry.cs | 2 +- .../UOContent/Engines/Craft/DefCartography.cs | 2 +- .../UOContent/Engines/Craft/DefCooking.cs | 2 +- .../Engines/Craft/DefGlassblowing.cs | 2 +- .../UOContent/Engines/Craft/DefInscription.cs | 2 +- .../UOContent/Engines/Craft/DefMasonry.cs | 2 +- .../UOContent/Engines/Craft/DefTailoring.cs | 2 +- .../UOContent/Engines/Craft/DefTinkering.cs | 2 +- .../UOContent/Engines/Doom/GenGauntlet.cs | 2 +- .../Factions/Gumps/FactionImbueGump.cs | 12 ++--- .../Engines/Harvest/Core/HarvestResource.cs | 10 ++-- Projects/UOContent/Gumps/NoticeGump.cs | 10 ++-- Projects/UOContent/Gumps/WarningGump.cs | 12 ++--- .../Skill Items/Magical/Misc/Moongate.cs | 39 ++++++++------ 27 files changed, 138 insertions(+), 173 deletions(-) diff --git a/Distribution/Data/Decoration/Britannia/wind.cfg b/Distribution/Data/Decoration/Britannia/wind.cfg index 695d46747..93746ee8a 100644 --- a/Distribution/Data/Decoration/Britannia/wind.cfg +++ b/Distribution/Data/Decoration/Britannia/wind.cfg @@ -770,4 +770,4 @@ Static 0x1F3C # Arch Cure Static 0x1F45 -5304 88 19 \ No newline at end of file +5304 88 19 diff --git a/Projects/UOContent/Engines/ConPVP/DuelContext.cs b/Projects/UOContent/Engines/ConPVP/DuelContext.cs index 9e763c767..8217c5af8 100644 --- a/Projects/UOContent/Engines/ConPVP/DuelContext.cs +++ b/Projects/UOContent/Engines/ConPVP/DuelContext.cs @@ -2749,7 +2749,7 @@ namespace Server.Engines.ConPVP GumpWidth = 300; GumpHeight = 150; MessageColor = 0xFFC000; - MessageString = "Are you sure you wish to spectate this duel?"; + Message = "Are you sure you wish to spectate this duel?"; TitleColor = 0x7800; TitleNumber = 1062051; // Gate Warning diff --git a/Projects/UOContent/Engines/Craft/Core/CraftGump.cs b/Projects/UOContent/Engines/Craft/Core/CraftGump.cs index 9feeadb5a..653444076 100644 --- a/Projects/UOContent/Engines/Craft/Core/CraftGump.cs +++ b/Projects/UOContent/Engines/Craft/Core/CraftGump.cs @@ -24,7 +24,7 @@ namespace Server.Engines.Craft private readonly BaseTool m_Tool; public CraftGump( - Mobile from, CraftSystem craftSystem, BaseTool tool, object notice, CraftPage page = CraftPage.None + Mobile from, CraftSystem craftSystem, BaseTool tool, TextDefinition notice, CraftPage page = CraftPage.None ) : base(40, 40) { m_From = from; @@ -48,13 +48,13 @@ namespace Server.Engines.Craft AddImageTiled(215, 37, 305, 250, 2624); AddAlphaRegion(10, 10, 510, 417); - if (craftSystem.GumpTitleNumber > 0) + if (craftSystem.GumpTitle.Number > 0) { - AddHtmlLocalized(10, 12, 510, 20, craftSystem.GumpTitleNumber, LabelColor); + AddHtmlLocalized(10, 12, 510, 20, craftSystem.GumpTitle.Number, LabelColor); } else { - AddHtml(10, 12, 510, 20, craftSystem.GumpTitleString); + AddHtml(10, 12, 510, 20, craftSystem.GumpTitle.String); } AddHtmlLocalized(10, 37, 200, 22, 1044010, LabelColor); //
CATEGORIES
@@ -106,20 +106,20 @@ namespace Server.Engines.Craft } // **************************************** - if (notice is int noticeInt && noticeInt > 0) + if (notice.Number > 0) { - AddHtmlLocalized(170, 295, 350, 40, noticeInt, LabelColor); + AddHtmlLocalized(170, 295, 350, 40, notice.Number, LabelColor); } - else if (notice is string) + else { - AddHtml(170, 295, 350, 40, $"{notice}"); + AddHtml(170, 295, 350, 40, $"{notice.String}"); } // If the system has more than one resource if (craftSystem.CraftSubRes.Init) { - var nameString = craftSystem.CraftSubRes.NameString; - var nameNumber = craftSystem.CraftSubRes.NameNumber; + var nameString = craftSystem.CraftSubRes.Name.String; + var nameNumber = craftSystem.CraftSubRes.Name.Number; var resIndex = context?.LastResourceIndex ?? -1; @@ -129,8 +129,8 @@ namespace Server.Engines.Craft { var subResource = craftSystem.CraftSubRes.GetAt(resIndex); - nameString = subResource.NameString; - nameNumber = subResource.NameNumber; + nameString = subResource.Name.String; + nameNumber = subResource.Name.Number; resourceType = subResource.ItemType; } @@ -162,8 +162,8 @@ namespace Server.Engines.Craft // For dragon scales if (craftSystem.CraftSubRes2.Init) { - var nameString = craftSystem.CraftSubRes2.NameString; - var nameNumber = craftSystem.CraftSubRes2.NameNumber; + var nameString = craftSystem.CraftSubRes2.Name.String; + var nameNumber = craftSystem.CraftSubRes2.Name.Number; var resIndex = context?.LastResourceIndex2 ?? -1; @@ -173,8 +173,8 @@ namespace Server.Engines.Craft { var subResource = craftSystem.CraftSubRes2.GetAt(resIndex); - nameString = subResource.NameString; - nameNumber = subResource.NameNumber; + nameString = subResource.Name.String; + nameNumber = subResource.Name.Number; resourceType = subResource.ItemType; } @@ -270,21 +270,21 @@ namespace Server.Engines.Craft AddButton(220, 60 + index * 20, 4005, 4007, GetButtonID(5, i)); - if (subResource.NameNumber > 0) + if (subResource.Name.Number > 0) { AddHtmlLocalized( 255, 63 + index * 20, 250, 18, - subResource.NameNumber, + subResource.Name.Number, resourceCount.ToString(), LabelColor ); } else { - AddLabel(255, 60 + index * 20, LabelHue, $"{subResource.NameString} ({resourceCount})"); + AddLabel(255, 60 + index * 20, LabelHue, $"{subResource.Name.String} ({resourceCount})"); } } } diff --git a/Projects/UOContent/Engines/Craft/Core/CraftGumpItem.cs b/Projects/UOContent/Engines/Craft/Core/CraftGumpItem.cs index ec0a307e5..ad8ccfd87 100644 --- a/Projects/UOContent/Engines/Craft/Core/CraftGumpItem.cs +++ b/Projects/UOContent/Engines/Craft/Core/CraftGumpItem.cs @@ -58,13 +58,13 @@ namespace Server.Engines.Craft AddHtmlLocalized(10, 277, 150, 22, 1044055, LabelColor); //
MATERIALS
AddHtmlLocalized(10, 362, 150, 22, 1044056, LabelColor); //
OTHER
- if (craftSystem.GumpTitleNumber > 0) + if (craftSystem.GumpTitle.Number > 0) { - AddHtmlLocalized(10, 12, 510, 20, craftSystem.GumpTitleNumber, LabelColor); + AddHtmlLocalized(10, 12, 510, 20, craftSystem.GumpTitle.Number, LabelColor); } else { - AddHtml(10, 12, 510, 20, craftSystem.GumpTitleString); + AddHtml(10, 12, 510, 20, craftSystem.GumpTitle.String); } AddButton(15, 387, 4014, 4016, 0); @@ -230,15 +230,11 @@ namespace Server.Engines.Craft for (var i = 0; i < m_CraftItem.Resources.Count - (cropScroll ? 1 : 0) && i < 4; i++) { - Type type; - string nameString; - int nameNumber; - var craftResource = m_CraftItem.Resources[i]; - type = craftResource.ItemType; - nameString = craftResource.NameString; - nameNumber = craftResource.NameNumber; + var type = craftResource.ItemType; + var nameString = craftResource.Name.String; + var nameNumber = craftResource.Name.Number; // Resource Mutation if (type == res.ResType && resIndex > -1) @@ -247,12 +243,12 @@ namespace Server.Engines.Craft type = subResource.ItemType; - nameString = subResource.NameString; + nameString = subResource.Name.String; nameNumber = subResource.GenericNameNumber; if (nameNumber <= 0) { - nameNumber = subResource.NameNumber; + nameNumber = subResource.Name.Number; } } // ****************** diff --git a/Projects/UOContent/Engines/Craft/Core/CraftItem.cs b/Projects/UOContent/Engines/Craft/Core/CraftItem.cs index aab182f4c..9e738f8dc 100644 --- a/Projects/UOContent/Engines/Craft/Core/CraftItem.cs +++ b/Projects/UOContent/Engines/Craft/Core/CraftItem.cs @@ -279,7 +279,7 @@ namespace Server.Engines.Craft Skills.Add(craftSkill); } - public bool ConsumeAttributes(Mobile from, ref object message, bool consume) + public bool ConsumeAttributes(Mobile from, ref TextDefinition message, bool consume) { bool consumMana; bool consumHits; @@ -393,7 +393,7 @@ namespace Server.Engines.Craft return inResourceTable; } - public bool Find(Mobile from, int[] itemIDs) + public static bool Find(Mobile from, int[] itemIDs) { var map = from.Map; @@ -474,6 +474,7 @@ namespace Server.Engines.Craft throw new ArgumentOutOfRangeException(nameof(types)); } + // TODO: Optimize allocation var items = new Item[types.Length][]; var totals = new int[types.Length]; @@ -576,13 +577,13 @@ namespace Server.Engines.Craft public bool ConsumeRes( Mobile from, Type typeRes, CraftSystem craftSystem, ref int resHue, ref int maxAmount, - ConsumeType consumeType, ref object message + ConsumeType consumeType, ref TextDefinition message ) => ConsumeRes(from, typeRes, craftSystem, ref resHue, ref maxAmount, consumeType, ref message, false); public bool ConsumeRes( Mobile from, Type typeRes, CraftSystem craftSystem, ref int resHue, ref int maxAmount, - ConsumeType consumeType, ref object message, bool isFailure + ConsumeType consumeType, ref TextDefinition message, bool isFailure ) { var ourPack = from.Backpack; @@ -662,13 +663,13 @@ namespace Server.Engines.Craft { res = Resources[i]; - if (res.MessageNumber > 0) + if (res.Message.Number > 0) { - message = res.MessageNumber; + message = res.Message.Number; } - else if (!string.IsNullOrEmpty(res.MessageString)) + else if (!string.IsNullOrEmpty(res.Message.String)) { - message = res.MessageString; + message = res.Message.String; } else { @@ -720,10 +721,12 @@ namespace Server.Engines.Craft { index = -1; + var isQuantityType = IsQuantityType(types); + // TODO: Optimize this for (var i = 0; i < types.Length; i++) { - var quantity = IsQuantityType(types) + var quantity = isQuantityType ? GetQuantity(ourPack, types[i]) : ourPack.GetBestGroupAmount(types[i], true, CheckHueGrouping); @@ -772,13 +775,13 @@ namespace Server.Engines.Craft res = Resources[index]; - if (res.MessageNumber > 0) + if (res.Message.Number > 0) { - message = res.MessageNumber; + message = res.Message.Number; } - else if (!string.IsNullOrEmpty(res.MessageString)) + else if (!string.IsNullOrEmpty(res.Message.String)) { - message = res.MessageString; + message = res.Message.String; } else { @@ -975,7 +978,7 @@ namespace Server.Engines.Craft var resHue = 0; var maxAmount = 0; - object message = null; + TextDefinition message = null; if (!ConsumeRes(from, typeRes, craftSystem, ref resHue, ref maxAmount, ConsumeType.None, ref message)) { @@ -1036,7 +1039,7 @@ namespace Server.Engines.Craft } int checkResHue = 0, checkMaxAmount = 0; - object checkMessage = null; + TextDefinition checkMessage = null; // Not enough resource to craft it if (!(ConsumeRes( @@ -1054,13 +1057,13 @@ namespace Server.Engines.Craft { from.SendGump(new CraftGump(from, craftSystem, tool, checkMessage)); } - else if (checkMessage is int messageInt && messageInt > 0) + else if (checkMessage.Number > 0) { - from.SendLocalizedMessage(messageInt); + from.SendLocalizedMessage(checkMessage.Number); } else { - from.SendMessage(checkMessage.ToString()); + from.SendMessage(checkMessage.String); } return; @@ -1072,7 +1075,7 @@ namespace Server.Engines.Craft var endquality = 1; var resHue = 0; var maxAmount = 0; - object message = null; + TextDefinition message = null; var num = 0; if (CheckSkills(from, typeRes, craftSystem, ref ignored, out var allRequiredSkills)) @@ -1085,13 +1088,13 @@ namespace Server.Engines.Craft { from.SendGump(new CraftGump(from, craftSystem, tool, message)); } - else if (message is int messageIn && messageIn > 0) + else if (message.Number > 0) { - from.SendLocalizedMessage(messageIn); + from.SendLocalizedMessage(message.Number); } else { - from.SendMessage(message.ToString()); + from.SendMessage(message.String); } return; @@ -1265,13 +1268,13 @@ namespace Server.Engines.Craft { from.SendGump(new CraftGump(from, craftSystem, tool, message)); } - else if (message is int messageInt && messageInt > 0) + else if (message.Number > 0) { - from.SendLocalizedMessage(messageInt); + from.SendLocalizedMessage(message.Number); } else { - from.SendMessage(message.ToString()); + from.SendMessage(message.String); } return; diff --git a/Projects/UOContent/Engines/Craft/Core/CraftRes.cs b/Projects/UOContent/Engines/Craft/Core/CraftRes.cs index b4f60eb5c..f3fd089e6 100644 --- a/Projects/UOContent/Engines/Craft/Core/CraftRes.cs +++ b/Projects/UOContent/Engines/Craft/Core/CraftRes.cs @@ -9,34 +9,27 @@ namespace Server.Engines.Craft ItemType = type; Amount = amount; - NameNumber = name; - MessageNumber = message; - - NameString = name; - MessageString = message; + Name = name; + Message = message; } public Type ItemType { get; } - public string MessageString { get; } + public TextDefinition Message { get; } - public int MessageNumber { get; } - - public string NameString { get; } - - public int NameNumber { get; } + public TextDefinition Name { get; } public int Amount { get; } public void SendMessage(Mobile from) { - if (MessageNumber > 0) + if (Message.Number > 0) { - from.SendLocalizedMessage(MessageNumber); + from.SendLocalizedMessage(Message.Number); } - else if (!string.IsNullOrEmpty(MessageString)) + else if (!string.IsNullOrEmpty(Message.String)) { - from.SendMessage(MessageString); + from.SendMessage(Message.String); } else { diff --git a/Projects/UOContent/Engines/Craft/Core/CraftSubRes.cs b/Projects/UOContent/Engines/Craft/Core/CraftSubRes.cs index c0c552029..69d4768b2 100644 --- a/Projects/UOContent/Engines/Craft/Core/CraftSubRes.cs +++ b/Projects/UOContent/Engines/Craft/Core/CraftSubRes.cs @@ -4,7 +4,7 @@ namespace Server.Engines.Craft { public class CraftSubRes { - public CraftSubRes(Type type, TextDefinition name, double reqSkill, object message) : this( + public CraftSubRes(Type type, TextDefinition name, double reqSkill, TextDefinition message) : this( type, name, reqSkill, @@ -14,11 +14,10 @@ namespace Server.Engines.Craft { } - public CraftSubRes(Type type, TextDefinition name, double reqSkill, int genericNameNumber, object message) + public CraftSubRes(Type type, TextDefinition name, double reqSkill, int genericNameNumber, TextDefinition message) { ItemType = type; - NameNumber = name; - NameString = name; + Name = name; RequiredSkill = reqSkill; GenericNameNumber = genericNameNumber; Message = message; @@ -26,13 +25,11 @@ namespace Server.Engines.Craft public Type ItemType { get; } - public string NameString { get; } - - public int NameNumber { get; } + public TextDefinition Name { get; } public int GenericNameNumber { get; } - public object Message { get; } + public TextDefinition Message { get; } public double RequiredSkill { get; } } diff --git a/Projects/UOContent/Engines/Craft/Core/CraftSubResCol.cs b/Projects/UOContent/Engines/Craft/Core/CraftSubResCol.cs index 2079f9e0b..b52ad86ad 100644 --- a/Projects/UOContent/Engines/Craft/Core/CraftSubResCol.cs +++ b/Projects/UOContent/Engines/Craft/Core/CraftSubResCol.cs @@ -11,9 +11,7 @@ namespace Server.Engines.Craft public Type ResType { get; set; } - public string NameString { get; set; } - - public int NameNumber { get; set; } + public TextDefinition Name { get; set; } public CraftSubRes GetAt(int index) => this[index]; diff --git a/Projects/UOContent/Engines/Craft/Core/CraftSystem.cs b/Projects/UOContent/Engines/Craft/Core/CraftSystem.cs index 4b00e03e3..1805aeed3 100644 --- a/Projects/UOContent/Engines/Craft/Core/CraftSystem.cs +++ b/Projects/UOContent/Engines/Craft/Core/CraftSystem.cs @@ -50,8 +50,7 @@ namespace Server.Engines.Craft public abstract SkillName MainSkill { get; } - public virtual int GumpTitleNumber => 0; - public virtual string GumpTitleString => ""; + public virtual TextDefinition GumpTitle => 0; public virtual CraftECA ECA => CraftECA.ChanceMinusSixty; @@ -269,65 +268,39 @@ namespace Server.Engines.Craft CraftItems[index].ForceNonExceptional = true; } - public void SetSubRes(Type type, string name) + public void SetSubRes(Type type, TextDefinition name) { CraftSubRes.ResType = type; - CraftSubRes.NameString = name; + CraftSubRes.Name = name; CraftSubRes.Init = true; } - public void SetSubRes(Type type, int name) - { - CraftSubRes.ResType = type; - CraftSubRes.NameNumber = name; - CraftSubRes.Init = true; - } - - public void AddSubRes(Type type, int name, double reqSkill, object message) - { - var craftSubRes = new CraftSubRes(type, name, reqSkill, message); - CraftSubRes.Add(craftSubRes); - } - - public void AddSubRes(Type type, int name, double reqSkill, int genericName, object message) + public void AddSubRes(Type type, TextDefinition name, double reqSkill, int genericName, TextDefinition message) { var craftSubRes = new CraftSubRes(type, name, reqSkill, genericName, message); CraftSubRes.Add(craftSubRes); } - public void AddSubRes(Type type, string name, double reqSkill, object message) + public void AddSubRes(Type type, TextDefinition name, double reqSkill, TextDefinition message) { var craftSubRes = new CraftSubRes(type, name, reqSkill, message); CraftSubRes.Add(craftSubRes); } - public void SetSubRes2(Type type, string name) + public void SetSubRes2(Type type, TextDefinition name) { CraftSubRes2.ResType = type; - CraftSubRes2.NameString = name; + CraftSubRes2.Name = name; CraftSubRes2.Init = true; } - public void SetSubRes2(Type type, int name) - { - CraftSubRes2.ResType = type; - CraftSubRes2.NameNumber = name; - CraftSubRes2.Init = true; - } - - public void AddSubRes2(Type type, int name, double reqSkill, object message) - { - var craftSubRes = new CraftSubRes(type, name, reqSkill, message); - CraftSubRes2.Add(craftSubRes); - } - - public void AddSubRes2(Type type, int name, double reqSkill, int genericName, object message) + public void AddSubRes2(Type type, TextDefinition name, double reqSkill, int genericName, TextDefinition message) { var craftSubRes = new CraftSubRes(type, name, reqSkill, genericName, message); CraftSubRes2.Add(craftSubRes); } - public void AddSubRes2(Type type, string name, double reqSkill, object message) + public void AddSubRes2(Type type, TextDefinition name, double reqSkill, TextDefinition message) { var craftSubRes = new CraftSubRes(type, name, reqSkill, message); CraftSubRes2.Add(craftSubRes); diff --git a/Projects/UOContent/Engines/Craft/Core/Enhance.cs b/Projects/UOContent/Engines/Craft/Core/Enhance.cs index c5a6c0377..2ba478f5d 100644 --- a/Projects/UOContent/Engines/Craft/Core/Enhance.cs +++ b/Projects/UOContent/Engines/Craft/Core/Enhance.cs @@ -22,7 +22,7 @@ namespace Server.Engines.Craft { public static EnhanceResult Invoke( Mobile from, CraftSystem craftSystem, BaseTool tool, Item item, - CraftResource resource, Type resType, ref object resMessage + CraftResource resource, Type resType, ref TextDefinition resMessage ) { if (item == null) @@ -410,7 +410,7 @@ namespace Server.Engines.Craft { if (targeted is Item item) { - object message = null; + TextDefinition message = null; var res = Enhance.Invoke( from, m_CraftSystem, diff --git a/Projects/UOContent/Engines/Craft/DefAlchemy.cs b/Projects/UOContent/Engines/Craft/DefAlchemy.cs index 0d1b66311..d74f9ff2e 100644 --- a/Projects/UOContent/Engines/Craft/DefAlchemy.cs +++ b/Projects/UOContent/Engines/Craft/DefAlchemy.cs @@ -15,7 +15,7 @@ namespace Server.Engines.Craft public override SkillName MainSkill => SkillName.Alchemy; - public override int GumpTitleNumber => 1044001; + public override TextDefinition GumpTitle => 1044001; public static CraftSystem CraftSystem => m_CraftSystem ??= new DefAlchemy(); diff --git a/Projects/UOContent/Engines/Craft/DefBlacksmithy.cs b/Projects/UOContent/Engines/Craft/DefBlacksmithy.cs index b470983f2..a571c7461 100644 --- a/Projects/UOContent/Engines/Craft/DefBlacksmithy.cs +++ b/Projects/UOContent/Engines/Craft/DefBlacksmithy.cs @@ -28,7 +28,7 @@ namespace Server.Engines.Craft public override SkillName MainSkill => SkillName.Blacksmith; - public override int GumpTitleNumber => 1044002; + public override TextDefinition GumpTitle => 1044002; public static CraftSystem CraftSystem => m_CraftSystem ??= new DefBlacksmithy(); diff --git a/Projects/UOContent/Engines/Craft/DefBowFletching.cs b/Projects/UOContent/Engines/Craft/DefBowFletching.cs index ac042499c..1625c92ef 100644 --- a/Projects/UOContent/Engines/Craft/DefBowFletching.cs +++ b/Projects/UOContent/Engines/Craft/DefBowFletching.cs @@ -13,7 +13,7 @@ namespace Server.Engines.Craft public override SkillName MainSkill => SkillName.Fletching; - public override int GumpTitleNumber => 1044006; + public override TextDefinition GumpTitle => 1044006; public static CraftSystem CraftSystem => m_CraftSystem ??= new DefBowFletching(); diff --git a/Projects/UOContent/Engines/Craft/DefCarpentry.cs b/Projects/UOContent/Engines/Craft/DefCarpentry.cs index 95e1a76f6..e46c1b9d7 100644 --- a/Projects/UOContent/Engines/Craft/DefCarpentry.cs +++ b/Projects/UOContent/Engines/Craft/DefCarpentry.cs @@ -13,7 +13,7 @@ namespace Server.Engines.Craft public override SkillName MainSkill => SkillName.Carpentry; - public override int GumpTitleNumber => 1044004; + public override TextDefinition GumpTitle => 1044004; public static CraftSystem CraftSystem => m_CraftSystem ??= new DefCarpentry(); diff --git a/Projects/UOContent/Engines/Craft/DefCartography.cs b/Projects/UOContent/Engines/Craft/DefCartography.cs index 0c93b0fa6..8e14e54d6 100644 --- a/Projects/UOContent/Engines/Craft/DefCartography.cs +++ b/Projects/UOContent/Engines/Craft/DefCartography.cs @@ -13,7 +13,7 @@ namespace Server.Engines.Craft public override SkillName MainSkill => SkillName.Cartography; - public override int GumpTitleNumber => 1044008; + public override TextDefinition GumpTitle => 1044008; public static CraftSystem CraftSystem => m_CraftSystem ??= new DefCartography(); diff --git a/Projects/UOContent/Engines/Craft/DefCooking.cs b/Projects/UOContent/Engines/Craft/DefCooking.cs index 199c287cc..fd41791c9 100644 --- a/Projects/UOContent/Engines/Craft/DefCooking.cs +++ b/Projects/UOContent/Engines/Craft/DefCooking.cs @@ -13,7 +13,7 @@ namespace Server.Engines.Craft public override SkillName MainSkill => SkillName.Cooking; - public override int GumpTitleNumber => 1044003; + public override TextDefinition GumpTitle => 1044003; public static CraftSystem CraftSystem => m_CraftSystem ??= new DefCooking(); diff --git a/Projects/UOContent/Engines/Craft/DefGlassblowing.cs b/Projects/UOContent/Engines/Craft/DefGlassblowing.cs index bf4793f13..3d60a26a7 100644 --- a/Projects/UOContent/Engines/Craft/DefGlassblowing.cs +++ b/Projects/UOContent/Engines/Craft/DefGlassblowing.cs @@ -14,7 +14,7 @@ namespace Server.Engines.Craft public override SkillName MainSkill => SkillName.Alchemy; - public override int GumpTitleNumber => 1044622; + public override TextDefinition GumpTitle => 1044622; public static CraftSystem CraftSystem => m_CraftSystem ??= new DefGlassblowing(); diff --git a/Projects/UOContent/Engines/Craft/DefInscription.cs b/Projects/UOContent/Engines/Craft/DefInscription.cs index df75d4cb4..e779c99a8 100644 --- a/Projects/UOContent/Engines/Craft/DefInscription.cs +++ b/Projects/UOContent/Engines/Craft/DefInscription.cs @@ -35,7 +35,7 @@ namespace Server.Engines.Craft public override SkillName MainSkill => SkillName.Inscribe; - public override int GumpTitleNumber => 1044009; + public override TextDefinition GumpTitle => 1044009; public static CraftSystem CraftSystem => m_CraftSystem ??= new DefInscription(); diff --git a/Projects/UOContent/Engines/Craft/DefMasonry.cs b/Projects/UOContent/Engines/Craft/DefMasonry.cs index cd2d6cdea..2de64124b 100644 --- a/Projects/UOContent/Engines/Craft/DefMasonry.cs +++ b/Projects/UOContent/Engines/Craft/DefMasonry.cs @@ -14,7 +14,7 @@ namespace Server.Engines.Craft public override SkillName MainSkill => SkillName.Carpentry; - public override int GumpTitleNumber => 1044500; + public override TextDefinition GumpTitle => 1044500; public static CraftSystem CraftSystem => m_CraftSystem ??= new DefMasonry(); diff --git a/Projects/UOContent/Engines/Craft/DefTailoring.cs b/Projects/UOContent/Engines/Craft/DefTailoring.cs index fba543763..f338928de 100644 --- a/Projects/UOContent/Engines/Craft/DefTailoring.cs +++ b/Projects/UOContent/Engines/Craft/DefTailoring.cs @@ -21,7 +21,7 @@ namespace Server.Engines.Craft public override SkillName MainSkill => SkillName.Tailoring; - public override int GumpTitleNumber => 1044005; // Tailoring Menu + public override TextDefinition GumpTitle => 1044005; // Tailoring Menu public static CraftSystem CraftSystem => m_CraftSystem ??= new DefTailoring(); diff --git a/Projects/UOContent/Engines/Craft/DefTinkering.cs b/Projects/UOContent/Engines/Craft/DefTinkering.cs index dbe6f497a..93d17ad7f 100644 --- a/Projects/UOContent/Engines/Craft/DefTinkering.cs +++ b/Projects/UOContent/Engines/Craft/DefTinkering.cs @@ -29,7 +29,7 @@ namespace Server.Engines.Craft public override SkillName MainSkill => SkillName.Tinkering; - public override int GumpTitleNumber => 1044007; + public override TextDefinition GumpTitle => 1044007; public static CraftSystem CraftSystem => m_CraftSystem ??= new DefTinkering(); diff --git a/Projects/UOContent/Engines/Doom/GenGauntlet.cs b/Projects/UOContent/Engines/Doom/GenGauntlet.cs index ebc5979f9..881546cb6 100644 --- a/Projects/UOContent/Engines/Doom/GenGauntlet.cs +++ b/Projects/UOContent/Engines/Doom/GenGauntlet.cs @@ -118,7 +118,7 @@ namespace Server.Engines.Doom gate.GumpHeight = 280; gate.MessageColor = 0x7F00; - gate.MessageNumber = 1062109; // You are about to exit Dungeon Doom. Do you wish to continue? + gate.Message = 1062109; // You are about to exit Dungeon Doom. Do you wish to continue? gate.TitleColor = 0x7800; gate.TitleNumber = 1062108; // Please verify... diff --git a/Projects/UOContent/Engines/Factions/Gumps/FactionImbueGump.cs b/Projects/UOContent/Engines/Factions/Gumps/FactionImbueGump.cs index 3f9c5df00..29931054a 100644 --- a/Projects/UOContent/Engines/Factions/Gumps/FactionImbueGump.cs +++ b/Projects/UOContent/Engines/Factions/Gumps/FactionImbueGump.cs @@ -13,11 +13,11 @@ namespace Server.Factions private readonly Faction m_Faction; private readonly Item m_Item; private readonly Mobile m_Mobile; - private readonly object m_Notice; + private readonly TextDefinition m_Notice; private readonly BaseTool m_Tool; public FactionImbueGump( - int quality, Item item, Mobile from, CraftSystem craftSystem, BaseTool tool, object notice, + int quality, Item item, Mobile from, CraftSystem craftSystem, BaseTool tool, TextDefinition notice, int availableSilver, Faction faction, FactionItemDefinition def ) : base(100, 200) { @@ -98,13 +98,13 @@ namespace Server.Factions { m_Mobile.SendGump(new CraftGump(m_Mobile, m_CraftSystem, m_Tool, m_Notice)); } - else if (m_Notice is string s) + else if (m_Notice.Number > 0) { - m_Mobile.SendMessage(s); + m_Mobile.SendLocalizedMessage(m_Notice.Number); } - else if (m_Notice is int i && i > 0) + else { - m_Mobile.SendLocalizedMessage(i); + m_Mobile.SendMessage(m_Notice.String); } } } diff --git a/Projects/UOContent/Engines/Harvest/Core/HarvestResource.cs b/Projects/UOContent/Engines/Harvest/Core/HarvestResource.cs index 4fdb5b1b4..37df99a26 100644 --- a/Projects/UOContent/Engines/Harvest/Core/HarvestResource.cs +++ b/Projects/UOContent/Engines/Harvest/Core/HarvestResource.cs @@ -4,7 +4,7 @@ namespace Server.Engines.Harvest { public class HarvestResource { - public HarvestResource(double reqSkill, double minSkill, double maxSkill, object message, params Type[] types) + public HarvestResource(double reqSkill, double minSkill, double maxSkill, TextDefinition message, params Type[] types) { ReqSkill = reqSkill; MinSkill = minSkill; @@ -21,17 +21,17 @@ namespace Server.Engines.Harvest public double MaxSkill { get; set; } - public object SuccessMessage { get; } + public TextDefinition SuccessMessage { get; } public void SendSuccessTo(Mobile m) { - if (SuccessMessage is int messageInt) + if (SuccessMessage.Number > 0) { - m.SendLocalizedMessage(messageInt); + m.SendLocalizedMessage(SuccessMessage.Number); } else { - m.SendMessage(SuccessMessage.ToString()); + m.SendMessage(SuccessMessage.String); } } } diff --git a/Projects/UOContent/Gumps/NoticeGump.cs b/Projects/UOContent/Gumps/NoticeGump.cs index 582e25c96..6ae0fa683 100644 --- a/Projects/UOContent/Gumps/NoticeGump.cs +++ b/Projects/UOContent/Gumps/NoticeGump.cs @@ -9,7 +9,7 @@ namespace Server.Gumps private readonly NoticeGumpCallback m_Callback; public NoticeGump( - int header, int headerColor, object content, int contentColor, int width, int height, + int header, int headerColor, TextDefinition content, int contentColor, int width, int height, NoticeGumpCallback callback = null ) : base((640 - width) / 2, (480 - height) / 2) { @@ -28,18 +28,18 @@ namespace Server.Gumps AddImageTiled(10, 40, width - 20, height - 80, 2624); AddAlphaRegion(10, 40, width - 20, height - 80); - if (content is int i) + if (content.Number > 0) { - AddHtmlLocalized(10, 40, width - 20, height - 80, i, contentColor, false, true); + AddHtmlLocalized(10, 40, width - 20, height - 80, content.Number, contentColor, false, true); } - else if (content is string) + else { AddHtml( 10, 40, width - 20, height - 80, - $"{content}", + $"{content.String}", false, true ); diff --git a/Projects/UOContent/Gumps/WarningGump.cs b/Projects/UOContent/Gumps/WarningGump.cs index 8b3acfd41..6b5315f78 100644 --- a/Projects/UOContent/Gumps/WarningGump.cs +++ b/Projects/UOContent/Gumps/WarningGump.cs @@ -9,7 +9,7 @@ namespace Server.Gumps private readonly WarningGumpCallback m_Callback; public WarningGump( - int header, int headerColor, object content, int contentColor, int width, int height, + int header, int headerColor, TextDefinition content, int contentColor, int width, int height, WarningGumpCallback callback = null, bool cancelButton = true ) : base((640 - width) / 2, (480 - height) / 2) { @@ -28,18 +28,18 @@ namespace Server.Gumps AddImageTiled(10, 40, width - 20, height - 80, 2624); AddAlphaRegion(10, 40, width - 20, height - 80); - if (content is int i) + if (content.Number > 0) { - AddHtmlLocalized(10, 40, width - 20, height - 80, i, contentColor, false, true); + AddHtmlLocalized(10, 40, width - 20, height - 80, content.Number, contentColor, false, true); } - else if (content is string) + else { AddHtml( 10, 40, width - 20, height - 80, - $"{content}", + $"{content.String}", false, true ); @@ -71,7 +71,7 @@ namespace Server.Gumps } else { - m_Callback.Invoke(false); + m_Callback(false); } } } diff --git a/Projects/UOContent/Items/Skill Items/Magical/Misc/Moongate.cs b/Projects/UOContent/Items/Skill Items/Magical/Misc/Moongate.cs index b083d3940..e56860bb1 100644 --- a/Projects/UOContent/Items/Skill Items/Magical/Misc/Moongate.cs +++ b/Projects/UOContent/Items/Skill Items/Magical/Misc/Moongate.cs @@ -274,10 +274,7 @@ namespace Server.Items public int TitleNumber { get; set; } [CommandProperty(AccessLevel.GameMaster)] - public int MessageNumber { get; set; } - - [CommandProperty(AccessLevel.GameMaster)] - public string MessageString { get; set; } + public TextDefinition Message { get; set; } public virtual void Warning_Callback(Mobile from, bool okay) { @@ -289,14 +286,14 @@ namespace Server.Items public override void BeginConfirmation(Mobile from) { - if (GumpWidth > 0 && GumpHeight > 0 && TitleNumber > 0 && (MessageNumber > 0 || MessageString != null)) + if (GumpWidth > 0 && GumpHeight > 0 && TitleNumber > 0 && !Message.IsEmpty) { from.CloseGump(); from.SendGump( new WarningGump( TitleNumber, TitleColor, - MessageString ?? (object)MessageNumber, + Message, MessageColor, GumpWidth, GumpHeight, @@ -314,7 +311,9 @@ namespace Server.Items { base.Serialize(writer); - writer.Write(0); // version + writer.Write(1); // version + + TextDefinition.Serialize(writer, Message); writer.WriteEncodedInt(GumpWidth); writer.WriteEncodedInt(GumpHeight); @@ -323,9 +322,6 @@ namespace Server.Items writer.WriteEncodedInt(MessageColor); writer.WriteEncodedInt(TitleNumber); - writer.WriteEncodedInt(MessageNumber); - - writer.Write(MessageString); } public override void Deserialize(IGenericReader reader) @@ -336,6 +332,11 @@ namespace Server.Items switch (version) { + case 1: + { + Message = TextDefinition.Deserialize(reader); + goto case 0; + } case 0: { GumpWidth = reader.ReadEncodedInt(); @@ -345,9 +346,13 @@ namespace Server.Items MessageColor = reader.ReadEncodedInt(); TitleNumber = reader.ReadEncodedInt(); - MessageNumber = reader.ReadEncodedInt(); - MessageString = reader.ReadString(); + if (version == 0) + { + var number = reader.ReadEncodedInt(); + var message = reader.ReadString(); + Message = number > 0 ? number : message; + } break; } @@ -388,11 +393,11 @@ namespace Server.Items 40, 400, 200, - 1062050, + 1062050, // This Gate goes to Felucca... Continue to enter the gate, Cancel to stay here 32512, false, true - ); // This Gate goes to Felucca... Continue to enter the gate, Cancel to stay here + ); } else { @@ -401,11 +406,11 @@ namespace Server.Items 40, 400, 200, - 1062049, + 1062049, // Dost thou wish to step into the moongate? Continue to enter the gate, Cancel to stay here 32512, false, true - ); // Dost thou wish to step into the moongate? Continue to enter the gate, Cancel to stay here + ); } AddImageTiled(10, 250, 400, 20, 2624); @@ -429,7 +434,7 @@ namespace Server.Items 40, 380, 60, - @"Dost thou wish to step into the moongate? Continue to enter the gate, Cancel to stay here" + "Dost thou wish to step into the moongate? Continue to enter the gate, Cancel to stay here" ); AddHtmlLocalized(55, 110, 290, 20, 1011012); // CANCEL From ecfa2905140e7cc9a4434929f31f2c7f3a49d84a Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Wed, 16 Feb 2022 17:29:29 -0800 Subject: [PATCH 073/213] fix: Fixes running schema migrations on Windows (#932) --- Projects/Schema Migrations/Run Schema Migrations.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Projects/Schema Migrations/Run Schema Migrations.csproj b/Projects/Schema Migrations/Run Schema Migrations.csproj index 39947e2f9..b671b550a 100644 --- a/Projects/Schema Migrations/Run Schema Migrations.csproj +++ b/Projects/Schema Migrations/Run Schema Migrations.csproj @@ -8,6 +8,6 @@ - + From 11dcbe7edb39f3a881eeaa78a9d6f43fb480d9a3 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Wed, 16 Feb 2022 18:52:58 -0800 Subject: [PATCH 074/213] fix: Fixes scrolls not working (#933) --- Projects/UOContent/Spells/Chivalry/SacredJourney.cs | 5 ++++- Projects/UOContent/Spells/Fourth/Recall.cs | 4 ++++ Projects/UOContent/Spells/Seventh/GateTravel.cs | 4 ++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Projects/UOContent/Spells/Chivalry/SacredJourney.cs b/Projects/UOContent/Spells/Chivalry/SacredJourney.cs index 0b8667796..8245c88de 100644 --- a/Projects/UOContent/Spells/Chivalry/SacredJourney.cs +++ b/Projects/UOContent/Spells/Chivalry/SacredJourney.cs @@ -16,9 +16,12 @@ namespace Server.Spells.Chivalry ); private readonly Runebook m_Book; - private readonly RunebookEntry m_Entry; + public SacredJourneySpell(Mobile caster, Item scroll) : base(caster, scroll, _info) + { + } + public SacredJourneySpell( Mobile caster, RunebookEntry entry = null, Runebook book = null, Item scroll = null ) : base(caster, scroll, _info) diff --git a/Projects/UOContent/Spells/Fourth/Recall.cs b/Projects/UOContent/Spells/Fourth/Recall.cs index c2f556e33..f9ea8cd1e 100644 --- a/Projects/UOContent/Spells/Fourth/Recall.cs +++ b/Projects/UOContent/Spells/Fourth/Recall.cs @@ -22,6 +22,10 @@ namespace Server.Spells.Fourth private readonly RunebookEntry m_Entry; + public RecallSpell(Mobile caster, Item scroll) : base(caster, scroll, _info) + { + } + public RecallSpell(Mobile caster, RunebookEntry entry = null, Runebook book = null, Item scroll = null) : base( caster, scroll, diff --git a/Projects/UOContent/Spells/Seventh/GateTravel.cs b/Projects/UOContent/Spells/Seventh/GateTravel.cs index 13a171c04..5377ddb22 100644 --- a/Projects/UOContent/Spells/Seventh/GateTravel.cs +++ b/Projects/UOContent/Spells/Seventh/GateTravel.cs @@ -20,6 +20,10 @@ namespace Server.Spells.Seventh private readonly RunebookEntry m_Entry; + public GateTravelSpell(Mobile caster, Item scroll) : base(caster, scroll, _info) + { + } + public GateTravelSpell(Mobile caster, RunebookEntry entry = null, Item scroll = null) : base(caster, scroll, _info) => m_Entry = entry; From 36d07dd34d10c3fa53402032e7f9c50f3a192b5b Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Thu, 17 Feb 2022 08:45:08 -0800 Subject: [PATCH 075/213] fix: Fixes ruleset (#934) --- Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index 4a52a9154..6f875b8d0 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -62,6 +62,6 @@ 3.4.255 all
- + From 04909828c85c78f255c6bddcf156274641ce112d Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Fri, 18 Feb 2022 11:00:10 -0800 Subject: [PATCH 076/213] fix: Fixes argument for schema generation in publish command (#935) --- publish.cmd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/publish.cmd b/publish.cmd index ffe8c6039..15daf9977 100755 --- a/publish.cmd +++ b/publish.cmd @@ -39,7 +39,7 @@ echo dotnet publish ${config} ${os} --no-restore --self-contained=false -o Distr dotnet publish ${config} ${os} --no-restore --self-contained=false -o Distribution/Assemblies Projects/UOContent/UOContent.csproj echo Generating serialization migration schema... -dotnet tool run ModernUOSchemaGenerator ModernUO.sln +dotnet tool run ModernUOSchemaGenerator -- ModernUO.sln exit $? @@ -73,4 +73,4 @@ echo dotnet publish %config% %os% --no-restore --self-contained=false -o Distrib dotnet publish %config% %os% --no-restore --self-contained=false -o Distribution\Assemblies Projects\UOContent\UOContent.csproj echo Generating serialization migration schema... -dotnet tool run ModernUOSchemaGenerator ModernUO.sln +dotnet tool run ModernUOSchemaGenerator -- ModernUO.sln From 2009ac6892faf83332dec48acaa23ce4c06e1447 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Fri, 18 Feb 2022 11:13:38 -0800 Subject: [PATCH 077/213] fix: Adds more null checks for text definition to prevent NPEs (#936) --- .../UOContent/Engines/Craft/Core/CraftGump.cs | 15 +++++---- .../UOContent/Engines/Craft/Core/CraftItem.cs | 30 +++++++++++------- .../UOContent/Engines/Craft/Core/CraftRes.cs | 4 +-- .../Factions/Gumps/FactionImbueGump.cs | 15 +++++---- .../Engines/Harvest/Core/HarvestResource.cs | 15 +++++---- Projects/UOContent/Gumps/NoticeGump.cs | 31 ++++++++++--------- Projects/UOContent/Gumps/WarningGump.cs | 31 ++++++++++--------- .../Skill Items/Magical/Misc/Moongate.cs | 2 +- 8 files changed, 82 insertions(+), 61 deletions(-) diff --git a/Projects/UOContent/Engines/Craft/Core/CraftGump.cs b/Projects/UOContent/Engines/Craft/Core/CraftGump.cs index 653444076..29b1d469d 100644 --- a/Projects/UOContent/Engines/Craft/Core/CraftGump.cs +++ b/Projects/UOContent/Engines/Craft/Core/CraftGump.cs @@ -106,13 +106,16 @@ namespace Server.Engines.Craft } // **************************************** - if (notice.Number > 0) + if (notice != null) { - AddHtmlLocalized(170, 295, 350, 40, notice.Number, LabelColor); - } - else - { - AddHtml(170, 295, 350, 40, $"{notice.String}"); + if (notice.Number > 0) + { + AddHtmlLocalized(170, 295, 350, 40, notice.Number, LabelColor); + } + else + { + AddHtml(170, 295, 350, 40, $"{notice.String}"); + } } // If the system has more than one resource diff --git a/Projects/UOContent/Engines/Craft/Core/CraftItem.cs b/Projects/UOContent/Engines/Craft/Core/CraftItem.cs index 9e738f8dc..ee825dce3 100644 --- a/Projects/UOContent/Engines/Craft/Core/CraftItem.cs +++ b/Projects/UOContent/Engines/Craft/Core/CraftItem.cs @@ -1088,13 +1088,16 @@ namespace Server.Engines.Craft { from.SendGump(new CraftGump(from, craftSystem, tool, message)); } - else if (message.Number > 0) + else if (message != null) { - from.SendLocalizedMessage(message.Number); - } - else - { - from.SendMessage(message.String); + if (message.Number > 0) + { + from.SendLocalizedMessage(message.Number); + } + else + { + from.SendMessage(message.String); + } } return; @@ -1268,13 +1271,16 @@ namespace Server.Engines.Craft { from.SendGump(new CraftGump(from, craftSystem, tool, message)); } - else if (message.Number > 0) + else if (message != null) { - from.SendLocalizedMessage(message.Number); - } - else - { - from.SendMessage(message.String); + if (message.Number > 0) + { + from.SendLocalizedMessage(message.Number); + } + else + { + from.SendMessage(message.String); + } } return; diff --git a/Projects/UOContent/Engines/Craft/Core/CraftRes.cs b/Projects/UOContent/Engines/Craft/Core/CraftRes.cs index f3fd089e6..dc6657b97 100644 --- a/Projects/UOContent/Engines/Craft/Core/CraftRes.cs +++ b/Projects/UOContent/Engines/Craft/Core/CraftRes.cs @@ -23,11 +23,11 @@ namespace Server.Engines.Craft public void SendMessage(Mobile from) { - if (Message.Number > 0) + if (Message?.Number > 0) { from.SendLocalizedMessage(Message.Number); } - else if (!string.IsNullOrEmpty(Message.String)) + else if (!string.IsNullOrEmpty(Message?.String)) { from.SendMessage(Message.String); } diff --git a/Projects/UOContent/Engines/Factions/Gumps/FactionImbueGump.cs b/Projects/UOContent/Engines/Factions/Gumps/FactionImbueGump.cs index 29931054a..e8ffee06d 100644 --- a/Projects/UOContent/Engines/Factions/Gumps/FactionImbueGump.cs +++ b/Projects/UOContent/Engines/Factions/Gumps/FactionImbueGump.cs @@ -98,13 +98,16 @@ namespace Server.Factions { m_Mobile.SendGump(new CraftGump(m_Mobile, m_CraftSystem, m_Tool, m_Notice)); } - else if (m_Notice.Number > 0) + else if (m_Notice != null) { - m_Mobile.SendLocalizedMessage(m_Notice.Number); - } - else - { - m_Mobile.SendMessage(m_Notice.String); + if (m_Notice.Number > 0) + { + m_Mobile.SendLocalizedMessage(m_Notice.Number); + } + else + { + m_Mobile.SendMessage(m_Notice.String); + } } } } diff --git a/Projects/UOContent/Engines/Harvest/Core/HarvestResource.cs b/Projects/UOContent/Engines/Harvest/Core/HarvestResource.cs index 37df99a26..72ad34b8f 100644 --- a/Projects/UOContent/Engines/Harvest/Core/HarvestResource.cs +++ b/Projects/UOContent/Engines/Harvest/Core/HarvestResource.cs @@ -25,13 +25,16 @@ namespace Server.Engines.Harvest public void SendSuccessTo(Mobile m) { - if (SuccessMessage.Number > 0) + if (SuccessMessage != null) { - m.SendLocalizedMessage(SuccessMessage.Number); - } - else - { - m.SendMessage(SuccessMessage.String); + if (SuccessMessage.Number > 0) + { + m.SendLocalizedMessage(SuccessMessage.Number); + } + else + { + m.SendMessage(SuccessMessage.String); + } } } } diff --git a/Projects/UOContent/Gumps/NoticeGump.cs b/Projects/UOContent/Gumps/NoticeGump.cs index 6ae0fa683..eb10a69a0 100644 --- a/Projects/UOContent/Gumps/NoticeGump.cs +++ b/Projects/UOContent/Gumps/NoticeGump.cs @@ -28,21 +28,24 @@ namespace Server.Gumps AddImageTiled(10, 40, width - 20, height - 80, 2624); AddAlphaRegion(10, 40, width - 20, height - 80); - if (content.Number > 0) + if (content != null) { - AddHtmlLocalized(10, 40, width - 20, height - 80, content.Number, contentColor, false, true); - } - else - { - AddHtml( - 10, - 40, - width - 20, - height - 80, - $"{content.String}", - false, - true - ); + if (content.Number > 0) + { + AddHtmlLocalized(10, 40, width - 20, height - 80, content.Number, contentColor, false, true); + } + else + { + AddHtml( + 10, + 40, + width - 20, + height - 80, + $"{content.String}", + false, + true + ); + } } AddImageTiled(10, height - 30, width - 20, 20, 2624); diff --git a/Projects/UOContent/Gumps/WarningGump.cs b/Projects/UOContent/Gumps/WarningGump.cs index 6b5315f78..3217bcdf9 100644 --- a/Projects/UOContent/Gumps/WarningGump.cs +++ b/Projects/UOContent/Gumps/WarningGump.cs @@ -28,21 +28,24 @@ namespace Server.Gumps AddImageTiled(10, 40, width - 20, height - 80, 2624); AddAlphaRegion(10, 40, width - 20, height - 80); - if (content.Number > 0) + if (content != null) { - AddHtmlLocalized(10, 40, width - 20, height - 80, content.Number, contentColor, false, true); - } - else - { - AddHtml( - 10, - 40, - width - 20, - height - 80, - $"{content.String}", - false, - true - ); + if (content.Number > 0) + { + AddHtmlLocalized(10, 40, width - 20, height - 80, content.Number, contentColor, false, true); + } + else + { + AddHtml( + 10, + 40, + width - 20, + height - 80, + $"{content.String}", + false, + true + ); + } } AddImageTiled(10, height - 30, width - 20, 20, 2624); diff --git a/Projects/UOContent/Items/Skill Items/Magical/Misc/Moongate.cs b/Projects/UOContent/Items/Skill Items/Magical/Misc/Moongate.cs index e56860bb1..9bf834dba 100644 --- a/Projects/UOContent/Items/Skill Items/Magical/Misc/Moongate.cs +++ b/Projects/UOContent/Items/Skill Items/Magical/Misc/Moongate.cs @@ -286,7 +286,7 @@ namespace Server.Items public override void BeginConfirmation(Mobile from) { - if (GumpWidth > 0 && GumpHeight > 0 && TitleNumber > 0 && !Message.IsEmpty) + if (GumpWidth > 0 && GumpHeight > 0 && TitleNumber > 0 && Message?.IsEmpty == false) { from.CloseGump(); from.SendGump( From 699478425f5227deb62c4f7c5692318effa7909e Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Fri, 18 Feb 2022 11:15:32 -0800 Subject: [PATCH 078/213] chore: Updates readme to remove blurb about schema migration (#937) --- README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/README.md b/README.md index 0983a8826..957665a56 100644 --- a/README.md +++ b/README.md @@ -59,9 +59,6 @@ Rider 2021.3+           & - `rhel.7`, `rhel.8` - Redhat - If blank, the operating system running the build is used. Linux Mint 20 is not supported directly yet, so build explicitly against `ubuntu.20.04` instead. -**Note:** Building in Visual Studio (or Rider) will not run the schema migration. The schema migration ensures future changes -to the code will be backward compatible. - ## Running the Server - Follow the [publish](https://github.com/modernuo/ModernUO#publishing-builds) instructions - Run `ModernUO.exe` or `dotnet ModernUO.dll` from the `Distribution` directory on the server From 6593abf418259628040a2adaf336c9bf21a01db0 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Fri, 18 Feb 2022 22:11:57 -0800 Subject: [PATCH 079/213] fix: Fixes weight problem with dupe. Fixes mobile base weight. (#938) --- Projects/Server/Mobiles/Mobile.cs | 26 ++++++++++++++++---------- Projects/UOContent/Commands/Dupe.cs | 21 +++++++++++---------- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/Projects/Server/Mobiles/Mobile.cs b/Projects/Server/Mobiles/Mobile.cs index 0e1f21fd4..d112a5434 100644 --- a/Projects/Server/Mobiles/Mobile.cs +++ b/Projects/Server/Mobiles/Mobile.cs @@ -1872,7 +1872,7 @@ namespace Server public static bool DisableDismountInWarmode { get; set; } - public static int BodyWeight { get; set; } = 14; + public static int BodyWeight { get; set; } = 11; // 11 + 3 for the backpack [CommandProperty(AccessLevel.GameMaster)] public IMount Mount @@ -4107,19 +4107,25 @@ namespace Server switch (type) { default: - m_TotalGold += delta; - Delta(MobileDelta.Gold); - break; + { + m_TotalGold += delta; + Delta(MobileDelta.Gold); + break; + } case TotalType.Items: - m_TotalItems += delta; - break; + { + m_TotalItems += delta; + break; + } case TotalType.Weight: - m_TotalWeight += delta; - Delta(MobileDelta.Weight); - OnWeightChange(m_TotalWeight - delta); - break; + { + m_TotalWeight += delta; + Delta(MobileDelta.Weight); + OnWeightChange(m_TotalWeight - delta); + break; + } } } diff --git a/Projects/UOContent/Commands/Dupe.cs b/Projects/UOContent/Commands/Dupe.cs index 3cbf9de10..3b90a0adf 100644 --- a/Projects/UOContent/Commands/Dupe.cs +++ b/Projects/UOContent/Commands/Dupe.cs @@ -47,11 +47,13 @@ namespace Server.Commands for (var i = 0; i < props.Length; i++) { + var p = props[i]; try { - if (props[i].CanRead && props[i].CanWrite) + // Do not set the parent since it screws up mobile/container totals and weights. + if (p.CanRead && p.CanWrite && p.Name != "Parent") { - props[i].SetValue(dest, props[i].GetValue(src, null), null); + p.SetValue(dest, p.GetValue(src, null), null); } } catch @@ -97,14 +99,12 @@ namespace Server.Commands if (m_InBag) { - if (copy.Parent is Container cont) + pack = copy.Parent switch { - pack = cont; - } - else if (copy.Parent is Mobile m) - { - pack = m.Backpack; - } + Container cont => cont, + Mobile m => m.Backpack, + _ => pack + }; } else { @@ -130,7 +130,6 @@ namespace Server.Commands { CopyProperties(newItem, copy); copy.OnAfterDuped(newItem); - newItem.Parent = null; if (pack != null) { @@ -141,7 +140,9 @@ namespace Server.Commands newItem.MoveToWorld(from.Location, from.Map); } + newItem.UpdateTotals(); newItem.InvalidateProperties(); + newItem.Delta(ItemDelta.Update); CommandLogging.WriteLine( from, From 032f21ff273a5d429de4f96af0921f90f6cd0c66 Mon Sep 17 00:00:00 2001 From: Arthrutus <75637913+Arthrutus@users.noreply.github.com> Date: Mon, 21 Feb 2022 01:23:25 -0600 Subject: [PATCH 080/213] fix: Update Blighted Grove Teleporters (#939) --- Distribution/Data/teleporters.json | 58 ++++++++---------------------- 1 file changed, 14 insertions(+), 44 deletions(-) diff --git a/Distribution/Data/teleporters.json b/Distribution/Data/teleporters.json index 82a4fe684..91e70eb0b 100644 --- a/Distribution/Data/teleporters.json +++ b/Distribution/Data/teleporters.json @@ -40,9 +40,9 @@ "back": true }, { - "src": { "map": "Felucca", "loc": [589, 1637, 0] }, - "dst": { "map": "Felucca", "loc": [6575, 888, 0] }, - "back": false + "src": { "map": "Felucca", "loc": [588, 1637, 0] }, + "dst": { "map": "Felucca", "loc": [6472, 868, 26] }, + "back": true }, { "src": { "map": "Felucca", "loc": [766, 1645, 0] }, @@ -2054,16 +2054,6 @@ "dst": { "map": "Felucca", "loc": [6503, 88, 0] }, "back": false }, - { - "src": { "map": "Felucca", "loc": [6488, 849, 40] }, - "dst": { "map": "Felucca", "loc": [6587, 867, 0] }, - "back": false - }, - { - "src": { "map": "Felucca", "loc": [6488, 850, 41] }, - "dst": { "map": "Felucca", "loc": [6587, 868, 0] }, - "back": false - }, { "src": { "map": "Felucca", "loc": [6540, 116, -15] }, "dst": { "map": "Felucca", "loc": [6537, 138, -20] }, @@ -2085,13 +2075,8 @@ "back": false }, { - "src": { "map": "Felucca", "loc": [6574, 889, 0] }, - "dst": { "map": "Felucca", "loc": [6472, 869, 20] }, - "back": false - }, - { - "src": { "map": "Felucca", "loc": [6575, 889, 0] }, - "dst": { "map": "Felucca", "loc": [6473, 869, 20] }, + "src": { "map": "Felucca", "loc": [6477, 860, 9] }, + "dst": { "map": "Felucca", "loc": [6574, 889, 0] }, "back": false }, { @@ -2116,7 +2101,7 @@ }, { "src": { "map": "Felucca", "loc": [6588, 867, 0] }, - "dst": { "map": "Felucca", "loc": [6489, 849, 39] }, + "dst": { "map": "Felucca", "loc": [6488, 849, 40] }, "back": false }, { @@ -2220,8 +2205,13 @@ "back": true }, { - "src": { "map": "Trammel", "loc": [589, 1637, 0] }, - "dst": { "map": "Trammel", "loc": [6575, 888, 0] }, + "src": { "map": "Trammel", "loc": [588, 1637, 0] }, + "dst": { "map": "Trammel", "loc": [6472, 868, 26] }, + "back": true + }, + { + "src": { "map": "Trammel", "loc": [6477, 860, 9] }, + "dst": { "map": "Trammel", "loc": [6574, 889, 0] }, "back": false }, { @@ -4179,16 +4169,6 @@ "dst": { "map": "Trammel", "loc": [6503, 88, 0] }, "back": false }, - { - "src": { "map": "Trammel", "loc": [6488, 849, 40] }, - "dst": { "map": "Trammel", "loc": [6587, 867, 0] }, - "back": false - }, - { - "src": { "map": "Trammel", "loc": [6488, 850, 41] }, - "dst": { "map": "Trammel", "loc": [6587, 868, 0] }, - "back": false - }, { "src": { "map": "Trammel", "loc": [6540, 116, -15] }, "dst": { "map": "Trammel", "loc": [6537, 138, -20] }, @@ -4209,16 +4189,6 @@ "dst": { "map": "Trammel", "loc": [6576, 73, 0] }, "back": false }, - { - "src": { "map": "Trammel", "loc": [6574, 889, 0] }, - "dst": { "map": "Trammel", "loc": [6472, 869, 20] }, - "back": false - }, - { - "src": { "map": "Trammel", "loc": [6575, 889, 0] }, - "dst": { "map": "Trammel", "loc": [6473, 869, 20] }, - "back": false - }, { "src": { "map": "Trammel", "loc": [6577, 159, 13] }, "dst": { "map": "Trammel", "loc": [6577, 177, 30] }, @@ -4241,7 +4211,7 @@ }, { "src": { "map": "Trammel", "loc": [6588, 867, 0] }, - "dst": { "map": "Trammel", "loc": [6489, 849, 39] }, + "dst": { "map": "Trammel", "loc": [6488, 849, 40] }, "back": false }, { From dc2b00ec5bc3c46a40c1fa802b8990480955cae4 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Wed, 23 Feb 2022 21:21:20 -0800 Subject: [PATCH 081/213] fix: Fixes town crier NPE (#942) --- .../UOContent/Mobiles/Townfolk/TownCrier.cs | 26 +++++++------------ 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/Projects/UOContent/Mobiles/Townfolk/TownCrier.cs b/Projects/UOContent/Mobiles/Townfolk/TownCrier.cs index 34e7814ed..0162b9093 100644 --- a/Projects/UOContent/Mobiles/Townfolk/TownCrier.cs +++ b/Projects/UOContent/Mobiles/Townfolk/TownCrier.cs @@ -28,14 +28,9 @@ namespace Server.Mobiles public TownCrierEntry GetRandomEntry() { - if (Entries == null || Entries.Count == 0) + for (var i = (Entries?.Count ?? 0) - 1; i >= 0; --i) { - return null; - } - - for (var i = Entries.Count - 1; Entries != null && i >= 0; --i) - { - if (i >= Entries.Count) + if (i >= Entries!.Count) { continue; } @@ -366,14 +361,9 @@ namespace Server.Mobiles public TownCrierEntry GetRandomEntry() { - if (Entries == null || Entries.Count == 0) + for (var i = (Entries?.Count ?? 0) - 1; i >= 0; --i) { - return GlobalTownCrierEntryList.Instance.GetRandomEntry(); - } - - for (var i = Entries.Count - 1; Entries != null && i >= 0; --i) - { - if (i >= Entries.Count) + if (i >= Entries!.Count) { continue; } @@ -387,8 +377,12 @@ namespace Server.Mobiles } var entry = GlobalTownCrierEntryList.Instance.GetRandomEntry(); + if (entry == null || Entries?.Count > 0 && Utility.RandomBool()) + { + entry = Entries.RandomElement(); + } - return entry ?? (Entries?.Count > 0 && Utility.RandomBool() ? Entries.RandomElement() : null); + return entry; } public TownCrierEntry AddEntry(string[] lines, TimeSpan duration) @@ -420,7 +414,7 @@ namespace Server.Mobiles if (Entries == null && GlobalTownCrierEntryList.Instance.IsEmpty) { - _autoShoutTimer.Stop(); + _autoShoutTimer?.Stop(); _autoShoutTimer = null; } } From 5db8b1354c661f3325a3f799f728aa7a8aca5d36 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sat, 26 Feb 2022 23:43:25 -0800 Subject: [PATCH 082/213] fix: Fixes various minor issues (#943) --- Projects/Server/Mobiles/Mobile.cs | 18 ++++++++++++++---- .../Network/Packets/IncomingAccountPackets.cs | 2 ++ Projects/UOContent/Commands/Properties.cs | 2 +- Projects/UOContent/Gumps/ClientGump.cs | 2 +- 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/Projects/Server/Mobiles/Mobile.cs b/Projects/Server/Mobiles/Mobile.cs index d112a5434..3a7803cb9 100644 --- a/Projects/Server/Mobiles/Mobile.cs +++ b/Projects/Server/Mobiles/Mobile.cs @@ -9,6 +9,7 @@ using Server.Guilds; using Server.Gumps; using Server.HuePickers; using Server.Items; +using Server.Logging; using Server.Menus; using Server.Mobiles; using Server.Network; @@ -408,6 +409,8 @@ namespace Server // Allow four warmode changes in 0.5 seconds, any more will be delay for two seconds private const int WarmodeCatchCount = 4; + private static readonly ILogger logger = LogFactory.GetLogger(typeof(Mobile)); + // TODO: Make these configurations private static readonly TimeSpan WarmodeSpamCatch = TimeSpan.FromSeconds(Core.SE ? 1.0 : 0.5); private static readonly TimeSpan WarmodeSpamDelay = TimeSpan.FromSeconds(Core.SE ? 4.0 : 2.0); @@ -5191,13 +5194,20 @@ namespace Server item.Spawner = null; } - amount = Math.Clamp(amount, 1, item.Amount); - var oldAmount = item.Amount; - if (amount < oldAmount) + if (oldAmount <= 0) { - LiftItemDupe(item, amount); + logger.Error($"Item {item.GetType()} ({item.Serial}) has amount of {oldAmount}, but must be at least 1"); + } + else + { + amount = Math.Clamp(amount, 1, oldAmount); + + if (amount < oldAmount) + { + LiftItemDupe(item, amount); + } } var map = from.Map; diff --git a/Projects/Server/Network/Packets/IncomingAccountPackets.cs b/Projects/Server/Network/Packets/IncomingAccountPackets.cs index 4444b95ad..b7f1eebb5 100644 --- a/Projects/Server/Network/Packets/IncomingAccountPackets.cs +++ b/Projects/Server/Network/Packets/IncomingAccountPackets.cs @@ -318,6 +318,8 @@ namespace Server.Network state.SendSeasonChange((byte)m.GetSeason(), true); state.SendMapChange(m.Map); + state.SendPlayMusic(m.Region.Music); + EventSink.InvokeLogin(m); } diff --git a/Projects/UOContent/Commands/Properties.cs b/Projects/UOContent/Commands/Properties.cs index 21a3e25b0..4ff86a699 100644 --- a/Projects/UOContent/Commands/Properties.cs +++ b/Projects/UOContent/Commands/Properties.cs @@ -72,7 +72,7 @@ namespace Server.Commands if (attr == null) { - failReason = $"Property '${propertyName}' not found."; + failReason = $"Property '{propertyName}' not found."; return null; } diff --git a/Projects/UOContent/Gumps/ClientGump.cs b/Projects/UOContent/Gumps/ClientGump.cs index 9084b8baf..4d10f2405 100644 --- a/Projects/UOContent/Gumps/ClientGump.cs +++ b/Projects/UOContent/Gumps/ClientGump.cs @@ -272,7 +272,7 @@ namespace Server.Gumps { focus.Say("I've been kicked!"); - m_State.Disconnect($"Kicked by ${from}."); + m_State.Disconnect($"Kicked by {from}."); CommandLogging.WriteLine( from, From 941452de4acf4e587d78ba513327281214dbdc09 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 27 Feb 2022 00:13:49 -0800 Subject: [PATCH 083/213] fix: Stops creating blocked packets entirely (#944) Optimizes larger servers where users are logging in and packets are being created for no reason. --- Projects/Server/Items/Item.cs | 2 +- Projects/Server/Items/VirtualHair.cs | 4 +- Projects/Server/Mobiles/Mobile.cs | 2 +- Projects/Server/Network/NetState/NetState.cs | 2 +- .../Network/Packets/IncomingAccountPackets.cs | 917 +++++++------ .../Network/Packets/IncomingEntityPackets.cs | 271 ++-- .../Packets/IncomingExtendedCommandPackets.cs | 945 +++++++------ .../Network/Packets/IncomingHousePackets.cs | 23 +- .../Network/Packets/IncomingItemPackets.cs | 265 ++-- .../Network/Packets/IncomingMessagePackets.cs | 221 ++- .../Network/Packets/IncomingMobilePackets.cs | 275 ++-- .../Packets/IncomingMovementPackets.cs | 149 +- .../Server/Network/Packets/IncomingPackets.cs | 155 ++- .../Network/Packets/IncomingPlayerPackets.cs | 1183 ++++++++-------- .../Packets/IncomingTargetingPackets.cs | 187 ++- .../Network/Packets/IncomingVendorPackets.cs | 143 +- .../Network/Packets/OutgoingAccountPackets.cs | 671 +++++---- .../Network/Packets/OutgoingCombatPackets.cs | 57 +- .../Packets/OutgoingContainerPackets.cs | 359 +++-- .../Network/Packets/OutgoingDamagePackets.cs | 53 +- .../Network/Packets/OutgoingEffectPackets.cs | 589 ++++---- .../Network/Packets/OutgoingEntityPackets.cs | 225 ++-- .../Packets/OutgoingEquipmentPackets.cs | 183 ++- .../Network/Packets/OutgoingGumpPackets.cs | 355 +++-- .../Network/Packets/OutgoingItemPackets.cs | 143 +- .../Network/Packets/OutgoingLightPackets.cs | 33 +- .../Network/Packets/OutgoingMapPackets.cs | 73 +- .../Network/Packets/OutgoingMenuPackets.cs | 383 +++--- .../Network/Packets/OutgoingMessagePackets.cs | 479 ++++--- .../Network/Packets/OutgoingMobilePackets.cs | 1199 ++++++++--------- .../Packets/OutgoingMovementPackets.cs | 161 ++- .../Server/Network/Packets/OutgoingPackets.cs | 9 + .../Network/Packets/OutgoingPlayerPackets.cs | 563 ++++---- .../Packets/OutgoingSecureTradePackets.cs | 165 ++- .../Network/Packets/OutgoingTargetPackets.cs | 87 +- .../Packets/OutgoingVendorBuyPackets.cs | 179 ++- .../Packets/OutgoingVendorSellPackets.cs | 107 +- .../Network/Packets/PacketContainerBuilder.cs | 139 +- .../UOContent/Engines/Chat/ChatPackets.cs | 2 +- Projects/UOContent/Engines/Harvest/Fishing.cs | 7 +- Projects/UOContent/Engines/Help/HelpTopic.cs | 2 +- .../UOContent/Engines/Party/PartyPackets.cs | 8 +- .../CharacterStatuePackets.cs | 2 +- Projects/UOContent/Items/Books/BookPackets.cs | 4 +- .../Bulletin Boards/BulletinBoardPackets.cs | 4 +- .../Items/Games/Mahjong/MahjongPackets.cs | 12 +- .../UOContent/Items/Maps/MapItemPackets.cs | 4 +- .../Items/Misc/Corpses/CorpsePackets.cs | 4 +- .../Items/Skill Items/Magical/Spellbook.cs | 2 +- .../Weapons/Abilities/WeaponAbilityPackets.cs | 2 +- Projects/UOContent/Misc/BuffIcons.cs | 4 +- Projects/UOContent/Misc/ProfessionInfo.cs | 14 +- .../UOContent/Mobiles/Vendors/BaseVendor.cs | 2 +- .../UOContent/Multis/Houses/HousePackets.cs | 6 +- Projects/UOContent/Network/ConnectUO.cs | 2 +- Projects/UOContent/Network/MapUO.cs | 4 +- Projects/UOContent/Network/UOGateway.cs | 4 +- .../Skills/Tracking/OutgoingArrowPackets.cs | 2 +- 58 files changed, 5510 insertions(+), 5537 deletions(-) create mode 100644 Projects/Server/Network/Packets/OutgoingPackets.cs diff --git a/Projects/Server/Items/Item.cs b/Projects/Server/Items/Item.cs index 8531c5a86..8dc75c17c 100644 --- a/Projects/Server/Items/Item.cs +++ b/Projects/Server/Items/Item.cs @@ -4139,7 +4139,7 @@ namespace Server var ns = from.NetState; - if (ns == null) + if (ns.CannotSendPackets()) { return; } diff --git a/Projects/Server/Items/VirtualHair.cs b/Projects/Server/Items/VirtualHair.cs index ba09bedf1..91debb93b 100644 --- a/Projects/Server/Items/VirtualHair.cs +++ b/Projects/Server/Items/VirtualHair.cs @@ -12,7 +12,7 @@ namespace Server public static void SendHairEquipUpdatePacket(this NetState ns, Mobile m, uint hairSerial, int itemId, int hue, Layer layer) { - if (ns == null) + if (ns.CannotSendPackets()) { return; } @@ -42,7 +42,7 @@ namespace Server public static void SendRemoveHairPacket(this NetState ns, uint hairSerial) { - if (ns == null) + if (ns.CannotSendPackets()) { return; } diff --git a/Projects/Server/Mobiles/Mobile.cs b/Projects/Server/Mobiles/Mobile.cs index 3a7803cb9..c94b62b9c 100644 --- a/Projects/Server/Mobiles/Mobile.cs +++ b/Projects/Server/Mobiles/Mobile.cs @@ -8317,7 +8317,7 @@ namespace Server { var ns = m_NetState; - if (ns == null) + if (ns.CannotSendPackets()) { return false; } diff --git a/Projects/Server/Network/NetState/NetState.cs b/Projects/Server/Network/NetState/NetState.cs index b1916bf7b..7adfa951e 100755 --- a/Projects/Server/Network/NetState/NetState.cs +++ b/Projects/Server/Network/NetState/NetState.cs @@ -481,7 +481,7 @@ namespace Server.Network public void Send(ReadOnlySpan span) { - if (span == null || Connection == null || BlockAllPackets) + if (span == null || this.CannotSendPackets()) { return; } diff --git a/Projects/Server/Network/Packets/IncomingAccountPackets.cs b/Projects/Server/Network/Packets/IncomingAccountPackets.cs index b7f1eebb5..41bf8919d 100644 --- a/Projects/Server/Network/Packets/IncomingAccountPackets.cs +++ b/Projects/Server/Network/Packets/IncomingAccountPackets.cs @@ -18,526 +18,525 @@ using System.Collections.Generic; using System.IO; using CV = Server.ClientVersion; -namespace Server.Network +namespace Server.Network; + +public static class IncomingAccountPackets { - public static class IncomingAccountPackets + private const int m_AuthIDWindowSize = 128; + private static readonly Dictionary m_AuthIDWindow = + new(m_AuthIDWindowSize); + + internal struct AuthIDPersistence { - private const int m_AuthIDWindowSize = 128; - private static readonly Dictionary m_AuthIDWindow = - new(m_AuthIDWindowSize); + public DateTime Age; + public readonly ClientVersion Version; - internal struct AuthIDPersistence + public AuthIDPersistence(ClientVersion v) { - public DateTime Age; - public readonly ClientVersion Version; + Age = Core.Now; + Version = v; + } + } - public AuthIDPersistence(ClientVersion v) - { - Age = Core.Now; - Version = v; - } + public static void Configure() + { + IncomingPackets.Register(0x00, 104, false, CreateCharacter); + IncomingPackets.Register(0x5D, 73, false, PlayCharacter); + IncomingPackets.Register(0x80, 62, false, AccountLogin); + IncomingPackets.Register(0x83, 39, false, DeleteCharacter); + IncomingPackets.Register(0x91, 65, false, GameLogin); + IncomingPackets.Register(0xA0, 3, false, PlayServer); + IncomingPackets.Register(0xBB, 9, false, AccountID); + IncomingPackets.Register(0xBD, 0, false, ClientVersion); + IncomingPackets.Register(0xBE, 0, true, AssistVersion); + IncomingPackets.Register(0xCF, 0, false, AccountLogin); + IncomingPackets.Register(0xE1, 0, false, ClientType); + IncomingPackets.Register(0xEF, 21, false, LoginServerSeed); + IncomingPackets.Register(0xF8, 106, false, CreateCharacter); + } + + public static void CreateCharacter(NetState state, CircularBufferReader reader, ref int packetLength) + { + reader.Seek(9, SeekOrigin.Current); + /* + var unk1 = reader.ReadInt32(); + var unk2 = reader.ReadInt32(); + int unk3 = reader.ReadByte(); + */ + var name = reader.ReadAscii(30); + + reader.Seek(2, SeekOrigin.Current); + var flags = reader.ReadInt32(); + reader.Seek(8, SeekOrigin.Current); + int prof = reader.ReadByte(); + reader.Seek(15, SeekOrigin.Current); + + int genderRace = reader.ReadByte(); + + var stats = new StatNameValue[] + { + new(StatType.Str, reader.ReadByte()), + new(StatType.Dex, reader.ReadByte()), + new(StatType.Int, reader.ReadByte()) + }; + + var skills = new SkillNameValue[state.NewCharacterCreation ? 4 : 3]; + skills[0] = new SkillNameValue((SkillName)reader.ReadByte(), reader.ReadByte()); + skills[1] = new SkillNameValue((SkillName)reader.ReadByte(), reader.ReadByte()); + skills[2] = new SkillNameValue((SkillName)reader.ReadByte(), reader.ReadByte()); + if (state.NewCharacterCreation) + { + skills[3] = new SkillNameValue((SkillName)reader.ReadByte(), reader.ReadByte()); } - public static void Configure() + int hue = reader.ReadUInt16(); + int hairVal = reader.ReadInt16(); + int hairHue = reader.ReadInt16(); + int hairValf = reader.ReadInt16(); + int hairHuef = reader.ReadInt16(); + reader.ReadByte(); + int cityIndex = reader.ReadByte(); + reader.Seek(8, SeekOrigin.Current); + /* + var charSlot = reader.ReadInt32(); + var clientIP = reader.ReadInt32(); + */ + int shirtHue = reader.ReadInt16(); + int pantsHue = reader.ReadInt16(); + + /* + Pre-7.0.0.0: + 0x00, 0x01 -> Human Male, Human Female + 0x02, 0x03 -> Elf Male, Elf Female + + Post-7.0.0.0: + 0x00, 0x01 + 0x02, 0x03 -> Human Male, Human Female + 0x04, 0x05 -> Elf Male, Elf Female + 0x05, 0x06 -> Gargoyle Male, Gargoyle Female + */ + + var female = genderRace % 2 != 0; + + var raceID = state.StygianAbyss ? (byte)(genderRace < 4 ? 0 : genderRace / 2 - 1) : (byte)(genderRace / 2); + Race race = Race.Races[raceID] ?? Race.DefaultRace; + + var info = state.CityInfo; + var a = state.Account; + + if (info == null || a == null || cityIndex < 0 || cityIndex >= info.Length) { - IncomingPackets.Register(0x00, 104, false, CreateCharacter); - IncomingPackets.Register(0x5D, 73, false, PlayCharacter); - IncomingPackets.Register(0x80, 62, false, AccountLogin); - IncomingPackets.Register(0x83, 39, false, DeleteCharacter); - IncomingPackets.Register(0x91, 65, false, GameLogin); - IncomingPackets.Register(0xA0, 3, false, PlayServer); - IncomingPackets.Register(0xBB, 9, false, AccountID); - IncomingPackets.Register(0xBD, 0, false, ClientVersion); - IncomingPackets.Register(0xBE, 0, true, AssistVersion); - IncomingPackets.Register(0xCF, 0, false, AccountLogin); - IncomingPackets.Register(0xE1, 0, false, ClientType); - IncomingPackets.Register(0xEF, 21, false, LoginServerSeed); - IncomingPackets.Register(0xF8, 106, false, CreateCharacter); + state.Disconnect("Invalid city selected during character creation."); + return; } - public static void CreateCharacter(NetState state, CircularBufferReader reader, ref int packetLength) + // Check if anyone is using this account + for (var i = 0; i < a.Length; ++i) { - reader.Seek(9, SeekOrigin.Current); - /* - var unk1 = reader.ReadInt32(); - var unk2 = reader.ReadInt32(); - int unk3 = reader.ReadByte(); - */ - var name = reader.ReadAscii(30); + var check = a[i]; - reader.Seek(2, SeekOrigin.Current); - var flags = reader.ReadInt32(); - reader.Seek(8, SeekOrigin.Current); - int prof = reader.ReadByte(); - reader.Seek(15, SeekOrigin.Current); - - int genderRace = reader.ReadByte(); - - var stats = new StatNameValue[] + if (check != null && check.Map != Map.Internal) { - new(StatType.Str, reader.ReadByte()), - new(StatType.Dex, reader.ReadByte()), - new(StatType.Int, reader.ReadByte()) - }; - - var skills = new SkillNameValue[state.NewCharacterCreation ? 4 : 3]; - skills[0] = new SkillNameValue((SkillName)reader.ReadByte(), reader.ReadByte()); - skills[1] = new SkillNameValue((SkillName)reader.ReadByte(), reader.ReadByte()); - skills[2] = new SkillNameValue((SkillName)reader.ReadByte(), reader.ReadByte()); - if (state.NewCharacterCreation) - { - skills[3] = new SkillNameValue((SkillName)reader.ReadByte(), reader.ReadByte()); - } - - int hue = reader.ReadUInt16(); - int hairVal = reader.ReadInt16(); - int hairHue = reader.ReadInt16(); - int hairValf = reader.ReadInt16(); - int hairHuef = reader.ReadInt16(); - reader.ReadByte(); - int cityIndex = reader.ReadByte(); - reader.Seek(8, SeekOrigin.Current); - /* - var charSlot = reader.ReadInt32(); - var clientIP = reader.ReadInt32(); - */ - int shirtHue = reader.ReadInt16(); - int pantsHue = reader.ReadInt16(); - - /* - Pre-7.0.0.0: - 0x00, 0x01 -> Human Male, Human Female - 0x02, 0x03 -> Elf Male, Elf Female - - Post-7.0.0.0: - 0x00, 0x01 - 0x02, 0x03 -> Human Male, Human Female - 0x04, 0x05 -> Elf Male, Elf Female - 0x05, 0x06 -> Gargoyle Male, Gargoyle Female - */ - - var female = genderRace % 2 != 0; - - var raceID = state.StygianAbyss ? (byte)(genderRace < 4 ? 0 : genderRace / 2 - 1) : (byte)(genderRace / 2); - Race race = Race.Races[raceID] ?? Race.DefaultRace; - - var info = state.CityInfo; - var a = state.Account; - - if (info == null || a == null || cityIndex < 0 || cityIndex >= info.Length) - { - state.Disconnect("Invalid city selected during character creation."); + state.LogInfo("Account in use"); + state.SendPopupMessage(PMMessage.CharInWorld); return; } - - // Check if anyone is using this account - for (var i = 0; i < a.Length; ++i) - { - var check = a[i]; - - if (check != null && check.Map != Map.Internal) - { - state.LogInfo("Account in use"); - state.SendPopupMessage(PMMessage.CharInWorld); - return; - } - } - - state.Flags = (ClientFlags)flags; - - var args = new CharacterCreatedEventArgs( - state, - a, - name, - female, - hue, - stats, - info[cityIndex], - skills, - shirtHue, - pantsHue, - hairVal, - hairHue, - hairValf, - hairHuef, - prof, - race - ); - - state.SendClientVersionRequest(); - - state.BlockAllPackets = true; - - EventSink.InvokeCharacterCreated(args); - - var m = args.Mobile; - - if (m != null) - { - state.Mobile = m; - m.NetState = state; - new LoginTimer(state, m).Start(); - } - else - { - state.BlockAllPackets = false; - state.Disconnect("Character creation blocked."); - } } - public static void DeleteCharacter(NetState state, CircularBufferReader reader, ref int packetLength) + state.Flags = (ClientFlags)flags; + + var args = new CharacterCreatedEventArgs( + state, + a, + name, + female, + hue, + stats, + info[cityIndex], + skills, + shirtHue, + pantsHue, + hairVal, + hairHue, + hairValf, + hairHuef, + prof, + race + ); + + state.SendClientVersionRequest(); + + state.BlockAllPackets = true; + + EventSink.InvokeCharacterCreated(args); + + var m = args.Mobile; + + if (m != null) { - reader.Seek(30, SeekOrigin.Current); - var index = reader.ReadInt32(); - - EventSink.InvokeDeleteRequest(state, index); - } - - public static void AccountID(NetState state, CircularBufferReader reader, ref int packetLength) - { - } - - public static void AssistVersion(NetState state, CircularBufferReader reader, ref int packetLength) - { - var unk = reader.ReadInt32(); - var av = reader.ReadAscii(); - } - - public static void ClientVersion(NetState state, CircularBufferReader reader, ref int packetLength) - { - var version = state.Version = new CV(reader.ReadAscii()); - - EventSink.InvokeClientVersionReceived(state, version); - } - - public static void ClientType(NetState state, CircularBufferReader reader, ref int packetLength) - { - reader.ReadUInt16(); - - int type = reader.ReadUInt16(); - var version = state.Version = new CV(reader.ReadAscii()); - - EventSink.InvokeClientVersionReceived(state, version); - } - - public static void PlayCharacter(NetState state, CircularBufferReader reader, ref int packetLength) - { - reader.Seek(4, SeekOrigin.Current); // 0xEDEDEDED - - reader.Seek(30, SeekOrigin.Current); // var name = reader.ReadAscii(30); - - reader.Seek(2, SeekOrigin.Current); - - var flags = reader.ReadInt32(); - - reader.Seek(24, SeekOrigin.Current); - - var charSlot = reader.ReadInt32(); - reader.Seek(4, SeekOrigin.Current); // var clientIP = reader.ReadInt32(); - - var a = state.Account; - - if (a == null || charSlot < 0 || charSlot >= a.Length) - { - state.Disconnect("Invalid character slot selected."); - return; - } - - var m = a[charSlot]; - - // Check if anyone is using this account - for (var i = 0; i < a.Length; ++i) - { - var check = a[i]; - - if (check != null && check.Map != Map.Internal && check != m) - { - state.LogInfo("Account in use"); - state.SendPopupMessage(PMMessage.CharInWorld); - return; - } - } - - if (m == null) - { - state.Disconnect("Empty character slot selected."); - return; - } - - m.NetState?.Disconnect("Character selected for a player already logged in."); - - state.SendClientVersionRequest(); - - state.BlockAllPackets = true; - - state.Flags = (ClientFlags)flags; - state.Mobile = m; m.NetState = state; - new LoginTimer(state, m).Start(); } - - public static void DoLogin(this NetState state, Mobile m) + else { - state.SendLoginConfirmation(m); + state.BlockAllPackets = false; + state.Disconnect("Character creation blocked."); + } + } - state.SendMapChange(m.Map); + public static void DeleteCharacter(NetState state, CircularBufferReader reader, ref int packetLength) + { + reader.Seek(30, SeekOrigin.Current); + var index = reader.ReadInt32(); - state.SendMapPatches(); + EventSink.InvokeDeleteRequest(state, index); + } - state.SendSeasonChange((byte)m.GetSeason(), true); + public static void AccountID(NetState state, CircularBufferReader reader, ref int packetLength) + { + } + + public static void AssistVersion(NetState state, CircularBufferReader reader, ref int packetLength) + { + var unk = reader.ReadInt32(); + var av = reader.ReadAscii(); + } + + public static void ClientVersion(NetState state, CircularBufferReader reader, ref int packetLength) + { + var version = state.Version = new CV(reader.ReadAscii()); + + EventSink.InvokeClientVersionReceived(state, version); + } + + public static void ClientType(NetState state, CircularBufferReader reader, ref int packetLength) + { + reader.ReadUInt16(); + + int type = reader.ReadUInt16(); + var version = state.Version = new CV(reader.ReadAscii()); + + EventSink.InvokeClientVersionReceived(state, version); + } + + public static void PlayCharacter(NetState state, CircularBufferReader reader, ref int packetLength) + { + reader.Seek(4, SeekOrigin.Current); // 0xEDEDEDED + + reader.Seek(30, SeekOrigin.Current); // var name = reader.ReadAscii(30); + + reader.Seek(2, SeekOrigin.Current); + + var flags = reader.ReadInt32(); + + reader.Seek(24, SeekOrigin.Current); + + var charSlot = reader.ReadInt32(); + reader.Seek(4, SeekOrigin.Current); // var clientIP = reader.ReadInt32(); + + var a = state.Account; + + if (a == null || charSlot < 0 || charSlot >= a.Length) + { + state.Disconnect("Invalid character slot selected."); + return; + } + + var m = a[charSlot]; + + // Check if anyone is using this account + for (var i = 0; i < a.Length; ++i) + { + var check = a[i]; + + if (check != null && check.Map != Map.Internal && check != m) + { + state.LogInfo("Account in use"); + state.SendPopupMessage(PMMessage.CharInWorld); + return; + } + } + + if (m == null) + { + state.Disconnect("Empty character slot selected."); + return; + } + + m.NetState?.Disconnect("Character selected for a player already logged in."); + + state.SendClientVersionRequest(); + + state.BlockAllPackets = true; + + state.Flags = (ClientFlags)flags; + + state.Mobile = m; + m.NetState = state; + + new LoginTimer(state, m).Start(); + } + + public static void DoLogin(this NetState state, Mobile m) + { + state.SendLoginConfirmation(m); + + state.SendMapChange(m.Map); + + state.SendMapPatches(); + + state.SendSeasonChange((byte)m.GetSeason(), true); + + state.SendSupportedFeature(); + + state.Sequence = 0; + + state.SendMobileUpdate(m); + state.SendMobileUpdate(m); + + m.CheckLightLevels(true); + + state.SendMobileUpdate(m); + + state.SendMobileIncoming(m, m); + + state.SendMobileStatus(m); + state.SendSetWarMode(m.Warmode); + + m.SendEverything(); + + state.SendSupportedFeature(); + state.SendMobileUpdate(m); + + state.SendMobileStatus(m); + state.SendSetWarMode(m.Warmode); + state.SendMobileIncoming(m, m); + + state.SendLoginComplete(); + state.SendCurrentTime(); + state.SendSeasonChange((byte)m.GetSeason(), true); + state.SendMapChange(m.Map); + + state.SendPlayMusic(m.Region.Music); + + EventSink.InvokeLogin(m); + } + + private static int GenerateAuthID(this NetState state) + { + if (m_AuthIDWindow.Count == m_AuthIDWindowSize) + { + var oldestID = 0; + var oldest = DateTime.MaxValue; + + foreach (var (key, authId) in m_AuthIDWindow) + { + if (authId.Age < oldest) + { + oldestID = key; + oldest = authId.Age; + } + } + + m_AuthIDWindow.Remove(oldestID); + } + + int authID; + + do + { + authID = Utility.Random(1, int.MaxValue - 1); + + if (Utility.RandomBool()) + { + authID |= 1 << 31; + } + } while (m_AuthIDWindow.ContainsKey(authID)); + + m_AuthIDWindow[authID] = new AuthIDPersistence(state.Version); + + return authID; + } + + public static void GameLogin(NetState state, CircularBufferReader reader, ref int packetLength) + { + // TODO: Connection throttling + + if (state.SentFirstPacket) + { + state.Disconnect("Duplicate game login packet received."); + return; + } + + state.SentFirstPacket = true; + + var authID = reader.ReadInt32(); + + if (!m_AuthIDWindow.TryGetValue(authID, out var ap)) + { + state.LogInfo("Invalid client detected, disconnecting..."); + state.Disconnect("Unable to find auth id."); + } + + if (state._authId != 0 && authID != state._authId || state._authId == 0 && authID != state._seed) + { + state.LogInfo("Invalid client detected, disconnecting..."); + state.Disconnect("Invalid auth id in game login packet."); + return; + } + + m_AuthIDWindow.Remove(authID); + state.Version = ap.Version; + + var username = reader.ReadAscii(30); + var password = reader.ReadAscii(30); + + var e = new GameLoginEventArgs(state, username, password); + + EventSink.InvokeGameLogin(e); + + if (e.Accepted) + { + state.CityInfo = e.CityInfo; + + // Comment out these lines to turn off huffman compression + state.CompressionEnabled = true; + state.PacketEncoder ??= NetworkCompression.Compress; state.SendSupportedFeature(); + state.SendCharacterList(); + } + else + { + state.Disconnect("Login rejected by GameLogin packet handler."); + } + } - state.Sequence = 0; + public static void PlayServer(NetState state, CircularBufferReader reader, ref int packetLength) + { + int index = reader.ReadInt16(); + var info = state.ServerInfo; + var a = state.Account; - state.SendMobileUpdate(m); - state.SendMobileUpdate(m); + if (info == null || a == null || index < 0 || index >= info.Length) + { + state.Disconnect("Invalid server selected."); + } + else + { + var si = info[index]; - m.CheckLightLevels(true); + state._authId = GenerateAuthID(state); - state.SendMobileUpdate(m); + state.SentFirstPacket = false; + state.SendPlayServerAck(si, state._authId); + } + } - state.SendMobileIncoming(m, m); + public static void LoginServerSeed(NetState state, CircularBufferReader reader, ref int packetLength) + { + state._seed = reader.ReadInt32(); + state.Seeded = true; - state.SendMobileStatus(m); - state.SendSetWarMode(m.Warmode); - - m.SendEverything(); - - state.SendSupportedFeature(); - state.SendMobileUpdate(m); - - state.SendMobileStatus(m); - state.SendSetWarMode(m.Warmode); - state.SendMobileIncoming(m, m); - - state.SendLoginComplete(); - state.SendCurrentTime(); - state.SendSeasonChange((byte)m.GetSeason(), true); - state.SendMapChange(m.Map); - - state.SendPlayMusic(m.Region.Music); - - EventSink.InvokeLogin(m); + if (state._seed == 0) + { + state.LogInfo("Invalid client detected, disconnecting"); + state.Disconnect("Duplicate seed sent."); + return; } - private static int GenerateAuthID(this NetState state) + var clientMaj = reader.ReadInt32(); + var clientMin = reader.ReadInt32(); + var clientRev = reader.ReadInt32(); + var clientPat = reader.ReadInt32(); + + state.Version = new ClientVersion(clientMaj, clientMin, clientRev, clientPat); + } + + public static void AccountLogin(NetState state, CircularBufferReader reader, ref int packetLength) + { + // TODO: Throttle Connection + + if (state.SentFirstPacket) { - if (m_AuthIDWindow.Count == m_AuthIDWindowSize) - { - var oldestID = 0; - var oldest = DateTime.MaxValue; - - foreach (var (key, authId) in m_AuthIDWindow) - { - if (authId.Age < oldest) - { - oldestID = key; - oldest = authId.Age; - } - } - - m_AuthIDWindow.Remove(oldestID); - } - - int authID; - - do - { - authID = Utility.Random(1, int.MaxValue - 1); - - if (Utility.RandomBool()) - { - authID |= 1 << 31; - } - } while (m_AuthIDWindow.ContainsKey(authID)); - - m_AuthIDWindow[authID] = new AuthIDPersistence(state.Version); - - return authID; + state.Disconnect("Duplicate account login packet sent."); + return; } - public static void GameLogin(NetState state, CircularBufferReader reader, ref int packetLength) + state.SentFirstPacket = true; + + var username = reader.ReadAscii(30); + var password = reader.ReadAscii(30); + + var accountLoginEventArgs = new AccountLoginEventArgs(state, username, password); + + EventSink.InvokeAccountLogin(accountLoginEventArgs); + + if (accountLoginEventArgs.Accepted) { - // TODO: Connection throttling + var serverListEventArgs = new ServerListEventArgs(state, state.Account); - if (state.SentFirstPacket) + EventSink.InvokeServerList(serverListEventArgs); + + if (serverListEventArgs.Rejected) { - state.Disconnect("Duplicate game login packet received."); - return; - } - - state.SentFirstPacket = true; - - var authID = reader.ReadInt32(); - - if (!m_AuthIDWindow.TryGetValue(authID, out var ap)) - { - state.LogInfo("Invalid client detected, disconnecting..."); - state.Disconnect("Unable to find auth id."); - } - - if (state._authId != 0 && authID != state._authId || state._authId == 0 && authID != state._seed) - { - state.LogInfo("Invalid client detected, disconnecting..."); - state.Disconnect("Invalid auth id in game login packet."); - return; - } - - m_AuthIDWindow.Remove(authID); - state.Version = ap.Version; - - var username = reader.ReadAscii(30); - var password = reader.ReadAscii(30); - - var e = new GameLoginEventArgs(state, username, password); - - EventSink.InvokeGameLogin(e); - - if (e.Accepted) - { - state.CityInfo = e.CityInfo; - - // Comment out these lines to turn off huffman compression - state.CompressionEnabled = true; - state.PacketEncoder ??= NetworkCompression.Compress; - - state.SendSupportedFeature(); - state.SendCharacterList(); + state.Account = null; + AccountLogin_ReplyRej(state, ALRReason.BadComm); } else { - state.Disconnect("Login rejected by GameLogin packet handler."); + state.ServerInfo = serverListEventArgs.Servers.ToArray(); + state.SendAccountLoginAck(); } } - - public static void PlayServer(NetState state, CircularBufferReader reader, ref int packetLength) + else { - int index = reader.ReadInt16(); - var info = state.ServerInfo; - var a = state.Account; + AccountLogin_ReplyRej(state, accountLoginEventArgs.RejectReason); + } + } - if (info == null || a == null || index < 0 || index >= info.Length) - { - state.Disconnect("Invalid server selected."); - } - else - { - var si = info[index]; + private static void AccountLogin_ReplyRej(this NetState state, ALRReason reason) + { + state.SendAccountLoginRejected(reason); + state.Disconnect($"Account login rejected due to {reason}"); + } - state._authId = GenerateAuthID(state); + private class LoginTimer : Timer + { + private readonly Mobile _mobile; + private readonly NetState _state; - state.SentFirstPacket = false; - state.SendPlayServerAck(si, state._authId); - } + public LoginTimer(NetState state, Mobile m) : base(TimeSpan.FromMilliseconds(64), TimeSpan.FromMilliseconds(64)) + { + _state = state; + _mobile = m; } - public static void LoginServerSeed(NetState state, CircularBufferReader reader, ref int packetLength) + protected override void OnTick() { - state._seed = reader.ReadInt32(); - state.Seeded = true; - - if (state._seed == 0) + if (_state != null) { - state.LogInfo("Invalid client detected, disconnecting"); - state.Disconnect("Duplicate seed sent."); - return; - } - - var clientMaj = reader.ReadInt32(); - var clientMin = reader.ReadInt32(); - var clientRev = reader.ReadInt32(); - var clientPat = reader.ReadInt32(); - - state.Version = new ClientVersion(clientMaj, clientMin, clientRev, clientPat); - } - - public static void AccountLogin(NetState state, CircularBufferReader reader, ref int packetLength) - { - // TODO: Throttle Connection - - if (state.SentFirstPacket) - { - state.Disconnect("Duplicate account login packet sent."); - return; - } - - state.SentFirstPacket = true; - - var username = reader.ReadAscii(30); - var password = reader.ReadAscii(30); - - var accountLoginEventArgs = new AccountLoginEventArgs(state, username, password); - - EventSink.InvokeAccountLogin(accountLoginEventArgs); - - if (accountLoginEventArgs.Accepted) - { - var serverListEventArgs = new ServerListEventArgs(state, state.Account); - - EventSink.InvokeServerList(serverListEventArgs); - - if (serverListEventArgs.Rejected) + if (_state.Account == null) { - state.Account = null; - AccountLogin_ReplyRej(state, ALRReason.BadComm); + _state.Disconnect("Account was deleted during the login process."); } - else + else if (_mobile == null) { - state.ServerInfo = serverListEventArgs.Servers.ToArray(); - state.SendAccountLoginAck(); + _state.Disconnect("Player was deleted during the login process."); + } + else if (_state.Version != null) + { + _state.BlockAllPackets = false; + DoLogin(_state, _mobile); + } + else // Waiting to receive the client version before we continue the login process + { + return; } } - else - { - AccountLogin_ReplyRej(state, accountLoginEventArgs.RejectReason); - } - } - private static void AccountLogin_ReplyRej(this NetState state, ALRReason reason) - { - state.SendAccountLoginRejected(reason); - state.Disconnect($"Account login rejected due to {reason}"); - } - - private class LoginTimer : Timer - { - private readonly Mobile _mobile; - private readonly NetState _state; - - public LoginTimer(NetState state, Mobile m) : base(TimeSpan.FromSeconds(1.0), TimeSpan.FromSeconds(1.0)) - { - _state = state; - _mobile = m; - } - - protected override void OnTick() - { - if (_state != null) - { - if (_state.Account == null) - { - _state.Disconnect("Account was deleted during the login process."); - } - else if (_mobile == null) - { - _state.Disconnect("Player was deleted during the login process."); - } - else if (_state.Version != null) - { - _state.BlockAllPackets = false; - DoLogin(_state, _mobile); - } - else // Waiting to receive the client version before we continue the login process - { - return; - } - } - - Stop(); - } + Stop(); } } } diff --git a/Projects/Server/Network/Packets/IncomingEntityPackets.cs b/Projects/Server/Network/Packets/IncomingEntityPackets.cs index ac6c0dd3d..bd2815eee 100644 --- a/Projects/Server/Network/Packets/IncomingEntityPackets.cs +++ b/Projects/Server/Network/Packets/IncomingEntityPackets.cs @@ -13,97 +13,160 @@ * along with this program. If not, see . * *************************************************************************/ -namespace Server.Network +namespace Server.Network; + +public static class IncomingEntityPackets { - public static class IncomingEntityPackets + public static bool SingleClickProps { get; set; } + + public static void Configure() { - public static bool SingleClickProps { get; set; } + IncomingPackets.Register(0x06, 5, true, UseReq); + IncomingPackets.Register(0x09, 5, true, LookReq); + IncomingPackets.Register(0xB6, 9, true, ObjectHelpRequest); + IncomingPackets.Register(0xD6, 0, true, BatchQueryProperties); + } - public static void Configure() + public static void ObjectHelpRequest(NetState state, CircularBufferReader reader, ref int packetLength) + { + var from = state.Mobile; + + var serial = (Serial)reader.ReadUInt32(); + int unk = reader.ReadByte(); + var lang = reader.ReadAscii(3); + + if (serial.IsItem) { - IncomingPackets.Register(0x06, 5, true, UseReq); - IncomingPackets.Register(0x09, 5, true, LookReq); - IncomingPackets.Register(0xB6, 9, true, ObjectHelpRequest); - IncomingPackets.Register(0xD6, 0, true, BatchQueryProperties); - } + var item = World.FindItem(serial); - public static void ObjectHelpRequest(NetState state, CircularBufferReader reader, ref int packetLength) - { - var from = state.Mobile; - - var serial = (Serial)reader.ReadUInt32(); - int unk = reader.ReadByte(); - var lang = reader.ReadAscii(3); - - if (serial.IsItem) + if (item != null && from.Map == item.Map && Utility.InUpdateRange(item.GetWorldLocation(), from.Location) && + from.CanSee(item)) { - var item = World.FindItem(serial); - - if (item != null && from.Map == item.Map && Utility.InUpdateRange(item.GetWorldLocation(), from.Location) && - from.CanSee(item)) - { - item.OnHelpRequest(from); - } - } - else if (serial.IsMobile) - { - var m = World.FindMobile(serial); - - if (m != null && from.Map == m.Map && Utility.InUpdateRange(m.Location, from.Location) && from.CanSee(m)) - { - m.OnHelpRequest(m); - } + item.OnHelpRequest(from); } } - - public static void UseReq(NetState state, CircularBufferReader reader, ref int packetLength) + else if (serial.IsMobile) { - var from = state.Mobile; + var m = World.FindMobile(serial); - if (from.AccessLevel >= AccessLevel.Counselor || Core.TickCount - from.NextActionTime >= 0) + if (m != null && from.Map == m.Map && Utility.InUpdateRange(m.Location, from.Location) && from.CanSee(m)) { - var value = reader.ReadUInt32(); + m.OnHelpRequest(m); + } + } + } - if ((value & ~0x7FFFFFFF) != 0) - { - from.OnPaperdollRequest(); - } - else - { - Serial s = (Serial)value; + public static void UseReq(NetState state, CircularBufferReader reader, ref int packetLength) + { + var from = state.Mobile; - if (s.IsMobile) - { - var m = World.FindMobile(s); + if (from.AccessLevel >= AccessLevel.Counselor || Core.TickCount - from.NextActionTime >= 0) + { + var value = reader.ReadUInt32(); - if (m?.Deleted == false) - { - from.Use(m); - } - } - else if (s.IsItem) - { - var item = World.FindItem(s); - - if (item?.Deleted == false) - { - from.Use(item); - } - } - } - - from.NextActionTime = Core.TickCount + Mobile.ActionDelay; + if ((value & ~0x7FFFFFFF) != 0) + { + from.OnPaperdollRequest(); } else { - from.SendActionMessage(); + Serial s = (Serial)value; + + if (s.IsMobile) + { + var m = World.FindMobile(s); + + if (m?.Deleted == false) + { + from.Use(m); + } + } + else if (s.IsItem) + { + var item = World.FindItem(s); + + if (item?.Deleted == false) + { + from.Use(item); + } + } + } + + from.NextActionTime = Core.TickCount + Mobile.ActionDelay; + } + else + { + from.SendActionMessage(); + } + } + + public static void LookReq(NetState state, CircularBufferReader reader, ref int packetLength) + { + var from = state.Mobile; + + Serial s = (Serial)reader.ReadUInt32(); + + if (s.IsMobile) + { + var m = World.FindMobile(s); + + if (m != null && from.CanSee(m) && Utility.InUpdateRange(from.Location, m.Location)) + { + if (SingleClickProps) + { + m.OnAosSingleClick(from); + } + else + { + if (from.Region.OnSingleClick(from, m)) + { + m.OnSingleClick(from); + } + } } } - - public static void LookReq(NetState state, CircularBufferReader reader, ref int packetLength) + else if (s.IsItem) { - var from = state.Mobile; + var item = World.FindItem(s); + if (item?.Deleted == false && from.CanSee(item) && + Utility.InUpdateRange(from.Location, item.GetWorldLocation())) + { + if (SingleClickProps) + { + item.OnAosSingleClick(from); + } + else if (from.Region.OnSingleClick(from, item)) + { + if (item.Parent is Item parentItem) + { + parentItem.OnSingleClickContained(from, item); + } + + item.OnSingleClick(from); + } + } + } + } + + public static void BatchQueryProperties(NetState state, CircularBufferReader reader, ref int packetLength) + { + if (!ObjectPropertyList.Enabled) + { + return; + } + + var from = state.Mobile; + + var length = reader.Remaining; + + if (length % 4 != 0) + { + return; + } + + while (reader.Remaining > 0) + { Serial s = (Serial)reader.ReadUInt32(); if (s.IsMobile) @@ -112,17 +175,7 @@ namespace Server.Network if (m != null && from.CanSee(m) && Utility.InUpdateRange(from.Location, m.Location)) { - if (SingleClickProps) - { - m.OnAosSingleClick(from); - } - else - { - if (from.Region.OnSingleClick(from, m)) - { - m.OnSingleClick(from); - } - } + m.SendPropertiesTo(from); } } else if (s.IsItem) @@ -132,61 +185,7 @@ namespace Server.Network if (item?.Deleted == false && from.CanSee(item) && Utility.InUpdateRange(from.Location, item.GetWorldLocation())) { - if (SingleClickProps) - { - item.OnAosSingleClick(from); - } - else if (from.Region.OnSingleClick(from, item)) - { - if (item.Parent is Item parentItem) - { - parentItem.OnSingleClickContained(from, item); - } - - item.OnSingleClick(from); - } - } - } - } - - public static void BatchQueryProperties(NetState state, CircularBufferReader reader, ref int packetLength) - { - if (!ObjectPropertyList.Enabled) - { - return; - } - - var from = state.Mobile; - - var length = reader.Remaining; - - if (length % 4 != 0) - { - return; - } - - while (reader.Remaining > 0) - { - Serial s = (Serial)reader.ReadUInt32(); - - if (s.IsMobile) - { - var m = World.FindMobile(s); - - if (m != null && from.CanSee(m) && Utility.InUpdateRange(from.Location, m.Location)) - { - m.SendPropertiesTo(from); - } - } - else if (s.IsItem) - { - var item = World.FindItem(s); - - if (item?.Deleted == false && from.CanSee(item) && - Utility.InUpdateRange(from.Location, item.GetWorldLocation())) - { - item.SendPropertiesTo(from); - } + item.SendPropertiesTo(from); } } } diff --git a/Projects/Server/Network/Packets/IncomingExtendedCommandPackets.cs b/Projects/Server/Network/Packets/IncomingExtendedCommandPackets.cs index c78da3903..e082c70e1 100644 --- a/Projects/Server/Network/Packets/IncomingExtendedCommandPackets.cs +++ b/Projects/Server/Network/Packets/IncomingExtendedCommandPackets.cs @@ -16,502 +16,501 @@ using System.Collections.Generic; using Server.ContextMenus; -namespace Server.Network +namespace Server.Network; + +public static class IncomingExtendedCommandPackets { - public static class IncomingExtendedCommandPackets + private static readonly PacketHandler[] m_ExtendedHandlersLow = new PacketHandler[0x100]; + private static readonly Dictionary m_ExtendedHandlersHigh = new(); + + // TODO: Change to outside configuration + public static int[] ValidAnimations { get; set; } = { - private static readonly PacketHandler[] m_ExtendedHandlersLow = new PacketHandler[0x100]; - private static readonly Dictionary m_ExtendedHandlersHigh = new(); + 6, 21, 32, 33, + 100, 101, 102, 103, + 104, 105, 106, 107, + 108, 109, 110, 111, + 112, 113, 114, 115, + 116, 117, 118, 119, + 120, 121, 123, 124, + 125, 126, 127, 128 + }; - // TODO: Change to outside configuration - public static int[] ValidAnimations { get; set; } = + public static void Configure() + { + IncomingPackets.Register(0xBF, 0, true, ExtendedCommand); + + RegisterExtended(0x05, false, ScreenSize); + RegisterExtended(0x06, true, PartyMessage); + RegisterExtended(0x09, true, DisarmRequest); + RegisterExtended(0x0A, true, StunRequest); + RegisterExtended(0x0B, false, Language); + RegisterExtended(0x0C, true, CloseStatus); + RegisterExtended(0x0E, true, Animate); + RegisterExtended(0x0F, false, Empty); // What's this? + RegisterExtended(0x10, true, QueryProperties); + RegisterExtended(0x13, true, ContextMenuRequest); + RegisterExtended(0x15, true, ContextMenuResponse); + RegisterExtended(0x1A, true, StatLockChange); + RegisterExtended(0x1C, true, CastSpell); + RegisterExtended(0x24, false, UnhandledBF); + RegisterExtended(0x2C, true, BandageTarget); + RegisterExtended(0x2D, true, TargetedSpell); + RegisterExtended(0x2E, true, TargetedSkillUse); + RegisterExtended(0x30, true, TargetByResourceMacro); + RegisterExtended(0x32, true, ToggleFlying); + } + + private static void UnhandledBF(NetState state, CircularBufferReader reader, ref int packetLength) + { + } + + public static void Empty(NetState state, CircularBufferReader reader, ref int packetLength) + { + } + + public static void RegisterExtended(int packetID, bool ingame, OnPacketReceive onReceive) + { + if (packetID >= 0 && packetID < 0x100) { - 6, 21, 32, 33, - 100, 101, 102, 103, - 104, 105, 106, 107, - 108, 109, 110, 111, - 112, 113, 114, 115, - 116, 117, 118, 119, - 120, 121, 123, 124, - 125, 126, 127, 128 - }; - - public static void Configure() + m_ExtendedHandlersLow[packetID] = new PacketHandler(packetID, 0, ingame, onReceive); + } + else { - IncomingPackets.Register(0xBF, 0, true, ExtendedCommand); + m_ExtendedHandlersHigh[packetID] = new PacketHandler(packetID, 0, ingame, onReceive); + } + } - RegisterExtended(0x05, false, ScreenSize); - RegisterExtended(0x06, true, PartyMessage); - RegisterExtended(0x09, true, DisarmRequest); - RegisterExtended(0x0A, true, StunRequest); - RegisterExtended(0x0B, false, Language); - RegisterExtended(0x0C, true, CloseStatus); - RegisterExtended(0x0E, true, Animate); - RegisterExtended(0x0F, false, Empty); // What's this? - RegisterExtended(0x10, true, QueryProperties); - RegisterExtended(0x13, true, ContextMenuRequest); - RegisterExtended(0x15, true, ContextMenuResponse); - RegisterExtended(0x1A, true, StatLockChange); - RegisterExtended(0x1C, true, CastSpell); - RegisterExtended(0x24, false, UnhandledBF); - RegisterExtended(0x2C, true, BandageTarget); - RegisterExtended(0x2D, true, TargetedSpell); - RegisterExtended(0x2E, true, TargetedSkillUse); - RegisterExtended(0x30, true, TargetByResourceMacro); - RegisterExtended(0x32, true, ToggleFlying); + public static PacketHandler GetExtendedHandler(int packetID) + { + if (packetID >= 0 && packetID < 0x100) + { + return m_ExtendedHandlersLow[packetID]; } - private static void UnhandledBF(NetState state, CircularBufferReader reader, ref int packetLength) + m_ExtendedHandlersHigh.TryGetValue(packetID, out var handler); + return handler; + } + + public static void RemoveExtendedHandler(int packetID) + { + if (packetID >= 0 && packetID < 0x100) { + m_ExtendedHandlersLow[packetID] = null; + } + else + { + m_ExtendedHandlersHigh.Remove(packetID); + } + } + + public static void ExtendedCommand(NetState state, CircularBufferReader reader, ref int packetLength) + { + int packetId = reader.ReadUInt16(); + + var ph = GetExtendedHandler(packetId); + + if (ph == null) + { + reader.Trace(state); + return; } - public static void Empty(NetState state, CircularBufferReader reader, ref int packetLength) - { - } - - public static void RegisterExtended(int packetID, bool ingame, OnPacketReceive onReceive) - { - if (packetID >= 0 && packetID < 0x100) - { - m_ExtendedHandlersLow[packetID] = new PacketHandler(packetID, 0, ingame, onReceive); - } - else - { - m_ExtendedHandlersHigh[packetID] = new PacketHandler(packetID, 0, ingame, onReceive); - } - } - - public static PacketHandler GetExtendedHandler(int packetID) - { - if (packetID >= 0 && packetID < 0x100) - { - return m_ExtendedHandlersLow[packetID]; - } - - m_ExtendedHandlersHigh.TryGetValue(packetID, out var handler); - return handler; - } - - public static void RemoveExtendedHandler(int packetID) - { - if (packetID >= 0 && packetID < 0x100) - { - m_ExtendedHandlersLow[packetID] = null; - } - else - { - m_ExtendedHandlersHigh.Remove(packetID); - } - } - - public static void ExtendedCommand(NetState state, CircularBufferReader reader, ref int packetLength) - { - int packetId = reader.ReadUInt16(); - - var ph = GetExtendedHandler(packetId); - - if (ph == null) - { - reader.Trace(state); - return; - } - - if (ph.Ingame && state.Mobile?.Deleted != false) - { - if (state.Mobile == null) - { - state.LogInfo( - "Sent in-game packet (0xBFx{0:X2}) before having been attached to a mobile", - packetId - ); - } - - state.Disconnect($"Sent in-game packet(0xBFx{packetId:X2}) but mobile is deleted."); - } - else - { - ph.OnReceive(state, reader, ref packetLength); - } - } - - public static void ScreenSize(NetState state, CircularBufferReader reader, ref int packetLength) - { - var width = reader.ReadInt32(); - var unk = reader.ReadInt32(); - } - - // TODO: Move out of the core - public static void PartyMessage(NetState state, CircularBufferReader reader, ref int packetLength) + if (ph.Ingame && state.Mobile?.Deleted != false) { if (state.Mobile == null) { - return; + state.LogInfo( + "Sent in-game packet (0xBFx{0:X2}) before having been attached to a mobile", + packetId + ); } - switch (reader.ReadByte()) + state.Disconnect($"Sent in-game packet(0xBFx{packetId:X2}) but mobile is deleted."); + } + else + { + ph.OnReceive(state, reader, ref packetLength); + } + } + + public static void ScreenSize(NetState state, CircularBufferReader reader, ref int packetLength) + { + var width = reader.ReadInt32(); + var unk = reader.ReadInt32(); + } + + // TODO: Move out of the core + public static void PartyMessage(NetState state, CircularBufferReader reader, ref int packetLength) + { + if (state.Mobile == null) + { + return; + } + + switch (reader.ReadByte()) + { + case 0x01: + PartyMessage_AddMember(state, reader, ref packetLength); + break; + case 0x02: + PartyMessage_RemoveMember(state, reader, ref packetLength); + break; + case 0x03: + PartyMessage_PrivateMessage(state, reader, ref packetLength); + break; + case 0x04: + PartyMessage_PublicMessage(state, reader, ref packetLength); + break; + case 0x06: + PartyMessage_SetCanLoot(state, reader, ref packetLength); + break; + case 0x08: + PartyMessage_Accept(state, reader, ref packetLength); + break; + case 0x09: + PartyMessage_Decline(state, reader, ref packetLength); + break; + default: + reader.Trace(state); + break; + } + } + + public static void PartyMessage_AddMember(NetState state, CircularBufferReader reader, ref int packetLength) + { + PartyCommands.Handler?.OnAdd(state.Mobile); + } + + public static void PartyMessage_RemoveMember(NetState state, CircularBufferReader reader, ref int packetLength) + { + PartyCommands.Handler?.OnRemove(state.Mobile, World.FindMobile((Serial)reader.ReadUInt32())); + } + + public static void PartyMessage_PrivateMessage(NetState state, CircularBufferReader reader, ref int packetLength) + { + PartyCommands.Handler?.OnPrivateMessage( + state.Mobile, + World.FindMobile((Serial)reader.ReadUInt32()), + reader.ReadBigUniSafe() + ); + } + + public static void PartyMessage_PublicMessage(NetState state, CircularBufferReader reader, ref int packetLength) + { + PartyCommands.Handler?.OnPublicMessage(state.Mobile, reader.ReadBigUniSafe()); + } + + public static void PartyMessage_SetCanLoot(NetState state, CircularBufferReader reader, ref int packetLength) + { + PartyCommands.Handler?.OnSetCanLoot(state.Mobile, reader.ReadBoolean()); + } + + public static void PartyMessage_Accept(NetState state, CircularBufferReader reader, ref int packetLength) + { + PartyCommands.Handler?.OnAccept(state.Mobile, World.FindMobile((Serial)reader.ReadUInt32())); + } + + public static void PartyMessage_Decline(NetState state, CircularBufferReader reader, ref int packetLength) + { + PartyCommands.Handler?.OnDecline(state.Mobile, World.FindMobile((Serial)reader.ReadUInt32())); + } + + public static void Animate(NetState state, CircularBufferReader reader, ref int packetLength) + { + var from = state.Mobile; + + if (from == null) + { + return; + } + + var action = reader.ReadInt32(); + + var ok = false; + + for (var i = 0; !ok && i < ValidAnimations.Length; ++i) + { + ok = action == ValidAnimations[i]; + } + + if (ok && from.Alive && from.Body.IsHuman && !from.Mounted) + { + from.Animate(action, 7, 1, true, false, 0); + } + } + + public static void CastSpell(NetState state, CircularBufferReader reader, ref int packetLength) + { + var from = state.Mobile; + + if (from == null) + { + return; + } + + Item spellbook = reader.ReadInt16() == 1 ? World.FindItem((Serial)reader.ReadUInt32()) : null; + + var spellID = reader.ReadInt16() - 1; + EventSink.InvokeCastSpellRequest(from, spellID, spellbook); + } + + public static void ToggleFlying(NetState state, CircularBufferReader reader, ref int packetLength) + { + state.Mobile?.ToggleFlying(); + } + + public static void StunRequest(NetState state, CircularBufferReader reader, ref int packetLength) + { + var from = state.Mobile; + + if (from == null) + { + return; + } + + EventSink.InvokeStunRequest(from); + } + + public static void DisarmRequest(NetState state, CircularBufferReader reader, ref int packetLength) + { + var from = state.Mobile; + + if (from == null) + { + return; + } + + EventSink.InvokeDisarmRequest(from); + } + + public static void StatLockChange(NetState state, CircularBufferReader reader, ref int packetLength) + { + var from = state.Mobile; + + if (from == null) + { + return; + } + + int stat = reader.ReadByte(); + int lockValue = reader.ReadByte(); + + if (lockValue > 2) + { + lockValue = 0; + } + + switch (stat) + { + case 0: + from.StrLock = (StatLockType)lockValue; + break; + case 1: + from.DexLock = (StatLockType)lockValue; + break; + case 2: + from.IntLock = (StatLockType)lockValue; + break; + } + } + + public static void CloseStatus(NetState state, CircularBufferReader reader, ref int packetLength) + { + var serial = (Serial)reader.ReadUInt32(); + } + + public static void Language(NetState state, CircularBufferReader reader, ref int packetLength) + { + var from = state.Mobile; + + if (from == null) + { + return; + } + + from.Language = reader.ReadAscii(4); + } + + public static void QueryProperties(NetState state, CircularBufferReader reader, ref int packetLength) + { + if (!ObjectPropertyList.Enabled) + { + return; + } + + var from = state.Mobile; + + Serial s = (Serial)reader.ReadUInt32(); + + if (s.IsMobile) + { + var m = World.FindMobile(s); + + if (m != null && from.CanSee(m) && Utility.InUpdateRange(from.Location, m.Location)) { - case 0x01: - PartyMessage_AddMember(state, reader, ref packetLength); - break; - case 0x02: - PartyMessage_RemoveMember(state, reader, ref packetLength); - break; - case 0x03: - PartyMessage_PrivateMessage(state, reader, ref packetLength); - break; - case 0x04: - PartyMessage_PublicMessage(state, reader, ref packetLength); - break; - case 0x06: - PartyMessage_SetCanLoot(state, reader, ref packetLength); - break; - case 0x08: - PartyMessage_Accept(state, reader, ref packetLength); - break; - case 0x09: - PartyMessage_Decline(state, reader, ref packetLength); - break; - default: - reader.Trace(state); - break; + m.SendPropertiesTo(from); } } - - public static void PartyMessage_AddMember(NetState state, CircularBufferReader reader, ref int packetLength) + else if (s.IsItem) { - PartyCommands.Handler?.OnAdd(state.Mobile); - } + var item = World.FindItem(s); - public static void PartyMessage_RemoveMember(NetState state, CircularBufferReader reader, ref int packetLength) - { - PartyCommands.Handler?.OnRemove(state.Mobile, World.FindMobile((Serial)reader.ReadUInt32())); - } - - public static void PartyMessage_PrivateMessage(NetState state, CircularBufferReader reader, ref int packetLength) - { - PartyCommands.Handler?.OnPrivateMessage( - state.Mobile, - World.FindMobile((Serial)reader.ReadUInt32()), - reader.ReadBigUniSafe() - ); - } - - public static void PartyMessage_PublicMessage(NetState state, CircularBufferReader reader, ref int packetLength) - { - PartyCommands.Handler?.OnPublicMessage(state.Mobile, reader.ReadBigUniSafe()); - } - - public static void PartyMessage_SetCanLoot(NetState state, CircularBufferReader reader, ref int packetLength) - { - PartyCommands.Handler?.OnSetCanLoot(state.Mobile, reader.ReadBoolean()); - } - - public static void PartyMessage_Accept(NetState state, CircularBufferReader reader, ref int packetLength) - { - PartyCommands.Handler?.OnAccept(state.Mobile, World.FindMobile((Serial)reader.ReadUInt32())); - } - - public static void PartyMessage_Decline(NetState state, CircularBufferReader reader, ref int packetLength) - { - PartyCommands.Handler?.OnDecline(state.Mobile, World.FindMobile((Serial)reader.ReadUInt32())); - } - - public static void Animate(NetState state, CircularBufferReader reader, ref int packetLength) - { - var from = state.Mobile; - - if (from == null) + if (item?.Deleted == false && from.CanSee(item) && + Utility.InUpdateRange(from.Location, item.GetWorldLocation())) { - return; - } - - var action = reader.ReadInt32(); - - var ok = false; - - for (var i = 0; !ok && i < ValidAnimations.Length; ++i) - { - ok = action == ValidAnimations[i]; - } - - if (ok && from.Alive && from.Body.IsHuman && !from.Mounted) - { - from.Animate(action, 7, 1, true, false, 0); - } - } - - public static void CastSpell(NetState state, CircularBufferReader reader, ref int packetLength) - { - var from = state.Mobile; - - if (from == null) - { - return; - } - - Item spellbook = reader.ReadInt16() == 1 ? World.FindItem((Serial)reader.ReadUInt32()) : null; - - var spellID = reader.ReadInt16() - 1; - EventSink.InvokeCastSpellRequest(from, spellID, spellbook); - } - - public static void ToggleFlying(NetState state, CircularBufferReader reader, ref int packetLength) - { - state.Mobile?.ToggleFlying(); - } - - public static void StunRequest(NetState state, CircularBufferReader reader, ref int packetLength) - { - var from = state.Mobile; - - if (from == null) - { - return; - } - - EventSink.InvokeStunRequest(from); - } - - public static void DisarmRequest(NetState state, CircularBufferReader reader, ref int packetLength) - { - var from = state.Mobile; - - if (from == null) - { - return; - } - - EventSink.InvokeDisarmRequest(from); - } - - public static void StatLockChange(NetState state, CircularBufferReader reader, ref int packetLength) - { - var from = state.Mobile; - - if (from == null) - { - return; - } - - int stat = reader.ReadByte(); - int lockValue = reader.ReadByte(); - - if (lockValue > 2) - { - lockValue = 0; - } - - switch (stat) - { - case 0: - from.StrLock = (StatLockType)lockValue; - break; - case 1: - from.DexLock = (StatLockType)lockValue; - break; - case 2: - from.IntLock = (StatLockType)lockValue; - break; - } - } - - public static void CloseStatus(NetState state, CircularBufferReader reader, ref int packetLength) - { - var serial = (Serial)reader.ReadUInt32(); - } - - public static void Language(NetState state, CircularBufferReader reader, ref int packetLength) - { - var from = state.Mobile; - - if (from == null) - { - return; - } - - from.Language = reader.ReadAscii(4); - } - - public static void QueryProperties(NetState state, CircularBufferReader reader, ref int packetLength) - { - if (!ObjectPropertyList.Enabled) - { - return; - } - - var from = state.Mobile; - - Serial s = (Serial)reader.ReadUInt32(); - - if (s.IsMobile) - { - var m = World.FindMobile(s); - - if (m != null && from.CanSee(m) && Utility.InUpdateRange(from.Location, m.Location)) - { - m.SendPropertiesTo(from); - } - } - else if (s.IsItem) - { - var item = World.FindItem(s); - - if (item?.Deleted == false && from.CanSee(item) && - Utility.InUpdateRange(from.Location, item.GetWorldLocation())) - { - item.SendPropertiesTo(from); - } - } - } - - public static void ContextMenuResponse(NetState state, CircularBufferReader reader, ref int packetLength) - { - var from = state.Mobile; - - if (from == null) - { - return; - } - - var menu = from.ContextMenu; - - from.ContextMenu = null; - - if (menu != null && from == menu.From) - { - var entity = World.FindEntity((Serial)reader.ReadUInt32()); - - if (entity != null && entity == menu.Target && from.CanSee(entity)) - { - Point3D p; - - if (entity is Mobile) - { - p = entity.Location; - } - else if (entity is Item item) - { - p = item.GetWorldLocation(); - } - else - { - return; - } - - int index = reader.ReadUInt16(); - - if (index >= 0 && index < menu.Entries.Length) - { - var e = menu.Entries[index]; - - var range = e.Range; - - if (range == -1) - { - range = 18; - } - - if (e.Enabled && from.InRange(p, range)) - { - e.OnClick(); - } - } - } - } - } - - public static void ContextMenuRequest(NetState state, CircularBufferReader reader, ref int packetLength) - { - var from = state.Mobile; - var target = World.FindEntity((Serial)reader.ReadUInt32()); - - if (from != null && target != null && from.Map == target.Map && from.CanSee(target)) - { - var item = target as Item; - - var checkLocation = item?.GetWorldLocation() ?? target.Location; - if (!(Utility.InUpdateRange(from.Location, checkLocation) && from.CheckContextMenuDisplay(target))) - { - return; - } - - var c = new ContextMenu(from, target); - - if (c.Entries.Length > 0) - { - if (item?.RootParent is Mobile mobile && mobile != from && mobile.AccessLevel >= from.AccessLevel) - { - for (var i = 0; i < c.Entries.Length; ++i) - { - if (!c.Entries[i].NonLocalUse) - { - c.Entries[i].Enabled = false; - } - } - } - - from.ContextMenu = c; - } - } - } - - public static void BandageTarget(NetState state, CircularBufferReader reader, ref int packetLength) - { - var from = state.Mobile; - - if (from == null) - { - return; - } - - if (from.AccessLevel >= AccessLevel.Counselor || Core.TickCount - from.NextActionTime >= 0) - { - var bandage = World.FindItem((Serial)reader.ReadUInt32()); - - if (bandage == null) - { - return; - } - - var target = World.FindMobile((Serial)reader.ReadUInt32()); - - if (target == null) - { - return; - } - - EventSink.InvokeBandageTargetRequest(from, bandage, target); - - from.NextActionTime = Core.TickCount + Mobile.ActionDelay; - } - else - { - from.SendActionMessage(); - } - } - - public static void TargetedSpell(NetState state, CircularBufferReader reader, ref int packetLength) - { - var spellId = (short)(reader.ReadInt16() - 1); // zero based; - - EventSink.InvokeTargetedSpell(state.Mobile, World.FindEntity((Serial)reader.ReadUInt32()), spellId); - } - - public static void TargetedSkillUse(NetState state, CircularBufferReader reader, ref int packetLength) - { - var skillId = reader.ReadInt16(); - - EventSink.InvokeTargetedSkillUse(state.Mobile, World.FindEntity((Serial)reader.ReadUInt32()), skillId); - } - - public static void TargetByResourceMacro(NetState state, CircularBufferReader reader, ref int packetLength) - { - var serial = (Serial)reader.ReadUInt32(); - - if (serial.IsItem) - { - EventSink.InvokeTargetByResourceMacro(state.Mobile, World.FindItem(serial), reader.ReadInt16()); + item.SendPropertiesTo(from); } } } + + public static void ContextMenuResponse(NetState state, CircularBufferReader reader, ref int packetLength) + { + var from = state.Mobile; + + if (from == null) + { + return; + } + + var menu = from.ContextMenu; + + from.ContextMenu = null; + + if (menu != null && from == menu.From) + { + var entity = World.FindEntity((Serial)reader.ReadUInt32()); + + if (entity != null && entity == menu.Target && from.CanSee(entity)) + { + Point3D p; + + if (entity is Mobile) + { + p = entity.Location; + } + else if (entity is Item item) + { + p = item.GetWorldLocation(); + } + else + { + return; + } + + int index = reader.ReadUInt16(); + + if (index >= 0 && index < menu.Entries.Length) + { + var e = menu.Entries[index]; + + var range = e.Range; + + if (range == -1) + { + range = 18; + } + + if (e.Enabled && from.InRange(p, range)) + { + e.OnClick(); + } + } + } + } + } + + public static void ContextMenuRequest(NetState state, CircularBufferReader reader, ref int packetLength) + { + var from = state.Mobile; + var target = World.FindEntity((Serial)reader.ReadUInt32()); + + if (from != null && target != null && from.Map == target.Map && from.CanSee(target)) + { + var item = target as Item; + + var checkLocation = item?.GetWorldLocation() ?? target.Location; + if (!(Utility.InUpdateRange(from.Location, checkLocation) && from.CheckContextMenuDisplay(target))) + { + return; + } + + var c = new ContextMenu(from, target); + + if (c.Entries.Length > 0) + { + if (item?.RootParent is Mobile mobile && mobile != from && mobile.AccessLevel >= from.AccessLevel) + { + for (var i = 0; i < c.Entries.Length; ++i) + { + if (!c.Entries[i].NonLocalUse) + { + c.Entries[i].Enabled = false; + } + } + } + + from.ContextMenu = c; + } + } + } + + public static void BandageTarget(NetState state, CircularBufferReader reader, ref int packetLength) + { + var from = state.Mobile; + + if (from == null) + { + return; + } + + if (from.AccessLevel >= AccessLevel.Counselor || Core.TickCount - from.NextActionTime >= 0) + { + var bandage = World.FindItem((Serial)reader.ReadUInt32()); + + if (bandage == null) + { + return; + } + + var target = World.FindMobile((Serial)reader.ReadUInt32()); + + if (target == null) + { + return; + } + + EventSink.InvokeBandageTargetRequest(from, bandage, target); + + from.NextActionTime = Core.TickCount + Mobile.ActionDelay; + } + else + { + from.SendActionMessage(); + } + } + + public static void TargetedSpell(NetState state, CircularBufferReader reader, ref int packetLength) + { + var spellId = (short)(reader.ReadInt16() - 1); // zero based; + + EventSink.InvokeTargetedSpell(state.Mobile, World.FindEntity((Serial)reader.ReadUInt32()), spellId); + } + + public static void TargetedSkillUse(NetState state, CircularBufferReader reader, ref int packetLength) + { + var skillId = reader.ReadInt16(); + + EventSink.InvokeTargetedSkillUse(state.Mobile, World.FindEntity((Serial)reader.ReadUInt32()), skillId); + } + + public static void TargetByResourceMacro(NetState state, CircularBufferReader reader, ref int packetLength) + { + var serial = (Serial)reader.ReadUInt32(); + + if (serial.IsItem) + { + EventSink.InvokeTargetByResourceMacro(state.Mobile, World.FindItem(serial), reader.ReadInt16()); + } + } } diff --git a/Projects/Server/Network/Packets/IncomingHousePackets.cs b/Projects/Server/Network/Packets/IncomingHousePackets.cs index 64fd2d4f3..b5969f56c 100644 --- a/Projects/Server/Network/Packets/IncomingHousePackets.cs +++ b/Projects/Server/Network/Packets/IncomingHousePackets.cs @@ -13,18 +13,17 @@ * along with this program. If not, see . * *************************************************************************/ -namespace Server.Network -{ - public static class IncomingHousePackets - { - public static void Configure() - { - IncomingPackets.Register(0xFB, 2, false, ShowPublicHouseContent); - } +namespace Server.Network; - public static void ShowPublicHouseContent(NetState state, CircularBufferReader reader, ref int packetLength) - { - var showPublicHouseContent = reader.ReadBoolean(); - } +public static class IncomingHousePackets +{ + public static void Configure() + { + IncomingPackets.Register(0xFB, 2, false, ShowPublicHouseContent); + } + + public static void ShowPublicHouseContent(NetState state, CircularBufferReader reader, ref int packetLength) + { + var showPublicHouseContent = reader.ReadBoolean(); } } diff --git a/Projects/Server/Network/Packets/IncomingItemPackets.cs b/Projects/Server/Network/Packets/IncomingItemPackets.cs index 6ad33ef4c..0e3cf6601 100644 --- a/Projects/Server/Network/Packets/IncomingItemPackets.cs +++ b/Projects/Server/Network/Packets/IncomingItemPackets.cs @@ -17,159 +17,158 @@ using System.Collections.Generic; using System.IO; using Server.Items; -namespace Server.Network +namespace Server.Network; + +public static class IncomingItemPackets { - public static class IncomingItemPackets + public static void Configure() { - public static void Configure() + IncomingPackets.Register(0x07, 7, true, LiftReq); + IncomingPackets.Register(0x08, 15, true, DropReq); + IncomingPackets.Register(0x13, 10, true, EquipReq); + IncomingPackets.Register(0xEC, 0, false, EquipMacro); + IncomingPackets.Register(0xED, 0, false, UnequipMacro); + } + + public static void LiftReq(NetState state, CircularBufferReader reader, ref int packetLength) + { + var serial = (Serial)reader.ReadUInt32(); + int amount = reader.ReadUInt16(); + var item = World.FindItem(serial); + + state.Mobile.Lift(item, amount, out _, out _); + } + + public static void EquipReq(NetState state, CircularBufferReader reader, ref int packetLength) + { + var from = state.Mobile; + var item = from.Holding; + + var valid = item != null && item.HeldBy == from && item.Map == Map.Internal; + + from.Holding = null; + + if (!valid) { - IncomingPackets.Register(0x07, 7, true, LiftReq); - IncomingPackets.Register(0x08, 15, true, DropReq); - IncomingPackets.Register(0x13, 10, true, EquipReq); - IncomingPackets.Register(0xEC, 0, false, EquipMacro); - IncomingPackets.Register(0xED, 0, false, UnequipMacro); + return; } - public static void LiftReq(NetState state, CircularBufferReader reader, ref int packetLength) - { - var serial = (Serial)reader.ReadUInt32(); - int amount = reader.ReadUInt16(); - var item = World.FindItem(serial); + reader.Seek(5, SeekOrigin.Current); + var to = World.FindMobile((Serial)reader.ReadUInt32()) ?? from; - state.Mobile.Lift(item, amount, out _, out _); + if (!to.AllowEquipFrom(from) || !to.EquipItem(item)) + { + item.Bounce(from); } - public static void EquipReq(NetState state, CircularBufferReader reader, ref int packetLength) + item.ClearBounce(); + } + + public static void DropReq(NetState state, CircularBufferReader reader, ref int packetLength) + { + reader.ReadInt32(); // serial, ignored + int x = reader.ReadInt16(); + int y = reader.ReadInt16(); + int z = reader.ReadSByte(); + if (state.ContainerGridLines) { - var from = state.Mobile; - var item = from.Holding; - - var valid = item != null && item.HeldBy == from && item.Map == Map.Internal; - - from.Holding = null; - - if (!valid) - { - return; - } - - reader.Seek(5, SeekOrigin.Current); - var to = World.FindMobile((Serial)reader.ReadUInt32()) ?? from; - - if (!to.AllowEquipFrom(from) || !to.EquipItem(item)) - { - item.Bounce(from); - } - - item.ClearBounce(); - } - - public static void DropReq(NetState state, CircularBufferReader reader, ref int packetLength) - { - reader.ReadInt32(); // serial, ignored - int x = reader.ReadInt16(); - int y = reader.ReadInt16(); - int z = reader.ReadSByte(); - if (state.ContainerGridLines) - { - reader.ReadByte(); // Grid Location? - } - else - { - packetLength -= 1; - } - - Serial dest = (Serial)reader.ReadUInt32(); - - var loc = new Point3D(x, y, z); - - var from = state.Mobile; - - if (dest.IsMobile) - { - from.Drop(World.FindMobile(dest), loc); - } - else if (dest.IsItem) - { - var item = World.FindItem(dest); - - if (item is BaseMulti multi && multi.AllowsRelativeDrop) - { - loc.m_X += multi.X; - loc.m_Y += multi.Y; - from.Drop(loc); - } - else - { - from.Drop(item, loc); - } - } - else - { - from.Drop(loc); - } - } - - public static void DropReq6017(NetState state, CircularBufferReader reader, ref int packetLength) - { - reader.ReadInt32(); // serial, ignored - int x = reader.ReadInt16(); - int y = reader.ReadInt16(); - int z = reader.ReadSByte(); reader.ReadByte(); // Grid Location? - Serial dest = (Serial)reader.ReadUInt32(); + } + else + { + packetLength -= 1; + } - var loc = new Point3D(x, y, z); + Serial dest = (Serial)reader.ReadUInt32(); - var from = state.Mobile; + var loc = new Point3D(x, y, z); - if (dest.IsMobile) + var from = state.Mobile; + + if (dest.IsMobile) + { + from.Drop(World.FindMobile(dest), loc); + } + else if (dest.IsItem) + { + var item = World.FindItem(dest); + + if (item is BaseMulti multi && multi.AllowsRelativeDrop) { - from.Drop(World.FindMobile(dest), loc); - } - else if (dest.IsItem) - { - var item = World.FindItem(dest); - - if (item is BaseMulti multi && multi.AllowsRelativeDrop) - { - loc.m_X += multi.X; - loc.m_Y += multi.Y; - from.Drop(loc); - } - else - { - from.Drop(item, loc); - } + loc.m_X += multi.X; + loc.m_Y += multi.Y; + from.Drop(loc); } else { - from.Drop(loc); + from.Drop(item, loc); } } - - public static void EquipMacro(NetState state, CircularBufferReader reader, ref int packetLength) + else { - int count = reader.ReadByte(); - var serialList = new List(count); - for (var i = 0; i < count; ++i) - { - serialList.Add((Serial)reader.ReadUInt32()); - } - - EventSink.InvokeEquipMacro(state.Mobile, serialList); - } - - public static void UnequipMacro(NetState state, CircularBufferReader reader, ref int packetLength) - { - int count = reader.ReadByte(); - var layers = new List(count); - for (var i = 0; i < count; ++i) - { - layers.Add((Layer)reader.ReadUInt16()); - } - - EventSink.InvokeUnequipMacro(state.Mobile, layers); + from.Drop(loc); } } + + public static void DropReq6017(NetState state, CircularBufferReader reader, ref int packetLength) + { + reader.ReadInt32(); // serial, ignored + int x = reader.ReadInt16(); + int y = reader.ReadInt16(); + int z = reader.ReadSByte(); + reader.ReadByte(); // Grid Location? + Serial dest = (Serial)reader.ReadUInt32(); + + var loc = new Point3D(x, y, z); + + var from = state.Mobile; + + if (dest.IsMobile) + { + from.Drop(World.FindMobile(dest), loc); + } + else if (dest.IsItem) + { + var item = World.FindItem(dest); + + if (item is BaseMulti multi && multi.AllowsRelativeDrop) + { + loc.m_X += multi.X; + loc.m_Y += multi.Y; + from.Drop(loc); + } + else + { + from.Drop(item, loc); + } + } + else + { + from.Drop(loc); + } + } + + public static void EquipMacro(NetState state, CircularBufferReader reader, ref int packetLength) + { + int count = reader.ReadByte(); + var serialList = new List(count); + for (var i = 0; i < count; ++i) + { + serialList.Add((Serial)reader.ReadUInt32()); + } + + EventSink.InvokeEquipMacro(state.Mobile, serialList); + } + + public static void UnequipMacro(NetState state, CircularBufferReader reader, ref int packetLength) + { + int count = reader.ReadByte(); + var layers = new List(count); + for (var i = 0; i < count; ++i) + { + layers.Add((Layer)reader.ReadUInt16()); + } + + EventSink.InvokeUnequipMacro(state.Mobile, layers); + } } diff --git a/Projects/Server/Network/Packets/IncomingMessagePackets.cs b/Projects/Server/Network/Packets/IncomingMessagePackets.cs index a40355498..0f25bf85e 100644 --- a/Projects/Server/Network/Packets/IncomingMessagePackets.cs +++ b/Projects/Server/Network/Packets/IncomingMessagePackets.cs @@ -15,146 +15,145 @@ using System; -namespace Server.Network +namespace Server.Network; + +[Flags] +public enum MessageType { - [Flags] - public enum MessageType + Regular = 0x00, + System = 0x01, + Emote = 0x02, + Label = 0x06, + Focus = 0x07, + Whisper = 0x08, + Yell = 0x09, + Spell = 0x0A, + + Guild = 0x0D, + Alliance = 0x0E, + Command = 0x0F, + + Encoded = 0xC0 +} + +public static class IncomingMessagePackets +{ + private static readonly KeywordList m_KeywordList = new(); + + public static void Configure() { - Regular = 0x00, - System = 0x01, - Emote = 0x02, - Label = 0x06, - Focus = 0x07, - Whisper = 0x08, - Yell = 0x09, - Spell = 0x0A, - - Guild = 0x0D, - Alliance = 0x0E, - Command = 0x0F, - - Encoded = 0xC0 + IncomingPackets.Register(0x03, 0, true, AsciiSpeech); + IncomingPackets.Register(0xAD, 0, true, UnicodeSpeech); } - public static class IncomingMessagePackets + public static void AsciiSpeech(NetState state, CircularBufferReader reader, ref int packetLength) { - private static readonly KeywordList m_KeywordList = new(); + var from = state.Mobile; - public static void Configure() + if (from == null) { - IncomingPackets.Register(0x03, 0, true, AsciiSpeech); - IncomingPackets.Register(0xAD, 0, true, UnicodeSpeech); + return; } - public static void AsciiSpeech(NetState state, CircularBufferReader reader, ref int packetLength) + var type = (MessageType)reader.ReadByte(); + int hue = reader.ReadInt16(); + reader.ReadInt16(); // font + var text = reader.ReadAsciiSafe().Trim(); + + if (text.Length is <= 0 or > 128) { - var from = state.Mobile; - - if (from == null) - { - return; - } - - var type = (MessageType)reader.ReadByte(); - int hue = reader.ReadInt16(); - reader.ReadInt16(); // font - var text = reader.ReadAsciiSafe().Trim(); - - if (text.Length is <= 0 or > 128) - { - return; - } - - if (!Enum.IsDefined(typeof(MessageType), type)) - { - type = MessageType.Regular; - } - - from.DoSpeech(text, Array.Empty(), type, Utility.ClipDyedHue(hue)); + return; } - public static void UnicodeSpeech(NetState state, CircularBufferReader reader, ref int packetLength) + if (!Enum.IsDefined(typeof(MessageType), type)) { - var from = state.Mobile; + type = MessageType.Regular; + } - if (from == null) + from.DoSpeech(text, Array.Empty(), type, Utility.ClipDyedHue(hue)); + } + + public static void UnicodeSpeech(NetState state, CircularBufferReader reader, ref int packetLength) + { + var from = state.Mobile; + + if (from == null) + { + return; + } + + var type = (MessageType)reader.ReadByte(); + int hue = reader.ReadInt16(); + reader.ReadInt16(); // font + var lang = reader.ReadAscii(4); + string text; + + var isEncoded = (type & MessageType.Encoded) != 0; + int[] keywords; + + if (isEncoded) + { + int value = reader.ReadInt16(); + var count = (value & 0xFFF0) >> 4; + var hold = value & 0xF; + + if (count is < 0 or > 50) { return; } - var type = (MessageType)reader.ReadByte(); - int hue = reader.ReadInt16(); - reader.ReadInt16(); // font - var lang = reader.ReadAscii(4); - string text; + var keyList = m_KeywordList; - var isEncoded = (type & MessageType.Encoded) != 0; - int[] keywords; - - if (isEncoded) + for (var i = 0; i < count; ++i) { - int value = reader.ReadInt16(); - var count = (value & 0xFFF0) >> 4; - var hold = value & 0xF; + int speechID; - if (count is < 0 or > 50) + if ((i & 1) == 0) { - return; + hold <<= 8; + hold |= reader.ReadByte(); + speechID = hold; + hold = 0; + } + else + { + value = reader.ReadInt16(); + speechID = (value & 0xFFF0) >> 4; + hold = value & 0xF; } - var keyList = m_KeywordList; - - for (var i = 0; i < count; ++i) + if (!keyList.Contains(speechID)) { - int speechID; - - if ((i & 1) == 0) - { - hold <<= 8; - hold |= reader.ReadByte(); - speechID = hold; - hold = 0; - } - else - { - value = reader.ReadInt16(); - speechID = (value & 0xFFF0) >> 4; - hold = value & 0xF; - } - - if (!keyList.Contains(speechID)) - { - keyList.Add(speechID); - } + keyList.Add(speechID); } - - text = reader.ReadUTF8Safe(); - - keywords = keyList.ToArray(); - } - else - { - text = reader.ReadBigUniSafe(); - - keywords = Array.Empty(); } - text = text.Trim(); + text = reader.ReadUTF8Safe(); - if (text.Length is <= 0 or > 128) - { - return; - } - - type &= ~MessageType.Encoded; - - if (!Enum.IsDefined(typeof(MessageType), type)) - { - type = MessageType.Regular; - } - - from.Language = lang; - from.DoSpeech(text, keywords, type, Utility.ClipDyedHue(hue)); + keywords = keyList.ToArray(); } + else + { + text = reader.ReadBigUniSafe(); + + keywords = Array.Empty(); + } + + text = text.Trim(); + + if (text.Length is <= 0 or > 128) + { + return; + } + + type &= ~MessageType.Encoded; + + if (!Enum.IsDefined(typeof(MessageType), type)) + { + type = MessageType.Regular; + } + + from.Language = lang; + from.DoSpeech(text, keywords, type, Utility.ClipDyedHue(hue)); } } diff --git a/Projects/Server/Network/Packets/IncomingMobilePackets.cs b/Projects/Server/Network/Packets/IncomingMobilePackets.cs index eed4135ce..569fa430b 100644 --- a/Projects/Server/Network/Packets/IncomingMobilePackets.cs +++ b/Projects/Server/Network/Packets/IncomingMobilePackets.cs @@ -15,152 +15,151 @@ using Server.Items; -namespace Server.Network +namespace Server.Network; + +public static class IncomingMobilePackets { - public static class IncomingMobilePackets + public static void Configure() { - public static void Configure() + IncomingPackets.Register(0x75, 35, true, RenameRequest); + IncomingPackets.Register(0x98, 0, true, MobileNameRequest); + IncomingPackets.Register(0xB8, 0, true, ProfileReq); + IncomingPackets.Register(0x6F, 0, true, SecureTrade); + } + + public static void RenameRequest(NetState state, CircularBufferReader reader, ref int packetLength) + { + var from = state.Mobile; + var targ = World.FindMobile((Serial)reader.ReadUInt32()); + + if (targ != null) { - IncomingPackets.Register(0x75, 35, true, RenameRequest); - IncomingPackets.Register(0x98, 0, true, MobileNameRequest); - IncomingPackets.Register(0xB8, 0, true, ProfileReq); - IncomingPackets.Register(0x6F, 0, true, SecureTrade); + EventSink.InvokeRenameRequest(from, targ, reader.ReadAsciiSafe()); + } + } + + public static void MobileNameRequest(NetState state, CircularBufferReader reader, ref int packetLength) + { + var m = World.FindMobile((Serial)reader.ReadUInt32()); + + if (m != null && Utility.InUpdateRange(state.Mobile.Location, m.Location) && state.Mobile.CanSee(m)) + { + state.SendMobileName(m); + } + } + + public static void ProfileReq(NetState state, CircularBufferReader reader, ref int packetLength) + { + int type = reader.ReadByte(); + var serial = (Serial)reader.ReadUInt32(); + + var beholder = state.Mobile; + var beheld = World.FindMobile(serial); + + if (beheld == null) + { + return; } - public static void RenameRequest(NetState state, CircularBufferReader reader, ref int packetLength) + switch (type) { - var from = state.Mobile; - var targ = World.FindMobile((Serial)reader.ReadUInt32()); + case 0x00: // display request + { + EventSink.InvokeProfileRequest(beholder, beheld); - if (targ != null) - { - EventSink.InvokeRenameRequest(from, targ, reader.ReadAsciiSafe()); - } - } - - public static void MobileNameRequest(NetState state, CircularBufferReader reader, ref int packetLength) - { - var m = World.FindMobile((Serial)reader.ReadUInt32()); - - if (m != null && Utility.InUpdateRange(state.Mobile.Location, m.Location) && state.Mobile.CanSee(m)) - { - state.SendMobileName(m); - } - } - - public static void ProfileReq(NetState state, CircularBufferReader reader, ref int packetLength) - { - int type = reader.ReadByte(); - var serial = (Serial)reader.ReadUInt32(); - - var beholder = state.Mobile; - var beheld = World.FindMobile(serial); - - if (beheld == null) - { - return; - } - - switch (type) - { - case 0x00: // display request - { - EventSink.InvokeProfileRequest(beholder, beheld); - - break; - } - case 0x01: // edit request - { - reader.ReadInt16(); // Skip - int length = reader.ReadUInt16(); - - if (length > 511) - { - return; - } - - var text = reader.ReadBigUni(length); - - EventSink.InvokeChangeProfileRequest(beholder, beheld, text); - - break; - } - } - } - - public static void SecureTrade(NetState state, CircularBufferReader reader, ref int packetLength) - { - switch (reader.ReadByte()) - { - case 1: // Cancel - { - var serial = (Serial)reader.ReadUInt32(); - - if (World.FindItem(serial) is SecureTradeContainer cont && cont.Trade != null && - (cont.Trade.From.Mobile == state.Mobile || cont.Trade.To.Mobile == state.Mobile)) - { - cont.Trade.Cancel(); - } - - break; - } - case 2: // Check - { - var serial = (Serial)reader.ReadUInt32(); - - if (World.FindItem(serial) is SecureTradeContainer cont) - { - var trade = cont.Trade; - - var value = reader.ReadInt32() != 0; - - if (trade != null) - { - if (trade.From.Mobile == state.Mobile) - { - trade.From.Accepted = value; - trade.Update(); - } - else if (trade.To.Mobile == state.Mobile) - { - trade.To.Accepted = value; - trade.Update(); - } - } - } - - break; - } - case 3: // Update Gold - { - var serial = (Serial)reader.ReadUInt32(); - - if (World.FindItem(serial) is SecureTradeContainer cont) - { - var gold = reader.ReadInt32(); - var plat = reader.ReadInt32(); - - var trade = cont.Trade; - - if (trade != null) - { - if (trade.From.Mobile == state.Mobile) - { - trade.From.Gold = gold; - trade.From.Plat = plat; - trade.UpdateFromCurrency(); - } - else if (trade.To.Mobile == state.Mobile) - { - trade.To.Gold = gold; - trade.To.Plat = plat; - trade.UpdateToCurrency(); - } - } - } - } break; - } + } + case 0x01: // edit request + { + reader.ReadInt16(); // Skip + int length = reader.ReadUInt16(); + + if (length > 511) + { + return; + } + + var text = reader.ReadBigUni(length); + + EventSink.InvokeChangeProfileRequest(beholder, beheld, text); + + break; + } + } + } + + public static void SecureTrade(NetState state, CircularBufferReader reader, ref int packetLength) + { + switch (reader.ReadByte()) + { + case 1: // Cancel + { + var serial = (Serial)reader.ReadUInt32(); + + if (World.FindItem(serial) is SecureTradeContainer cont && cont.Trade != null && + (cont.Trade.From.Mobile == state.Mobile || cont.Trade.To.Mobile == state.Mobile)) + { + cont.Trade.Cancel(); + } + + break; + } + case 2: // Check + { + var serial = (Serial)reader.ReadUInt32(); + + if (World.FindItem(serial) is SecureTradeContainer cont) + { + var trade = cont.Trade; + + var value = reader.ReadInt32() != 0; + + if (trade != null) + { + if (trade.From.Mobile == state.Mobile) + { + trade.From.Accepted = value; + trade.Update(); + } + else if (trade.To.Mobile == state.Mobile) + { + trade.To.Accepted = value; + trade.Update(); + } + } + } + + break; + } + case 3: // Update Gold + { + var serial = (Serial)reader.ReadUInt32(); + + if (World.FindItem(serial) is SecureTradeContainer cont) + { + var gold = reader.ReadInt32(); + var plat = reader.ReadInt32(); + + var trade = cont.Trade; + + if (trade != null) + { + if (trade.From.Mobile == state.Mobile) + { + trade.From.Gold = gold; + trade.From.Plat = plat; + trade.UpdateFromCurrency(); + } + else if (trade.To.Mobile == state.Mobile) + { + trade.To.Gold = gold; + trade.To.Plat = plat; + trade.UpdateToCurrency(); + } + } + } + } + break; } } } diff --git a/Projects/Server/Network/Packets/IncomingMovementPackets.cs b/Projects/Server/Network/Packets/IncomingMovementPackets.cs index 9dc38d598..0a82df9a7 100644 --- a/Projects/Server/Network/Packets/IncomingMovementPackets.cs +++ b/Projects/Server/Network/Packets/IncomingMovementPackets.cs @@ -13,88 +13,49 @@ * along with this program. If not, see . * *************************************************************************/ -namespace Server.Network +namespace Server.Network; + +public static class IncomingMovementPackets { - public static class IncomingMovementPackets + public static void Configure() { - public static void Configure() + IncomingPackets.Register(0x02, 7, true, MovementReq); + // Not used by OSI, and interferes with ClassicUO/Razor protocol extensions + // IncomingPackets.Register(0xF0, 0, true, NewMovementReq); + // IncomingPackets.Register(0xF1, 9, true, TimeSyncReq); + } + + public static void NewMovementReq(NetState ns, CircularBufferReader reader) + { + var from = ns.Mobile; + + if (from == null) { - IncomingPackets.Register(0x02, 7, true, MovementReq); - // Not used by OSI, and interferes with ClassicUO/Razor protocol extensions - // IncomingPackets.Register(0xF0, 0, true, NewMovementReq); - // IncomingPackets.Register(0xF1, 9, true, TimeSyncReq); + return; } - public static void NewMovementReq(NetState ns, CircularBufferReader reader) + var steps = reader.ReadByte(); + for (int i = 0; i < steps; i++) { - var from = ns.Mobile; - - if (from == null) - { - return; - } - - var steps = reader.ReadByte(); - for (int i = 0; i < steps; i++) - { - var t1 = reader.ReadUInt64(); // start time? - var t2 = reader.ReadUInt64(); // end time? - int seq = reader.ReadByte(); - var dir = (Direction)reader.ReadByte(); - var mode = reader.ReadInt32(); // 1 = walk, 2 = run - if (mode == 2) - { - dir |= Direction.Running; - } - - // Location - reader.ReadInt32(); // x - reader.ReadInt32(); // y - reader.ReadInt32(); // z - - if (ns.Sequence == 0 && seq != 0 || !from.Move(dir)) - { - ns.SendMovementRej(seq, from); - ns.Sequence = 0; - } - else - { - ++seq; - - if (seq == 256) - { - seq = 1; - } - - ns.Sequence = seq; - } - } - } - - public static void TimeSyncReq(NetState ns, CircularBufferReader reader) - { - reader.ReadUInt64(); // Client Time? - - ns.SendTimeSyncResponse(); - } - - public static void MovementReq(NetState state, CircularBufferReader reader, ref int packetLength) - { - var from = state.Mobile; - - if (from == null) - { - return; - } - - var dir = (Direction)reader.ReadByte(); + var t1 = reader.ReadUInt64(); // start time? + var t2 = reader.ReadUInt64(); // end time? int seq = reader.ReadByte(); - var key = reader.ReadUInt32(); - - if (state.Sequence == 0 && seq != 0 || !from.Move(dir)) + var dir = (Direction)reader.ReadByte(); + var mode = reader.ReadInt32(); // 1 = walk, 2 = run + if (mode == 2) { - state.SendMovementRej(seq, from); - state.Sequence = 0; + dir |= Direction.Running; + } + + // Location + reader.ReadInt32(); // x + reader.ReadInt32(); // y + reader.ReadInt32(); // z + + if (ns.Sequence == 0 && seq != 0 || !from.Move(dir)) + { + ns.SendMovementRej(seq, from); + ns.Sequence = 0; } else { @@ -105,8 +66,46 @@ namespace Server.Network seq = 1; } - state.Sequence = seq; + ns.Sequence = seq; } } } + + public static void TimeSyncReq(NetState ns, CircularBufferReader reader) + { + reader.ReadUInt64(); // Client Time? + + ns.SendTimeSyncResponse(); + } + + public static void MovementReq(NetState state, CircularBufferReader reader, ref int packetLength) + { + var from = state.Mobile; + + if (from == null) + { + return; + } + + var dir = (Direction)reader.ReadByte(); + int seq = reader.ReadByte(); + var key = reader.ReadUInt32(); + + if (state.Sequence == 0 && seq != 0 || !from.Move(dir)) + { + state.SendMovementRej(seq, from); + state.Sequence = 0; + } + else + { + ++seq; + + if (seq == 256) + { + seq = 1; + } + + state.Sequence = seq; + } + } } diff --git a/Projects/Server/Network/Packets/IncomingPackets.cs b/Projects/Server/Network/Packets/IncomingPackets.cs index a99a86053..71fbfd578 100644 --- a/Projects/Server/Network/Packets/IncomingPackets.cs +++ b/Projects/Server/Network/Packets/IncomingPackets.cs @@ -16,91 +16,90 @@ using System.Collections.Generic; using System.Runtime.CompilerServices; -namespace Server.Network +namespace Server.Network; + +public static class IncomingPackets { - public static class IncomingPackets + private static readonly PacketHandler[] m_6017Handlers = new PacketHandler[0x100]; + + private static readonly EncodedPacketHandler[] m_EncodedHandlersLow = new EncodedPacketHandler[0x100]; + + private static readonly Dictionary m_EncodedHandlersHigh = + new(); + + public static PacketHandler[] Handlers { get; } = new PacketHandler[0x100]; + + public static void Register(int packetID, int length, bool ingame, OnPacketReceive onReceive) { - private static readonly PacketHandler[] m_6017Handlers = new PacketHandler[0x100]; + Handlers[packetID] = new PacketHandler(packetID, length, ingame, onReceive); + m_6017Handlers[packetID] ??= new PacketHandler(packetID, length, ingame, onReceive); + } - private static readonly EncodedPacketHandler[] m_EncodedHandlersLow = new EncodedPacketHandler[0x100]; + public static PacketHandler GetHandler(int packetID) => Handlers[packetID]; - private static readonly Dictionary m_EncodedHandlersHigh = - new(); - - public static PacketHandler[] Handlers { get; } = new PacketHandler[0x100]; - - public static void Register(int packetID, int length, bool ingame, OnPacketReceive onReceive) + public static void RegisterEncoded(int packetID, bool ingame, OnEncodedPacketReceive onReceive) + { + if (packetID >= 0 && packetID < 0x100) { - Handlers[packetID] = new PacketHandler(packetID, length, ingame, onReceive); - m_6017Handlers[packetID] ??= new PacketHandler(packetID, length, ingame, onReceive); + m_EncodedHandlersLow[packetID] = new EncodedPacketHandler(packetID, ingame, onReceive); } - - public static PacketHandler GetHandler(int packetID) => Handlers[packetID]; - - public static void RegisterEncoded(int packetID, bool ingame, OnEncodedPacketReceive onReceive) + else { - if (packetID >= 0 && packetID < 0x100) - { - m_EncodedHandlersLow[packetID] = new EncodedPacketHandler(packetID, ingame, onReceive); - } - else - { - m_EncodedHandlersHigh[packetID] = new EncodedPacketHandler(packetID, ingame, onReceive); - } - } - - public static EncodedPacketHandler GetEncodedHandler(int packetID) - { - if (packetID >= 0 && packetID < 0x100) - { - return m_EncodedHandlersLow[packetID]; - } - - m_EncodedHandlersHigh.TryGetValue(packetID, out var handler); - return handler; - } - - public static void RemoveEncodedHandler(int packetID) - { - if (packetID >= 0 && packetID < 0x100) - { - m_EncodedHandlersLow[packetID] = null; - } - else - { - m_EncodedHandlersHigh.Remove(packetID); - } - } - - public static void RegisterThrottler(int packetID, ThrottlePacketCallback t) - { - var ph = GetHandler(packetID); - - if (ph != null) - { - ph.ThrottleCallback = t; - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsInfoPacket(byte packetId) - { - // These packets can arrive at any time during the login process. They're just informational. - return packetId switch - { - 0x01 => true, // Disconnect - 0x73 => true, // Ping - 0xA4 => true, // SystemInfo - 0xB1 => true, // Gump Response - 0xBB => true, // Account ID - 0xBD => true, // Client Version - 0xBE => true, // Assist Version - 0xD9 => true, // Hardware Info - 0xDD => true, // Gumps (Packed) - 0xE1 => true, // Client Type - 0xF4 => true, // CrashReport - _ => false - }; + m_EncodedHandlersHigh[packetID] = new EncodedPacketHandler(packetID, ingame, onReceive); } } + + public static EncodedPacketHandler GetEncodedHandler(int packetID) + { + if (packetID >= 0 && packetID < 0x100) + { + return m_EncodedHandlersLow[packetID]; + } + + m_EncodedHandlersHigh.TryGetValue(packetID, out var handler); + return handler; + } + + public static void RemoveEncodedHandler(int packetID) + { + if (packetID >= 0 && packetID < 0x100) + { + m_EncodedHandlersLow[packetID] = null; + } + else + { + m_EncodedHandlersHigh.Remove(packetID); + } + } + + public static void RegisterThrottler(int packetID, ThrottlePacketCallback t) + { + var ph = GetHandler(packetID); + + if (ph != null) + { + ph.ThrottleCallback = t; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsInfoPacket(byte packetId) + { + // These packets can arrive at any time during the login process. They're just informational. + return packetId switch + { + 0x01 => true, // Disconnect + 0x73 => true, // Ping + 0xA4 => true, // SystemInfo + 0xB1 => true, // Gump Response + 0xBB => true, // Account ID + 0xBD => true, // Client Version + 0xBE => true, // Assist Version + 0xD9 => true, // Hardware Info + 0xDD => true, // Gumps (Packed) + 0xE1 => true, // Client Type + 0xF4 => true, // CrashReport + _ => false + }; + } } diff --git a/Projects/Server/Network/Packets/IncomingPlayerPackets.cs b/Projects/Server/Network/Packets/IncomingPlayerPackets.cs index 00371638d..2b7e14515 100644 --- a/Projects/Server/Network/Packets/IncomingPlayerPackets.cs +++ b/Projects/Server/Network/Packets/IncomingPlayerPackets.cs @@ -19,609 +19,608 @@ using Server.Diagnostics; using Server.Exceptions; using Server.Gumps; -namespace Server.Network +namespace Server.Network; + +public static class IncomingPlayerPackets { - public static class IncomingPlayerPackets + public static void Configure() { - public static void Configure() - { - IncomingPackets.Register(0x01, 5, false, Disconnect); - IncomingPackets.Register(0x05, 5, true, AttackReq); - IncomingPackets.Register(0x12, 0, true, TextCommand); - IncomingPackets.Register(0x22, 3, true, Resynchronize); - IncomingPackets.Register(0x2C, 2, true, DeathStatusResponse); - IncomingPackets.Register(0x34, 10, true, MobileQuery); - IncomingPackets.Register(0x3A, 0, true, ChangeSkillLock); - IncomingPackets.Register(0x72, 5, true, SetWarMode); - IncomingPackets.Register(0x73, 2, false, PingReq); - IncomingPackets.Register(0x7D, 13, true, MenuResponse); - IncomingPackets.Register(0x95, 9, true, HuePickerResponse); - IncomingPackets.Register(0x9A, 0, true, AsciiPromptResponse); - IncomingPackets.Register(0x9B, 258, true, HelpRequest); - IncomingPackets.Register(0xA4, 149, false, SystemInfo); - IncomingPackets.Register(0xA7, 4, true, RequestScrollWindow); - IncomingPackets.Register(0xB1, 0, true, DisplayGumpResponse); - IncomingPackets.Register(0xC2, 0, true, UnicodePromptResponse); - IncomingPackets.Register(0xC8, 2, true, SetUpdateRange); - IncomingPackets.Register(0xD0, 0, true, ConfigurationFile); - IncomingPackets.Register(0xD1, 2, true, LogoutReq); - IncomingPackets.Register(0xD7, 0, true, EncodedCommand); - IncomingPackets.Register(0xF4, 0, false, CrashReport); + IncomingPackets.Register(0x01, 5, false, Disconnect); + IncomingPackets.Register(0x05, 5, true, AttackReq); + IncomingPackets.Register(0x12, 0, true, TextCommand); + IncomingPackets.Register(0x22, 3, true, Resynchronize); + IncomingPackets.Register(0x2C, 2, true, DeathStatusResponse); + IncomingPackets.Register(0x34, 10, true, MobileQuery); + IncomingPackets.Register(0x3A, 0, true, ChangeSkillLock); + IncomingPackets.Register(0x72, 5, true, SetWarMode); + IncomingPackets.Register(0x73, 2, false, PingReq); + IncomingPackets.Register(0x7D, 13, true, MenuResponse); + IncomingPackets.Register(0x95, 9, true, HuePickerResponse); + IncomingPackets.Register(0x9A, 0, true, AsciiPromptResponse); + IncomingPackets.Register(0x9B, 258, true, HelpRequest); + IncomingPackets.Register(0xA4, 149, false, SystemInfo); + IncomingPackets.Register(0xA7, 4, true, RequestScrollWindow); + IncomingPackets.Register(0xB1, 0, true, DisplayGumpResponse); + IncomingPackets.Register(0xC2, 0, true, UnicodePromptResponse); + IncomingPackets.Register(0xC8, 2, true, SetUpdateRange); + IncomingPackets.Register(0xD0, 0, true, ConfigurationFile); + IncomingPackets.Register(0xD1, 2, true, LogoutReq); + IncomingPackets.Register(0xD7, 0, true, EncodedCommand); + IncomingPackets.Register(0xF4, 0, false, CrashReport); - IncomingPackets.RegisterEncoded(0x28, true, GuildGumpRequest); - IncomingPackets.RegisterEncoded(0x32, true, QuestGumpRequest); + IncomingPackets.RegisterEncoded(0x28, true, GuildGumpRequest); + IncomingPackets.RegisterEncoded(0x32, true, QuestGumpRequest); + } + + public static void DeathStatusResponse(NetState state, CircularBufferReader reader, ref int packetLength) + { + // Ignored + } + + public static void RequestScrollWindow(NetState state, CircularBufferReader reader, ref int packetLength) + { + int lastTip = reader.ReadInt16(); + int type = reader.ReadByte(); + } + + public static void AttackReq(NetState state, CircularBufferReader reader, ref int packetLength) + { + var from = state.Mobile; + + if (from == null) + { + return; } - public static void DeathStatusResponse(NetState state, CircularBufferReader reader, ref int packetLength) + var m = World.FindMobile((Serial)reader.ReadUInt32()); + + if (m != null) { - // Ignored + from.Attack(m); } + } - public static void RequestScrollWindow(NetState state, CircularBufferReader reader, ref int packetLength) + public static void HuePickerResponse(NetState state, CircularBufferReader reader, ref int packetLength) + { + var serial = reader.ReadUInt32(); + _ = reader.ReadInt16(); // Item ID + var hue = Utility.ClipDyedHue(reader.ReadInt16() & 0x3FFF); + + foreach (var huePicker in state.HuePickers) { - int lastTip = reader.ReadInt16(); - int type = reader.ReadByte(); - } - - public static void AttackReq(NetState state, CircularBufferReader reader, ref int packetLength) - { - var from = state.Mobile; - - if (from == null) + if (huePicker.Serial == serial) { - return; - } - - var m = World.FindMobile((Serial)reader.ReadUInt32()); - - if (m != null) - { - from.Attack(m); - } - } - - public static void HuePickerResponse(NetState state, CircularBufferReader reader, ref int packetLength) - { - var serial = reader.ReadUInt32(); - _ = reader.ReadInt16(); // Item ID - var hue = Utility.ClipDyedHue(reader.ReadInt16() & 0x3FFF); - - foreach (var huePicker in state.HuePickers) - { - if (huePicker.Serial == serial) - { - state.RemoveHuePicker(huePicker); - huePicker.OnResponse(hue); - break; - } - } - } - - public static void SystemInfo(NetState state, CircularBufferReader reader, ref int packetLength) - { - int v1 = reader.ReadByte(); - int v2 = reader.ReadUInt16(); - int v3 = reader.ReadByte(); - var s1 = reader.ReadAscii(32); - var s2 = reader.ReadAscii(32); - var s3 = reader.ReadAscii(32); - var s4 = reader.ReadAscii(32); - int v4 = reader.ReadUInt16(); - int v5 = reader.ReadUInt16(); - var v6 = reader.ReadInt32(); - var v7 = reader.ReadInt32(); - var v8 = reader.ReadInt32(); - } - - public static void TextCommand(NetState state, CircularBufferReader reader, ref int packetLength) - { - var from = state.Mobile; - - if (from == null) - { - return; - } - - int type = reader.ReadByte(); - var command = reader.ReadAscii(); - - switch (type) - { - case 0xC7: // Animate - { - EventSink.InvokeAnimateRequest(from, command); - - break; - } - case 0x24: // Use skill - { - var tokenizer = command.Tokenize(' '); - if (!tokenizer.MoveNext() || !int.TryParse(tokenizer.Current, out var skillIndex)) - { - break; - } - - Skills.UseSkill(from, skillIndex); - - break; - } - case 0x43: // Open spellbook - { - if (!int.TryParse(command, out var booktype)) - { - booktype = 1; - } - - EventSink.InvokeOpenSpellbookRequest(from, booktype); - - break; - } - case 0x27: // Cast spell from book - { - var tokenizer = command.Tokenize(' '); - var spellID = (tokenizer.MoveNext() ? Utility.ToInt32(tokenizer.Current) : 0) - 1; - var serial = tokenizer.MoveNext() ? (Serial)Utility.ToUInt32(tokenizer.Current) : Serial.MinusOne; - - EventSink.InvokeCastSpellRequest(from, spellID, World.FindItem(serial)); - - break; - } - case 0x58: // Open door - { - EventSink.InvokeOpenDoorMacroUsed(from); - - break; - } - case 0x56: // Cast spell from macro - { - var spellID = Utility.ToInt32(command) - 1; - - EventSink.InvokeCastSpellRequest(from, spellID, null); - - break; - } - case 0xF4: // Invoke virtues from macro - { - var virtueID = Utility.ToInt32(command) - 1; - - EventSink.InvokeVirtueMacroRequest(from, virtueID); - - break; - } - case 0x2F: // Old scroll double click - { - /* - * This command is still sent for items 0xEF3 - 0xEF9 - * - * Command is one of three, depending on the item ID of the scroll: - * - [scroll serial] - * - [scroll serial] [target serial] - * - [scroll serial] [x] [y] [z] - */ - break; - } - default: - { - state.LogInfo("Unknown text-command type 0x{0:X2}: {1}", state, type, command); - break; - } - } - } - - public static void AsciiPromptResponse(NetState state, CircularBufferReader reader, ref int packetLength) - { - var from = state.Mobile; - - if (from == null) - { - return; - } - - var serial = reader.ReadUInt32(); - var prompt = reader.ReadInt32(); - var type = reader.ReadInt32(); - var text = reader.ReadAsciiSafe(); - - if (text.Length > 128) - { - return; - } - - var p = from.Prompt; - - if (p?.Serial == serial && p.Serial == prompt) - { - from.Prompt = null; - - if (type == 0) - { - p.OnCancel(from); - } - else - { - p.OnResponse(from, text); - } - } - } - - public static void UnicodePromptResponse(NetState state, CircularBufferReader reader, ref int packetLength) - { - var from = state.Mobile; - - if (from == null) - { - return; - } - - var serial = reader.ReadUInt32(); - var prompt = reader.ReadInt32(); - var type = reader.ReadInt32(); - var lang = reader.ReadAscii(4); - var text = reader.ReadLittleUniSafe(); - - if (text.Length > 128) - { - return; - } - - var p = from.Prompt; - - if (p?.Serial == serial && p.Serial == prompt) - { - from.Prompt = null; - - if (type == 0) - { - p.OnCancel(from); - } - else - { - p.OnResponse(from, text); - } - } - } - - public static void MenuResponse(NetState state, CircularBufferReader reader, ref int packetLength) - { - var serial = reader.ReadUInt32(); - int menuID = reader.ReadInt16(); // unused in our implementation - int index = reader.ReadInt16(); - int itemID = reader.ReadInt16(); - int hue = reader.ReadInt16(); - - index -= 1; // convert from 1-based to 0-based - - foreach (var menu in state.Menus) - { - if (menu.Serial == serial) - { - state.RemoveMenu(menu); - - if (index >= 0 && index < menu.EntryLength) - { - menu.OnResponse(state, index); - } - else - { - menu.OnCancel(state); - } - - break; - } - } - } - - public static void Disconnect(NetState state, CircularBufferReader reader, ref int packetLength) - { - var minusOne = reader.ReadInt32(); - } - - public static void ConfigurationFile(NetState state, CircularBufferReader reader, ref int packetLength) - { - } - - public static void LogoutReq(NetState state, CircularBufferReader reader, ref int packetLength) - { - state.SendLogoutAck(); - } - - public static void ChangeSkillLock(NetState state, CircularBufferReader reader, ref int packetLength) - { - var s = state.Mobile.Skills[reader.ReadInt16()]; - - s?.SetLockNoRelay((SkillLock)reader.ReadByte()); - } - - public static void HelpRequest(NetState state, CircularBufferReader reader, ref int packetLength) - { - EventSink.InvokeHelpRequest(state.Mobile); - } - - public static void DisplayGumpResponse(NetState state, CircularBufferReader reader, ref int packetLength) - { - var serial = (Serial)reader.ReadUInt32(); - var typeID = reader.ReadInt32(); - var buttonID = reader.ReadInt32(); - - foreach (var gump in state.Gumps) - { - if (gump.Serial != serial || gump.TypeID != typeID) - { - continue; - } - - var buttonExists = buttonID == 0; // 0 is always 'close' - - if (!buttonExists) - { - foreach (var e in gump.Entries) - { - if (e is GumpButton button && button.ButtonID == buttonID) - { - buttonExists = true; - break; - } - - if (e is GumpImageTileButton tileButton && tileButton.ButtonID == buttonID) - { - buttonExists = true; - break; - } - } - } - - if (!buttonExists) - { - state.LogInfo("Invalid gump response, disconnecting..."); - var exception = new InvalidGumpResponseException($"Button {buttonID} doesn't exist"); - exception.SetStackTrace(new StackTrace()); - NetState.TraceException(exception); - state.Mobile?.SendMessage("Invalid gump response."); - - // state.Disconnect("Invalid gump response."); - return; - } - - var switchCount = reader.ReadInt32(); - - if (switchCount < 0 || switchCount > gump.m_Switches) - { - state.LogInfo("Invalid gump response, disconnecting..."); - var exception = new InvalidGumpResponseException($"Bad switch count {switchCount}"); - exception.SetStackTrace(new StackTrace()); - NetState.TraceException(exception); - state.Mobile?.SendMessage("Invalid gump response."); - - // state.Disconnect("Invalid gump response."); - return; - } - - var switches = new int[switchCount]; - - for (var i = 0; i < switches.Length; ++i) - { - switches[i] = reader.ReadInt32(); - } - - var textCount = reader.ReadInt32(); - - if (textCount < 0 || textCount > gump.m_TextEntries) - { - state.LogInfo("Invalid gump response, disconnecting..."); - var exception = new InvalidGumpResponseException($"Bad text entry count {textCount}"); - exception.SetStackTrace(new StackTrace()); - NetState.TraceException(exception); - state.Mobile?.SendMessage("Invalid gump response."); - - // state.Disconnect("Invalid gump response."); - return; - } - - var textEntries = new TextRelay[textCount]; - - for (var i = 0; i < textEntries.Length; ++i) - { - int entryID = reader.ReadUInt16(); - int textLength = reader.ReadUInt16(); - - if (textLength > 239) - { - state.LogInfo("Invalid gump response, disconnecting..."); - var exception = new InvalidGumpResponseException($"Text entry {i} is too long ({textLength})"); - exception.SetStackTrace(new StackTrace()); - NetState.TraceException(exception); - state.Mobile?.SendMessage("Invalid gump response."); - - // state.Disconnect("Invalid gump response."); - return; - } - - var text = reader.ReadBigUniSafe(textLength); - textEntries[i] = new TextRelay(entryID, text); - } - - state.RemoveGump(gump); - - var prof = GumpProfile.Acquire(gump.GetType()); - - prof?.Start(); - - gump.OnResponse(state, new RelayInfo(buttonID, switches, textEntries)); - - prof?.Finish(); - - return; - } - - if (typeID == 461) - { - // Virtue gump - var switchCount = reader.Remaining >= 4 ? reader.ReadInt32() : 0; - - if (buttonID == 1 && switchCount > 0) - { - var beheld = World.FindMobile((Serial)reader.ReadUInt32()); - - if (beheld != null) - { - EventSink.InvokeVirtueGumpRequest(state.Mobile, beheld); - } - } - else - { - var beheld = World.FindMobile(serial); - - if (beheld != null) - { - EventSink.InvokeVirtueItemRequest(state.Mobile, beheld, buttonID); - } - } - } - } - - public static void SetWarMode(NetState state, CircularBufferReader reader, ref int packetLength) - { - state.Mobile?.DelayChangeWarmode(reader.ReadBoolean()); - } - - // TODO: Throttle/make this more safe - public static void Resynchronize(NetState state, CircularBufferReader reader, ref int packetLength) - { - var from = state.Mobile; - - if (from == null) - { - return; - } - - state.SendMobileUpdate(from); - state.SendMobileIncoming(from, from); - - from.SendEverything(); - - state.Sequence = 0; - } - - public static void PingReq(NetState state, CircularBufferReader reader, ref int packetLength) - { - state.SendPingAck(reader.ReadByte()); - } - - public static void SetUpdateRange(NetState state, CircularBufferReader reader, ref int packetLength) - { - state.SendChangeUpdateRange(18); - } - - public static void MobileQuery(NetState state, CircularBufferReader reader, ref int packetLength) - { - var from = state.Mobile; - if (from == null) - { - return; - } - - reader.ReadInt32(); // 0xEDEDEDED - int type = reader.ReadByte(); - var m = World.FindMobile((Serial)reader.ReadUInt32()); - - if (m == null) - { - return; - } - - switch (type) - { - case 0x04: // Stats - { - m.OnStatsQuery(from); - break; - } - case 0x05: - { - m.OnSkillsQuery(from); - break; - } - default: - { - reader.Trace(state); - break; - } - } - } - - public static void CrashReport(NetState state, CircularBufferReader reader, ref int packetLength) - { - var clientMaj = reader.ReadByte(); - var clientMin = reader.ReadByte(); - var clientRev = reader.ReadByte(); - var clientPat = reader.ReadByte(); - - var x = reader.ReadUInt16(); - var y = reader.ReadUInt16(); - var z = reader.ReadSByte(); - var map = reader.ReadByte(); - - var account = reader.ReadAscii(32); - var character = reader.ReadAscii(32); - var ip = reader.ReadAscii(15); - - var unk1 = reader.ReadInt32(); - var exception = reader.ReadInt32(); - - var process = reader.ReadAscii(100); - var report = reader.ReadAscii(100); - - reader.ReadByte(); // 0x00 - - var offset = reader.ReadInt32(); - - int count = reader.ReadByte(); - - for (var i = 0; i < count; i++) - { - var address = reader.ReadInt32(); - } - } - - public static void GuildGumpRequest(NetState state, IEntity e, EncodedReader reader) - { - EventSink.InvokeGuildGumpRequest(state.Mobile); - } - - public static void QuestGumpRequest(NetState state, IEntity e, EncodedReader reader) - { - EventSink.InvokeQuestGumpRequest(state.Mobile); - } - - public static void EncodedCommand(NetState state, CircularBufferReader reader, ref int packetLength) - { - var e = World.FindEntity((Serial)reader.ReadUInt32()); - int packetId = reader.ReadUInt16(); - - var ph = IncomingPackets.GetEncodedHandler(packetId); - - if (ph == null) - { - reader.Trace(state); - return; - } - - if (ph.Ingame && state.Mobile == null) - { - state.LogInfo( - "Sent in-game packet (0xD7x{0:X2}) before being attached to a mobile", - packetId - ); - state.Disconnect($"Sent in-game packet (0xD7x{packetId:X2}) before being attached to a mobile."); - } - else if (ph.Ingame && state.Mobile.Deleted) - { - state.Disconnect($"Sent in-game packet(0xD7x{packetId:X2}) but mobile is deleted."); - } - else - { - ph.OnReceive(state, e, new EncodedReader(reader)); + state.RemoveHuePicker(huePicker); + huePicker.OnResponse(hue); + break; } } } + + public static void SystemInfo(NetState state, CircularBufferReader reader, ref int packetLength) + { + int v1 = reader.ReadByte(); + int v2 = reader.ReadUInt16(); + int v3 = reader.ReadByte(); + var s1 = reader.ReadAscii(32); + var s2 = reader.ReadAscii(32); + var s3 = reader.ReadAscii(32); + var s4 = reader.ReadAscii(32); + int v4 = reader.ReadUInt16(); + int v5 = reader.ReadUInt16(); + var v6 = reader.ReadInt32(); + var v7 = reader.ReadInt32(); + var v8 = reader.ReadInt32(); + } + + public static void TextCommand(NetState state, CircularBufferReader reader, ref int packetLength) + { + var from = state.Mobile; + + if (from == null) + { + return; + } + + int type = reader.ReadByte(); + var command = reader.ReadAscii(); + + switch (type) + { + case 0xC7: // Animate + { + EventSink.InvokeAnimateRequest(from, command); + + break; + } + case 0x24: // Use skill + { + var tokenizer = command.Tokenize(' '); + if (!tokenizer.MoveNext() || !int.TryParse(tokenizer.Current, out var skillIndex)) + { + break; + } + + Skills.UseSkill(from, skillIndex); + + break; + } + case 0x43: // Open spellbook + { + if (!int.TryParse(command, out var booktype)) + { + booktype = 1; + } + + EventSink.InvokeOpenSpellbookRequest(from, booktype); + + break; + } + case 0x27: // Cast spell from book + { + var tokenizer = command.Tokenize(' '); + var spellID = (tokenizer.MoveNext() ? Utility.ToInt32(tokenizer.Current) : 0) - 1; + var serial = tokenizer.MoveNext() ? (Serial)Utility.ToUInt32(tokenizer.Current) : Serial.MinusOne; + + EventSink.InvokeCastSpellRequest(from, spellID, World.FindItem(serial)); + + break; + } + case 0x58: // Open door + { + EventSink.InvokeOpenDoorMacroUsed(from); + + break; + } + case 0x56: // Cast spell from macro + { + var spellID = Utility.ToInt32(command) - 1; + + EventSink.InvokeCastSpellRequest(from, spellID, null); + + break; + } + case 0xF4: // Invoke virtues from macro + { + var virtueID = Utility.ToInt32(command) - 1; + + EventSink.InvokeVirtueMacroRequest(from, virtueID); + + break; + } + case 0x2F: // Old scroll double click + { + /* + * This command is still sent for items 0xEF3 - 0xEF9 + * + * Command is one of three, depending on the item ID of the scroll: + * - [scroll serial] + * - [scroll serial] [target serial] + * - [scroll serial] [x] [y] [z] + */ + break; + } + default: + { + state.LogInfo("Unknown text-command type 0x{0:X2}: {1}", state, type, command); + break; + } + } + } + + public static void AsciiPromptResponse(NetState state, CircularBufferReader reader, ref int packetLength) + { + var from = state.Mobile; + + if (from == null) + { + return; + } + + var serial = reader.ReadUInt32(); + var prompt = reader.ReadInt32(); + var type = reader.ReadInt32(); + var text = reader.ReadAsciiSafe(); + + if (text.Length > 128) + { + return; + } + + var p = from.Prompt; + + if (p?.Serial == serial && p.Serial == prompt) + { + from.Prompt = null; + + if (type == 0) + { + p.OnCancel(from); + } + else + { + p.OnResponse(from, text); + } + } + } + + public static void UnicodePromptResponse(NetState state, CircularBufferReader reader, ref int packetLength) + { + var from = state.Mobile; + + if (from == null) + { + return; + } + + var serial = reader.ReadUInt32(); + var prompt = reader.ReadInt32(); + var type = reader.ReadInt32(); + var lang = reader.ReadAscii(4); + var text = reader.ReadLittleUniSafe(); + + if (text.Length > 128) + { + return; + } + + var p = from.Prompt; + + if (p?.Serial == serial && p.Serial == prompt) + { + from.Prompt = null; + + if (type == 0) + { + p.OnCancel(from); + } + else + { + p.OnResponse(from, text); + } + } + } + + public static void MenuResponse(NetState state, CircularBufferReader reader, ref int packetLength) + { + var serial = reader.ReadUInt32(); + int menuID = reader.ReadInt16(); // unused in our implementation + int index = reader.ReadInt16(); + int itemID = reader.ReadInt16(); + int hue = reader.ReadInt16(); + + index -= 1; // convert from 1-based to 0-based + + foreach (var menu in state.Menus) + { + if (menu.Serial == serial) + { + state.RemoveMenu(menu); + + if (index >= 0 && index < menu.EntryLength) + { + menu.OnResponse(state, index); + } + else + { + menu.OnCancel(state); + } + + break; + } + } + } + + public static void Disconnect(NetState state, CircularBufferReader reader, ref int packetLength) + { + var minusOne = reader.ReadInt32(); + } + + public static void ConfigurationFile(NetState state, CircularBufferReader reader, ref int packetLength) + { + } + + public static void LogoutReq(NetState state, CircularBufferReader reader, ref int packetLength) + { + state.SendLogoutAck(); + } + + public static void ChangeSkillLock(NetState state, CircularBufferReader reader, ref int packetLength) + { + var s = state.Mobile.Skills[reader.ReadInt16()]; + + s?.SetLockNoRelay((SkillLock)reader.ReadByte()); + } + + public static void HelpRequest(NetState state, CircularBufferReader reader, ref int packetLength) + { + EventSink.InvokeHelpRequest(state.Mobile); + } + + public static void DisplayGumpResponse(NetState state, CircularBufferReader reader, ref int packetLength) + { + var serial = (Serial)reader.ReadUInt32(); + var typeID = reader.ReadInt32(); + var buttonID = reader.ReadInt32(); + + foreach (var gump in state.Gumps) + { + if (gump.Serial != serial || gump.TypeID != typeID) + { + continue; + } + + var buttonExists = buttonID == 0; // 0 is always 'close' + + if (!buttonExists) + { + foreach (var e in gump.Entries) + { + if (e is GumpButton button && button.ButtonID == buttonID) + { + buttonExists = true; + break; + } + + if (e is GumpImageTileButton tileButton && tileButton.ButtonID == buttonID) + { + buttonExists = true; + break; + } + } + } + + if (!buttonExists) + { + state.LogInfo("Invalid gump response, disconnecting..."); + var exception = new InvalidGumpResponseException($"Button {buttonID} doesn't exist"); + exception.SetStackTrace(new StackTrace()); + NetState.TraceException(exception); + state.Mobile?.SendMessage("Invalid gump response."); + + // state.Disconnect("Invalid gump response."); + return; + } + + var switchCount = reader.ReadInt32(); + + if (switchCount < 0 || switchCount > gump.m_Switches) + { + state.LogInfo("Invalid gump response, disconnecting..."); + var exception = new InvalidGumpResponseException($"Bad switch count {switchCount}"); + exception.SetStackTrace(new StackTrace()); + NetState.TraceException(exception); + state.Mobile?.SendMessage("Invalid gump response."); + + // state.Disconnect("Invalid gump response."); + return; + } + + var switches = new int[switchCount]; + + for (var i = 0; i < switches.Length; ++i) + { + switches[i] = reader.ReadInt32(); + } + + var textCount = reader.ReadInt32(); + + if (textCount < 0 || textCount > gump.m_TextEntries) + { + state.LogInfo("Invalid gump response, disconnecting..."); + var exception = new InvalidGumpResponseException($"Bad text entry count {textCount}"); + exception.SetStackTrace(new StackTrace()); + NetState.TraceException(exception); + state.Mobile?.SendMessage("Invalid gump response."); + + // state.Disconnect("Invalid gump response."); + return; + } + + var textEntries = new TextRelay[textCount]; + + for (var i = 0; i < textEntries.Length; ++i) + { + int entryID = reader.ReadUInt16(); + int textLength = reader.ReadUInt16(); + + if (textLength > 239) + { + state.LogInfo("Invalid gump response, disconnecting..."); + var exception = new InvalidGumpResponseException($"Text entry {i} is too long ({textLength})"); + exception.SetStackTrace(new StackTrace()); + NetState.TraceException(exception); + state.Mobile?.SendMessage("Invalid gump response."); + + // state.Disconnect("Invalid gump response."); + return; + } + + var text = reader.ReadBigUniSafe(textLength); + textEntries[i] = new TextRelay(entryID, text); + } + + state.RemoveGump(gump); + + var prof = GumpProfile.Acquire(gump.GetType()); + + prof?.Start(); + + gump.OnResponse(state, new RelayInfo(buttonID, switches, textEntries)); + + prof?.Finish(); + + return; + } + + if (typeID == 461) + { + // Virtue gump + var switchCount = reader.Remaining >= 4 ? reader.ReadInt32() : 0; + + if (buttonID == 1 && switchCount > 0) + { + var beheld = World.FindMobile((Serial)reader.ReadUInt32()); + + if (beheld != null) + { + EventSink.InvokeVirtueGumpRequest(state.Mobile, beheld); + } + } + else + { + var beheld = World.FindMobile(serial); + + if (beheld != null) + { + EventSink.InvokeVirtueItemRequest(state.Mobile, beheld, buttonID); + } + } + } + } + + public static void SetWarMode(NetState state, CircularBufferReader reader, ref int packetLength) + { + state.Mobile?.DelayChangeWarmode(reader.ReadBoolean()); + } + + // TODO: Throttle/make this more safe + public static void Resynchronize(NetState state, CircularBufferReader reader, ref int packetLength) + { + var from = state.Mobile; + + if (from == null) + { + return; + } + + state.SendMobileUpdate(from); + state.SendMobileIncoming(from, from); + + from.SendEverything(); + + state.Sequence = 0; + } + + public static void PingReq(NetState state, CircularBufferReader reader, ref int packetLength) + { + state.SendPingAck(reader.ReadByte()); + } + + public static void SetUpdateRange(NetState state, CircularBufferReader reader, ref int packetLength) + { + state.SendChangeUpdateRange(18); + } + + public static void MobileQuery(NetState state, CircularBufferReader reader, ref int packetLength) + { + var from = state.Mobile; + if (from == null) + { + return; + } + + reader.ReadInt32(); // 0xEDEDEDED + int type = reader.ReadByte(); + var m = World.FindMobile((Serial)reader.ReadUInt32()); + + if (m == null) + { + return; + } + + switch (type) + { + case 0x04: // Stats + { + m.OnStatsQuery(from); + break; + } + case 0x05: + { + m.OnSkillsQuery(from); + break; + } + default: + { + reader.Trace(state); + break; + } + } + } + + public static void CrashReport(NetState state, CircularBufferReader reader, ref int packetLength) + { + var clientMaj = reader.ReadByte(); + var clientMin = reader.ReadByte(); + var clientRev = reader.ReadByte(); + var clientPat = reader.ReadByte(); + + var x = reader.ReadUInt16(); + var y = reader.ReadUInt16(); + var z = reader.ReadSByte(); + var map = reader.ReadByte(); + + var account = reader.ReadAscii(32); + var character = reader.ReadAscii(32); + var ip = reader.ReadAscii(15); + + var unk1 = reader.ReadInt32(); + var exception = reader.ReadInt32(); + + var process = reader.ReadAscii(100); + var report = reader.ReadAscii(100); + + reader.ReadByte(); // 0x00 + + var offset = reader.ReadInt32(); + + int count = reader.ReadByte(); + + for (var i = 0; i < count; i++) + { + var address = reader.ReadInt32(); + } + } + + public static void GuildGumpRequest(NetState state, IEntity e, EncodedReader reader) + { + EventSink.InvokeGuildGumpRequest(state.Mobile); + } + + public static void QuestGumpRequest(NetState state, IEntity e, EncodedReader reader) + { + EventSink.InvokeQuestGumpRequest(state.Mobile); + } + + public static void EncodedCommand(NetState state, CircularBufferReader reader, ref int packetLength) + { + var e = World.FindEntity((Serial)reader.ReadUInt32()); + int packetId = reader.ReadUInt16(); + + var ph = IncomingPackets.GetEncodedHandler(packetId); + + if (ph == null) + { + reader.Trace(state); + return; + } + + if (ph.Ingame && state.Mobile == null) + { + state.LogInfo( + "Sent in-game packet (0xD7x{0:X2}) before being attached to a mobile", + packetId + ); + state.Disconnect($"Sent in-game packet (0xD7x{packetId:X2}) before being attached to a mobile."); + } + else if (ph.Ingame && state.Mobile.Deleted) + { + state.Disconnect($"Sent in-game packet(0xD7x{packetId:X2}) but mobile is deleted."); + } + else + { + ph.OnReceive(state, e, new EncodedReader(reader)); + } + } } diff --git a/Projects/Server/Network/Packets/IncomingTargetingPackets.cs b/Projects/Server/Network/Packets/IncomingTargetingPackets.cs index b87b221de..1d03d85e9 100644 --- a/Projects/Server/Network/Packets/IncomingTargetingPackets.cs +++ b/Projects/Server/Network/Packets/IncomingTargetingPackets.cs @@ -16,130 +16,129 @@ using Server.Diagnostics; using Server.Targeting; -namespace Server.Network +namespace Server.Network; + +public static class IncomingTargetingPackets { - public static class IncomingTargetingPackets + public static void Configure() { - public static void Configure() + IncomingPackets.Register(0x6C, 19, true, TargetResponse); + } + + public static void TargetResponse(NetState state, CircularBufferReader reader, ref int packetLength) + { + int type = reader.ReadByte(); + var targetID = reader.ReadInt32(); + int flags = reader.ReadByte(); + var serial = (Serial)reader.ReadUInt32(); + int x = reader.ReadInt16(); + int y = reader.ReadInt16(); + reader.ReadByte(); + int z = reader.ReadSByte(); + int graphic = reader.ReadUInt16(); + + if (targetID == unchecked((int)0xDEADBEEF)) { - IncomingPackets.Register(0x6C, 19, true, TargetResponse); + return; } - public static void TargetResponse(NetState state, CircularBufferReader reader, ref int packetLength) + var from = state.Mobile; + + var t = from.Target; + + if (t == null) { - int type = reader.ReadByte(); - var targetID = reader.ReadInt32(); - int flags = reader.ReadByte(); - var serial = (Serial)reader.ReadUInt32(); - int x = reader.ReadInt16(); - int y = reader.ReadInt16(); - reader.ReadByte(); - int z = reader.ReadSByte(); - int graphic = reader.ReadUInt16(); + return; + } - if (targetID == unchecked((int)0xDEADBEEF)) + var prof = TargetProfile.Acquire(t.GetType()); + prof?.Start(); + + try + { + if (x == -1 && y == -1 && !serial.IsValid) { - return; + // User pressed escape + t.Cancel(from, TargetCancelType.Canceled); } - - var from = state.Mobile; - - var t = from.Target; - - if (t == null) + else if (t.TargetID != targetID) { - return; + // Sanity, prevent fake target } - - var prof = TargetProfile.Acquire(t.GetType()); - prof?.Start(); - - try + else { - if (x == -1 && y == -1 && !serial.IsValid) - { - // User pressed escape - t.Cancel(from, TargetCancelType.Canceled); - } - else if (t.TargetID != targetID) - { - // Sanity, prevent fake target - } - else - { - object toTarget; + object toTarget; - if (type == 1) + if (type == 1) + { + if (graphic == 0) { - if (graphic == 0) + toTarget = new LandTarget(new Point3D(x, y, z), from.Map); + } + else + { + var map = from.Map; + + if (map == null || map == Map.Internal) { - toTarget = new LandTarget(new Point3D(x, y, z), from.Map); + t.Cancel(from, TargetCancelType.Canceled); + return; } else { - var map = from.Map; + var tiles = map.Tiles.GetStaticTiles(x, y, !t.DisallowMultis); - if (map == null || map == Map.Internal) + var valid = false; + + if (state.HighSeas) + { + var id = TileData.ItemTable[graphic & TileData.MaxItemValue]; + if (id.Surface) + { + z -= id.Height; + } + } + + for (var i = 0; !valid && i < tiles.Length; ++i) + { + if (tiles[i].Z == z && tiles[i].ID == graphic) + { + valid = true; + } + } + + if (!valid) { t.Cancel(from, TargetCancelType.Canceled); return; } else { - var tiles = map.Tiles.GetStaticTiles(x, y, !t.DisallowMultis); - - var valid = false; - - if (state.HighSeas) - { - var id = TileData.ItemTable[graphic & TileData.MaxItemValue]; - if (id.Surface) - { - z -= id.Height; - } - } - - for (var i = 0; !valid && i < tiles.Length; ++i) - { - if (tiles[i].Z == z && tiles[i].ID == graphic) - { - valid = true; - } - } - - if (!valid) - { - t.Cancel(from, TargetCancelType.Canceled); - return; - } - else - { - toTarget = new StaticTarget(new Point3D(x, y, z), graphic); - } + toTarget = new StaticTarget(new Point3D(x, y, z), graphic); } } } - else if (serial.IsMobile) - { - toTarget = World.FindMobile(serial); - } - else if (serial.IsItem) - { - toTarget = World.FindItem(serial); - } - else - { - t.Cancel(from, TargetCancelType.Canceled); - return; - } - - t.Invoke(from, toTarget); } + else if (serial.IsMobile) + { + toTarget = World.FindMobile(serial); + } + else if (serial.IsItem) + { + toTarget = World.FindItem(serial); + } + else + { + t.Cancel(from, TargetCancelType.Canceled); + return; + } + + t.Invoke(from, toTarget); } - finally - { - prof?.Finish(); - } + } + finally + { + prof?.Finish(); } } } diff --git a/Projects/Server/Network/Packets/IncomingVendorPackets.cs b/Projects/Server/Network/Packets/IncomingVendorPackets.cs index 4a9f9cf8a..0a11dd2d4 100644 --- a/Projects/Server/Network/Packets/IncomingVendorPackets.cs +++ b/Projects/Server/Network/Packets/IncomingVendorPackets.cs @@ -15,96 +15,95 @@ using System.Collections.Generic; -namespace Server.Network +namespace Server.Network; + +public static class IncomingVendorPackets { - public static class IncomingVendorPackets + public static void Configure() { - public static void Configure() + IncomingPackets.Register(0x3B, 0, true, VendorBuyReply); + IncomingPackets.Register(0x9F, 0, true, VendorSellReply); + } + + public static void VendorBuyReply(NetState state, CircularBufferReader reader, ref int packetLength) + { + var vendor = World.FindMobile((Serial)reader.ReadUInt32()); + + if (vendor == null) { - IncomingPackets.Register(0x3B, 0, true, VendorBuyReply); - IncomingPackets.Register(0x9F, 0, true, VendorSellReply); + return; } - public static void VendorBuyReply(NetState state, CircularBufferReader reader, ref int packetLength) + var flag = reader.ReadByte(); + + if (!vendor.Deleted && Utility.InRange(vendor.Location, state.Mobile.Location, 10) && flag == 0x02) { - var vendor = World.FindMobile((Serial)reader.ReadUInt32()); + var msgSize = packetLength - 8; // Remaining bytes - if (vendor == null) + if (msgSize / 7 > 100) { return; } - var flag = reader.ReadByte(); - - if (!vendor.Deleted && Utility.InRange(vendor.Location, state.Mobile.Location, 10) && flag == 0x02) + var buyList = new List(msgSize / 7); + while (msgSize > 0) { - var msgSize = packetLength - 8; // Remaining bytes - - if (msgSize / 7 > 100) - { - return; - } - - var buyList = new List(msgSize / 7); - while (msgSize > 0) - { - var layer = reader.ReadByte(); - var serial = (Serial)reader.ReadUInt32(); - int amount = reader.ReadInt16(); - - buyList.Add(new BuyItemResponse(serial, amount)); - msgSize -= 7; - } - - if (buyList.Count <= 0 || (vendor as IVendor)?.OnBuyItems(state.Mobile, buyList) != true) - { - return; - } - } - - state.SendEndVendorBuy(vendor.Serial); - } - - public static void VendorSellReply(NetState state, CircularBufferReader reader, ref int packetLength) - { - var serial = (Serial)reader.ReadUInt32(); - var vendor = World.FindMobile(serial); - - if (vendor == null) - { - return; - } - - if (vendor.Deleted || !Utility.InRange(vendor.Location, state.Mobile.Location, 10)) - { - state.SendEndVendorSell(vendor.Serial); - return; - } - - int count = reader.ReadUInt16(); - - if (count >= 100 || reader.Remaining != count * 6) - { - return; - } - - var sellList = new List(count); - - for (var i = 0; i < count; i++) - { - var item = World.FindItem((Serial)reader.ReadUInt32()); + var layer = reader.ReadByte(); + var serial = (Serial)reader.ReadUInt32(); int amount = reader.ReadInt16(); - if (item != null && amount > 0) - { - sellList.Add(new SellItemResponse(item, amount)); - } + buyList.Add(new BuyItemResponse(serial, amount)); + msgSize -= 7; } - if (sellList.Count > 0 && vendor is IVendor v && v.OnSellItems(state.Mobile, sellList)) + if (buyList.Count <= 0 || (vendor as IVendor)?.OnBuyItems(state.Mobile, buyList) != true) { - state.SendEndVendorSell(vendor.Serial); + return; } } + + state.SendEndVendorBuy(vendor.Serial); + } + + public static void VendorSellReply(NetState state, CircularBufferReader reader, ref int packetLength) + { + var serial = (Serial)reader.ReadUInt32(); + var vendor = World.FindMobile(serial); + + if (vendor == null) + { + return; + } + + if (vendor.Deleted || !Utility.InRange(vendor.Location, state.Mobile.Location, 10)) + { + state.SendEndVendorSell(vendor.Serial); + return; + } + + int count = reader.ReadUInt16(); + + if (count >= 100 || reader.Remaining != count * 6) + { + return; + } + + var sellList = new List(count); + + for (var i = 0; i < count; i++) + { + var item = World.FindItem((Serial)reader.ReadUInt32()); + int amount = reader.ReadInt16(); + + if (item != null && amount > 0) + { + sellList.Add(new SellItemResponse(item, amount)); + } + } + + if (sellList.Count > 0 && vendor is IVendor v && v.OnSellItems(state.Mobile, sellList)) + { + state.SendEndVendorSell(vendor.Serial); + } } } diff --git a/Projects/Server/Network/Packets/OutgoingAccountPackets.cs b/Projects/Server/Network/Packets/OutgoingAccountPackets.cs index f49793649..d29a8cbe4 100644 --- a/Projects/Server/Network/Packets/OutgoingAccountPackets.cs +++ b/Projects/Server/Network/Packets/OutgoingAccountPackets.cs @@ -19,436 +19,435 @@ using System.Buffers; using System.Runtime.CompilerServices; using Server.Accounting; -namespace Server.Network +namespace Server.Network; + +public enum ALRReason : byte { - public enum ALRReason : byte - { - Invalid = 0, - InUse = 1, - Blocked = 2, - BadPass = 3, - Idle = 254, - BadComm = 255 - } + Invalid = 0, + InUse = 1, + Blocked = 2, + BadPass = 3, + Idle = 254, + BadComm = 255 +} - public enum PMMessage : byte - { - None = 0, - CharNoExist = 1, - CharExists = 2, - CharInWorld = 5, - LoginSyncError = 6, - IdleWarning = 7 - } +public enum PMMessage : byte +{ + None = 0, + CharNoExist = 1, + CharExists = 2, + CharInWorld = 5, + LoginSyncError = 6, + IdleWarning = 7 +} - public enum DeleteResultType - { - PasswordInvalid, - CharNotExist, - CharBeingPlayed, - CharTooYoung, - CharQueued, - BadRequest - } +public enum DeleteResultType +{ + PasswordInvalid, + CharNotExist, + CharBeingPlayed, + CharTooYoung, + CharQueued, + BadRequest +} - public static class OutgoingAccountPackets - { - /** +public static class OutgoingAccountPackets +{ + /** * Packet: 0x81 * Length: Up to 425 bytes * * Displays the list of characters during the login process. * Note: Currently Unused */ - public static void SendChangeCharacter(this NetState ns, IAccount a) + public static void SendChangeCharacter(this NetState ns, IAccount a) + { + if (ns == null || a == null) { - if (ns == null || a == null) - { - return; - } - - var length = 5 + a.Length * 60; - var writer = new SpanWriter(stackalloc byte[length]); - - writer.Write((byte)0x81); // Packet ID - writer.Write((ushort)length); - writer.Write((ushort)0); // Count & Placeholder - - int count = 0; - - for (var i = 0; i < a.Length; ++i) - { - var m = a[i]; - - if (m == null) - { - writer.Clear(60); - } - else - { - var name = (m.RawName?.Trim()).DefaultIfNullOrEmpty("-no name-"); - - count++; - writer.WriteAscii(name, 30); - writer.Clear(30); // Password (empty) - } - } - - var position = writer.Position; - writer.Seek(3, SeekOrigin.Begin); - writer.Write((byte)count); - writer.Seek(position, SeekOrigin.Begin); - - ns.Send(writer.Span); + return; } - /** + var length = 5 + a.Length * 60; + var writer = new SpanWriter(stackalloc byte[length]); + + writer.Write((byte)0x81); // Packet ID + writer.Write((ushort)length); + writer.Write((ushort)0); // Count & Placeholder + + int count = 0; + + for (var i = 0; i < a.Length; ++i) + { + var m = a[i]; + + if (m == null) + { + writer.Clear(60); + } + else + { + var name = (m.RawName?.Trim()).DefaultIfNullOrEmpty("-no name-"); + + count++; + writer.WriteAscii(name, 30); + writer.Clear(30); // Password (empty) + } + } + + var position = writer.Position; + writer.Seek(3, SeekOrigin.Begin); + writer.Write((byte)count); + writer.Seek(position, SeekOrigin.Begin); + + ns.Send(writer.Span); + } + + /** * Packet: 0xBD * Length: 3 bytes * * Sends a requests for the client version */ - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void SendClientVersionRequest(this NetState ns) => ns?.Send(stackalloc byte[] { 0xBD, 0x00, 0x03 }); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SendClientVersionRequest(this NetState ns) => ns?.Send(stackalloc byte[] { 0xBD, 0x00, 0x03 }); - /** + /** * Packet: 0x85 * Length: 2 bytes * * Sends the result of a deletion request */ - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void SendCharacterDeleteResult(this NetState ns, DeleteResultType res) => - ns?.Send(stackalloc byte[] { 0x85, (byte)res }); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SendCharacterDeleteResult(this NetState ns, DeleteResultType res) => + ns?.Send(stackalloc byte[] { 0x85, (byte)res }); - /** + /** * Packet: 0x53 * Length: 2 bytes * * Sends a PopupMessage with a predetermined message */ - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void SendPopupMessage(this NetState ns, PMMessage msg) => - ns?.Send(stackalloc byte[] { 0x53, (byte)msg }); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SendPopupMessage(this NetState ns, PMMessage msg) => + ns?.Send(stackalloc byte[] { 0x53, (byte)msg }); - /** + /** * Packet: 0xB9 * Length: 3 or 5 bytes * * Sends support features based on the client version */ - public static void SendSupportedFeature(this NetState ns) + public static void SendSupportedFeature(this NetState ns) + { + if (ns.CannotSendPackets()) { - if (ns == null) + return; + } + + var flags = ExpansionInfo.CoreExpansion.SupportedFeatures; + + if (ns.Account.Limit >= 6) + { + flags |= FeatureFlags.LiveAccount; + flags &= ~FeatureFlags.UOTD; + + if (ns.Account.Limit > 6) { - return; - } - - var flags = ExpansionInfo.CoreExpansion.SupportedFeatures; - - if (ns.Account.Limit >= 6) - { - flags |= FeatureFlags.LiveAccount; - flags &= ~FeatureFlags.UOTD; - - if (ns.Account.Limit > 6) - { - flags |= FeatureFlags.SeventhCharacterSlot; - } - else - { - flags |= FeatureFlags.SixthCharacterSlot; - } - } - - var length = ns.ExtendedSupportedFeatures ? 5 : 3; - var writer = new SpanWriter(stackalloc byte[length]); - writer.Write((byte)0xB9); // Packet ID - - if (ns.ExtendedSupportedFeatures) - { - writer.Write((uint)flags); + flags |= FeatureFlags.SeventhCharacterSlot; } else { - writer.Write((ushort)flags); + flags |= FeatureFlags.SixthCharacterSlot; } - - ns.Send(writer.Span); } - /** + var length = ns.ExtendedSupportedFeatures ? 5 : 3; + var writer = new SpanWriter(stackalloc byte[length]); + writer.Write((byte)0xB9); // Packet ID + + if (ns.ExtendedSupportedFeatures) + { + writer.Write((uint)flags); + } + else + { + writer.Write((ushort)flags); + } + + ns.Send(writer.Span); + } + + /** * Packet: 0x1B * Length: 37 bytes * * Sends login confirmation */ - public static void SendLoginConfirmation(this NetState ns, Mobile m) + public static void SendLoginConfirmation(this NetState ns, Mobile m) + { + if (ns.CannotSendPackets()) { - if (ns == null) - { - return; - } - - var writer = new SpanWriter(stackalloc byte[37]); - writer.Write((byte)0x1B); // PacketID - writer.Write(m.Serial); - writer.Write(0); - writer.Write((short)m.Body); - writer.Write((short)m.X); - writer.Write((short)m.Y); - writer.Write((short)m.Z); - writer.Write((byte)m.Direction); - writer.Write((byte)0); - writer.Write(-1); - - writer.Write(0); - - var map = m.Map; - - if (map == null || map == Map.Internal) - { - map = m.LogoutMap; - } - - writer.Write((short)(map?.Width ?? Map.Felucca.Width)); - writer.Write((short)(map?.Height ?? Map.Felucca.Height)); - writer.Clear(writer.Capacity - writer.Position); // Remaining is zero - - ns.Send(writer.Span); + return; } - /** + var writer = new SpanWriter(stackalloc byte[37]); + writer.Write((byte)0x1B); // PacketID + writer.Write(m.Serial); + writer.Write(0); + writer.Write((short)m.Body); + writer.Write((short)m.X); + writer.Write((short)m.Y); + writer.Write((short)m.Z); + writer.Write((byte)m.Direction); + writer.Write((byte)0); + writer.Write(-1); + + writer.Write(0); + + var map = m.Map; + + if (map == null || map == Map.Internal) + { + map = m.LogoutMap; + } + + writer.Write((short)(map?.Width ?? Map.Felucca.Width)); + writer.Write((short)(map?.Height ?? Map.Felucca.Height)); + writer.Clear(writer.Capacity - writer.Position); // Remaining is zero + + ns.Send(writer.Span); + } + + /** * Packet: 0x55 * Length: 1 byte * * Sends login completion */ - public static void SendLoginComplete(this NetState ns) - { - ns?.Send(stackalloc byte[] { 0x55 }); - } + public static void SendLoginComplete(this NetState ns) + { + ns?.Send(stackalloc byte[] { 0x55 }); + } - /** + /** * Packet: 0x86 * Length: Up to 424 bytes * * Sends updated character list */ - public static void SendCharacterListUpdate(this NetState ns, IAccount a) + public static void SendCharacterListUpdate(this NetState ns, IAccount a) + { + if (ns == null || a == null) { - if (ns == null || a == null) - { - return; - } - - var highSlot = -1; - - for (var i = a.Length - 1; i >= 0; i--) - { - if (a[i] != null) - { - highSlot = i; - break; - } - } - - var count = Math.Max(Math.Max(highSlot + 1, a.Limit), 5); - var length = 4 + count * 60; - var writer = new SpanWriter(stackalloc byte[length]); - writer.Write((byte)0x86); // Packet ID - writer.Write((ushort)length); - - writer.Write((byte)count); - - for (int i = 0; i < count; i++) - { - var m = a[i]; - - if (m == null) - { - writer.Clear(60); - } - else - { - var name = (m.RawName?.Trim()).DefaultIfNullOrEmpty("-no name-"); - writer.WriteAscii(name, 30); - writer.Clear(30); // password - } - } - - ns.Send(writer.Span); + return; } - /** + var highSlot = -1; + + for (var i = a.Length - 1; i >= 0; i--) + { + if (a[i] != null) + { + highSlot = i; + break; + } + } + + var count = Math.Max(Math.Max(highSlot + 1, a.Limit), 5); + var length = 4 + count * 60; + var writer = new SpanWriter(stackalloc byte[length]); + writer.Write((byte)0x86); // Packet ID + writer.Write((ushort)length); + + writer.Write((byte)count); + + for (int i = 0; i < count; i++) + { + var m = a[i]; + + if (m == null) + { + writer.Clear(60); + } + else + { + var name = (m.RawName?.Trim()).DefaultIfNullOrEmpty("-no name-"); + writer.WriteAscii(name, 30); + writer.Clear(30); // password + } + } + + ns.Send(writer.Span); + } + + /** * Packet: 0xA9 * Length: 1410 or more bytes * * Sends list of characters and starting cities. */ - public static void SendCharacterList(this NetState ns) + public static void SendCharacterList(this NetState ns) + { + var acct = ns?.Account; + + if (acct == null) { - var acct = ns?.Account; - - if (acct == null) - { - return; - } - - var client70130 = ns.NewCharacterList; - var textLength = client70130 ? 32 : 31; - - var cityInfo = ns.CityInfo; - - var highSlot = -1; - - for (var i = acct.Length - 1; i >= 0; i--) - { - if (acct[i] != null) - { - highSlot = i; - break; - } - } - - var count = Math.Max(Math.Max(highSlot + 1, acct.Limit), 5); - var length = (client70130 ? - 11 + (textLength * 2 + 25) * cityInfo.Length : - 9 + (textLength * 2 + 1) * cityInfo.Length) + count * 60; - var writer = new SpanWriter(stackalloc byte[length]); - writer.Write((byte)0xA9); // Packet ID - writer.Write((ushort)length); - writer.Write((byte)count); - - for (int i = 0; i < count; i++) - { - var m = acct[i]; - - if (m == null) - { - writer.Clear(60); - } - else - { - var name = (m.RawName?.Trim()).DefaultIfNullOrEmpty("-no name-"); - writer.WriteAscii(name, 30); - writer.Clear(30); // password - } - } - - writer.Write((byte)cityInfo.Length); - - for (int i = 0; i < cityInfo.Length; ++i) - { - var ci = cityInfo[i]; - - writer.Write((byte)i); - writer.WriteAscii(ci.City, textLength); - writer.WriteAscii(ci.Building, textLength); - if (client70130) - { - writer.Write(ci.X); - writer.Write(ci.Y); - writer.Write(ci.Z); - writer.Write(ci.Map?.MapID ?? 0); - writer.Write(ci.Description); - writer.Write(0); - } - } - - var flags = ExpansionInfo.CoreExpansion.CharacterListFlags; - - if (count > 6) - { - flags |= CharacterListFlags.SeventhCharacterSlot | - CharacterListFlags.SixthCharacterSlot; // 7th Character Slot - TODO: Is SixthCharacterSlot Required? - } - else if (count == 6) - { - flags |= CharacterListFlags.SixthCharacterSlot; // 6th Character Slot - } - else if (acct.Limit == 1) - { - flags |= CharacterListFlags.SlotLimit & - CharacterListFlags.OneCharacterSlot; // Limit Characters & One Character - } - - writer.Write((int)flags); - if (client70130) - { - writer.Write((short)-1); - } - - ns.Send(writer.Span); + return; } - /** + var client70130 = ns.NewCharacterList; + var textLength = client70130 ? 32 : 31; + + var cityInfo = ns.CityInfo; + + var highSlot = -1; + + for (var i = acct.Length - 1; i >= 0; i--) + { + if (acct[i] != null) + { + highSlot = i; + break; + } + } + + var count = Math.Max(Math.Max(highSlot + 1, acct.Limit), 5); + var length = (client70130 ? + 11 + (textLength * 2 + 25) * cityInfo.Length : + 9 + (textLength * 2 + 1) * cityInfo.Length) + count * 60; + var writer = new SpanWriter(stackalloc byte[length]); + writer.Write((byte)0xA9); // Packet ID + writer.Write((ushort)length); + writer.Write((byte)count); + + for (int i = 0; i < count; i++) + { + var m = acct[i]; + + if (m == null) + { + writer.Clear(60); + } + else + { + var name = (m.RawName?.Trim()).DefaultIfNullOrEmpty("-no name-"); + writer.WriteAscii(name, 30); + writer.Clear(30); // password + } + } + + writer.Write((byte)cityInfo.Length); + + for (int i = 0; i < cityInfo.Length; ++i) + { + var ci = cityInfo[i]; + + writer.Write((byte)i); + writer.WriteAscii(ci.City, textLength); + writer.WriteAscii(ci.Building, textLength); + if (client70130) + { + writer.Write(ci.X); + writer.Write(ci.Y); + writer.Write(ci.Z); + writer.Write(ci.Map?.MapID ?? 0); + writer.Write(ci.Description); + writer.Write(0); + } + } + + var flags = ExpansionInfo.CoreExpansion.CharacterListFlags; + + if (count > 6) + { + flags |= CharacterListFlags.SeventhCharacterSlot | + CharacterListFlags.SixthCharacterSlot; // 7th Character Slot - TODO: Is SixthCharacterSlot Required? + } + else if (count == 6) + { + flags |= CharacterListFlags.SixthCharacterSlot; // 6th Character Slot + } + else if (acct.Limit == 1) + { + flags |= CharacterListFlags.SlotLimit & + CharacterListFlags.OneCharacterSlot; // Limit Characters & One Character + } + + writer.Write((int)flags); + if (client70130) + { + writer.Write((short)-1); + } + + ns.Send(writer.Span); + } + + /** * Packet: 0x82 * Length: 2 bytes * * Sends a reason for rejecting the login */ - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void SendAccountLoginRejected(this NetState ns, ALRReason reason) => - ns?.Send(stackalloc byte[] { 0x82, (byte)reason }); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SendAccountLoginRejected(this NetState ns, ALRReason reason) => + ns?.Send(stackalloc byte[] { 0x82, (byte)reason }); - /** + /** * Packet: 0xA8 * Length: 6 + 40 bytes per server listing * * Sends login acknowledge with server listing */ - public static void SendAccountLoginAck(this NetState ns) + public static void SendAccountLoginAck(this NetState ns) + { + if (ns.CannotSendPackets()) { - if (ns == null) - { - return; - } - - var info = ns.ServerInfo; - var length = 6 + 40 * info.Length; - var writer = new SpanWriter(stackalloc byte[length]); - writer.Write((byte)0xA8); // Packet ID - writer.Write((ushort)length); - writer.Write((byte)0x5D); - writer.Write((ushort)info.Length); - - for (var i = 0; i < info.Length; ++i) - { - var si = info[i]; - - writer.Write((ushort)i); - writer.WriteAscii(si.Name, 32); - writer.Write((byte)si.FullPercent); - writer.Write((sbyte)si.TimeZone); - // UO only supports IPv4 - writer.Write(si.RawAddress); - } - - ns.Send(writer.Span); + return; } - /** + var info = ns.ServerInfo; + var length = 6 + 40 * info.Length; + var writer = new SpanWriter(stackalloc byte[length]); + writer.Write((byte)0xA8); // Packet ID + writer.Write((ushort)length); + writer.Write((byte)0x5D); + writer.Write((ushort)info.Length); + + for (var i = 0; i < info.Length; ++i) + { + var si = info[i]; + + writer.Write((ushort)i); + writer.WriteAscii(si.Name, 32); + writer.Write((byte)si.FullPercent); + writer.Write((sbyte)si.TimeZone); + // UO only supports IPv4 + writer.Write(si.RawAddress); + } + + ns.Send(writer.Span); + } + + /** * Packet: 0x8C * Length: 11 bytes * * Sends acknowledge play server */ - public static void SendPlayServerAck(this NetState ns, ServerInfo si, int authId) + public static void SendPlayServerAck(this NetState ns, ServerInfo si, int authId) + { + if (ns.CannotSendPackets()) { - if (ns == null) - { - return; - } - - var writer = new SpanWriter(stackalloc byte[11]); - writer.Write((byte)0x8C); // Packet ID - - writer.WriteLE(si.RawAddress); - writer.Write((short)si.Address.Port); - writer.Write(authId); - - ns.Send(writer.Span); + return; } + + var writer = new SpanWriter(stackalloc byte[11]); + writer.Write((byte)0x8C); // Packet ID + + writer.WriteLE(si.RawAddress); + writer.Write((short)si.Address.Port); + writer.Write(authId); + + ns.Send(writer.Span); } } diff --git a/Projects/Server/Network/Packets/OutgoingCombatPackets.cs b/Projects/Server/Network/Packets/OutgoingCombatPackets.cs index e272a79cf..c5b23631b 100644 --- a/Projects/Server/Network/Packets/OutgoingCombatPackets.cs +++ b/Projects/Server/Network/Packets/OutgoingCombatPackets.cs @@ -16,42 +16,41 @@ using System.Buffers; using System.Runtime.CompilerServices; -namespace Server.Network +namespace Server.Network; + +public static class OutgoingCombatPackets { - public static class OutgoingCombatPackets + public static void SendSwing(this NetState ns, Serial attacker, Serial defender) { - public static void SendSwing(this NetState ns, Serial attacker, Serial defender) + if (ns.CannotSendPackets()) { - if (ns == null) - { - return; - } - - var writer = new SpanWriter(stackalloc byte[10]); - writer.Write((byte)0x2F); // Packet ID - writer.Write((byte)0); - writer.Write(attacker); - writer.Write(defender); - - ns.Send(writer.Span); + return; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe void SendSetWarMode(this NetState ns, bool warmode) => - ns?.Send(stackalloc byte[] { 0x72, *(byte*)&warmode, 0x00, 0x32, 0x00 }); + var writer = new SpanWriter(stackalloc byte[10]); + writer.Write((byte)0x2F); // Packet ID + writer.Write((byte)0); + writer.Write(attacker); + writer.Write(defender); - public static void SendChangeCombatant(this NetState ns, Serial combatant) + ns.Send(writer.Span); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe void SendSetWarMode(this NetState ns, bool warmode) => + ns?.Send(stackalloc byte[] { 0x72, *(byte*)&warmode, 0x00, 0x32, 0x00 }); + + public static void SendChangeCombatant(this NetState ns, Serial combatant) + { + if (ns.CannotSendPackets()) { - if (ns == null) - { - return; - } - - var writer = new SpanWriter(stackalloc byte[5]); - writer.Write((byte)0xAA); // Packet ID - writer.Write(combatant); - - ns.Send(writer.Span); + return; } + + var writer = new SpanWriter(stackalloc byte[5]); + writer.Write((byte)0xAA); // Packet ID + writer.Write(combatant); + + ns.Send(writer.Span); } } diff --git a/Projects/Server/Network/Packets/OutgoingContainerPackets.cs b/Projects/Server/Network/Packets/OutgoingContainerPackets.cs index 69d6ffb01..d664e40f6 100644 --- a/Projects/Server/Network/Packets/OutgoingContainerPackets.cs +++ b/Projects/Server/Network/Packets/OutgoingContainerPackets.cs @@ -17,194 +17,193 @@ using System; using System.Buffers; using System.IO; -namespace Server.Network +namespace Server.Network; + +public static class OutgoingContainerPackets { - public static class OutgoingContainerPackets + public static void SendDisplaySpellbook(this NetState ns, Serial book) => ns.SendDisplayContainer(book, -1); + + public static void SendSpellbookContent(this NetState ns, Serial book, int graphic, int offset, ulong content) { - public static void SendDisplaySpellbook(this NetState ns, Serial book) => ns.SendDisplayContainer(book, -1); - - public static void SendSpellbookContent(this NetState ns, Serial book, int graphic, int offset, ulong content) + if (ns.CannotSendPackets()) { - if (ns == null) - { - return; - } - - if (ObjectPropertyList.Enabled && ns.NewSpellbook) - { - ns.SendNewSpellbookContent(book, graphic, offset, content); - } - else - { - ns.SendOldSpellbookContent(book, offset, content); - } + return; } - public static void SendNewSpellbookContent(this NetState ns, Serial book, int graphic, int offset, ulong content) + if (ObjectPropertyList.Enabled && ns.NewSpellbook) { - if (ns == null) - { - return; - } - - var writer = new SpanWriter(stackalloc byte[23]); - writer.Write((byte)0xBF); // Packet ID - writer.Write((ushort)23); // Length - writer.Write((short)0x1B); // Subpacket - writer.Write((short)0x01); // Command - - writer.Write(book); - writer.Write((short)graphic); - writer.Write((short)offset); - - for (var i = 0; i < 8; ++i) - { - writer.Write((byte)(content >> (i * 8))); - } - - ns.Send(writer.Span); + ns.SendNewSpellbookContent(book, graphic, offset, content); } - - public static void SendOldSpellbookContent(this NetState ns, Serial book, int offset, ulong content) + else { - if (ns == null) - { - return; - } - - var count = content.NumberOfSetBits(); - var length = 5 + count * (ns.ContainerGridLines ? 20 : 19); - - var writer = new SpanWriter(stackalloc byte[length]); - writer.Write((byte)0x3C); // Packet ID - writer.Write((ushort)length); - writer.Write((ushort)count); - - ulong mask = 1; - for (var i = 0; i < 64; ++i, mask <<= 1) - { - if ((content & mask) != 0) - { - writer.Write(0x7FFFFFFF - i); - writer.Write((ushort)0); // child ItemID - writer.Write((byte)0); // ItemID offset - writer.Write((ushort)(i + offset)); // Amount - writer.Write(0); // X, Y - if (ns.ContainerGridLines) - { - writer.Write((byte)0); // Grid Location - } - writer.Write(book); - writer.Write((short)0); // Quest Hue - } - } - - ns.Send(writer.Span); - } - - public static void SendDisplayContainer(this NetState ns, Serial cont, int gumpId) - { - if (ns == null) - { - return; - } - - var writer = new SpanWriter(stackalloc byte[ns.HighSeas ? 9 : 7]); - writer.Write((byte)0x24); // Packet ID - writer.Write(cont); - writer.Write((ushort)gumpId); - if (ns.HighSeas) - { - writer.Write((short)0x7D); - } - - ns.Send(writer.Span); - } - - public static void SendContainerContentUpdate(this NetState ns, Item item) - { - if (ns == null) - { - return; - } - - Serial parentSerial; - - if (item.Parent is Item parentItem) - { - parentSerial = parentItem.Serial; - } - else - { - Console.WriteLine("Warning: ContainerContentUpdate on item with !(parent is Item)"); - parentSerial = Serial.Zero; - } - - var writer = new SpanWriter(stackalloc byte[ns.ContainerGridLines ? 21 : 20]); - writer.Write((byte)0x25); // Packet ID - writer.Write(item.Serial); - writer.Write((ushort)item.ItemID); - writer.Write((byte)0); // signed, itemID offset - writer.Write((ushort)Math.Min(item.Amount, ushort.MaxValue)); - writer.Write((short)item.X); - writer.Write((short)item.Y); - if (ns.ContainerGridLines) - { - writer.Write((byte)0); // Grid Location? - } - writer.Write(parentSerial); - writer.Write((ushort)(item.QuestItem ? Item.QuestItemHue : item.Hue)); - - ns.Send(writer.Span); - } - - public static void SendContainerContent(this NetState ns, Mobile beholder, Item beheld) - { - if (ns == null) - { - return; - } - - var items = beheld.Items; - var count = items.Count; - - var writer = new SpanWriter(stackalloc byte[5 + items.Count * (ns.ContainerGridLines ? 20 : 19)]); - writer.Write((byte)0x3C); // Packet ID - writer.Seek(4, SeekOrigin.Current); // Length & written count - - var written = 0; - - for (var i = 0; i < count; ++i) - { - var child = items[i]; - - if (!child.Deleted && beholder.CanSee(child)) - { - var loc = child.Location; - - writer.Write(child.Serial); - writer.Write((ushort)child.ItemID); - writer.Write((byte)0); // signed, itemID offset - writer.Write((ushort)Math.Min(child.Amount, ushort.MaxValue)); - writer.Write((short)loc.X); - writer.Write((short)loc.Y); - if (ns.ContainerGridLines) - { - writer.Write((byte)0); // Grid Location? - } - writer.Write(beheld.Serial); - writer.Write((ushort)(child.QuestItem ? Item.QuestItemHue : child.Hue)); - - ++written; - } - } - - writer.Seek(1, SeekOrigin.Begin); - writer.Write((ushort)writer.BytesWritten); - writer.Write((ushort)written); - writer.Seek(0, SeekOrigin.End); - - ns.Send(writer.Span); + ns.SendOldSpellbookContent(book, offset, content); } } + + public static void SendNewSpellbookContent(this NetState ns, Serial book, int graphic, int offset, ulong content) + { + if (ns.CannotSendPackets()) + { + return; + } + + var writer = new SpanWriter(stackalloc byte[23]); + writer.Write((byte)0xBF); // Packet ID + writer.Write((ushort)23); // Length + writer.Write((short)0x1B); // Subpacket + writer.Write((short)0x01); // Command + + writer.Write(book); + writer.Write((short)graphic); + writer.Write((short)offset); + + for (var i = 0; i < 8; ++i) + { + writer.Write((byte)(content >> (i * 8))); + } + + ns.Send(writer.Span); + } + + public static void SendOldSpellbookContent(this NetState ns, Serial book, int offset, ulong content) + { + if (ns.CannotSendPackets()) + { + return; + } + + var count = content.NumberOfSetBits(); + var length = 5 + count * (ns.ContainerGridLines ? 20 : 19); + + var writer = new SpanWriter(stackalloc byte[length]); + writer.Write((byte)0x3C); // Packet ID + writer.Write((ushort)length); + writer.Write((ushort)count); + + ulong mask = 1; + for (var i = 0; i < 64; ++i, mask <<= 1) + { + if ((content & mask) != 0) + { + writer.Write(0x7FFFFFFF - i); + writer.Write((ushort)0); // child ItemID + writer.Write((byte)0); // ItemID offset + writer.Write((ushort)(i + offset)); // Amount + writer.Write(0); // X, Y + if (ns.ContainerGridLines) + { + writer.Write((byte)0); // Grid Location + } + writer.Write(book); + writer.Write((short)0); // Quest Hue + } + } + + ns.Send(writer.Span); + } + + public static void SendDisplayContainer(this NetState ns, Serial cont, int gumpId) + { + if (ns.CannotSendPackets()) + { + return; + } + + var writer = new SpanWriter(stackalloc byte[ns.HighSeas ? 9 : 7]); + writer.Write((byte)0x24); // Packet ID + writer.Write(cont); + writer.Write((ushort)gumpId); + if (ns.HighSeas) + { + writer.Write((short)0x7D); + } + + ns.Send(writer.Span); + } + + public static void SendContainerContentUpdate(this NetState ns, Item item) + { + if (ns.CannotSendPackets()) + { + return; + } + + Serial parentSerial; + + if (item.Parent is Item parentItem) + { + parentSerial = parentItem.Serial; + } + else + { + Console.WriteLine("Warning: ContainerContentUpdate on item with !(parent is Item)"); + parentSerial = Serial.Zero; + } + + var writer = new SpanWriter(stackalloc byte[ns.ContainerGridLines ? 21 : 20]); + writer.Write((byte)0x25); // Packet ID + writer.Write(item.Serial); + writer.Write((ushort)item.ItemID); + writer.Write((byte)0); // signed, itemID offset + writer.Write((ushort)Math.Min(item.Amount, ushort.MaxValue)); + writer.Write((short)item.X); + writer.Write((short)item.Y); + if (ns.ContainerGridLines) + { + writer.Write((byte)0); // Grid Location? + } + writer.Write(parentSerial); + writer.Write((ushort)(item.QuestItem ? Item.QuestItemHue : item.Hue)); + + ns.Send(writer.Span); + } + + public static void SendContainerContent(this NetState ns, Mobile beholder, Item beheld) + { + if (ns.CannotSendPackets()) + { + return; + } + + var items = beheld.Items; + var count = items.Count; + + var writer = new SpanWriter(stackalloc byte[5 + items.Count * (ns.ContainerGridLines ? 20 : 19)]); + writer.Write((byte)0x3C); // Packet ID + writer.Seek(4, SeekOrigin.Current); // Length & written count + + var written = 0; + + for (var i = 0; i < count; ++i) + { + var child = items[i]; + + if (!child.Deleted && beholder.CanSee(child)) + { + var loc = child.Location; + + writer.Write(child.Serial); + writer.Write((ushort)child.ItemID); + writer.Write((byte)0); // signed, itemID offset + writer.Write((ushort)Math.Min(child.Amount, ushort.MaxValue)); + writer.Write((short)loc.X); + writer.Write((short)loc.Y); + if (ns.ContainerGridLines) + { + writer.Write((byte)0); // Grid Location? + } + writer.Write(beheld.Serial); + writer.Write((ushort)(child.QuestItem ? Item.QuestItemHue : child.Hue)); + + ++written; + } + } + + writer.Seek(1, SeekOrigin.Begin); + writer.Write((ushort)writer.BytesWritten); + writer.Write((ushort)written); + writer.Seek(0, SeekOrigin.End); + + ns.Send(writer.Span); + } } diff --git a/Projects/Server/Network/Packets/OutgoingDamagePackets.cs b/Projects/Server/Network/Packets/OutgoingDamagePackets.cs index 02e3b989b..41d99d0b9 100644 --- a/Projects/Server/Network/Packets/OutgoingDamagePackets.cs +++ b/Projects/Server/Network/Packets/OutgoingDamagePackets.cs @@ -16,36 +16,35 @@ using System; using System.Buffers; -namespace Server.Network +namespace Server.Network; + +public static class OutgoingDamagePackets { - public static class OutgoingDamagePackets + public static void SendDamage(this NetState ns, Serial serial, int amount) { - public static void SendDamage(this NetState ns, Serial serial, int amount) + if (ns.CannotSendPackets()) { - if (ns == null) - { - return; - } - - var writer = new SpanWriter(stackalloc byte[ns.DamagePacket ? 7 : 11]); - - if (ns.DamagePacket) - { - writer.Write((byte)0x0B); // Packet ID - writer.Write(serial); - writer.Write((ushort)Math.Clamp(amount, 0, 0xFFFF)); - } - else - { - writer.Write((byte)0xBF); // Packet ID - writer.Write((ushort)11); // Length - writer.Write((ushort)0x22); - writer.Write((byte)1); - writer.Write(serial); - writer.Write((byte)Math.Clamp(amount, 0, 0xFF)); - } - - ns.Send(writer.Span); + return; } + + var writer = new SpanWriter(stackalloc byte[ns.DamagePacket ? 7 : 11]); + + if (ns.DamagePacket) + { + writer.Write((byte)0x0B); // Packet ID + writer.Write(serial); + writer.Write((ushort)Math.Clamp(amount, 0, 0xFFFF)); + } + else + { + writer.Write((byte)0xBF); // Packet ID + writer.Write((ushort)11); // Length + writer.Write((ushort)0x22); + writer.Write((byte)1); + writer.Write(serial); + writer.Write((byte)Math.Clamp(amount, 0, 0xFF)); + } + + ns.Send(writer.Span); } } diff --git a/Projects/Server/Network/Packets/OutgoingEffectPackets.cs b/Projects/Server/Network/Packets/OutgoingEffectPackets.cs index 1b09c042e..1b3d80c8c 100644 --- a/Projects/Server/Network/Packets/OutgoingEffectPackets.cs +++ b/Projects/Server/Network/Packets/OutgoingEffectPackets.cs @@ -16,325 +16,324 @@ using System; using System.Buffers; -namespace Server.Network +namespace Server.Network; + +public static class OutgoingEffectPackets { - public static class OutgoingEffectPackets + public const int SoundPacketLength = 12; + public const int ParticleEffectLength = 49; + public const int HuedEffectLength = 36; + public const int BoltEffectLength = 36; + + public static void SendSoundEffect(this NetState ns, int soundID, IPoint3D target) { - public const int SoundPacketLength = 12; - public const int ParticleEffectLength = 49; - public const int HuedEffectLength = 36; - public const int BoltEffectLength = 36; - - public static void SendSoundEffect(this NetState ns, int soundID, IPoint3D target) + if (ns.CannotSendPackets()) { - if (ns == null) - { - return; - } - - Span buffer = stackalloc byte[SoundPacketLength].InitializePacket(); - CreateSoundEffect(buffer, soundID, target); - - ns.Send(buffer); + return; } - public static void CreateSoundEffect(Span buffer, int soundID, IPoint3D target) - { - if (buffer[0] != 0) - { - return; - } + Span buffer = stackalloc byte[SoundPacketLength].InitializePacket(); + CreateSoundEffect(buffer, soundID, target); - var writer = new SpanWriter(buffer); - writer.Write((byte)0x54); // Packet ID - writer.Write((byte)1); // flags - writer.Write((short)soundID); - writer.Write((short)0); // volume - writer.Write((short)target.X); - writer.Write((short)target.Y); - writer.Write((short)target.Z); + ns.Send(buffer); + } + + public static void CreateSoundEffect(Span buffer, int soundID, IPoint3D target) + { + if (buffer[0] != 0) + { + return; } - public static void CreateParticleEffect( - Span buffer, - EffectType type, Serial from, Serial to, int itemID, IPoint3D fromPoint, IPoint3D toPoint, - int speed, int duration, bool fixedDirection, bool explode, int hue, int renderMode, int effect, - int explodeEffect, int explodeSound, Serial serial, int layer, int unknown - ) - { - if (buffer[0] != 0) - { - return; - } + var writer = new SpanWriter(buffer); + writer.Write((byte)0x54); // Packet ID + writer.Write((byte)1); // flags + writer.Write((short)soundID); + writer.Write((short)0); // volume + writer.Write((short)target.X); + writer.Write((short)target.Y); + writer.Write((short)target.Z); + } - var writer = new SpanWriter(buffer); - writer.Write((byte)0xC7); // Packet ID - writer.Write((byte)type); - writer.Write(from); - writer.Write(to); - writer.Write((short)itemID); - writer.Write((short)fromPoint.X); - writer.Write((short)fromPoint.Y); - writer.Write((sbyte)fromPoint.Z); - writer.Write((short)toPoint.X); - writer.Write((short)toPoint.Y); - writer.Write((sbyte)toPoint.Z); - writer.Write((byte)speed); - writer.Write((byte)duration); - writer.Write((byte)0); - writer.Write((byte)0); - writer.Write(fixedDirection); - writer.Write(explode); - writer.Write(hue); - writer.Write(renderMode); - writer.Write((short)effect); - writer.Write((short)explodeEffect); - writer.Write((short)explodeSound); - writer.Write(serial); - writer.Write((byte)layer); - writer.Write((short)unknown); + public static void CreateParticleEffect( + Span buffer, + EffectType type, Serial from, Serial to, int itemID, IPoint3D fromPoint, IPoint3D toPoint, + int speed, int duration, bool fixedDirection, bool explode, int hue, int renderMode, int effect, + int explodeEffect, int explodeSound, Serial serial, int layer, int unknown + ) + { + if (buffer[0] != 0) + { + return; } - public static void CreateTargetParticleEffect( - Span buffer, - IEntity e, int itemID, int speed, int duration, int hue, int renderMode, int effect, int layer, int unknown - ) => CreateParticleEffect( - buffer, - EffectType.FixedFrom, - e.Serial, - Serial.Zero, - itemID, - e.Location, - e.Location, - speed, - duration, - true, - false, - hue, - renderMode, - effect, - 1, - 0, - e.Serial, - layer, - unknown - ); + var writer = new SpanWriter(buffer); + writer.Write((byte)0xC7); // Packet ID + writer.Write((byte)type); + writer.Write(from); + writer.Write(to); + writer.Write((short)itemID); + writer.Write((short)fromPoint.X); + writer.Write((short)fromPoint.Y); + writer.Write((sbyte)fromPoint.Z); + writer.Write((short)toPoint.X); + writer.Write((short)toPoint.Y); + writer.Write((sbyte)toPoint.Z); + writer.Write((byte)speed); + writer.Write((byte)duration); + writer.Write((byte)0); + writer.Write((byte)0); + writer.Write(fixedDirection); + writer.Write(explode); + writer.Write(hue); + writer.Write(renderMode); + writer.Write((short)effect); + writer.Write((short)explodeEffect); + writer.Write((short)explodeSound); + writer.Write(serial); + writer.Write((byte)layer); + writer.Write((short)unknown); + } - public static void CreateLocationParticleEffect( - Span buffer, - IEntity e, int itemID, int speed, int duration, int hue, int renderMode, int effect, int unknown - ) => CreateParticleEffect( - buffer, - EffectType.FixedXYZ, - e.Serial, - Serial.Zero, - itemID, - e.Location, - e.Location, - speed, - duration, - true, - false, - hue, - renderMode, - effect, - 1, - 0, - e.Serial, - 255, - unknown - ); + public static void CreateTargetParticleEffect( + Span buffer, + IEntity e, int itemID, int speed, int duration, int hue, int renderMode, int effect, int layer, int unknown + ) => CreateParticleEffect( + buffer, + EffectType.FixedFrom, + e.Serial, + Serial.Zero, + itemID, + e.Location, + e.Location, + speed, + duration, + true, + false, + hue, + renderMode, + effect, + 1, + 0, + e.Serial, + layer, + unknown + ); - public static void CreateMovingParticleEffect( - Span buffer, - IEntity from, IEntity to, int itemID, int speed, int duration, bool fixedDirection, - bool explodes, int hue, int renderMode, int effect, int explodeEffect, int explodeSound, EffectLayer layer, - int unknown - ) => CreateParticleEffect( - buffer, - EffectType.Moving, - from.Serial, - to.Serial, - itemID, - from.Location, - to.Location, - speed, - duration, - fixedDirection, - explodes, - hue, - renderMode, - effect, - explodeEffect, - explodeSound, - Serial.Zero, - (int)layer, - unknown - ); + public static void CreateLocationParticleEffect( + Span buffer, + IEntity e, int itemID, int speed, int duration, int hue, int renderMode, int effect, int unknown + ) => CreateParticleEffect( + buffer, + EffectType.FixedXYZ, + e.Serial, + Serial.Zero, + itemID, + e.Location, + e.Location, + speed, + duration, + true, + false, + hue, + renderMode, + effect, + 1, + 0, + e.Serial, + 255, + unknown + ); - public static void CreateHuedEffect( - Span buffer, - EffectType type, Serial from, Serial to, int itemID, Point3D fromPoint, Point3D toPoint, - int speed, int duration, bool fixedDirection, bool explode, int hue, int renderMode - ) + public static void CreateMovingParticleEffect( + Span buffer, + IEntity from, IEntity to, int itemID, int speed, int duration, bool fixedDirection, + bool explodes, int hue, int renderMode, int effect, int explodeEffect, int explodeSound, EffectLayer layer, + int unknown + ) => CreateParticleEffect( + buffer, + EffectType.Moving, + from.Serial, + to.Serial, + itemID, + from.Location, + to.Location, + speed, + duration, + fixedDirection, + explodes, + hue, + renderMode, + effect, + explodeEffect, + explodeSound, + Serial.Zero, + (int)layer, + unknown + ); + + public static void CreateHuedEffect( + Span buffer, + EffectType type, Serial from, Serial to, int itemID, Point3D fromPoint, Point3D toPoint, + int speed, int duration, bool fixedDirection, bool explode, int hue, int renderMode + ) + { + if (buffer[0] != 0) { - if (buffer[0] != 0) - { - return; - } - - var writer = new SpanWriter(buffer); - writer.Write((byte)0xC0); // Packet ID - writer.Write((byte)type); - writer.Write(from); - writer.Write(to); - writer.Write((short)itemID); - writer.Write((short)fromPoint.X); - writer.Write((short)fromPoint.Y); - writer.Write((sbyte)fromPoint.Z); - writer.Write((short)toPoint.X); - writer.Write((short)toPoint.Y); - writer.Write((sbyte)toPoint.Z); - writer.Write((byte)speed); - writer.Write((byte)duration); - writer.Write((byte)0); - writer.Write((byte)0); - writer.Write(fixedDirection); - writer.Write(explode); - writer.Write(hue); - writer.Write(renderMode); + return; } - public static void CreateTargetHuedEffect( - Span buffer, - IEntity e, int itemID, int speed, int duration, int hue, int renderMode - ) => CreateHuedEffect( - buffer, - EffectType.FixedFrom, - e.Serial, - Serial.Zero, - itemID, - e.Location, - e.Location, - speed, - duration, - true, - false, - hue, - renderMode - ); + var writer = new SpanWriter(buffer); + writer.Write((byte)0xC0); // Packet ID + writer.Write((byte)type); + writer.Write(from); + writer.Write(to); + writer.Write((short)itemID); + writer.Write((short)fromPoint.X); + writer.Write((short)fromPoint.Y); + writer.Write((sbyte)fromPoint.Z); + writer.Write((short)toPoint.X); + writer.Write((short)toPoint.Y); + writer.Write((sbyte)toPoint.Z); + writer.Write((byte)speed); + writer.Write((byte)duration); + writer.Write((byte)0); + writer.Write((byte)0); + writer.Write(fixedDirection); + writer.Write(explode); + writer.Write(hue); + writer.Write(renderMode); + } - public static void CreateLocationHuedEffect( - Span buffer, - Point3D p, int itemID, int speed, int duration, int hue, int renderMode - ) => CreateHuedEffect( - buffer, - EffectType.FixedXYZ, - Serial.Zero, - Serial.Zero, - itemID, - p, - p, - speed, - duration, - true, - false, - hue, - renderMode - ); + public static void CreateTargetHuedEffect( + Span buffer, + IEntity e, int itemID, int speed, int duration, int hue, int renderMode + ) => CreateHuedEffect( + buffer, + EffectType.FixedFrom, + e.Serial, + Serial.Zero, + itemID, + e.Location, + e.Location, + speed, + duration, + true, + false, + hue, + renderMode + ); - public static void CreateMovingHuedEffect( - Span buffer, - IEntity from, IEntity to, int itemID, int speed, int duration, bool fixedDirection, - bool explodes, int hue, int renderMode - ) => CreateHuedEffect( - buffer, - EffectType.Moving, - from.Serial, - to.Serial, - itemID, - from.Location, - to.Location, - speed, - duration, - fixedDirection, - explodes, - hue, - renderMode - ); + public static void CreateLocationHuedEffect( + Span buffer, + Point3D p, int itemID, int speed, int duration, int hue, int renderMode + ) => CreateHuedEffect( + buffer, + EffectType.FixedXYZ, + Serial.Zero, + Serial.Zero, + itemID, + p, + p, + speed, + duration, + true, + false, + hue, + renderMode + ); - public static void CreateMovingHuedEffect( - Span buffer, - int itemID, Point3D fromLocation, Point3D toLocation, int speed, int duration, - bool fixedDirection, bool explodes, int hue, int renderMode - ) => CreateHuedEffect( - buffer, - EffectType.Moving, - Serial.Zero, - Serial.Zero, - itemID, - fromLocation, - toLocation, - speed, - duration, - fixedDirection, - explodes, - hue, - renderMode - ); + public static void CreateMovingHuedEffect( + Span buffer, + IEntity from, IEntity to, int itemID, int speed, int duration, bool fixedDirection, + bool explodes, int hue, int renderMode + ) => CreateHuedEffect( + buffer, + EffectType.Moving, + from.Serial, + to.Serial, + itemID, + from.Location, + to.Location, + speed, + duration, + fixedDirection, + explodes, + hue, + renderMode + ); - public static void CreateMovingHuedEffect( - Span buffer, - Serial from, Serial to, int itemID, Point3D fromLocation, Point3D toLocation, int speed, int duration, - bool fixedDirection, bool explodes, int hue, int renderMode - ) => CreateHuedEffect( - buffer, - EffectType.Moving, - from, - to, - itemID, - fromLocation, - toLocation, - speed, - duration, - fixedDirection, - explodes, - hue, - renderMode - ); + public static void CreateMovingHuedEffect( + Span buffer, + int itemID, Point3D fromLocation, Point3D toLocation, int speed, int duration, + bool fixedDirection, bool explodes, int hue, int renderMode + ) => CreateHuedEffect( + buffer, + EffectType.Moving, + Serial.Zero, + Serial.Zero, + itemID, + fromLocation, + toLocation, + speed, + duration, + fixedDirection, + explodes, + hue, + renderMode + ); - public static void CreateBoltEffect(Span buffer, IEntity target, int hue) => CreateHuedEffect( - buffer, - EffectType.Lightning, - target.Serial, - Serial.Zero, - 0, - target.Location, - target.Location, - 0, - 0, - false, - false, - hue, - 0 - ); + public static void CreateMovingHuedEffect( + Span buffer, + Serial from, Serial to, int itemID, Point3D fromLocation, Point3D toLocation, int speed, int duration, + bool fixedDirection, bool explodes, int hue, int renderMode + ) => CreateHuedEffect( + buffer, + EffectType.Moving, + from, + to, + itemID, + fromLocation, + toLocation, + speed, + duration, + fixedDirection, + explodes, + hue, + renderMode + ); - public static void SendScreenEffect(this NetState ns, ScreenEffectType type) + public static void CreateBoltEffect(Span buffer, IEntity target, int hue) => CreateHuedEffect( + buffer, + EffectType.Lightning, + target.Serial, + Serial.Zero, + 0, + target.Location, + target.Location, + 0, + 0, + false, + false, + hue, + 0 + ); + + public static void SendScreenEffect(this NetState ns, ScreenEffectType type) + { + if (ns.CannotSendPackets()) { - if (ns == null) - { - return; - } - - var writer = new SpanWriter(stackalloc byte[28]); - - writer.Write((byte)0x70); // Packet ID - writer.Write((byte)0x4); - writer.Clear(8); - writer.Write((ushort)type); - writer.Clear(16); - - ns.Send(writer.Span); + return; } + + var writer = new SpanWriter(stackalloc byte[28]); + + writer.Write((byte)0x70); // Packet ID + writer.Write((byte)0x4); + writer.Clear(8); + writer.Write((ushort)type); + writer.Clear(16); + + ns.Send(writer.Span); } } diff --git a/Projects/Server/Network/Packets/OutgoingEntityPackets.cs b/Projects/Server/Network/Packets/OutgoingEntityPackets.cs index 5bb608e36..cf84157e2 100644 --- a/Projects/Server/Network/Packets/OutgoingEntityPackets.cs +++ b/Projects/Server/Network/Packets/OutgoingEntityPackets.cs @@ -17,135 +17,134 @@ using System; using System.Buffers; using Server.Items; -namespace Server.Network +namespace Server.Network; + +public static class OutgoingEntityPackets { - public static class OutgoingEntityPackets + public const int OPLPacketLength = 9; + public const int RemoveEntityLength = 5; + public const int MaxWorldEntityPacketLength = 26; + + public static void CreateOPLInfo(Span buffer, Item item) => + CreateOPLInfo(buffer, item.Serial, item.PropertyList.Hash); + + public static void CreateOPLInfo(Span buffer, Serial serial, int hash) { - public const int OPLPacketLength = 9; - public const int RemoveEntityLength = 5; - public const int MaxWorldEntityPacketLength = 26; - - public static void CreateOPLInfo(Span buffer, Item item) => - CreateOPLInfo(buffer, item.Serial, item.PropertyList.Hash); - - public static void CreateOPLInfo(Span buffer, Serial serial, int hash) + if (buffer[0] != 0) { - if (buffer[0] != 0) - { - return; - } - - var writer = new SpanWriter(buffer); - writer.Write((byte)0xDC); // Packet ID - writer.Write(serial); - writer.Write(hash); + return; } - public static void SendOPLInfo(this NetState ns, IPropertyListObject obj) => - ns.SendOPLInfo(obj.Serial, obj.PropertyList.Hash); + var writer = new SpanWriter(buffer); + writer.Write((byte)0xDC); // Packet ID + writer.Write(serial); + writer.Write(hash); + } - public static void SendOPLInfo(this NetState ns, Serial serial, int hash) + public static void SendOPLInfo(this NetState ns, IPropertyListObject obj) => + ns.SendOPLInfo(obj.Serial, obj.PropertyList.Hash); + + public static void SendOPLInfo(this NetState ns, Serial serial, int hash) + { + if (ns.CannotSendPackets()) { - if (ns == null) - { - return; - } - - Span buffer = stackalloc byte[OPLPacketLength].InitializePacket(); - CreateOPLInfo(buffer, serial, hash); - - ns.Send(buffer); + return; } - public static void CreateRemoveEntity(Span buffer, Serial serial) - { - if (buffer[0] != 0) - { - return; - } + Span buffer = stackalloc byte[OPLPacketLength].InitializePacket(); + CreateOPLInfo(buffer, serial, hash); - var writer = new SpanWriter(buffer); - writer.Write((byte)0x1D); // Packet ID - writer.Write(serial); + ns.Send(buffer); + } + + public static void CreateRemoveEntity(Span buffer, Serial serial) + { + if (buffer[0] != 0) + { + return; } - public static void SendRemoveEntity(this NetState ns, Serial serial) + var writer = new SpanWriter(buffer); + writer.Write((byte)0x1D); // Packet ID + writer.Write(serial); + } + + public static void SendRemoveEntity(this NetState ns, Serial serial) + { + if (ns.CannotSendPackets()) { - if (ns == null) - { - return; - } - - Span buffer = stackalloc byte[RemoveEntityLength].InitializePacket(); - CreateRemoveEntity(buffer, serial); - - ns.Send(buffer); + return; } - public static int CreateWorldEntity(Span buffer, IEntity entity, bool isHS) + Span buffer = stackalloc byte[RemoveEntityLength].InitializePacket(); + CreateRemoveEntity(buffer, serial); + + ns.Send(buffer); + } + + public static int CreateWorldEntity(Span buffer, IEntity entity, bool isHS) + { + if (buffer[0] != 0) { - if (buffer[0] != 0) - { - return buffer.Length; - } - - var writer = new SpanWriter(buffer); - writer.Write((byte)0xF3); // Packet ID - writer.Write((short)0x1); // command - - int type = 0; - int gfx = 0; - int amount = 1; - int hue = 0; - byte light = 0; - int flags = 0; - - if (entity is BaseMulti multi) - { - type = 2; - gfx = multi.ItemID & (isHS ? 0xFFFF : 0x7FFF); - hue = multi.Hue; - amount = multi.Amount; - } - else if (entity is Item item) - { - // type = 3 if is damageable - gfx = item.ItemID & (isHS ? 0xFFFF : 0x7FFF); - hue = item.Hue; - amount = item.Amount; - light = (byte)item.Light; - flags = item.GetPacketFlags(); - } - else if (entity is Mobile mobile) - { - type = 1; - gfx = mobile.Body; - hue = mobile.Hue; - flags = mobile.GetPacketFlags(true); - } - - writer.Write((byte)type); - writer.Write(entity.Serial); - writer.Write((ushort)gfx); - writer.Write((byte)0); - - writer.Write((short)amount); // Min - writer.Write((short)amount); // Max - - writer.Write((short)(entity.X & 0x7FFF)); - writer.Write((short)(entity.Y & 0x3FFF)); - writer.Write((sbyte)entity.Z); - - writer.Write(light); - writer.Write((short)hue); - writer.Write((byte)flags); - - if (isHS) - { - writer.Write((short)0); - } - - return writer.Position; + return buffer.Length; } + + var writer = new SpanWriter(buffer); + writer.Write((byte)0xF3); // Packet ID + writer.Write((short)0x1); // command + + int type = 0; + int gfx = 0; + int amount = 1; + int hue = 0; + byte light = 0; + int flags = 0; + + if (entity is BaseMulti multi) + { + type = 2; + gfx = multi.ItemID & (isHS ? 0xFFFF : 0x7FFF); + hue = multi.Hue; + amount = multi.Amount; + } + else if (entity is Item item) + { + // type = 3 if is damageable + gfx = item.ItemID & (isHS ? 0xFFFF : 0x7FFF); + hue = item.Hue; + amount = item.Amount; + light = (byte)item.Light; + flags = item.GetPacketFlags(); + } + else if (entity is Mobile mobile) + { + type = 1; + gfx = mobile.Body; + hue = mobile.Hue; + flags = mobile.GetPacketFlags(true); + } + + writer.Write((byte)type); + writer.Write(entity.Serial); + writer.Write((ushort)gfx); + writer.Write((byte)0); + + writer.Write((short)amount); // Min + writer.Write((short)amount); // Max + + writer.Write((short)(entity.X & 0x7FFF)); + writer.Write((short)(entity.Y & 0x3FFF)); + writer.Write((sbyte)entity.Z); + + writer.Write(light); + writer.Write((short)hue); + writer.Write((byte)flags); + + if (isHS) + { + writer.Write((short)0); + } + + return writer.Position; } } diff --git a/Projects/Server/Network/Packets/OutgoingEquipmentPackets.cs b/Projects/Server/Network/Packets/OutgoingEquipmentPackets.cs index 7f2a0a3f1..543203f6e 100644 --- a/Projects/Server/Network/Packets/OutgoingEquipmentPackets.cs +++ b/Projects/Server/Network/Packets/OutgoingEquipmentPackets.cs @@ -17,108 +17,107 @@ using System; using System.Buffers; using System.Collections.Generic; -namespace Server.Network +namespace Server.Network; + +public class EquipInfoAttribute { - public class EquipInfoAttribute + public EquipInfoAttribute(int number, int charges = -1) { - public EquipInfoAttribute(int number, int charges = -1) - { - Number = number; - Charges = charges; - } - - public int Number { get; } - - public int Charges { get; } + Number = number; + Charges = charges; } - public static class OutgoingEquipmentPackets + public int Number { get; } + + public int Charges { get; } +} + +public static class OutgoingEquipmentPackets +{ + public static void SendDisplayEquipmentInfo( + this NetState ns, + Serial serial, int number, string crafterName, bool unidentified, List attrs + ) { - public static void SendDisplayEquipmentInfo( - this NetState ns, - Serial serial, int number, string crafterName, bool unidentified, List attrs - ) + if (ns.CannotSendPackets()) { - if (ns == null) - { - return; - } - - crafterName = crafterName.DefaultIfNullOrEmpty(""); - - var length = 17 + - (crafterName.Length > 0 ? 6 + crafterName.Length : 0) + - (unidentified ? 4 : 0) + - attrs.Count * 6; - - var writer = new SpanWriter(stackalloc byte[length]); - writer.Write((byte)0xBF); // Packet ID - writer.Write((ushort)length); - writer.Write((ushort)0x10); // Subpacket - writer.Write(serial); - writer.Write(number); - - if (crafterName.Length > 0) - { - writer.Write(-3); // crafted by - - writer.Write((ushort)crafterName.Length); - writer.WriteAscii(crafterName); - } - - if (unidentified) - { - writer.Write(-4); - } - - for (var i = 0; i < attrs.Count; ++i) - { - var attr = attrs[i]; - writer.Write(attr.Number); - writer.Write((short)attr.Charges); - } - - writer.Write(-1); - - ns.Send(writer.Span); + return; } - public static void SendEquipUpdate(this NetState ns, Item item) + crafterName = crafterName.DefaultIfNullOrEmpty(""); + + var length = 17 + + (crafterName.Length > 0 ? 6 + crafterName.Length : 0) + + (unidentified ? 4 : 0) + + attrs.Count * 6; + + var writer = new SpanWriter(stackalloc byte[length]); + writer.Write((byte)0xBF); // Packet ID + writer.Write((ushort)length); + writer.Write((ushort)0x10); // Subpacket + writer.Write(serial); + writer.Write(number); + + if (crafterName.Length > 0) { - if (ns == null) - { - return; - } + writer.Write(-3); // crafted by - Serial parentSerial; - - var parent = item.Parent as Mobile; - var hue = item.Hue; - - if (parent != null) - { - parentSerial = parent.Serial; - - if (parent.SolidHueOverride >= 0) - { - hue = parent.SolidHueOverride; - } - } - else - { - Console.WriteLine("Warning: EquipUpdate on item with !(parent is Mobile)"); - parentSerial = Serial.Zero; - } - - var writer = new SpanWriter(stackalloc byte[15]); - writer.Write((byte)0x2E); // Packet ID - writer.Write(item.Serial); - writer.Write((short)item.ItemID); - writer.Write((ushort)item.Layer); - writer.Write(parentSerial); - writer.Write((short)hue); - - ns.Send(writer.Span); + writer.Write((ushort)crafterName.Length); + writer.WriteAscii(crafterName); } + + if (unidentified) + { + writer.Write(-4); + } + + for (var i = 0; i < attrs.Count; ++i) + { + var attr = attrs[i]; + writer.Write(attr.Number); + writer.Write((short)attr.Charges); + } + + writer.Write(-1); + + ns.Send(writer.Span); + } + + public static void SendEquipUpdate(this NetState ns, Item item) + { + if (ns.CannotSendPackets()) + { + return; + } + + Serial parentSerial; + + var parent = item.Parent as Mobile; + var hue = item.Hue; + + if (parent != null) + { + parentSerial = parent.Serial; + + if (parent.SolidHueOverride >= 0) + { + hue = parent.SolidHueOverride; + } + } + else + { + Console.WriteLine("Warning: EquipUpdate on item with !(parent is Mobile)"); + parentSerial = Serial.Zero; + } + + var writer = new SpanWriter(stackalloc byte[15]); + writer.Write((byte)0x2E); // Packet ID + writer.Write(item.Serial); + writer.Write((short)item.ItemID); + writer.Write((ushort)item.Layer); + writer.Write(parentSerial); + writer.Write((short)hue); + + ns.Send(writer.Span); } } diff --git a/Projects/Server/Network/Packets/OutgoingGumpPackets.cs b/Projects/Server/Network/Packets/OutgoingGumpPackets.cs index 8fab20ff2..9460f9c8f 100644 --- a/Projects/Server/Network/Packets/OutgoingGumpPackets.cs +++ b/Projects/Server/Network/Packets/OutgoingGumpPackets.cs @@ -22,200 +22,199 @@ using Server.Collections; using Server.Gumps; using Server.Logging; -namespace Server.Network +namespace Server.Network; + +public static class OutgoingGumpPackets { - public static class OutgoingGumpPackets + private static readonly ILogger logger = LogFactory.GetLogger(typeof(OutgoingGumpPackets)); + + public static void SendCloseGump(this NetState ns, int typeId, int buttonId) { - private static readonly ILogger logger = LogFactory.GetLogger(typeof(OutgoingGumpPackets)); - - public static void SendCloseGump(this NetState ns, int typeId, int buttonId) + if (ns.CannotSendPackets()) { - if (ns == null) - { - return; - } - - var writer = new SpanWriter(stackalloc byte[13]); - writer.Write((byte)0xBF); // Packet ID - writer.Write((ushort)13); - - writer.Write((short)0x04); - writer.Write(typeId); - writer.Write(buttonId); - - ns.Send(writer.Span); + return; } - private static readonly byte[] _layoutBuffer = GC.AllocateUninitializedArray(0x20000); - private static readonly byte[] _stringsBuffer = GC.AllocateUninitializedArray(0x20000); - private static readonly byte[] _packBuffer = GC.AllocateUninitializedArray(0x20000); - private static readonly OrderedHashSet _stringsList = new(32); + var writer = new SpanWriter(stackalloc byte[13]); + writer.Write((byte)0xBF); // Packet ID + writer.Write((ushort)13); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WritePacked(ReadOnlySpan span, ref SpanWriter writer) + writer.Write((short)0x04); + writer.Write(typeId); + writer.Write(buttonId); + + ns.Send(writer.Span); + } + + private static readonly byte[] _layoutBuffer = GC.AllocateUninitializedArray(0x20000); + private static readonly byte[] _stringsBuffer = GC.AllocateUninitializedArray(0x20000); + private static readonly byte[] _packBuffer = GC.AllocateUninitializedArray(0x20000); + private static readonly OrderedHashSet _stringsList = new(32); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void WritePacked(ReadOnlySpan span, ref SpanWriter writer) + { + var length = span.Length; + + if (length == 0) { - var length = span.Length; - - if (length == 0) - { - writer.Write(0); - return; - } - - var wantLength = Zlib.MaxPackSize(length); - var packBuffer = _packBuffer; - byte[] rentedBuffer = null; - - if (wantLength > packBuffer.Length) - { - packBuffer = rentedBuffer = ArrayPool.Shared.Rent(wantLength); - } - - var packLength = wantLength; - - var error = Zlib.Pack(packBuffer, ref packLength, span, length, ZlibQuality.Default); - - if (error != ZlibError.Okay) - { - logger.Warning($"Gump compression failed {error}"); - - writer.Write(4); - writer.Write(0); - return; - } - - writer.Write(4 + packLength); - writer.Write(length); - writer.Write(packBuffer.AsSpan(0, packLength)); - - if (rentedBuffer != null) - { - ArrayPool.Shared.Return(rentedBuffer); - } + writer.Write(0); + return; } - public static void SendDisplayGump(this NetState ns, Gump gump, out int switches, out int entries) + var wantLength = Zlib.MaxPackSize(length); + var packBuffer = _packBuffer; + byte[] rentedBuffer = null; + + if (wantLength > packBuffer.Length) { - switches = 0; - entries = 0; - - if (ns == null) - { - return; - } - - var packed = ns.Unpack; - - var layoutWriter = new SpanWriter(_layoutBuffer); - - if (!gump.Draggable) - { - layoutWriter.Write(Gump.NoMove); - } - - if (!gump.Closable) - { - layoutWriter.Write(Gump.NoClose); - } - - if (!gump.Disposable) - { - layoutWriter.Write(Gump.NoDispose); - } - - if (!gump.Resizable) - { - layoutWriter.Write(Gump.NoResize); - } - - foreach (var entry in gump.Entries) - { - entry.AppendTo(ref layoutWriter, _stringsList, ref entries, ref switches); - } - - var stringsWriter = new SpanWriter(_stringsBuffer); - - foreach (var str in _stringsList) - { - var s = str ?? ""; - stringsWriter.Write((ushort)s.Length); - stringsWriter.WriteBigUni(s); - } - - int maxLength; - if (packed) - { - var worstLayoutLength = Zlib.MaxPackSize(layoutWriter.BytesWritten); - var worstStringsLength = Zlib.MaxPackSize(stringsWriter.BytesWritten); - maxLength = 40 + worstLayoutLength + worstStringsLength; - } - else - { - maxLength = 23 + layoutWriter.BytesWritten + stringsWriter.BytesWritten; - } - - var writer = new SpanWriter(maxLength); - writer.Write((byte)(packed ? 0xDD : 0xB0)); // Packet ID - writer.Seek(2, SeekOrigin.Current); - - writer.Write(gump.Serial); - writer.Write(gump.TypeID); - writer.Write(gump.X); - writer.Write(gump.Y); - - if (packed) - { - layoutWriter.Write((byte)0); // Layout text terminator - WritePacked(layoutWriter.Span, ref writer); - - writer.Write(_stringsList.Count); - WritePacked(stringsWriter.Span, ref writer); - } - else - { - writer.Write((ushort)layoutWriter.BytesWritten); - writer.Write(layoutWriter.Span); - - writer.Write((ushort)_stringsList.Count); - writer.Write(stringsWriter.Span); - } - - writer.WritePacketLength(); - - ns.Send(writer.Span); - - layoutWriter.Dispose(); // Just in case - stringsWriter.Dispose(); // Just in case - - if (_stringsList.Count > 0) - { - _stringsList.Clear(); - } + packBuffer = rentedBuffer = ArrayPool.Shared.Rent(wantLength); } - public static void SendDisplaySignGump(this NetState ns, Serial serial, int gumpId, string unknown, string caption) + var packLength = wantLength; + + var error = Zlib.Pack(packBuffer, ref packLength, span, length, ZlibQuality.Default); + + if (error != ZlibError.Okay) { - if (ns == null) - { - return; - } + logger.Warning($"Gump compression failed {error}"); - unknown ??= ""; - caption ??= ""; + writer.Write(4); + writer.Write(0); + return; + } - var length = 15 + unknown.Length + caption.Length; - var writer = new SpanWriter(stackalloc byte[length]); - writer.Write((byte)0x8B); // Packet ID - writer.Write((ushort)length); + writer.Write(4 + packLength); + writer.Write(length); + writer.Write(packBuffer.AsSpan(0, packLength)); - writer.Write(serial); - writer.Write((short)gumpId); - writer.Write((short)(unknown.Length + 1)); - writer.WriteAsciiNull(unknown); - writer.Write((short)(caption.Length + 1)); - writer.WriteAsciiNull(caption); - - ns.Send(writer.Span); + if (rentedBuffer != null) + { + ArrayPool.Shared.Return(rentedBuffer); } } + + public static void SendDisplayGump(this NetState ns, Gump gump, out int switches, out int entries) + { + switches = 0; + entries = 0; + + if (ns.CannotSendPackets()) + { + return; + } + + var packed = ns.Unpack; + + var layoutWriter = new SpanWriter(_layoutBuffer); + + if (!gump.Draggable) + { + layoutWriter.Write(Gump.NoMove); + } + + if (!gump.Closable) + { + layoutWriter.Write(Gump.NoClose); + } + + if (!gump.Disposable) + { + layoutWriter.Write(Gump.NoDispose); + } + + if (!gump.Resizable) + { + layoutWriter.Write(Gump.NoResize); + } + + foreach (var entry in gump.Entries) + { + entry.AppendTo(ref layoutWriter, _stringsList, ref entries, ref switches); + } + + var stringsWriter = new SpanWriter(_stringsBuffer); + + foreach (var str in _stringsList) + { + var s = str ?? ""; + stringsWriter.Write((ushort)s.Length); + stringsWriter.WriteBigUni(s); + } + + int maxLength; + if (packed) + { + var worstLayoutLength = Zlib.MaxPackSize(layoutWriter.BytesWritten); + var worstStringsLength = Zlib.MaxPackSize(stringsWriter.BytesWritten); + maxLength = 40 + worstLayoutLength + worstStringsLength; + } + else + { + maxLength = 23 + layoutWriter.BytesWritten + stringsWriter.BytesWritten; + } + + var writer = new SpanWriter(maxLength); + writer.Write((byte)(packed ? 0xDD : 0xB0)); // Packet ID + writer.Seek(2, SeekOrigin.Current); + + writer.Write(gump.Serial); + writer.Write(gump.TypeID); + writer.Write(gump.X); + writer.Write(gump.Y); + + if (packed) + { + layoutWriter.Write((byte)0); // Layout text terminator + WritePacked(layoutWriter.Span, ref writer); + + writer.Write(_stringsList.Count); + WritePacked(stringsWriter.Span, ref writer); + } + else + { + writer.Write((ushort)layoutWriter.BytesWritten); + writer.Write(layoutWriter.Span); + + writer.Write((ushort)_stringsList.Count); + writer.Write(stringsWriter.Span); + } + + writer.WritePacketLength(); + + ns.Send(writer.Span); + + layoutWriter.Dispose(); // Just in case + stringsWriter.Dispose(); // Just in case + + if (_stringsList.Count > 0) + { + _stringsList.Clear(); + } + } + + public static void SendDisplaySignGump(this NetState ns, Serial serial, int gumpId, string unknown, string caption) + { + if (ns.CannotSendPackets()) + { + return; + } + + unknown ??= ""; + caption ??= ""; + + var length = 15 + unknown.Length + caption.Length; + var writer = new SpanWriter(stackalloc byte[length]); + writer.Write((byte)0x8B); // Packet ID + writer.Write((ushort)length); + + writer.Write(serial); + writer.Write((short)gumpId); + writer.Write((short)(unknown.Length + 1)); + writer.WriteAsciiNull(unknown); + writer.Write((short)(caption.Length + 1)); + writer.WriteAsciiNull(caption); + + ns.Send(writer.Span); + } } diff --git a/Projects/Server/Network/Packets/OutgoingItemPackets.cs b/Projects/Server/Network/Packets/OutgoingItemPackets.cs index 47997e7de..7f72363ce 100644 --- a/Projects/Server/Network/Packets/OutgoingItemPackets.cs +++ b/Projects/Server/Network/Packets/OutgoingItemPackets.cs @@ -17,84 +17,83 @@ using System; using System.Buffers; using Server.Items; -namespace Server.Network +namespace Server.Network; + +public static class OutgoingItemPackets { - public static class OutgoingItemPackets + public static int CreateWorldItem(Span buffer, Item item) { - public static int CreateWorldItem(Span buffer, Item item) + if (buffer[0] != 0) { - if (buffer[0] != 0) - { - // This assumes the packet was sliced properly - return buffer.Length; - } - - var itemID = item is BaseMulti ? item.ItemID | 0x4000 : item.ItemID & 0x3FFF; - var amount = item.Amount; - var hasAmount = amount != 0; - var serial = hasAmount ? item.Serial.Value | 0x80000000 : item.Serial.Value & 0x7FFFFFFF; - var loc = item.Location; - var hue = item.Hue; - var flags = item.GetPacketFlags(); - var direction = (int)item.Direction; - var hasDirection = direction != 0; - var hasHue = hue != 0; - var hasFlags = flags != 0; - var x = hasDirection ? loc.X | 0x8000 : loc.X & 0x7FFF; - var y = (loc.Y & 0x3FFF) | (hasHue ? 0x8000 : 0) | (hasFlags ? 0x4000 : 0); - var length = 14 + (hasAmount ? 2 : 0) + - (hasDirection ? 1 : 0) + - (hasHue ? 2 : 0) + - (hasFlags ? 1 : 0); - - var writer = new SpanWriter(buffer); - writer.Write((byte)0x1A); // Packet ID - writer.Write((ushort)length); - writer.Write(serial); - writer.Write((ushort)itemID); - - if (hasAmount) - { - writer.Write((ushort)amount); - } - - writer.Write((ushort)x); - writer.Write((ushort)y); - - if (hasDirection) - { - writer.Write((byte)direction); - } - - writer.Write((sbyte)loc.Z); - - if (hasHue) - { - writer.Write((ushort)hue); - } - - if (hasFlags) - { - writer.Write((byte)flags); - } - - return writer.BytesWritten; + // This assumes the packet was sliced properly + return buffer.Length; } - public static void SendWorldItem(this NetState ns, Item item) + var itemID = item is BaseMulti ? item.ItemID | 0x4000 : item.ItemID & 0x3FFF; + var amount = item.Amount; + var hasAmount = amount != 0; + var serial = hasAmount ? item.Serial.Value | 0x80000000 : item.Serial.Value & 0x7FFFFFFF; + var loc = item.Location; + var hue = item.Hue; + var flags = item.GetPacketFlags(); + var direction = (int)item.Direction; + var hasDirection = direction != 0; + var hasHue = hue != 0; + var hasFlags = flags != 0; + var x = hasDirection ? loc.X | 0x8000 : loc.X & 0x7FFF; + var y = (loc.Y & 0x3FFF) | (hasHue ? 0x8000 : 0) | (hasFlags ? 0x4000 : 0); + var length = 14 + (hasAmount ? 2 : 0) + + (hasDirection ? 1 : 0) + + (hasHue ? 2 : 0) + + (hasFlags ? 1 : 0); + + var writer = new SpanWriter(buffer); + writer.Write((byte)0x1A); // Packet ID + writer.Write((ushort)length); + writer.Write(serial); + writer.Write((ushort)itemID); + + if (hasAmount) { - if (ns == null) - { - return; - } - - Span buffer = stackalloc byte[OutgoingEntityPackets.MaxWorldEntityPacketLength].InitializePacket(); - - var length = ns.StygianAbyss ? - OutgoingEntityPackets.CreateWorldEntity(buffer, item, ns.HighSeas) : - CreateWorldItem(buffer, item); - - ns.Send(buffer[..length]); + writer.Write((ushort)amount); } + + writer.Write((ushort)x); + writer.Write((ushort)y); + + if (hasDirection) + { + writer.Write((byte)direction); + } + + writer.Write((sbyte)loc.Z); + + if (hasHue) + { + writer.Write((ushort)hue); + } + + if (hasFlags) + { + writer.Write((byte)flags); + } + + return writer.BytesWritten; + } + + public static void SendWorldItem(this NetState ns, Item item) + { + if (ns.CannotSendPackets()) + { + return; + } + + Span buffer = stackalloc byte[OutgoingEntityPackets.MaxWorldEntityPacketLength].InitializePacket(); + + var length = ns.StygianAbyss ? + OutgoingEntityPackets.CreateWorldEntity(buffer, item, ns.HighSeas) : + CreateWorldItem(buffer, item); + + ns.Send(buffer[..length]); } } diff --git a/Projects/Server/Network/Packets/OutgoingLightPackets.cs b/Projects/Server/Network/Packets/OutgoingLightPackets.cs index 7f738a004..f47042f0f 100644 --- a/Projects/Server/Network/Packets/OutgoingLightPackets.cs +++ b/Projects/Server/Network/Packets/OutgoingLightPackets.cs @@ -16,27 +16,26 @@ using System.Buffers; using System.Runtime.CompilerServices; -namespace Server.Network +namespace Server.Network; + +public static class OutgoingLightPackets { - public static class OutgoingLightPackets + public static void SendPersonalLightLevel(this NetState ns, Serial serial, int level) { - public static void SendPersonalLightLevel(this NetState ns, Serial serial, int level) + if (ns.CannotSendPackets()) { - if (ns == null) - { - return; - } - - var writer = new SpanWriter(stackalloc byte[6]); - writer.Write((byte)0x4E); // Packet ID - writer.Write(serial); - writer.Write((byte)level); - - ns.Send(writer.Span); + return; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void SendGlobalLightLevel(this NetState ns, int level = 0) => - ns?.Send(stackalloc byte[] { 0x4F, (byte)level }); + var writer = new SpanWriter(stackalloc byte[6]); + writer.Write((byte)0x4E); // Packet ID + writer.Write(serial); + writer.Write((byte)level); + + ns.Send(writer.Span); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SendGlobalLightLevel(this NetState ns, int level = 0) => + ns?.Send(stackalloc byte[] { 0x4F, (byte)level }); } diff --git a/Projects/Server/Network/Packets/OutgoingMapPackets.cs b/Projects/Server/Network/Packets/OutgoingMapPackets.cs index be692358d..a0e71abb7 100644 --- a/Projects/Server/Network/Packets/OutgoingMapPackets.cs +++ b/Projects/Server/Network/Packets/OutgoingMapPackets.cs @@ -16,50 +16,49 @@ using System.Buffers; using System.Runtime.CompilerServices; -namespace Server.Network +namespace Server.Network; + +public static class OutgoingMapPackets { - public static class OutgoingMapPackets + private static byte[] _mapPatchesPacket = new byte[41]; + + public static void SendMapPatches(this NetState ns) { - private static byte[] _mapPatchesPacket = new byte[41]; - - public static void SendMapPatches(this NetState ns) + if (ns.CannotSendPackets()) { - if (ns == null) - { - return; - } - - if (_mapPatchesPacket[0] == 0) - { - var writer = new SpanWriter(_mapPatchesPacket); - writer.Write((byte)0xBF); // Packet ID - writer.Write((ushort)41); // Length - writer.Write((ushort)0x18); // Subpacket - writer.Write(4); - - for (int i = 0; i < 4; i++) - { - var map = Map.Maps[i]; - - writer.Write(map?.Tiles.Patch.StaticBlocks ?? 0); - writer.Write(map?.Tiles.Patch.LandBlocks ?? 0); - } - } - - ns.Send(_mapPatchesPacket); + return; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void SendInvalidMap(this NetState ns) => ns?.Send(stackalloc byte[] { 0xC6 }); - - public static void SendMapChange(this NetState ns, Map map) + if (_mapPatchesPacket[0] == 0) { - if (map == null) - { - return; - } + var writer = new SpanWriter(_mapPatchesPacket); + writer.Write((byte)0xBF); // Packet ID + writer.Write((ushort)41); // Length + writer.Write((ushort)0x18); // Subpacket + writer.Write(4); - ns?.Send(stackalloc byte[] { 0xBF, 0x00, 0x06, 0x00, 0x08, (byte)map.MapID }); + for (int i = 0; i < 4; i++) + { + var map = Map.Maps[i]; + + writer.Write(map?.Tiles.Patch.StaticBlocks ?? 0); + writer.Write(map?.Tiles.Patch.LandBlocks ?? 0); + } } + + ns.Send(_mapPatchesPacket); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SendInvalidMap(this NetState ns) => ns?.Send(stackalloc byte[] { 0xC6 }); + + public static void SendMapChange(this NetState ns, Map map) + { + if (map == null) + { + return; + } + + ns?.Send(stackalloc byte[] { 0xBF, 0x00, 0x06, 0x00, 0x08, (byte)map.MapID }); } } diff --git a/Projects/Server/Network/Packets/OutgoingMenuPackets.cs b/Projects/Server/Network/Packets/OutgoingMenuPackets.cs index 75c059d07..71db481cc 100644 --- a/Projects/Server/Network/Packets/OutgoingMenuPackets.cs +++ b/Projects/Server/Network/Packets/OutgoingMenuPackets.cs @@ -5,210 +5,209 @@ using Server.ContextMenus; using Server.Menus.ItemLists; using Server.Menus.Questions; -namespace Server.Network +namespace Server.Network; + +[Flags] +public enum CMEFlags { - [Flags] - public enum CMEFlags + None = 0x00, + Disabled = 0x01, + Arrow = 0x02, + Highlighted = 0x04, + Colored = 0x20 +} + +public static class OutgoingMenuPackets +{ + public static void SendDisplayItemListMenu(this NetState ns, ItemListMenu menu) { - None = 0x00, - Disabled = 0x01, - Arrow = 0x02, - Highlighted = 0x04, - Colored = 0x20 + if (ns == null || menu == null) + { + return; + } + + var question = menu.Question?.Trim(); + var questionLength = question?.Length ?? 0; + + var entries = menu.Entries; + int entriesLength = (byte)entries.Length; + + var maxLength = 11 + questionLength; + for (int i = 0; i < entriesLength; i++) + { + maxLength += 5 + entries[i].Name?.Length ?? 0; // could be trimmed + } + + var writer = new SpanWriter(stackalloc byte[maxLength]); + writer.Write((byte)0x7C); // Packet ID + writer.Seek(2, SeekOrigin.Current); + writer.Write(menu.Serial); + writer.Write((ushort)0); + + writer.Write((byte)questionLength); + + if (question != null) + { + writer.WriteAscii(question); + } + + writer.Write((byte)entriesLength); + + for (var i = 0; i < entriesLength; ++i) + { + var e = entries[i]; + + writer.Write((ushort)e.ItemID); + writer.Write((short)e.Hue); + + var name = e.Name?.Trim(); + + if (name == null) + { + writer.Write((byte)0); + } + else + { + var nameLength = name.Length; + writer.Write((byte)nameLength); + writer.WriteAscii(name); + } + } + + writer.WritePacketLength(); + ns.Send(writer.Span); } - public static class OutgoingMenuPackets + public static void SendDisplayQuestionMenu(this NetState ns, QuestionMenu menu) { - public static void SendDisplayItemListMenu(this NetState ns, ItemListMenu menu) + if (ns == null || menu == null) { - if (ns == null || menu == null) - { - return; - } - - var question = menu.Question?.Trim(); - var questionLength = question?.Length ?? 0; - - var entries = menu.Entries; - int entriesLength = (byte)entries.Length; - - var maxLength = 11 + questionLength; - for (int i = 0; i < entriesLength; i++) - { - maxLength += 5 + entries[i].Name?.Length ?? 0; // could be trimmed - } - - var writer = new SpanWriter(stackalloc byte[maxLength]); - writer.Write((byte)0x7C); // Packet ID - writer.Seek(2, SeekOrigin.Current); - writer.Write(menu.Serial); - writer.Write((ushort)0); - - writer.Write((byte)questionLength); - - if (question != null) - { - writer.WriteAscii(question); - } - - writer.Write((byte)entriesLength); - - for (var i = 0; i < entriesLength; ++i) - { - var e = entries[i]; - - writer.Write((ushort)e.ItemID); - writer.Write((short)e.Hue); - - var name = e.Name?.Trim(); - - if (name == null) - { - writer.Write((byte)0); - } - else - { - var nameLength = name.Length; - writer.Write((byte)nameLength); - writer.WriteAscii(name); - } - } - - writer.WritePacketLength(); - ns.Send(writer.Span); + return; } - public static void SendDisplayQuestionMenu(this NetState ns, QuestionMenu menu) + var question = menu.Question?.Trim(); + var questionLength = question?.Length ?? 0; + + var answers = menu.Answers; + int answersLength = (byte)answers.Length; + + var maxLength = 11 + questionLength; + for (int i = 0; i < answersLength; i++) { - if (ns == null || menu == null) - { - return; - } - - var question = menu.Question?.Trim(); - var questionLength = question?.Length ?? 0; - - var answers = menu.Answers; - int answersLength = (byte)answers.Length; - - var maxLength = 11 + questionLength; - for (int i = 0; i < answersLength; i++) - { - maxLength += 5 + answers[i]?.Length ?? 0; // could be trimmed - } - - var writer = new SpanWriter(stackalloc byte[maxLength]); - writer.Write((byte)0x7C); // Packet ID - writer.Seek(2, SeekOrigin.Current); - writer.Write(menu.Serial); - writer.Write((ushort)0); - writer.Write((byte)questionLength); - - if (question != null) - { - writer.WriteAscii(question); - } - - writer.Write((byte)answersLength); - - for (var i = 0; i < answersLength; ++i) - { - writer.Write(0); - - var answer = answers[i]?.Trim(); - - if (answer == null) - { - writer.Write((byte)0); - } - else - { - var nameLength = answer.Length; - writer.Write((byte)nameLength); - writer.WriteAscii(answer); - } - } - - writer.WritePacketLength(); - ns.Send(writer.Span); + maxLength += 5 + answers[i]?.Length ?? 0; // could be trimmed } - public static void SendDisplayContextMenu(this NetState ns, ContextMenu menu) + var writer = new SpanWriter(stackalloc byte[maxLength]); + writer.Write((byte)0x7C); // Packet ID + writer.Seek(2, SeekOrigin.Current); + writer.Write(menu.Serial); + writer.Write((ushort)0); + writer.Write((byte)questionLength); + + if (question != null) { - if (ns == null || menu == null) - { - return; - } - - var newCommand = ns.NewHaven && menu.RequiresNewPacket; - - var entries = menu.Entries; - var entriesLength = (byte)entries.Length; - var maxLength = 12 + entriesLength * 8; - - var writer = new SpanWriter(stackalloc byte[maxLength]); - writer.Write((byte)0xBF); // Packet ID - writer.Seek(2, SeekOrigin.Current); // Length - writer.Write((short)0x14); // Subpacket - writer.Write((short)(newCommand ? 0x02 : 0x01)); // Command - - var target = menu.Target; - writer.Write(target.Serial); - writer.Write(entriesLength); - - var p = target switch - { - Mobile _ => target.Location, - Item item => item.GetWorldLocation(), - _ => Point3D.Zero - }; - - for (var i = 0; i < entriesLength; ++i) - { - var e = entries[i]; - - var range = e.Range; - - if (range == -1) - { - range = Core.GlobalUpdateRange; - } - - var flags = e.Flags; - if (!(e.Enabled && menu.From.InRange(p, range))) - { - flags |= CMEFlags.Disabled; - } - - if (newCommand) - { - writer.Write(e.Number); - writer.Write((short)i); - writer.Write((short)flags); - } - else - { - writer.Write((short)i); - writer.Write((ushort)(e.Number - 3000000)); - - var color = e.Color & 0xFFFF; - - if (color != 0xFFFF) - { - flags |= CMEFlags.Colored; - } - - writer.Write((short)flags); - - if ((flags & CMEFlags.Colored) != 0) - { - writer.Write((short)color); - } - } - } - - writer.WritePacketLength(); - ns.Send(writer.Span); + writer.WriteAscii(question); } + + writer.Write((byte)answersLength); + + for (var i = 0; i < answersLength; ++i) + { + writer.Write(0); + + var answer = answers[i]?.Trim(); + + if (answer == null) + { + writer.Write((byte)0); + } + else + { + var nameLength = answer.Length; + writer.Write((byte)nameLength); + writer.WriteAscii(answer); + } + } + + writer.WritePacketLength(); + ns.Send(writer.Span); + } + + public static void SendDisplayContextMenu(this NetState ns, ContextMenu menu) + { + if (ns == null || menu == null) + { + return; + } + + var newCommand = ns.NewHaven && menu.RequiresNewPacket; + + var entries = menu.Entries; + var entriesLength = (byte)entries.Length; + var maxLength = 12 + entriesLength * 8; + + var writer = new SpanWriter(stackalloc byte[maxLength]); + writer.Write((byte)0xBF); // Packet ID + writer.Seek(2, SeekOrigin.Current); // Length + writer.Write((short)0x14); // Subpacket + writer.Write((short)(newCommand ? 0x02 : 0x01)); // Command + + var target = menu.Target; + writer.Write(target.Serial); + writer.Write(entriesLength); + + var p = target switch + { + Mobile _ => target.Location, + Item item => item.GetWorldLocation(), + _ => Point3D.Zero + }; + + for (var i = 0; i < entriesLength; ++i) + { + var e = entries[i]; + + var range = e.Range; + + if (range == -1) + { + range = Core.GlobalUpdateRange; + } + + var flags = e.Flags; + if (!(e.Enabled && menu.From.InRange(p, range))) + { + flags |= CMEFlags.Disabled; + } + + if (newCommand) + { + writer.Write(e.Number); + writer.Write((short)i); + writer.Write((short)flags); + } + else + { + writer.Write((short)i); + writer.Write((ushort)(e.Number - 3000000)); + + var color = e.Color & 0xFFFF; + + if (color != 0xFFFF) + { + flags |= CMEFlags.Colored; + } + + writer.Write((short)flags); + + if ((flags & CMEFlags.Colored) != 0) + { + writer.Write((short)color); + } + } + } + + writer.WritePacketLength(); + ns.Send(writer.Span); } } diff --git a/Projects/Server/Network/Packets/OutgoingMessagePackets.cs b/Projects/Server/Network/Packets/OutgoingMessagePackets.cs index a7a8d8e46..77763f92f 100644 --- a/Projects/Server/Network/Packets/OutgoingMessagePackets.cs +++ b/Projects/Server/Network/Packets/OutgoingMessagePackets.cs @@ -19,264 +19,263 @@ using System.IO; using System.Runtime.CompilerServices; using Server.Prompts; -namespace Server.Network +namespace Server.Network; + +[Flags] +public enum AffixType : byte { - [Flags] - public enum AffixType : byte + Append = 0x00, + Prepend = 0x01, + System = 0x02 +} + +public static class OutgoingMessagePackets +{ + public static void SendMessageLocalized( + this NetState ns, + Serial serial, int graphic, MessageType type, int hue, int font, int number, string name = "", string args = "" + ) { - Append = 0x00, - Prepend = 0x01, - System = 0x02 + if (ns.CannotSendPackets()) + { + return; + } + + Span buffer = stackalloc byte[GetMaxMessageLocalizedLength(args)]; + var length = CreateMessageLocalized( + buffer, serial, graphic, type, hue, font, number, name, args + ); + + ns.Send(buffer[..length]); } - public static class OutgoingMessagePackets + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int GetMaxMessageLocalizedLength(string args) => 50 + (args?.Length ?? 0) * 2; + + public static int CreateMessageLocalized( + Span buffer, + Serial serial, int graphic, MessageType type, int hue, int font, int number, string name = "", string args = "" + ) { - public static void SendMessageLocalized( - this NetState ns, - Serial serial, int graphic, MessageType type, int hue, int font, int number, string name = "", string args = "" - ) + if (buffer[0] != 0) { - if (ns == null) - { - return; - } - - Span buffer = stackalloc byte[GetMaxMessageLocalizedLength(args)]; - var length = CreateMessageLocalized( - buffer, serial, graphic, type, hue, font, number, name, args - ); - - ns.Send(buffer[..length]); + return buffer.Length; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int GetMaxMessageLocalizedLength(string args) => 50 + (args?.Length ?? 0) * 2; + name ??= ""; + args ??= ""; - public static int CreateMessageLocalized( - Span buffer, - Serial serial, int graphic, MessageType type, int hue, int font, int number, string name = "", string args = "" - ) + if (hue == 0) { - if (buffer[0] != 0) - { - return buffer.Length; - } + hue = 0x3B2; + } - name ??= ""; - args ??= ""; + var writer = new SpanWriter(buffer); + writer.Write((byte)0xC1); + writer.Seek(2, SeekOrigin.Current); + writer.Write(serial); + writer.Write((short)graphic); + writer.Write((byte)type); + writer.Write((short)hue); + writer.Write((short)font); + writer.Write(number); + writer.WriteAscii(name, 30); + writer.WriteLittleUniNull(args); - if (hue == 0) - { - hue = 0x3B2; - } + writer.WritePacketLength(); + return writer.Position; + } - var writer = new SpanWriter(buffer); - writer.Write((byte)0xC1); - writer.Seek(2, SeekOrigin.Current); - writer.Write(serial); - writer.Write((short)graphic); - writer.Write((byte)type); - writer.Write((short)hue); - writer.Write((short)font); - writer.Write(number); + public static void SendMessageLocalizedAffix( + this NetState ns, + Serial serial, int graphic, MessageType type, int hue, int font, int number, string name, + AffixType affixType, string affix = "", string args = "" + ) + { + if (ns.CannotSendPackets()) + { + return; + } + + Span buffer = stackalloc byte[GetMaxMessageLocalizedAffixLength(affix, args)].InitializePacket(); + var length = CreateMessageLocalizedAffix( + buffer, serial, graphic, type, hue, font, number, name, affixType, affix, args + ); + + ns.Send(buffer[..length]); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int GetMaxMessageLocalizedAffixLength(string affix, string args) => + 52 + (affix?.Length ?? 0) + (args?.Length ?? 0) * 2; + + public static int CreateMessageLocalizedAffix( + Span buffer, + Serial serial, int graphic, MessageType type, int hue, int font, int number, string name, + AffixType affixType, string affix = "", string args = "" + ) + { + if (buffer[0] != 0) + { + return buffer.Length; + } + + name ??= ""; + affix ??= ""; + args ??= ""; + + if (hue == 0) + { + hue = 0x3B2; + } + + var writer = new SpanWriter(buffer); + writer.Write((byte)0xCC); + writer.Seek(2, SeekOrigin.Current); + writer.Write(serial); + writer.Write((short)graphic); + writer.Write((byte)type); + writer.Write((short)hue); + writer.Write((short)font); + writer.Write(number); + writer.Write((byte)affixType); + writer.WriteAscii(name, 30); + writer.WriteAsciiNull(affix); + writer.WriteBigUniNull(args); + + writer.WritePacketLength(); + return writer.Position; + } + + public static void SendMessage( + this NetState ns, + Serial serial, int graphic, MessageType type, int hue, int font, bool ascii, string lang, string name, string text + ) + { + if (ns.CannotSendPackets()) + { + return; + } + + Span buffer = stackalloc byte[GetMaxMessageLength(text)].InitializePacket(); + var length = CreateMessage( + buffer, + serial, + graphic, + type, + hue, + font, + ascii, + lang, + name, + text + ); + + ns.Send(buffer[..length]); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int GetMaxMessageLength(string text) => 50 + (text?.Length ?? 0) * 2; + + public static int CreateMessage( + Span buffer, + Serial serial, + int graphic, + MessageType type, + int hue, + int font, + bool ascii, + string lang, + string name, + string text + ) + { + if (buffer[0] != 0) + { + return buffer.Length; + } + + name ??= ""; + text ??= ""; + lang ??= "ENU"; + + if (hue == 0) + { + hue = 0x3B2; + } + + var writer = new SpanWriter(buffer); + writer.Write((byte)(ascii ? 0x1C : 0xAE)); // Packet ID + writer.Seek(2, SeekOrigin.Current); + writer.Write(serial); + writer.Write((short)graphic); + writer.Write((byte)type); + writer.Write((short)hue); + writer.Write((short)font); + if (ascii) + { writer.WriteAscii(name, 30); - writer.WriteLittleUniNull(args); - - writer.WritePacketLength(); - return writer.Position; + writer.WriteAsciiNull(text); } - - public static void SendMessageLocalizedAffix( - this NetState ns, - Serial serial, int graphic, MessageType type, int hue, int font, int number, string name, - AffixType affixType, string affix = "", string args = "" - ) + else { - if (ns == null) - { - return; - } - - Span buffer = stackalloc byte[GetMaxMessageLocalizedAffixLength(affix, args)].InitializePacket(); - var length = CreateMessageLocalizedAffix( - buffer, serial, graphic, type, hue, font, number, name, affixType, affix, args - ); - - ns.Send(buffer[..length]); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int GetMaxMessageLocalizedAffixLength(string affix, string args) => - 52 + (affix?.Length ?? 0) + (args?.Length ?? 0) * 2; - - public static int CreateMessageLocalizedAffix( - Span buffer, - Serial serial, int graphic, MessageType type, int hue, int font, int number, string name, - AffixType affixType, string affix = "", string args = "" - ) - { - if (buffer[0] != 0) - { - return buffer.Length; - } - - name ??= ""; - affix ??= ""; - args ??= ""; - - if (hue == 0) - { - hue = 0x3B2; - } - - var writer = new SpanWriter(buffer); - writer.Write((byte)0xCC); - writer.Seek(2, SeekOrigin.Current); - writer.Write(serial); - writer.Write((short)graphic); - writer.Write((byte)type); - writer.Write((short)hue); - writer.Write((short)font); - writer.Write(number); - writer.Write((byte)affixType); + writer.WriteAscii(lang, 4); writer.WriteAscii(name, 30); - writer.WriteAsciiNull(affix); - writer.WriteBigUniNull(args); - - writer.WritePacketLength(); - return writer.Position; - } - - public static void SendMessage( - this NetState ns, - Serial serial, int graphic, MessageType type, int hue, int font, bool ascii, string lang, string name, string text - ) - { - if (ns == null) - { - return; - } - - Span buffer = stackalloc byte[GetMaxMessageLength(text)].InitializePacket(); - var length = CreateMessage( - buffer, - serial, - graphic, - type, - hue, - font, - ascii, - lang, - name, - text - ); - - ns.Send(buffer[..length]); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int GetMaxMessageLength(string text) => 50 + (text?.Length ?? 0) * 2; - - public static int CreateMessage( - Span buffer, - Serial serial, - int graphic, - MessageType type, - int hue, - int font, - bool ascii, - string lang, - string name, - string text - ) - { - if (buffer[0] != 0) - { - return buffer.Length; - } - - name ??= ""; - text ??= ""; - lang ??= "ENU"; - - if (hue == 0) - { - hue = 0x3B2; - } - - var writer = new SpanWriter(buffer); - writer.Write((byte)(ascii ? 0x1C : 0xAE)); // Packet ID - writer.Seek(2, SeekOrigin.Current); - writer.Write(serial); - writer.Write((short)graphic); - writer.Write((byte)type); - writer.Write((short)hue); - writer.Write((short)font); - if (ascii) - { - writer.WriteAscii(name, 30); - writer.WriteAsciiNull(text); - } - else - { - writer.WriteAscii(lang, 4); - writer.WriteAscii(name, 30); - writer.WriteBigUniNull(text); - } - - writer.WritePacketLength(); - return writer.Position; - } - - public static void SendFollowMessage(this NetState ns, Serial s1, Serial s2) - { - if (ns == null) - { - return; - } - - var writer = new SpanWriter(stackalloc byte[9]); - writer.Write((byte)0x15); // Packet ID - writer.Write(s1); - writer.Write(s2); - - ns.Send(writer.Span); - } - - public static void SendPrompt(this NetState ns, Prompt prompt) - { - if (ns == null || prompt == null) - { - return; - } - - var writer = new SpanWriter(stackalloc byte[21]); - writer.Write((byte)0xC2); // Packet ID - writer.Write((ushort)21); - writer.Write(prompt.Serial); - writer.Write(prompt.Serial); - writer.Clear(10); - - ns.Send(writer.Span); - } - - public static void SendHelpResponse(this NetState ns, Serial s, string text) - { - text = text?.Trim() ?? ""; - - if (ns == null || text.Length == 0) - { - return; - } - - var length = 9 + text.Length * 2; - var writer = new SpanWriter(stackalloc byte[length]); - writer.Write((byte)0xB7); - writer.Write((ushort)length); - writer.Write(s); writer.WriteBigUniNull(text); - - ns.Send(writer.Span); } + + writer.WritePacketLength(); + return writer.Position; + } + + public static void SendFollowMessage(this NetState ns, Serial s1, Serial s2) + { + if (ns.CannotSendPackets()) + { + return; + } + + var writer = new SpanWriter(stackalloc byte[9]); + writer.Write((byte)0x15); // Packet ID + writer.Write(s1); + writer.Write(s2); + + ns.Send(writer.Span); + } + + public static void SendPrompt(this NetState ns, Prompt prompt) + { + if (ns == null || prompt == null) + { + return; + } + + var writer = new SpanWriter(stackalloc byte[21]); + writer.Write((byte)0xC2); // Packet ID + writer.Write((ushort)21); + writer.Write(prompt.Serial); + writer.Write(prompt.Serial); + writer.Clear(10); + + ns.Send(writer.Span); + } + + public static void SendHelpResponse(this NetState ns, Serial s, string text) + { + text = text?.Trim() ?? ""; + + if (ns == null || text.Length == 0) + { + return; + } + + var length = 9 + text.Length * 2; + var writer = new SpanWriter(stackalloc byte[length]); + writer.Write((byte)0xB7); + writer.Write((ushort)length); + writer.Write(s); + writer.WriteBigUniNull(text); + + ns.Send(writer.Span); } } diff --git a/Projects/Server/Network/Packets/OutgoingMobilePackets.cs b/Projects/Server/Network/Packets/OutgoingMobilePackets.cs index 36a7a61ef..751737fec 100644 --- a/Projects/Server/Network/Packets/OutgoingMobilePackets.cs +++ b/Projects/Server/Network/Packets/OutgoingMobilePackets.cs @@ -19,691 +19,690 @@ using System.IO; using System.Runtime.CompilerServices; using Microsoft.Toolkit.HighPerformance; -namespace Server.Network +namespace Server.Network; + +public static class OutgoingMobilePackets { - public static class OutgoingMobilePackets + public const int BondedStatusPacketLength = 11; + public const int DeathAnimationPacketLength = 13; + public const int MobileMovingPacketLength = 17; + public const int MobileMovingPacketCacheHeight = 16; // 8 notoriety, 2 client versions + public const int MobileMovingPacketCacheByteLength = MobileMovingPacketLength * MobileMovingPacketCacheHeight; + public const int AttributeMaximum = 100; + public const int MobileAttributePacketLength = 9; + public const int MobileAttributesPacketLength = 17; + public const int MobileAnimationPacketLength = 14; + public const int NewMobileAnimationPacketLength = 10; + public const int MobileHealthbarPacketLength = 12; + public const int MobileStatusCompactLength = 43; + public const int MobileStatusMaxLength = 121; + + public static bool ExtendedStatus { get; set; } + + public static void Initialize() { - public const int BondedStatusPacketLength = 11; - public const int DeathAnimationPacketLength = 13; - public const int MobileMovingPacketLength = 17; - public const int MobileMovingPacketCacheHeight = 16; // 8 notoriety, 2 client versions - public const int MobileMovingPacketCacheByteLength = MobileMovingPacketLength * MobileMovingPacketCacheHeight; - public const int AttributeMaximum = 100; - public const int MobileAttributePacketLength = 9; - public const int MobileAttributesPacketLength = 17; - public const int MobileAnimationPacketLength = 14; - public const int NewMobileAnimationPacketLength = 10; - public const int MobileHealthbarPacketLength = 12; - public const int MobileStatusCompactLength = 43; - public const int MobileStatusMaxLength = 121; + ExtendedStatus = ServerConfiguration.GetOrUpdateSetting("extendedStatus", false); + } - public static bool ExtendedStatus { get; set; } - - public static void Initialize() + public static void CreateBondedStatus(Span buffer, Serial serial, bool bonded) + { + if (buffer[0] != 0) { - ExtendedStatus = ServerConfiguration.GetOrUpdateSetting("extendedStatus", false); + return; } - public static void CreateBondedStatus(Span buffer, Serial serial, bool bonded) - { - if (buffer[0] != 0) - { - return; - } + var writer = new SpanWriter(buffer); + writer.Write((byte)0xBF); // Packet ID + writer.Write((ushort)11); // Length + writer.Write((ushort)0x19); // Subpacket ID + writer.Write((byte)0); // Command + writer.Write(serial); + writer.Write(bonded); + } - var writer = new SpanWriter(buffer); - writer.Write((byte)0xBF); // Packet ID - writer.Write((ushort)11); // Length - writer.Write((ushort)0x19); // Subpacket ID - writer.Write((byte)0); // Command - writer.Write(serial); - writer.Write(bonded); + public static void SendBondedStatus(this NetState ns, Serial serial, bool bonded) + { + if (ns.CannotSendPackets()) + { + return; } - public static void SendBondedStatus(this NetState ns, Serial serial, bool bonded) + var writer = new SpanWriter(stackalloc byte[11]); + writer.Write((byte)0xBF); // Packet ID + writer.Write((ushort)11); // Length + writer.Write((ushort)0x19); // Subpacket ID + writer.Write((byte)0); // Command + writer.Write(serial); + writer.Write(bonded); + + ns.Send(writer.Span); + } + + public static void CreateDeathAnimation(Span buffer, Serial killed, Serial corpse) + { + if (buffer[0] != 0) { - if (ns == null) - { - return; - } - - var writer = new SpanWriter(stackalloc byte[11]); - writer.Write((byte)0xBF); // Packet ID - writer.Write((ushort)11); // Length - writer.Write((ushort)0x19); // Subpacket ID - writer.Write((byte)0); // Command - writer.Write(serial); - writer.Write(bonded); - - ns.Send(writer.Span); + return; } - public static void CreateDeathAnimation(Span buffer, Serial killed, Serial corpse) - { - if (buffer[0] != 0) - { - return; - } + var writer = new SpanWriter(buffer); + writer.Write((byte)0xAF); // Packet ID + writer.Write(killed); + writer.Write(corpse); + writer.Write(0); // ?? + } - var writer = new SpanWriter(buffer); - writer.Write((byte)0xAF); // Packet ID - writer.Write(killed); - writer.Write(corpse); - writer.Write(0); // ?? + public static void SendDeathAnimation(this NetState ns, Serial killed, Serial corpse) + { + if (ns.CannotSendPackets()) + { + return; } - public static void SendDeathAnimation(this NetState ns, Serial killed, Serial corpse) - { - if (ns == null) - { - return; - } + Span span = stackalloc byte[DeathAnimationPacketLength]; + CreateDeathAnimation(span, killed, corpse); + ns.Send(span); + } - Span span = stackalloc byte[DeathAnimationPacketLength]; - CreateDeathAnimation(span, killed, corpse); - ns.Send(span); + public static void CreateMobileMoving(Span buffer, Mobile m, int noto, bool stygianAbyss) + { + if (buffer[0] != 0) + { + return; } - public static void CreateMobileMoving(Span buffer, Mobile m, int noto, bool stygianAbyss) + var loc = m.Location; + var hue = m.SolidHueOverride >= 0 ? m.SolidHueOverride : m.Hue; + + var writer = new SpanWriter(buffer); + writer.Write((byte)0x77); // Packet ID + writer.Write(m.Serial); + writer.Write((short)m.Body); + writer.Write((short)loc.m_X); + writer.Write((short)loc.m_Y); + writer.Write((sbyte)loc.m_Z); + writer.Write((byte)m.Direction); + writer.Write((short)hue); + writer.Write((byte)m.GetPacketFlags(stygianAbyss)); + writer.Write((byte)noto); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SendMobileMoving(this NetState ns, Mobile source, Mobile target) => + ns.SendMobileMoving(target, Notoriety.Compute(source, target)); + + public static void SendMobileMoving(this NetState ns, Mobile target, int noto) + { + if (ns.CannotSendPackets()) { - if (buffer[0] != 0) - { - return; - } - - var loc = m.Location; - var hue = m.SolidHueOverride >= 0 ? m.SolidHueOverride : m.Hue; - - var writer = new SpanWriter(buffer); - writer.Write((byte)0x77); // Packet ID - writer.Write(m.Serial); - writer.Write((short)m.Body); - writer.Write((short)loc.m_X); - writer.Write((short)loc.m_Y); - writer.Write((sbyte)loc.m_Z); - writer.Write((byte)m.Direction); - writer.Write((short)hue); - writer.Write((byte)m.GetPacketFlags(stygianAbyss)); - writer.Write((byte)noto); + return; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void SendMobileMoving(this NetState ns, Mobile source, Mobile target) => - ns.SendMobileMoving(target, Notoriety.Compute(source, target)); + Span buffer = stackalloc byte[MobileMovingPacketLength].InitializePacket(); + CreateMobileMoving(buffer, target, noto, ns.StygianAbyss); + ns.Send(buffer); + } - public static void SendMobileMoving(this NetState ns, Mobile target, int noto) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SendMobileMovingUsingCache(this NetState ns, Span2D cache, Mobile source, Mobile target) => + ns.SendMobileMovingUsingCache(cache, target, Notoriety.Compute(source, target)); + + // Requires a buffer of 16 packets, 17bytes per packet (272 bytes). + // Requires cache to have the first byte of each packet zeroed. + public static void SendMobileMovingUsingCache(this NetState ns, Span2D cache, Mobile target, int noto) + { + if (ns.CannotSendPackets()) { - if (ns == null) - { - return; - } - - Span buffer = stackalloc byte[MobileMovingPacketLength].InitializePacket(); - CreateMobileMoving(buffer, target, noto, ns.StygianAbyss); - ns.Send(buffer); + return; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void SendMobileMovingUsingCache(this NetState ns, Span2D cache, Mobile source, Mobile target) => - ns.SendMobileMovingUsingCache(cache, target, Notoriety.Compute(source, target)); + var stygianAbyss = ns.StygianAbyss; + var row = noto * 2 + (stygianAbyss ? 1 : 0); + var buffer = cache.GetRowSpan(row); + CreateMobileMoving(buffer, target, noto, stygianAbyss); - // Requires a buffer of 16 packets, 17bytes per packet (272 bytes). - // Requires cache to have the first byte of each packet zeroed. - public static void SendMobileMovingUsingCache(this NetState ns, Span2D cache, Mobile target, int noto) + ns.Send(buffer); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void WriteAttribute( + this ref SpanWriter writer, int max, int cur, bool normalize = false, bool reverse = false + ) + { + if (normalize && max != 0) { - if (ns == null) + if (reverse) { - return; - } - - var stygianAbyss = ns.StygianAbyss; - var row = noto * 2 + (stygianAbyss ? 1 : 0); - var buffer = cache.GetRowSpan(row); - CreateMobileMoving(buffer, target, noto, stygianAbyss); - - ns.Send(buffer); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void WriteAttribute( - this ref SpanWriter writer, int max, int cur, bool normalize = false, bool reverse = false - ) - { - if (normalize && max != 0) - { - if (reverse) - { - writer.Write((short)(cur * AttributeMaximum / max)); - writer.Write((short)AttributeMaximum); - } - else - { - writer.Write((short)AttributeMaximum); - writer.Write((short)(cur * AttributeMaximum / max)); - } + writer.Write((short)(cur * AttributeMaximum / max)); + writer.Write((short)AttributeMaximum); } else { - if (reverse) - { - writer.Write((short)cur); - writer.Write((short)max); - } - else - { - writer.Write((short)max); - writer.Write((short)cur); - } + writer.Write((short)AttributeMaximum); + writer.Write((short)(cur * AttributeMaximum / max)); } } - - public static void SendMobileHits(this NetState ns, Mobile m, bool normalize = false) + else { - if (ns == null) + if (reverse) { - return; - } - - Span span = stackalloc byte[MobileAttributePacketLength]; - CreateMobileHits(span, m, normalize); - ns.Send(span); - } - - public static void CreateMobileHits(Span buffer, Mobile m, bool normalize = false) - { - if (buffer[0] != 0) - { - return; - } - - var writer = new SpanWriter(buffer); - writer.Write((byte)0xA1); // Packet ID - writer.Write(m.Serial); - writer.WriteAttribute(m.HitsMax, m.Hits, normalize); - } - - public static void SendMobileMana(this NetState ns, Mobile m, bool normalize = false) - { - if (ns == null) - { - return; - } - - Span span = stackalloc byte[MobileAttributePacketLength]; - CreateMobileMana(span, m, normalize); - ns.Send(span); - } - - public static void CreateMobileMana(Span buffer, Mobile m, bool normalize = false) - { - if (buffer[0] != 0) - { - return; - } - - var writer = new SpanWriter(buffer); - writer.Write((byte)0xA2); // Packet ID - writer.Write(m.Serial); - writer.WriteAttribute(m.ManaMax, m.Mana, normalize); - } - - public static void SendMobileStam(this NetState ns, Mobile m, bool normalize = false) - { - if (ns == null) - { - return; - } - - Span span = stackalloc byte[MobileAttributePacketLength]; - CreateMobileStam(span, m, normalize); - ns.Send(span); - } - - public static void CreateMobileStam(Span buffer, Mobile m, bool normalize = false) - { - if (buffer[0] != 0) - { - return; - } - - var writer = new SpanWriter(buffer); - writer.Write((byte)0xA3); // Packet ID - writer.Write(m.Serial); - writer.WriteAttribute(m.StamMax, m.Stam, normalize); - } - - public static void SendMobileAttributes(this NetState ns, Mobile m, bool normalize = false) - { - if (ns == null) - { - return; - } - - Span span = stackalloc byte[MobileAttributesPacketLength]; - CreateMobileAttributes(span, m, normalize); - ns.Send(span); - } - - public static void CreateMobileAttributes(Span buffer, Mobile m, bool normalize = false) - { - if (buffer[0] != 0) - { - return; - } - - var writer = new SpanWriter(buffer); - writer.Write((byte)0x2D); // Packet ID - writer.Write(m.Serial); - - writer.WriteAttribute(m.HitsMax, m.Hits, normalize); - writer.WriteAttribute(m.ManaMax, m.Mana, normalize); - writer.WriteAttribute(m.StamMax, m.Stam, normalize); - } - - public static void SendMobileName(this NetState ns, Mobile m) - { - if (ns == null) - { - return; - } - - var writer = new SpanWriter(stackalloc byte[37]); - writer.Write((byte)0x98); // Packet ID - writer.Write((ushort)37); - writer.Write(m.Serial); - writer.WriteAscii(m.Name ?? "", 29); - writer.Write((byte)0); // Null terminator - - ns.Send(writer.Span); - } - - public static void CreateMobileAnimation( - Span buffer, - Serial mobile, int action, int frameCount, int repeatCount, bool forward, bool repeat, int delay - ) - { - if (buffer[0] != 0) - { - return; - } - - var writer = new SpanWriter(buffer); - writer.Write((byte)0x6E); // Packet ID - writer.Write(mobile); - writer.Write((short)action); - writer.Write((short)frameCount); - writer.Write((short)repeatCount); - writer.Write(!forward); // protocol has really "reverse" but I find this more intuitive - writer.Write(repeat); - writer.Write((byte)delay); - } - - public static void SendMobileAnimation( - this NetState ns, - Serial mobile, int action, int frameCount, int repeatCount, bool forward, bool repeat, int delay - ) - { - if (ns == null) - { - return; - } - - Span span = stackalloc byte[MobileAnimationPacketLength]; - CreateMobileAnimation(span, mobile, action, frameCount, repeatCount, forward, repeat, delay); - ns.Send(span); - } - - public static void CreateNewMobileAnimation( - Span buffer, - Serial mobile, int action, int frameCount, int delay - ) - { - var writer = new SpanWriter(buffer); - writer.Write((byte)0xE2); // Packet ID - writer.Write(mobile); - writer.Write((short)action); - writer.Write((short)frameCount); - writer.Write((byte)delay); - } - - public static void SendNewMobileAnimation(this NetState ns, Serial mobile, int action, int frameCount, int delay) - { - if (ns == null) - { - return; - } - - Span span = stackalloc byte[NewMobileAnimationPacketLength]; - CreateNewMobileAnimation(span, mobile, action, frameCount, delay); - ns.Send(span); - } - - public static void SendMobileHealthbar(this NetState ns, Mobile m, Healthbar healthbar) - { - if (ns == null) - { - return; - } - - Span span = stackalloc byte[MobileHealthbarPacketLength]; - CreateMobileHealthbar(span, m, healthbar); - ns.Send(span); - } - - public static void CreateMobileHealthbar(Span buffer, Mobile m, Healthbar healthbar) - { - if (buffer[0] != 0) - { - return; - } - - switch (healthbar) - { - case Healthbar.Poison: - { - CreateMobileHealthbar(buffer, m.Serial, Healthbar.Poison, m.Poison?.Level + 1 ?? 0); - break; - } - case Healthbar.Yellow: - { - CreateMobileHealthbar(buffer, m.Serial, Healthbar.Yellow, m.Blessed || m.YellowHealthbar ? 1 : 0); - break; - } - default: - { - Console.WriteLine("Packets: Invalid Healthbar {0} in {1}", healthbar, nameof(CreateMobileHealthbar)); - CreateMobileHealthbar(buffer, m.Serial, Healthbar.Normal, 0); - break; - } - } - } - - public static void CreateMobileHealthbar(Span buffer, Serial serial, Healthbar healthbar, int level) - { - var writer = new SpanWriter(buffer); - writer.Write((byte)0x17); // Packet ID - writer.Write((ushort)12); - writer.Write(serial); - writer.Write((short)1); // Show bar - writer.Write((short)healthbar); - writer.Write((byte)level); // 0 is off for that bar type - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void CreateMobileStatusCompact(Span buffer, Mobile m, bool canBeRenamed) => - CreateMobileStatus(buffer, null, m, 0, canBeRenamed); - - public static void SendMobileStatusCompact(this NetState ns, Mobile m, bool canBeRenamed) - { - if (ns == null) - { - return; - } - - Span buffer = stackalloc byte[MobileStatusCompactLength]; - CreateMobileStatusCompact(buffer, m, canBeRenamed); - - ns.Send(buffer); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void SendMobileStatus(this NetState ns, Mobile m) => ns.SendMobileStatus(m, m); - - public static void SendMobileStatus(this NetState ns, Mobile beholder, Mobile beheld) - { - if (ns == null || beheld == null) - { - return; - } - - Span buffer = stackalloc byte[MobileStatusMaxLength]; - int version; - - if (beholder != beheld) - { - version = 0; - } - else if (Core.HS && ns.ExtendedStatus) - { - version = 6; - } - else if (Core.ML && ns.SupportsExpansion(Expansion.ML)) - { - /* - * For the ML era, the version value must be 5 if the original UO distribution - * is used and the client is not lower than version 5 - */ - version = ExtendedStatus ? 6 : 5; + writer.Write((short)cur); + writer.Write((short)max); } else { - version = Core.AOS ? 4 : 3; + writer.Write((short)max); + writer.Write((short)cur); } + } + } - var length = CreateMobileStatus(buffer, beholder, beheld, version, beheld.CanBeRenamedBy(beholder)); - ns.Send(buffer[..length]); + public static void SendMobileHits(this NetState ns, Mobile m, bool normalize = false) + { + if (ns.CannotSendPackets()) + { + return; } - public static int CreateMobileStatus( - Span buffer, Mobile beholder, Mobile beheld, int version, bool canBeRenamed - ) + Span span = stackalloc byte[MobileAttributePacketLength]; + CreateMobileHits(span, m, normalize); + ns.Send(span); + } + + public static void CreateMobileHits(Span buffer, Mobile m, bool normalize = false) + { + if (buffer[0] != 0) { - if (buffer[0] != 0) - { - return buffer.Length; - } + return; + } - var name = beheld.Name ?? ""; + var writer = new SpanWriter(buffer); + writer.Write((byte)0xA1); // Packet ID + writer.Write(m.Serial); + writer.WriteAttribute(m.HitsMax, m.Hits, normalize); + } - var writer = new SpanWriter(buffer); - writer.Write((byte)0x11); // Packet ID - writer.Seek(2, SeekOrigin.Current); - writer.Write(beheld.Serial); - writer.WriteAscii(name, 30); - writer.WriteAttribute(beheld.HitsMax, beheld.Hits, version == 0, true); - writer.Write(canBeRenamed); - writer.Write((byte)version); + public static void SendMobileMana(this NetState ns, Mobile m, bool normalize = false) + { + if (ns.CannotSendPackets()) + { + return; + } - if (version <= 0) - { - writer.WritePacketLength(); - return writer.Position; - } + Span span = stackalloc byte[MobileAttributePacketLength]; + CreateMobileMana(span, m, normalize); + ns.Send(span); + } - writer.Write(beheld.Female); + public static void CreateMobileMana(Span buffer, Mobile m, bool normalize = false) + { + if (buffer[0] != 0) + { + return; + } - writer.Write((short)beheld.Str); - writer.Write((short)beheld.Dex); - writer.Write((short)beheld.Int); + var writer = new SpanWriter(buffer); + writer.Write((byte)0xA2); // Packet ID + writer.Write(m.Serial); + writer.WriteAttribute(m.ManaMax, m.Mana, normalize); + } - writer.Write((short)beheld.Stam); - writer.Write((short)beheld.StamMax); - writer.Write((short)beheld.Mana); - writer.Write((short)beheld.ManaMax); + public static void SendMobileStam(this NetState ns, Mobile m, bool normalize = false) + { + if (ns.CannotSendPackets()) + { + return; + } - writer.Write(beheld.TotalGold); - writer.Write((short)(Core.AOS ? beheld.PhysicalResistance : (int)(beheld.ArmorRating + 0.5))); - writer.Write((short)(Mobile.BodyWeight + beheld.TotalWeight)); + Span span = stackalloc byte[MobileAttributePacketLength]; + CreateMobileStam(span, m, normalize); + ns.Send(span); + } - if (version >= 5) - { - writer.Write((short)beheld.MaxWeight); - writer.Write((byte)(beheld.Race?.RaceID + 1 ?? 0)); // Would be 0x00 if it's a non-ML enabled account but... - } + public static void CreateMobileStam(Span buffer, Mobile m, bool normalize = false) + { + if (buffer[0] != 0) + { + return; + } - writer.Write((short)beheld.StatCap); + var writer = new SpanWriter(buffer); + writer.Write((byte)0xA3); // Packet ID + writer.Write(m.Serial); + writer.WriteAttribute(m.StamMax, m.Stam, normalize); + } - writer.Write((byte)beheld.Followers); - writer.Write((byte)beheld.FollowersMax); + public static void SendMobileAttributes(this NetState ns, Mobile m, bool normalize = false) + { + if (ns.CannotSendPackets()) + { + return; + } - if (version >= 4) - { - writer.Write((short)beheld.FireResistance); // Fire - writer.Write((short)beheld.ColdResistance); // Cold - writer.Write((short)beheld.PoisonResistance); // Poison - writer.Write((short)beheld.EnergyResistance); // Energy - writer.Write((short)beheld.Luck); // Luck + Span span = stackalloc byte[MobileAttributesPacketLength]; + CreateMobileAttributes(span, m, normalize); + ns.Send(span); + } - var weapon = beheld.Weapon; + public static void CreateMobileAttributes(Span buffer, Mobile m, bool normalize = false) + { + if (buffer[0] != 0) + { + return; + } - int min = 0, max = 0; - weapon?.GetStatusDamage(beheld, out min, out max); - writer.Write((short)min); // Damage min - writer.Write((short)max); // Damage max + var writer = new SpanWriter(buffer); + writer.Write((byte)0x2D); // Packet ID + writer.Write(m.Serial); - writer.Write(beheld.TithingPoints); - } + writer.WriteAttribute(m.HitsMax, m.Hits, normalize); + writer.WriteAttribute(m.ManaMax, m.Mana, normalize); + writer.WriteAttribute(m.StamMax, m.Stam, normalize); + } - if (version >= 6) - { - for (var i = 0; i < 15; ++i) + public static void SendMobileName(this NetState ns, Mobile m) + { + if (ns.CannotSendPackets()) + { + return; + } + + var writer = new SpanWriter(stackalloc byte[37]); + writer.Write((byte)0x98); // Packet ID + writer.Write((ushort)37); + writer.Write(m.Serial); + writer.WriteAscii(m.Name ?? "", 29); + writer.Write((byte)0); // Null terminator + + ns.Send(writer.Span); + } + + public static void CreateMobileAnimation( + Span buffer, + Serial mobile, int action, int frameCount, int repeatCount, bool forward, bool repeat, int delay + ) + { + if (buffer[0] != 0) + { + return; + } + + var writer = new SpanWriter(buffer); + writer.Write((byte)0x6E); // Packet ID + writer.Write(mobile); + writer.Write((short)action); + writer.Write((short)frameCount); + writer.Write((short)repeatCount); + writer.Write(!forward); // protocol has really "reverse" but I find this more intuitive + writer.Write(repeat); + writer.Write((byte)delay); + } + + public static void SendMobileAnimation( + this NetState ns, + Serial mobile, int action, int frameCount, int repeatCount, bool forward, bool repeat, int delay + ) + { + if (ns.CannotSendPackets()) + { + return; + } + + Span span = stackalloc byte[MobileAnimationPacketLength]; + CreateMobileAnimation(span, mobile, action, frameCount, repeatCount, forward, repeat, delay); + ns.Send(span); + } + + public static void CreateNewMobileAnimation( + Span buffer, + Serial mobile, int action, int frameCount, int delay + ) + { + var writer = new SpanWriter(buffer); + writer.Write((byte)0xE2); // Packet ID + writer.Write(mobile); + writer.Write((short)action); + writer.Write((short)frameCount); + writer.Write((byte)delay); + } + + public static void SendNewMobileAnimation(this NetState ns, Serial mobile, int action, int frameCount, int delay) + { + if (ns.CannotSendPackets()) + { + return; + } + + Span span = stackalloc byte[NewMobileAnimationPacketLength]; + CreateNewMobileAnimation(span, mobile, action, frameCount, delay); + ns.Send(span); + } + + public static void SendMobileHealthbar(this NetState ns, Mobile m, Healthbar healthbar) + { + if (ns.CannotSendPackets()) + { + return; + } + + Span span = stackalloc byte[MobileHealthbarPacketLength]; + CreateMobileHealthbar(span, m, healthbar); + ns.Send(span); + } + + public static void CreateMobileHealthbar(Span buffer, Mobile m, Healthbar healthbar) + { + if (buffer[0] != 0) + { + return; + } + + switch (healthbar) + { + case Healthbar.Poison: { - writer.Write((short)beheld.GetAOSStatus(i)); + CreateMobileHealthbar(buffer, m.Serial, Healthbar.Poison, m.Poison?.Level + 1 ?? 0); + break; } - } + case Healthbar.Yellow: + { + CreateMobileHealthbar(buffer, m.Serial, Healthbar.Yellow, m.Blessed || m.YellowHealthbar ? 1 : 0); + break; + } + default: + { + Console.WriteLine("Packets: Invalid Healthbar {0} in {1}", healthbar, nameof(CreateMobileHealthbar)); + CreateMobileHealthbar(buffer, m.Serial, Healthbar.Normal, 0); + break; + } + } + } + public static void CreateMobileHealthbar(Span buffer, Serial serial, Healthbar healthbar, int level) + { + var writer = new SpanWriter(buffer); + writer.Write((byte)0x17); // Packet ID + writer.Write((ushort)12); + writer.Write(serial); + writer.Write((short)1); // Show bar + writer.Write((short)healthbar); + writer.Write((byte)level); // 0 is off for that bar type + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void CreateMobileStatusCompact(Span buffer, Mobile m, bool canBeRenamed) => + CreateMobileStatus(buffer, null, m, 0, canBeRenamed); + + public static void SendMobileStatusCompact(this NetState ns, Mobile m, bool canBeRenamed) + { + if (ns.CannotSendPackets()) + { + return; + } + + Span buffer = stackalloc byte[MobileStatusCompactLength]; + CreateMobileStatusCompact(buffer, m, canBeRenamed); + + ns.Send(buffer); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SendMobileStatus(this NetState ns, Mobile m) => ns.SendMobileStatus(m, m); + + public static void SendMobileStatus(this NetState ns, Mobile beholder, Mobile beheld) + { + if (ns == null || beheld == null) + { + return; + } + + Span buffer = stackalloc byte[MobileStatusMaxLength]; + int version; + + if (beholder != beheld) + { + version = 0; + } + else if (Core.HS && ns.ExtendedStatus) + { + version = 6; + } + else if (Core.ML && ns.SupportsExpansion(Expansion.ML)) + { + /* + * For the ML era, the version value must be 5 if the original UO distribution + * is used and the client is not lower than version 5 + */ + version = ExtendedStatus ? 6 : 5; + } + else + { + version = Core.AOS ? 4 : 3; + } + + var length = CreateMobileStatus(buffer, beholder, beheld, version, beheld.CanBeRenamedBy(beholder)); + ns.Send(buffer[..length]); + } + + public static int CreateMobileStatus( + Span buffer, Mobile beholder, Mobile beheld, int version, bool canBeRenamed + ) + { + if (buffer[0] != 0) + { + return buffer.Length; + } + + var name = beheld.Name ?? ""; + + var writer = new SpanWriter(buffer); + writer.Write((byte)0x11); // Packet ID + writer.Seek(2, SeekOrigin.Current); + writer.Write(beheld.Serial); + writer.WriteAscii(name, 30); + writer.WriteAttribute(beheld.HitsMax, beheld.Hits, version == 0, true); + writer.Write(canBeRenamed); + writer.Write((byte)version); + + if (version <= 0) + { writer.WritePacketLength(); return writer.Position; } - public static void SendMobileUpdate(this NetState ns, Mobile m) + writer.Write(beheld.Female); + + writer.Write((short)beheld.Str); + writer.Write((short)beheld.Dex); + writer.Write((short)beheld.Int); + + writer.Write((short)beheld.Stam); + writer.Write((short)beheld.StamMax); + writer.Write((short)beheld.Mana); + writer.Write((short)beheld.ManaMax); + + writer.Write(beheld.TotalGold); + writer.Write((short)(Core.AOS ? beheld.PhysicalResistance : (int)(beheld.ArmorRating + 0.5))); + writer.Write((short)(Mobile.BodyWeight + beheld.TotalWeight)); + + if (version >= 5) { - if (ns == null) - { - return; - } - - var writer = new SpanWriter(stackalloc byte[19]); - writer.Write((byte)0x20); // Packet ID - writer.Write(m.Serial); - writer.Write((short)m.Body); - writer.Write((byte)0); - writer.Write((short)(m.SolidHueOverride >= 0 ? m.SolidHueOverride : m.Hue)); - writer.Write((byte)m.GetPacketFlags(ns.StygianAbyss)); - writer.Write((short)m.X); - writer.Write((short)m.Y); - writer.Write((short)0); - writer.Write((byte)m.Direction); - writer.Write((sbyte)m.Z); - - ns.Send(writer.Span); + writer.Write((short)beheld.MaxWeight); + writer.Write((byte)(beheld.Race?.RaceID + 1 ?? 0)); // Would be 0x00 if it's a non-ML enabled account but... } - public static void SendMobileIncoming(this NetState ns, Mobile beholder, Mobile beheld) - { - if (ns == null) - { - return; - } + writer.Write((short)beheld.StatCap); - Span layers = stackalloc bool[256]; + writer.Write((byte)beheld.Followers); + writer.Write((byte)beheld.FollowersMax); + + if (version >= 4) + { + writer.Write((short)beheld.FireResistance); // Fire + writer.Write((short)beheld.ColdResistance); // Cold + writer.Write((short)beheld.PoisonResistance); // Poison + writer.Write((short)beheld.EnergyResistance); // Energy + writer.Write((short)beheld.Luck); // Luck + + var weapon = beheld.Weapon; + + int min = 0, max = 0; + weapon?.GetStatusDamage(beheld, out min, out max); + writer.Write((short)min); // Damage min + writer.Write((short)max); // Damage max + + writer.Write(beheld.TithingPoints); + } + + if (version >= 6) + { + for (var i = 0; i < 15; ++i) + { + writer.Write((short)beheld.GetAOSStatus(i)); + } + } + + writer.WritePacketLength(); + return writer.Position; + } + + public static void SendMobileUpdate(this NetState ns, Mobile m) + { + if (ns.CannotSendPackets()) + { + return; + } + + var writer = new SpanWriter(stackalloc byte[19]); + writer.Write((byte)0x20); // Packet ID + writer.Write(m.Serial); + writer.Write((short)m.Body); + writer.Write((byte)0); + writer.Write((short)(m.SolidHueOverride >= 0 ? m.SolidHueOverride : m.Hue)); + writer.Write((byte)m.GetPacketFlags(ns.StygianAbyss)); + writer.Write((short)m.X); + writer.Write((short)m.Y); + writer.Write((short)0); + writer.Write((byte)m.Direction); + writer.Write((sbyte)m.Z); + + ns.Send(writer.Span); + } + + public static void SendMobileIncoming(this NetState ns, Mobile beholder, Mobile beheld) + { + if (ns.CannotSendPackets()) + { + return; + } + + Span layers = stackalloc bool[256]; #if NO_LOCAL_INIT layers.Clear(); #endif - var eq = beheld.Items; - var maxLength = 23 + (eq.Count + 2) * 9; - var writer = new SpanWriter(stackalloc byte[maxLength]); - writer.Write((byte)0x78); // Packet ID - writer.Seek(2, SeekOrigin.Current); + var eq = beheld.Items; + var maxLength = 23 + (eq.Count + 2) * 9; + var writer = new SpanWriter(stackalloc byte[maxLength]); + writer.Write((byte)0x78); // Packet ID + writer.Seek(2, SeekOrigin.Current); - var sa = ns.StygianAbyss; - var newPacket = ns.NewMobileIncoming; - var itemIdMask = newPacket ? 0xFFFF : 0x7FFF; + var sa = ns.StygianAbyss; + var newPacket = ns.NewMobileIncoming; + var itemIdMask = newPacket ? 0xFFFF : 0x7FFF; - var hue = beheld.SolidHueOverride >= 0 ? beheld.SolidHueOverride : beheld.Hue; + var hue = beheld.SolidHueOverride >= 0 ? beheld.SolidHueOverride : beheld.Hue; - writer.Write(beheld.Serial); - writer.Write((short)beheld.Body); - writer.Write((short)beheld.X); - writer.Write((short)beheld.Y); - writer.Write((sbyte)beheld.Z); - writer.Write((byte)beheld.Direction); - writer.Write((short)hue); - writer.Write((byte)beheld.GetPacketFlags(sa)); - writer.Write((byte)Notoriety.Compute(beholder, beheld)); + writer.Write(beheld.Serial); + writer.Write((short)beheld.Body); + writer.Write((short)beheld.X); + writer.Write((short)beheld.Y); + writer.Write((sbyte)beheld.Z); + writer.Write((byte)beheld.Direction); + writer.Write((short)hue); + writer.Write((byte)beheld.GetPacketFlags(sa)); + writer.Write((byte)Notoriety.Compute(beholder, beheld)); - for (var i = 0; i < eq.Count; ++i) + for (var i = 0; i < eq.Count; ++i) + { + var item = eq[i]; + var layer = (byte)item.Layer; + + if (item.Deleted || !beholder.CanSee(item) || layers[layer]) { - var item = eq[i]; - var layer = (byte)item.Layer; - - if (item.Deleted || !beholder.CanSee(item) || layers[layer]) - { - continue; - } - - layers[layer] = true; - hue = beheld.SolidHueOverride >= 0 ? beheld.SolidHueOverride : item.Hue; - - var itemID = item.ItemID & itemIdMask; - var writeHue = newPacket || hue != 0; - - if (!newPacket && writeHue) - { - itemID |= 0x8000; - } - - writer.Write(item.Serial); - writer.Write((ushort)itemID); - writer.Write(layer); - - if (writeHue) - { - writer.Write((short)hue); - } + continue; } - if (beheld.HairItemID > 0 && !layers[(int)Layer.Hair]) + layers[layer] = true; + hue = beheld.SolidHueOverride >= 0 ? beheld.SolidHueOverride : item.Hue; + + var itemID = item.ItemID & itemIdMask; + var writeHue = newPacket || hue != 0; + + if (!newPacket && writeHue) { - layers[(int)Layer.Hair] = true; - hue = beheld.SolidHueOverride >= 0 ? beheld.SolidHueOverride : beheld.HairHue; - - var itemID = beheld.HairItemID & itemIdMask; - var writeHue = newPacket || hue != 0; - - if (!newPacket && writeHue) - { - itemID |= 0x8000; - } - - writer.Write(HairInfo.FakeSerial(beheld.Serial)); - writer.Write((ushort)itemID); - writer.Write((byte)Layer.Hair); - - if (writeHue) - { - writer.Write((short)hue); - } + itemID |= 0x8000; } - if (beheld.FacialHairItemID > 0 && !layers[(int)Layer.FacialHair]) + writer.Write(item.Serial); + writer.Write((ushort)itemID); + writer.Write(layer); + + if (writeHue) { - layers[(int)Layer.FacialHair] = true; - hue = beheld.SolidHueOverride >= 0 ? beheld.SolidHueOverride : beheld.FacialHairHue; - - var itemID = beheld.FacialHairItemID & itemIdMask; - var writeHue = newPacket || hue != 0; - - if (!newPacket && writeHue) - { - itemID |= 0x8000; - } - - writer.Write(FacialHairInfo.FakeSerial(beheld.Serial)); - writer.Write((ushort)itemID); - writer.Write((byte)Layer.FacialHair); - - if (writeHue) - { - writer.Write((short)hue); - } + writer.Write((short)hue); } - - writer.Write(0); // terminate - - writer.WritePacketLength(); - ns.Send(writer.Span); } + + if (beheld.HairItemID > 0 && !layers[(int)Layer.Hair]) + { + layers[(int)Layer.Hair] = true; + hue = beheld.SolidHueOverride >= 0 ? beheld.SolidHueOverride : beheld.HairHue; + + var itemID = beheld.HairItemID & itemIdMask; + var writeHue = newPacket || hue != 0; + + if (!newPacket && writeHue) + { + itemID |= 0x8000; + } + + writer.Write(HairInfo.FakeSerial(beheld.Serial)); + writer.Write((ushort)itemID); + writer.Write((byte)Layer.Hair); + + if (writeHue) + { + writer.Write((short)hue); + } + } + + if (beheld.FacialHairItemID > 0 && !layers[(int)Layer.FacialHair]) + { + layers[(int)Layer.FacialHair] = true; + hue = beheld.SolidHueOverride >= 0 ? beheld.SolidHueOverride : beheld.FacialHairHue; + + var itemID = beheld.FacialHairItemID & itemIdMask; + var writeHue = newPacket || hue != 0; + + if (!newPacket && writeHue) + { + itemID |= 0x8000; + } + + writer.Write(FacialHairInfo.FakeSerial(beheld.Serial)); + writer.Write((ushort)itemID); + writer.Write((byte)Layer.FacialHair); + + if (writeHue) + { + writer.Write((short)hue); + } + } + + writer.Write(0); // terminate + + writer.WritePacketLength(); + ns.Send(writer.Span); } } diff --git a/Projects/Server/Network/Packets/OutgoingMovementPackets.cs b/Projects/Server/Network/Packets/OutgoingMovementPackets.cs index 78ee3c892..b366a7dec 100644 --- a/Projects/Server/Network/Packets/OutgoingMovementPackets.cs +++ b/Projects/Server/Network/Packets/OutgoingMovementPackets.cs @@ -16,102 +16,101 @@ using System.Buffers; using System.Runtime.CompilerServices; -namespace Server.Network +namespace Server.Network; + +public enum SpeedControlSetting { - public enum SpeedControlSetting + Disable, + Mount, + Walk +} + +public static class OutgoingMovementPackets +{ + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SendSpeedControl(this NetState ns, SpeedControlSetting speedControl) => + ns?.Send(stackalloc byte[] { 0xBF, 0x00, 0x6, 0x00, 0x26, (byte)speedControl }); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SendMovePlayer(this NetState ns, Direction d) => ns?.Send(stackalloc byte[] { 0x97, (byte)d }); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SendMovementAck(this NetState ns, int seq, Mobile m) => + ns.SendMovementAck(seq, Notoriety.Compute(m, m)); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SendMovementAck(this NetState ns, int seq, int noto) => + ns?.Send(stackalloc byte[] { 0x22, (byte)seq, (byte)noto }); + + public static void SendMovementRej(this NetState ns, int seq, Mobile m) { - Disable, - Mount, - Walk + if (ns.CannotSendPackets()) + { + return; + } + + var writer = new SpanWriter(stackalloc byte[8]); + writer.Write((byte)0x21); // Packet ID + writer.Write((byte)seq); + writer.Write((short)m.X); + writer.Write((short)m.Y); + writer.Write((byte)m.Direction); + writer.Write((sbyte)m.Z); + + ns.Send(writer.Span); } - public static class OutgoingMovementPackets + public static void SendInitialFastwalkStack(this NetState ns, uint[] keys) { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void SendSpeedControl(this NetState ns, SpeedControlSetting speedControl) => - ns?.Send(stackalloc byte[] { 0xBF, 0x00, 0x6, 0x00, 0x26, (byte)speedControl }); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void SendMovePlayer(this NetState ns, Direction d) => ns?.Send(stackalloc byte[] { 0x97, (byte)d }); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void SendMovementAck(this NetState ns, int seq, Mobile m) => - ns.SendMovementAck(seq, Notoriety.Compute(m, m)); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void SendMovementAck(this NetState ns, int seq, int noto) => - ns?.Send(stackalloc byte[] { 0x22, (byte)seq, (byte)noto }); - - public static void SendMovementRej(this NetState ns, int seq, Mobile m) + if (ns.CannotSendPackets()) { - if (ns == null) - { - return; - } - - var writer = new SpanWriter(stackalloc byte[8]); - writer.Write((byte)0x21); // Packet ID - writer.Write((byte)seq); - writer.Write((short)m.X); - writer.Write((short)m.Y); - writer.Write((byte)m.Direction); - writer.Write((sbyte)m.Z); - - ns.Send(writer.Span); + return; } - public static void SendInitialFastwalkStack(this NetState ns, uint[] keys) + var writer = new SpanWriter(stackalloc byte[29]); + writer.Write((byte)0xBF); // Packet ID + writer.Write((ushort)29); + writer.Write((ushort)0x1); // Subpacket + writer.Write(keys[0]); + writer.Write(keys[1]); + writer.Write(keys[2]); + writer.Write(keys[3]); + writer.Write(keys[4]); + writer.Write(keys[5]); + + ns.Send(writer.Span); + } + + public static void SendFastwalkStackKey(this NetState ns, uint key = 0) + { + if (ns.CannotSendPackets()) { - if (ns == null) - { - return; - } - - var writer = new SpanWriter(stackalloc byte[29]); - writer.Write((byte)0xBF); // Packet ID - writer.Write((ushort)29); - writer.Write((ushort)0x1); // Subpacket - writer.Write(keys[0]); - writer.Write(keys[1]); - writer.Write(keys[2]); - writer.Write(keys[3]); - writer.Write(keys[4]); - writer.Write(keys[5]); - - ns.Send(writer.Span); + return; } - public static void SendFastwalkStackKey(this NetState ns, uint key = 0) + var writer = new SpanWriter(stackalloc byte[9]); + writer.Write((byte)0xBF); // Packet ID + writer.Write((ushort)9); + writer.Write((ushort)0x2); // Subpacket + writer.Write(key); + + ns.Send(writer.Span); + } + + public static void SendTimeSyncResponse(this NetState ns) + { + if (ns.CannotSendPackets()) { - if (ns == null) - { - return; - } - - var writer = new SpanWriter(stackalloc byte[9]); - writer.Write((byte)0xBF); // Packet ID - writer.Write((ushort)9); - writer.Write((ushort)0x2); // Subpacket - writer.Write(key); - - ns.Send(writer.Span); + return; } - public static void SendTimeSyncResponse(this NetState ns) - { - if (ns == null) - { - return; - } + var writer = new SpanWriter(stackalloc byte[25]); + writer.Write((byte)0xF2); // Packet ID - var writer = new SpanWriter(stackalloc byte[25]); - writer.Write((byte)0xF2); // Packet ID + writer.Write(Core.TickCount); // ?? + writer.Write(Core.TickCount); // ?? + writer.Write(Core.TickCount); // ?? - writer.Write(Core.TickCount); // ?? - writer.Write(Core.TickCount); // ?? - writer.Write(Core.TickCount); // ?? - - ns.Send(writer.Span); - } + ns.Send(writer.Span); } } diff --git a/Projects/Server/Network/Packets/OutgoingPackets.cs b/Projects/Server/Network/Packets/OutgoingPackets.cs new file mode 100644 index 000000000..a20356fe9 --- /dev/null +++ b/Projects/Server/Network/Packets/OutgoingPackets.cs @@ -0,0 +1,9 @@ +using System.Runtime.CompilerServices; + +namespace Server.Network; + +public static class OutgoingPackets +{ + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool CannotSendPackets(this NetState ns) => ns?.Connection == null || ns.BlockAllPackets; +} diff --git a/Projects/Server/Network/Packets/OutgoingPlayerPackets.cs b/Projects/Server/Network/Packets/OutgoingPlayerPackets.cs index 051ac8f7e..af33c444e 100644 --- a/Projects/Server/Network/Packets/OutgoingPlayerPackets.cs +++ b/Projects/Server/Network/Packets/OutgoingPlayerPackets.cs @@ -17,338 +17,337 @@ using System; using System.Buffers; using System.Runtime.CompilerServices; -namespace Server.Network +namespace Server.Network; + +public enum LRReason : byte { - public enum LRReason : byte + CannotLift, + OutOfRange, + OutOfSight, + TryToSteal, + AreHolding, + Inspecific +} + +public static class OutgoingPlayerPackets +{ + public const int DragEffectPacketLength = 26; + + public static void SendStatLockInfo(this NetState ns, Mobile m) { - CannotLift, - OutOfRange, - OutOfSight, - TryToSteal, - AreHolding, - Inspecific + if (ns.CannotSendPackets()) + { + return; + } + + var writer = new SpanWriter(stackalloc byte[12]); + writer.Write((byte)0xBF); // Packet ID + writer.Write((ushort)12); + writer.Write((short)0x19); + writer.Write((byte)2); + writer.Write(m.Serial); + writer.Write((byte)0); + + var lockBits = ((int)m.StrLock << 4) | ((int)m.DexLock << 2) | (int)m.IntLock; + + writer.Write((byte)lockBits); + + ns.Send(writer.Span); } - public static class OutgoingPlayerPackets + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SendChangeUpdateRange(this NetState ns, byte range) => + ns?.Send(stackalloc byte[] { 0xC8, range }); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SendDeathStatus(this NetState ns, bool dead) => + ns?.Send(stackalloc byte[] { 0x2C, dead ? (byte)0 : (byte)2 }); + + public static void SendDisplayProfile(this NetState ns, Serial m, string header, string body, string footer) { - public const int DragEffectPacketLength = 26; - - public static void SendStatLockInfo(this NetState ns, Mobile m) + if (ns.CannotSendPackets()) { - if (ns == null) - { - return; - } - - var writer = new SpanWriter(stackalloc byte[12]); - writer.Write((byte)0xBF); // Packet ID - writer.Write((ushort)12); - writer.Write((short)0x19); - writer.Write((byte)2); - writer.Write(m.Serial); - writer.Write((byte)0); - - var lockBits = ((int)m.StrLock << 4) | ((int)m.DexLock << 2) | (int)m.IntLock; - - writer.Write((byte)lockBits); - - ns.Send(writer.Span); + return; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void SendChangeUpdateRange(this NetState ns, byte range) => - ns?.Send(stackalloc byte[] { 0xC8, range }); + header ??= ""; + body ??= ""; + footer ??= ""; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void SendDeathStatus(this NetState ns, bool dead) => - ns?.Send(stackalloc byte[] { 0x2C, dead ? (byte)0 : (byte)2 }); + var length = 12 + header.Length + footer.Length * 2 + body.Length * 2; + var writer = new SpanWriter(stackalloc byte[length]); + writer.Write((byte)0xB8); // Packet ID + writer.Write((ushort)length); + writer.Write(m); + writer.WriteAsciiNull(header); + writer.WriteBigUniNull(footer); + writer.WriteBigUniNull(body); - public static void SendDisplayProfile(this NetState ns, Serial m, string header, string body, string footer) + ns.Send(writer.Span); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SendLiftReject(this NetState ns, LRReason reason) => + ns?.Send(stackalloc byte[] { 0x27, (byte)reason }); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SendLogoutAck(this NetState ns) => ns?.Send(stackalloc byte[] { 0xD1, 0x01 }); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SendWeather(this NetState ns, byte type, byte density, byte temp) => + ns?.Send(stackalloc byte[] { 0x65, type, density, temp }); + + public static void SendServerChange(this NetState ns, Point3D p, Map map) + { + if (ns.CannotSendPackets()) { - if (ns == null) - { - return; - } - - header ??= ""; - body ??= ""; - footer ??= ""; - - var length = 12 + header.Length + footer.Length * 2 + body.Length * 2; - var writer = new SpanWriter(stackalloc byte[length]); - writer.Write((byte)0xB8); // Packet ID - writer.Write((ushort)length); - writer.Write(m); - writer.WriteAsciiNull(header); - writer.WriteBigUniNull(footer); - writer.WriteBigUniNull(body); - - ns.Send(writer.Span); + return; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void SendLiftReject(this NetState ns, LRReason reason) => - ns?.Send(stackalloc byte[] { 0x27, (byte)reason }); + var writer = new SpanWriter(stackalloc byte[16]); + writer.Write((byte)0x76); // Packet ID + writer.Write((short)p.X); + writer.Write((short)p.Y); + writer.Write((short)p.Z); + writer.Write((byte)0); + writer.Write((short)0); + writer.Write((short)0); + writer.Write((short)map.Width); + writer.Write((short)map.Height); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void SendLogoutAck(this NetState ns) => ns?.Send(stackalloc byte[] { 0xD1, 0x01 }); + ns.Send(writer.Span); + } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void SendWeather(this NetState ns, byte type, byte density, byte temp) => - ns?.Send(stackalloc byte[] { 0x65, type, density, temp }); - - public static void SendServerChange(this NetState ns, Point3D p, Map map) + public static void SendSkillsUpdate(this NetState ns, Skills skills) + { + if (ns.CannotSendPackets()) { - if (ns == null) - { - return; - } - - var writer = new SpanWriter(stackalloc byte[16]); - writer.Write((byte)0x76); // Packet ID - writer.Write((short)p.X); - writer.Write((short)p.Y); - writer.Write((short)p.Z); - writer.Write((byte)0); - writer.Write((short)0); - writer.Write((short)0); - writer.Write((short)map.Width); - writer.Write((short)map.Height); - - ns.Send(writer.Span); + return; } - public static void SendSkillsUpdate(this NetState ns, Skills skills) + var length = 6 + 9 * skills.Length; + var writer = new SpanWriter(stackalloc byte[length]); + writer.Write((byte)0x3A); // Packet ID + writer.Write((ushort)length); + writer.Write((byte)0x02); // type: absolute, capped + + for (var i = 0; i < skills.Length; ++i) { - if (ns == null) - { - return; - } + var s = skills[i]; - var length = 6 + 9 * skills.Length; - var writer = new SpanWriter(stackalloc byte[length]); - writer.Write((byte)0x3A); // Packet ID - writer.Write((ushort)length); - writer.Write((byte)0x02); // type: absolute, capped - - for (var i = 0; i < skills.Length; ++i) - { - var s = skills[i]; - - var v = s.NonRacialValue; - var uv = Math.Clamp((int)(v * 10), 0, 0xFFFF); - - writer.Write((ushort)(s.Info.SkillID + 1)); - writer.Write((ushort)uv); - writer.Write((ushort)s.BaseFixedPoint); - writer.Write((byte)s.Lock); - writer.Write((ushort)s.CapFixedPoint); - } - - writer.Write((short)0); // terminate - - ns.Send(writer.Span); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void SendSequence(this NetState ns, byte sequence) => ns?.Send(stackalloc byte[] { 0x7B, sequence }); - - public static void SendSkillChange(this NetState ns, Skill skill) - { - if (ns == null) - { - return; - } - - var writer = new SpanWriter(stackalloc byte[13]); - writer.Write((byte)0x3A); // Packet ID - writer.Write((ushort)13); - - var v = skill.NonRacialValue; + var v = s.NonRacialValue; var uv = Math.Clamp((int)(v * 10), 0, 0xFFFF); - writer.Write((byte)0xDF); // type: delta, capped - writer.Write((ushort)skill.Info.SkillID); + writer.Write((ushort)(s.Info.SkillID + 1)); writer.Write((ushort)uv); - writer.Write((ushort)skill.BaseFixedPoint); - writer.Write((byte)skill.Lock); - writer.Write((ushort)skill.CapFixedPoint); - - ns.Send(writer.Span); + writer.Write((ushort)s.BaseFixedPoint); + writer.Write((byte)s.Lock); + writer.Write((ushort)s.CapFixedPoint); } - public static void SendLaunchBrowser(this NetState ns, string uri) + writer.Write((short)0); // terminate + + ns.Send(writer.Span); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SendSequence(this NetState ns, byte sequence) => ns?.Send(stackalloc byte[] { 0x7B, sequence }); + + public static void SendSkillChange(this NetState ns, Skill skill) + { + if (ns.CannotSendPackets()) { - if (ns == null) - { - return; - } - - uri ??= ""; - - var length = 4 + uri.Length; - var writer = new SpanWriter(stackalloc byte[length]); - writer.Write((byte)0xA5); // Packet ID - writer.Write((ushort)length); - writer.WriteAsciiNull(uri); - - ns.Send(writer.Span); + return; } - public static void CreateDragEffect( - Span buffer, - Serial srcSerial, Point3D srcLocation, - Serial trgSerial, Point3D trgLocation, - int itemID, int hue, int amount - ) + var writer = new SpanWriter(stackalloc byte[13]); + writer.Write((byte)0x3A); // Packet ID + writer.Write((ushort)13); + + var v = skill.NonRacialValue; + var uv = Math.Clamp((int)(v * 10), 0, 0xFFFF); + + writer.Write((byte)0xDF); // type: delta, capped + writer.Write((ushort)skill.Info.SkillID); + writer.Write((ushort)uv); + writer.Write((ushort)skill.BaseFixedPoint); + writer.Write((byte)skill.Lock); + writer.Write((ushort)skill.CapFixedPoint); + + ns.Send(writer.Span); + } + + public static void SendLaunchBrowser(this NetState ns, string uri) + { + if (ns.CannotSendPackets()) { - if (buffer[0] != 0) - { - return; - } - - var writer = new SpanWriter(buffer); - writer.Write((byte)0x23); // Packet ID - writer.Write((short)itemID); - writer.Write((byte)0); - writer.Write((short)hue); - writer.Write((short)amount); - writer.Write(srcSerial); - writer.Write((short)srcLocation.X); - writer.Write((short)srcLocation.Y); - writer.Write((sbyte)srcLocation.Z); - writer.Write(trgSerial); - writer.Write((short)trgLocation.X); - writer.Write((short)trgLocation.Y); - writer.Write((sbyte)trgLocation.Z); + return; } - public static void SendDragEffect( - this NetState ns, - Serial srcSerial, Point3D srcLocation, - Serial trgSerial, Point3D trgLocation, - int itemID, int hue, int amount - ) + uri ??= ""; + + var length = 4 + uri.Length; + var writer = new SpanWriter(stackalloc byte[length]); + writer.Write((byte)0xA5); // Packet ID + writer.Write((ushort)length); + writer.WriteAsciiNull(uri); + + ns.Send(writer.Span); + } + + public static void CreateDragEffect( + Span buffer, + Serial srcSerial, Point3D srcLocation, + Serial trgSerial, Point3D trgLocation, + int itemID, int hue, int amount + ) + { + if (buffer[0] != 0) { - if (ns == null) - { - return; - } - - Span buffer = stackalloc byte[DragEffectPacketLength].InitializePacket(); - CreateDragEffect(buffer, srcSerial, srcLocation, trgSerial, trgLocation, itemID, hue, amount); - ns.Send(buffer); + return; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe void SendSeasonChange(this NetState ns, byte season, bool playSound) => - ns?.Send(stackalloc byte[]{ 0xBC, season, *(byte*)&playSound }); + var writer = new SpanWriter(buffer); + writer.Write((byte)0x23); // Packet ID + writer.Write((short)itemID); + writer.Write((byte)0); + writer.Write((short)hue); + writer.Write((short)amount); + writer.Write(srcSerial); + writer.Write((short)srcLocation.X); + writer.Write((short)srcLocation.Y); + writer.Write((sbyte)srcLocation.Z); + writer.Write(trgSerial); + writer.Write((short)trgLocation.X); + writer.Write((short)trgLocation.Y); + writer.Write((sbyte)trgLocation.Z); + } - public static void SendDisplayPaperdoll(this NetState ns, Serial m, string title, bool warmode, bool canLift) + public static void SendDragEffect( + this NetState ns, + Serial srcSerial, Point3D srcLocation, + Serial trgSerial, Point3D trgLocation, + int itemID, int hue, int amount + ) + { + if (ns.CannotSendPackets()) { - if (ns == null) - { - return; - } - - byte flags = 0x00; - - if (warmode) - { - flags |= 0x01; - } - - if (canLift) - { - flags |= 0x02; - } - - var writer = new SpanWriter(stackalloc byte[66]); - writer.Write((byte)0x88); // Packet ID - writer.Write(m); - writer.WriteAscii(title, 60); - writer.Write(flags); - - ns.Send(writer.Span); + return; } - public static void SendPlayMusic(this NetState ns, MusicName music) + Span buffer = stackalloc byte[DragEffectPacketLength].InitializePacket(); + CreateDragEffect(buffer, srcSerial, srcLocation, trgSerial, trgLocation, itemID, hue, amount); + ns.Send(buffer); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe void SendSeasonChange(this NetState ns, byte season, bool playSound) => + ns?.Send(stackalloc byte[]{ 0xBC, season, *(byte*)&playSound }); + + public static void SendDisplayPaperdoll(this NetState ns, Serial m, string title, bool warmode, bool canLift) + { + if (ns.CannotSendPackets()) { - if (ns == null) - { - return; - } - - var writer = new SpanWriter(stackalloc byte[3]); - writer.Write((byte)0x6D); // Packet ID - writer.Write((short)music); - - ns.Send(writer.Span); + return; } - public static void SendStopMusic(this NetState ns) => ns?.Send(stackalloc byte[] { 0x6D, 0x1F, 0xFF }); + byte flags = 0x00; - public static void SendScrollMessage(this NetState ns, int type, int tip, string text) + if (warmode) { - if (ns == null) - { - return; - } - - text ??= ""; - - var length = 10 + text.Length; - var writer = new SpanWriter(stackalloc byte[length]); - writer.Write((byte)0xA6); // Packet ID - writer.Write((ushort)length); - writer.Write((byte)type); - writer.Write(tip); - writer.Write((ushort)text.Length); - writer.WriteAscii(text); - - ns.Send(writer.Span); + flags |= 0x01; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void SendCurrentTime(this NetState ns) => ns.SendCurrentTime(Core.Now); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void SendCurrentTime(this NetState ns, DateTime date) => - ns?.Send(stackalloc byte[] { 0x5B, (byte)date.Hour, (byte)date.Minute, (byte)date.Second }); - - public static void SendPathfindMessage(this NetState ns, Point3D p) + if (canLift) { - if (ns == null) - { - return; - } - - var writer = new SpanWriter(stackalloc byte[7]); - writer.Write((byte)0x38); // Packet ID - writer.Write((short)p.X); - writer.Write((short)p.Y); - writer.Write((short)p.Z); - - ns.Send(writer.Span); + flags |= 0x02; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void SendPingAck(this NetState ns, byte ping) => ns?.Send(stackalloc byte[] { 0x73, ping }); + var writer = new SpanWriter(stackalloc byte[66]); + writer.Write((byte)0x88); // Packet ID + writer.Write(m); + writer.WriteAscii(title, 60); + writer.Write(flags); - public static void SendDisplayHuePicker(this NetState ns, Serial huePickerSerial, int huePickerItemID) + ns.Send(writer.Span); + } + + public static void SendPlayMusic(this NetState ns, MusicName music) + { + if (ns.CannotSendPackets()) { - if (ns == null) - { - return; - } - - var writer = new SpanWriter(stackalloc byte[9]); - writer.Write((byte)0x95); // Packet ID - writer.Write(huePickerSerial); - writer.Write((short)0); - writer.Write((short)huePickerItemID); - - ns.Send(writer.Span); + return; } + + var writer = new SpanWriter(stackalloc byte[3]); + writer.Write((byte)0x6D); // Packet ID + writer.Write((short)music); + + ns.Send(writer.Span); + } + + public static void SendStopMusic(this NetState ns) => ns?.Send(stackalloc byte[] { 0x6D, 0x1F, 0xFF }); + + public static void SendScrollMessage(this NetState ns, int type, int tip, string text) + { + if (ns.CannotSendPackets()) + { + return; + } + + text ??= ""; + + var length = 10 + text.Length; + var writer = new SpanWriter(stackalloc byte[length]); + writer.Write((byte)0xA6); // Packet ID + writer.Write((ushort)length); + writer.Write((byte)type); + writer.Write(tip); + writer.Write((ushort)text.Length); + writer.WriteAscii(text); + + ns.Send(writer.Span); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SendCurrentTime(this NetState ns) => ns.SendCurrentTime(Core.Now); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SendCurrentTime(this NetState ns, DateTime date) => + ns?.Send(stackalloc byte[] { 0x5B, (byte)date.Hour, (byte)date.Minute, (byte)date.Second }); + + public static void SendPathfindMessage(this NetState ns, Point3D p) + { + if (ns.CannotSendPackets()) + { + return; + } + + var writer = new SpanWriter(stackalloc byte[7]); + writer.Write((byte)0x38); // Packet ID + writer.Write((short)p.X); + writer.Write((short)p.Y); + writer.Write((short)p.Z); + + ns.Send(writer.Span); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SendPingAck(this NetState ns, byte ping) => ns?.Send(stackalloc byte[] { 0x73, ping }); + + public static void SendDisplayHuePicker(this NetState ns, Serial huePickerSerial, int huePickerItemID) + { + if (ns.CannotSendPackets()) + { + return; + } + + var writer = new SpanWriter(stackalloc byte[9]); + writer.Write((byte)0x95); // Packet ID + writer.Write(huePickerSerial); + writer.Write((short)0); + writer.Write((short)huePickerItemID); + + ns.Send(writer.Span); } } diff --git a/Projects/Server/Network/Packets/OutgoingSecureTradePackets.cs b/Projects/Server/Network/Packets/OutgoingSecureTradePackets.cs index eef3336ee..4459d3038 100644 --- a/Projects/Server/Network/Packets/OutgoingSecureTradePackets.cs +++ b/Projects/Server/Network/Packets/OutgoingSecureTradePackets.cs @@ -16,106 +16,105 @@ using System.Buffers; using Server.Items; -namespace Server.Network +namespace Server.Network; + +public enum TradeFlag : byte { - public enum TradeFlag : byte + Display, + Close, + Update, + UpdateGold, + UpdateLedger +} + +public static class OutgoingSecureTradePackets +{ + public static void SendDisplaySecureTrade( + this NetState ns, Mobile them, Container first, Container second, string name + ) { - Display, - Close, - Update, - UpdateGold, - UpdateLedger + if (ns.CannotSendPackets()) + { + return; + } + + var writer = new SpanWriter(stackalloc byte[47]); + writer.Write((byte)0x6F); // Packet ID + writer.Write((ushort)47); // Length + writer.Write((byte)TradeFlag.Display); + writer.Write(them.Serial); + writer.Write(first.Serial); + writer.Write(second.Serial); + writer.Write(true); + + writer.WriteAscii(name ?? "", 30); + + ns.Send(writer.Span); } - public static class OutgoingSecureTradePackets + public static void SendCloseSecureTrade(this NetState ns, Container cont) { - public static void SendDisplaySecureTrade( - this NetState ns, Mobile them, Container first, Container second, string name - ) + if (ns.CannotSendPackets()) { - if (ns == null) - { - return; - } - - var writer = new SpanWriter(stackalloc byte[47]); - writer.Write((byte)0x6F); // Packet ID - writer.Write((ushort)47); // Length - writer.Write((byte)TradeFlag.Display); - writer.Write(them.Serial); - writer.Write(first.Serial); - writer.Write(second.Serial); - writer.Write(true); - - writer.WriteAscii(name ?? "", 30); - - ns.Send(writer.Span); + return; } - public static void SendCloseSecureTrade(this NetState ns, Container cont) + var writer = new SpanWriter(stackalloc byte[17]); + writer.Write((byte)0x6F); // Packet ID + writer.Write((ushort)17); // Length + writer.Write((byte)TradeFlag.Close); + writer.Write(cont.Serial); + writer.Write(0); + writer.Write(0); + writer.Write(false); + + ns.Send(writer.Span); + } + + public static void SendUpdateSecureTrade(this NetState ns, Container cont, bool first, bool second) => + ns.SendUpdateSecureTrade(cont, TradeFlag.Update, first ? 1 : 0, second ? 1 : 0); + + public static void SendUpdateSecureTrade(this NetState ns, Container cont, TradeFlag flag, int first, int second) + { + if (ns.CannotSendPackets()) { - if (ns == null) - { - return; - } - - var writer = new SpanWriter(stackalloc byte[17]); - writer.Write((byte)0x6F); // Packet ID - writer.Write((ushort)17); // Length - writer.Write((byte)TradeFlag.Close); - writer.Write(cont.Serial); - writer.Write(0); - writer.Write(0); - writer.Write(false); - - ns.Send(writer.Span); + return; } - public static void SendUpdateSecureTrade(this NetState ns, Container cont, bool first, bool second) => - ns.SendUpdateSecureTrade(cont, TradeFlag.Update, first ? 1 : 0, second ? 1 : 0); + var writer = new SpanWriter(stackalloc byte[17]); + writer.Write((byte)0x6F); // Packet ID + writer.Write((ushort)17); // Length + writer.Write((byte)flag); + writer.Write(cont.Serial); + writer.Write(first); + writer.Write(second); + writer.Write(false); - public static void SendUpdateSecureTrade(this NetState ns, Container cont, TradeFlag flag, int first, int second) + ns.Send(writer.Span); + } + + public static void SendSecureTradeEquip(this NetState ns, Item item, Mobile m) + { + if (ns.CannotSendPackets()) { - if (ns == null) - { - return; - } - - var writer = new SpanWriter(stackalloc byte[17]); - writer.Write((byte)0x6F); // Packet ID - writer.Write((ushort)17); // Length - writer.Write((byte)flag); - writer.Write(cont.Serial); - writer.Write(first); - writer.Write(second); - writer.Write(false); - - ns.Send(writer.Span); + return; } - public static void SendSecureTradeEquip(this NetState ns, Item item, Mobile m) + var writer = new SpanWriter(stackalloc byte[ns.ContainerGridLines ? 21 : 20]); + writer.Write((byte)0x25); // Packet ID + writer.Write(item.Serial); + writer.Write((short)item.ItemID); + writer.Write((byte)0); + writer.Write((short)item.Amount); + writer.Write((short)item.X); + writer.Write((short)item.Y); + if (ns.ContainerGridLines) { - if (ns == null) - { - return; - } - - var writer = new SpanWriter(stackalloc byte[ns.ContainerGridLines ? 21 : 20]); - writer.Write((byte)0x25); // Packet ID - writer.Write(item.Serial); - writer.Write((short)item.ItemID); writer.Write((byte)0); - writer.Write((short)item.Amount); - writer.Write((short)item.X); - writer.Write((short)item.Y); - if (ns.ContainerGridLines) - { - writer.Write((byte)0); - } - writer.Write(m.Serial); - writer.Write((short)item.Hue); - - ns.Send(writer.Span); } + writer.Write(m.Serial); + writer.Write((short)item.Hue); + + ns.Send(writer.Span); } } diff --git a/Projects/Server/Network/Packets/OutgoingTargetPackets.cs b/Projects/Server/Network/Packets/OutgoingTargetPackets.cs index 04b3a7e08..3de19ae85 100644 --- a/Projects/Server/Network/Packets/OutgoingTargetPackets.cs +++ b/Projects/Server/Network/Packets/OutgoingTargetPackets.cs @@ -16,56 +16,55 @@ using System.Buffers; using Server.Targeting; -namespace Server.Network +namespace Server.Network; + +public static class OutgoingTargetPackets { - public static class OutgoingTargetPackets + public static void SendMultiTargetReq(this NetState ns, MultiTarget t) { - public static void SendMultiTargetReq(this NetState ns, MultiTarget t) + if (ns.CannotSendPackets()) { - if (ns == null) - { - return; - } - - var writer = new SpanWriter(stackalloc byte[ns.HighSeas ? 30 : 26]); - writer.Write((byte)0x99); // Packet ID - writer.Write(t.AllowGround); - writer.Write(t.TargetID); - writer.Write((byte)t.Flags); - writer.Clear(11); - writer.Write((short)t.MultiID); - writer.Write((short)t.Offset.X); - writer.Write((short)t.Offset.Y); - writer.Write((short)t.Offset.Z); - if (ns.HighSeas) - { - writer.Write(0); - } - - ns.Send(writer.Span); + return; } - public static void SendCancelTarget(this NetState ns) => - ns?.Send(stackalloc byte[] - { - 0x6C, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 - }); - - public static void SendTargetReq(this NetState ns, Target t) + var writer = new SpanWriter(stackalloc byte[ns.HighSeas ? 30 : 26]); + writer.Write((byte)0x99); // Packet ID + writer.Write(t.AllowGround); + writer.Write(t.TargetID); + writer.Write((byte)t.Flags); + writer.Clear(11); + writer.Write((short)t.MultiID); + writer.Write((short)t.Offset.X); + writer.Write((short)t.Offset.Y); + writer.Write((short)t.Offset.Z); + if (ns.HighSeas) { - if (ns == null) - { - return; - } - - var writer = new SpanWriter(stackalloc byte[19]); - writer.Write((byte)0x6C); // Packet ID - writer.Write(t.AllowGround); - writer.Write(t.TargetID); - writer.Write((byte)t.Flags); - writer.Clear(12); - - ns.Send(writer.Span); + writer.Write(0); } + + ns.Send(writer.Span); + } + + public static void SendCancelTarget(this NetState ns) => + ns?.Send(stackalloc byte[] + { + 0x6C, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 + }); + + public static void SendTargetReq(this NetState ns, Target t) + { + if (ns.CannotSendPackets()) + { + return; + } + + var writer = new SpanWriter(stackalloc byte[19]); + writer.Write((byte)0x6C); // Packet ID + writer.Write(t.AllowGround); + writer.Write(t.TargetID); + writer.Write((byte)t.Flags); + writer.Clear(12); + + ns.Send(writer.Span); } } diff --git a/Projects/Server/Network/Packets/OutgoingVendorBuyPackets.cs b/Projects/Server/Network/Packets/OutgoingVendorBuyPackets.cs index f70dfa49d..429792d6d 100644 --- a/Projects/Server/Network/Packets/OutgoingVendorBuyPackets.cs +++ b/Projects/Server/Network/Packets/OutgoingVendorBuyPackets.cs @@ -17,111 +17,110 @@ using System.Buffers; using System.Collections.Generic; using Server.Items; -namespace Server.Network +namespace Server.Network; + +public static class OutgoingVendorBuyPackets { - public static class OutgoingVendorBuyPackets + public static void SendVendorBuyContent(this NetState ns, List list) { - public static void SendVendorBuyContent(this NetState ns, List list) + if (ns.CannotSendPackets()) { - if (ns == null) - { - return; - } - - var length = 5 + list.Count * (ns.ContainerGridLines ? 20 : 19); - var writer = new SpanWriter(stackalloc byte[length]); - writer.Write((byte)0x3C); // Packet ID - writer.Write((ushort)length); - writer.Write((short)list.Count); - - for (var i = list.Count - 1; i >= 0; --i) - { - var bis = list[i]; - - writer.Write(bis.MySerial); - writer.Write((ushort)bis.ItemID); - writer.Write((byte)0); // itemID offset - writer.Write((ushort)bis.Amount); - writer.Write((short)(i + 1)); // x - writer.Write((short)1); // y - if (ns.ContainerGridLines) - { - writer.Write((byte)0); // Grid Location? - } - writer.Write(bis.ContainerSerial); - writer.Write((ushort)bis.Hue); - } - - ns.Send(writer.Span); + return; } - public static void SendDisplayBuyList(this NetState ns, Serial vendor) + var length = 5 + list.Count * (ns.ContainerGridLines ? 20 : 19); + var writer = new SpanWriter(stackalloc byte[length]); + writer.Write((byte)0x3C); // Packet ID + writer.Write((ushort)length); + writer.Write((short)list.Count); + + for (var i = list.Count - 1; i >= 0; --i) { - if (ns == null) - { - return; - } + var bis = list[i]; - var writer = new SpanWriter(stackalloc byte[ns.HighSeas ? 9 : 7]); - writer.Write((byte)0x24); // Packet ID - writer.Write(vendor); - writer.Write((short)0x30); // Vendor Buy Window - if (ns.HighSeas) + writer.Write(bis.MySerial); + writer.Write((ushort)bis.ItemID); + writer.Write((byte)0); // itemID offset + writer.Write((ushort)bis.Amount); + writer.Write((short)(i + 1)); // x + writer.Write((short)1); // y + if (ns.ContainerGridLines) { - writer.Write((short)0x0); + writer.Write((byte)0); // Grid Location? } - - ns.Send(writer.Span); + writer.Write(bis.ContainerSerial); + writer.Write((ushort)bis.Hue); } - public static void SendVendorBuyList(this NetState ns, Mobile vendor, List list) + ns.Send(writer.Span); + } + + public static void SendDisplayBuyList(this NetState ns, Serial vendor) + { + if (ns.CannotSendPackets()) { - if (ns == null) - { - return; - } - - var length = 8; - for (int i = 0; i < list.Count; i++) - { - length += 6 + list[i].Description?.Length ?? 0; - } - - var writer = new SpanWriter(stackalloc byte[length]); - writer.Write((byte)0x74); // Packet ID - writer.Write((ushort)length); - writer.Write((vendor.FindItemOnLayer(Layer.ShopBuy) as Container)?.Serial ?? Serial.MinusOne); - writer.Write((byte)list.Count); - - for (var i = 0; i < list.Count; ++i) - { - var bis = list[i]; - - writer.Write(bis.Price); - - var desc = bis.Description ?? ""; - - writer.Write((byte)(desc.Length + 1)); - writer.WriteAsciiNull(desc); - } - - ns.Send(writer.Span); + return; } - public static void SendEndVendorBuy(this NetState ns, Serial vendor) + var writer = new SpanWriter(stackalloc byte[ns.HighSeas ? 9 : 7]); + writer.Write((byte)0x24); // Packet ID + writer.Write(vendor); + writer.Write((short)0x30); // Vendor Buy Window + if (ns.HighSeas) { - if (ns == null) - { - return; - } - - var writer = new SpanWriter(stackalloc byte[8]); - writer.Write((byte)0x3B); // Packet ID - writer.Write((ushort)8); - writer.Write(vendor); - writer.Write((byte)0); // Buy count - - ns.Send(writer.Span); + writer.Write((short)0x0); } + + ns.Send(writer.Span); + } + + public static void SendVendorBuyList(this NetState ns, Mobile vendor, List list) + { + if (ns.CannotSendPackets()) + { + return; + } + + var length = 8; + for (int i = 0; i < list.Count; i++) + { + length += 6 + list[i].Description?.Length ?? 0; + } + + var writer = new SpanWriter(stackalloc byte[length]); + writer.Write((byte)0x74); // Packet ID + writer.Write((ushort)length); + writer.Write((vendor.FindItemOnLayer(Layer.ShopBuy) as Container)?.Serial ?? Serial.MinusOne); + writer.Write((byte)list.Count); + + for (var i = 0; i < list.Count; ++i) + { + var bis = list[i]; + + writer.Write(bis.Price); + + var desc = bis.Description ?? ""; + + writer.Write((byte)(desc.Length + 1)); + writer.WriteAsciiNull(desc); + } + + ns.Send(writer.Span); + } + + public static void SendEndVendorBuy(this NetState ns, Serial vendor) + { + if (ns.CannotSendPackets()) + { + return; + } + + var writer = new SpanWriter(stackalloc byte[8]); + writer.Write((byte)0x3B); // Packet ID + writer.Write((ushort)8); + writer.Write(vendor); + writer.Write((byte)0); // Buy count + + ns.Send(writer.Span); } } diff --git a/Projects/Server/Network/Packets/OutgoingVendorSellPackets.cs b/Projects/Server/Network/Packets/OutgoingVendorSellPackets.cs index 5393a4802..90489b668 100644 --- a/Projects/Server/Network/Packets/OutgoingVendorSellPackets.cs +++ b/Projects/Server/Network/Packets/OutgoingVendorSellPackets.cs @@ -18,66 +18,65 @@ using System.Buffers; using System.Collections.Generic; using System.IO; -namespace Server.Network +namespace Server.Network; + +public static class OutgoingVendorSellPackets { - public static class OutgoingVendorSellPackets + public static void SendVendorSellList(this NetState ns, Serial vendor, List list) { - public static void SendVendorSellList(this NetState ns, Serial vendor, List list) + if (ns.CannotSendPackets()) { - if (ns == null) - { - return; - } - - var maxLength = 9; - for (int i = 0; i < list.Count; i++) - { - var sis = list[i]; - var item = sis.Item; - maxLength += 14 + Math.Max(item.Name?.Length ?? 0, sis.Name?.Length ?? 0); - } - - var writer = new SpanWriter(stackalloc byte[maxLength]); - writer.Write((byte)0x9E); // Packet ID - writer.Seek(2, SeekOrigin.Current); - - writer.Write(vendor); - writer.Write((ushort)list.Count); - - for (var i = 0; i < list.Count; i++) - { - var sis = list[i]; - var item = sis.Item; - writer.Write(item.Serial); - writer.Write((ushort)item.ItemID); - writer.Write((ushort)item.Hue); - writer.Write((ushort)item.Amount); - writer.Write((ushort)sis.Price); - - var name = (item.Name?.Trim()).DefaultIfNullOrEmpty(sis.Name ?? ""); - - writer.Write((ushort)name.Length); - writer.WriteAscii(name); - } - - writer.WritePacketLength(); - ns.Send(writer.Span); + return; } - public static void SendEndVendorSell(this NetState ns, Serial vendor) + var maxLength = 9; + for (int i = 0; i < list.Count; i++) { - if (ns == null) - { - return; - } - - var writer = new SpanWriter(stackalloc byte[8]); - writer.Write((byte)0x3B); // Packet ID - writer.Write((ushort)8); - writer.Write(vendor); - writer.Write((byte)0); - - ns.Send(writer.Span); + var sis = list[i]; + var item = sis.Item; + maxLength += 14 + Math.Max(item.Name?.Length ?? 0, sis.Name?.Length ?? 0); } + + var writer = new SpanWriter(stackalloc byte[maxLength]); + writer.Write((byte)0x9E); // Packet ID + writer.Seek(2, SeekOrigin.Current); + + writer.Write(vendor); + writer.Write((ushort)list.Count); + + for (var i = 0; i < list.Count; i++) + { + var sis = list[i]; + var item = sis.Item; + writer.Write(item.Serial); + writer.Write((ushort)item.ItemID); + writer.Write((ushort)item.Hue); + writer.Write((ushort)item.Amount); + writer.Write((ushort)sis.Price); + + var name = (item.Name?.Trim()).DefaultIfNullOrEmpty(sis.Name ?? ""); + + writer.Write((ushort)name.Length); + writer.WriteAscii(name); + } + + writer.WritePacketLength(); + ns.Send(writer.Span); + } + + public static void SendEndVendorSell(this NetState ns, Serial vendor) + { + if (ns.CannotSendPackets()) + { + return; + } + + var writer = new SpanWriter(stackalloc byte[8]); + writer.Write((byte)0x3B); // Packet ID + writer.Write((ushort)8); + writer.Write(vendor); + writer.Write((byte)0); + + ns.Send(writer.Span); } } diff --git a/Projects/Server/Network/Packets/PacketContainerBuilder.cs b/Projects/Server/Network/Packets/PacketContainerBuilder.cs index deee3e501..55eba01c1 100644 --- a/Projects/Server/Network/Packets/PacketContainerBuilder.cs +++ b/Projects/Server/Network/Packets/PacketContainerBuilder.cs @@ -18,98 +18,97 @@ using System.Buffers; using System.Buffers.Binary; using System.Runtime.CompilerServices; -namespace Server.Network +namespace Server.Network; + +public ref struct PacketContainerBuilder { - public ref struct PacketContainerBuilder + public const int MinPacketLength = 5; + + private bool _finished; + private int _count; + + private byte[] _arrayToReturnToPool; + private Span _bytes; + + public PacketContainerBuilder(Span initialBuffer) { - public const int MinPacketLength = 5; + _arrayToReturnToPool = null; + _finished = false; + _count = 0; - private bool _finished; - private int _count; + _bytes = initialBuffer; + _bytes[0] = 0xF7; // Packet ID + Length = MinPacketLength; // Length + Count + } - private byte[] _arrayToReturnToPool; - private Span _bytes; + public int Length { get; set; } - public PacketContainerBuilder(Span initialBuffer) + public int Capacity => _bytes.Length; + + [MethodImpl(MethodImplOptions.NoInlining)] + public ReadOnlySpan Finalize() + { + if (!_finished) { - _arrayToReturnToPool = null; - _finished = false; - _count = 0; - - _bytes = initialBuffer; - _bytes[0] = 0xF7; // Packet ID - Length = MinPacketLength; // Length + Count + BinaryPrimitives.WriteUInt16BigEndian(_bytes[1..3], (ushort)Length); + BinaryPrimitives.WriteUInt16BigEndian(_bytes[3..5], (ushort)_count); } - public int Length { get; set; } + return _bytes[..Length]; + } - public int Capacity => _bytes.Length; - - [MethodImpl(MethodImplOptions.NoInlining)] - public ReadOnlySpan Finalize() + [MethodImpl(MethodImplOptions.NoInlining)] + public Span GetSpan(int bytesNeeded) + { + if (_finished) { - if (!_finished) - { - BinaryPrimitives.WriteUInt16BigEndian(_bytes[1..3], (ushort)Length); - BinaryPrimitives.WriteUInt16BigEndian(_bytes[3..5], (ushort)_count); - } - - return _bytes[..Length]; + throw new InvalidOperationException("Attempted to use PacketContainerBuilder after finalize"); } - [MethodImpl(MethodImplOptions.NoInlining)] - public Span GetSpan(int bytesNeeded) + if (Length > _bytes.Length - bytesNeeded) { - if (_finished) - { - throw new InvalidOperationException("Attempted to use PacketContainerBuilder after finalize"); - } - - if (Length > _bytes.Length - bytesNeeded) - { - Grow(bytesNeeded); - } - - return _bytes[Length..]; + Grow(bytesNeeded); } - [MethodImpl(MethodImplOptions.NoInlining)] - public void Advance(int bytesWritten) - { - if (_finished) - { - throw new InvalidOperationException("Attempted to use PacketContainerBuilder after finalize"); - } + return _bytes[Length..]; + } - _count++; - Length += bytesWritten; + [MethodImpl(MethodImplOptions.NoInlining)] + public void Advance(int bytesWritten) + { + if (_finished) + { + throw new InvalidOperationException("Attempted to use PacketContainerBuilder after finalize"); } - [MethodImpl(MethodImplOptions.NoInlining)] - private void Grow(int additionalCapacityBeyondPos) + _count++; + Length += bytesWritten; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private void Grow(int additionalCapacityBeyondPos) + { + var newLength = Math.Max(Length + additionalCapacityBeyondPos, _bytes.Length * 2); + byte[] poolArray = ArrayPool.Shared.Rent(newLength); + + _bytes[..Length].CopyTo(poolArray); + + byte[] toReturn = _arrayToReturnToPool; + _bytes = _arrayToReturnToPool = poolArray; + if (toReturn != null) { - var newLength = Math.Max(Length + additionalCapacityBeyondPos, _bytes.Length * 2); - byte[] poolArray = ArrayPool.Shared.Rent(newLength); - - _bytes[..Length].CopyTo(poolArray); - - byte[] toReturn = _arrayToReturnToPool; - _bytes = _arrayToReturnToPool = poolArray; - if (toReturn != null) - { - ArrayPool.Shared.Return(toReturn); - } + ArrayPool.Shared.Return(toReturn); } + } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Dispose() + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Dispose() + { + byte[] toReturn = _arrayToReturnToPool; + this = default; // for safety, to avoid using pooled array if this instance is erroneously appended to again + if (toReturn != null) { - byte[] toReturn = _arrayToReturnToPool; - this = default; // for safety, to avoid using pooled array if this instance is erroneously appended to again - if (toReturn != null) - { - ArrayPool.Shared.Return(toReturn); - } + ArrayPool.Shared.Return(toReturn); } } } diff --git a/Projects/UOContent/Engines/Chat/ChatPackets.cs b/Projects/UOContent/Engines/Chat/ChatPackets.cs index 30ad48adc..01b47b471 100644 --- a/Projects/UOContent/Engines/Chat/ChatPackets.cs +++ b/Projects/UOContent/Engines/Chat/ChatPackets.cs @@ -103,7 +103,7 @@ namespace Server.Engines.Chat public static void SendChatMessage(this NetState ns, string lang, int number, string param1, string param2) { - if (ns == null) + if (ns.CannotSendPackets()) { return; } diff --git a/Projects/UOContent/Engines/Harvest/Fishing.cs b/Projects/UOContent/Engines/Harvest/Fishing.cs index 035f21e4d..7e8cb9009 100644 --- a/Projects/UOContent/Engines/Harvest/Fishing.cs +++ b/Projects/UOContent/Engines/Harvest/Fishing.cs @@ -464,12 +464,7 @@ namespace Server.Engines.Harvest var ns = from.NetState; - if (ns == null) - { - return; - } - - if (number == 1043297 || ns.HighSeas) + if (number == 1043297 || ns?.HighSeas == true) { from.SendLocalizedMessage(number, name); } diff --git a/Projects/UOContent/Engines/Help/HelpTopic.cs b/Projects/UOContent/Engines/Help/HelpTopic.cs index 0fc242891..1b9179169 100644 --- a/Projects/UOContent/Engines/Help/HelpTopic.cs +++ b/Projects/UOContent/Engines/Help/HelpTopic.cs @@ -35,7 +35,7 @@ namespace Server.Engines.Help public static void SendDisplayHelpTopic(this NetState ns, int topicID, bool display = true) { - if (ns == null) + if (ns.CannotSendPackets()) { return; } diff --git a/Projects/UOContent/Engines/Party/PartyPackets.cs b/Projects/UOContent/Engines/Party/PartyPackets.cs index 627f1811f..97c2bb952 100644 --- a/Projects/UOContent/Engines/Party/PartyPackets.cs +++ b/Projects/UOContent/Engines/Party/PartyPackets.cs @@ -48,7 +48,7 @@ namespace Server.Engines.PartySystem public static void SendPartyMemberList(this NetState ns, Party p) { - if (ns == null) + if (ns.CannotSendPackets()) { return; } @@ -64,7 +64,7 @@ namespace Server.Engines.PartySystem public static void SendPartyRemoveMember(this NetState ns, Serial m, Party p = null) { - if (ns == null) + if (ns.CannotSendPackets()) { return; } @@ -104,7 +104,7 @@ namespace Server.Engines.PartySystem public static void SendPartyTextMessage(this NetState ns, Serial m, string text, bool toAll) { - if (ns == null) + if (ns.CannotSendPackets()) { return; } @@ -134,7 +134,7 @@ namespace Server.Engines.PartySystem public static void SendPartyInvitation(this NetState ns, Serial leader) { - if (ns == null) + if (ns.CannotSendPackets()) { return; } diff --git a/Projects/UOContent/Engines/Veteran Rewards/Character Statue Maker/CharacterStatuePackets.cs b/Projects/UOContent/Engines/Veteran Rewards/Character Statue Maker/CharacterStatuePackets.cs index b7a6a59e3..a66d08291 100644 --- a/Projects/UOContent/Engines/Veteran Rewards/Character Statue Maker/CharacterStatuePackets.cs +++ b/Projects/UOContent/Engines/Veteran Rewards/Character Statue Maker/CharacterStatuePackets.cs @@ -47,7 +47,7 @@ namespace Server.Engines.VeteranRewards public static void SendStatueAnimation(this NetState ns, Serial serial, int status, int anim, int frame) { - if (ns == null) + if (ns.CannotSendPackets()) { return; } diff --git a/Projects/UOContent/Items/Books/BookPackets.cs b/Projects/UOContent/Items/Books/BookPackets.cs index 6eee9c451..af59afa86 100644 --- a/Projects/UOContent/Items/Books/BookPackets.cs +++ b/Projects/UOContent/Items/Books/BookPackets.cs @@ -135,7 +135,7 @@ namespace Server.Items public static void SendBookContent(this NetState ns, BaseBook book) { - if (ns == null) + if (ns.CannotSendPackets()) { return; } @@ -183,7 +183,7 @@ namespace Server.Items public static void SendBookCover(this NetState ns, Mobile from, BaseBook book) { - if (ns == null) + if (ns.CannotSendPackets()) { return; } diff --git a/Projects/UOContent/Items/Bulletin Boards/BulletinBoardPackets.cs b/Projects/UOContent/Items/Bulletin Boards/BulletinBoardPackets.cs index 5a5ada1c9..0eac35aab 100644 --- a/Projects/UOContent/Items/Bulletin Boards/BulletinBoardPackets.cs +++ b/Projects/UOContent/Items/Bulletin Boards/BulletinBoardPackets.cs @@ -168,7 +168,7 @@ namespace Server.Network public static void SendBBDisplayBoard(this NetState ns, BaseBulletinBoard board) { - if (ns == null) + if (ns.CannotSendPackets()) { return; } @@ -203,7 +203,7 @@ namespace Server.Network public static void SendBBMessage(this NetState ns, BaseBulletinBoard board, BulletinMessage msg, bool content = false) { - if (ns == null) + if (ns.CannotSendPackets()) { return; } diff --git a/Projects/UOContent/Items/Games/Mahjong/MahjongPackets.cs b/Projects/UOContent/Items/Games/Mahjong/MahjongPackets.cs index 73da28c08..601f676d4 100644 --- a/Projects/UOContent/Items/Games/Mahjong/MahjongPackets.cs +++ b/Projects/UOContent/Items/Games/Mahjong/MahjongPackets.cs @@ -287,7 +287,7 @@ namespace Server.Engines.Mahjong public static void SendMahjongJoinGame(this NetState ns, Serial game) { - if (ns == null) + if (ns.CannotSendPackets()) { return; } @@ -303,7 +303,7 @@ namespace Server.Engines.Mahjong public static void SendMahjongPlayersInfo(this NetState ns, MahjongGame game, Mobile to) { - if (ns == null) + if (ns.CannotSendPackets()) { return; } @@ -361,7 +361,7 @@ namespace Server.Engines.Mahjong public static void SendMahjongTileInfo(this NetState ns, MahjongTile tile, Mobile to) { - if (ns == null) + if (ns.CannotSendPackets()) { return; } @@ -407,7 +407,7 @@ namespace Server.Engines.Mahjong public static void SendMahjongTilesInfo(this NetState ns, MahjongGame game, Mobile to) { - if (ns == null) + if (ns.CannotSendPackets()) { return; } @@ -460,7 +460,7 @@ namespace Server.Engines.Mahjong public static void SendMahjongGeneralInfo(this NetState ns, MahjongGame game) { - if (ns == null) + if (ns.CannotSendPackets()) { return; } @@ -503,7 +503,7 @@ namespace Server.Engines.Mahjong public static void SendMahjongRelieve(this NetState ns, Serial game) { - if (ns == null) + if (ns.CannotSendPackets()) { return; } diff --git a/Projects/UOContent/Items/Maps/MapItemPackets.cs b/Projects/UOContent/Items/Maps/MapItemPackets.cs index 08229830c..2de7dd443 100644 --- a/Projects/UOContent/Items/Maps/MapItemPackets.cs +++ b/Projects/UOContent/Items/Maps/MapItemPackets.cs @@ -65,7 +65,7 @@ namespace Server.Network public static void SendMapDetails(this NetState ns, MapItem map) { - if (ns == null) + if (ns.CannotSendPackets()) { return; } @@ -93,7 +93,7 @@ namespace Server.Network public static void SendMapCommand(this NetState ns, MapItem map, int command, int x = 0, int y = 0, bool editable = false) { - if (ns == null) + if (ns.CannotSendPackets()) { return; } diff --git a/Projects/UOContent/Items/Misc/Corpses/CorpsePackets.cs b/Projects/UOContent/Items/Misc/Corpses/CorpsePackets.cs index 7de62807b..b78300f70 100644 --- a/Projects/UOContent/Items/Misc/Corpses/CorpsePackets.cs +++ b/Projects/UOContent/Items/Misc/Corpses/CorpsePackets.cs @@ -23,7 +23,7 @@ namespace Server.Network { public static void SendCorpseEquip(this NetState ns, Mobile beholder, Corpse beheld) { - if (ns == null) + if (ns.CannotSendPackets()) { return; } @@ -67,7 +67,7 @@ namespace Server.Network public static void SendCorpseContent(this NetState ns, Mobile beholder, Corpse beheld) { - if (ns == null) + if (ns.CannotSendPackets()) { return; } diff --git a/Projects/UOContent/Items/Skill Items/Magical/Spellbook.cs b/Projects/UOContent/Items/Skill Items/Magical/Spellbook.cs index 18d0dc042..500fc7b5c 100644 --- a/Projects/UOContent/Items/Skill Items/Magical/Spellbook.cs +++ b/Projects/UOContent/Items/Skill Items/Magical/Spellbook.cs @@ -671,7 +671,7 @@ namespace Server.Items // The client must know about the spellbook or it will crash! var ns = to.NetState; - if (ns == null) + if (ns.CannotSendPackets()) { return; } diff --git a/Projects/UOContent/Items/Weapons/Abilities/WeaponAbilityPackets.cs b/Projects/UOContent/Items/Weapons/Abilities/WeaponAbilityPackets.cs index 8165628bf..744995544 100644 --- a/Projects/UOContent/Items/Weapons/Abilities/WeaponAbilityPackets.cs +++ b/Projects/UOContent/Items/Weapons/Abilities/WeaponAbilityPackets.cs @@ -32,7 +32,7 @@ namespace Server.Items public static void SendToggleSpecialAbility(this NetState ns, int abilityId, bool active) { - if (ns == null) + if (ns.CannotSendPackets()) { return; } diff --git a/Projects/UOContent/Misc/BuffIcons.cs b/Projects/UOContent/Misc/BuffIcons.cs index 0c9e48340..7e7621568 100644 --- a/Projects/UOContent/Misc/BuffIcons.cs +++ b/Projects/UOContent/Misc/BuffIcons.cs @@ -162,7 +162,7 @@ namespace Server long ticks ) { - if (ns == null) + if (ns.CannotSendPackets()) { return; } @@ -207,7 +207,7 @@ namespace Server public static void SendRemoveBuffPacket(NetState ns, Serial mob, BuffIcon iconID) { - if (ns == null) + if (ns.CannotSendPackets()) { return; } diff --git a/Projects/UOContent/Misc/ProfessionInfo.cs b/Projects/UOContent/Misc/ProfessionInfo.cs index 6a2902d20..0c945556b 100644 --- a/Projects/UOContent/Misc/ProfessionInfo.cs +++ b/Projects/UOContent/Misc/ProfessionInfo.cs @@ -15,19 +15,21 @@ namespace Server return true; } - var lowerName = name.ToLowerInvariant().Replace(" ", ""); + var lowerName = name?.ToLowerInvariant().Replace(" ", ""); - foreach (var so in SkillInfo.Table) + if (!string.IsNullOrEmpty(lowerName)) { - if (lowerName == so.ProfessionSkillName.ToLowerInvariant()) + foreach (var so in SkillInfo.Table) { - skillName = (SkillName)so.SkillID; - return true; + if (lowerName == so.ProfessionSkillName.ToLowerInvariant()) + { + skillName = (SkillName)so.SkillID; + return true; + } } } return false; - } static ProfessionInfo() diff --git a/Projects/UOContent/Mobiles/Vendors/BaseVendor.cs b/Projects/UOContent/Mobiles/Vendors/BaseVendor.cs index 8cb8eb5c2..712ba2698 100644 --- a/Projects/UOContent/Mobiles/Vendors/BaseVendor.cs +++ b/Projects/UOContent/Mobiles/Vendors/BaseVendor.cs @@ -969,7 +969,7 @@ namespace Server.Mobiles var ns = from.NetState; - if (ns == null) + if (ns.CannotSendPackets()) { return; } diff --git a/Projects/UOContent/Multis/Houses/HousePackets.cs b/Projects/UOContent/Multis/Houses/HousePackets.cs index 98e8a675e..a84c9bc45 100644 --- a/Projects/UOContent/Multis/Houses/HousePackets.cs +++ b/Projects/UOContent/Multis/Houses/HousePackets.cs @@ -29,7 +29,7 @@ namespace Server.Multis public static void SendBeginHouseCustomization(this NetState ns, Serial house) { - if (ns == null) + if (ns.CannotSendPackets()) { return; } @@ -50,7 +50,7 @@ namespace Server.Multis public static void SendEndHouseCustomization(this NetState ns, Serial house) { - if (ns == null) + if (ns.CannotSendPackets()) { return; } @@ -71,7 +71,7 @@ namespace Server.Multis public static void SendDesignStateGeneral(this NetState ns, Serial house, int revision) { - if (ns == null) + if (ns.CannotSendPackets()) { return; } diff --git a/Projects/UOContent/Network/ConnectUO.cs b/Projects/UOContent/Network/ConnectUO.cs index 44749b378..fb4a51e29 100644 --- a/Projects/UOContent/Network/ConnectUO.cs +++ b/Projects/UOContent/Network/ConnectUO.cs @@ -102,7 +102,7 @@ namespace Server.Network public static void SendServerPollInfo(this NetState ns) { - if (ns == null) + if (ns.CannotSendPackets()) { return; } diff --git a/Projects/UOContent/Network/MapUO.cs b/Projects/UOContent/Network/MapUO.cs index c5d4649a2..b0ddf0d75 100644 --- a/Projects/UOContent/Network/MapUO.cs +++ b/Projects/UOContent/Network/MapUO.cs @@ -56,7 +56,7 @@ namespace Server.Network public static void SendGuildMemberLocations(this NetState ns, Mobile from, Guild guild, bool sendLocations) { - if (ns == null) + if (ns.CannotSendPackets()) { return; } @@ -116,7 +116,7 @@ namespace Server.Network public static void SendPartyMemberLocations(this NetState ns, Mobile from, Party party) { - if (ns == null) + if (ns.CannotSendPackets()) { return; } diff --git a/Projects/UOContent/Network/UOGateway.cs b/Projects/UOContent/Network/UOGateway.cs index 97ecf3a22..2980760e4 100644 --- a/Projects/UOContent/Network/UOGateway.cs +++ b/Projects/UOContent/Network/UOGateway.cs @@ -61,7 +61,7 @@ namespace Server.Network this NetState ns, uint age, int clients, int items, int mobiles, long mem ) { - if (ns == null) + if (ns.CannotSendPackets()) { return; } @@ -82,7 +82,7 @@ namespace Server.Network this NetState ns, string name, int age, int clients, int items, int mobiles, int mem ) { - if (ns == null) + if (ns.CannotSendPackets()) { return; } diff --git a/Projects/UOContent/Skills/Tracking/OutgoingArrowPackets.cs b/Projects/UOContent/Skills/Tracking/OutgoingArrowPackets.cs index 0006e8413..6bf666de4 100644 --- a/Projects/UOContent/Skills/Tracking/OutgoingArrowPackets.cs +++ b/Projects/UOContent/Skills/Tracking/OutgoingArrowPackets.cs @@ -28,7 +28,7 @@ namespace Server.Network public static void SendArrow(this NetState ns, byte command, int x, int y, Serial s) { - if (ns == null) + if (ns.CannotSendPackets()) { return; } From 5b7b99e0dec81fb2c609d06c92a07e87f4ff911a Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 27 Feb 2022 02:15:06 -0800 Subject: [PATCH 084/213] fix: Adds CUO settings support and adds more robust 7.0.9 support (#945) --- Projects/Server/Client/ClientVersion.cs | 268 +++++++++ Projects/Server/Client/UOClient.cs | 133 ++++ Projects/Server/ClientVersion.cs | 237 -------- .../Configuration/ServerConfiguration.cs | 569 +++++++----------- .../ServerConfigurationPrompts.cs | 220 +++++++ .../Server/Configuration/ServerSettings.cs | 2 +- Projects/Server/MultiData.cs | 23 +- .../NetState/NetState.ClientVersion.cs | 51 +- Projects/Server/Utilities/PathUtility.cs | 121 ++-- Projects/UOContent/Misc/AccountPrompt.cs | 57 +- Projects/UOContent/Misc/ClientVerification.cs | 43 +- Projects/UOContent/Misc/ServerAccess.cs | 7 +- 12 files changed, 958 insertions(+), 773 deletions(-) create mode 100644 Projects/Server/Client/ClientVersion.cs create mode 100644 Projects/Server/Client/UOClient.cs delete mode 100644 Projects/Server/ClientVersion.cs create mode 100644 Projects/Server/Configuration/ServerConfigurationPrompts.cs diff --git a/Projects/Server/Client/ClientVersion.cs b/Projects/Server/Client/ClientVersion.cs new file mode 100644 index 000000000..09e68d582 --- /dev/null +++ b/Projects/Server/Client/ClientVersion.cs @@ -0,0 +1,268 @@ +/************************************************************************* + * ModernUO * + * Copyright 2019-2022 - ModernUO Development Team * + * Email: hi@modernuo.com * + * File: ClientVersion.cs * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using Server.Buffers; + +namespace Server; + +public enum ClientType +{ + Regular, + UOTD, + God, + SA +} + +public class ClientVersion : IComparable, IComparer +{ + public static readonly ClientVersion Version400a = new("4.0.0a"); + public static readonly ClientVersion Version407a = new("4.0.7a"); + public static readonly ClientVersion Version500a = new("5.0.0a"); + public static readonly ClientVersion Version502b = new("5.0.2b"); + public static readonly ClientVersion Version6000 = new("6.0.0.0"); + public static readonly ClientVersion Version6017 = new("6.0.1.7"); + public static readonly ClientVersion Version60142 = new("6.0.14.2"); + public static readonly ClientVersion Version7000 = new("7.0.0.0"); + public static readonly ClientVersion Version7090 = new("7.0.9.0"); + public static readonly ClientVersion Version70130 = new("7.0.13.0"); + public static readonly ClientVersion Version70160 = new("7.0.16.0"); + public static readonly ClientVersion Version70300 = new("7.0.30.0"); + public static readonly ClientVersion Version70331 = new("7.0.33.1"); + public static readonly ClientVersion Version704565 = new("7.0.45.65"); + public static readonly ClientVersion Version70500 = new("7.0.50.0"); + public static readonly ClientVersion Version70610 = new("7.0.61.0"); + + public ClientVersion(int maj, int min, int rev, int pat, ClientType type = ClientType.Regular) + { + Major = maj; + Minor = min; + Revision = rev; + Patch = pat; + Type = type; + + SourceString = Utility.Intern(ToStringImpl()); + } + + public ClientVersion(string fmt) + { + fmt = fmt.ToLower(); + SourceString = Utility.Intern(fmt); + + try + { + var br1 = fmt.IndexOfOrdinal('.'); + var br2 = fmt.IndexOf('.', br1 + 1); + + var br3 = br2 + 1; + while (br3 < fmt.Length && char.IsDigit(fmt, br3)) + { + br3++; + } + + Major = Utility.ToInt32(fmt.AsSpan()[..br1]); + Minor = Utility.ToInt32(fmt.Substring(br1 + 1, br2 - br1 - 1)); + Revision = Utility.ToInt32(fmt.Substring(br2 + 1, br3 - br2 - 1)); + + if (br3 < fmt.Length) + { + if (Major <= 5 && Minor <= 0 && Revision <= 6) // Anything before 5.0.7 + { + if (!char.IsWhiteSpace(fmt, br3)) + { + Patch = fmt[br3] - 'a' + 1; + } + } + else + { + Patch = Utility.ToInt32(fmt.Substring(br3 + 1, fmt.Length - br3 - 1)); + } + } + + if (fmt.InsensitiveContains("god") || fmt.InsensitiveContains("gq")) + { + Type = ClientType.God; + } + else if (fmt.InsensitiveContains("third dawn") || + fmt.InsensitiveContains("uo:td") || + fmt.InsensitiveContains("uotd") || + fmt.InsensitiveContains("uo3d") || + fmt.InsensitiveContains("uo:3d")) + { + Type = ClientType.UOTD; + } + else + { + Type = ClientType.Regular; + } + } + catch + { + Major = 0; + Minor = 0; + Revision = 0; + Patch = 0; + Type = ClientType.Regular; + } + } + + public int Major { get; } + + public int Minor { get; } + + public int Revision { get; } + + public int Patch { get; } + + public ClientType Type { get; } + + public string SourceString { get; } + + public int CompareTo(ClientVersion o) + { + if (o == null) + { + return 1; + } + + if (Major > o.Major) + { + return 1; + } + + if (Major < o.Major) + { + return -1; + } + + if (Minor > o.Minor) + { + return 1; + } + + if (Minor < o.Minor) + { + return -1; + } + + if (Revision > o.Revision) + { + return 1; + } + + if (Revision < o.Revision) + { + return -1; + } + + if (Patch > o.Patch) + { + return 1; + } + + if (Patch < o.Patch) + { + return -1; + } + + return 0; + } + + int IComparer.Compare(ClientVersion x, ClientVersion y) => Compare(x, y); + + public static bool operator ==(ClientVersion l, ClientVersion r) => Compare(l, r) == 0; + + public static bool operator !=(ClientVersion l, ClientVersion r) => Compare(l, r) != 0; + + public static bool operator >=(ClientVersion l, ClientVersion r) => Compare(l, r) >= 0; + + public static bool operator >(ClientVersion l, ClientVersion r) => Compare(l, r) > 0; + + public static bool operator <=(ClientVersion l, ClientVersion r) => Compare(l, r) <= 0; + + public static bool operator <(ClientVersion l, ClientVersion r) => Compare(l, r) < 0; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override int GetHashCode() => HashCode.Combine(Major, Minor, Revision, Patch, Type); + + public override bool Equals(object obj) + { + var v = obj as ClientVersion; + + return Major == v?.Major + && Minor == v.Minor + && Revision == v.Revision + && Patch == v.Patch + && Type == v.Type; + } + + private string ToStringImpl() + { + using var builder = new ValueStringBuilder(stackalloc char[32]); + + builder.Append(Major.ToString()); + builder.Append('.'); + builder.Append(Minor.ToString()); + builder.Append('.'); + builder.Append(Revision.ToString()); + + if (Major <= 5 && Minor <= 0 && Revision <= 6) // Anything before 5.0.7 + { + if (Patch > 0) + { + builder.Append((char)('a' + (Patch - 1))); + } + } + else + { + builder.Append('.'); + builder.Append(Patch.ToString()); + } + + if (Type != ClientType.Regular) + { + builder.Append(' '); + builder.Append(Type.ToString().ToLower()); + } + + return builder.ToString(); + } + + public override string ToString() => SourceString; + + public static bool IsNull(object x) => ReferenceEquals(x, null); + + public static int Compare(ClientVersion a, ClientVersion b) + { + if (IsNull(a) && IsNull(b)) + { + return 0; + } + + if (IsNull(a)) + { + return -1; + } + + if (IsNull(b)) + { + return 1; + } + + return a.CompareTo(b); + } +} diff --git a/Projects/Server/Client/UOClient.cs b/Projects/Server/Client/UOClient.cs new file mode 100644 index 000000000..e19b801f3 --- /dev/null +++ b/Projects/Server/Client/UOClient.cs @@ -0,0 +1,133 @@ +/************************************************************************* + * ModernUO * + * Copyright 2019-2022 - ModernUO Development Team * + * Email: hi@modernuo.com * + * File: UOClient.cs * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + +using System; +using System.Buffers.Binary; +using System.IO; +using System.Text.Json.Serialization; +using Server.Json; +using Server.Logging; + +namespace Server; + +public static class UOClient +{ + private static readonly ILogger logger = LogFactory.GetLogger(typeof(UOClient)); + + private static bool _automaticallyDetected; + + public static CUOSettings CuoSettings { get; private set; } + public static ClientVersion ServerClientVersion { get; private set; } + + public static void Load() + { + ServerClientVersion = ServerConfiguration.GetSetting("clientData.clientVersion", (ClientVersion)null); + + if (ServerClientVersion == null) + { + ServerClientVersion = DetectCUOClient() ?? DetectClassicClient(); + _automaticallyDetected = true; + } + } + + public static void Configure() + { + if (ServerClientVersion == null) + { + logger.Warning("Could not detect client version."); + } + else if (CuoSettings.ClientVersion == ServerClientVersion) + { + logger.Information($"Automatically detected client version {ServerClientVersion} from CUO settings."); + } + else if (_automaticallyDetected) + { + logger.Information($"Automatically detected client version {ServerClientVersion}"); + } + else + { + logger.Information($"Manually configured to use client version {ServerClientVersion}"); + } + } + + private static ClientVersion DetectCUOClient() + { + var path = Core.FindDataFile("settings.json", false); + if (File.Exists(path)) + { + var settings = JsonConfig.Deserialize(path); + var file = new FileInfo(path); + + if (settings.UltimaOnlineDirectory != null) + { + settings.UltimaOnlineDirectory = PathUtility.GetFullPath(settings.UltimaOnlineDirectory, file.DirectoryName); + if (Directory.Exists(settings.UltimaOnlineDirectory)) + { + CuoSettings = settings; + } + } + + return settings.ClientVersion; + } + + return null; + } + + private static ClientVersion DetectClassicClient() + { + var path = Core.FindDataFile("client.exe", false); + + if (File.Exists(path)) + { + using FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read); + var buffer = GC.AllocateUninitializedArray((int)fs.Length, true); + fs.Read(buffer); + // VS_VERSION_INFO (unicode) + Span vsVersionInfo = stackalloc byte[] + { + 0x56, 0x00, 0x53, 0x00, 0x5F, 0x00, 0x56, 0x00, + 0x45, 0x00, 0x52, 0x00, 0x53, 0x00, 0x49, 0x00, + 0x4F, 0x00, 0x4E, 0x00, 0x5F, 0x00, 0x49, 0x00, + 0x4E, 0x00, 0x46, 0x00, 0x4F, 0x00 + }; + + for (var i = 0; i < buffer.Length; i++) + { + if (vsVersionInfo.SequenceEqual(buffer.AsSpan(i, 30))) + { + var offset = i + 42; // 30 + 12 + + var minorPart = BinaryPrimitives.ReadUInt16LittleEndian(buffer.AsSpan(offset)); + var majorPart = BinaryPrimitives.ReadUInt16LittleEndian(buffer.AsSpan(offset + 2)); + var privatePart = BinaryPrimitives.ReadUInt16LittleEndian(buffer.AsSpan(offset + 4)); + var buildPart = BinaryPrimitives.ReadUInt16LittleEndian(buffer.AsSpan(offset + 6)); + + return new ClientVersion(majorPart, minorPart, buildPart, privatePart); + } + } + } + + return null; + } + + public record CUOSettings + { + [JsonPropertyName("clientversion")] + public ClientVersion ClientVersion { get; set; } + + [JsonPropertyName("ultimaonlinedirectory")] + public string UltimaOnlineDirectory { get; set; } + } +} diff --git a/Projects/Server/ClientVersion.cs b/Projects/Server/ClientVersion.cs deleted file mode 100644 index 8325eb06a..000000000 --- a/Projects/Server/ClientVersion.cs +++ /dev/null @@ -1,237 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Runtime.CompilerServices; -using Server.Buffers; - -namespace Server -{ - public enum ClientType - { - Regular, - UOTD, - God, - SA - } - - public class ClientVersion : IComparable, IComparer - { - public ClientVersion(int maj, int min, int rev, int pat, ClientType type = ClientType.Regular) - { - Major = maj; - Minor = min; - Revision = rev; - Patch = pat; - Type = type; - - SourceString = Utility.Intern(ToStringImpl()); - } - - public ClientVersion(string fmt) - { - fmt = fmt.ToLower(); - SourceString = Utility.Intern(fmt); - - try - { - var br1 = fmt.IndexOfOrdinal('.'); - var br2 = fmt.IndexOf('.', br1 + 1); - - var br3 = br2 + 1; - while (br3 < fmt.Length && char.IsDigit(fmt, br3)) - { - br3++; - } - - Major = Utility.ToInt32(fmt.AsSpan()[..br1]); - Minor = Utility.ToInt32(fmt.Substring(br1 + 1, br2 - br1 - 1)); - Revision = Utility.ToInt32(fmt.Substring(br2 + 1, br3 - br2 - 1)); - - if (br3 < fmt.Length) - { - if (Major <= 5 && Minor <= 0 && Revision <= 6) // Anything before 5.0.7 - { - if (!char.IsWhiteSpace(fmt, br3)) - { - Patch = fmt[br3] - 'a' + 1; - } - } - else - { - Patch = Utility.ToInt32(fmt.Substring(br3 + 1, fmt.Length - br3 - 1)); - } - } - - if (fmt.InsensitiveContains("god") || fmt.InsensitiveContains("gq")) - { - Type = ClientType.God; - } - else if (fmt.InsensitiveContains("third dawn") || - fmt.InsensitiveContains("uo:td") || - fmt.InsensitiveContains("uotd") || - fmt.InsensitiveContains("uo3d") || - fmt.InsensitiveContains("uo:3d")) - { - Type = ClientType.UOTD; - } - else - { - Type = ClientType.Regular; - } - } - catch - { - Major = 0; - Minor = 0; - Revision = 0; - Patch = 0; - Type = ClientType.Regular; - } - } - - public int Major { get; } - - public int Minor { get; } - - public int Revision { get; } - - public int Patch { get; } - - public ClientType Type { get; } - - public string SourceString { get; } - - public int CompareTo(ClientVersion o) - { - if (o == null) - { - return 1; - } - - if (Major > o.Major) - { - return 1; - } - - if (Major < o.Major) - { - return -1; - } - - if (Minor > o.Minor) - { - return 1; - } - - if (Minor < o.Minor) - { - return -1; - } - - if (Revision > o.Revision) - { - return 1; - } - - if (Revision < o.Revision) - { - return -1; - } - - if (Patch > o.Patch) - { - return 1; - } - - if (Patch < o.Patch) - { - return -1; - } - - return 0; - } - - int IComparer.Compare(ClientVersion x, ClientVersion y) => Compare(x, y); - - public static bool operator ==(ClientVersion l, ClientVersion r) => Compare(l, r) == 0; - - public static bool operator !=(ClientVersion l, ClientVersion r) => Compare(l, r) != 0; - - public static bool operator >=(ClientVersion l, ClientVersion r) => Compare(l, r) >= 0; - - public static bool operator >(ClientVersion l, ClientVersion r) => Compare(l, r) > 0; - - public static bool operator <=(ClientVersion l, ClientVersion r) => Compare(l, r) <= 0; - - public static bool operator <(ClientVersion l, ClientVersion r) => Compare(l, r) < 0; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override int GetHashCode() => HashCode.Combine(Major, Minor, Revision, Patch, Type); - - public override bool Equals(object obj) - { - var v = obj as ClientVersion; - - return Major == v?.Major - && Minor == v.Minor - && Revision == v.Revision - && Patch == v.Patch - && Type == v.Type; - } - - private string ToStringImpl() - { - using var builder = new ValueStringBuilder(stackalloc char[32]); - - builder.Append(Major.ToString()); - builder.Append('.'); - builder.Append(Minor.ToString()); - builder.Append('.'); - builder.Append(Revision.ToString()); - - if (Major <= 5 && Minor <= 0 && Revision <= 6) // Anything before 5.0.7 - { - if (Patch > 0) - { - builder.Append((char)('a' + (Patch - 1))); - } - } - else - { - builder.Append('.'); - builder.Append(Patch.ToString()); - } - - if (Type != ClientType.Regular) - { - builder.Append(' '); - builder.Append(Type.ToString().ToLower()); - } - - return builder.ToString(); - } - - public override string ToString() => SourceString; - - public static bool IsNull(object x) => ReferenceEquals(x, null); - - public static int Compare(ClientVersion a, ClientVersion b) - { - if (IsNull(a) && IsNull(b)) - { - return 0; - } - - if (IsNull(a)) - { - return -1; - } - - if (IsNull(b)) - { - return 1; - } - - return a.CompareTo(b); - } - } -} diff --git a/Projects/Server/Configuration/ServerConfiguration.cs b/Projects/Server/Configuration/ServerConfiguration.cs index d32519748..77f76db2f 100644 --- a/Projects/Server/Configuration/ServerConfiguration.cs +++ b/Projects/Server/Configuration/ServerConfiguration.cs @@ -15,424 +15,279 @@ using System; using System.Collections.Generic; -using System.Globalization; using System.IO; using System.Net; using Server.Json; using Server.Logging; -namespace Server +namespace Server; + +public static class ServerConfiguration { - public static class ServerConfiguration + private static readonly ILogger logger = LogFactory.GetLogger(typeof(ServerConfiguration)); + + private const string _relPath = "Configuration/modernuo.json"; + private static readonly string m_FilePath = Path.Join(Core.BaseDirectory, _relPath); + private static ServerSettings m_Settings; + private static bool m_Mocked; + + public static List AssemblyDirectories => m_Settings.AssemblyDirectories; + + public static HashSet DataDirectories => m_Settings.DataDirectories; + + public static List Listeners => m_Settings.Listeners; + + public static ClientVersion GetSetting(string key, ClientVersion defaultValue) => + m_Settings.Settings.TryGetValue(key, out var value) ? new ClientVersion(value) : defaultValue; + + public static string GetSetting(string key, string defaultValue) => + m_Settings.Settings.TryGetValue(key, out var value) ? value : defaultValue; + + public static int GetSetting(string key, int defaultValue) { - private static readonly ILogger logger = LogFactory.GetLogger(typeof(ServerConfiguration)); + m_Settings.Settings.TryGetValue(key, out var strValue); + return int.TryParse(strValue, out var value) ? value : defaultValue; + } - private const string _relPath = "Configuration/modernuo.json"; - private static readonly string m_FilePath = Path.Join(Core.BaseDirectory, _relPath); - private static ServerSettings m_Settings; - private static bool m_Mocked; + public static long GetSetting(string key, long defaultValue) + { + m_Settings.Settings.TryGetValue(key, out var strValue); + return long.TryParse(strValue, out var value) ? value : defaultValue; + } - public static List AssemblyDirectories => m_Settings.AssemblyDirectories; + public static bool GetSetting(string key, bool defaultValue) + { + m_Settings.Settings.TryGetValue(key, out var strValue); + return bool.TryParse(strValue, out var value) ? value : defaultValue; + } - public static List DataDirectories => m_Settings.DataDirectories; + public static T GetSetting(string key, T defaultValue) where T : struct, Enum + { + m_Settings.Settings.TryGetValue(key, out var strValue); + return Enum.TryParse(strValue, out T value) ? value : defaultValue; + } - public static List Listeners => m_Settings.Listeners; - - public static ClientVersion GetSetting(string key, ClientVersion defaultValue) => - m_Settings.Settings.TryGetValue(key, out var value) ? new ClientVersion(value) : defaultValue; - - public static string GetSetting(string key, string defaultValue) => - m_Settings.Settings.TryGetValue(key, out var value) ? value : defaultValue; - - public static int GetSetting(string key, int defaultValue) + public static T? GetSetting(string key) where T : struct, Enum + { + if (!m_Settings.Settings.TryGetValue(key, out var strValue)) { - m_Settings.Settings.TryGetValue(key, out var strValue); - return int.TryParse(strValue, out var value) ? value : defaultValue; + return null; } - public static long GetSetting(string key, long defaultValue) + return Enum.TryParse(strValue, out T value) ? value : null; + } + + public static string GetOrUpdateSetting(string key, string defaultValue) + { + if (m_Settings.Settings.TryGetValue(key, out var value)) { - m_Settings.Settings.TryGetValue(key, out var strValue); - return long.TryParse(strValue, out var value) ? value : defaultValue; - } - - public static bool GetSetting(string key, bool defaultValue) - { - m_Settings.Settings.TryGetValue(key, out var strValue); - return bool.TryParse(strValue, out var value) ? value : defaultValue; - } - - public static T GetSetting(string key, T defaultValue) where T : struct, Enum - { - m_Settings.Settings.TryGetValue(key, out var strValue); - return Enum.TryParse(strValue, out T value) ? value : defaultValue; - } - - public static T? GetSetting(string key) where T : struct, Enum - { - if (!m_Settings.Settings.TryGetValue(key, out var strValue)) - { - return null; - } - - return Enum.TryParse(strValue, out T value) ? value : null; - } - - public static string GetOrUpdateSetting(string key, string defaultValue) - { - if (m_Settings.Settings.TryGetValue(key, out var value)) - { - return value; - } - - SetSetting(key, value = defaultValue); return value; } - public static int GetOrUpdateSetting(string key, int defaultValue) + SetSetting(key, value = defaultValue); + return value; + } + + public static int GetOrUpdateSetting(string key, int defaultValue) + { + int value; + + if (m_Settings.Settings.TryGetValue(key, out var strValue)) { - int value; - - if (m_Settings.Settings.TryGetValue(key, out var strValue)) - { - value = int.TryParse(strValue, out value) ? value : defaultValue; - } - else - { - SetSetting(key, (value = defaultValue).ToString()); - } - - return value; + value = int.TryParse(strValue, out value) ? value : defaultValue; + } + else + { + SetSetting(key, (value = defaultValue).ToString()); } - public static long GetOrUpdateSetting(string key, long defaultValue) + return value; + } + + public static long GetOrUpdateSetting(string key, long defaultValue) + { + long value; + + if (m_Settings.Settings.TryGetValue(key, out var strValue)) { - long value; - - if (m_Settings.Settings.TryGetValue(key, out var strValue)) - { - value = long.TryParse(strValue, out value) ? value : defaultValue; - } - else - { - SetSetting(key, (value = defaultValue).ToString()); - } - - return value; + value = long.TryParse(strValue, out value) ? value : defaultValue; + } + else + { + SetSetting(key, (value = defaultValue).ToString()); } - public static bool GetOrUpdateSetting(string key, bool defaultValue) + return value; + } + + public static bool GetOrUpdateSetting(string key, bool defaultValue) + { + bool value; + + if (m_Settings.Settings.TryGetValue(key, out var strValue)) { - bool value; - - if (m_Settings.Settings.TryGetValue(key, out var strValue)) - { - value = bool.TryParse(strValue, out value) ? value : defaultValue; - } - else - { - SetSetting(key, (value = defaultValue).ToString()); - } - - return value; + value = bool.TryParse(strValue, out value) ? value : defaultValue; + } + else + { + SetSetting(key, (value = defaultValue).ToString()); } - public static TimeSpan GetOrUpdateSetting(string key, TimeSpan defaultValue) + return value; + } + + public static TimeSpan GetOrUpdateSetting(string key, TimeSpan defaultValue) + { + TimeSpan value; + + if (m_Settings.Settings.TryGetValue(key, out var strValue)) { - TimeSpan value; - - if (m_Settings.Settings.TryGetValue(key, out var strValue)) - { - value = TimeSpan.TryParse(strValue, out value) ? value : defaultValue; - } - else - { - SetSetting(key, (value = defaultValue).ToString()); - } - - return value; + value = TimeSpan.TryParse(strValue, out value) ? value : defaultValue; + } + else + { + SetSetting(key, (value = defaultValue).ToString()); } - public static T GetOrUpdateSetting(string key, T defaultValue) where T : struct, Enum + return value; + } + + public static T GetOrUpdateSetting(string key, T defaultValue) where T : struct, Enum + { + T value; + + if (m_Settings.Settings.TryGetValue(key, out var strValue)) { - T value; - - if (m_Settings.Settings.TryGetValue(key, out var strValue)) - { - value = Enum.TryParse(strValue, out value) ? value : defaultValue; - } - else - { - SetSetting(key, (value = defaultValue).ToString()); - } - - return value; + value = Enum.TryParse(strValue, out value) ? value : defaultValue; + } + else + { + SetSetting(key, (value = defaultValue).ToString()); } - public static void SetSetting(string key, TimeSpan value) => SetSetting(key, value.ToString()); + return value; + } - public static void SetSetting(string key, int value) => SetSetting(key, value.ToString()); + public static void SetSetting(string key, TimeSpan value) => SetSetting(key, value.ToString()); - public static void SetSetting(string key, long value) => SetSetting(key, value.ToString()); + public static void SetSetting(string key, int value) => SetSetting(key, value.ToString()); - public static void SetSetting(string key, bool value) => SetSetting(key, value.ToString()); + public static void SetSetting(string key, long value) => SetSetting(key, value.ToString()); - public static void SetSetting(string key, T value) where T : struct, Enum => - SetSetting(key, value.ToString()); + public static void SetSetting(string key, bool value) => SetSetting(key, value.ToString()); - public static void SetSetting(string key, string value) + public static void SetSetting(string key, T value) where T : struct, Enum => + SetSetting(key, value.ToString()); + + public static void SetSetting(string key, string value) + { + m_Settings.Settings[key] = value; + Save(); + } + + // If mock is enabled we skip the console readline. + public static void Load(bool mocked = false) + { + m_Mocked = mocked; + var updated = false; + + if (File.Exists(m_FilePath)) { - m_Settings.Settings[key] = value; - Save(); + logger.Information($"Reading server configuration from {_relPath}..."); + m_Settings = JsonConfig.Deserialize(m_FilePath); + + if (m_Settings == null) + { + logger.Error("Reading server configuration failed"); + throw new FileNotFoundException($"Failed to deserialize {m_FilePath}."); + } + + logger.Information("Reading server configuration done"); + } + else + { + updated = true; + m_Settings = new ServerSettings(); } - // If mock is enabled we skip the console readline. - public static void Load(bool mocked = false) + if (mocked) { - m_Mocked = mocked; - var updated = false; + return; + } - if (File.Exists(m_FilePath)) + if (m_Settings.DataDirectories.Count == 0) + { + updated = true; + foreach (var directory in ServerConfigurationPrompts.GetDataDirectories()) { - logger.Information($"Reading server configuration from {_relPath}..."); - m_Settings = JsonConfig.Deserialize(m_FilePath); - - if (m_Settings == null) - { - logger.Error("Reading server configuration failed"); - throw new FileNotFoundException($"Failed to deserialize {m_FilePath}."); - } - - logger.Information("Reading server configuration done"); - } - else - { - updated = true; - m_Settings = new ServerSettings(); - } - - if (mocked) - { - return; - } - - if (m_Settings.DataDirectories.Count == 0) - { - updated = true; - m_Settings.DataDirectories.AddRange(GetDataDirectories()); - } - - if (m_Settings.Listeners.Count == 0) - { - updated = true; - m_Settings.Listeners.AddRange(GetListeners()); - } - - if (m_Settings.Expansion == null) - { - var expansion = GetSetting("currentExpansion"); - var hasExpansion = expansion != null; - - expansion ??= GetExpansion(); - - if (expansion <= Expansion.ML && !hasExpansion) - { - SetPre6000Support(); - } - - updated = true; - m_Settings.Expansion = expansion; - } - - Core.Expansion = m_Settings.Expansion.Value; - - if (updated) - { - Save(); - Console.Write("Server configuration saved to "); - Utility.PushColor(ConsoleColor.Green); - Console.WriteLine($"{_relPath}."); - Utility.PopColor(); + m_Settings.DataDirectories.Add(directory); } } - private static void SetPre6000Support() + UOClient.Load(); + var cuoClientFiles = UOClient.CuoSettings?.UltimaOnlineDirectory; + + if (cuoClientFiles != null) { - Console.WriteLine("Will you be using a client version older than 6.0.0.0?"); + DataDirectories.Add(cuoClientFiles); + } - do + if (m_Settings.Listeners.Count == 0) + { + updated = true; + m_Settings.Listeners.AddRange(ServerConfigurationPrompts.GetListeners()); + } + + bool? isPre60000 = null; + + if (m_Settings.Expansion == null) + { + var expansion = GetSetting("currentExpansion"); + var hasExpansion = expansion != null; + + expansion ??= ServerConfigurationPrompts.GetExpansion(); + + if (expansion <= Expansion.ML && !hasExpansion) { - Console.Write("y or [n]> "); - var input = Console.ReadLine(); - if (string.IsNullOrWhiteSpace(input) || input.InsensitiveStartsWith("n")) - { - Utility.PushColor(ConsoleColor.Yellow); - Console.WriteLine("Client >= 6.0.0.0 chosen."); - Utility.PopColor(); - return; - } - - if (input.InsensitiveStartsWith("y")) + isPre60000 = ServerConfigurationPrompts.GetIsClientPre6000(); + if (isPre60000 == true) { SetSetting("maps.enablePre6000Trammel", true.ToString()); - - Utility.PushColor(ConsoleColor.Yellow); - Console.WriteLine("Client <= 5.0.9.1 chosen."); - Utility.PopColor(); - return; } - - Console.Write("Invalid option "); - Utility.PushColor(ConsoleColor.Red); - Console.Write(input); - Utility.PopColor(); - Console.WriteLine(". Press y for yes or n for no."); - } while (true); - } - - private static Expansion GetExpansion() - { - Console.WriteLine("Please choose an expansion by typing the number or short name:"); - var expansions = ExpansionInfo.Table; - - for (int i = 0; i < expansions.Length; i++) - { - var info = expansions[i]; - Console.WriteLine(" - {0,2}: {1} ({2})", i, ((Expansion)info.ID).ToString(), info.Name); } - var maxExpansion = (Expansion)expansions[^1].ID; - var maxExpansionName = maxExpansion.ToString(); - - do - { - Console.Write("[enter for {0}]> ", maxExpansionName); - var input = Console.ReadLine(); - Expansion expansion; - - if (string.IsNullOrWhiteSpace(input)) - { - expansion = maxExpansion; - } - else if (int.TryParse(input, NumberStyles.Integer, null, out var number) && - number >= 0 && number < expansions.Length) - { - expansion = (Expansion)number; - } - else if (!Enum.TryParse(input, out expansion)) - { - Utility.PushColor(ConsoleColor.Red); - Console.Write(input); - Utility.PopColor(); - Console.WriteLine(" is an invalid expansion option."); - continue; - } - - Console.Write("Expansion set to "); - Utility.PushColor(ConsoleColor.Green); - Console.Write(ExpansionInfo.GetInfo(expansion).Name); - Utility.PopColor(); - Console.WriteLine("."); - return expansion; - } while (true); + updated = true; + m_Settings.Expansion = expansion; } - private static List GetDataDirectories() + if (isPre60000 != true) { - Console.WriteLine("Please enter the absolute path to the Ultima Online data:"); - - var directories = new List(); - - do + if (ServerConfigurationPrompts.GetIsClient7090()) { - Console.Write("{0}> ", directories.Count > 0 ? "[enter to finish]" : " "); - var directory = Console.ReadLine(); - if (string.IsNullOrWhiteSpace(directory)) - { - break; - } - - if (Directory.Exists(directory)) - { - directories.Add(directory); - Console.Write("Added "); - Utility.PushColor(ConsoleColor.Green); - Console.Write(directory); - Utility.PopColor(); - Console.WriteLine("."); - } - else - { - Utility.PushColor(ConsoleColor.Red); - Console.Write(directory); - Utility.PopColor(); - Console.WriteLine(" does not exist."); - } - } while (true); - - return directories; - } - - private static List GetListeners() - { - Console.WriteLine("Please enter the IP and ports to listen:"); - Console.WriteLine(" - Only enter IP addresses directly bound to this machine"); - Console.WriteLine(" - To listen to all IP addresses enter 0.0.0.0"); - - var ips = new List(); - - do - { - // IP:Port? - Console.Write("[{0}]> ", ips.Count > 0 ? "enter to finish" : "0.0.0.0:2593"); - var ipStr = Console.ReadLine(); - - IPEndPoint ip; - if (string.IsNullOrWhiteSpace(ipStr)) - { - if (ips.Count > 0) - { - break; - } - - ip = new IPEndPoint(IPAddress.Any, 2593); - } - else - { - if (!ipStr.ContainsOrdinal(':')) - { - ipStr += ":2593"; - } - - if (!IPEndPoint.TryParse(ipStr, out ip)) - { - Utility.PushColor(ConsoleColor.Red); - Console.Write(ipStr); - Utility.PopColor(); - Console.WriteLine(" is not a valid IP or port."); - continue; - } - } - - ips.Add(ip); - Console.Write("Added "); - Utility.PushColor(ConsoleColor.Green); - Console.Write(ip); - Utility.PopColor(); - Console.WriteLine("."); - } while (true); - - return ips; - } - - public static void Save() - { - if (m_Mocked) - { - return; + updated = true; + SetSetting("maps.enablePostHSMultiComponentFormat", true); } + } - JsonConfig.Serialize(m_FilePath, m_Settings); + Core.Expansion = m_Settings.Expansion.Value; + + if (updated) + { + Save(); + Console.Write("Server configuration saved to "); + Utility.PushColor(ConsoleColor.Green); + Console.WriteLine($"{_relPath}."); + Utility.PopColor(); } } + + public static void Save() + { + if (m_Mocked) + { + return; + } + + JsonConfig.Serialize(m_FilePath, m_Settings); + } } diff --git a/Projects/Server/Configuration/ServerConfigurationPrompts.cs b/Projects/Server/Configuration/ServerConfigurationPrompts.cs new file mode 100644 index 000000000..7976870a6 --- /dev/null +++ b/Projects/Server/Configuration/ServerConfigurationPrompts.cs @@ -0,0 +1,220 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Net; + +namespace Server; + +public static class ServerConfigurationPrompts +{ + internal static bool GetIsClient7090() + { + if (UOClient.ServerClientVersion != null) + { + return UOClient.ServerClientVersion >= ClientVersion.Version7090; + } + + Console.WriteLine("Will you be using a client version 7.0.9.0 or newer?"); + + do + { + Console.Write("[y] or n> "); + var input = Console.ReadLine(); + if (string.IsNullOrWhiteSpace(input) || input.InsensitiveStartsWith("y")) + { + Utility.PushColor(ConsoleColor.Yellow); + Console.WriteLine("Client >= 7.0.9.0 chosen."); + Utility.PopColor(); + return true; + } + + if (input.InsensitiveStartsWith("n")) + { + Utility.PushColor(ConsoleColor.Yellow); + Console.WriteLine("Client < 7.0.9.0 chosen."); + Utility.PopColor(); + return false; + } + + Console.Write("Invalid option "); + Utility.PushColor(ConsoleColor.Red); + Console.Write(input); + Utility.PopColor(); + Console.WriteLine(". Press y for yes or n for no."); + } while (true); + } + + + internal static bool GetIsClientPre6000() + { + if (UOClient.ServerClientVersion != null) + { + return UOClient.ServerClientVersion < ClientVersion.Version6000; + } + + Console.WriteLine("Will you be using a client version older than 6.0.0.0?"); + + do + { + Console.Write("y or [n]> "); + var input = Console.ReadLine(); + if (string.IsNullOrWhiteSpace(input) || input.InsensitiveStartsWith("n")) + { + Utility.PushColor(ConsoleColor.Yellow); + Console.WriteLine("Client >= 6.0.0.0 chosen."); + Utility.PopColor(); + return false; + } + + if (input.InsensitiveStartsWith("y")) + { + Utility.PushColor(ConsoleColor.Yellow); + Console.WriteLine("Client < 6.0.0.0 chosen."); + Utility.PopColor(); + return true; + } + + Console.Write("Invalid option "); + Utility.PushColor(ConsoleColor.Red); + Console.Write(input); + Utility.PopColor(); + Console.WriteLine(". Press y for yes or n for no."); + } while (true); + } + + internal static Expansion GetExpansion() + { + Console.WriteLine("Please choose an expansion by typing the number or short name:"); + var expansions = ExpansionInfo.Table; + + for (int i = 0; i < expansions.Length; i++) + { + var info = expansions[i]; + Console.WriteLine(" - {0,2}: {1} ({2})", i, ((Expansion)info.ID).ToString(), info.Name); + } + + var maxExpansion = (Expansion)expansions[^1].ID; + var maxExpansionName = maxExpansion.ToString(); + + do + { + Console.Write("[enter for {0}]> ", maxExpansionName); + var input = Console.ReadLine(); + Expansion expansion; + + if (string.IsNullOrWhiteSpace(input)) + { + expansion = maxExpansion; + } + else if (int.TryParse(input, NumberStyles.Integer, null, out var number) && + number >= 0 && number < expansions.Length) + { + expansion = (Expansion)number; + } + else if (!Enum.TryParse(input, out expansion)) + { + Utility.PushColor(ConsoleColor.Red); + Console.Write(input); + Utility.PopColor(); + Console.WriteLine(" is an invalid expansion option."); + continue; + } + + Console.Write("Expansion set to "); + Utility.PushColor(ConsoleColor.Green); + Console.Write(ExpansionInfo.GetInfo(expansion).Name); + Utility.PopColor(); + Console.WriteLine("."); + return expansion; + } while (true); + } + + internal static List GetDataDirectories() + { + Console.WriteLine("Please enter the absolute path to your ClassicUO or Ultima Online data:"); + + var directories = new List(); + + do + { + Console.Write("{0}> ", directories.Count > 0 ? "[enter to finish]" : " "); + var directory = Console.ReadLine(); + if (string.IsNullOrWhiteSpace(directory)) + { + break; + } + + if (Directory.Exists(directory)) + { + directories.Add(directory); + Console.Write("Added "); + Utility.PushColor(ConsoleColor.Green); + Console.Write(directory); + Utility.PopColor(); + Console.WriteLine("."); + } + else + { + Utility.PushColor(ConsoleColor.Red); + Console.Write(directory); + Utility.PopColor(); + Console.WriteLine(" does not exist."); + } + } while (true); + + return directories; + } + + internal static List GetListeners() + { + Console.WriteLine("Please enter the IP and ports to listen:"); + Console.WriteLine(" - Only enter IP addresses directly bound to this machine"); + Console.WriteLine(" - To listen to all IP addresses enter 0.0.0.0"); + + var ips = new List(); + + do + { + // IP:Port? + Console.Write("[{0}]> ", ips.Count > 0 ? "enter to finish" : "0.0.0.0:2593"); + var ipStr = Console.ReadLine(); + + IPEndPoint ip; + if (string.IsNullOrWhiteSpace(ipStr)) + { + if (ips.Count > 0) + { + break; + } + + ip = new IPEndPoint(IPAddress.Any, 2593); + } + else + { + if (!ipStr.ContainsOrdinal(':')) + { + ipStr += ":2593"; + } + + if (!IPEndPoint.TryParse(ipStr, out ip)) + { + Utility.PushColor(ConsoleColor.Red); + Console.Write(ipStr); + Utility.PopColor(); + Console.WriteLine(" is not a valid IP or port."); + continue; + } + } + + ips.Add(ip); + Console.Write("Added "); + Utility.PushColor(ConsoleColor.Green); + Console.Write(ip); + Utility.PopColor(); + Console.WriteLine("."); + } while (true); + + return ips; + } +} diff --git a/Projects/Server/Configuration/ServerSettings.cs b/Projects/Server/Configuration/ServerSettings.cs index 87f69a595..23eddb6de 100644 --- a/Projects/Server/Configuration/ServerSettings.cs +++ b/Projects/Server/Configuration/ServerSettings.cs @@ -25,7 +25,7 @@ namespace Server public List AssemblyDirectories { get; set; } = new(); [JsonPropertyName("dataDirectories")] - public List DataDirectories { get; set; } = new(); + public HashSet DataDirectories { get; set; } = new(); [JsonPropertyName("listeners")] public List Listeners { get; set; } = new(); diff --git a/Projects/Server/MultiData.cs b/Projects/Server/MultiData.cs index 6bda94398..ead7417af 100644 --- a/Projects/Server/MultiData.cs +++ b/Projects/Server/MultiData.cs @@ -11,7 +11,8 @@ namespace Server private static readonly BinaryReader m_IndexReader; private static readonly BinaryReader m_StreamReader; - private static readonly bool UsingUOPFormat; + public static readonly bool PostHSMulFormat; + public static readonly bool UsingUOPFormat; static MultiData() { @@ -21,9 +22,13 @@ namespace Server { LoadUOP(multiUOPPath); UsingUOPFormat = true; + PostHSMulFormat = false; return; } + // Client version 7.0.9.0+ + PostHSMulFormat = UOClient.ServerClientVersion >= ClientVersion.Version7090; + var idxPath = Core.FindDataFile("multi.idx"); var mulPath = Core.FindDataFile("multi.mul"); @@ -223,7 +228,7 @@ namespace Server m_StreamReader.BaseStream.Seek(lookup, SeekOrigin.Begin); - return new MultiComponentList(m_StreamReader, length / (MultiComponentList.PostHSFormat ? 16 : 12)); + return new MultiComponentList(m_StreamReader, length / (PostHSMulFormat ? 16 : 12)); } catch { @@ -378,15 +383,9 @@ namespace Server allTiles[i].OffsetX = reader.ReadInt16(); allTiles[i].OffsetY = reader.ReadInt16(); allTiles[i].OffsetZ = reader.ReadInt16(); - - if (PostHSFormat) - { - allTiles[i].Flags = (TileFlag)reader.ReadUInt64(); - } - else - { - allTiles[i].Flags = (TileFlag)reader.ReadUInt32(); - } + allTiles[i].Flags = MultiData.PostHSMulFormat + ? (TileFlag)reader.ReadUInt64() + : (TileFlag)reader.ReadUInt32(); var e = allTiles[i]; @@ -539,7 +538,7 @@ namespace Server public static void Configure() { // OSI Client Patch 7.0.9.0 - PostHSFormat = ServerConfiguration.GetOrUpdateSetting("maps.enablePostHSMultiComponentFormat", true); + PostHSFormat = ServerConfiguration.GetSetting("maps.enablePostHSMultiComponentFormat", true); } public static bool PostHSFormat { get; set; } diff --git a/Projects/Server/Network/NetState/NetState.ClientVersion.cs b/Projects/Server/Network/NetState/NetState.ClientVersion.cs index 4302ec0b1..844c9fb21 100644 --- a/Projects/Server/Network/NetState/NetState.ClientVersion.cs +++ b/Projects/Server/Network/NetState/NetState.ClientVersion.cs @@ -19,23 +19,6 @@ namespace Server.Network { public partial class NetState { - private static readonly ClientVersion m_Version400a = new("4.0.0a"); - private static readonly ClientVersion m_Version407a = new("4.0.7a"); - private static readonly ClientVersion m_Version500a = new("5.0.0a"); - private static readonly ClientVersion m_Version502b = new("5.0.2b"); - private static readonly ClientVersion m_Version6000 = new("6.0.0.0"); - private static readonly ClientVersion m_Version6017 = new("6.0.1.7"); - private static readonly ClientVersion m_Version60142 = new("6.0.14.2"); - private static readonly ClientVersion m_Version7000 = new("7.0.0.0"); - private static readonly ClientVersion m_Version7090 = new("7.0.9.0"); - private static readonly ClientVersion m_Version70130 = new("7.0.13.0"); - private static readonly ClientVersion m_Version70160 = new("7.0.16.0"); - private static readonly ClientVersion m_Version70300 = new("7.0.30.0"); - private static readonly ClientVersion m_Version70331 = new("7.0.33.1"); - private static readonly ClientVersion m_Version704565 = new("7.0.45.65"); - private static readonly ClientVersion m_Version70500 = new("7.0.50.0"); - private static readonly ClientVersion m_Version70610 = new("7.0.61.0"); - public ProtocolChanges ProtocolChanges { get; set; } public ClientFlags Flags { get; set; } @@ -52,23 +35,23 @@ namespace Server.Network public static ProtocolChanges ProtocolChangesByVersion(ClientVersion version) => version switch { - var v when v >= m_Version70610 => ProtocolChanges.Version70610, - var v when v >= m_Version70500 => ProtocolChanges.Version70500, - var v when v >= m_Version704565 => ProtocolChanges.Version704565, - var v when v >= m_Version70331 => ProtocolChanges.Version70331, - var v when v >= m_Version70300 => ProtocolChanges.Version70300, - var v when v >= m_Version70160 => ProtocolChanges.Version70160, - var v when v >= m_Version70130 => ProtocolChanges.Version70130, - var v when v >= m_Version7090 => ProtocolChanges.Version7090, - var v when v >= m_Version7000 => ProtocolChanges.Version7000, - var v when v >= m_Version60142 => ProtocolChanges.Version60142, - var v when v >= m_Version6017 => ProtocolChanges.Version6017, - var v when v >= m_Version6000 => ProtocolChanges.Version6000, - var v when v >= m_Version502b => ProtocolChanges.Version502b, - var v when v >= m_Version500a => ProtocolChanges.Version500a, - var v when v >= m_Version407a => ProtocolChanges.Version407a, - var v when v >= m_Version400a => ProtocolChanges.Version400a, - _ => ProtocolChanges.None + var v when v >= ClientVersion.Version70610 => ProtocolChanges.Version70610, + var v when v >= ClientVersion.Version70500 => ProtocolChanges.Version70500, + var v when v >= ClientVersion.Version704565 => ProtocolChanges.Version704565, + var v when v >= ClientVersion.Version70331 => ProtocolChanges.Version70331, + var v when v >= ClientVersion.Version70300 => ProtocolChanges.Version70300, + var v when v >= ClientVersion.Version70160 => ProtocolChanges.Version70160, + var v when v >= ClientVersion.Version70130 => ProtocolChanges.Version70130, + var v when v >= ClientVersion.Version7090 => ProtocolChanges.Version7090, + var v when v >= ClientVersion.Version7000 => ProtocolChanges.Version7000, + var v when v >= ClientVersion.Version60142 => ProtocolChanges.Version60142, + var v when v >= ClientVersion.Version6017 => ProtocolChanges.Version6017, + var v when v >= ClientVersion.Version6000 => ProtocolChanges.Version6000, + var v when v >= ClientVersion.Version502b => ProtocolChanges.Version502b, + var v when v >= ClientVersion.Version500a => ProtocolChanges.Version500a, + var v when v >= ClientVersion.Version407a => ProtocolChanges.Version407a, + var v when v >= ClientVersion.Version400a => ProtocolChanges.Version400a, + _ => ProtocolChanges.None }; [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/Projects/Server/Utilities/PathUtility.cs b/Projects/Server/Utilities/PathUtility.cs index 6f22c46db..b85b7b07d 100644 --- a/Projects/Server/Utilities/PathUtility.cs +++ b/Projects/Server/Utilities/PathUtility.cs @@ -17,70 +17,69 @@ using System; using System.IO; using Server.Text; -namespace Server +namespace Server; + +public static class PathUtility { - public static class PathUtility + public static string EnsureDirectory(string dir) { - public static string EnsureDirectory(string dir) + var path = GetFullPath(dir, Core.BaseDirectory); + Directory.CreateDirectory(path); + + return path; + } + + public static void EnsureDirectory(this FileInfo fi) + { + var dir = GetFullPath(fi.DirectoryName, Core.BaseDirectory); + if (dir != null) { - var path = GetFullPath(dir, Core.BaseDirectory); - Directory.CreateDirectory(path); - - return path; - } - - public static void EnsureDirectory(this FileInfo fi) - { - var dir = GetFullPath(fi.DirectoryName, Core.BaseDirectory); - if (dir != null) - { - Directory.CreateDirectory(dir); - } - } - - public static void EnsureDirectory(this DirectoryInfo di) - { - var file = GetFullPath(di.FullName, Core.BaseDirectory); - Directory.CreateDirectory(file); - } - - public static string GetFullPath(string relativeOrAbsolutePath) => - GetFullPath(relativeOrAbsolutePath, Core.BaseDirectory); - - public static string GetFullPath(string relativeOrAbsolutePath, string basePath) => - relativeOrAbsolutePath switch - { - null => null, - "" => basePath, - _ => Path.IsPathRooted(relativeOrAbsolutePath) - ? relativeOrAbsolutePath - : Path.GetFullPath(relativeOrAbsolutePath, basePath) - }; - - public static string EnsureRandomPath(string basePath) - { - Span bytes = stackalloc byte[8]; - Utility.RandomBytes(bytes); - return EnsureDirectory(Path.Combine(basePath, bytes.ToHexString())); - } - - public static void CopyDirectory(string sourcePath, string destinationPath, bool recursive = true) - { - var searchOptions = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly; - foreach (var file in Directory.EnumerateFiles(sourcePath, "*", searchOptions)) - { - var fi = new FileInfo(file); - var relativePath = Path.GetRelativePath(sourcePath, fi.DirectoryName!); - var destFolder = Path.Combine(destinationPath, relativePath); - EnsureDirectory(destFolder); - fi.CopyTo(Path.Combine(destFolder, fi.Name)); - } - } - - public static void MoveDirectory(string sourcePath, string destinationPath) - { - CopyDirectory(sourcePath, destinationPath); - Directory.Delete(sourcePath, true); + Directory.CreateDirectory(dir); } } + + public static void EnsureDirectory(this DirectoryInfo di) + { + var file = GetFullPath(di.FullName, Core.BaseDirectory); + Directory.CreateDirectory(file); + } + + public static string GetFullPath(string relativeOrAbsolutePath) => + GetFullPath(relativeOrAbsolutePath, Core.BaseDirectory); + + public static string GetFullPath(string relativeOrAbsolutePath, string basePath) => + relativeOrAbsolutePath switch + { + null => null, + "" => basePath, + _ => Path.IsPathRooted(relativeOrAbsolutePath) + ? relativeOrAbsolutePath + : Path.GetFullPath(relativeOrAbsolutePath, basePath) + }; + + public static string EnsureRandomPath(string basePath) + { + Span bytes = stackalloc byte[8]; + Utility.RandomBytes(bytes); + return EnsureDirectory(Path.Combine(basePath, bytes.ToHexString())); + } + + public static void CopyDirectory(string sourcePath, string destinationPath, bool recursive = true) + { + var searchOptions = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly; + foreach (var file in Directory.EnumerateFiles(sourcePath, "*", searchOptions)) + { + var fi = new FileInfo(file); + var relativePath = Path.GetRelativePath(sourcePath, fi.DirectoryName!); + var destFolder = Path.Combine(destinationPath, relativePath); + EnsureDirectory(destFolder); + fi.CopyTo(Path.Combine(destFolder, fi.Name)); + } + } + + public static void MoveDirectory(string sourcePath, string destinationPath) + { + CopyDirectory(sourcePath, destinationPath); + Directory.Delete(sourcePath, true); + } } diff --git a/Projects/UOContent/Misc/AccountPrompt.cs b/Projects/UOContent/Misc/AccountPrompt.cs index 1483f022e..0d4a22e06 100644 --- a/Projects/UOContent/Misc/AccountPrompt.cs +++ b/Projects/UOContent/Misc/AccountPrompt.cs @@ -1,41 +1,42 @@ using System; using Server.Accounting; +using Server.Logging; -namespace Server.Misc +namespace Server.Misc; + +public static class AccountPrompt { - public static class AccountPrompt + private static readonly ILogger logger = LogFactory.GetLogger(typeof(AccountPrompt)); + + public static void Initialize() { - public static void Initialize() + if (Accounts.Count == 0) { - if (Accounts.Count == 0) + Console.WriteLine("This server has no accounts."); + Console.Write("Do you want to create the owner account now? (y/n): "); + + var answer = Console.ReadLine(); + if (answer is "y" or "Y") { - Console.WriteLine("This server has no accounts."); - Console.Write("Do you want to create the owner account now? (y/n): "); + Console.WriteLine(); - var answer = Console.ReadLine(); - if (answer is "y" or "Y") + Console.Write("Username: "); + var username = Console.ReadLine(); + + Console.Write("Password: "); + var password = Console.ReadLine(); + + var a = new Account(username, password) { - Console.WriteLine(); + AccessLevel = AccessLevel.Owner + }; - Console.Write("Username: "); - var username = Console.ReadLine(); - - Console.Write("Password: "); - var password = Console.ReadLine(); - - var a = new Account(username, password); - a.AccessLevel = AccessLevel.Owner; - - Console.WriteLine("Account created."); - - ServerAccess.AddProtectedAccount(a, true); - Console.WriteLine("Added {0} to the protected accounts list.", a.Username); - } - else - { - Console.WriteLine(); - Console.WriteLine("Account not created."); - } + logger.Information("Owner account created: {0}", username); + ServerAccess.AddProtectedAccount(a, true); + } + else + { + logger.Warning("No owner account created."); } } } diff --git a/Projects/UOContent/Misc/ClientVerification.cs b/Projects/UOContent/Misc/ClientVerification.cs index 7b264eec8..20c90f1f7 100644 --- a/Projects/UOContent/Misc/ClientVerification.cs +++ b/Projects/UOContent/Misc/ClientVerification.cs @@ -1,6 +1,4 @@ using System; -using System.Buffers.Binary; -using System.IO; using Server.Buffers; using Server.Gumps; using Server.Logging; @@ -14,7 +12,6 @@ namespace Server.Misc private static readonly ILogger logger = LogFactory.GetLogger(typeof(ClientVerification)); private static bool _enable; - private static bool _detectClientRequirement; private static InvalidClientResponse _invalidClientResponse; private static string _versionExpression; @@ -33,11 +30,6 @@ namespace Server.Misc MinRequired = ServerConfiguration.GetSetting("clientVerification.minRequired", (ClientVersion)null); MaxRequired = ServerConfiguration.GetSetting("clientVerification.maxRequired", (ClientVersion)null); - if (MinRequired == null && MaxRequired == null) - { - _detectClientRequirement = ServerConfiguration.GetOrUpdateSetting("clientVerification.detectFromClientExe", true); - } - _enable = ServerConfiguration.GetOrUpdateSetting("clientVerification.enable", true); _invalidClientResponse = ServerConfiguration.GetOrUpdateSetting("clientVerification.invalidClientResponse", InvalidClientResponse.Kick); @@ -53,40 +45,9 @@ namespace Server.Misc { EventSink.ClientVersionReceived += EventSink_ClientVersionReceived; - if (_detectClientRequirement) + if (MinRequired == null && MaxRequired == null) { - var path = Core.FindDataFile("client.exe", false); - - if (File.Exists(path)) - { - using FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read); - var buffer = GC.AllocateUninitializedArray((int)fs.Length, true); - fs.Read(buffer); - // VS_VERSION_INFO (unicode) - Span vsVersionInfo = stackalloc byte[] - { - 0x56, 0x00, 0x53, 0x00, 0x5F, 0x00, 0x56, 0x00, - 0x45, 0x00, 0x52, 0x00, 0x53, 0x00, 0x49, 0x00, - 0x4F, 0x00, 0x4E, 0x00, 0x5F, 0x00, 0x49, 0x00, - 0x4E, 0x00, 0x46, 0x00, 0x4F, 0x00 - }; - - for (var i = 0; i < buffer.Length; i++) - { - if (vsVersionInfo.SequenceEqual(buffer.AsSpan(i, 30))) - { - var offset = i + 42; // 30 + 12 - - var minorPart = BinaryPrimitives.ReadUInt16LittleEndian(buffer.AsSpan(offset)); - var majorPart = BinaryPrimitives.ReadUInt16LittleEndian(buffer.AsSpan(offset + 2)); - var privatePart = BinaryPrimitives.ReadUInt16LittleEndian(buffer.AsSpan(offset + 4)); - var buildPart = BinaryPrimitives.ReadUInt16LittleEndian(buffer.AsSpan(offset + 6)); - - MinRequired = new ClientVersion(majorPart, minorPart, buildPart, privatePart); - break; - } - } - } + MinRequired = UOClient.ServerClientVersion; } if (MinRequired != null || MaxRequired != null) diff --git a/Projects/UOContent/Misc/ServerAccess.cs b/Projects/UOContent/Misc/ServerAccess.cs index 9b43d604a..357082c85 100644 --- a/Projects/UOContent/Misc/ServerAccess.cs +++ b/Projects/UOContent/Misc/ServerAccess.cs @@ -56,8 +56,11 @@ public static class ServerAccess } ServerAccessConfiguration = JsonConfig.Deserialize(path); - var protectedAccounts = string.Join(", ", ServerAccessConfiguration.ProtectedAccounts); - logger.Information("Protected accounts registered: {0}", protectedAccounts); + if (ServerAccessConfiguration.ProtectedAccounts.Count > 0) + { + var protectedAccounts = string.Join(", ", ServerAccessConfiguration.ProtectedAccounts); + logger.Information("Protected accounts registered: {0}", protectedAccounts); + } } public static void Initialize() From e873d2ed7e8cca91ed1f19e2623886b9a29e5816 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 27 Feb 2022 02:20:03 -0800 Subject: [PATCH 085/213] fix: Simplifies fastwalk detection (#907) * Uses a circular buffer for steps. * Limits to 3 steps instead of 4. * Gives a 5% buffer on the first step. --- Projects/Server/Mobiles/Mobile.cs | 20 ++- Projects/Server/Mobiles/Movement.cs | 10 +- .../Network/NetState/NetState.Fastwalk.cs | 167 ++++++++++-------- .../UOContent/Network/FastwalkDetection.cs | 67 +++++++ 4 files changed, 186 insertions(+), 78 deletions(-) create mode 100644 Projects/UOContent/Network/FastwalkDetection.cs diff --git a/Projects/Server/Mobiles/Mobile.cs b/Projects/Server/Mobiles/Mobile.cs index c94b62b9c..84e12e759 100644 --- a/Projects/Server/Mobiles/Mobile.cs +++ b/Projects/Server/Mobiles/Mobile.cs @@ -9029,7 +9029,10 @@ namespace Server public Direction GetDirectionTo(IPoint2D p, bool run = false) => p == null ? Direction.North | (run ? Direction.Running : 0) : GetDirectionTo(p.X, p.Y, run); - public void PublicOverheadMessage(MessageType type, int hue, bool ascii, string text, bool noLineOfSight = true) + public void PublicOverheadMessage( + MessageType type, int hue, bool ascii, string text, bool noLineOfSight = true, + AccessLevel accessLevel = AccessLevel.Player + ) { if (m_Map == null) { @@ -9042,7 +9045,11 @@ namespace Server foreach (var state in eable) { - if (state.Mobile.CanSee(this) && (noLineOfSight || state.Mobile.InLOS(this))) + if ( + state.Mobile.AccessLevel >= accessLevel && + state.Mobile.CanSee(this) && + (noLineOfSight || state.Mobile.InLOS(this)) + ) { var length = OutgoingMessagePackets.CreateMessage( buffer, Serial, Body, type, hue, 3, ascii, Language, Name, text @@ -9093,7 +9100,8 @@ namespace Server public void PublicOverheadMessage( MessageType type, int hue, int number, AffixType affixType, string affix, - string args = "", bool noLineOfSight = false + string args = "", bool noLineOfSight = false, + AccessLevel accessLevel = AccessLevel.Player ) { if (m_Map == null) @@ -9107,7 +9115,11 @@ namespace Server foreach (var state in eable) { - if (state.Mobile.CanSee(this) && (noLineOfSight || state.Mobile.InLOS(this))) + if ( + state.Mobile.AccessLevel >= accessLevel && + state.Mobile.CanSee(this) && + (noLineOfSight || state.Mobile.InLOS(this)) + ) { var length = OutgoingMessagePackets.CreateMessageLocalizedAffix( buffer, Serial, Body, type, hue, 3, number, Name, affixType, affix, args diff --git a/Projects/Server/Mobiles/Movement.cs b/Projects/Server/Mobiles/Movement.cs index 3ea012573..44cfc473d 100644 --- a/Projects/Server/Mobiles/Movement.cs +++ b/Projects/Server/Mobiles/Movement.cs @@ -19,16 +19,16 @@ namespace Server.Movement { // Movement implementation algorithm public static IMovementImpl Impl { get; set; } - public static int WalkFootDelay { get; set; } = 440; - public static int RunFootDelay { get; set; } = 220; - public static int WalkMountDelay { get; set; } = 220; - public static int RunMountDelay { get; set; } = 110; + public static int WalkFootDelay { get; set; } = 400; + public static int RunFootDelay { get; set; } = 200; + public static int WalkMountDelay { get; set; } = 200; + public static int RunMountDelay { get; set; } = 100; public static bool EnableFastwalkPrevention { get; set; } = true; public static AccessLevel FastwalkExemptionLevel { get; set; } = AccessLevel.Counselor; // If this is changed during runtime, then the steps array needs resizing. - public static int MaxSteps { get; private set; } = 4; + public static int MaxSteps { get; private set; } = 3; public static void Configure() { diff --git a/Projects/Server/Network/NetState/NetState.Fastwalk.cs b/Projects/Server/Network/NetState/NetState.Fastwalk.cs index eb6934aaf..3b1036254 100644 --- a/Projects/Server/Network/NetState/NetState.Fastwalk.cs +++ b/Projects/Server/Network/NetState/NetState.Fastwalk.cs @@ -13,80 +13,109 @@ * along with this program. If not, see . * *************************************************************************/ +using System.Runtime.CompilerServices; using CalcMoves = Server.Movement.Movement; -namespace Server.Network +namespace Server.Network; + +public partial class NetState { - public partial class NetState + // The next step + private int _stepIndex; + // The last index to expire + private int _expiredIndex; + + private long[] _steps; + + public bool AddStep(Direction d) { - private int _stepIndex; - private int _stepCount; - private long _startDelay; - private long[] _stepDelays; - - public bool AddStep(Direction d) + if (Mobile == null) { - if (Mobile == null) - { - return false; - } - - var maxSteps = CalcMoves.MaxSteps; - - _stepDelays ??= new long[maxSteps]; - var length = _stepDelays.Length; - - var index = _stepIndex - _stepCount; - if (index < 0) - { - index += length; - } - - var now = Core.TickCount; - var last = _startDelay; - - // Discard old steps by decrementing the step counter - while (index != _stepIndex || _stepCount >= maxSteps) - { - var step = _stepDelays[index++]; - if (now - last < step) - { - break; - } - - last += step; - _stepCount--; - if (index >= length) - { - index = 0; - } - } - - _startDelay = last; - - // If we are out of steps, fail - if (_stepCount >= maxSteps) - { - return false; - } - - var delay = Mobile.ComputeMovementSpeed(d); - - // Add the delay - _stepDelays[_stepIndex++] = delay; - - if (_stepIndex >= length) - { - _stepIndex = 0; - } - - if (_stepCount == 0) - { - _startDelay = now; - } - _stepCount++; - - return true; + return false; } + + _steps ??= new long[CalcMoves.MaxSteps + 1]; // Extra index as a sentinel + var stepsLength = _steps.Length; + + var now = Core.TickCount; + + var lastIndex = -1; + + // Expire old steps + while (_expiredIndex != _stepIndex) + { + var step = _steps[_expiredIndex]; + + // Is the step ahead of us, or the next step rolled over and we didn't yet + if (step > now || lastIndex > -1 && _steps[lastIndex] > step) + { + break; + } + + lastIndex = _expiredIndex++; + + if (_expiredIndex == stepsLength) + { + _expiredIndex -= stepsLength; + } + } + + var stepsTaken = (_stepIndex < _expiredIndex ? _stepIndex + stepsLength : _stepIndex) - _expiredIndex; + var maxSteps = _steps.Length - 1; + + // Can we take a step? + if (stepsTaken >= maxSteps) + { + return false; + } + + var delay = Mobile.ComputeMovementSpeed(d); + + var prev = _stepIndex - 1; + if (prev < 0) + { + prev += stepsLength; + } + + // Give a 5% buffer on the first step + _steps[_stepIndex++] = stepsTaken > 0 ? _steps[prev] + delay : now + delay * 950 / 1000; + + if (_stepIndex == stepsLength) + { + _stepIndex -= stepsLength; + } + + // If CalcMoves.MaxSteps is modified, we need to adjust accordingly + AdjustSteps(CalcMoves.MaxSteps); + + return true; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void AdjustSteps(int maxSteps) + { + var stepsLength = maxSteps + 1; + + if (_steps.Length == stepsLength) + { + return; + } + + var oldSteps = _steps; + _steps = new long[stepsLength]; + + var expiredIndex = _expiredIndex; + var newStepIndex = 0; + while (newStepIndex < maxSteps && expiredIndex != _stepIndex) + { + _steps[newStepIndex++] = oldSteps[expiredIndex++]; + if (expiredIndex >= oldSteps.Length) + { + expiredIndex -= oldSteps.Length; + } + } + + _expiredIndex = 0; + _stepIndex = newStepIndex; } } diff --git a/Projects/UOContent/Network/FastwalkDetection.cs b/Projects/UOContent/Network/FastwalkDetection.cs new file mode 100644 index 000000000..4328f0f12 --- /dev/null +++ b/Projects/UOContent/Network/FastwalkDetection.cs @@ -0,0 +1,67 @@ +using System.Collections.Generic; +using Server.Commands.Generic; + +namespace Server.Network; + +public static class FastwalkDetection +{ + private static readonly HashSet _debugFastwalk = new(); + + public static void Initialize() + { + TargetCommands.Register(new DebugFastwalk()); + EventSink.FastWalk += OnFastwalk; + } + + private static void OnFastwalk(FastWalkEventArgs e) + { + var from = e.NetState.Mobile; + if (from == null) + { + return; + } + + if (!_debugFastwalk.Contains(from)) + { + return; + } + + from.PublicOverheadMessage(MessageType.Emote, from.EmoteHue, false, "Fastwalk Detected", accessLevel: AccessLevel.GameMaster); + } + + public class DebugFastwalk : BaseCommand + { + public DebugFastwalk() + { + AccessLevel = AccessLevel.GameMaster; + Supports = CommandSupport.AllMobiles; + Commands = new[] { "DebugFastwalk" }; + ObjectTypes = ObjectTypes.Mobiles; + ListOptimized = true; + Usage = "DebugFastwalk "; + Description = "Enables fastwalk debug messages"; + } + + public override void ExecuteList(CommandEventArgs e, List list) + { + var on = e.Arguments.Length == 0 || e.GetBoolean(0); + + foreach (var o in list) + { + if (o is not Mobile m) + { + continue; + } + + if (on) + { + _debugFastwalk.Add(m); + } + else + { + _debugFastwalk.Remove(m); + } + } + } + } +} From 651cffa872a214a9a15abdf782ae30bd3324534d Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 27 Feb 2022 03:10:35 -0800 Subject: [PATCH 086/213] fix: Cleans up mobile status packets (#835) * Removes Span2D for mobile moving. Instead uses pure math and simplifies the calculation. * Cleans up the extended mobile status packet. --- Projects/Server/Mobiles/Mobile.cs | 23 +++---- Projects/Server/Network/PacketUtilities.cs | 7 +- .../Network/Packets/OutgoingMobilePackets.cs | 66 ++++++++++--------- 3 files changed, 49 insertions(+), 47 deletions(-) diff --git a/Projects/Server/Mobiles/Mobile.cs b/Projects/Server/Mobiles/Mobile.cs index 84e12e759..b348f1041 100644 --- a/Projects/Server/Mobiles/Mobile.cs +++ b/Projects/Server/Mobiles/Mobile.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Runtime.CompilerServices; -using Microsoft.Toolkit.HighPerformance; using Server.Accounting; using Server.Buffers; using Server.ContextMenus; @@ -2961,13 +2960,12 @@ namespace Server ? OutgoingVirtualHairPackets.RemovePacketLength : OutgoingVirtualHairPackets.EquipUpdatePacketLength; - Span facialhairPacket = stackalloc byte[facialHairLength].InitializePacket(); + Span facialHairPacket = stackalloc byte[facialHairLength].InitializePacket(); const int cacheLength = OutgoingMobilePackets.MobileMovingPacketCacheByteLength; const int width = OutgoingMobilePackets.MobileMovingPacketLength; - const int height = OutgoingMobilePackets.MobileMovingPacketCacheHeight; - var mobileMovingCache = stackalloc byte[cacheLength].AsSpan2D(height, width).InitializePackets(); + var mobileMovingCache = stackalloc byte[cacheLength].InitializePackets(width); var ourState = m_NetState; @@ -3069,12 +3067,12 @@ namespace Server { if (removeFacialHair) { - OutgoingVirtualHairPackets.CreateRemoveHairPacket(facialhairPacket, facialHairSerial); + OutgoingVirtualHairPackets.CreateRemoveHairPacket(facialHairPacket, facialHairSerial); } else { OutgoingVirtualHairPackets.CreateHairEquipUpdatePacket( - facialhairPacket, + facialHairPacket, this, facialHairSerial, FacialHairItemID, @@ -3082,7 +3080,7 @@ namespace Server Layer.FacialHair ); } - ourState.Send(facialhairPacket); + ourState.Send(facialHairPacket); } if (sendOPLUpdate) @@ -3208,12 +3206,12 @@ namespace Server { if (removeFacialHair) { - OutgoingVirtualHairPackets.CreateRemoveHairPacket(facialhairPacket, facialHairSerial); + OutgoingVirtualHairPackets.CreateRemoveHairPacket(facialHairPacket, facialHairSerial); } else { OutgoingVirtualHairPackets.CreateHairEquipUpdatePacket( - facialhairPacket, + facialHairPacket, this, facialHairSerial, FacialHairItemID, @@ -3221,7 +3219,7 @@ namespace Server Layer.FacialHair ); } - state.Send(facialhairPacket); + state.Send(facialHairPacket); } SendOPLPacketTo(state); @@ -4472,10 +4470,9 @@ namespace Server eable.Free(); const int cacheLength = OutgoingMobilePackets.MobileMovingPacketCacheByteLength; - var width = OutgoingMobilePackets.MobileMovingPacketLength; - var height = OutgoingMobilePackets.MobileMovingPacketCacheHeight; + const int width = OutgoingMobilePackets.MobileMovingPacketLength; - var mobileMovingCache = stackalloc byte[cacheLength].AsSpan2D(height, width).InitializePackets(); + var mobileMovingCache = stackalloc byte[cacheLength].InitializePackets(width); foreach (var m in m_MoveClientList) { diff --git a/Projects/Server/Network/PacketUtilities.cs b/Projects/Server/Network/PacketUtilities.cs index f6fd7df14..320cda166 100644 --- a/Projects/Server/Network/PacketUtilities.cs +++ b/Projects/Server/Network/PacketUtilities.cs @@ -17,7 +17,6 @@ using System; using System.Buffers; using System.IO; using System.Runtime.CompilerServices; -using Microsoft.Toolkit.HighPerformance; namespace Server.Network { @@ -55,12 +54,12 @@ namespace Server.Network } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Span2D InitializePackets(this Span2D buffer) + public static Span InitializePackets(this Span buffer, int width) { #if NO_LOCAL_INIT - for (var i = 0; i < buffer.Height; i++) + for (var i = 0; i < buffer.Length; i += width) { - buffer.GetRowSpan(i)[0] = 0; + buffer[i] = 0; } #endif return buffer; diff --git a/Projects/Server/Network/Packets/OutgoingMobilePackets.cs b/Projects/Server/Network/Packets/OutgoingMobilePackets.cs index 751737fec..271af7d97 100644 --- a/Projects/Server/Network/Packets/OutgoingMobilePackets.cs +++ b/Projects/Server/Network/Packets/OutgoingMobilePackets.cs @@ -17,7 +17,6 @@ using System; using System.Buffers; using System.IO; using System.Runtime.CompilerServices; -using Microsoft.Toolkit.HighPerformance; namespace Server.Network; @@ -26,7 +25,7 @@ public static class OutgoingMobilePackets public const int BondedStatusPacketLength = 11; public const int DeathAnimationPacketLength = 13; public const int MobileMovingPacketLength = 17; - public const int MobileMovingPacketCacheHeight = 16; // 8 notoriety, 2 client versions + public const int MobileMovingPacketCacheHeight = 7 * 2; // 7 notoriety, 2 client versions public const int MobileMovingPacketCacheByteLength = MobileMovingPacketLength * MobileMovingPacketCacheHeight; public const int AttributeMaximum = 100; public const int MobileAttributePacketLength = 9; @@ -35,13 +34,16 @@ public static class OutgoingMobilePackets public const int NewMobileAnimationPacketLength = 10; public const int MobileHealthbarPacketLength = 12; public const int MobileStatusCompactLength = 43; - public const int MobileStatusMaxLength = 121; + public const int MobileStatusLength = 70; + public const int MobileStatusAOSLength = 88; + public const int MobileStatusMLLength = 91; + public const int MobileStatusHSLength = 121; - public static bool ExtendedStatus { get; set; } + public static bool ExtendedStatus { get; private set; } = true; - public static void Initialize() + public static void Configure() { - ExtendedStatus = ServerConfiguration.GetOrUpdateSetting("extendedStatus", false); + ExtendedStatus = ServerConfiguration.GetSetting("client.showExtendedStatus", true); } public static void CreateBondedStatus(Span buffer, Serial serial, bool bonded) @@ -144,12 +146,12 @@ public static class OutgoingMobilePackets } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void SendMobileMovingUsingCache(this NetState ns, Span2D cache, Mobile source, Mobile target) => + public static void SendMobileMovingUsingCache(this NetState ns, Span cache, Mobile source, Mobile target) => ns.SendMobileMovingUsingCache(cache, target, Notoriety.Compute(source, target)); - // Requires a buffer of 16 packets, 17bytes per packet (272 bytes). - // Requires cache to have the first byte of each packet zeroed. - public static void SendMobileMovingUsingCache(this NetState ns, Span2D cache, Mobile target, int noto) + // Requires a buffer of 14 packets, 17 bytes per packet (238 bytes). + // Requires cache to have the first byte of each packet initially zeroed. + public static void SendMobileMovingUsingCache(this NetState ns, Span cache, Mobile target, int noto) { if (ns.CannotSendPackets()) { @@ -157,8 +159,9 @@ public static class OutgoingMobilePackets } var stygianAbyss = ns.StygianAbyss; - var row = noto * 2 + (stygianAbyss ? 1 : 0); - var buffer = cache.GetRowSpan(row); + // Indexes 0-6 for pre-SA, and 7-13 for SA + var row = noto + (stygianAbyss ? 6 : -1); + var buffer = cache.Slice(row * MobileMovingPacketLength, MobileMovingPacketLength); CreateMobileMoving(buffer, target, noto, stygianAbyss); ns.Send(buffer); @@ -431,7 +434,7 @@ public static class OutgoingMobilePackets [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void CreateMobileStatusCompact(Span buffer, Mobile m, bool canBeRenamed) => - CreateMobileStatus(buffer, null, m, 0, canBeRenamed); + CreateMobileStatus(buffer, m, 0, canBeRenamed); public static void SendMobileStatusCompact(this NetState ns, Mobile m, bool canBeRenamed) { @@ -451,46 +454,50 @@ public static class OutgoingMobilePackets public static void SendMobileStatus(this NetState ns, Mobile beholder, Mobile beheld) { - if (ns == null || beheld == null) + if (ns.CannotSendPackets() || beheld == null) { return; } - Span buffer = stackalloc byte[MobileStatusMaxLength]; int version; + int length; if (beholder != beheld) { version = 0; + length = MobileStatusCompactLength; } - else if (Core.HS && ns.ExtendedStatus) + else if (ExtendedStatus && ns.ExtendedStatus) { version = 6; + length = MobileStatusHSLength; } else if (Core.ML && ns.SupportsExpansion(Expansion.ML)) { - /* - * For the ML era, the version value must be 5 if the original UO distribution - * is used and the client is not lower than version 5 - */ - version = ExtendedStatus ? 6 : 5; + version = 5; + length = MobileStatusMLLength; + } + else if (Core.AOS) + { + version = 4; + length = MobileStatusAOSLength; } else { - version = Core.AOS ? 4 : 3; + version = 3; + length = MobileStatusLength; } - var length = CreateMobileStatus(buffer, beholder, beheld, version, beheld.CanBeRenamedBy(beholder)); - ns.Send(buffer[..length]); + Span buffer = stackalloc byte[length]; + CreateMobileStatus(buffer, beheld, version, beheld.CanBeRenamedBy(beholder)); + ns.Send(buffer); } - public static int CreateMobileStatus( - Span buffer, Mobile beholder, Mobile beheld, int version, bool canBeRenamed - ) + public static void CreateMobileStatus(Span buffer, Mobile beheld, int version, bool canBeRenamed) { if (buffer[0] != 0) { - return buffer.Length; + return; } var name = beheld.Name ?? ""; @@ -507,7 +514,7 @@ public static class OutgoingMobilePackets if (version <= 0) { writer.WritePacketLength(); - return writer.Position; + return; } writer.Write(beheld.Female); @@ -563,7 +570,6 @@ public static class OutgoingMobilePackets } writer.WritePacketLength(); - return writer.Position; } public static void SendMobileUpdate(this NetState ns, Mobile m) From 77181678da687cad470b7d470bae2d9c5649614e Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 27 Feb 2022 03:18:17 -0800 Subject: [PATCH 087/213] fix: Converts BaseArmor and BaseClothing to use string crafter fields (#928) --- .../Items/Armor/BaseArmor.Migrations.cs | 165 +++++++++++++ Projects/UOContent/Items/Armor/BaseArmor.cs | 147 +----------- .../Items/Clothing/BaseClothing.Migrations.cs | 88 +++++++ .../UOContent/Items/Clothing/BaseClothing.cs | 87 +------ Projects/UOContent/Items/Misc/ArcaneGem.cs | 4 +- .../UOContent/Items/Weapons/BaseWeapon.cs | 5 +- .../Migrations/Server.Items.BaseArmor.v9.json | 216 ++++++++++++++++++ .../Server.Items.BaseClothing.v7.json | 99 ++++++++ .../Mobiles/Special/DummySpecific.cs | 58 ++--- 9 files changed, 610 insertions(+), 259 deletions(-) create mode 100644 Projects/UOContent/Items/Armor/BaseArmor.Migrations.cs create mode 100644 Projects/UOContent/Items/Clothing/BaseClothing.Migrations.cs create mode 100644 Projects/UOContent/Migrations/Server.Items.BaseArmor.v9.json create mode 100644 Projects/UOContent/Migrations/Server.Items.BaseClothing.v7.json diff --git a/Projects/UOContent/Items/Armor/BaseArmor.Migrations.cs b/Projects/UOContent/Items/Armor/BaseArmor.Migrations.cs new file mode 100644 index 000000000..2e4906f52 --- /dev/null +++ b/Projects/UOContent/Items/Armor/BaseArmor.Migrations.cs @@ -0,0 +1,165 @@ +using AMA = Server.Items.ArmorMeditationAllowance; + +namespace Server.Items; + +public partial class BaseArmor +{ + private void MigrateFrom(V8Content content) + { + _attributes = content.Attributes ?? AttributesDefaultValue(); + _armorAttributes = content.ArmorAttributes ?? ArmorAttributesDefaultValue(); + _physicalBonus = content.PhysicalBonus ?? 0; + _fireBonus = content.FireBonus ?? 0; + _coldBonus = content.ColdBonus ?? 0; + _poisonBonus = content.PoisonBonus ?? 0; + _energyBonus = content.EnergyBonus ?? 0; + _identified = content.Identified; + _maxHitPoints = content.MaxHitPoints ?? 0; + _hitPoints = content.HitPoints ?? 0; + _crafter = content.Crafter?.RawName; // Convert from Mobile -> String via RawName + _quality = content.Quality ?? ArmorQuality.Regular; + _durability = content.Durability ?? ArmorDurabilityLevel.Regular; + _rawResource = content.RawResource ?? DefaultResource; + _armorBase = content.BaseArmorRating ?? -1; + _strBonus = content.StrBonus ?? -1; + _dexBonus = content.DexBonus ?? -1; + _intBonus = content.IntBonus ?? -1; + _strReq = content.StrRequirement ?? -1; + _dexReq = content.DexRequirement ?? -1; + _intReq = content.IntRequirement ?? -1; + _meditate = content.MeditationAllowance ?? (AMA)(-1); + _skillBonuses = content.SkillBonuses ?? SkillBonusesDefaultValue(); + _playerConstructed = content.PlayerConstructed; + } + + // Version 7 (pre-codegen) + private void Deserialize(IGenericReader reader, int version) + { + var flags = (OldSaveFlag)reader.ReadEncodedInt(); + + Attributes = new AosAttributes(this); + + if (GetSaveFlag(flags, OldSaveFlag.Attributes)) + { + Attributes.Deserialize(reader); + } + + ArmorAttributes = new AosArmorAttributes(this); + + if (GetSaveFlag(flags, OldSaveFlag.ArmorAttributes)) + { + ArmorAttributes.Deserialize(reader); + } + + if (GetSaveFlag(flags, OldSaveFlag.PhysicalBonus)) + { + _physicalBonus = reader.ReadEncodedInt(); + } + + if (GetSaveFlag(flags, OldSaveFlag.FireBonus)) + { + _fireBonus = reader.ReadEncodedInt(); + } + + if (GetSaveFlag(flags, OldSaveFlag.ColdBonus)) + { + _coldBonus = reader.ReadEncodedInt(); + } + + if (GetSaveFlag(flags, OldSaveFlag.PoisonBonus)) + { + _poisonBonus = reader.ReadEncodedInt(); + } + + if (GetSaveFlag(flags, OldSaveFlag.EnergyBonus)) + { + _energyBonus = reader.ReadEncodedInt(); + } + + _identified = GetSaveFlag(flags, OldSaveFlag.Identified); + + if (GetSaveFlag(flags, OldSaveFlag.MaxHitPoints)) + { + _maxHitPoints = reader.ReadEncodedInt(); + } + + if (GetSaveFlag(flags, OldSaveFlag.HitPoints)) + { + _hitPoints = reader.ReadEncodedInt(); + } + + if (GetSaveFlag(flags, OldSaveFlag.Crafter)) + { + _crafter = reader.ReadEntity()?.RawName; + } + + if (GetSaveFlag(flags, OldSaveFlag.Quality)) + { + _quality = (ArmorQuality)reader.ReadEncodedInt(); + } + + if (GetSaveFlag(flags, OldSaveFlag.Durability)) + { + _durability = (ArmorDurabilityLevel)reader.ReadEncodedInt(); + } + + if (GetSaveFlag(flags, OldSaveFlag.Protection)) + { + _protection = (ArmorProtectionLevel)reader.ReadEncodedInt(); + } + + if (GetSaveFlag(flags, OldSaveFlag.Resource)) + { + _rawResource = (CraftResource)reader.ReadEncodedInt(); + } + + if (GetSaveFlag(flags, OldSaveFlag.BaseArmor)) + { + _armorBase = reader.ReadEncodedInt(); + } + + if (GetSaveFlag(flags, OldSaveFlag.StrBonus)) + { + _strBonus = reader.ReadEncodedInt(); + } + + if (GetSaveFlag(flags, OldSaveFlag.DexBonus)) + { + _dexBonus = reader.ReadEncodedInt(); + } + + if (GetSaveFlag(flags, OldSaveFlag.IntBonus)) + { + _intBonus = reader.ReadEncodedInt(); + } + + if (GetSaveFlag(flags, OldSaveFlag.StrReq)) + { + _strReq = reader.ReadEncodedInt(); + } + + if (GetSaveFlag(flags, OldSaveFlag.DexReq)) + { + _dexReq = reader.ReadEncodedInt(); + } + + if (GetSaveFlag(flags, OldSaveFlag.IntReq)) + { + _intReq = reader.ReadEncodedInt(); + } + + if (GetSaveFlag(flags, OldSaveFlag.MedAllowance)) + { + _meditate = (AMA)reader.ReadEncodedInt(); + } + + SkillBonuses = new AosSkillBonuses(this); + + if (GetSaveFlag(flags, OldSaveFlag.SkillBonuses)) + { + SkillBonuses.Deserialize(reader); + } + + PlayerConstructed = GetSaveFlag(flags, OldSaveFlag.PlayerConstructed); + } +} diff --git a/Projects/UOContent/Items/Armor/BaseArmor.cs b/Projects/UOContent/Items/Armor/BaseArmor.cs index dd79ac923..faba5062c 100644 --- a/Projects/UOContent/Items/Armor/BaseArmor.cs +++ b/Projects/UOContent/Items/Armor/BaseArmor.cs @@ -10,7 +10,7 @@ using AMT = Server.Items.ArmorMaterialType; namespace Server.Items { - [Serializable(8, false)] + [Serializable(9, false)] public abstract partial class BaseArmor : Item, IScissorable, IFactionItem, ICraftable, IWearableDurability { [SerializableField(0, setter: "private")] @@ -99,7 +99,7 @@ namespace Server.Items [InvalidateProperties] [SerializableField(10)] [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] - private Mobile _crafter; + private string _crafter; [SerializableFieldSaveFlag(10)] private bool ShouldSerializeCrafter() => _crafter != null; @@ -572,7 +572,7 @@ namespace Server.Items if (makersMark) { - Crafter = from; + Crafter = from.RawName; } var resourceType = typeRes ?? craftItem.Resources[0].ItemType; @@ -1076,143 +1076,6 @@ namespace Server.Items m?.CheckStatTimers(); } - private void Deserialize(IGenericReader reader, int version) - { - var flags = (OldSaveFlag)reader.ReadEncodedInt(); - - Attributes = new AosAttributes(this); - - if (GetSaveFlag(flags, OldSaveFlag.Attributes)) - { - Attributes.Deserialize(reader); - } - - ArmorAttributes = new AosArmorAttributes(this); - - if (GetSaveFlag(flags, OldSaveFlag.ArmorAttributes)) - { - ArmorAttributes.Deserialize(reader); - } - - if (GetSaveFlag(flags, OldSaveFlag.PhysicalBonus)) - { - _physicalBonus = reader.ReadEncodedInt(); - } - - if (GetSaveFlag(flags, OldSaveFlag.FireBonus)) - { - _fireBonus = reader.ReadEncodedInt(); - } - - if (GetSaveFlag(flags, OldSaveFlag.ColdBonus)) - { - _coldBonus = reader.ReadEncodedInt(); - } - - if (GetSaveFlag(flags, OldSaveFlag.PoisonBonus)) - { - _poisonBonus = reader.ReadEncodedInt(); - } - - if (GetSaveFlag(flags, OldSaveFlag.EnergyBonus)) - { - _energyBonus = reader.ReadEncodedInt(); - } - - _identified = GetSaveFlag(flags, OldSaveFlag.Identified); - - if (GetSaveFlag(flags, OldSaveFlag.MaxHitPoints)) - { - _maxHitPoints = reader.ReadEncodedInt(); - } - - if (GetSaveFlag(flags, OldSaveFlag.HitPoints)) - { - _hitPoints = reader.ReadEncodedInt(); - } - - if (GetSaveFlag(flags, OldSaveFlag.Crafter)) - { - _crafter = reader.ReadEntity(); - } - - if (GetSaveFlag(flags, OldSaveFlag.Quality)) - { - _quality = (ArmorQuality)reader.ReadEncodedInt(); - } - else - { - _quality = ArmorQuality.Regular; - } - - if (GetSaveFlag(flags, OldSaveFlag.Durability)) - { - _durability = (ArmorDurabilityLevel)reader.ReadEncodedInt(); - } - - if (GetSaveFlag(flags, OldSaveFlag.Protection)) - { - _protection = (ArmorProtectionLevel)reader.ReadEncodedInt(); - } - - if (GetSaveFlag(flags, OldSaveFlag.Resource)) - { - _rawResource = (CraftResource)reader.ReadEncodedInt(); - } - - if (GetSaveFlag(flags, OldSaveFlag.BaseArmor)) - { - _armorBase = reader.ReadEncodedInt(); - } - - if (GetSaveFlag(flags, OldSaveFlag.StrBonus)) - { - _strBonus = reader.ReadEncodedInt(); - } - - if (GetSaveFlag(flags, OldSaveFlag.DexBonus)) - { - _dexBonus = reader.ReadEncodedInt(); - } - - if (GetSaveFlag(flags, OldSaveFlag.IntBonus)) - { - _intBonus = reader.ReadEncodedInt(); - } - - if (GetSaveFlag(flags, OldSaveFlag.StrReq)) - { - _strReq = reader.ReadEncodedInt(); - } - - if (GetSaveFlag(flags, OldSaveFlag.DexReq)) - { - _dexReq = reader.ReadEncodedInt(); - } - - if (GetSaveFlag(flags, OldSaveFlag.IntReq)) - { - _intReq = reader.ReadEncodedInt(); - } - - if (GetSaveFlag(flags, OldSaveFlag.MedAllowance)) - { - _meditate = (AMA)reader.ReadEncodedInt(); - } - - SkillBonuses = new AosSkillBonuses(this); - - if (GetSaveFlag(flags, OldSaveFlag.SkillBonuses)) - { - SkillBonuses.Deserialize(reader); - } - - if (GetSaveFlag(flags, OldSaveFlag.PlayerConstructed)) - { - PlayerConstructed = true; - } - } - public override bool AllowSecureTrade(Mobile from, Mobile to, Mobile newOwner, bool accepted) { if (!Ethic.CheckTrade(from, to, newOwner, this)) @@ -1431,7 +1294,7 @@ namespace Server.Items if (_crafter != null) { - list.Add(1050043, _crafter.Name); // crafted by ~1_NAME~ + list.Add(1050043, _crafter); // crafted by ~1_NAME~ } if (m_FactionState != null) @@ -1672,7 +1535,7 @@ namespace Server.Items return; } - from.NetState.SendDisplayEquipmentInfo(Serial, number, _crafter?.RawName, false, attrs); + from.NetState.SendDisplayEquipmentInfo(Serial, number, _crafter, false, attrs); } [Flags] diff --git a/Projects/UOContent/Items/Clothing/BaseClothing.Migrations.cs b/Projects/UOContent/Items/Clothing/BaseClothing.Migrations.cs new file mode 100644 index 000000000..1278b0db2 --- /dev/null +++ b/Projects/UOContent/Items/Clothing/BaseClothing.Migrations.cs @@ -0,0 +1,88 @@ +namespace Server.Items; + +public partial class BaseClothing +{ + private void MigrateFrom(V6Content content) + { + _rawResource = content.RawResource ?? DefaultResource; + _attributes = content.Attributes ?? AttributesDefaultValue(); + _clothingAttributes = content.ClothingAttributes ?? ClothingAttributesDefaultValue(); + _skillBonuses = content.SkillBonuses ?? SkillBonusesDefaultValue(); + _resistances = content.Resistances ?? ResistancesDefaultValue(); + _maxHitPoints = content.MaxHitPoints ?? 0; + _playerConstructed = content.PlayerConstructed; + _crafter = content.Crafter?.RawName; // Convert from Mobile -> String via RawName + _quality = content.Quality ?? ClothingQuality.Regular; + _strReq = content.StrRequirement ?? -1; + } + + // Version 5 (pre-codegen) + private void Deserialize(IGenericReader reader, int version) + { + var flags = (OldSaveFlag)reader.ReadEncodedInt(); + + if (GetSaveFlag(flags, OldSaveFlag.Resource)) + { + _rawResource = (CraftResource)reader.ReadEncodedInt(); + } + else + { + _rawResource = DefaultResource; + } + + Attributes = new AosAttributes(this); + + if (GetSaveFlag(flags, OldSaveFlag.Attributes)) + { + Attributes.Deserialize(reader); + } + + ClothingAttributes = new AosArmorAttributes(this); + + if (GetSaveFlag(flags, OldSaveFlag.ClothingAttributes)) + { + ClothingAttributes.Deserialize(reader); + } + + SkillBonuses = new AosSkillBonuses(this); + + if (GetSaveFlag(flags, OldSaveFlag.SkillBonuses)) + { + SkillBonuses.Deserialize(reader); + } + + Resistances = new AosElementAttributes(this); + + if (GetSaveFlag(flags, OldSaveFlag.Resistances)) + { + Resistances.Deserialize(reader); + } + + if (GetSaveFlag(flags, OldSaveFlag.MaxHitPoints)) + { + _maxHitPoints = reader.ReadEncodedInt(); + } + + if (GetSaveFlag(flags, OldSaveFlag.HitPoints)) + { + _hitPoints = reader.ReadEncodedInt(); + } + + if (GetSaveFlag(flags, OldSaveFlag.Crafter)) + { + _crafter = reader.ReadEntity()?.RawName; + } + + if (GetSaveFlag(flags, OldSaveFlag.Quality)) + { + _quality = (ClothingQuality)reader.ReadEncodedInt(); + } + + if (GetSaveFlag(flags, OldSaveFlag.StrReq)) + { + _strReq = reader.ReadEncodedInt(); + } + + PlayerConstructed = GetSaveFlag(flags, OldSaveFlag.PlayerConstructed); + } +} diff --git a/Projects/UOContent/Items/Clothing/BaseClothing.cs b/Projects/UOContent/Items/Clothing/BaseClothing.cs index 251d86ad0..90070675e 100644 --- a/Projects/UOContent/Items/Clothing/BaseClothing.cs +++ b/Projects/UOContent/Items/Clothing/BaseClothing.cs @@ -22,7 +22,7 @@ namespace Server.Items int MaxArcaneCharges { get; set; } } - [Serializable(6, false)] + [Serializable(7, false)] public abstract partial class BaseClothing : Item, IDyable, IScissorable, IFactionItem, ICraftable, IWearableDurability { [SerializableField(0, "private", "private")] @@ -93,7 +93,7 @@ namespace Server.Items [InvalidateProperties] [SerializableField(8)] [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] - private Mobile _crafter; + private string _crafter; [SerializableFieldSaveFlag(8)] private bool ShouldSerializeCrafter() => _crafter != null; @@ -193,7 +193,7 @@ namespace Server.Items if (makersMark) { - Crafter = from; + Crafter = from.RawName; } if (DefaultResource != CraftResource.None) @@ -699,7 +699,7 @@ namespace Server.Items if (_crafter != null) { - list.Add(1050043, _crafter.Name); // crafted by ~1_NAME~ + list.Add(1050043, _crafter); // crafted by ~1_NAME~ } if (_factionState != null) @@ -907,7 +907,7 @@ namespace Server.Items return; } - from.NetState.SendDisplayEquipmentInfo(Serial, number, _crafter?.RawName, false, attrs); + from.NetState.SendDisplayEquipmentInfo(Serial, number, _crafter, false, attrs); } public virtual void AddEquipInfoAttributes(Mobile from, List attrs) @@ -964,83 +964,6 @@ namespace Server.Items private static bool GetSaveFlag(OldSaveFlag flags, OldSaveFlag toGet) => (flags & toGet) != 0; - private void Deserialize(IGenericReader reader, int version) - { - var flags = (OldSaveFlag)reader.ReadEncodedInt(); - - if (GetSaveFlag(flags, OldSaveFlag.Resource)) - { - _rawResource = (CraftResource)reader.ReadEncodedInt(); - } - else - { - _rawResource = DefaultResource; - } - - Attributes = new AosAttributes(this); - - if (GetSaveFlag(flags, OldSaveFlag.Attributes)) - { - Attributes.Deserialize(reader); - } - - ClothingAttributes = new AosArmorAttributes(this); - - if (GetSaveFlag(flags, OldSaveFlag.ClothingAttributes)) - { - ClothingAttributes.Deserialize(reader); - } - - SkillBonuses = new AosSkillBonuses(this); - - if (GetSaveFlag(flags, OldSaveFlag.SkillBonuses)) - { - SkillBonuses.Deserialize(reader); - } - - Resistances = new AosElementAttributes(this); - - if (GetSaveFlag(flags, OldSaveFlag.Resistances)) - { - Resistances.Deserialize(reader); - } - - if (GetSaveFlag(flags, OldSaveFlag.MaxHitPoints)) - { - _maxHitPoints = reader.ReadEncodedInt(); - } - - if (GetSaveFlag(flags, OldSaveFlag.HitPoints)) - { - _hitPoints = reader.ReadEncodedInt(); - } - - if (GetSaveFlag(flags, OldSaveFlag.Crafter)) - { - _crafter = reader.ReadEntity(); - } - - if (GetSaveFlag(flags, OldSaveFlag.Quality)) - { - _quality = (ClothingQuality)reader.ReadEncodedInt(); - } - else - { - _quality = ClothingQuality.Regular; - } - - if (GetSaveFlag(flags, OldSaveFlag.StrReq)) - { - _strReq = reader.ReadEncodedInt(); - } - else - { - _strReq = -1; - } - - PlayerConstructed = GetSaveFlag(flags, OldSaveFlag.PlayerConstructed); - } - [AfterDeserialization] private void AfterDeserialization() { diff --git a/Projects/UOContent/Items/Misc/ArcaneGem.cs b/Projects/UOContent/Items/Misc/ArcaneGem.cs index 5da64655f..c287efe35 100644 --- a/Projects/UOContent/Items/Misc/ArcaneGem.cs +++ b/Projects/UOContent/Items/Misc/ArcaneGem.cs @@ -126,12 +126,12 @@ namespace Server.Items if (clothing != null) { clothing.Quality = ClothingQuality.Regular; - clothing.Crafter = from; + clothing.Crafter = from.RawName; } else if (armor != null) { armor.Quality = ArmorQuality.Regular; - armor.Crafter = from; + armor.Crafter = from.RawName; armor.PhysicalBonus = armor.FireBonus = armor.ColdBonus = diff --git a/Projects/UOContent/Items/Weapons/BaseWeapon.cs b/Projects/UOContent/Items/Weapons/BaseWeapon.cs index 2b7b4fd06..43b45990c 100644 --- a/Projects/UOContent/Items/Weapons/BaseWeapon.cs +++ b/Projects/UOContent/Items/Weapons/BaseWeapon.cs @@ -3971,10 +3971,7 @@ namespace Server.Items parentMobile.AddSkillMod(m_MageMod); } - if (GetSaveFlag(flags, SaveFlag.PlayerConstructed)) - { - PlayerConstructed = true; - } + PlayerConstructed = GetSaveFlag(flags, SaveFlag.PlayerConstructed); SkillBonuses = new AosSkillBonuses(this); diff --git a/Projects/UOContent/Migrations/Server.Items.BaseArmor.v9.json b/Projects/UOContent/Migrations/Server.Items.BaseArmor.v9.json new file mode 100644 index 000000000..56579b4a3 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.BaseArmor.v9.json @@ -0,0 +1,216 @@ +{ + "version": 9, + "type": "Server.Items.BaseArmor", + "properties": [ + { + "name": "Attributes", + "type": "Server.AosAttributes", + "usesSaveFlag": true, + "rule": "RawSerializableMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "ArmorAttributes", + "type": "Server.AosArmorAttributes", + "usesSaveFlag": true, + "rule": "RawSerializableMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "PhysicalBonus", + "type": "int", + "usesSaveFlag": true, + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "EncodedInt" + ] + }, + { + "name": "FireBonus", + "type": "int", + "usesSaveFlag": true, + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "EncodedInt" + ] + }, + { + "name": "ColdBonus", + "type": "int", + "usesSaveFlag": true, + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "EncodedInt" + ] + }, + { + "name": "PoisonBonus", + "type": "int", + "usesSaveFlag": true, + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "EncodedInt" + ] + }, + { + "name": "EnergyBonus", + "type": "int", + "usesSaveFlag": true, + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "EncodedInt" + ] + }, + { + "name": "Identified", + "type": "bool", + "usesSaveFlag": true, + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "MaxHitPoints", + "type": "int", + "usesSaveFlag": true, + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "EncodedInt" + ] + }, + { + "name": "HitPoints", + "type": "int", + "usesSaveFlag": true, + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "EncodedInt" + ] + }, + { + "name": "Crafter", + "type": "string", + "usesSaveFlag": true, + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "Quality", + "type": "Server.Items.ArmorQuality", + "usesSaveFlag": true, + "rule": "EnumMigrationRule" + }, + { + "name": "Durability", + "type": "Server.Items.ArmorDurabilityLevel", + "usesSaveFlag": true, + "rule": "EnumMigrationRule" + }, + { + "name": "ProtectionLevel", + "type": "Server.Items.ArmorProtectionLevel", + "usesSaveFlag": true, + "rule": "EnumMigrationRule" + }, + { + "name": "RawResource", + "type": "Server.Items.CraftResource", + "usesSaveFlag": true, + "rule": "EnumMigrationRule" + }, + { + "name": "BaseArmorRating", + "type": "int", + "usesSaveFlag": true, + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "EncodedInt" + ] + }, + { + "name": "StrBonus", + "type": "int", + "usesSaveFlag": true, + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "EncodedInt" + ] + }, + { + "name": "DexBonus", + "type": "int", + "usesSaveFlag": true, + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "EncodedInt" + ] + }, + { + "name": "IntBonus", + "type": "int", + "usesSaveFlag": true, + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "EncodedInt" + ] + }, + { + "name": "StrRequirement", + "type": "int", + "usesSaveFlag": true, + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "EncodedInt" + ] + }, + { + "name": "DexRequirement", + "type": "int", + "usesSaveFlag": true, + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "EncodedInt" + ] + }, + { + "name": "IntRequirement", + "type": "int", + "usesSaveFlag": true, + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "EncodedInt" + ] + }, + { + "name": "MeditationAllowance", + "type": "Server.Items.ArmorMeditationAllowance", + "usesSaveFlag": true, + "rule": "EnumMigrationRule" + }, + { + "name": "SkillBonuses", + "type": "Server.AosSkillBonuses", + "usesSaveFlag": true, + "rule": "RawSerializableMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "PlayerConstructed", + "type": "bool", + "usesSaveFlag": true, + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.BaseClothing.v7.json b/Projects/UOContent/Migrations/Server.Items.BaseClothing.v7.json new file mode 100644 index 000000000..ade6ff6cb --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.BaseClothing.v7.json @@ -0,0 +1,99 @@ +{ + "version": 7, + "type": "Server.Items.BaseClothing", + "properties": [ + { + "name": "RawResource", + "type": "Server.Items.CraftResource", + "usesSaveFlag": true, + "rule": "EnumMigrationRule" + }, + { + "name": "Attributes", + "type": "Server.AosAttributes", + "usesSaveFlag": true, + "rule": "RawSerializableMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "ClothingAttributes", + "type": "Server.AosArmorAttributes", + "usesSaveFlag": true, + "rule": "RawSerializableMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "SkillBonuses", + "type": "Server.AosSkillBonuses", + "usesSaveFlag": true, + "rule": "RawSerializableMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "Resistances", + "type": "Server.AosElementAttributes", + "usesSaveFlag": true, + "rule": "RawSerializableMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "MaxHitPoints", + "type": "int", + "usesSaveFlag": true, + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "EncodedInt" + ] + }, + { + "name": "HitPoints", + "type": "int", + "usesSaveFlag": true, + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "EncodedInt" + ] + }, + { + "name": "PlayerConstructed", + "type": "bool", + "usesSaveFlag": true, + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "Crafter", + "type": "string", + "usesSaveFlag": true, + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "Quality", + "type": "Server.Items.ClothingQuality", + "usesSaveFlag": true, + "rule": "EnumMigrationRule" + }, + { + "name": "StrRequirement", + "type": "int", + "usesSaveFlag": true, + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Mobiles/Special/DummySpecific.cs b/Projects/UOContent/Mobiles/Special/DummySpecific.cs index fc064c378..560de2b43 100644 --- a/Projects/UOContent/Mobiles/Special/DummySpecific.cs +++ b/Projects/UOContent/Mobiles/Special/DummySpecific.cs @@ -42,21 +42,21 @@ namespace Server.Mobiles var cht = new ChainChest(); cht.Movable = false; cht.LootType = LootType.Newbied; - cht.Crafter = this; + cht.Crafter = RawName; cht.Quality = ArmorQuality.Regular; AddItem(cht); var chl = new ChainLegs(); chl.Movable = false; chl.LootType = LootType.Newbied; - chl.Crafter = this; + chl.Crafter = RawName; chl.Quality = ArmorQuality.Regular; AddItem(chl); var pla = new PlateArms(); pla.Movable = false; pla.LootType = LootType.Newbied; - pla.Crafter = this; + pla.Crafter = RawName; pla.Quality = ArmorQuality.Regular; AddItem(pla); @@ -116,21 +116,21 @@ namespace Server.Mobiles var cht = new ChainChest(); cht.Movable = false; cht.LootType = LootType.Newbied; - cht.Crafter = this; + cht.Crafter = RawName; cht.Quality = ArmorQuality.Regular; AddItem(cht); var chl = new ChainLegs(); chl.Movable = false; chl.LootType = LootType.Newbied; - chl.Crafter = this; + chl.Crafter = RawName; chl.Quality = ArmorQuality.Regular; AddItem(chl); var pla = new PlateArms(); pla.Movable = false; pla.LootType = LootType.Newbied; - pla.Crafter = this; + pla.Crafter = RawName; pla.Quality = ArmorQuality.Regular; AddItem(pla); @@ -190,21 +190,21 @@ namespace Server.Mobiles var cht = new ChainChest(); cht.Movable = false; cht.LootType = LootType.Newbied; - cht.Crafter = this; + cht.Crafter = RawName; cht.Quality = ArmorQuality.Regular; AddItem(cht); var chl = new ChainLegs(); chl.Movable = false; chl.LootType = LootType.Newbied; - chl.Crafter = this; + chl.Crafter = RawName; chl.Quality = ArmorQuality.Regular; AddItem(chl); var pla = new PlateArms(); pla.Movable = false; pla.LootType = LootType.Newbied; - pla.Crafter = this; + pla.Crafter = RawName; pla.Quality = ArmorQuality.Regular; AddItem(pla); @@ -328,28 +328,28 @@ namespace Server.Mobiles var lea = new LeatherArms(); lea.Movable = false; lea.LootType = LootType.Newbied; - lea.Crafter = this; + lea.Crafter = RawName; lea.Quality = ArmorQuality.Regular; AddItem(lea); var lec = new LeatherChest(); lec.Movable = false; lec.LootType = LootType.Newbied; - lec.Crafter = this; + lec.Crafter = RawName; lec.Quality = ArmorQuality.Regular; AddItem(lec); var leg = new LeatherGorget(); leg.Movable = false; leg.LootType = LootType.Newbied; - leg.Crafter = this; + leg.Crafter = RawName; leg.Quality = ArmorQuality.Regular; AddItem(leg); var lel = new LeatherLegs(); lel.Movable = false; lel.LootType = LootType.Newbied; - lel.Crafter = this; + lel.Crafter = RawName; lel.Quality = ArmorQuality.Regular; AddItem(lel); @@ -419,28 +419,28 @@ namespace Server.Mobiles var lea = new LeatherArms(); lea.Movable = false; lea.LootType = LootType.Newbied; - lea.Crafter = this; + lea.Crafter = RawName; lea.Quality = ArmorQuality.Regular; AddItem(lea); var lec = new LeatherChest(); lec.Movable = false; lec.LootType = LootType.Newbied; - lec.Crafter = this; + lec.Crafter = RawName; lec.Quality = ArmorQuality.Regular; AddItem(lec); var leg = new LeatherGorget(); leg.Movable = false; leg.LootType = LootType.Newbied; - leg.Crafter = this; + leg.Crafter = RawName; leg.Quality = ArmorQuality.Regular; AddItem(leg); var lel = new LeatherLegs(); lel.Movable = false; lel.LootType = LootType.Newbied; - lel.Crafter = this; + lel.Crafter = RawName; lel.Quality = ArmorQuality.Regular; AddItem(lel); @@ -514,28 +514,28 @@ namespace Server.Mobiles var lea = new LeatherArms(); lea.Movable = false; lea.LootType = LootType.Newbied; - lea.Crafter = this; + lea.Crafter = RawName; lea.Quality = ArmorQuality.Regular; AddItem(lea); var lec = new LeatherChest(); lec.Movable = false; lec.LootType = LootType.Newbied; - lec.Crafter = this; + lec.Crafter = RawName; lec.Quality = ArmorQuality.Regular; AddItem(lec); var leg = new LeatherGorget(); leg.Movable = false; leg.LootType = LootType.Newbied; - leg.Crafter = this; + leg.Crafter = RawName; leg.Quality = ArmorQuality.Regular; AddItem(leg); var lel = new LeatherLegs(); lel.Movable = false; lel.LootType = LootType.Newbied; - lel.Crafter = this; + lel.Crafter = RawName; lel.Quality = ArmorQuality.Regular; AddItem(lel); @@ -611,28 +611,28 @@ namespace Server.Mobiles var lea = new LeatherArms(); lea.Movable = false; lea.LootType = LootType.Newbied; - lea.Crafter = this; + lea.Crafter = RawName; lea.Quality = ArmorQuality.Regular; AddItem(lea); var lec = new LeatherChest(); lec.Movable = false; lec.LootType = LootType.Newbied; - lec.Crafter = this; + lec.Crafter = RawName; lec.Quality = ArmorQuality.Regular; AddItem(lec); var leg = new LeatherGorget(); leg.Movable = false; leg.LootType = LootType.Newbied; - leg.Crafter = this; + leg.Crafter = RawName; leg.Quality = ArmorQuality.Regular; AddItem(leg); var lel = new LeatherLegs(); lel.Movable = false; lel.LootType = LootType.Newbied; - lel.Crafter = this; + lel.Crafter = RawName; lel.Quality = ArmorQuality.Regular; AddItem(lel); @@ -719,28 +719,28 @@ namespace Server.Mobiles var lea = new LeatherArms(); lea.Movable = false; lea.LootType = LootType.Newbied; - lea.Crafter = this; + lea.Crafter = RawName; lea.Quality = ArmorQuality.Regular; AddItem(lea); var lec = new LeatherChest(); lec.Movable = false; lec.LootType = LootType.Newbied; - lec.Crafter = this; + lec.Crafter = RawName; lec.Quality = ArmorQuality.Regular; AddItem(lec); var leg = new LeatherGorget(); leg.Movable = false; leg.LootType = LootType.Newbied; - leg.Crafter = this; + leg.Crafter = RawName; leg.Quality = ArmorQuality.Regular; AddItem(leg); var lel = new LeatherLegs(); lel.Movable = false; lel.LootType = LootType.Newbied; - lel.Crafter = this; + lel.Crafter = RawName; lel.Quality = ArmorQuality.Regular; AddItem(lel); From 003ad1164f6127ef7145946c9f4aa30cb71ed6c5 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 27 Feb 2022 17:01:49 -0800 Subject: [PATCH 088/213] fix: Codegens containers (#946) --- .../UOContent/Items/Containers/Container.cs | 1376 ++++++----------- .../Migrations/Server.Items.Backpack.v0.json | 4 + .../Migrations/Server.Items.Bag.v0.json | 4 + .../Migrations/Server.Items.Barrel.v0.json | 4 + .../Server.Items.BaseBagBall.v0.json | 4 + .../Migrations/Server.Items.Basket.v0.json | 4 + .../Server.Items.CreatureBackpack.v0.json | 4 + .../Server.Items.FinishedWoodenChest.v0.json | 4 + .../Server.Items.GildedWoodenChest.v0.json | 4 + .../Migrations/Server.Items.Keg.v0.json | 4 + .../Server.Items.LargeBagBall.v0.json | 4 + .../Server.Items.LargeCrate.v0.json | 4 + .../Server.Items.MediumCrate.v0.json | 4 + .../Migrations/Server.Items.MetalBox.v0.json | 4 + .../Server.Items.MetalChest.v0.json | 4 + .../Server.Items.MetalGoldenChest.v0.json | 4 + .../Server.Items.OrnateWoodenChest.v0.json | 4 + .../Server.Items.PicnicBasket.v0.json | 4 + .../Server.Items.PlainWoodenChest.v0.json | 4 + .../Migrations/Server.Items.Pouch.v0.json | 4 + .../Server.Items.SmallBagBall.v0.json | 4 + .../Server.Items.SmallCrate.v0.json | 4 + .../Server.Items.StrongBackpack.v0.json | 4 + .../Migrations/Server.Items.WoodenBox.v0.json | 4 + .../Server.Items.WoodenChest.v0.json | 4 + .../Server.Items.WoodenFootLocker.v0.json | 4 + 26 files changed, 534 insertions(+), 942 deletions(-) create mode 100644 Projects/UOContent/Migrations/Server.Items.Backpack.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Bag.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Barrel.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.BaseBagBall.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Basket.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.CreatureBackpack.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.FinishedWoodenChest.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.GildedWoodenChest.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Keg.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.LargeBagBall.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.LargeCrate.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.MediumCrate.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.MetalBox.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.MetalChest.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.MetalGoldenChest.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.OrnateWoodenChest.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.PicnicBasket.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.PlainWoodenChest.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Pouch.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.SmallBagBall.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.SmallCrate.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.StrongBackpack.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.WoodenBox.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.WoodenChest.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.WoodenFootLocker.v0.json diff --git a/Projects/UOContent/Items/Containers/Container.cs b/Projects/UOContent/Items/Containers/Container.cs index 1fce1751a..eea535f1e 100644 --- a/Projects/UOContent/Items/Containers/Container.cs +++ b/Projects/UOContent/Items/Containers/Container.cs @@ -4,1013 +4,505 @@ using Server.Mobiles; using Server.Multis; using Server.Network; -namespace Server.Items +namespace Server.Items; + +[ManualDirtyChecking] +public abstract class BaseContainer : Container { - public abstract class BaseContainer : Container + public BaseContainer(int itemID) : base(itemID) { - public BaseContainer(int itemID) : base(itemID) - { - } - - public BaseContainer(Serial serial) : base(serial) - { - } - - public override int DefaultMaxWeight => IsSecure ? 0 : base.DefaultMaxWeight; - - public override bool IsAccessibleTo(Mobile m) => BaseHouse.CheckAccessible(m, this) && base.IsAccessibleTo(m); - - public override bool CheckHold(Mobile m, Item item, bool message, bool checkItems, int plusItems, int plusWeight) - { - if (IsSecure && !BaseHouse.CheckHold(m, this, item, message, checkItems, plusItems, plusWeight)) - { - return false; - } - - return base.CheckHold(m, item, message, checkItems, plusItems, plusWeight); - } - - public override bool CheckItemUse(Mobile from, Item item) - { - if (IsDecoContainer && item is BaseBook) - { - return true; - } - - return base.CheckItemUse(from, item); - } - - public override void GetContextMenuEntries(Mobile from, List list) - { - base.GetContextMenuEntries(from, list); - SetSecureLevelEntry.AddTo(from, this, list); - } - - public override bool TryDropItem(Mobile from, Item dropped, bool sendFullMessage) - { - if (!CheckHold(from, dropped, sendFullMessage, true)) - { - return false; - } - - var house = BaseHouse.FindHouseAt(this); - - if (house?.HasLockedDownItem(this) == true) - { - if (dropped is VendorRentalContract || dropped is Container container && - container.FindItemByType() != null) - { - from.SendLocalizedMessage(1062492); // You cannot place a rental contract in a locked down container. - return false; - } - - if (!house.LockDown(from, dropped, false)) - { - return false; - } - } - - var list = Items; - - for (var i = 0; i < list.Count; ++i) - { - var item = list[i]; - - if (item is not Container && item.StackWith(from, dropped, false)) - { - return true; - } - } - - DropItem(dropped); - - return true; - } - - public override bool OnDragDropInto(Mobile from, Item item, Point3D p) - { - if (!CheckHold(from, item, true, true)) - { - return false; - } - - var house = BaseHouse.FindHouseAt(this); - - if (house?.HasLockedDownItem(this) == true) - { - if (item is VendorRentalContract || item is Container container && - container.FindItemByType() != null) - { - from.SendLocalizedMessage(1062492); // You cannot place a rental contract in a locked down container. - return false; - } - - if (!house.LockDown(from, item, false)) - { - return false; - } - } - - item.Location = new Point3D(p.X, p.Y, 0); - AddItem(item); - - from.SendSound(GetDroppedSound(item), GetWorldLocation()); - - return true; - } - - public override void UpdateTotal(Item sender, TotalType type, int delta) - { - base.UpdateTotal(sender, type, delta); - - if (type == TotalType.Weight) - { - (RootParent as Mobile)?.InvalidateProperties(); - } - } - - public override void OnDoubleClick(Mobile from) - { - if (from.AccessLevel > AccessLevel.Player || from.InRange(GetWorldLocation(), 2) || RootParent is PlayerVendor) - { - Open(from); - } - else - { - from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that. - } - } - - public virtual void Open(Mobile from) - { - DisplayTo(from); - } - - /* Note: base class insertion; we cannot serialize anything here */ - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - } } - public class CreatureBackpack : Backpack // Used on BaseCreature + public BaseContainer(Serial serial) : base(serial) { - [Constructible] - public CreatureBackpack(string name) + } + + public override int DefaultMaxWeight => IsSecure ? 0 : base.DefaultMaxWeight; + + public override bool IsAccessibleTo(Mobile m) => BaseHouse.CheckAccessible(m, this) && base.IsAccessibleTo(m); + + public override bool CheckHold(Mobile m, Item item, bool message, bool checkItems, int plusItems, int plusWeight) + { + if (IsSecure && !BaseHouse.CheckHold(m, this, item, message, checkItems, plusItems, plusWeight)) { - Name = name; - Layer = Layer.Backpack; - Hue = 5; - Weight = 3.0; - } - - public CreatureBackpack(Serial serial) : base(serial) - { - } - - public override void AddNameProperty(ObjectPropertyList list) - { - if (Name != null) - { - list.Add(1075257, Name); // Contents of ~1_PETNAME~'s pack. - } - else - { - base.AddNameProperty(list); - } - } - - public override void OnItemRemoved(Item item) - { - if (Items.Count == 0) - { - Delete(); - } - - base.OnItemRemoved(item); - } - - public override bool OnDragLift(Mobile from) - { - if (from.AccessLevel > AccessLevel.Player) - { - return true; - } - - from.SendLocalizedMessage(500169); // You cannot pick that up. return false; } - public override bool OnDragDropInto(Mobile from, Item item, Point3D p) => false; - - public override bool TryDropItem(Mobile from, Item dropped, bool sendFullMessage) => false; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(1); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - if (version == 0) - { - Weight = 13.0; - } - } + return base.CheckHold(m, item, message, checkItems, plusItems, plusWeight); } - public class StrongBackpack : Backpack // Used on Pack animals + public override bool CheckItemUse(Mobile from, Item item) { - [Constructible] - public StrongBackpack() + if (IsDecoContainer && item is BaseBook) { - Layer = Layer.Backpack; - Weight = 13.0; - } - - public StrongBackpack(Serial serial) : base(serial) - { - } - - public override int DefaultMaxWeight => 1600; - - public override bool CheckHold(Mobile m, Item item, bool message, bool checkItems, int plusItems, int plusWeight) => - base.CheckHold(m, item, false, checkItems, plusItems, plusWeight); - - public override bool CheckContentDisplay(Mobile from) => - RootParent is BaseCreature creature && creature.Controlled && creature.ControlMaster == from || - base.CheckContentDisplay(from); - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(1); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - if (version == 0) - { - Weight = 13.0; - } - } - } - - public class Backpack : BaseContainer, IDyable - { - [Constructible] - public Backpack() : base(0xE75) - { - Layer = Layer.Backpack; - Weight = 3.0; - } - - public Backpack(Serial serial) : base(serial) - { - } - - public override int DefaultMaxWeight - { - get - { - if (Core.ML && Parent is Mobile m && m.Player && m.Backpack == this) - { - return 550; - } - - return base.DefaultMaxWeight; - } - } - - public bool Dye(Mobile from, DyeTub sender) - { - if (Deleted) - { - return false; - } - - Hue = sender.DyedHue; - return true; } - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(1); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - if (version == 0 && ItemID == 0x9B2) - { - ItemID = 0xE75; - } - } + return base.CheckItemUse(from, item); } - public class Pouch : TrappableContainer + public override void GetContextMenuEntries(Mobile from, List list) { - [Constructible] - public Pouch() : base(0xE79) => Weight = 1.0; - - public Pouch(Serial serial) : base(serial) - { - } - - 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(); - } + base.GetContextMenuEntries(from, list); + SetSecureLevelEntry.AddTo(from, this, list); } - public abstract class BaseBagBall : BaseContainer, IDyable + public override bool TryDropItem(Mobile from, Item dropped, bool sendFullMessage) { - public BaseBagBall(int itemID) : base(itemID) => Weight = 1.0; - - public BaseBagBall(Serial serial) : base(serial) + if (!CheckHold(from, dropped, sendFullMessage, true)) { + return false; } - public bool Dye(Mobile from, DyeTub sender) + var house = BaseHouse.FindHouseAt(this); + + if (house?.HasLockedDownItem(this) == true) { - if (Deleted) + if (dropped is VendorRentalContract || dropped is Container container && + container.FindItemByType() != null) { + from.SendLocalizedMessage(1062492); // You cannot place a rental contract in a locked down container. return false; } - Hue = sender.DyedHue; - - return 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 SmallBagBall : BaseBagBall - { - [Constructible] - public SmallBagBall() : base(0x2256) - { - } - - public SmallBagBall(Serial serial) : base(serial) - { - } - - 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 LargeBagBall : BaseBagBall - { - [Constructible] - public LargeBagBall() : base(0x2257) - { - } - - public LargeBagBall(Serial serial) : base(serial) - { - } - - 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 Bag : BaseContainer, IDyable - { - [Constructible] - public Bag() : base(0xE76) => Weight = 2.0; - - public Bag(Serial serial) : base(serial) - { - } - - public bool Dye(Mobile from, DyeTub sender) - { - if (Deleted) + if (!house.LockDown(from, dropped, false)) { return false; } - - Hue = sender.DyedHue; - - return true; } - public override void Serialize(IGenericWriter writer) + var list = Items; + + for (var i = 0; i < list.Count; ++i) { - base.Serialize(writer); + var item = list[i]; - writer.Write(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } - - public class Barrel : BaseContainer - { - [Constructible] - public Barrel() : base(0xE77) => Weight = 25.0; - - public Barrel(Serial serial) : base(serial) - { - } - - 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(); - - if (Weight == 0.0) + if (item is not Container && item.StackWith(from, dropped, false)) { - Weight = 25.0; + return true; } } + + DropItem(dropped); + + return true; } - public class Keg : BaseContainer + public override bool OnDragDropInto(Mobile from, Item item, Point3D p) { - [Constructible] - public Keg() : base(0xE7F) => Weight = 15.0; - - public Keg(Serial serial) : base(serial) + if (!CheckHold(from, item, true, true)) { + return false; } - public override void Serialize(IGenericWriter writer) + var house = BaseHouse.FindHouseAt(this); + + if (house?.HasLockedDownItem(this) == true) { - base.Serialize(writer); - - writer.Write(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } - - public class PicnicBasket : BaseContainer - { - [Constructible] - public PicnicBasket() : base(0xE7A) => Weight = 2.0; - - public PicnicBasket(Serial serial) : base(serial) - { - } - - 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 Basket : BaseContainer - { - [Constructible] - public Basket() : base(0x990) => Weight = 1.0; - - public Basket(Serial serial) : base(serial) - { - } - - 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(); - } - } - - [Furniture] - [Flippable(0x9AA, 0xE7D)] - public class WoodenBox : LockableContainer - { - [Constructible] - public WoodenBox() : base(0x9AA) => Weight = 4.0; - - public WoodenBox(Serial serial) : base(serial) - { - } - - 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(); - } - } - - [Furniture] - [Flippable(0x9A9, 0xE7E)] - public class SmallCrate : LockableContainer - { - [Constructible] - public SmallCrate() : base(0x9A9) => Weight = 2.0; - - public SmallCrate(Serial serial) : base(serial) - { - } - - 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(); - - if (Weight == 4.0) + if (item is VendorRentalContract || item is Container container && + container.FindItemByType() != null) { - Weight = 2.0; - } - } - } - - [Furniture] - [Flippable(0xE3F, 0xE3E)] - public class MediumCrate : LockableContainer - { - [Constructible] - public MediumCrate() : base(0xE3F) => Weight = 2.0; - - public MediumCrate(Serial serial) : base(serial) - { - } - - 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(); - - if (Weight == 6.0) - { - Weight = 2.0; - } - } - } - - [Furniture] - [Flippable(0xE3D, 0xE3C)] - public class LargeCrate : LockableContainer - { - [Constructible] - public LargeCrate() : base(0xE3D) => Weight = 1.0; - - public LargeCrate(Serial serial) : base(serial) - { - } - - 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(); - - if (Weight == 8.0) - { - Weight = 1.0; - } - } - } - - [DynamicFlipping, Flippable(0x9A8, 0xE80)] - public class MetalBox : LockableContainer - { - [Constructible] - public MetalBox() : base(0x9A8) - { - } - - public MetalBox(Serial serial) : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(1); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - if (version == 0 && Weight == 3) - { - Weight = -1; - } - } - } - - [DynamicFlipping, Flippable(0x9AB, 0xE7C)] - public class MetalChest : LockableContainer - { - [Constructible] - public MetalChest() : base(0x9AB) - { - } - - public MetalChest(Serial serial) : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(1); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - if (version == 0 && Weight == 25) - { - Weight = -1; - } - } - } - - [DynamicFlipping, Flippable(0xE41, 0xE40)] - public class MetalGoldenChest : LockableContainer - { - [Constructible] - public MetalGoldenChest() : base(0xE41) - { - } - - public MetalGoldenChest(Serial serial) : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(1); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - if (version == 0 && Weight == 25) - { - Weight = -1; - } - } - } - - [Furniture] - [Flippable(0xe43, 0xe42)] - public class WoodenChest : LockableContainer - { - [Constructible] - public WoodenChest() : base(0xe43) => Weight = 2.0; - - public WoodenChest(Serial serial) : base(serial) - { - } - - 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(); - - if (Weight == 15.0) - { - Weight = 2.0; - } - } - } - - [Furniture] - [Flippable(0x280B, 0x280C)] - public class PlainWoodenChest : LockableContainer - { - [Constructible] - public PlainWoodenChest() : base(0x280B) - { - } - - public PlainWoodenChest(Serial serial) : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(1); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - if (version == 0 && Weight == 15) - { - Weight = -1; - } - } - } - - [Furniture] - [Flippable(0x280D, 0x280E)] - public class OrnateWoodenChest : LockableContainer - { - [Constructible] - public OrnateWoodenChest() : base(0x280D) - { - } - - public OrnateWoodenChest(Serial serial) : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(1); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - if (version == 0 && Weight == 15) - { - Weight = -1; - } - } - } - - [Furniture] - [Flippable(0x280F, 0x2810)] - public class GildedWoodenChest : LockableContainer - { - [Constructible] - public GildedWoodenChest() : base(0x280F) - { - } - - public GildedWoodenChest(Serial serial) : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(1); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - if (version == 0 && Weight == 15) - { - Weight = -1; - } - } - } - - [Furniture] - [Flippable(0x2811, 0x2812)] - public class WoodenFootLocker : LockableContainer - { - [Constructible] - public WoodenFootLocker() : base(0x2811) => GumpID = 0x10B; - - public WoodenFootLocker(Serial serial) : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(2); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - if (version == 0 && Weight == 15) - { - Weight = -1; + from.SendLocalizedMessage(1062492); // You cannot place a rental contract in a locked down container. + return false; } - if (version < 2) + if (!house.LockDown(from, item, false)) { - GumpID = 0x10B; + return false; } } + + item.Location = new Point3D(p.X, p.Y, 0); + AddItem(item); + + from.SendSound(GetDroppedSound(item), GetWorldLocation()); + + return true; } - [Furniture] - [Flippable(0x2813, 0x2814)] - public class FinishedWoodenChest : LockableContainer + public override void UpdateTotal(Item sender, TotalType type, int delta) { - [Constructible] - public FinishedWoodenChest() : base(0x2813) + base.UpdateTotal(sender, type, delta); + + if (type == TotalType.Weight) { - } - - public FinishedWoodenChest(Serial serial) : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(1); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - if (version == 0 && Weight == 15) - { - Weight = -1; - } + (RootParent as Mobile)?.InvalidateProperties(); } } - [Furniture] - [Serializable(0)] - [Flippable(0x2DF1, 0x2DF2)] - public partial class RarewoodChest : LockableContainer + public override void OnDoubleClick(Mobile from) { - [Constructible] - public RarewoodChest() : base(0x2DF1) + if (from.AccessLevel > AccessLevel.Player || from.InRange(GetWorldLocation(), 2) || RootParent is PlayerVendor) { + Open(from); + } + else + { + from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that. } } - [Furniture] - [Serializable(0)] - [Flippable(0x2DF3, 0x2DF4)] - public partial class DecorativeBox : LockableContainer + public virtual void Open(Mobile from) + { + DisplayTo(from); + } + + /* Note: base class insertion; we cannot serialize anything here */ + public override void Serialize(IGenericWriter writer) + { + base.Serialize(writer); + } + + public override void Deserialize(IGenericReader reader) + { + base.Deserialize(reader); + } +} + +[Serializable(0, false)] +public partial class CreatureBackpack : Backpack // Used on BaseCreature +{ + [Constructible] + public CreatureBackpack(string name) + { + Name = name; + Layer = Layer.Backpack; + Hue = 5; + Weight = 3.0; + } + + public override void AddNameProperty(ObjectPropertyList list) + { + if (Name != null) + { + list.Add(1075257, Name); // Contents of ~1_PETNAME~'s pack. + } + else + { + base.AddNameProperty(list); + } + } + + public override void OnItemRemoved(Item item) + { + if (Items.Count == 0) + { + Delete(); + } + + base.OnItemRemoved(item); + } + + public override bool OnDragLift(Mobile from) + { + if (from.AccessLevel > AccessLevel.Player) + { + return true; + } + + from.SendLocalizedMessage(500169); // You cannot pick that up. + return false; + } + + public override bool OnDragDropInto(Mobile from, Item item, Point3D p) => false; + + public override bool TryDropItem(Mobile from, Item dropped, bool sendFullMessage) => false; +} + +[Serializable(0, false)] +public partial class StrongBackpack : Backpack // Used on Pack animals +{ + [Constructible] + public StrongBackpack() + { + Layer = Layer.Backpack; + Weight = 13.0; + } + + public override int DefaultMaxWeight => 1600; + + public override bool CheckHold(Mobile m, Item item, bool message, bool checkItems, int plusItems, int plusWeight) => + base.CheckHold(m, item, false, checkItems, plusItems, plusWeight); + + public override bool CheckContentDisplay(Mobile from) => + RootParent is BaseCreature creature && creature.Controlled && creature.ControlMaster == from || + base.CheckContentDisplay(from); +} + +[Serializable(0, false)] +public partial class Backpack : BaseContainer, IDyable +{ + [Constructible] + public Backpack() : base(0xE75) + { + Layer = Layer.Backpack; + Weight = 3.0; + } + + public override int DefaultMaxWeight + { + get + { + if (Core.ML && Parent is Mobile m && m.Player && m.Backpack == this) + { + return 550; + } + + return base.DefaultMaxWeight; + } + } + + public bool Dye(Mobile from, DyeTub sender) + { + if (Deleted) + { + return false; + } + + Hue = sender.DyedHue; + + return true; + } +} + +[Serializable(0, false)] +public partial class Pouch : TrappableContainer +{ + [Constructible] + public Pouch() : base(0xE79) => Weight = 1.0; +} + +[Serializable(0, false)] +public abstract partial class BaseBagBall : BaseContainer, IDyable +{ + public BaseBagBall(int itemID) : base(itemID) => Weight = 1.0; + + public bool Dye(Mobile from, DyeTub sender) + { + if (Deleted) + { + return false; + } + + Hue = sender.DyedHue; + + return true; + } +} + +[Serializable(0, false)] +public partial class SmallBagBall : BaseBagBall +{ + [Constructible] + public SmallBagBall() : base(0x2256) + { + } +} + +[Serializable(0, false)] +public partial class LargeBagBall : BaseBagBall +{ + [Constructible] + public LargeBagBall() : base(0x2257) + { + } +} + +[Serializable(0, false)] +public partial class Bag : BaseContainer, IDyable +{ + [Constructible] + public Bag() : base(0xE76) => Weight = 2.0; + + public bool Dye(Mobile from, DyeTub sender) + { + if (Deleted) + { + return false; + } + + Hue = sender.DyedHue; + + return true; + } +} + +[Serializable(0, false)] +public partial class Barrel : BaseContainer +{ + [Constructible] + public Barrel() : base(0xE77) => Weight = 25.0; +} + +[Serializable(0, false)] +public partial class Keg : BaseContainer +{ + [Constructible] + public Keg() : base(0xE7F) => Weight = 15.0; +} + +[Serializable(0, false)] +public partial class PicnicBasket : BaseContainer +{ + [Constructible] + public PicnicBasket() : base(0xE7A) => Weight = 2.0; +} + +[Serializable(0, false)] +public partial class Basket : BaseContainer +{ + [Constructible] + public Basket() : base(0x990) => Weight = 1.0; +} + +[Furniture] +[Flippable(0x9AA, 0xE7D)] +[Serializable(0, false)] +public partial class WoodenBox : LockableContainer +{ + [Constructible] + public WoodenBox() : base(0x9AA) => Weight = 4.0; +} + +[Furniture] +[Flippable(0x9A9, 0xE7E)] +[Serializable(0, false)] +public partial class SmallCrate : LockableContainer +{ + [Constructible] + public SmallCrate() : base(0x9A9) => Weight = 2.0; +} + +[Furniture] +[Flippable(0xE3F, 0xE3E)] +[Serializable(0, false)] +public partial class MediumCrate : LockableContainer +{ + [Constructible] + public MediumCrate() : base(0xE3F) => Weight = 2.0; +} + +[Furniture] +[Flippable(0xE3D, 0xE3C)] +[Serializable(0, false)] +public partial class LargeCrate : LockableContainer +{ + [Constructible] + public LargeCrate() : base(0xE3D) => Weight = 1.0; +} + +[DynamicFlipping] +[Flippable(0x9A8, 0xE80)] +[Serializable(0, false)] +public partial class MetalBox : LockableContainer +{ + [Constructible] + public MetalBox() : base(0x9A8) + { + } +} + +[DynamicFlipping] +[Flippable(0x9AB, 0xE7C)] +[Serializable(0, false)] +public partial class MetalChest : LockableContainer +{ + [Constructible] + public MetalChest() : base(0x9AB) + { + } +} + +[DynamicFlipping, Flippable(0xE41, 0xE40)] +[Serializable(0, false)] +public partial class MetalGoldenChest : LockableContainer +{ + [Constructible] + public MetalGoldenChest() : base(0xE41) + { + } +} + +[Furniture] +[Flippable(0xe43, 0xe42)] +[Serializable(0, false)] +public partial class WoodenChest : LockableContainer +{ + [Constructible] + public WoodenChest() : base(0xe43) => Weight = 2.0; +} + +[Furniture] +[Flippable(0x280B, 0x280C)] +[Serializable(0, false)] +public partial class PlainWoodenChest : LockableContainer +{ + [Constructible] + public PlainWoodenChest() : base(0x280B) + { + } +} + +[Furniture] +[Flippable(0x280D, 0x280E)] +[Serializable(0, false)] +public partial class OrnateWoodenChest : LockableContainer +{ + [Constructible] + public OrnateWoodenChest() : base(0x280D) + { + } +} + +[Furniture] +[Flippable(0x280F, 0x2810)] +[Serializable(0, false)] +public partial class GildedWoodenChest : LockableContainer +{ + [Constructible] + public GildedWoodenChest() : base(0x280F) + { + } +} + +[Furniture] +[Flippable(0x2811, 0x2812)] +[Serializable(0, false)] +public partial class WoodenFootLocker : LockableContainer +{ + [Constructible] + public WoodenFootLocker() : base(0x2811) => GumpID = 0x10B; +} + +[Furniture] +[Flippable(0x2813, 0x2814)] +[Serializable(0, false)] +public partial class FinishedWoodenChest : LockableContainer +{ + [Constructible] + public FinishedWoodenChest() : base(0x2813) + { + } +} + +[Furniture] +[Serializable(0)] +[Flippable(0x2DF1, 0x2DF2)] +public partial class RarewoodChest : LockableContainer +{ + [Constructible] + public RarewoodChest() : base(0x2DF1) + { + } +} + +[Furniture] +[Serializable(0)] +[Flippable(0x2DF3, 0x2DF4)] +public partial class DecorativeBox : LockableContainer +{ + [Constructible] + public DecorativeBox() : base(0x2DF4) { - [Constructible] - public DecorativeBox() : base(0x2DF4) - { - } } } diff --git a/Projects/UOContent/Migrations/Server.Items.Backpack.v0.json b/Projects/UOContent/Migrations/Server.Items.Backpack.v0.json new file mode 100644 index 000000000..079753f27 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Backpack.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Backpack" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Bag.v0.json b/Projects/UOContent/Migrations/Server.Items.Bag.v0.json new file mode 100644 index 000000000..10c6b3e4d --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Bag.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Bag" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Barrel.v0.json b/Projects/UOContent/Migrations/Server.Items.Barrel.v0.json new file mode 100644 index 000000000..b15228a5a --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Barrel.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Barrel" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.BaseBagBall.v0.json b/Projects/UOContent/Migrations/Server.Items.BaseBagBall.v0.json new file mode 100644 index 000000000..296084218 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.BaseBagBall.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.BaseBagBall" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Basket.v0.json b/Projects/UOContent/Migrations/Server.Items.Basket.v0.json new file mode 100644 index 000000000..537b71d86 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Basket.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Basket" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.CreatureBackpack.v0.json b/Projects/UOContent/Migrations/Server.Items.CreatureBackpack.v0.json new file mode 100644 index 000000000..6a28e8198 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.CreatureBackpack.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.CreatureBackpack" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.FinishedWoodenChest.v0.json b/Projects/UOContent/Migrations/Server.Items.FinishedWoodenChest.v0.json new file mode 100644 index 000000000..e2242c3b7 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.FinishedWoodenChest.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.FinishedWoodenChest" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.GildedWoodenChest.v0.json b/Projects/UOContent/Migrations/Server.Items.GildedWoodenChest.v0.json new file mode 100644 index 000000000..fe2ba5fe0 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.GildedWoodenChest.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.GildedWoodenChest" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Keg.v0.json b/Projects/UOContent/Migrations/Server.Items.Keg.v0.json new file mode 100644 index 000000000..7a00e229a --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Keg.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Keg" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.LargeBagBall.v0.json b/Projects/UOContent/Migrations/Server.Items.LargeBagBall.v0.json new file mode 100644 index 000000000..24dcc0b7b --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.LargeBagBall.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.LargeBagBall" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.LargeCrate.v0.json b/Projects/UOContent/Migrations/Server.Items.LargeCrate.v0.json new file mode 100644 index 000000000..c3d152a8d --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.LargeCrate.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.LargeCrate" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.MediumCrate.v0.json b/Projects/UOContent/Migrations/Server.Items.MediumCrate.v0.json new file mode 100644 index 000000000..1d1cbab84 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.MediumCrate.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.MediumCrate" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.MetalBox.v0.json b/Projects/UOContent/Migrations/Server.Items.MetalBox.v0.json new file mode 100644 index 000000000..5ccce1a91 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.MetalBox.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.MetalBox" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.MetalChest.v0.json b/Projects/UOContent/Migrations/Server.Items.MetalChest.v0.json new file mode 100644 index 000000000..b0f41c3c9 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.MetalChest.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.MetalChest" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.MetalGoldenChest.v0.json b/Projects/UOContent/Migrations/Server.Items.MetalGoldenChest.v0.json new file mode 100644 index 000000000..3f1d63f0d --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.MetalGoldenChest.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.MetalGoldenChest" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.OrnateWoodenChest.v0.json b/Projects/UOContent/Migrations/Server.Items.OrnateWoodenChest.v0.json new file mode 100644 index 000000000..16c2b29d5 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.OrnateWoodenChest.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.OrnateWoodenChest" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.PicnicBasket.v0.json b/Projects/UOContent/Migrations/Server.Items.PicnicBasket.v0.json new file mode 100644 index 000000000..ded401af8 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.PicnicBasket.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.PicnicBasket" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.PlainWoodenChest.v0.json b/Projects/UOContent/Migrations/Server.Items.PlainWoodenChest.v0.json new file mode 100644 index 000000000..bdf8b28d1 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.PlainWoodenChest.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.PlainWoodenChest" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Pouch.v0.json b/Projects/UOContent/Migrations/Server.Items.Pouch.v0.json new file mode 100644 index 000000000..7a2cc5ea7 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Pouch.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Pouch" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.SmallBagBall.v0.json b/Projects/UOContent/Migrations/Server.Items.SmallBagBall.v0.json new file mode 100644 index 000000000..02f023431 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.SmallBagBall.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.SmallBagBall" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.SmallCrate.v0.json b/Projects/UOContent/Migrations/Server.Items.SmallCrate.v0.json new file mode 100644 index 000000000..c911e5111 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.SmallCrate.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.SmallCrate" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.StrongBackpack.v0.json b/Projects/UOContent/Migrations/Server.Items.StrongBackpack.v0.json new file mode 100644 index 000000000..2429aa2cc --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.StrongBackpack.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.StrongBackpack" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.WoodenBox.v0.json b/Projects/UOContent/Migrations/Server.Items.WoodenBox.v0.json new file mode 100644 index 000000000..e6441683e --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.WoodenBox.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.WoodenBox" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.WoodenChest.v0.json b/Projects/UOContent/Migrations/Server.Items.WoodenChest.v0.json new file mode 100644 index 000000000..7b527cf6b --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.WoodenChest.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.WoodenChest" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.WoodenFootLocker.v0.json b/Projects/UOContent/Migrations/Server.Items.WoodenFootLocker.v0.json new file mode 100644 index 000000000..ec607aa35 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.WoodenFootLocker.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.WoodenFootLocker" +} \ No newline at end of file From 9bc6d5bdb831f79795f95a4af991d63e4bad1d89 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 27 Feb 2022 17:09:12 -0800 Subject: [PATCH 089/213] fix: Codegens salvage bags (#947) --- .../UOContent/Items/Containers/SalvageBag.cs | 639 +++++++++--------- .../Server.Items.SalvageBag.v0.json | 4 + 2 files changed, 312 insertions(+), 331 deletions(-) create mode 100644 Projects/UOContent/Migrations/Server.Items.SalvageBag.v0.json diff --git a/Projects/UOContent/Items/Containers/SalvageBag.cs b/Projects/UOContent/Items/Containers/SalvageBag.cs index 3d8be35dc..365a9e39d 100644 --- a/Projects/UOContent/Items/Containers/SalvageBag.cs +++ b/Projects/UOContent/Items/Containers/SalvageBag.cs @@ -6,393 +6,370 @@ using Server.Engines.Craft; using Server.Network; using Server.Utilities; -namespace Server.Items +namespace Server.Items; + +[Serializable(0)] +public partial class SalvageBag : Bag { - public class SalvageBag : Bag + private bool m_Failure; + + [Constructible] + public SalvageBag() : this(Utility.RandomBlueHue()) { - private bool m_Failure; + } - [Constructible] - public SalvageBag() - : this(Utility.RandomBlueHue()) + [Constructible] + public SalvageBag(int hue) + { + Weight = 2.0; + Hue = hue; + m_Failure = false; + } + + public override int LabelNumber => 1079931; // Salvage Bag + + public override void GetContextMenuEntries(Mobile from, List list) + { + base.GetContextMenuEntries(from, list); + + if (from.Alive) { + var inBackpack = IsChildOf(from.Backpack); + var resmeltables = inBackpack && Resmeltables(); + var scissorables = inBackpack && Scissorables(); + list.Add(new SalvageIngotsEntry(this, resmeltables)); + list.Add(new SalvageClothEntry(this, scissorables)); + list.Add(new SalvageAllEntry(this, resmeltables && scissorables)); } + } - [Constructible] - public SalvageBag(int hue) + private bool Resmelt(Mobile from, Item item, CraftResource resource) + { + try { - Weight = 2.0; - Hue = hue; - m_Failure = false; - } - - public SalvageBag(Serial serial) - : base(serial) - { - } - - public override int LabelNumber => 1079931; // Salvage Bag - - public override void GetContextMenuEntries(Mobile from, List list) - { - base.GetContextMenuEntries(from, list); - - if (from.Alive) + if (CraftResources.GetType(resource) != CraftResourceType.Metal) { - list.Add(new SalvageIngotsEntry(this, IsChildOf(from.Backpack) && Resmeltables())); - list.Add(new SalvageClothEntry(this, IsChildOf(from.Backpack) && Scissorables())); - list.Add(new SalvageAllEntry(this, IsChildOf(from.Backpack) && Resmeltables() && Scissorables())); + return false; } - } - private bool Resmelt(Mobile from, Item item, CraftResource resource) - { - try + var info = CraftResources.GetInfo(resource); + + if (info == null || info.ResourceTypes.Length == 0) { - if (CraftResources.GetType(resource) != CraftResourceType.Metal) + return false; + } + + var craftItem = DefBlacksmithy.CraftSystem.CraftItems.SearchFor(item.GetType()); + + if (craftItem == null || craftItem.Resources.Count == 0) + { + return false; + } + + var craftResource = craftItem.Resources[0]; + + if (craftResource.Amount < 2) + { + return false; // Not enough metal to resmelt + } + + var difficulty = resource switch + { + CraftResource.DullCopper => 65.0, + CraftResource.ShadowIron => 70.0, + CraftResource.Copper => 75.0, + CraftResource.Bronze => 80.0, + CraftResource.Gold => 85.0, + CraftResource.Agapite => 90.0, + CraftResource.Verite => 95.0, + CraftResource.Valorite => 99.0, + _ => 0.0 + }; + + var ingot = info.ResourceTypes[0].CreateInstance(); + + if (item is DragonBardingDeed || item is BaseArmor armor && armor.PlayerConstructed || + item is BaseWeapon weapon && weapon.PlayerConstructed || + item is BaseClothing clothing && clothing.PlayerConstructed) + { + var mining = from.Skills.Mining.Value; + if (mining > 100.0) { - return false; + mining = 100.0; } - var info = CraftResources.GetInfo(resource); - - if (info == null || info.ResourceTypes.Length == 0) - { - return false; - } - - var craftItem = DefBlacksmithy.CraftSystem.CraftItems.SearchFor(item.GetType()); - - if (craftItem == null || craftItem.Resources.Count == 0) - { - return false; - } - - var craftResource = craftItem.Resources[0]; - - if (craftResource.Amount < 2) - { - return false; // Not enough metal to resmelt - } - - var difficulty = resource switch - { - CraftResource.DullCopper => 65.0, - CraftResource.ShadowIron => 70.0, - CraftResource.Copper => 75.0, - CraftResource.Bronze => 80.0, - CraftResource.Gold => 85.0, - CraftResource.Agapite => 90.0, - CraftResource.Verite => 95.0, - CraftResource.Valorite => 99.0, - _ => 0.0 - }; - - var ingot = info.ResourceTypes[0].CreateInstance(); - - if (item is DragonBardingDeed || item is BaseArmor armor && armor.PlayerConstructed || - item is BaseWeapon weapon && weapon.PlayerConstructed || - item is BaseClothing clothing && clothing.PlayerConstructed) - { - var mining = from.Skills.Mining.Value; - if (mining > 100.0) - { - mining = 100.0; - } - - var amount = ((4 + mining) * craftResource.Amount - 4) * 0.0068; - if (amount < 2) - { - ingot.Amount = 2; - } - else - { - ingot.Amount = (int)amount; - } - } - else + var amount = ((4 + mining) * craftResource.Amount - 4) * 0.0068; + if (amount < 2) { ingot.Amount = 2; } - - if (difficulty > from.Skills.Mining.Value) - { - m_Failure = true; - ingot.Delete(); - } else { - item.Delete(); + ingot.Amount = (int)amount; } - - from.AddToBackpack(ingot); - - from.PlaySound(0x2A); - from.PlaySound(0x240); - - return true; - } - catch (Exception ex) - { - Console.WriteLine(ex.ToString()); - } - - return false; - } - - private bool Resmeltables() // Where context menu checks for metal items and dragon barding deeds - { - foreach (var i in Items) - { - return i?.Deleted == false && ( - i is BaseWeapon weapon && CraftResources.GetType(weapon.Resource) == CraftResourceType.Metal || - i is BaseArmor armor && CraftResources.GetType(armor.Resource) == CraftResourceType.Metal || - i is DragonBardingDeed); - } - - return false; - } - - private bool Scissorables() // Where context menu checks for Leather items and cloth items - { - foreach (var i in Items) - { - if (i is not IScissorable || i.Deleted) - { - continue; - } - - if (i is BaseClothing or Cloth or BoltOfCloth or Hides or BonePile || i is BaseArmor armor && CraftResources.GetType(armor.Resource) == CraftResourceType.Leather) - { - return true; - } - } - - return false; - } - - private void SalvageIngots(Mobile from) - { - if (from.Backpack.FindItemsByType().All(tool => tool.CraftSystem != DefBlacksmithy.CraftSystem)) - { - from.SendLocalizedMessage(1079822); // You need a blacksmithing tool in order to salvage ingots. - return; - } - - DefBlacksmithy.CheckAnvilAndForge(from, 2, out _, out var forge); - - if (!forge) - { - from.SendLocalizedMessage(1044265); // You must be near a forge. - return; - } - - var salvaged = 0; - var notSalvaged = 0; - - Container sBag = this; - - var smeltables = sBag.FindItemsByType(); - - foreach (var item in smeltables) - { - if (item?.Deleted != false) - { - continue; - } - - if (item is BaseArmor armor && Resmelt(from, armor, armor.Resource) || - item is BaseWeapon weapon && Resmelt(from, weapon, weapon.Resource) || - item is DragonBardingDeed) - { - salvaged++; - } - else - { - notSalvaged++; - } - } - - if (m_Failure) - { - from.SendLocalizedMessage(1079975); // You failed to smelt some metal for lack of skill. - m_Failure = false; } else { - from.SendLocalizedMessage( - 1079973, - $"{salvaged}\t{salvaged + notSalvaged}" - ); // Salvaged: ~1_COUNT~/~2_NUM~ blacksmithed items + ingot.Amount = 2; + } + + if (difficulty > from.Skills.Mining.Value) + { + m_Failure = true; + ingot.Delete(); + } + else + { + item.Delete(); + } + + from.AddToBackpack(ingot); + + from.PlaySound(0x2A); + from.PlaySound(0x240); + + return true; + } + catch (Exception ex) + { + Console.WriteLine(ex.ToString()); + } + + return false; + } + + private bool Resmeltables() // Where context menu checks for metal items and dragon barding deeds + { + foreach (var i in Items) + { + return i?.Deleted == false && ( + i is BaseWeapon weapon && CraftResources.GetType(weapon.Resource) == CraftResourceType.Metal || + i is BaseArmor armor && CraftResources.GetType(armor.Resource) == CraftResourceType.Metal || + i is DragonBardingDeed + ); + } + + return false; + } + + private bool Scissorables() // Where context menu checks for Leather items and cloth items + { + foreach (var i in Items) + { + if (i is not IScissorable || i.Deleted) + { + continue; + } + + if (i is BaseClothing or Cloth or BoltOfCloth or Hides or BonePile || i is BaseArmor armor && CraftResources.GetType(armor.Resource) == CraftResourceType.Leather) + { + return true; } } - private void SalvageCloth(Mobile from) - { - var scissors = from.Backpack.FindItemByType(); + return false; + } - if (scissors == null) + private void SalvageIngots(Mobile from) + { + if (from.Backpack.FindItemsByType().All(tool => tool.CraftSystem != DefBlacksmithy.CraftSystem)) + { + from.SendLocalizedMessage(1079822); // You need a blacksmithing tool in order to salvage ingots. + return; + } + + DefBlacksmithy.CheckAnvilAndForge(from, 2, out _, out var forge); + + if (!forge) + { + from.SendLocalizedMessage(1044265); // You must be near a forge. + return; + } + + var salvaged = 0; + var notSalvaged = 0; + + Container sBag = this; + + var smeltables = sBag.FindItemsByType(); + + foreach (var item in smeltables) + { + if (item?.Deleted != false) + { + continue; + } + + if (item is BaseArmor armor && Resmelt(from, armor, armor.Resource) || + item is BaseWeapon weapon && Resmelt(from, weapon, weapon.Resource) || + item is DragonBardingDeed) + { + salvaged++; + } + else + { + notSalvaged++; + } + } + + if (m_Failure) + { + from.SendLocalizedMessage(1079975); // You failed to smelt some metal for lack of skill. + m_Failure = false; + } + else + { + from.SendLocalizedMessage( + 1079973, + $"{salvaged}\t{salvaged + notSalvaged}" + ); // Salvaged: ~1_COUNT~/~2_NUM~ blacksmithed items + } + } + + private static readonly Type[] _clothTypes = { + typeof(Leather), typeof(Cloth), typeof(SpinedLeather), typeof(HornedLeather), typeof(BarbedLeather), + typeof(Bandage), typeof(Bone) + }; + + private void SalvageCloth(Mobile from) + { + var scissors = from.Backpack.FindItemByType(); + + if (scissors == null) + { + from.SendLocalizedMessage(1079823); // You need scissors in order to salvage cloth. + return; + } + + var salvaged = 0; + var notSalvaged = 0; + + Container sBag = this; + + var scissorables = sBag.FindItemsByType(); + + for (var i = scissorables.Count - 1; i >= 0; --i) + { + var item = scissorables[i]; + + if (item is not IScissorable scissorable) + { + continue; + } + + if (Scissors.CanScissor(from, scissorable) && scissorable.Scissor(from, scissors)) + { + ++salvaged; + } + else + { + ++notSalvaged; + } + } + + // Salvaged: ~1_COUNT~/~2_NUM~ tailored items + from.SendLocalizedMessage(1079974, $"{salvaged}\t{salvaged + notSalvaged}"); + + var items = FindItemsByType(_clothTypes); + + for (var i = 0; i < items.Length; i++) + { + from.AddToBackpack(items[i]); + } + } + + private void SalvageAll(Mobile from) + { + SalvageIngots(from); + SalvageCloth(from); + } + + private class SalvageAllEntry : ContextMenuEntry + { + private readonly SalvageBag m_Bag; + + public SalvageAllEntry(SalvageBag bag, bool enabled) : base(6276) + { + m_Bag = bag; + + if (!enabled) + { + Flags |= CMEFlags.Disabled; + } + } + + public override void OnClick() + { + if (m_Bag.Deleted) { - from.SendLocalizedMessage(1079823); // You need scissors in order to salvage cloth. return; } - var salvaged = 0; - var notSalvaged = 0; + var from = Owner.From; - Container sBag = this; - - var scissorables = sBag.FindItemsByType(); - - for (var i = scissorables.Count - 1; i >= 0; --i) + if (from.CheckAlive()) { - var item = scissorables[i]; - - if (item is not IScissorable scissorable) - { - continue; - } - - if (Scissors.CanScissor(from, scissorable) && scissorable.Scissor(from, scissors)) - { - ++salvaged; - } - else - { - ++notSalvaged; - } + m_Bag.SalvageAll(from); } + } + } - from.SendLocalizedMessage( - 1079974, - $"{salvaged}\t{salvaged + notSalvaged}" - ); // Salvaged: ~1_COUNT~/~2_NUM~ tailored items + private class SalvageIngotsEntry : ContextMenuEntry + { + private readonly SalvageBag m_Bag; - var items = FindItemsByType( - new[] - { - typeof(Leather), typeof(Cloth), typeof(SpinedLeather), typeof(HornedLeather), typeof(BarbedLeather), - typeof(Bandage), typeof(Bone) - } - ); + public SalvageIngotsEntry(SalvageBag bag, bool enabled) : base(6277) + { + m_Bag = bag; - for (var i = 0; i < items.Length; i++) + if (!enabled) { - from.AddToBackpack(items[i]); + Flags |= CMEFlags.Disabled; } } - private void SalvageAll(Mobile from) + public override void OnClick() { - SalvageIngots(from); - - SalvageCloth(from); - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - - private class SalvageAllEntry : ContextMenuEntry - { - private readonly SalvageBag m_Bag; - - public SalvageAllEntry(SalvageBag bag, bool enabled) - : base(6276) + if (m_Bag.Deleted) { - m_Bag = bag; - - if (!enabled) - { - Flags |= CMEFlags.Disabled; - } + return; } - public override void OnClick() + var from = Owner.From; + + if (from.CheckAlive()) { - if (m_Bag.Deleted) - { - return; - } + m_Bag.SalvageIngots(from); + } + } + } - var from = Owner.From; + private class SalvageClothEntry : ContextMenuEntry + { + private readonly SalvageBag m_Bag; - if (from.CheckAlive()) - { - m_Bag.SalvageAll(from); - } + public SalvageClothEntry(SalvageBag bag, bool enabled) : base(6278) + { + m_Bag = bag; + + if (!enabled) + { + Flags |= CMEFlags.Disabled; } } - private class SalvageIngotsEntry : ContextMenuEntry + public override void OnClick() { - private readonly SalvageBag m_Bag; - - public SalvageIngotsEntry(SalvageBag bag, bool enabled) - : base(6277) + if (m_Bag.Deleted) { - m_Bag = bag; - - if (!enabled) - { - Flags |= CMEFlags.Disabled; - } + return; } - public override void OnClick() + var from = Owner.From; + + if (from.CheckAlive()) { - if (m_Bag.Deleted) - { - return; - } - - var from = Owner.From; - - if (from.CheckAlive()) - { - m_Bag.SalvageIngots(from); - } - } - } - - private class SalvageClothEntry : ContextMenuEntry - { - private readonly SalvageBag m_Bag; - - public SalvageClothEntry(SalvageBag bag, bool enabled) - : base(6278) - { - m_Bag = bag; - - if (!enabled) - { - Flags |= CMEFlags.Disabled; - } - } - - public override void OnClick() - { - if (m_Bag.Deleted) - { - return; - } - - var from = Owner.From; - - if (from.CheckAlive()) - { - m_Bag.SalvageCloth(from); - } + m_Bag.SalvageCloth(from); } } } diff --git a/Projects/UOContent/Migrations/Server.Items.SalvageBag.v0.json b/Projects/UOContent/Migrations/Server.Items.SalvageBag.v0.json new file mode 100644 index 000000000..05f0387ef --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.SalvageBag.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.SalvageBag" +} \ No newline at end of file From 17f8d3563ae7f1ec54c8676a9860d707a9c19ad9 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 27 Feb 2022 17:22:38 -0800 Subject: [PATCH 090/213] fix: Codegens treasure/paragon chests & strongboxes (#948) --- .../Items/Containers/BaseTreasureChest.cs | 328 +++++++---------- .../Items/Containers/ParagonChest.cs | 329 ++++++++---------- .../UOContent/Items/Containers/Strongbox.cs | 241 ++++++------- .../Server.Items.BaseTreasureChest.v1.json | 21 ++ .../Server.Items.ParagonChest.v0.json | 14 + .../Migrations/Server.Items.StrongBox.v0.json | 16 + 6 files changed, 431 insertions(+), 518 deletions(-) create mode 100644 Projects/UOContent/Migrations/Server.Items.BaseTreasureChest.v1.json create mode 100644 Projects/UOContent/Migrations/Server.Items.ParagonChest.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.StrongBox.v0.json diff --git a/Projects/UOContent/Items/Containers/BaseTreasureChest.cs b/Projects/UOContent/Items/Containers/BaseTreasureChest.cs index 8d5276940..95be9334e 100644 --- a/Projects/UOContent/Items/Containers/BaseTreasureChest.cs +++ b/Projects/UOContent/Items/Containers/BaseTreasureChest.cs @@ -1,214 +1,138 @@ using System; -namespace Server.Items +namespace Server.Items; + +[Serializable(1, false)] +public partial class BaseTreasureChest : LockableContainer { - public class BaseTreasureChest : LockableContainer + public enum TreasureLevel { - public enum TreasureLevel + Level1, + Level2, + Level3, + Level4, + Level5, + Level6 + } + + private TimerExecutionToken _resetTimer; + + public BaseTreasureChest(int itemID, TreasureLevel level = TreasureLevel.Level2) : base(itemID) + { + _level = level; + _minSpawnTime = TimeSpan.FromMinutes(10); + _maxSpawnTime = TimeSpan.FromMinutes(60); + + Locked = true; + Movable = false; + + SetLockLevel(); + GenerateTreasure(); + } + + [SerializableField(0)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private TreasureLevel _level; + + [SerializableField(1)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private TimeSpan _minSpawnTime; + + [SerializableField(2)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private TimeSpan _maxSpawnTime; + + [CommandProperty(AccessLevel.GameMaster)] + public override bool Locked + { + get => base.Locked; + set { - Level1, - Level2, - Level3, - Level4, - Level5, - Level6 - } - - private TreasureResetTimer m_ResetTimer; - - public BaseTreasureChest(int itemID, TreasureLevel level = TreasureLevel.Level2) - : base(itemID) - { - Level = level; - Locked = true; - Movable = false; - - SetLockLevel(); - GenerateTreasure(); - } - - public BaseTreasureChest(Serial serial) : base(serial) - { - } - - [CommandProperty(AccessLevel.GameMaster)] - public TreasureLevel Level { get; set; } - - [CommandProperty(AccessLevel.GameMaster)] - public short MaxSpawnTime { get; set; } = 60; - - [CommandProperty(AccessLevel.GameMaster)] - public short MinSpawnTime { get; set; } = 10; - - [CommandProperty(AccessLevel.GameMaster)] - public override bool Locked - { - get => base.Locked; - set + if (base.Locked != value) { - if (base.Locked != value) + base.Locked = value; + + if (!value) { - base.Locked = value; - - if (!value) - { - StartResetTimer(); - } + StartResetTimer(); } } } - - public override bool IsDecoContainer => false; - - public override string DefaultName - { - get - { - if (Locked) - { - return "a locked treasure chest"; - } - - return "a treasure chest"; - } - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); - writer.Write((byte)Level); - writer.Write(MinSpawnTime); - writer.Write(MaxSpawnTime); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - Level = (TreasureLevel)reader.ReadByte(); - MinSpawnTime = reader.ReadShort(); - MaxSpawnTime = reader.ReadShort(); - - if (!Locked) - { - StartResetTimer(); - } - } - - protected virtual void SetLockLevel() - { - RequiredSkill = Level switch - { - TreasureLevel.Level1 => LockLevel = 5, - TreasureLevel.Level2 => LockLevel = 20, - TreasureLevel.Level3 => LockLevel = 50, - TreasureLevel.Level4 => LockLevel = 70, - TreasureLevel.Level5 => LockLevel = 90, - TreasureLevel.Level6 => LockLevel = 100, - _ => RequiredSkill - }; - } - - private void StartResetTimer() - { - if (m_ResetTimer == null) - { - m_ResetTimer = new TreasureResetTimer(this); - } - else - { - m_ResetTimer.Delay = TimeSpan.FromMinutes(Utility.Random(MinSpawnTime, MaxSpawnTime)); - } - - m_ResetTimer.Start(); - } - - protected virtual void GenerateTreasure() - { - var MinGold = 1; - var MaxGold = 2; - - switch (Level) - { - case TreasureLevel.Level1: - MinGold = 100; - MaxGold = 300; - break; - - case TreasureLevel.Level2: - MinGold = 300; - MaxGold = 600; - break; - - case TreasureLevel.Level3: - MinGold = 600; - MaxGold = 900; - break; - - case TreasureLevel.Level4: - MinGold = 900; - MaxGold = 1200; - break; - - case TreasureLevel.Level5: - MinGold = 1200; - MaxGold = 5000; - break; - - case TreasureLevel.Level6: - MinGold = 5000; - MaxGold = 9000; - break; - } - - DropItem(new Gold(MinGold, MaxGold)); - } - - public void ClearContents() - { - for (var i = Items.Count - 1; i >= 0; --i) - { - if (i < Items.Count) - { - Items[i].Delete(); - } - } - } - - public void Reset() - { - if (m_ResetTimer != null) - { - if (m_ResetTimer.Running) - { - m_ResetTimer.Stop(); - } - } - - Locked = true; - ClearContents(); - GenerateTreasure(); - } - - private class TreasureResetTimer : Timer - { - private readonly BaseTreasureChest m_Chest; - - public TreasureResetTimer(BaseTreasureChest chest) : base( - TimeSpan.FromMinutes(Utility.Random(chest.MinSpawnTime, chest.MaxSpawnTime)) - ) - { - m_Chest = chest; - } - - protected override void OnTick() - { - m_Chest.Reset(); - } - } + } + + public override bool IsDecoContainer => false; + + public override string DefaultName => Locked ? "a locked treasure chest" : "a treasure chest"; + + [AfterDeserialization] + private void AfterDeserialization() + { + if (!Locked) + { + StartResetTimer(); + } + } + + private void Deserialize(IGenericReader reader, int version) + { + _level = (TreasureLevel)reader.ReadByte(); + _minSpawnTime = TimeSpan.FromMinutes(reader.ReadShort()); + _maxSpawnTime = TimeSpan.FromMinutes(reader.ReadShort()); + } + + protected virtual void SetLockLevel() + { + RequiredSkill = _level switch + { + TreasureLevel.Level1 => LockLevel = 5, + TreasureLevel.Level2 => LockLevel = 20, + TreasureLevel.Level3 => LockLevel = 50, + TreasureLevel.Level4 => LockLevel = 70, + TreasureLevel.Level5 => LockLevel = 90, + TreasureLevel.Level6 => LockLevel = 100, + _ => LockLevel = 120 + }; + } + + private void StartResetTimer() + { + _resetTimer.Cancel(); + + var randomDuration = Utility.RandomMinMax(_minSpawnTime.Ticks, _maxSpawnTime.Ticks); + Timer.StartTimer(TimeSpan.FromTicks(randomDuration), Reset, out _resetTimer); + } + + protected virtual void GenerateTreasure() + { + var gold = _level switch + { + TreasureLevel.Level1 => Utility.RandomMinMax(100, 300), + TreasureLevel.Level2 => Utility.RandomMinMax(300, 600), + TreasureLevel.Level3 => Utility.RandomMinMax(600, 900), + TreasureLevel.Level4 => Utility.RandomMinMax(900, 1200), + TreasureLevel.Level5 => Utility.RandomMinMax(1200, 5000), + _ => Utility.RandomMinMax(5000, 9000), + }; + + DropItem(new Gold(gold)); + } + + public void ClearContents() + { + for (var i = Items.Count - 1; i >= 0; --i) + { + if (i < Items.Count) + { + Items[i].Delete(); + } + } + } + + public void Reset() + { + _resetTimer.Cancel(); + Locked = true; + ClearContents(); + GenerateTreasure(); } } diff --git a/Projects/UOContent/Items/Containers/ParagonChest.cs b/Projects/UOContent/Items/Containers/ParagonChest.cs index 94debdc29..9dab1ed92 100644 --- a/Projects/UOContent/Items/Containers/ParagonChest.cs +++ b/Projects/UOContent/Items/Containers/ParagonChest.cs @@ -1,216 +1,187 @@ -namespace Server.Items +namespace Server.Items; + +[Flippable] +[Serializable(0, false)] +public partial class ParagonChest : LockableContainer { - [Flippable] - public class ParagonChest : LockableContainer + private static readonly int[] _itemIDs = { - private static readonly int[] m_ItemIDs = + 0x9AB, 0xE40, 0xE41, 0xE7C + }; + + private static readonly int[] _hues = + { + 0x0, 0x455, 0x47E, 0x89F, 0x8A5, 0x8AB, + 0x966, 0x96D, 0x972, 0x973, 0x979 + }; + + [InternString] + [SerializableField(0, "private", "private")] + private string _name; + + [Constructible] + public ParagonChest(string name, int level) : base(_itemIDs.RandomElement()) + { + _name = name; + Hue = _hues.RandomElement(); + Fill(level); + } + + public override void OnSingleClick(Mobile from) + { + base.OnSingleClick(from); + LabelTo(from, 1063449, _name); + } + + public override void GetProperties(ObjectPropertyList list) + { + base.GetProperties(list); + + list.Add(1063449, _name); + } + + private static void GetRandomAOSStats(out int attributeCount, out int min, out int max) + { + var rnd = Utility.Random(15); + + if (rnd < 1) { - 0x9AB, 0xE40, 0xE41, 0xE7C + attributeCount = Utility.RandomMinMax(2, 6); + min = 20; + max = 70; + } + else if (rnd < 3) + { + attributeCount = Utility.RandomMinMax(2, 4); + min = 20; + max = 50; + } + else if (rnd < 6) + { + attributeCount = Utility.RandomMinMax(2, 3); + min = 20; + max = 40; + } + else if (rnd < 10) + { + attributeCount = Utility.RandomMinMax(1, 2); + min = 10; + max = 30; + } + else + { + attributeCount = 1; + min = 10; + max = 20; + } + } + + public void Flip() + { + ItemID = ItemID switch + { + 0x9AB => 0xE7C, + 0xE7C => 0x9AB, + 0xE40 => 0xE41, + 0xE41 => 0xE40, + _ => ItemID + }; + } + + private void Fill(int level) + { + TrapType = TrapType.ExplosionTrap; + TrapPower = level * 25; + TrapLevel = level; + Locked = true; + + RequiredSkill = level switch + { + 1 => 36, + 2 => 76, + 3 => 84, + 4 => 92, + 5 => 100, + _ => RequiredSkill }; - private static readonly int[] m_Hues = - { - 0x0, 0x455, 0x47E, 0x89F, 0x8A5, 0x8AB, - 0x966, 0x96D, 0x972, 0x973, 0x979 - }; + LockLevel = RequiredSkill - 10; + MaxLockLevel = RequiredSkill + 40; - private string m_Name; + DropItem(new Gold(level * 200)); - [Constructible] - public ParagonChest(string name, int level) : base(m_ItemIDs.RandomElement()) + for (var i = 0; i < level; ++i) { - m_Name = name; - Hue = m_Hues.RandomElement(); - Fill(level); + DropItem(Loot.RandomScroll(0, 63, SpellbookType.Regular)); } - public ParagonChest(Serial serial) : base(serial) + for (var i = 0; i < level * 2; ++i) { - } + var item = Core.AOS ? Loot.RandomArmorOrShieldOrWeaponOrJewelry() : Loot.RandomArmorOrShieldOrWeapon(); - public override void OnSingleClick(Mobile from) - { - base.OnSingleClick(from); - LabelTo(from, 1063449, m_Name); - } - - public override void GetProperties(ObjectPropertyList list) - { - base.GetProperties(list); - - list.Add(1063449, m_Name); - } - - private static void GetRandomAOSStats(out int attributeCount, out int min, out int max) - { - var rnd = Utility.Random(15); - - if (rnd < 1) + if (item is BaseWeapon weapon) { - attributeCount = Utility.RandomMinMax(2, 6); - min = 20; - max = 70; - } - else if (rnd < 3) - { - attributeCount = Utility.RandomMinMax(2, 4); - min = 20; - max = 50; - } - else if (rnd < 6) - { - attributeCount = Utility.RandomMinMax(2, 3); - min = 20; - max = 40; - } - else if (rnd < 10) - { - attributeCount = Utility.RandomMinMax(1, 2); - min = 10; - max = 30; - } - else - { - attributeCount = 1; - min = 10; - max = 20; - } - } - - public void Flip() - { - ItemID = ItemID switch - { - 0x9AB => 0xE7C, - 0xE7C => 0x9AB, - 0xE40 => 0xE41, - 0xE41 => 0xE40, - _ => ItemID - }; - } - - private void Fill(int level) - { - TrapType = TrapType.ExplosionTrap; - TrapPower = level * 25; - TrapLevel = level; - Locked = true; - - RequiredSkill = level switch - { - 1 => 36, - 2 => 76, - 3 => 84, - 4 => 92, - 5 => 100, - _ => RequiredSkill - }; - - LockLevel = RequiredSkill - 10; - MaxLockLevel = RequiredSkill + 40; - - DropItem(new Gold(level * 200)); - - for (var i = 0; i < level; ++i) - { - DropItem(Loot.RandomScroll(0, 63, SpellbookType.Regular)); - } - - for (var i = 0; i < level * 2; ++i) - { - Item item; - if (Core.AOS) { - item = Loot.RandomArmorOrShieldOrWeaponOrJewelry(); + GetRandomAOSStats(out var attributeCount, out var min, out var max); + BaseRunicTool.ApplyAttributesTo(weapon, attributeCount, min, max); } else { - item = Loot.RandomArmorOrShieldOrWeapon(); + weapon.DamageLevel = (WeaponDamageLevel)Utility.Random(6); + weapon.AccuracyLevel = (WeaponAccuracyLevel)Utility.Random(6); + weapon.DurabilityLevel = (WeaponDurabilityLevel)Utility.Random(6); } - if (item is BaseWeapon weapon) - { - if (Core.AOS) - { - GetRandomAOSStats(out var attributeCount, out var min, out var max); - BaseRunicTool.ApplyAttributesTo(weapon, attributeCount, min, max); - } - else - { - weapon.DamageLevel = (WeaponDamageLevel)Utility.Random(6); - weapon.AccuracyLevel = (WeaponAccuracyLevel)Utility.Random(6); - weapon.DurabilityLevel = (WeaponDurabilityLevel)Utility.Random(6); - } - - DropItem(weapon); - } - else if (item is BaseArmor armor) - { - if (Core.AOS) - { - GetRandomAOSStats(out var attributeCount, out var min, out var max); - BaseRunicTool.ApplyAttributesTo(armor, attributeCount, min, max); - } - else - { - armor.ProtectionLevel = (ArmorProtectionLevel)Utility.Random(6); - armor.Durability = (ArmorDurabilityLevel)Utility.Random(6); - } - - DropItem(armor); - } - else if (item is BaseHat hat) - { - if (Core.AOS) - { - GetRandomAOSStats(out var attributeCount, out var min, out var max); - BaseRunicTool.ApplyAttributesTo(hat, attributeCount, min, max); - } - - DropItem(hat); - } - else if (item is BaseJewel jewel) + DropItem(weapon); + } + else if (item is BaseArmor armor) + { + if (Core.AOS) { GetRandomAOSStats(out var attributeCount, out var min, out var max); - BaseRunicTool.ApplyAttributesTo(jewel, attributeCount, min, max); - - DropItem(jewel); + BaseRunicTool.ApplyAttributesTo(armor, attributeCount, min, max); + } + else + { + armor.ProtectionLevel = (ArmorProtectionLevel)Utility.Random(6); + armor.Durability = (ArmorDurabilityLevel)Utility.Random(6); } - } - for (var i = 0; i < level; i++) + DropItem(armor); + } + else if (item is BaseHat hat) { - var item = Loot.RandomPossibleReagent(); - item.Amount = Utility.RandomMinMax(40, 60); - DropItem(item); - } + if (Core.AOS) + { + GetRandomAOSStats(out var attributeCount, out var min, out var max); + BaseRunicTool.ApplyAttributesTo(hat, attributeCount, min, max); + } - for (var i = 0; i < level; i++) + DropItem(hat); + } + else if (item is BaseJewel jewel) { - var item = Loot.RandomGem(); - DropItem(item); + GetRandomAOSStats(out var attributeCount, out var min, out var max); + BaseRunicTool.ApplyAttributesTo(jewel, attributeCount, min, max); + + DropItem(jewel); } - - DropItem(new TreasureMap(level + 1, Utility.RandomBool() ? Map.Felucca : Map.Trammel)); } - public override void Serialize(IGenericWriter writer) + for (var i = 0; i < level; i++) { - base.Serialize(writer); - - writer.Write(0); // version - - writer.Write(m_Name); + var item = Loot.RandomPossibleReagent(); + item.Amount = Utility.RandomMinMax(40, 60); + DropItem(item); } - public override void Deserialize(IGenericReader reader) + for (var i = 0; i < level; i++) { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - m_Name = Utility.Intern(reader.ReadString()); + var item = Loot.RandomGem(); + DropItem(item); } + + DropItem(new TreasureMap(level + 1, Utility.RandomBool() ? Map.Felucca : Map.Trammel)); } } diff --git a/Projects/UOContent/Items/Containers/Strongbox.cs b/Projects/UOContent/Items/Containers/Strongbox.cs index a1d6b8ca8..880192a72 100644 --- a/Projects/UOContent/Items/Containers/Strongbox.cs +++ b/Projects/UOContent/Items/Containers/Strongbox.cs @@ -2,147 +2,114 @@ using System; using System.Collections.Generic; using Server.Multis; -namespace Server.Items +namespace Server.Items; + +[Flippable(0xE80, 0x9A8)] +[Serializable(0, false)] +public partial class StrongBox : BaseContainer, IChoppable { - [Flippable(0xE80, 0x9A8)] - public class StrongBox : BaseContainer, IChoppable + [InvalidateProperties] + [SerializableField(0)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private Mobile _owner; + + [InvalidateProperties] + [SerializableField(1)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private BaseHouse _house; + + public StrongBox(Mobile owner, BaseHouse house) : base(0xE80) { - private BaseHouse m_House; - private Mobile m_Owner; + _owner = owner; + _house = house; - public StrongBox(Mobile owner, BaseHouse house) : base(0xE80) + MaxItems = 25; + } + + public override double DefaultWeight => 100; + public override int LabelNumber => 1023712; + + public override int DefaultMaxWeight => 0; + + public override bool Decays => _house == null || _owner?.Deleted != false || !_house.IsCoOwner(_owner); + + public override TimeSpan DecayTime => TimeSpan.FromMinutes(30.0); + + public void OnChop(Mobile from) + { + if (_house?.Deleted != false || _owner?.Deleted != false || from == _owner || _house.IsOwner(from)) { - m_Owner = owner; - m_House = house; - - MaxItems = 25; - } - - public StrongBox(Serial serial) : base(serial) - { - } - - public override double DefaultWeight => 100; - public override int LabelNumber => 1023712; - - [CommandProperty(AccessLevel.GameMaster)] - public Mobile Owner - { - get => m_Owner; - set - { - m_Owner = value; - InvalidateProperties(); - } - } - - public override int DefaultMaxWeight => 0; - - public override bool Decays => m_House == null || m_Owner?.Deleted != false || !m_House.IsCoOwner(m_Owner); - - public override TimeSpan DecayTime => TimeSpan.FromMinutes(30.0); - - public void OnChop(Mobile from) - { - if (m_House?.Deleted != false || m_Owner?.Deleted != false || from == m_Owner || m_House.IsOwner(from)) - { - Chop(from); - } - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); // version - - writer.Write(m_Owner); - writer.Write(m_House); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - switch (version) - { - case 0: - { - m_Owner = reader.ReadEntity(); - m_House = reader.ReadEntity(); - - break; - } - } - - Timer.StartTimer(TimeSpan.FromSeconds(1.0), Validate); - } - - private void Validate() - { - if (m_Owner != null && m_House?.IsCoOwner(m_Owner) == false) - { - Console.WriteLine("Warning: Destroying strongbox of {0}", m_Owner.Name); - Destroy(); - } - } - - public override void AddNameProperty(ObjectPropertyList list) - { - if (m_Owner != null) - { - list.Add(1042887, m_Owner.Name); // a strong box owned by ~1_OWNER_NAME~ - } - else - { - base.AddNameProperty(list); - } - } - - public override void OnSingleClick(Mobile from) - { - if (m_Owner != null) - { - LabelTo(from, 1042887, m_Owner.Name); // a strong box owned by ~1_OWNER_NAME~ - - if (CheckContentDisplay(from)) - { - LabelTo(from, "({0} items, {1} stones)", TotalItems, TotalWeight); - } - } - else - { - base.OnSingleClick(from); - } - } - - public override bool IsAccessibleTo(Mobile m) => - m_Owner?.Deleted != false || m_House?.Deleted != false || - m.AccessLevel >= AccessLevel.GameMaster || - m == m_Owner && m_House.IsCoOwner(m) && base.IsAccessibleTo(m); - - private void Chop(Mobile from) - { - Effects.PlaySound(Location, Map, 0x3B3); - from.SendLocalizedMessage(500461); // You destroy the item. - Destroy(); - } - - public Container ConvertToStandardContainer() - { - Container metalBox = new MetalBox(); - var subItems = new List(Items); - - foreach (var subItem in subItems) - { - metalBox.AddItem(subItem); - } - - Delete(); - - return metalBox; + Chop(from); } } + + [AfterDeserialization] + private void AfterDeserialization() + { + Timer.StartTimer(TimeSpan.FromSeconds(1.0), Validate); + } + + private void Validate() + { + if (_owner != null && _house?.IsCoOwner(_owner) == false) + { + Console.WriteLine("Warning: Destroying strongbox of {0}", _owner.Name); + Destroy(); + } + } + + public override void AddNameProperty(ObjectPropertyList list) + { + if (_owner != null) + { + list.Add(1042887, _owner.Name); // a strong box owned by ~1_OWNER_NAME~ + } + else + { + base.AddNameProperty(list); + } + } + + public override void OnSingleClick(Mobile from) + { + if (_owner == null) + { + base.OnSingleClick(from); + return; + } + + LabelTo(from, 1042887, _owner.Name); // a strong box owned by ~1_OWNER_NAME~ + + if (CheckContentDisplay(from)) + { + LabelTo(from, "({0} items, {1} stones)", TotalItems, TotalWeight); + } + } + + public override bool IsAccessibleTo(Mobile m) => + _owner?.Deleted != false || _house?.Deleted != false || + m.AccessLevel >= AccessLevel.GameMaster || + m == _owner && _house.IsCoOwner(m) && base.IsAccessibleTo(m); + + private void Chop(Mobile from) + { + Effects.PlaySound(Location, Map, 0x3B3); + from.SendLocalizedMessage(500461); // You destroy the item. + Destroy(); + } + + public Container ConvertToStandardContainer() + { + Container metalBox = new MetalBox(); + var subItems = new List(Items); + + foreach (var subItem in subItems) + { + metalBox.AddItem(subItem); + } + + Delete(); + + return metalBox; + } } diff --git a/Projects/UOContent/Migrations/Server.Items.BaseTreasureChest.v1.json b/Projects/UOContent/Migrations/Server.Items.BaseTreasureChest.v1.json new file mode 100644 index 000000000..9fb711a6b --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.BaseTreasureChest.v1.json @@ -0,0 +1,21 @@ +{ + "version": 1, + "type": "Server.Items.BaseTreasureChest", + "properties": [ + { + "name": "Level", + "type": "Server.Items.BaseTreasureChest.TreasureLevel", + "rule": "EnumMigrationRule" + }, + { + "name": "MinSpawnTime", + "type": "System.TimeSpan", + "rule": "PrimitiveTypeMigrationRule" + }, + { + "name": "MaxSpawnTime", + "type": "System.TimeSpan", + "rule": "PrimitiveTypeMigrationRule" + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.ParagonChest.v0.json b/Projects/UOContent/Migrations/Server.Items.ParagonChest.v0.json new file mode 100644 index 000000000..285d0ce98 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.ParagonChest.v0.json @@ -0,0 +1,14 @@ +{ + "version": 0, + "type": "Server.Items.ParagonChest", + "properties": [ + { + "name": "Name", + "type": "string", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "InternString" + ] + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.StrongBox.v0.json b/Projects/UOContent/Migrations/Server.Items.StrongBox.v0.json new file mode 100644 index 000000000..5949fdd81 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.StrongBox.v0.json @@ -0,0 +1,16 @@ +{ + "version": 0, + "type": "Server.Items.StrongBox", + "properties": [ + { + "name": "Owner", + "type": "Server.Mobile", + "rule": "SerializableInterfaceMigrationRule" + }, + { + "name": "House", + "type": "Server.Multis.BaseHouse", + "rule": "SerializableInterfaceMigrationRule" + } + ] +} \ No newline at end of file From 54b268c02fde37c5417510d03d828f68a4939a5b Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 27 Feb 2022 18:02:36 -0800 Subject: [PATCH 091/213] fix: Codegens treasure chests (#949) --- .../Items/Containers/TreasureChest.cs | 106 ++----- .../TreasureChests/TreasureChestLevel1.cs | 176 +++++------ .../TreasureChests/TreasureChestLevel2.cs | 227 +++++++-------- .../TreasureChests/TreasureChestLevel3.cs | 263 ++++++++--------- .../TreasureChests/TreasureChestLevel4.cs | 274 ++++++++---------- ...ver.Items.MetalGoldenTreasureChest.v0.json | 4 + .../Server.Items.MetalTreasureChest.v0.json | 4 + .../Server.Items.TreasureChestLevel1.v0.json | 4 + .../Server.Items.TreasureChestLevel2.v0.json | 4 + .../Server.Items.TreasureChestLevel3.v0.json | 4 + .../Server.Items.TreasureChestLevel4.v0.json | 4 + .../Server.Items.WoodenTreasureChest.v0.json | 4 + 12 files changed, 470 insertions(+), 604 deletions(-) create mode 100644 Projects/UOContent/Migrations/Server.Items.MetalGoldenTreasureChest.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.MetalTreasureChest.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.TreasureChestLevel1.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.TreasureChestLevel2.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.TreasureChestLevel3.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.TreasureChestLevel4.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.WoodenTreasureChest.v0.json diff --git a/Projects/UOContent/Items/Containers/TreasureChest.cs b/Projects/UOContent/Items/Containers/TreasureChest.cs index b578438c4..d0f9f3acb 100644 --- a/Projects/UOContent/Items/Containers/TreasureChest.cs +++ b/Projects/UOContent/Items/Containers/TreasureChest.cs @@ -1,83 +1,31 @@ -namespace Server.Items +namespace Server.Items; + +[Flippable(0xe43, 0xe42)] +[Serializable(0, false)] +public partial class WoodenTreasureChest : BaseTreasureChest { - [Flippable(0xe43, 0xe42)] - public class WoodenTreasureChest : BaseTreasureChest + [Constructible] + public WoodenTreasureChest() : base(0xE43) + { + } +} + +[Flippable(0xe41, 0xe40)] +[Serializable(0, false)] +public partial class MetalGoldenTreasureChest : BaseTreasureChest +{ + [Constructible] + public MetalGoldenTreasureChest() : base(0xE41) + { + } +} + +[Flippable(0x9ab, 0xe7c)] +[Serializable(0, false)] +public partial class MetalTreasureChest : BaseTreasureChest +{ + [Constructible] + public MetalTreasureChest() : base(0x9AB) { - [Constructible] - public WoodenTreasureChest() : base(0xE43) - { - } - - public WoodenTreasureChest(Serial serial) : base(serial) - { - } - - 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(); - } - } - - [Flippable(0xe41, 0xe40)] - public class MetalGoldenTreasureChest : BaseTreasureChest - { - [Constructible] - public MetalGoldenTreasureChest() : base(0xE41) - { - } - - public MetalGoldenTreasureChest(Serial serial) : base(serial) - { - } - - 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(); - } - } - - [Flippable(0x9ab, 0xe7c)] - public class MetalTreasureChest : BaseTreasureChest - { - [Constructible] - public MetalTreasureChest() : base(0x9AB) - { - } - - public MetalTreasureChest(Serial serial) : base(serial) - { - } - - 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/TreasureChests/TreasureChestLevel1.cs b/Projects/UOContent/Items/TreasureChests/TreasureChestLevel1.cs index 1f8f4c6fa..28dacc9a7 100644 --- a/Projects/UOContent/Items/TreasureChests/TreasureChestLevel1.cs +++ b/Projects/UOContent/Items/TreasureChests/TreasureChestLevel1.cs @@ -1,124 +1,94 @@ using System; -namespace Server.Items +namespace Server.Items; + +[Serializable(0, false)] +public partial class TreasureChestLevel1 : LockableContainer { - public class TreasureChestLevel1 : LockableContainer + [Constructible] + public TreasureChestLevel1() : base(0xE41) { - private const int m_Level = 1; + SetChestAppearance(); + Movable = false; - [Constructible] - public TreasureChestLevel1() - : base(0xE41) + TrapType = TrapType.DartTrap; + TrapPower = Utility.Random(1, 25); + Locked = true; + + RequiredSkill = 57; + LockLevel = RequiredSkill - Utility.Random(1, 10); + MaxLockLevel = RequiredSkill + Utility.Random(1, 10); + + // According to OSI, loot in level 1 chest is: + // Gold 25 - 50 + // Bolts 10 + // Gems + // Normal weapon + // Normal armour + // Normal clothing + // Normal jewelry + + // Gold + DropItem(new Gold(Utility.Random(30, 100))); + + // Drop bolts + // DropItem( new Bolt( 10 ) ); + + // Gems + if (Utility.RandomBool()) { - SetChestAppearance(); - Movable = false; - - TrapType = TrapType.DartTrap; - TrapPower = m_Level * Utility.Random(1, 25); - Locked = true; - - RequiredSkill = 57; - LockLevel = RequiredSkill - Utility.Random(1, 10); - MaxLockLevel = RequiredSkill + Utility.Random(1, 10); - - // According to OSI, loot in level 1 chest is: - // Gold 25 - 50 - // Bolts 10 - // Gems - // Normal weapon - // Normal armour - // Normal clothing - // Normal jewelry - - // Gold - DropItem(new Gold(Utility.Random(30, 100))); - - // Drop bolts - // DropItem( new Bolt( 10 ) ); - - // Gems - if (Utility.RandomBool()) - { - var GemLoot = Loot.RandomGem(); - GemLoot.Amount = Utility.Random(1, 3); - DropItem(GemLoot); - } - - // Weapon - if (Utility.RandomBool()) - { - DropItem(Loot.RandomWeapon()); - } - - // Armour - if (Utility.RandomBool()) - { - DropItem(Loot.RandomArmorOrShield()); - } - - // Clothing - if (Utility.RandomBool()) - { - DropItem(Loot.RandomClothing()); - } - - // Jewelry - if (Utility.RandomBool()) - { - DropItem(Loot.RandomJewelry()); - } + var gems = Loot.RandomGem(); + gems.Amount = Utility.Random(1, 3); + DropItem(gems); } - public TreasureChestLevel1(Serial serial) - : base(serial) + // Weapon + if (Utility.RandomBool()) { + DropItem(Loot.RandomWeapon()); } - public override bool Decays => true; - - public override bool IsDecoContainer => false; - - public override TimeSpan DecayTime => TimeSpan.FromMinutes(Utility.Random(15, 60)); - - public override int DefaultGumpID => 0x42; - - public override int DefaultDropSound => 0x42; - - public override Rectangle2D Bounds => new(18, 105, 144, 73); - - private void SetChestAppearance() + // Armour + if (Utility.RandomBool()) { - var UseFirstItemId = Utility.RandomBool(); - - switch (Utility.RandomList(0, 1, 2)) - { - case 0: // Large Crate - ItemID = UseFirstItemId ? 0xe3c : 0xe3d; - GumpID = 0x44; - break; - - case 1: // Medium Crate - ItemID = UseFirstItemId ? 0xe3e : 0xe3f; - GumpID = 0x44; - break; - - case 2: // Small Crate - ItemID = UseFirstItemId ? 0x9a9 : 0xe7e; - GumpID = 0x44; - break; - } + DropItem(Loot.RandomArmorOrShield()); } - public override void Serialize(IGenericWriter writer) + // Clothing + if (Utility.RandomBool()) { - base.Serialize(writer); - writer.Write(1); // version + DropItem(Loot.RandomClothing()); } - public override void Deserialize(IGenericReader reader) + // Jewelry + if (Utility.RandomBool()) { - base.Deserialize(reader); - var version = reader.ReadInt(); + DropItem(Loot.RandomJewelry()); } } + + public override bool Decays => true; + + public override bool IsDecoContainer => false; + + public override TimeSpan DecayTime => TimeSpan.FromMinutes(Utility.Random(15, 60)); + + public override int DefaultGumpID => 0x44; + + public override int DefaultDropSound => 0x42; + + public override Rectangle2D Bounds => new(18, 105, 144, 73); + + private void SetChestAppearance() + { + ItemID = Utility.Random(6) switch + { + 0 => 0xe3c, // Large Crate + 1 => 0xe3d, // Large Crate + 2 => 0xe3e, // Medium Crate + 3 => 0xe3f, // Medium Crate + 4 => 0x9a9, // Small Crate + _ => 0xe7e // Small Crate + }; + } } diff --git a/Projects/UOContent/Items/TreasureChests/TreasureChestLevel2.cs b/Projects/UOContent/Items/TreasureChests/TreasureChestLevel2.cs index 14e4d3946..00ff932ac 100644 --- a/Projects/UOContent/Items/TreasureChests/TreasureChestLevel2.cs +++ b/Projects/UOContent/Items/TreasureChests/TreasureChestLevel2.cs @@ -1,147 +1,116 @@ using System; -namespace Server.Items +namespace Server.Items; + +[Serializable(0, false)] +public partial class TreasureChestLevel2 : LockableContainer { - public class TreasureChestLevel2 : LockableContainer + [Constructible] + public TreasureChestLevel2() : base(0xE41) { - private const int m_Level = 2; + SetChestAppearance(); + Movable = false; - [Constructible] - public TreasureChestLevel2() - : base(0xE41) + TrapType = TrapType.ExplosionTrap; + TrapPower = 2 * Utility.Random(1, 25); + Locked = true; + + RequiredSkill = 72; + LockLevel = RequiredSkill - Utility.Random(1, 10); + MaxLockLevel = RequiredSkill + Utility.Random(1, 10); + + // According to OSI, loot in level 2 chest is: + // Gold 80 - 150 + // Arrows 10 + // Reagents + // Scrolls + // Potions + // Gems + + // Gold + DropItem(new Gold(Utility.Random(70, 100))); + + // Drop bolts + // DropItem( new Arrow( 10 ) ); + + // Reagents + for (var i = Utility.Random(3); i > 0; i--) { - SetChestAppearance(); - Movable = false; - - TrapType = TrapType.ExplosionTrap; - TrapPower = m_Level * Utility.Random(1, 25); - Locked = true; - - RequiredSkill = 72; - LockLevel = RequiredSkill - Utility.Random(1, 10); - MaxLockLevel = RequiredSkill + Utility.Random(1, 10); - - // According to OSI, loot in level 2 chest is: - // Gold 80 - 150 - // Arrows 10 - // Reagents - // Scrolls - // Potions - // Gems - - // Gold - DropItem(new Gold(Utility.Random(70, 100))); - - // Drop bolts - // DropItem( new Arrow( 10 ) ); - - // Reagents - for (var i = Utility.Random(1, m_Level); i > 1; i--) - { - var ReagentLoot = Loot.RandomReagent(); - ReagentLoot.Amount = Utility.Random(1, m_Level); - DropItem(ReagentLoot); - } - - // Scrolls - for (var i = Utility.Random(1, m_Level); i > 1; i--) - { - Item ScrollLoot = Loot.RandomScroll(0, 39, SpellbookType.Regular); - ScrollLoot.Amount = Utility.Random(1, 8); - DropItem(ScrollLoot); - } - - // Potions - for (var i = Utility.Random(1, m_Level); i > 1; i--) - { - var PotionLoot = Loot.RandomPotion(); - DropItem(PotionLoot); - } - - // Gems - for (var i = Utility.Random(1, m_Level); i > 1; i--) - { - var GemLoot = Loot.RandomGem(); - GemLoot.Amount = Utility.Random(1, 6); - DropItem(GemLoot); - } + var reagents = Loot.RandomReagent(); + reagents.Amount = Utility.Random(1, 2); + DropItem(reagents); } - public TreasureChestLevel2(Serial serial) - : base(serial) + // Scrolls + if (Utility.RandomBool()) { + var scrolls = Loot.RandomScroll(0, 39, SpellbookType.Regular); + scrolls.Amount = Utility.Random(1, 8); + DropItem(scrolls); } - public override bool Decays => true; - - public override bool IsDecoContainer => false; - - public override TimeSpan DecayTime => TimeSpan.FromMinutes(Utility.Random(15, 60)); - - public override int DefaultGumpID => 0x42; - - public override int DefaultDropSound => 0x42; - - public override Rectangle2D Bounds => new(18, 105, 144, 73); - - private void SetChestAppearance() + // Potions + if (Utility.RandomBool()) { - var UseFirstItemId = Utility.RandomBool(); - - switch (Utility.RandomList(0, 1, 2, 3, 4, 5, 6, 7)) - { - case 0: // Large Crate - ItemID = UseFirstItemId ? 0xe3c : 0xe3d; - GumpID = 0x44; - break; - - case 1: // Medium Crate - ItemID = UseFirstItemId ? 0xe3e : 0xe3f; - GumpID = 0x44; - break; - - case 2: // Small Crate - ItemID = UseFirstItemId ? 0x9a9 : 0xe7e; - GumpID = 0x44; - break; - - case 3: // Wooden Chest - ItemID = UseFirstItemId ? 0xe42 : 0xe43; - GumpID = 0x49; - break; - - case 4: // Metal Chest - ItemID = UseFirstItemId ? 0x9ab : 0xe7c; - GumpID = 0x4A; - break; - - case 5: // Metal Golden Chest - ItemID = UseFirstItemId ? 0xe40 : 0xe41; - GumpID = 0x42; - break; - - case 6: // Keg - ItemID = 0xe7f; - GumpID = 0x3e; - break; - - case 7: // Barrel - ItemID = 0xe77; - GumpID = 0x3e; - break; - } + DropItem(Loot.RandomPotion()); } - public override void Serialize(IGenericWriter writer) + // Gems + if (Utility.RandomBool()) { - base.Serialize(writer); - writer.Write(1); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); + var gems = Loot.RandomGem(); + gems.Amount = Utility.Random(1, 6); + DropItem(gems); } } + + public override bool Decays => true; + + public override bool IsDecoContainer => false; + + public override TimeSpan DecayTime => TimeSpan.FromMinutes(Utility.Random(15, 60)); + + public override int DefaultGumpID => 0x42; + + public override int DefaultDropSound => 0x42; + + public override Rectangle2D Bounds => new(18, 105, 144, 73); + + private static readonly ValueTuple[] _chestAppearances = + { + // Large Crate + ValueTuple.Create(0xe3c, 0x44), + ValueTuple.Create(0xe3d, 0x44), + + // Medium Crate + ValueTuple.Create(0xe3e, 0x44), + ValueTuple.Create(0xe3f, 0x44), + + // Small Crate + ValueTuple.Create(0x9a9, 0x44), + ValueTuple.Create(0xe7e, 0x44), + + // Wooden Chest + ValueTuple.Create(0xe42, 0x49), + ValueTuple.Create(0xe43, 0x49), + + // Metal Chest + ValueTuple.Create(0x9ab, 0x4A), + ValueTuple.Create(0xe7c, 0x4A), + + // Metal Golden Chest + ValueTuple.Create(0xe40, 0x42), + ValueTuple.Create(0xe41, 0x42), + + // Keg + ValueTuple.Create(0xe7f, 0x3e), + + // Barrel + ValueTuple.Create(0xe77, 0x3e), + }; + + private void SetChestAppearance() + { + (ItemID, GumpID) = _chestAppearances.RandomElement(); + } } diff --git a/Projects/UOContent/Items/TreasureChests/TreasureChestLevel3.cs b/Projects/UOContent/Items/TreasureChests/TreasureChestLevel3.cs index bcd179d9a..a4368ea8d 100644 --- a/Projects/UOContent/Items/TreasureChests/TreasureChestLevel3.cs +++ b/Projects/UOContent/Items/TreasureChests/TreasureChestLevel3.cs @@ -1,166 +1,143 @@ using System; -namespace Server.Items +namespace Server.Items; + +[Serializable(0, false)] +public partial class TreasureChestLevel3 : LockableContainer { - public class TreasureChestLevel3 : LockableContainer + [Constructible] + public TreasureChestLevel3() : base(0xE41) { - private const int m_Level = 3; + SetChestAppearance(); + Movable = false; - [Constructible] - public TreasureChestLevel3() - : base(0xE41) + TrapType = TrapType.PoisonTrap; + TrapPower = 3 * Utility.Random(1, 25); + Locked = true; + + RequiredSkill = 84; + LockLevel = RequiredSkill - Utility.Random(1, 10); + MaxLockLevel = RequiredSkill + Utility.Random(1, 10); + + // According to OSI, loot in level 3 chest is: + // Gold 250 - 350 + // Arrows 10 + // Reagents + // Scrolls + // Potions + // Gems + // Magic Wand + // Magic weapon + // Magic armour + // Magic clothing (not implemented) + // Magic jewelry (not implemented) + + // Gold + DropItem(new Gold(Utility.Random(180, 240))); + + // Drop bolts + // DropItem( new Arrow( 10 ) ); + + // Reagents + for (var i = Utility.Random(2); i >= 0; i--) { - SetChestAppearance(); - Movable = false; - - TrapType = TrapType.PoisonTrap; - TrapPower = m_Level * Utility.Random(1, 25); - Locked = true; - - RequiredSkill = 84; - LockLevel = RequiredSkill - Utility.Random(1, 10); - MaxLockLevel = RequiredSkill + Utility.Random(1, 10); - - // According to OSI, loot in level 3 chest is: - // Gold 250 - 350 - // Arrows 10 - // Reagents - // Scrolls - // Potions - // Gems - // Magic Wand - // Magic weapon - // Magic armour - // Magic clothing (not implemented) - // Magic jewelry (not implemented) - - // Gold - DropItem(new Gold(Utility.Random(180, 240))); - - // Drop bolts - // DropItem( new Arrow( 10 ) ); - - // Reagents - for (var i = Utility.Random(1, m_Level); i > 1; i--) - { - var ReagentLoot = Loot.RandomReagent(); - ReagentLoot.Amount = Utility.Random(1, 9); - DropItem(ReagentLoot); - } - - // Scrolls - for (var i = Utility.Random(1, m_Level); i > 1; i--) - { - Item ScrollLoot = Loot.RandomScroll(0, 47, SpellbookType.Regular); - ScrollLoot.Amount = Utility.Random(1, 12); - DropItem(ScrollLoot); - } - - // Potions - for (var i = Utility.Random(1, m_Level); i > 1; i--) - { - var PotionLoot = Loot.RandomPotion(); - DropItem(PotionLoot); - } - - // Gems - for (var i = Utility.Random(1, m_Level); i > 1; i--) - { - var GemLoot = Loot.RandomGem(); - GemLoot.Amount = Utility.Random(1, 9); - DropItem(GemLoot); - } - - // Magic Wand - for (var i = Utility.Random(1, m_Level); i > 1; i--) - { - DropItem(Loot.RandomWand()); - } - - // Equipment - for (var i = Utility.Random(1, m_Level); i > 1; i--) - { - var item = Loot.RandomArmorOrShieldOrWeapon(); - - if (item is BaseWeapon weapon) - { - weapon.DamageLevel = (WeaponDamageLevel)Utility.Random(m_Level); - weapon.AccuracyLevel = (WeaponAccuracyLevel)Utility.Random(m_Level); - weapon.DurabilityLevel = (WeaponDurabilityLevel)Utility.Random(m_Level); - weapon.Quality = WeaponQuality.Regular; - } - else if (item is BaseArmor armor) - { - armor.ProtectionLevel = (ArmorProtectionLevel)Utility.Random(m_Level); - armor.Durability = (ArmorDurabilityLevel)Utility.Random(m_Level); - armor.Quality = ArmorQuality.Regular; - } - - DropItem(item); - } - - // Clothing - for (var i = Utility.Random(1, 2); i > 1; i--) - { - DropItem(Loot.RandomClothing()); - } - - // Jewelry - for (var i = Utility.Random(1, 2); i > 1; i--) - { - DropItem(Loot.RandomJewelry()); - } + var reagents = Loot.RandomReagent(); + reagents.Amount = Utility.Random(1, 9); + DropItem(reagents); } - public TreasureChestLevel3(Serial serial) - : base(serial) + // Scrolls + for (var i = Utility.Random(3); i > 0; i--) { + var scrolls = Loot.RandomScroll(0, 47, SpellbookType.Regular); + scrolls.Amount = Utility.Random(1, 12); + DropItem(scrolls); } - public override bool Decays => true; - - public override bool IsDecoContainer => false; - - public override TimeSpan DecayTime => TimeSpan.FromMinutes(Utility.Random(15, 60)); - - public override int DefaultGumpID => 0x42; - - public override int DefaultDropSound => 0x42; - - public override Rectangle2D Bounds => new(18, 105, 144, 73); - - private void SetChestAppearance() + // Potions + for (var i = Utility.Random(3); i > 0; i--) { - var UseFirstItemId = Utility.RandomBool(); - switch (Utility.RandomList(0, 1, 2)) + DropItem(Loot.RandomPotion()); + } + + // Gems + for (var i = Utility.Random(3); i > 0; i--) + { + var gems = Loot.RandomGem(); + gems.Amount = Utility.Random(1, 9); + DropItem(gems); + } + + // Magic Wand + for (var i = Utility.Random(3); i > 0; i--) + { + DropItem(Loot.RandomWand()); + } + + // Equipment + for (var i = Utility.Random(3); i > 0; i--) + { + var item = Loot.RandomArmorOrShieldOrWeapon(); + + if (item is BaseWeapon weapon) { - case 0: // Wooden Chest - ItemID = UseFirstItemId ? 0xe42 : 0xe43; - GumpID = 0x49; - break; - - case 1: // Metal Chest - ItemID = UseFirstItemId ? 0x9ab : 0xe7c; - GumpID = 0x4A; - break; - - case 2: // Metal Golden Chest - ItemID = UseFirstItemId ? 0xe40 : 0xe41; - GumpID = 0x42; - break; + weapon.DamageLevel = (WeaponDamageLevel)Utility.Random(3); + weapon.AccuracyLevel = (WeaponAccuracyLevel)Utility.Random(3); + weapon.DurabilityLevel = (WeaponDurabilityLevel)Utility.Random(3); + weapon.Quality = WeaponQuality.Regular; } + else if (item is BaseArmor armor) + { + armor.ProtectionLevel = (ArmorProtectionLevel)Utility.Random(3); + armor.Durability = (ArmorDurabilityLevel)Utility.Random(3); + armor.Quality = ArmorQuality.Regular; + } + + DropItem(item); } - public override void Serialize(IGenericWriter writer) + // Clothing + for (var i = Utility.Random(3); i > 0; i--) { - base.Serialize(writer); - writer.Write(1); // version + DropItem(Loot.RandomClothing()); } - public override void Deserialize(IGenericReader reader) + // Jewelry + for (var i = Utility.Random(3); i > 0; i--) { - base.Deserialize(reader); - var version = reader.ReadInt(); + DropItem(Loot.RandomJewelry()); } } + + public override bool Decays => true; + + public override bool IsDecoContainer => false; + + public override TimeSpan DecayTime => TimeSpan.FromMinutes(Utility.Random(15, 60)); + + public override int DefaultGumpID => 0x42; + + public override int DefaultDropSound => 0x42; + + public override Rectangle2D Bounds => new(18, 105, 144, 73); + + private static readonly ValueTuple[] _chestAppearances = + { + // Wooden Chest + ValueTuple.Create(0xe42, 0x49), + ValueTuple.Create(0xe43, 0x49), + + // Metal Chest + ValueTuple.Create(0x9ab, 0x4A), + ValueTuple.Create(0xe7c, 0x4A), + + // Metal Golden Chest + ValueTuple.Create(0xe40, 0x42), + ValueTuple.Create(0xe41, 0x42), + }; + + private void SetChestAppearance() + { + (ItemID, GumpID) = _chestAppearances.RandomElement(); + } } diff --git a/Projects/UOContent/Items/TreasureChests/TreasureChestLevel4.cs b/Projects/UOContent/Items/TreasureChests/TreasureChestLevel4.cs index ba550a924..0c223e215 100644 --- a/Projects/UOContent/Items/TreasureChests/TreasureChestLevel4.cs +++ b/Projects/UOContent/Items/TreasureChests/TreasureChestLevel4.cs @@ -1,175 +1,149 @@ using System; -namespace Server.Items +namespace Server.Items; + +[Serializable(0, false)] +public partial class TreasureChestLevel4 : LockableContainer { - public class TreasureChestLevel4 : LockableContainer + [Constructible] + public TreasureChestLevel4() : base(0xE41) { - private const int m_Level = 4; + SetChestAppearance(); + Movable = false; - [Constructible] - public TreasureChestLevel4() - : base(0xE41) + TrapType = TrapType.ExplosionTrap; + TrapPower = 4 * Utility.Random(10, 25); + Locked = true; + + RequiredSkill = 92; + LockLevel = RequiredSkill - Utility.Random(1, 10); + MaxLockLevel = RequiredSkill + Utility.Random(1, 10); + + // According to OSI, loot in level 4 chest is: + // Gold 500 - 900 + // Reagents + // Scrolls + // Blank scrolls + // Potions + // Gems + // Magic Wand + // Magic weapon + // Magic armour + // Magic clothing (not implemented) + // Magic jewelry (not implemented) + // Crystal ball (not implemented) + + // Gold + DropItem(new Gold(Utility.Random(200, 400))); + + // Reagents + for (var i = Utility.Random(4); i > 0; i--) { - SetChestAppearance(); - Movable = false; - - TrapType = TrapType.ExplosionTrap; - TrapPower = m_Level * Utility.Random(10, 25); - Locked = true; - - RequiredSkill = 92; - LockLevel = RequiredSkill - Utility.Random(1, 10); - MaxLockLevel = RequiredSkill + Utility.Random(1, 10); - - // According to OSI, loot in level 4 chest is: - // Gold 500 - 900 - // Reagents - // Scrolls - // Blank scrolls - // Potions - // Gems - // Magic Wand - // Magic weapon - // Magic armour - // Magic clothing (not implemented) - // Magic jewelry (not implemented) - // Crystal ball (not implemented) - - // Gold - DropItem(new Gold(Utility.Random(200, 400))); - - // Reagents - for (var i = Utility.Random(1, m_Level); i > 1; i--) - { - var ReagentLoot = Loot.RandomReagent(); - ReagentLoot.Amount = 12; - DropItem(ReagentLoot); - } - - // Scrolls - for (var i = Utility.Random(1, m_Level); i > 1; i--) - { - Item ScrollLoot = Loot.RandomScroll(0, 47, SpellbookType.Regular); - ScrollLoot.Amount = 16; - DropItem(ScrollLoot); - } - - // Drop blank scrolls - DropItem(new BlankScroll(Utility.Random(1, m_Level))); - - // Potions - for (var i = Utility.Random(1, m_Level); i > 1; i--) - { - var PotionLoot = Loot.RandomPotion(); - DropItem(PotionLoot); - } - - // Gems - for (var i = Utility.Random(1, m_Level); i > 1; i--) - { - var GemLoot = Loot.RandomGem(); - GemLoot.Amount = 12; - DropItem(GemLoot); - } - - // Magic Wand - for (var i = Utility.Random(1, m_Level); i > 1; i--) - { - DropItem(Loot.RandomWand()); - } - - // Equipment - for (var i = Utility.Random(1, m_Level); i > 1; i--) - { - var item = Loot.RandomArmorOrShieldOrWeapon(); - - if (item is BaseWeapon weapon) - { - weapon.DamageLevel = (WeaponDamageLevel)Utility.Random(m_Level); - weapon.AccuracyLevel = (WeaponAccuracyLevel)Utility.Random(m_Level); - weapon.DurabilityLevel = (WeaponDurabilityLevel)Utility.Random(m_Level); - weapon.Quality = WeaponQuality.Regular; - } - else if (item is BaseArmor armor) - { - armor.ProtectionLevel = (ArmorProtectionLevel)Utility.Random(m_Level); - armor.Durability = (ArmorDurabilityLevel)Utility.Random(m_Level); - armor.Quality = ArmorQuality.Regular; - } - - DropItem(item); - } - - // Clothing - for (var i = Utility.Random(1, 2); i > 1; i--) - { - DropItem(Loot.RandomClothing()); - } - - // Jewelry - for (var i = Utility.Random(1, 2); i > 1; i--) - { - DropItem(Loot.RandomJewelry()); - } - - // Crystal ball (not implemented) + var reagents = Loot.RandomReagent(); + reagents.Amount = 12; + DropItem(reagents); } - public TreasureChestLevel4(Serial serial) - : base(serial) + // Scrolls + for (var i = Utility.Random(4); i > 0; i--) { + var scroll = Loot.RandomScroll(0, 47, SpellbookType.Regular); + scroll.Amount = 16; + DropItem(scroll); } - public override bool Decays => true; + // Drop blank scrolls + DropItem(new BlankScroll(Utility.Random(1, 4))); - public override bool IsDecoContainer => false; - - public override TimeSpan DecayTime => TimeSpan.FromMinutes(Utility.Random(15, 60)); - - public override int DefaultGumpID => 0x42; - - public override int DefaultDropSound => 0x42; - - public override Rectangle2D Bounds => new(18, 105, 144, 73); - - private void SetChestAppearance() + // Potions + for (var i = Utility.Random(4); i > 0; i--) { - var UseFirstItemId = Utility.RandomBool(); + DropItem(Loot.RandomPotion()); + } - switch (Utility.Random(4)) + // Gems + for (var i = Utility.Random(4); i > 0; i--) + { + var gems = Loot.RandomGem(); + gems.Amount = 12; + DropItem(gems); + } + + // Magic Wand + for (var i = Utility.Random(4); i > 0; i--) + { + DropItem(Loot.RandomWand()); + } + + // Equipment + for (var i = Utility.Random(4); i > 0; i--) + { + var item = Loot.RandomArmorOrShieldOrWeapon(); + + if (item is BaseWeapon weapon) { - case 0: // Wooden Chest - ItemID = UseFirstItemId ? 0xe42 : 0xe43; - GumpID = 0x49; - break; - - case 1: // Metal Chest - ItemID = UseFirstItemId ? 0x9ab : 0xe7c; - GumpID = 0x4A; - break; - - case 2: // Metal Golden Chest - ItemID = UseFirstItemId ? 0xe40 : 0xe41; - GumpID = 0x42; - break; - - case 3: // Keg - ItemID = 0xe7f; - GumpID = 0x3e; - break; + weapon.DamageLevel = (WeaponDamageLevel)Utility.Random(4); + weapon.AccuracyLevel = (WeaponAccuracyLevel)Utility.Random(4); + weapon.DurabilityLevel = (WeaponDurabilityLevel)Utility.Random(4); + weapon.Quality = WeaponQuality.Regular; } + else if (item is BaseArmor armor) + { + armor.ProtectionLevel = (ArmorProtectionLevel)Utility.Random(4); + armor.Durability = (ArmorDurabilityLevel)Utility.Random(4); + armor.Quality = ArmorQuality.Regular; + } + + DropItem(item); } - public override void Serialize(IGenericWriter writer) + // Clothing + for (var i = Utility.Random(3); i > 0; i--) { - base.Serialize(writer); - writer.Write(1); // version + DropItem(Loot.RandomClothing()); } - public override void Deserialize(IGenericReader reader) + // Jewelry + for (var i = Utility.Random(3); i > 0; i--) { - base.Deserialize(reader); - var version = reader.ReadInt(); + DropItem(Loot.RandomJewelry()); } + + // Crystal ball (not implemented) + } + + public override bool Decays => true; + + public override bool IsDecoContainer => false; + + public override TimeSpan DecayTime => TimeSpan.FromMinutes(Utility.Random(15, 60)); + + public override int DefaultGumpID => 0x42; + + public override int DefaultDropSound => 0x42; + + public override Rectangle2D Bounds => new(18, 105, 144, 73); + + private static readonly ValueTuple[] _chestAppearances = + { + // Wooden Chest + ValueTuple.Create(0xe42, 0x49), + ValueTuple.Create(0xe43, 0x49), + + // Metal Chest + ValueTuple.Create(0x9ab, 0x4A), + ValueTuple.Create(0xe7c, 0x4A), + + // Metal Golden Chest + ValueTuple.Create(0xe40, 0x42), + ValueTuple.Create(0xe41, 0x42), + + // Keg + ValueTuple.Create(0xe7f, 0x3e), + }; + + private void SetChestAppearance() + { + (ItemID, GumpID) = _chestAppearances.RandomElement(); } } diff --git a/Projects/UOContent/Migrations/Server.Items.MetalGoldenTreasureChest.v0.json b/Projects/UOContent/Migrations/Server.Items.MetalGoldenTreasureChest.v0.json new file mode 100644 index 000000000..c4e11b5e3 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.MetalGoldenTreasureChest.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.MetalGoldenTreasureChest" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.MetalTreasureChest.v0.json b/Projects/UOContent/Migrations/Server.Items.MetalTreasureChest.v0.json new file mode 100644 index 000000000..75aa355b8 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.MetalTreasureChest.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.MetalTreasureChest" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.TreasureChestLevel1.v0.json b/Projects/UOContent/Migrations/Server.Items.TreasureChestLevel1.v0.json new file mode 100644 index 000000000..a02072708 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.TreasureChestLevel1.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.TreasureChestLevel1" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.TreasureChestLevel2.v0.json b/Projects/UOContent/Migrations/Server.Items.TreasureChestLevel2.v0.json new file mode 100644 index 000000000..321df3f4d --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.TreasureChestLevel2.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.TreasureChestLevel2" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.TreasureChestLevel3.v0.json b/Projects/UOContent/Migrations/Server.Items.TreasureChestLevel3.v0.json new file mode 100644 index 000000000..5e279bc26 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.TreasureChestLevel3.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.TreasureChestLevel3" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.TreasureChestLevel4.v0.json b/Projects/UOContent/Migrations/Server.Items.TreasureChestLevel4.v0.json new file mode 100644 index 000000000..eeb91f0cd --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.TreasureChestLevel4.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.TreasureChestLevel4" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.WoodenTreasureChest.v0.json b/Projects/UOContent/Migrations/Server.Items.WoodenTreasureChest.v0.json new file mode 100644 index 000000000..73b84ec68 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.WoodenTreasureChest.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.WoodenTreasureChest" +} \ No newline at end of file From ca29fc640af74a25f3290ddf6f8f0c8e31277b76 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Mon, 28 Feb 2022 07:04:07 -0800 Subject: [PATCH 092/213] fix: Fixes stats for earlier expansions (#950) --- Projects/UOContent/Misc/SkillCheck.cs | 875 +++++++++++++------------- 1 file changed, 439 insertions(+), 436 deletions(-) diff --git a/Projects/UOContent/Misc/SkillCheck.cs b/Projects/UOContent/Misc/SkillCheck.cs index e17527c3a..56f94bd01 100644 --- a/Projects/UOContent/Misc/SkillCheck.cs +++ b/Projects/UOContent/Misc/SkillCheck.cs @@ -3,488 +3,491 @@ using Server.Factions; using Server.Mobiles; using Server.Regions; -namespace Server.Misc +namespace Server.Misc; + +// TODO: Make this entirely configurable +public static class SkillCheck { - public static class SkillCheck + public enum Stat { - public enum Stat + Str, + Dex, + Int + } + + // Publish 16 changed max stats from 100 to 125 + private static int StatMax = Core.LBR ? 125 : 100; + + public const int Allowance = 3; // How many times may we use the same location/target for gain + + private const int + LocationSize = 5; // The size of eeach location, make this smaller so players dont have to move as far + + private static readonly bool AntiMacroCode = !Core.ML; // Change this to false to disable anti-macro code + + public static TimeSpan AntiMacroExpire = TimeSpan.FromMinutes(5.0); // How long do we remember targets/locations? + + private static readonly bool[] UseAntiMacro = + { + // true if this skill uses the anti-macro code, false if it does not + false, // Alchemy = 0, + true, // Anatomy = 1, + true, // AnimalLore = 2, + true, // ItemID = 3, + true, // ArmsLore = 4, + false, // Parry = 5, + true, // Begging = 6, + false, // Blacksmith = 7, + false, // Fletching = 8, + true, // Peacemaking = 9, + true, // Camping = 10, + false, // Carpentry = 11, + false, // Cartography = 12, + false, // Cooking = 13, + true, // DetectHidden = 14, + true, // Discordance = 15, + true, // EvalInt = 16, + true, // Healing = 17, + true, // Fishing = 18, + true, // Forensics = 19, + true, // Herding = 20, + true, // Hiding = 21, + true, // Provocation = 22, + false, // Inscribe = 23, + true, // Lockpicking = 24, + true, // Magery = 25, + true, // MagicResist = 26, + false, // Tactics = 27, + true, // Snooping = 28, + true, // Musicianship = 29, + true, // Poisoning = 30, + false, // Archery = 31, + true, // SpiritSpeak = 32, + true, // Stealing = 33, + false, // Tailoring = 34, + true, // AnimalTaming = 35, + true, // TasteID = 36, + false, // Tinkering = 37, + true, // Tracking = 38, + true, // Veterinary = 39, + false, // Swords = 40, + false, // Macing = 41, + false, // Fencing = 42, + false, // Wrestling = 43, + true, // Lumberjacking = 44, + true, // Mining = 45, + true, // Meditation = 46, + true, // Stealth = 47, + true, // RemoveTrap = 48, + true, // Necromancy = 49, + false, // Focus = 50, + true, // Chivalry = 51 + true, // Bushido = 52 + true, // Ninjitsu = 53 + true, // Spellweaving + true, // Mysticism = 55 + true, // Imbuing = 56 + false, // Throwing = 57 + }; + + private static readonly TimeSpan m_StatGainDelay = TimeSpan.FromMinutes(Core.ML ? 0.05 : 15); + private static readonly TimeSpan m_PetStatGainDelay = TimeSpan.FromMinutes(5.0); + + public static void Initialize() + { + Mobile.SkillCheckLocationHandler = Mobile_SkillCheckLocation; + Mobile.SkillCheckDirectLocationHandler = Mobile_SkillCheckDirectLocation; + + Mobile.SkillCheckTargetHandler = Mobile_SkillCheckTarget; + Mobile.SkillCheckDirectTargetHandler = Mobile_SkillCheckDirectTarget; + } + + public static bool Mobile_SkillCheckLocation(Mobile from, SkillName skillName, double minSkill, double maxSkill) + { + var skill = from.Skills[skillName]; + + if (skill == null) { - Str, - Dex, - Int + return false; } - public const int Allowance = 3; // How many times may we use the same location/target for gain + var value = skill.Value; - private const int - LocationSize = 5; // The size of eeach location, make this smaller so players dont have to move as far - - private static readonly bool AntiMacroCode = !Core.ML; // Change this to false to disable anti-macro code - - public static TimeSpan AntiMacroExpire = TimeSpan.FromMinutes(5.0); // How long do we remember targets/locations? - - private static readonly bool[] UseAntiMacro = + if (value < minSkill) { - // true if this skill uses the anti-macro code, false if it does not - false, // Alchemy = 0, - true, // Anatomy = 1, - true, // AnimalLore = 2, - true, // ItemID = 3, - true, // ArmsLore = 4, - false, // Parry = 5, - true, // Begging = 6, - false, // Blacksmith = 7, - false, // Fletching = 8, - true, // Peacemaking = 9, - true, // Camping = 10, - false, // Carpentry = 11, - false, // Cartography = 12, - false, // Cooking = 13, - true, // DetectHidden = 14, - true, // Discordance = 15, - true, // EvalInt = 16, - true, // Healing = 17, - true, // Fishing = 18, - true, // Forensics = 19, - true, // Herding = 20, - true, // Hiding = 21, - true, // Provocation = 22, - false, // Inscribe = 23, - true, // Lockpicking = 24, - true, // Magery = 25, - true, // MagicResist = 26, - false, // Tactics = 27, - true, // Snooping = 28, - true, // Musicianship = 29, - true, // Poisoning = 30, - false, // Archery = 31, - true, // SpiritSpeak = 32, - true, // Stealing = 33, - false, // Tailoring = 34, - true, // AnimalTaming = 35, - true, // TasteID = 36, - false, // Tinkering = 37, - true, // Tracking = 38, - true, // Veterinary = 39, - false, // Swords = 40, - false, // Macing = 41, - false, // Fencing = 42, - false, // Wrestling = 43, - true, // Lumberjacking = 44, - true, // Mining = 45, - true, // Meditation = 46, - true, // Stealth = 47, - true, // RemoveTrap = 48, - true, // Necromancy = 49, - false, // Focus = 50, - true, // Chivalry = 51 - true, // Bushido = 52 - true, // Ninjitsu = 53 - true, // Spellweaving - true, // Mysticism = 55 - true, // Imbuing = 56 - false, // Throwing = 57 - }; - - private static readonly TimeSpan m_StatGainDelay = TimeSpan.FromMinutes(Core.ML ? 0.05 : 15); - private static readonly TimeSpan m_PetStatGainDelay = TimeSpan.FromMinutes(5.0); - - public static void Initialize() - { - Mobile.SkillCheckLocationHandler = Mobile_SkillCheckLocation; - Mobile.SkillCheckDirectLocationHandler = Mobile_SkillCheckDirectLocation; - - Mobile.SkillCheckTargetHandler = Mobile_SkillCheckTarget; - Mobile.SkillCheckDirectTargetHandler = Mobile_SkillCheckDirectTarget; + return false; // Too difficult } - public static bool Mobile_SkillCheckLocation(Mobile from, SkillName skillName, double minSkill, double maxSkill) + if (value >= maxSkill) { - var skill = from.Skills[skillName]; - - if (skill == null) - { - return false; - } - - var value = skill.Value; - - if (value < minSkill) - { - return false; // Too difficult - } - - if (value >= maxSkill) - { - return true; // No challenge - } - - var chance = (value - minSkill) / (maxSkill - minSkill); - - var loc = new Point2D(from.Location.X / LocationSize, from.Location.Y / LocationSize); - return CheckSkill(from, skill, loc, chance); + return true; // No challenge } - public static bool Mobile_SkillCheckDirectLocation(Mobile from, SkillName skillName, double chance) + var chance = (value - minSkill) / (maxSkill - minSkill); + + var loc = new Point2D(from.Location.X / LocationSize, from.Location.Y / LocationSize); + return CheckSkill(from, skill, loc, chance); + } + + public static bool Mobile_SkillCheckDirectLocation(Mobile from, SkillName skillName, double chance) + { + var skill = from.Skills[skillName]; + + if (skill == null) { - var skill = from.Skills[skillName]; - - if (skill == null) - { - return false; - } - - if (chance < 0.0) - { - return false; // Too difficult - } - - if (chance >= 1.0) - { - return true; // No challenge - } - - var loc = new Point2D(from.Location.X / LocationSize, from.Location.Y / LocationSize); - return CheckSkill(from, skill, loc, chance); + return false; } - public static bool CheckSkill(Mobile from, Skill skill, object amObj, double chance) + if (chance < 0.0) { - if (from.Skills.Cap == 0) - { - return false; - } - - var success = chance >= Utility.RandomDouble(); - var gc = (double)(from.Skills.Cap - from.Skills.Total) / from.Skills.Cap; - gc += (skill.Cap - skill.Base) / skill.Cap; - gc /= 2; - - gc += (1.0 - chance) * (success ? 0.5 : - Core.AOS ? 0.0 : 0.2); - gc /= 2; - - gc *= skill.Info.GainFactor; - - if (gc < 0.01) - { - gc = 0.01; - } - - if (from is BaseCreature creature && creature.Controlled) - { - gc *= 2; - } - - if (from.Alive && (gc >= Utility.RandomDouble() && AllowGain(from, skill, amObj) || skill.Base < 10.0)) - { - Gain(from, skill); - } - - return success; + return false; // Too difficult } - public static bool Mobile_SkillCheckTarget( - Mobile from, SkillName skillName, object target, double minSkill, - double maxSkill - ) + if (chance >= 1.0) { - var skill = from.Skills[skillName]; - - if (skill == null) - { - return false; - } - - var value = skill.Value; - - if (value < minSkill) - { - return false; // Too difficult - } - - if (value >= maxSkill) - { - return true; // No challenge - } - - var chance = (value - minSkill) / (maxSkill - minSkill); - - return CheckSkill(from, skill, target, chance); + return true; // No challenge } - public static bool Mobile_SkillCheckDirectTarget(Mobile from, SkillName skillName, object target, double chance) + var loc = new Point2D(from.Location.X / LocationSize, from.Location.Y / LocationSize); + return CheckSkill(from, skill, loc, chance); + } + + public static bool CheckSkill(Mobile from, Skill skill, object amObj, double chance) + { + if (from.Skills.Cap == 0) { - var skill = from.Skills[skillName]; - - if (skill == null) - { - return false; - } - - if (chance < 0.0) - { - return false; // Too difficult - } - - if (chance >= 1.0) - { - return true; // No challenge - } - - return CheckSkill(from, skill, target, chance); + return false; } - private static bool AllowGain(Mobile from, Skill skill, object obj) + var success = chance >= Utility.RandomDouble(); + var gc = (double)(from.Skills.Cap - from.Skills.Total) / from.Skills.Cap; + gc += (skill.Cap - skill.Base) / skill.Cap; + gc /= 2; + + gc += (1.0 - chance) * (success ? 0.5 : + Core.AOS ? 0.0 : 0.2); + gc /= 2; + + gc *= skill.Info.GainFactor; + + if (gc < 0.01) { - if (Core.AOS && Faction.InSkillLoss(from)) // Changed some time between the introduction of AoS and SE. - { - return false; - } - - if (AntiMacroCode && from is PlayerMobile mobile && UseAntiMacro[skill.Info.SkillID]) - { - return mobile.AntiMacroCheck(skill, obj); - } - - return true; + gc = 0.01; } - public static void Gain(Mobile from, Skill skill) + if (from is BaseCreature creature && creature.Controlled) { - if (from.Region.IsPartOf()) + gc *= 2; + } + + if (from.Alive && (gc >= Utility.RandomDouble() && AllowGain(from, skill, amObj) || skill.Base < 10.0)) + { + Gain(from, skill); + } + + return success; + } + + public static bool Mobile_SkillCheckTarget( + Mobile from, SkillName skillName, object target, double minSkill, + double maxSkill + ) + { + var skill = from.Skills[skillName]; + + if (skill == null) + { + return false; + } + + var value = skill.Value; + + if (value < minSkill) + { + return false; // Too difficult + } + + if (value >= maxSkill) + { + return true; // No challenge + } + + var chance = (value - minSkill) / (maxSkill - minSkill); + + return CheckSkill(from, skill, target, chance); + } + + public static bool Mobile_SkillCheckDirectTarget(Mobile from, SkillName skillName, object target, double chance) + { + var skill = from.Skills[skillName]; + + if (skill == null) + { + return false; + } + + if (chance < 0.0) + { + return false; // Too difficult + } + + if (chance >= 1.0) + { + return true; // No challenge + } + + return CheckSkill(from, skill, target, chance); + } + + private static bool AllowGain(Mobile from, Skill skill, object obj) + { + if (Core.AOS && Faction.InSkillLoss(from)) // Changed some time between the introduction of AoS and SE. + { + return false; + } + + if (AntiMacroCode && from is PlayerMobile mobile && UseAntiMacro[skill.Info.SkillID]) + { + return mobile.AntiMacroCheck(skill, obj); + } + + return true; + } + + public static void Gain(Mobile from, Skill skill) + { + if (from.Region.IsPartOf()) + { + return; + } + + if (from is BaseCreature creature && creature.IsDeadPet) + { + return; + } + + if (skill.SkillName == SkillName.Focus && from is BaseCreature) + { + return; + } + + if (skill.Base < skill.Cap && skill.Lock == SkillLock.Up) + { + var toGain = 1; + + if (skill.Base <= 10.0) { - return; + toGain = Utility.Random(4) + 1; } - if (from is BaseCreature creature && creature.IsDeadPet) - { - return; - } + var skills = from.Skills; - if (skill.SkillName == SkillName.Focus && from is BaseCreature) + if (from.Player && skills.Total / skills.Cap >= Utility.RandomDouble()) { - return; - } - - if (skill.Base < skill.Cap && skill.Lock == SkillLock.Up) - { - var toGain = 1; - - if (skill.Base <= 10.0) + for (var i = 0; i < skills.Length; ++i) { - toGain = Utility.Random(4) + 1; - } + var toLower = skills[i]; - var skills = from.Skills; - - if (from.Player && skills.Total / skills.Cap >= Utility.RandomDouble()) - { - for (var i = 0; i < skills.Length; ++i) + if (toLower != skill && toLower.Lock == SkillLock.Down && toLower.BaseFixedPoint >= toGain) { - var toLower = skills[i]; - - if (toLower != skill && toLower.Lock == SkillLock.Down && toLower.BaseFixedPoint >= toGain) - { - toLower.BaseFixedPoint -= toGain; - break; - } - } - } - - if (from is PlayerMobile pm && skill.SkillName == pm.AcceleratedSkill && - pm.AcceleratedStart > Core.Now) - { - toGain *= Utility.RandomMinMax(2, 5); - } - - if (!from.Player || skills.Total + toGain <= skills.Cap) - { - skill.BaseFixedPoint += toGain; - } - } - - if (skill.Lock == SkillLock.Up) - { - var info = skill.Info; - - if (from.StrLock == StatLockType.Up && info.StrGain / 33.3 > Utility.RandomDouble()) - { - GainStat(from, Stat.Str); - } - else if (from.DexLock == StatLockType.Up && info.DexGain / 33.3 > Utility.RandomDouble()) - { - GainStat(from, Stat.Dex); - } - else if (from.IntLock == StatLockType.Up && info.IntGain / 33.3 > Utility.RandomDouble()) - { - GainStat(from, Stat.Int); - } - } - } - - public static bool CanLower(Mobile from, Stat stat) - { - return stat switch - { - Stat.Str => from.StrLock == StatLockType.Down && from.RawStr > 10, - Stat.Dex => from.DexLock == StatLockType.Down && from.RawDex > 10, - Stat.Int => from.IntLock == StatLockType.Down && from.RawInt > 10, - _ => false - }; - } - - public static bool CanRaise(Mobile from, Stat stat) - { - if (!(from is BaseCreature creature && creature.Controlled)) - { - if (from.RawStatTotal >= from.StatCap) - { - return false; - } - } - - return stat switch - { - Stat.Str => from.StrLock == StatLockType.Up && from.RawStr < 125, - Stat.Dex => from.DexLock == StatLockType.Up && from.RawDex < 125, - Stat.Int => from.IntLock == StatLockType.Up && from.RawInt < 125, - _ => false - }; - } - - public static void IncreaseStat(Mobile from, Stat stat, bool atrophy) - { - atrophy = atrophy || from.RawStatTotal >= from.StatCap; - - switch (stat) - { - case Stat.Str: - { - if (atrophy) - { - if (CanLower(from, Stat.Dex) && (from.RawDex < from.RawInt || !CanLower(from, Stat.Int))) - { - --from.RawDex; - } - else if (CanLower(from, Stat.Int)) - { - --from.RawInt; - } - } - - if (CanRaise(from, Stat.Str)) - { - ++from.RawStr; - } - + toLower.BaseFixedPoint -= toGain; break; } - case Stat.Dex: - { - if (atrophy) - { - if (CanLower(from, Stat.Str) && (from.RawStr < from.RawInt || !CanLower(from, Stat.Int))) - { - --from.RawStr; - } - else if (CanLower(from, Stat.Int)) - { - --from.RawInt; - } - } + } + } - if (CanRaise(from, Stat.Dex)) - { - ++from.RawDex; - } + if (from is PlayerMobile pm && skill.SkillName == pm.AcceleratedSkill && + pm.AcceleratedStart > Core.Now) + { + toGain *= Utility.RandomMinMax(2, 5); + } - break; - } - case Stat.Int: - { - if (atrophy) - { - if (CanLower(from, Stat.Str) && (from.RawStr < from.RawDex || !CanLower(from, Stat.Dex))) - { - --from.RawStr; - } - else if (CanLower(from, Stat.Dex)) - { - --from.RawDex; - } - } - - if (CanRaise(from, Stat.Int)) - { - ++from.RawInt; - } - - break; - } + if (!from.Player || skills.Total + toGain <= skills.Cap) + { + skill.BaseFixedPoint += toGain; } } - public static void GainStat(Mobile from, Stat stat) + if (skill.Lock == SkillLock.Up) { - switch (stat) + var info = skill.Info; + + if (from.StrLock == StatLockType.Up && info.StrGain / 33.3 > Utility.RandomDouble()) { - case Stat.Str: - { - if (from is BaseCreature creature && creature.Controlled) - { - if (creature.LastStrGain + m_PetStatGainDelay >= Core.Now) - { - return; - } - } - else if (from.LastStrGain + m_StatGainDelay >= Core.Now) - { - return; - } - - from.LastStrGain = Core.Now; - break; - } - case Stat.Dex: - { - if (from is BaseCreature creature && creature.Controlled) - { - if (creature.LastDexGain + m_PetStatGainDelay >= Core.Now) - { - return; - } - } - else if (from.LastDexGain + m_StatGainDelay >= Core.Now) - { - return; - } - - from.LastDexGain = Core.Now; - break; - } - case Stat.Int: - { - if (from is BaseCreature creature && creature.Controlled) - { - if (creature.LastIntGain + m_PetStatGainDelay >= Core.Now) - { - return; - } - } - else if (from.LastIntGain + m_StatGainDelay >= Core.Now) - { - return; - } - - from.LastIntGain = Core.Now; - break; - } + GainStat(from, Stat.Str); + } + else if (from.DexLock == StatLockType.Up && info.DexGain / 33.3 > Utility.RandomDouble()) + { + GainStat(from, Stat.Dex); + } + else if (from.IntLock == StatLockType.Up && info.IntGain / 33.3 > Utility.RandomDouble()) + { + GainStat(from, Stat.Int); } - - var atrophy = from.RawStatTotal / (double)from.StatCap >= Utility.RandomDouble(); - - IncreaseStat(from, stat, atrophy); } } + + public static bool CanLower(Mobile from, Stat stat) + { + return stat switch + { + Stat.Str => from.StrLock == StatLockType.Down && from.RawStr > 10, + Stat.Dex => from.DexLock == StatLockType.Down && from.RawDex > 10, + Stat.Int => from.IntLock == StatLockType.Down && from.RawInt > 10, + _ => false + }; + } + + public static bool CanRaise(Mobile from, Stat stat) + { + if (!(from is BaseCreature creature && creature.Controlled)) + { + if (from.RawStatTotal >= from.StatCap) + { + return false; + } + } + + return stat switch + { + Stat.Str => from.StrLock == StatLockType.Up && from.RawStr < StatMax, + Stat.Dex => from.DexLock == StatLockType.Up && from.RawDex < StatMax, + Stat.Int => from.IntLock == StatLockType.Up && from.RawInt < StatMax, + _ => false + }; + } + + public static void IncreaseStat(Mobile from, Stat stat, bool atrophy) + { + atrophy = atrophy || from.RawStatTotal >= from.StatCap; + + switch (stat) + { + case Stat.Str: + { + if (atrophy) + { + if (CanLower(from, Stat.Dex) && (from.RawDex < from.RawInt || !CanLower(from, Stat.Int))) + { + --from.RawDex; + } + else if (CanLower(from, Stat.Int)) + { + --from.RawInt; + } + } + + if (CanRaise(from, Stat.Str)) + { + ++from.RawStr; + } + + break; + } + case Stat.Dex: + { + if (atrophy) + { + if (CanLower(from, Stat.Str) && (from.RawStr < from.RawInt || !CanLower(from, Stat.Int))) + { + --from.RawStr; + } + else if (CanLower(from, Stat.Int)) + { + --from.RawInt; + } + } + + if (CanRaise(from, Stat.Dex)) + { + ++from.RawDex; + } + + break; + } + case Stat.Int: + { + if (atrophy) + { + if (CanLower(from, Stat.Str) && (from.RawStr < from.RawDex || !CanLower(from, Stat.Dex))) + { + --from.RawStr; + } + else if (CanLower(from, Stat.Dex)) + { + --from.RawDex; + } + } + + if (CanRaise(from, Stat.Int)) + { + ++from.RawInt; + } + + break; + } + } + } + + public static void GainStat(Mobile from, Stat stat) + { + switch (stat) + { + case Stat.Str: + { + if (from is BaseCreature creature && creature.Controlled) + { + if (creature.LastStrGain + m_PetStatGainDelay >= Core.Now) + { + return; + } + } + else if (from.LastStrGain + m_StatGainDelay >= Core.Now) + { + return; + } + + from.LastStrGain = Core.Now; + break; + } + case Stat.Dex: + { + if (from is BaseCreature creature && creature.Controlled) + { + if (creature.LastDexGain + m_PetStatGainDelay >= Core.Now) + { + return; + } + } + else if (from.LastDexGain + m_StatGainDelay >= Core.Now) + { + return; + } + + from.LastDexGain = Core.Now; + break; + } + case Stat.Int: + { + if (from is BaseCreature creature && creature.Controlled) + { + if (creature.LastIntGain + m_PetStatGainDelay >= Core.Now) + { + return; + } + } + else if (from.LastIntGain + m_StatGainDelay >= Core.Now) + { + return; + } + + from.LastIntGain = Core.Now; + break; + } + } + + var atrophy = from.RawStatTotal / (double)from.StatCap >= Utility.RandomDouble(); + + IncreaseStat(from, stat, atrophy); + } } From 5a43c806fe3d8882ee6f1c555a55454bd1601f99 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Mon, 28 Feb 2022 08:43:41 -0800 Subject: [PATCH 093/213] fix: Use tuple shorthand syntax (#951) --- .../TreasureChests/TreasureChestLevel2.cs | 30 +++++++++---------- .../TreasureChests/TreasureChestLevel3.cs | 14 ++++----- .../TreasureChests/TreasureChestLevel4.cs | 16 +++++----- 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/Projects/UOContent/Items/TreasureChests/TreasureChestLevel2.cs b/Projects/UOContent/Items/TreasureChests/TreasureChestLevel2.cs index 00ff932ac..74b78fe39 100644 --- a/Projects/UOContent/Items/TreasureChests/TreasureChestLevel2.cs +++ b/Projects/UOContent/Items/TreasureChests/TreasureChestLevel2.cs @@ -76,37 +76,37 @@ public partial class TreasureChestLevel2 : LockableContainer public override Rectangle2D Bounds => new(18, 105, 144, 73); - private static readonly ValueTuple[] _chestAppearances = + private static readonly (int, int)[] _chestAppearances = { // Large Crate - ValueTuple.Create(0xe3c, 0x44), - ValueTuple.Create(0xe3d, 0x44), + (0xe3c, 0x44), + (0xe3d, 0x44), // Medium Crate - ValueTuple.Create(0xe3e, 0x44), - ValueTuple.Create(0xe3f, 0x44), + (0xe3e, 0x44), + (0xe3f, 0x44), // Small Crate - ValueTuple.Create(0x9a9, 0x44), - ValueTuple.Create(0xe7e, 0x44), + (0x9a9, 0x44), + (0xe7e, 0x44), // Wooden Chest - ValueTuple.Create(0xe42, 0x49), - ValueTuple.Create(0xe43, 0x49), + (0xe42, 0x49), + (0xe43, 0x49), // Metal Chest - ValueTuple.Create(0x9ab, 0x4A), - ValueTuple.Create(0xe7c, 0x4A), + (0x9ab, 0x4A), + (0xe7c, 0x4A), // Metal Golden Chest - ValueTuple.Create(0xe40, 0x42), - ValueTuple.Create(0xe41, 0x42), + (0xe40, 0x42), + (0xe41, 0x42), // Keg - ValueTuple.Create(0xe7f, 0x3e), + (0xe7f, 0x3e), // Barrel - ValueTuple.Create(0xe77, 0x3e), + (0xe77, 0x3e), }; private void SetChestAppearance() diff --git a/Projects/UOContent/Items/TreasureChests/TreasureChestLevel3.cs b/Projects/UOContent/Items/TreasureChests/TreasureChestLevel3.cs index a4368ea8d..fe227b27a 100644 --- a/Projects/UOContent/Items/TreasureChests/TreasureChestLevel3.cs +++ b/Projects/UOContent/Items/TreasureChests/TreasureChestLevel3.cs @@ -121,19 +121,19 @@ public partial class TreasureChestLevel3 : LockableContainer public override Rectangle2D Bounds => new(18, 105, 144, 73); - private static readonly ValueTuple[] _chestAppearances = + private static readonly (int, int)[] _chestAppearances = { // Wooden Chest - ValueTuple.Create(0xe42, 0x49), - ValueTuple.Create(0xe43, 0x49), + (0xe42, 0x49), + (0xe43, 0x49), // Metal Chest - ValueTuple.Create(0x9ab, 0x4A), - ValueTuple.Create(0xe7c, 0x4A), + (0x9ab, 0x4A), + (0xe7c, 0x4A), // Metal Golden Chest - ValueTuple.Create(0xe40, 0x42), - ValueTuple.Create(0xe41, 0x42), + (0xe40, 0x42), + (0xe41, 0x42), }; private void SetChestAppearance() diff --git a/Projects/UOContent/Items/TreasureChests/TreasureChestLevel4.cs b/Projects/UOContent/Items/TreasureChests/TreasureChestLevel4.cs index 0c223e215..bc4afcc72 100644 --- a/Projects/UOContent/Items/TreasureChests/TreasureChestLevel4.cs +++ b/Projects/UOContent/Items/TreasureChests/TreasureChestLevel4.cs @@ -124,22 +124,22 @@ public partial class TreasureChestLevel4 : LockableContainer public override Rectangle2D Bounds => new(18, 105, 144, 73); - private static readonly ValueTuple[] _chestAppearances = + private static readonly (int, int)[] _chestAppearances = { // Wooden Chest - ValueTuple.Create(0xe42, 0x49), - ValueTuple.Create(0xe43, 0x49), + (0xe42, 0x49), + (0xe43, 0x49), // Metal Chest - ValueTuple.Create(0x9ab, 0x4A), - ValueTuple.Create(0xe7c, 0x4A), + (0x9ab, 0x4A), + (0xe7c, 0x4A), // Metal Golden Chest - ValueTuple.Create(0xe40, 0x42), - ValueTuple.Create(0xe41, 0x42), + (0xe40, 0x42), + (0xe41, 0x42), // Keg - ValueTuple.Create(0xe7f, 0x3e), + (0xe7f, 0x3e), }; private void SetChestAppearance() From 1f4162288e71b147f1bf1137c3b9139f441ceb3f Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Mon, 28 Feb 2022 17:24:00 -0800 Subject: [PATCH 094/213] fix: Fixes UOClient NPE (#952) --- Projects/Server/Client/UOClient.cs | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/Projects/Server/Client/UOClient.cs b/Projects/Server/Client/UOClient.cs index e19b801f3..583d3dc81 100644 --- a/Projects/Server/Client/UOClient.cs +++ b/Projects/Server/Client/UOClient.cs @@ -46,20 +46,21 @@ public static class UOClient { if (ServerClientVersion == null) { - logger.Warning("Could not detect client version."); + logger.Warning("Could not detect client version. This may cause data files to load improperly."); + return; } - else if (CuoSettings.ClientVersion == ServerClientVersion) + + if (_automaticallyDetected) { - logger.Information($"Automatically detected client version {ServerClientVersion} from CUO settings."); - } - else if (_automaticallyDetected) - { - logger.Information($"Automatically detected client version {ServerClientVersion}"); - } - else - { - logger.Information($"Manually configured to use client version {ServerClientVersion}"); + logger.Information( + CuoSettings?.ClientVersion == ServerClientVersion + ? $"Automatically detected client version {ServerClientVersion} from CUO settings." + : $"Automatically detected client version {ServerClientVersion}" + ); + return; } + + logger.Information($"Manually configured to use client version {ServerClientVersion}"); } private static ClientVersion DetectCUOClient() From 58b907d39e02b58f85a47c2deed3af2dda21981b Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Fri, 4 Mar 2022 12:32:25 -0800 Subject: [PATCH 095/213] fix: Fixes packet length checks (#953) Fixes an issue with DropReq where an old client was sending in 14 bytes, but the server was expecting 15 bytes. To fix this we introduced a new packet handler, `ContainerGridPacketHandler` and changed the code to determine the length of the packet dynamically using `GetLength(NetState)`. Also fixed throttling so dropped packets are properly skipped. --- ...ocket.cs => ContainerGridPacketHandler.cs} | 34 +- Projects/Server/Network/NetState/NetState.cs | 1764 ++++++++--------- Projects/Server/Network/PacketHandler.cs | 60 +- .../Network/Packets/IncomingAccountPackets.cs | 22 +- .../Network/Packets/IncomingEntityPackets.cs | 8 +- .../Packets/IncomingExtendedCommandPackets.cs | 104 +- .../Network/Packets/IncomingHousePackets.cs | 2 +- .../Network/Packets/IncomingItemPackets.cs | 19 +- .../Network/Packets/IncomingMessagePackets.cs | 4 +- .../Network/Packets/IncomingMobilePackets.cs | 8 +- .../Packets/IncomingMovementPackets.cs | 2 +- .../Server/Network/Packets/IncomingPackets.cs | 47 +- .../Network/Packets/IncomingPlayerPackets.cs | 62 +- .../Packets/IncomingTargetingPackets.cs | 2 +- .../Network/Packets/IncomingVendorPackets.cs | 5 +- .../UOContent/Engines/Chat/ChatPackets.cs | 4 +- .../Engines/ML Quests/Gumps/RaceChangeGump.cs | 2 +- .../Engines/UltimaStore/UltimaStorePackets.cs | 2 +- Projects/UOContent/Items/Books/BookPackets.cs | 6 +- .../Bulletin Boards/BulletinBoardPackets.cs | 2 +- .../Items/Games/Mahjong/MahjongPackets.cs | 2 +- .../UOContent/Items/Maps/MapItemPackets.cs | 2 +- Projects/UOContent/Misc/HardwareInfo.cs | 2 +- Projects/UOContent/Misc/PacketThrottles.cs | 6 +- .../Multis/Houses/HouseFoundation.cs | 2 +- Projects/UOContent/Network/ConnectUO.cs | 10 +- Projects/UOContent/Network/MapUO.cs | 4 +- .../UOContent/Network/ProtocolExtensions.cs | 6 +- Projects/UOContent/Network/UOGateway.cs | 8 +- .../UOContent/Skills/Tracking/Tracking.cs | 2 +- 30 files changed, 1077 insertions(+), 1126 deletions(-) rename Projects/Server/Network/{ISocket.cs => ContainerGridPacketHandler.cs} (52%) diff --git a/Projects/Server/Network/ISocket.cs b/Projects/Server/Network/ContainerGridPacketHandler.cs similarity index 52% rename from Projects/Server/Network/ISocket.cs rename to Projects/Server/Network/ContainerGridPacketHandler.cs index 75d3d8475..ccbf94603 100644 --- a/Projects/Server/Network/ISocket.cs +++ b/Projects/Server/Network/ContainerGridPacketHandler.cs @@ -1,8 +1,8 @@ /************************************************************************* * ModernUO * - * Copyright 2019-2020 - ModernUO Development Team * + * Copyright 2019-2022 - ModernUO Development Team * * Email: hi@modernuo.com * - * File: ISocket.cs * + * File: ContainerGridPacketHandler.cs * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -13,32 +13,14 @@ * along with this program. If not, see . * *************************************************************************/ -using System; -using System.Collections.Generic; -using System.Net; -using System.Net.Sockets; -using System.Threading.Tasks; +namespace Server.Network; -namespace Server.Network +public class ContainerGridPacketHandler : PacketHandler { - public interface ISocket + public ContainerGridPacketHandler(int packetID, int length, bool ingame, OnPacketReceive onReceive) + : base(packetID, length, ingame, onReceive) { - public IntPtr Handle { get; } - - public EndPoint LocalEndPoint { get; } - - public EndPoint RemoteEndPoint { get; } - - public Task SendAsync(IList> buffer, SocketFlags flags); - - public int Send(IList> buffer, SocketFlags flags); - - public Task ReceiveAsync(IList> buffer, SocketFlags flags); - - public int Receive(IList> buffers, SocketFlags flags); - - public void Shutdown(SocketShutdown how); - - public void Close(); } + + public override int GetLength(NetState ns) => base.GetLength(ns) + (ns.ContainerGridLines ? 1 : 0); } diff --git a/Projects/Server/Network/NetState/NetState.cs b/Projects/Server/Network/NetState/NetState.cs index 7adfa951e..d76846c0b 100755 --- a/Projects/Server/Network/NetState/NetState.cs +++ b/Projects/Server/Network/NetState/NetState.cs @@ -31,438 +31,426 @@ using Server.Items; using Server.Logging; using Server.Menus; -namespace Server.Network +namespace Server.Network; + +public delegate void NetStateCreatedCallback(NetState ns); + +public delegate void DecodePacket(CircularBuffer buffer, ref int length); +public delegate void EncodePacket(ReadOnlySpan inputBuffer, CircularBuffer outputBuffer, out int length); + +public partial class NetState : IComparable { - public delegate void NetStateCreatedCallback(NetState ns); + private static readonly ILogger logger = LogFactory.GetLogger(typeof(NetState)); - public delegate void DecodePacket(CircularBuffer buffer, ref int length); - public delegate void EncodePacket(ReadOnlySpan inputBuffer, CircularBuffer outputBuffer, out int length); + private const int RecvPipeSize = 1024 * 64; + private const int SendPipeSize = 1024 * 256; + private const int GumpCap = 512; + private const int HuePickerCap = 512; + private const int MenuCap = 512; + private const int PacketPerSecondThreshold = 3000; - public partial class NetState : IComparable + private static GCHandle[] _polledStates = new GCHandle[2048]; + private static readonly IPollGroup _pollGroup = PollGroup.Create(); + private static readonly Queue FlushPending = new(2048); + private static readonly Queue FlushedPartials = new(2048); + private static readonly ConcurrentQueue Disposed = new(); + + public static NetStateCreatedCallback CreatedCallback { get; set; } + + private readonly string _toString; + private ClientVersion _version; + private long _nextActivityCheck; + private bool _running = true; + private volatile DecodePacket _packetDecoder; + private volatile EncodePacket _packetEncoder; + private bool _flushQueued; + private readonly long[] _packetThrottles = new long[0x100]; + private readonly long[] _packetCounts = new long[0x100]; + private string _disconnectReason = string.Empty; + + internal int _authId; + internal int _seed; + internal ParserState _parserState = ParserState.AwaitingNextPacket; + internal ProtocolState _protocolState = ProtocolState.AwaitingSeed; + internal GCHandle _handle; + private bool _packetLogging; + + internal enum ParserState { - private static readonly ILogger logger = LogFactory.GetLogger(typeof(NetState)); + AwaitingNextPacket, + AwaitingPartialPacket, + ProcessingPacket, + Throttled, + Error + } - private const int RecvPipeSize = 1024 * 64; - private const int SendPipeSize = 1024 * 256; - private const int GumpCap = 512; - private const int HuePickerCap = 512; - private const int MenuCap = 512; - private const int PacketPerSecondThreshold = 3000; + internal enum ProtocolState + { + AwaitingSeed, // Based on the way the seed arrives, we know if this is a login server or a game server connection - private static GCHandle[] _polledStates = new GCHandle[2048]; - private static readonly IPollGroup _pollGroup = PollGroup.Create(); - private static readonly Queue FlushPending = new(2048); - private static readonly Queue FlushedPartials = new(2048); - private static readonly ConcurrentQueue Disposed = new(); + LoginServer_AwaitingLogin, + LoginServer_AwaitingServerSelect, + LoginServer_ServerSelectAck, - public static NetStateCreatedCallback CreatedCallback { get; set; } + GameServer_AwaitingGameServerLogin, + GameServer_LoggedIn, - private readonly string _toString; - private ClientVersion _version; - private long _nextActivityCheck; - private bool _running = true; - private volatile DecodePacket _packetDecoder; - private volatile EncodePacket _packetEncoder; - private bool _flushQueued; - private readonly long[] _packetThrottles = new long[0x100]; - private readonly long[] _packetCounts = new long[0x100]; - private string _disconnectReason = string.Empty; + Error + } - internal int _authId; - internal int _seed; - internal ParserState _parserState = ParserState.AwaitingNextPacket; - internal ProtocolState _protocolState = ProtocolState.AwaitingSeed; - internal GCHandle _handle; - private bool _packetLogging; + private static string _packetLoggingPath; - internal enum ParserState + public static void Configure() + { + _packetLoggingPath = ServerConfiguration.GetSetting("netstate.packetLoggingPath", Path.Combine(Core.BaseDirectory, "Packets")); + } + + public static void Initialize() + { + Timer.DelayCall(TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1.5), CheckAllAlive); + } + + public NetState(Socket connection) + { + Connection = connection; + Seeded = false; + Gumps = new List(); + HuePickers = new List(); + Menus = new List(); + Trades = new List(); + RecvPipe = new Pipe(GC.AllocateUninitializedArray(RecvPipeSize)); + SendPipe = new Pipe(GC.AllocateUninitializedArray(SendPipeSize)); + _nextActivityCheck = Core.TickCount + 30000; + ConnectedOn = Core.Now; + + try { - AwaitingNextPacket, - AwaitingPartialPacket, - ProcessingPacket, - Throttled, - Error + Address = Utility.Intern((Connection?.RemoteEndPoint as IPEndPoint)?.Address); + _toString = Address?.ToString() ?? "(error)"; + } + catch (Exception ex) + { + TraceException(ex); + Address = IPAddress.None; + _toString = "(error)"; } - internal enum ProtocolState + _handle = GCHandle.Alloc(this); + + try { - AwaitingSeed, // Based on the way the seed arrives, we know if this is a login server or a game server connection - - LoginServer_AwaitingLogin, - LoginServer_AwaitingServerSelect, - LoginServer_ServerSelectAck, - - GameServer_AwaitingGameServerLogin, - GameServer_LoggedIn, - - Error + _pollGroup.Add(connection, _handle); + } + catch (Exception ex) + { + TraceException(ex); + Disconnect("Unable to add socket to poll group"); } - private static string _packetLoggingPath; + CreatedCallback?.Invoke(this); + } - public static void Configure() + // Only use this for debugging. This will make your server very slow! + public bool PacketLogging + { + get => _packetLogging; + set { - _packetLoggingPath = ServerConfiguration.GetSetting("netstate.packetLoggingPath", Path.Combine(Core.BaseDirectory, "Packets")); - } + _packetLogging = value; - public static void Initialize() - { - Timer.DelayCall(TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1.5), CheckAllAlive); - } - - public NetState(Socket connection) - { - Connection = connection; - Seeded = false; - Gumps = new List(); - HuePickers = new List(); - Menus = new List(); - Trades = new List(); - RecvPipe = new Pipe(GC.AllocateUninitializedArray(RecvPipeSize)); - SendPipe = new Pipe(GC.AllocateUninitializedArray(SendPipeSize)); - _nextActivityCheck = Core.TickCount + 30000; - ConnectedOn = Core.Now; - - try + if (_packetLogging) { - Address = Utility.Intern((Connection?.RemoteEndPoint as IPEndPoint)?.Address); - _toString = Address?.ToString() ?? "(error)"; - } - catch (Exception ex) - { - TraceException(ex); - Address = IPAddress.None; - _toString = "(error)"; - } - - _handle = GCHandle.Alloc(this); - - try - { - _pollGroup.Add(connection, _handle); - } - catch (Exception ex) - { - TraceException(ex); - Disconnect("Unable to add socket to poll group"); - } - - CreatedCallback?.Invoke(this); - } - - // Only use this for debugging. This will make your server very slow! - public bool PacketLogging - { - get => _packetLogging; - set - { - _packetLogging = value; - - if (_packetLogging) - { - StartPacketLog(); - } + StartPacketLog(); } } + } - public DateTime ConnectedOn { get; } + public DateTime ConnectedOn { get; } - public TimeSpan ConnectedFor => Core.Now - ConnectedOn; + public TimeSpan ConnectedFor => Core.Now - ConnectedOn; - public IPAddress Address { get; } + public IPAddress Address { get; } - public DecodePacket PacketDecoder + public DecodePacket PacketDecoder + { + get => _packetDecoder; + set => _packetDecoder = value; + } + + public EncodePacket PacketEncoder + { + get => _packetEncoder; + set => _packetEncoder = value; + } + + public int CurrentPacket { get; internal set; } + + public bool SentFirstPacket { get; set; } + + public bool BlockAllPackets { get; set; } + + public List Trades { get; } + + public bool Seeded { get; set; } + + public Pipe RecvPipe { get; } + + public Pipe SendPipe { get; } + + public bool Running => _running; + + public Socket Connection { get; private set; } + + public bool CompressionEnabled { get; set; } + + public int Sequence { get; set; } + + public List Gumps { get; private set; } + + public List HuePickers { get; private set; } + + public List Menus { get; private set; } + + public CityInfo[] CityInfo { get; set; } + + public Mobile Mobile { get; set; } + + public ServerInfo[] ServerInfo { get; set; } + + public IAccount Account { get; set; } + + public int CompareTo(NetState other) => string.CompareOrdinal(_toString, other?._toString); + + private void SetPacketTime(int packetID) + { + if (packetID is >= 0 and < 0x100) { - get => _packetDecoder; - set => _packetDecoder = value; - } - - public EncodePacket PacketEncoder - { - get => _packetEncoder; - set => _packetEncoder = value; - } - - public int CurrentPacket { get; internal set; } - - public bool SentFirstPacket { get; set; } - - public bool BlockAllPackets { get; set; } - - public List Trades { get; } - - public bool Seeded { get; set; } - - public Pipe RecvPipe { get; } - - public Pipe SendPipe { get; } - - public bool Running => _running; - - public Socket Connection { get; private set; } - - public bool CompressionEnabled { get; set; } - - public int Sequence { get; set; } - - public List Gumps { get; private set; } - - public List HuePickers { get; private set; } - - public List Menus { get; private set; } - - public CityInfo[] CityInfo { get; set; } - - public Mobile Mobile { get; set; } - - public ServerInfo[] ServerInfo { get; set; } - - public IAccount Account { get; set; } - - public int CompareTo(NetState other) => string.CompareOrdinal(_toString, other?._toString); - - private void SetPacketTime(int packetID) - { - if (packetID is < 0 or >= 0x100) - { - return; - } - _packetThrottles[packetID] = Core.TickCount; } + } - public long GetPacketDelay(int packetID) + public long GetPacketTime(int packetID) => packetID is >= 0 and < 0x100 ? _packetThrottles[packetID] : 0; + + private void UpdatePacketCount(int packetID) + { + if (packetID is >= 0 and < 0x100) { - if (packetID is < 0 or >= 0x100) - { - return 0; - } - - return _packetThrottles[packetID]; - } - - private void UpdatePacketCount(int packetID) - { - if (packetID is < 0 or >= 0x100) - { - return; - } - _packetCounts[packetID]++; } + } - public int CheckPacketCounts() + public int CheckPacketCounts() + { + for (int i = 0; i < _packetCounts.Length; i++) { - for (int i = 0; i < _packetCounts.Length; i++) + long count = _packetCounts[i]; + _packetCounts[i] = 0; + + if (count > PacketPerSecondThreshold) { - long count = _packetCounts[i]; - _packetCounts[i] = 0; - - if (count > PacketPerSecondThreshold) - { - return i; - } - } - - return 0; - } - - public void ValidateAllTrades() - { - for (var i = Trades.Count - 1; i >= 0; --i) - { - if (i >= Trades.Count) - { - continue; - } - - var trade = Trades[i]; - - if (trade.From.Mobile.Deleted || trade.To.Mobile.Deleted || !trade.From.Mobile.Alive || - !trade.To.Mobile.Alive || !trade.From.Mobile.InRange(trade.To.Mobile, 2) || - trade.From.Mobile.Map != trade.To.Mobile.Map) - { - trade.Cancel(); - } + return i; } } - public void CancelAllTrades() + return 0; + } + + public void ValidateAllTrades() + { + for (var i = Trades.Count - 1; i >= 0; --i) { - for (var i = Trades.Count - 1; i >= 0; --i) + if (i >= Trades.Count) { - if (i < Trades.Count) - { - Trades[i].Cancel(); - } + continue; + } + + var trade = Trades[i]; + + if (trade.From.Mobile.Deleted || trade.To.Mobile.Deleted || !trade.From.Mobile.Alive || + !trade.To.Mobile.Alive || !trade.From.Mobile.InRange(trade.To.Mobile, 2) || + trade.From.Mobile.Map != trade.To.Mobile.Map) + { + trade.Cancel(); + } + } + } + + public void CancelAllTrades() + { + for (var i = Trades.Count - 1; i >= 0; --i) + { + if (i < Trades.Count) + { + Trades[i].Cancel(); + } + } + } + + public void RemoveTrade(SecureTrade trade) + { + Trades.Remove(trade); + } + + public SecureTrade FindTrade(Mobile m) + { + for (var i = 0; i < Trades.Count; ++i) + { + var trade = Trades[i]; + + if (trade.From.Mobile == m || trade.To.Mobile == m) + { + return trade; } } - public void RemoveTrade(SecureTrade trade) - { - Trades.Remove(trade); - } + return null; + } - public SecureTrade FindTrade(Mobile m) + public SecureTradeContainer FindTradeContainer(Mobile m) + { + for (var i = 0; i < Trades.Count; ++i) { - for (var i = 0; i < Trades.Count; ++i) + var trade = Trades[i]; + + var from = trade.From; + var to = trade.To; + + if (from.Mobile == Mobile && to.Mobile == m) { - var trade = Trades[i]; - - if (trade.From.Mobile == m || trade.To.Mobile == m) - { - return trade; - } + return from.Container; } - return null; - } - - public SecureTradeContainer FindTradeContainer(Mobile m) - { - for (var i = 0; i < Trades.Count; ++i) + if (from.Mobile == m && to.Mobile == Mobile) { - var trade = Trades[i]; - - var from = trade.From; - var to = trade.To; - - if (from.Mobile == Mobile && to.Mobile == m) - { - return from.Container; - } - - if (from.Mobile == m && to.Mobile == Mobile) - { - return to.Container; - } - } - - return null; - } - - public SecureTradeContainer AddTrade(NetState state) - { - var newTrade = new SecureTrade(Mobile, state.Mobile); - - Trades.Add(newTrade); - state.Trades.Add(newTrade); - - return newTrade.From.Container; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void LogInfo(string text) - { - logger.Information("Client: {0}: {1}", this, text); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void LogInfo(string format, params object[] args) - { - LogInfo(string.Format(format, args)); - } - - public void AddMenu(IMenu menu) - { - Menus ??= new List(); - - if (Menus.Count < MenuCap) - { - Menus.Add(menu); - } - else - { - LogInfo("Exceeded menu cap, disconnecting..."); - Disconnect("Exceeded menu cap."); + return to.Container; } } - public void RemoveMenu(IMenu menu) + return null; + } + + public SecureTradeContainer AddTrade(NetState state) + { + var newTrade = new SecureTrade(Mobile, state.Mobile); + + Trades.Add(newTrade); + state.Trades.Add(newTrade); + + return newTrade.From.Container; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void LogInfo(string text) + { + logger.Information("Client: {0}: {1}", this, text); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void LogInfo(string format, params object[] args) + { + LogInfo(string.Format(format, args)); + } + + public void AddMenu(IMenu menu) + { + Menus ??= new List(); + + if (Menus.Count < MenuCap) { - Menus?.Remove(menu); + Menus.Add(menu); } - - public void RemoveMenu(int index) + else { - Menus?.RemoveAt(index); + LogInfo("Exceeded menu cap, disconnecting..."); + Disconnect("Exceeded menu cap."); } + } - public void ClearMenus() + public void RemoveMenu(IMenu menu) + { + Menus?.Remove(menu); + } + + public void RemoveMenu(int index) + { + Menus?.RemoveAt(index); + } + + public void ClearMenus() + { + Menus?.Clear(); + } + + public void AddHuePicker(HuePicker huePicker) + { + HuePickers ??= new List(); + + if (HuePickers.Count < HuePickerCap) { - Menus?.Clear(); + HuePickers.Add(huePicker); } - - public void AddHuePicker(HuePicker huePicker) + else { - HuePickers ??= new List(); - - if (HuePickers.Count < HuePickerCap) - { - HuePickers.Add(huePicker); - } - else - { - LogInfo("Exceeded hue picker cap, disconnecting..."); - Disconnect("Exceeded hue picker cap."); - } + LogInfo("Exceeded hue picker cap, disconnecting..."); + Disconnect("Exceeded hue picker cap."); } + } - public void RemoveHuePicker(HuePicker huePicker) + public void RemoveHuePicker(HuePicker huePicker) + { + HuePickers?.Remove(huePicker); + } + + public void RemoveHuePicker(int index) + { + HuePickers?.RemoveAt(index); + } + + public void ClearHuePickers() + { + HuePickers?.Clear(); + } + + public void AddGump(Gump gump) + { + Gumps ??= new List(); + + if (Gumps.Count < GumpCap) { - HuePickers?.Remove(huePicker); + Gumps.Add(gump); } - - public void RemoveHuePicker(int index) + else { - HuePickers?.RemoveAt(index); + LogInfo("Exceeded gump cap, disconnecting..."); + Disconnect("Exceeded gump cap."); } + } - public void ClearHuePickers() - { - HuePickers?.Clear(); - } + public void RemoveGump(Gump gump) + { + Gumps?.Remove(gump); + } - public void AddGump(Gump gump) - { - Gumps ??= new List(); + public void RemoveGump(int index) + { + Gumps?.RemoveAt(index); + } - if (Gumps.Count < GumpCap) - { - Gumps.Add(gump); - } - else - { - LogInfo("Exceeded gump cap, disconnecting..."); - Disconnect("Exceeded gump cap."); - } - } + public void ClearGumps() + { + Gumps?.Clear(); + } - public void RemoveGump(Gump gump) - { - Gumps?.Remove(gump); - } + public void LaunchBrowser(string url) + { + this.SendMessageLocalized(Serial.MinusOne, -1, MessageType.Label, 0x35, 3, 501231); + this.SendLaunchBrowser(url); + } - public void RemoveGump(int index) - { - Gumps?.RemoveAt(index); - } + public override string ToString() => _toString; - public void ClearGumps() - { - Gumps?.Clear(); - } - - public void LaunchBrowser(string url) - { - this.SendMessageLocalized(Serial.MinusOne, -1, MessageType.Label, 0x35, 3, 501231); - this.SendLaunchBrowser(url); - } - - public override string ToString() => _toString; - - public bool GetSendBuffer(out CircularBuffer cBuffer) - { + public bool GetSendBuffer(out CircularBuffer cBuffer) + { #if THREADGUARD if (Thread.CurrentThread != Core.Thread) { @@ -473,630 +461,629 @@ namespace Server.Network return; } #endif - var result = SendPipe.Writer.TryGetMemory(); - cBuffer = new CircularBuffer(result.Buffer); + var result = SendPipe.Writer.TryGetMemory(); + cBuffer = new CircularBuffer(result.Buffer); - return !(result.IsClosed || result.Length <= 0); + return !(result.IsClosed || result.Length <= 0); + } + + public void Send(ReadOnlySpan span) + { + if (span == null || this.CannotSendPackets()) + { + return; } - public void Send(ReadOnlySpan span) + var length = span.Length; + if (length <= 0 || !GetSendBuffer(out var buffer)) { - if (span == null || this.CannotSendPackets()) + return; + } + + try + { + PacketSendProfile prof = null; + + if (Core.Profiling) { - return; + prof = PacketSendProfile.Acquire(span[0]); + prof.Start(); } - var length = span.Length; - if (length <= 0 || !GetSendBuffer(out var buffer)) + if (_packetEncoder != null) { - return; + _packetEncoder(span, buffer, out length); + } + else + { + buffer.CopyFrom(span); } - try + if (PacketLogging) { - PacketSendProfile prof = null; + LogPacket(span, ReadOnlySpan.Empty, span.Length, false); + } - if (Core.Profiling) + SendPipe.Writer.Advance((uint)length); + + if (!_flushQueued) + { + FlushPending.Enqueue(this); + _flushQueued = true; + } + + prof?.Finish(); + } + catch (Exception ex) + { +#if DEBUG + Console.WriteLine(ex); +#endif + TraceException(ex); + Disconnect("Exception while sending."); + } + } + + private void StartPacketLog() + { + try + { + var logDir = Path.Combine(_packetLoggingPath, _toString); + PathUtility.EnsureDirectory(logDir); + var logPath = Path.Combine(logDir, "packets.log"); + using var op = new StreamWriter(logPath, true); + + op.WriteLine(">>>>>>>>>> Logging started {0:yyyy/MM/dd HH:mm::ss} <<<<<<<<<<", Core.Now); + op.WriteLine(); + op.WriteLine(); + } + catch (Exception e) + { + Console.WriteLine(e); + } + } + + private void LogPacket(ReadOnlySpan first, ReadOnlySpan second, int totalLength, bool incoming) + { + try + { + var logDir = Path.Combine(_packetLoggingPath, _toString); + PathUtility.EnsureDirectory(logDir); + var logPath = Path.Combine(logDir, "packets.log"); + + const string incomingStr = "Client -> Server"; + const string outgoingStr = "Server -> Client"; + + using var sw = new StreamWriter(logPath, true); + sw.WriteLine($"{Core.Now:HH:mm:ss.ffff}: {(incoming ? incomingStr : outgoingStr)} 0x{first[0]:X2} (Length: {totalLength})"); + sw.FormatBuffer(first, second, totalLength); + sw.WriteLine(); + sw.WriteLine(); + } + catch + { + // ignored + } + } + + public void HandleReceive() + { + if (!_running) + { + return; + } + + ReceiveData(); + + var reader = RecvPipe.Reader; + + try + { + // Process as many packets as we can synchronously + while (_running && _parserState != ParserState.Error && _protocolState != ProtocolState.Error) + { + var result = reader.TryRead(); + var length = result.Length; + + if (length <= 0) { - prof = PacketSendProfile.Acquire(span[0]); - prof.Start(); + break; } - if (_packetEncoder != null) + var packetReader = new CircularBufferReader(result.Buffer); + var packetId = packetReader.ReadByte(); + int packetLength = length; + + // These can arrive at any time and are only informational + if (_protocolState != ProtocolState.AwaitingSeed && IncomingPackets.IsInfoPacket(packetId)) { - _packetEncoder(span, buffer, out length); + _parserState = ParserState.ProcessingPacket; + _parserState = HandlePacket(packetReader, packetId, out packetLength); } else { - buffer.CopyFrom(span); - } - - if (PacketLogging) - { - LogPacket(span, ReadOnlySpan.Empty, span.Length, false); - } - - SendPipe.Writer.Advance((uint)length); - - if (!_flushQueued) - { - FlushPending.Enqueue(this); - _flushQueued = true; - } - - prof?.Finish(); - } - catch (Exception ex) - { -#if DEBUG - Console.WriteLine(ex); -#endif - TraceException(ex); - Disconnect("Exception while sending."); - } - } - - private void StartPacketLog() - { - try - { - var logDir = Path.Combine(_packetLoggingPath, _toString); - PathUtility.EnsureDirectory(logDir); - var logPath = Path.Combine(logDir, "packets.log"); - using var op = new StreamWriter(logPath, true); - - op.WriteLine(">>>>>>>>>> Logging started {0:yyyy/MM/dd HH:mm::ss} <<<<<<<<<<", Core.Now); - op.WriteLine(); - op.WriteLine(); - } - catch (Exception e) - { - Console.WriteLine(e); - } - } - - private void LogPacket(ReadOnlySpan first, ReadOnlySpan second, int totalLength, bool incoming) - { - try - { - var logDir = Path.Combine(_packetLoggingPath, _toString); - PathUtility.EnsureDirectory(logDir); - var logPath = Path.Combine(logDir, "packets.log"); - - const string incomingStr = "Client -> Server"; - const string outgoingStr = "Server -> Client"; - - using var sw = new StreamWriter(logPath, true); - sw.WriteLine($"{Core.Now:HH:mm:ss.ffff}: {(incoming ? incomingStr : outgoingStr)} 0x{first[0]:X2} (Length: {totalLength})"); - sw.FormatBuffer(first, second, totalLength); - sw.WriteLine(); - sw.WriteLine(); - } - catch - { - // ignored - } - } - - public void HandleReceive() - { - if (!_running) - { - return; - } - - ReceiveData(); - - var reader = RecvPipe.Reader; - - try - { - // Process as many packets as we can synchronously - while (_running && _parserState != ParserState.Error && _protocolState != ProtocolState.Error) - { - var result = reader.TryRead(); - var length = result.Length; - - if (length <= 0) + switch (_protocolState) { - break; - } - - var packetReader = new CircularBufferReader(result.Buffer); - var packetId = packetReader.ReadByte(); - int packetLength = length; - - // These can arrive at any time and are only informational - if (_protocolState != ProtocolState.AwaitingSeed && IncomingPackets.IsInfoPacket(packetId)) - { - _parserState = ParserState.ProcessingPacket; - _parserState = HandlePacket(packetReader, packetId, length, out packetLength); - } - else - { - switch (_protocolState) - { - case ProtocolState.AwaitingSeed: + case ProtocolState.AwaitingSeed: + { + if (packetId == 0xEF) { - if (packetId == 0xEF) + _parserState = ParserState.ProcessingPacket; + _parserState = HandlePacket(packetReader, packetId, out packetLength); + if (_parserState == ParserState.AwaitingNextPacket) { - _parserState = ParserState.ProcessingPacket; - _parserState = HandlePacket(packetReader, packetId, length, out packetLength); - if (_parserState == ParserState.AwaitingNextPacket) - { - _protocolState = ProtocolState.LoginServer_AwaitingLogin; - } + _protocolState = ProtocolState.LoginServer_AwaitingLogin; } - else if (length >= 4) - { - int seed = (packetId << 24) | (packetReader.ReadByte() << 16) | (packetReader.ReadByte() << 8) | packetReader.ReadByte(); - - if (seed == 0) - { - HandleError(0, 0); - return; - } - - _seed = seed; - packetLength = 4; - - _parserState = ParserState.AwaitingNextPacket; - _protocolState = ProtocolState.GameServer_AwaitingGameServerLogin; - } - else - { - _parserState = ParserState.AwaitingPartialPacket; - } - break; } - - case ProtocolState.LoginServer_AwaitingLogin: + else if (length >= 4) { - if (packetId != 0xCF && packetId != 0x80) + int seed = (packetId << 24) | (packetReader.ReadByte() << 16) | (packetReader.ReadByte() << 8) | packetReader.ReadByte(); + + if (seed == 0) { - LogInfo("Possible encrypted client detected, disconnecting..."); - HandleError(packetId, packetLength); + HandleError(0, 0); return; } - _parserState = ParserState.ProcessingPacket; - _parserState = HandlePacket(packetReader, packetId, length, out packetLength); - if (_parserState == ParserState.AwaitingNextPacket) - { - _protocolState = ProtocolState.LoginServer_AwaitingServerSelect; - } - break; - } + _seed = seed; + packetLength = 4; - case ProtocolState.LoginServer_AwaitingServerSelect: - { - if (packetId != 0xA0) - { - HandleError(packetId, packetLength); - return; - } - - _parserState = ParserState.ProcessingPacket; - _parserState = HandlePacket(packetReader, packetId, length, out packetLength); - if (_parserState == ParserState.AwaitingNextPacket) - { - _protocolState = ProtocolState.LoginServer_ServerSelectAck; - Disconnect(string.Empty); - } - break; - } - - case ProtocolState.LoginServer_ServerSelectAck: - { -#if STRICT_UO_PROTOCOL - HandleError(packetId, packetLength); -#else - // Reset the state because CUO/Orion do not reconnect _parserState = ParserState.AwaitingNextPacket; - _protocolState = ProtocolState.AwaitingSeed; -#endif + _protocolState = ProtocolState.GameServer_AwaitingGameServerLogin; + } + else + { + _parserState = ParserState.AwaitingPartialPacket; + } + break; + } + + case ProtocolState.LoginServer_AwaitingLogin: + { + if (packetId != 0xCF && packetId != 0x80) + { + LogInfo("Possible encrypted client detected, disconnecting..."); + HandleError(packetId, packetLength); return; } - case ProtocolState.GameServer_AwaitingGameServerLogin: + _parserState = ParserState.ProcessingPacket; + _parserState = HandlePacket(packetReader, packetId, out packetLength); + if (_parserState == ParserState.AwaitingNextPacket) { - if (packetId != 0x91 && packetId != 0x80) - { - HandleError(packetId, packetLength); - return; - } + _protocolState = ProtocolState.LoginServer_AwaitingServerSelect; + } + break; + } - _parserState = ParserState.ProcessingPacket; - _parserState = HandlePacket(packetReader, packetId, length, out packetLength); - if (_parserState == ParserState.AwaitingNextPacket) - { - _protocolState = ProtocolState.GameServer_LoggedIn; - } - break; + case ProtocolState.LoginServer_AwaitingServerSelect: + { + if (packetId != 0xA0) + { + HandleError(packetId, packetLength); + return; } - case ProtocolState.GameServer_LoggedIn: + _parserState = ParserState.ProcessingPacket; + _parserState = HandlePacket(packetReader, packetId, out packetLength); + if (_parserState == ParserState.AwaitingNextPacket) { - _parserState = ParserState.ProcessingPacket; - _parserState = HandlePacket(packetReader, packetId, length, out packetLength); - break; + _protocolState = ProtocolState.LoginServer_ServerSelectAck; + Disconnect(string.Empty); } - } - } + break; + } - if (_parserState == ParserState.AwaitingNextPacket) - { - reader.Advance((uint)packetLength); - } - else if (_parserState is ParserState.AwaitingPartialPacket or ParserState.Throttled) - { - break; - } - else - { - HandleError(packetId, packetLength); - break; + case ProtocolState.LoginServer_ServerSelectAck: + { +#if STRICT_UO_PROTOCOL + HandleError(packetId, packetLength); +#else + // Reset the state because CUO/Orion do not reconnect + _parserState = ParserState.AwaitingNextPacket; + _protocolState = ProtocolState.AwaitingSeed; +#endif + return; + } + + case ProtocolState.GameServer_AwaitingGameServerLogin: + { + if (packetId != 0x91 && packetId != 0x80) + { + HandleError(packetId, packetLength); + return; + } + + _parserState = ParserState.ProcessingPacket; + _parserState = HandlePacket(packetReader, packetId, out packetLength); + if (_parserState == ParserState.AwaitingNextPacket) + { + _protocolState = ProtocolState.GameServer_LoggedIn; + } + break; + } + + case ProtocolState.GameServer_LoggedIn: + { + _parserState = ParserState.ProcessingPacket; + _parserState = HandlePacket(packetReader, packetId, out packetLength); + break; + } } } - reader.Commit(); + if (_parserState is ParserState.AwaitingNextPacket or ParserState.Throttled) + { + reader.Advance((uint)packetLength); + } + else if (_parserState is ParserState.AwaitingPartialPacket) + { + break; + } + else if (_parserState is ParserState.Error) + { + HandleError(packetId, packetLength); + break; + } } - catch (Exception ex) - { + + reader.Commit(); + } + catch (Exception ex) + { #if DEBUG Console.WriteLine(ex); #endif - TraceException(ex); - Disconnect("Exception during HandleReceive"); - } + TraceException(ex); + Disconnect("Exception during HandleReceive"); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void HandleError(byte packetId, int packetLength) + { + var msg = + $"{this} entered bad state on packet 0x{packetId:X2} with length {packetLength} while in protocol state {_protocolState} and parser state {_parserState}"; + Disconnect(msg); + _parserState = ParserState.Error; + _protocolState = ProtocolState.Error; + } + + /* + * length is the total buffer length. We might be able to use packetReader.Capacity() instead. + * packetLength is the length of the packet that this function actually found. + */ + private ParserState HandlePacket(CircularBufferReader packetReader, byte packetId, out int packetLength) + { + PacketHandler handler = IncomingPackets.GetHandler(packetId); + int length = packetReader.Length; + + if (handler == null) + { + LogInfo($"Received unknown packet 0x{packetId:X2} while in state {_protocolState}"); + packetLength = 1; + return ParserState.Error; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void HandleError(byte packetId, int packetLength) + packetLength = handler.GetLength(this); + if (packetLength <= 0) { - var msg = - $"{this} entered bad state on packet 0x{packetId:X2} with length {packetLength} while in protocol state {_protocolState} and parser state {_parserState}"; - Disconnect(msg); - _parserState = ParserState.Error; - _protocolState = ProtocolState.Error; - } - - /* - * length is the total buffer length. We might be able to use packetReader.Capacity() instead. - * packetLength is the length of the packet that this function actually found. - */ - private ParserState HandlePacket(CircularBufferReader packetReader, byte packetId, int length, out int packetLength) - { - PacketHandler handler = GetHandler(packetId); - if (handler == null) - { - LogInfo($"received unknown packet 0x{packetId:X2} while in state {_protocolState}"); - packetLength = length; - return ParserState.Error; - } - - packetLength = handler.Length; - if (packetLength <= 0) - { - // Variable length packet. See if we have pulled in the length. - if (length < 3) - { - return ParserState.AwaitingPartialPacket; - } - - packetLength = packetReader.ReadUInt16(); - if (packetLength < 3) - { - return ParserState.Error; - } - } - - // Not enough data, let's wait for more to come in - if (length < packetLength) + // Variable length packet. See if we have pulled in the length. + if (length < 3) { return ParserState.AwaitingPartialPacket; } - if (handler.Ingame) + packetLength = packetReader.ReadUInt16(); + if (packetLength < 3) { - if (Mobile == null) - { - LogInfo($"received packet 0x{packetId:X2} before having been attached to a mobile"); - return ParserState.Error; - } - - if (Mobile.Deleted) - { - return ParserState.Error; - } + return ParserState.Error; } - - ThrottlePacketCallback throttler = handler.ThrottleCallback; - if (throttler != null) - { - if (!throttler(packetId, this, out bool drop)) - { - return drop ? ParserState.AwaitingNextPacket : ParserState.Throttled; - } - - SetPacketTime(packetId); - } - - PacketReceiveProfile prof = null; - - if (Core.Profiling) - { - prof = PacketReceiveProfile.Acquire(packetId); - prof?.Start(); - } - - UpdatePacketCount(packetId); - - if (PacketLogging) - { - LogPacket(packetReader.First, packetReader.Second, packetLength, true); - } - - handler.OnReceive(this, packetReader, ref packetLength); - - prof?.Finish(packetLength); - - return ParserState.AwaitingNextPacket; } - private bool Flush() + // Not enough data, let's wait for more to come in + if (length < packetLength) { - _flushQueued = false; + return ParserState.AwaitingPartialPacket; + } - if (Connection == null) + if (handler.Ingame) + { + if (Mobile == null) { - return true; + LogInfo($"received packet 0x{packetId:X2} before having been attached to a mobile"); + return ParserState.Error; } - SendPipe.Writer.Flush(); - - var reader = SendPipe.Reader; - var result = reader.TryRead(); - - if (result.IsClosed || result.Length == 0) + if (Mobile.Deleted) { - return true; + return ParserState.Error; + } + } + + ThrottlePacketCallback throttler = handler.ThrottleCallback; + if (throttler != null) + { + if (!throttler(packetId, this, out bool drop)) + { + return drop ? ParserState.Throttled : ParserState.AwaitingNextPacket; } - var bytesWritten = 0; + SetPacketTime(packetId); + } - try - { - bytesWritten = Connection.Send(result.Buffer, SocketFlags.None); - } - catch (SocketException ex) - { - // Socket exceptions are generally ok, just spammy + PacketReceiveProfile prof = null; + + if (Core.Profiling) + { + prof = PacketReceiveProfile.Acquire(packetId); + prof?.Start(); + } + + UpdatePacketCount(packetId); + + if (PacketLogging) + { + LogPacket(packetReader.First, packetReader.Second, packetLength, true); + } + + handler.OnReceive(this, packetReader, packetLength); + + prof?.Finish(packetLength); + + return ParserState.AwaitingNextPacket; + } + + private bool Flush() + { + _flushQueued = false; + + if (Connection == null) + { + return true; + } + + SendPipe.Writer.Flush(); + + var reader = SendPipe.Reader; + var result = reader.TryRead(); + + if (result.IsClosed || result.Length == 0) + { + return true; + } + + var bytesWritten = 0; + + try + { + bytesWritten = Connection.Send(result.Buffer, SocketFlags.None); + } + catch (SocketException ex) + { + // Socket exceptions are generally ok, just spammy #if DEBUG Console.WriteLine(ex); #endif - Disconnect(string.Empty); - } - catch (Exception ex) - { + Disconnect(string.Empty); + } + catch (Exception ex) + { #if DEBUG Console.WriteLine(ex); #endif - Disconnect($"Disconnected with error: {ex}"); - TraceException(ex); - } - - if (bytesWritten > 0) - { - _nextActivityCheck = Core.TickCount + 90000; - reader.Advance((uint)bytesWritten); - } - - return bytesWritten == result.Length; + Disconnect($"Disconnected with error: {ex}"); + TraceException(ex); } - private void DecodePacket(ArraySegment[] buffer, ref int length) + if (bytesWritten > 0) { - CircularBuffer cBuffer = new CircularBuffer(buffer); - _packetDecoder?.Invoke(cBuffer, ref length); + _nextActivityCheck = Core.TickCount + 90000; + reader.Advance((uint)bytesWritten); } - private void ReceiveData() + return bytesWritten == result.Length; + } + + private void DecodePacket(ArraySegment[] buffer, ref int length) + { + CircularBuffer cBuffer = new CircularBuffer(buffer); + _packetDecoder?.Invoke(cBuffer, ref length); + } + + private void ReceiveData() + { + var writer = RecvPipe.Writer; + var result = writer.TryGetMemory(); + + if (result.IsClosed || result.Length == 0) { - var writer = RecvPipe.Writer; - var result = writer.TryGetMemory(); + return; + } - if (result.IsClosed || result.Length == 0) - { - return; - } + var bytesWritten = 0; - var bytesWritten = 0; - - try - { - bytesWritten = Connection.Receive(result.Buffer, SocketFlags.None); - } - catch (SocketException ex) - { + try + { + bytesWritten = Connection.Receive(result.Buffer, SocketFlags.None); + } + catch (SocketException ex) + { #if DEBUG if (ex.ErrorCode != 54 && ex.ErrorCode != 89 && ex.ErrorCode != 995) { Console.WriteLine(ex); } #endif - Disconnect(string.Empty); - } - catch (Exception ex) - { + Disconnect(string.Empty); + } + catch (Exception ex) + { #if DEBUG Console.WriteLine(ex); #endif - Disconnect($"Disconnected with error: {ex}"); - TraceException(ex); - } - - if (bytesWritten <= 0) - { - Disconnect(string.Empty); - return; - } - - DecodePacket(result.Buffer, ref bytesWritten); - - writer.Advance((uint)bytesWritten); - _nextActivityCheck = Core.TickCount + 90000; + Disconnect($"Disconnected with error: {ex}"); + TraceException(ex); } - public static void FlushAll() + if (bytesWritten <= 0) { - while (FlushPending.Count != 0) + Disconnect(string.Empty); + return; + } + + DecodePacket(result.Buffer, ref bytesWritten); + + writer.Advance((uint)bytesWritten); + _nextActivityCheck = Core.TickCount + 90000; + } + + public static void FlushAll() + { + while (FlushPending.Count != 0) + { + FlushPending.Dequeue()?.Flush(); + } + } + + public static void Slice() + { + int count = _pollGroup.Poll(ref _polledStates); + + if (count > 0) + { + for (int i = 0; i < count; i++) { - FlushPending.Dequeue()?.Flush(); + (_polledStates[i].Target as NetState)?.HandleReceive(); + _polledStates[i] = default; } } - public static void Slice() + while (FlushPending.TryDequeue(out var ns)) { - int count = _pollGroup.Poll(ref _polledStates); - - if (count > 0) + if (!ns.Flush()) { - for (int i = 0; i < count; i++) - { - (_polledStates[i].Target as NetState)?.HandleReceive(); - _polledStates[i] = default; - } - } - - while (FlushPending.TryDequeue(out var ns)) - { - if (!ns.Flush()) - { - // Incomplete data, so we need to requeue - FlushedPartials.Enqueue(ns); - } - } - - var hasDisposes = !Disposed.IsEmpty; - while (Disposed.TryDequeue(out var ns)) - { - ns.Dispose(); - } - - if (hasDisposes) - { - _pollGroup.Poll(ref _polledStates); + // Incomplete data, so we need to requeue + FlushedPartials.Enqueue(ns); } } - public void CheckAlive(long curTicks) + var hasDisposes = !Disposed.IsEmpty; + while (Disposed.TryDequeue(out var ns)) { - if (Connection != null && _nextActivityCheck - curTicks < 0) - { - LogInfo("Disconnecting due to inactivity..."); - Disconnect("Disconnecting due to inactivity."); - } + ns.Dispose(); } - public static void CheckAllAlive() + if (hasDisposes) { - try - { - long curTicks = Core.TickCount; + _pollGroup.Poll(ref _polledStates); + } + } - foreach (var ns in TcpServer.Instances) - { - ns.CheckAlive(curTicks); - } - } - catch (Exception ex) + public void CheckAlive(long curTicks) + { + if (Connection != null && _nextActivityCheck - curTicks < 0) + { + LogInfo("Disconnecting due to inactivity..."); + Disconnect("Disconnecting due to inactivity."); + } + } + + public static void CheckAllAlive() + { + try + { + long curTicks = Core.TickCount; + + foreach (var ns in TcpServer.Instances) { - TraceException(ex); + ns.CheckAlive(curTicks); } } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public PacketHandler GetHandler(int packetID) => IncomingPackets.GetHandler(packetID); - - public static void TraceException(Exception ex) + catch (Exception ex) { - try - { - using var op = new StreamWriter("network-errors.log", true); - op.WriteLine("# {0}", Core.Now); + TraceException(ex); + } + } - op.WriteLine(ex); + public static void TraceException(Exception ex) + { + try + { + using var op = new StreamWriter("network-errors.log", true); + op.WriteLine("# {0}", Core.Now); - op.WriteLine(); - op.WriteLine(); - } - catch - { - // ignored - } + op.WriteLine(ex); - Console.WriteLine(ex); + op.WriteLine(); + op.WriteLine(); + } + catch + { + // ignored } - public void Disconnect(string reason) + Console.WriteLine(ex); + } + + public void Disconnect(string reason) + { + if (!_running) { - if (!_running) - { - return; - } - - _running = false; - - try - { - if (_disconnectReason != string.Empty) - { - throw new Exception("Attempted to disconnect a netstate twice."); - } - } - catch (Exception ex) - { - TraceException(ex); - } - - _disconnectReason = reason; - Disposed.Enqueue(this); + return; } - public static void TraceDisconnect(string reason, string ip) + _running = false; + + try { - if (reason == string.Empty) + if (_disconnectReason != string.Empty) { - return; - } - - try - { - using StreamWriter op = new StreamWriter("network-disconnects.log", true); - op.WriteLine($"# {Core.Now}"); - - op.WriteLine($"NetState: {ip}"); - op.WriteLine(reason); - - op.WriteLine(); - op.WriteLine(); - } - catch (Exception ex) - { - TraceException(ex); + throw new Exception("Attempted to disconnect a netstate twice."); } } - - private void Dispose() + catch (Exception ex) { - TraceDisconnect(_disconnectReason, _toString); + TraceException(ex); + } - if (_running) - { - throw new Exception("Disconnected a NetState that is still running."); - } + _disconnectReason = reason; + Disposed.Enqueue(this); + } + + public static void TraceDisconnect(string reason, string ip) + { + if (reason == string.Empty) + { + return; + } + + try + { + using StreamWriter op = new StreamWriter("network-disconnects.log", true); + op.WriteLine($"# {Core.Now}"); + + op.WriteLine($"NetState: {ip}"); + op.WriteLine(reason); + + op.WriteLine(); + op.WriteLine(); + } + catch (Exception ex) + { + TraceException(ex); + } + } + + private void Dispose() + { + TraceDisconnect(_disconnectReason, _toString); + + if (_running) + { + throw new Exception("Disconnected a NetState that is still running."); + } #if THREADGUARD if (Thread.CurrentThread != Core.Thread) @@ -1109,46 +1096,45 @@ namespace Server.Network } #endif - TcpServer.Instances.Remove(this); - try - { - _pollGroup.Remove(Connection); - } - catch (Exception ex) - { - TraceException(ex); - } + TcpServer.Instances.Remove(this); + try + { + _pollGroup.Remove(Connection); + } + catch (Exception ex) + { + TraceException(ex); + } - Connection.Close(); - _handle.Free(); + Connection.Close(); + _handle.Free(); - var m = Mobile; - Mobile = null; + var m = Mobile; + Mobile = null; - if (m?.NetState == this) - { - m.NetState = null; - } + if (m?.NetState == this) + { + m.NetState = null; + } - var a = Account; + var a = Account; - Gumps.Clear(); - Menus.Clear(); - HuePickers.Clear(); - Account = null; - ServerInfo = null; - CityInfo = null; + Gumps.Clear(); + Menus.Clear(); + HuePickers.Clear(); + Account = null; + ServerInfo = null; + CityInfo = null; - var count = TcpServer.Instances.Count; + var count = TcpServer.Instances.Count; - if (a != null) - { - LogInfo("Disconnected. [{0} Online] [{1}]", count, a); - } - else - { - LogInfo("Disconnected. [{0} Online]", count); - } + if (a != null) + { + LogInfo("Disconnected. [{0} Online] [{1}]", count, a); + } + else + { + LogInfo("Disconnected. [{0} Online]", count); } } } diff --git a/Projects/Server/Network/PacketHandler.cs b/Projects/Server/Network/PacketHandler.cs index 664119b30..fdf13b589 100644 --- a/Projects/Server/Network/PacketHandler.cs +++ b/Projects/Server/Network/PacketHandler.cs @@ -1,27 +1,43 @@ -namespace Server.Network +/************************************************************************* + * ModernUO * + * Copyright 2019-2022 - ModernUO Development Team * + * Email: hi@modernuo.com * + * File: PacketHandler.cs * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + +namespace Server.Network; + +public delegate void OnPacketReceive(NetState state, CircularBufferReader reader, int packetLength); + +public delegate bool ThrottlePacketCallback(int packetId, NetState state, out bool drop); + +public class PacketHandler { - public delegate void OnPacketReceive(NetState state, CircularBufferReader reader, ref int packetLength); + private int _length; - public delegate bool ThrottlePacketCallback(int packetId, NetState state, out bool drop); - - public class PacketHandler + public PacketHandler(int packetID, int length, bool ingame, OnPacketReceive onReceive) { - public PacketHandler(int packetID, int length, bool ingame, OnPacketReceive onReceive) - { - PacketID = packetID; - Length = length; - Ingame = ingame; - OnReceive = onReceive; - } - - public int PacketID { get; } - - public int Length { get; } - - public OnPacketReceive OnReceive { get; } - - public ThrottlePacketCallback ThrottleCallback { get; set; } - - public bool Ingame { get; } + _length = length; + PacketID = packetID; + Ingame = ingame; + OnReceive = onReceive; } + + public int PacketID { get; } + + public virtual int GetLength(NetState ns) => _length; + + public OnPacketReceive OnReceive { get; } + + public ThrottlePacketCallback ThrottleCallback { get; set; } + + public bool Ingame { get; } } diff --git a/Projects/Server/Network/Packets/IncomingAccountPackets.cs b/Projects/Server/Network/Packets/IncomingAccountPackets.cs index 41bf8919d..a29d6157c 100644 --- a/Projects/Server/Network/Packets/IncomingAccountPackets.cs +++ b/Projects/Server/Network/Packets/IncomingAccountPackets.cs @@ -55,7 +55,7 @@ public static class IncomingAccountPackets IncomingPackets.Register(0xF8, 106, false, CreateCharacter); } - public static void CreateCharacter(NetState state, CircularBufferReader reader, ref int packetLength) + public static void CreateCharacter(NetState state, CircularBufferReader reader, int packetLength) { reader.Seek(9, SeekOrigin.Current); /* @@ -185,7 +185,7 @@ public static class IncomingAccountPackets } } - public static void DeleteCharacter(NetState state, CircularBufferReader reader, ref int packetLength) + public static void DeleteCharacter(NetState state, CircularBufferReader reader, int packetLength) { reader.Seek(30, SeekOrigin.Current); var index = reader.ReadInt32(); @@ -193,24 +193,24 @@ public static class IncomingAccountPackets EventSink.InvokeDeleteRequest(state, index); } - public static void AccountID(NetState state, CircularBufferReader reader, ref int packetLength) + public static void AccountID(NetState state, CircularBufferReader reader, int packetLength) { } - public static void AssistVersion(NetState state, CircularBufferReader reader, ref int packetLength) + public static void AssistVersion(NetState state, CircularBufferReader reader, int packetLength) { var unk = reader.ReadInt32(); var av = reader.ReadAscii(); } - public static void ClientVersion(NetState state, CircularBufferReader reader, ref int packetLength) + public static void ClientVersion(NetState state, CircularBufferReader reader, int packetLength) { var version = state.Version = new CV(reader.ReadAscii()); EventSink.InvokeClientVersionReceived(state, version); } - public static void ClientType(NetState state, CircularBufferReader reader, ref int packetLength) + public static void ClientType(NetState state, CircularBufferReader reader, int packetLength) { reader.ReadUInt16(); @@ -220,7 +220,7 @@ public static class IncomingAccountPackets EventSink.InvokeClientVersionReceived(state, version); } - public static void PlayCharacter(NetState state, CircularBufferReader reader, ref int packetLength) + public static void PlayCharacter(NetState state, CircularBufferReader reader, int packetLength) { reader.Seek(4, SeekOrigin.Current); // 0xEDEDEDED @@ -359,7 +359,7 @@ public static class IncomingAccountPackets return authID; } - public static void GameLogin(NetState state, CircularBufferReader reader, ref int packetLength) + public static void GameLogin(NetState state, CircularBufferReader reader, int packetLength) { // TODO: Connection throttling @@ -413,7 +413,7 @@ public static class IncomingAccountPackets } } - public static void PlayServer(NetState state, CircularBufferReader reader, ref int packetLength) + public static void PlayServer(NetState state, CircularBufferReader reader, int packetLength) { int index = reader.ReadInt16(); var info = state.ServerInfo; @@ -434,7 +434,7 @@ public static class IncomingAccountPackets } } - public static void LoginServerSeed(NetState state, CircularBufferReader reader, ref int packetLength) + public static void LoginServerSeed(NetState state, CircularBufferReader reader, int packetLength) { state._seed = reader.ReadInt32(); state.Seeded = true; @@ -454,7 +454,7 @@ public static class IncomingAccountPackets state.Version = new ClientVersion(clientMaj, clientMin, clientRev, clientPat); } - public static void AccountLogin(NetState state, CircularBufferReader reader, ref int packetLength) + public static void AccountLogin(NetState state, CircularBufferReader reader, int packetLength) { // TODO: Throttle Connection diff --git a/Projects/Server/Network/Packets/IncomingEntityPackets.cs b/Projects/Server/Network/Packets/IncomingEntityPackets.cs index bd2815eee..40fe5a252 100644 --- a/Projects/Server/Network/Packets/IncomingEntityPackets.cs +++ b/Projects/Server/Network/Packets/IncomingEntityPackets.cs @@ -27,7 +27,7 @@ public static class IncomingEntityPackets IncomingPackets.Register(0xD6, 0, true, BatchQueryProperties); } - public static void ObjectHelpRequest(NetState state, CircularBufferReader reader, ref int packetLength) + public static void ObjectHelpRequest(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; @@ -56,7 +56,7 @@ public static class IncomingEntityPackets } } - public static void UseReq(NetState state, CircularBufferReader reader, ref int packetLength) + public static void UseReq(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; @@ -100,7 +100,7 @@ public static class IncomingEntityPackets } } - public static void LookReq(NetState state, CircularBufferReader reader, ref int packetLength) + public static void LookReq(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; @@ -149,7 +149,7 @@ public static class IncomingEntityPackets } } - public static void BatchQueryProperties(NetState state, CircularBufferReader reader, ref int packetLength) + public static void BatchQueryProperties(NetState state, CircularBufferReader reader, int packetLength) { if (!ObjectPropertyList.Enabled) { diff --git a/Projects/Server/Network/Packets/IncomingExtendedCommandPackets.cs b/Projects/Server/Network/Packets/IncomingExtendedCommandPackets.cs index e082c70e1..bda5b3917 100644 --- a/Projects/Server/Network/Packets/IncomingExtendedCommandPackets.cs +++ b/Projects/Server/Network/Packets/IncomingExtendedCommandPackets.cs @@ -1,6 +1,6 @@ /************************************************************************* * ModernUO * - * Copyright 2019-2020 - ModernUO Development Team * + * Copyright 2019-2022 - ModernUO Development Team * * Email: hi@modernuo.com * * File: IncomingExtendedCommandPackets.cs * * * @@ -13,15 +13,13 @@ * along with this program. If not, see . * *************************************************************************/ -using System.Collections.Generic; using Server.ContextMenus; namespace Server.Network; public static class IncomingExtendedCommandPackets { - private static readonly PacketHandler[] m_ExtendedHandlersLow = new PacketHandler[0x100]; - private static readonly Dictionary m_ExtendedHandlersHigh = new(); + private static readonly PacketHandler[] _extendedHandlers = new PacketHandler[0x100]; // TODO: Change to outside configuration public static int[] ValidAnimations { get; set; } = @@ -61,50 +59,34 @@ public static class IncomingExtendedCommandPackets RegisterExtended(0x32, true, ToggleFlying); } - private static void UnhandledBF(NetState state, CircularBufferReader reader, ref int packetLength) + private static void UnhandledBF(NetState state, CircularBufferReader reader, int packetLength) { } - public static void Empty(NetState state, CircularBufferReader reader, ref int packetLength) + public static void Empty(NetState state, CircularBufferReader reader, int packetLength) { } public static void RegisterExtended(int packetID, bool ingame, OnPacketReceive onReceive) { - if (packetID >= 0 && packetID < 0x100) + if (packetID is >= 0 and < 0x100) { - m_ExtendedHandlersLow[packetID] = new PacketHandler(packetID, 0, ingame, onReceive); - } - else - { - m_ExtendedHandlersHigh[packetID] = new PacketHandler(packetID, 0, ingame, onReceive); + _extendedHandlers[packetID] = new PacketHandler(packetID, 0, ingame, onReceive); } } - public static PacketHandler GetExtendedHandler(int packetID) - { - if (packetID >= 0 && packetID < 0x100) - { - return m_ExtendedHandlersLow[packetID]; - } - - m_ExtendedHandlersHigh.TryGetValue(packetID, out var handler); - return handler; - } + public static PacketHandler GetExtendedHandler(int packetID) => + packetID is >= 0 and < 0x100 ? _extendedHandlers[packetID] : null; public static void RemoveExtendedHandler(int packetID) { - if (packetID >= 0 && packetID < 0x100) + if (packetID is >= 0 and < 0x100) { - m_ExtendedHandlersLow[packetID] = null; - } - else - { - m_ExtendedHandlersHigh.Remove(packetID); + _extendedHandlers[packetID] = null; } } - public static void ExtendedCommand(NetState state, CircularBufferReader reader, ref int packetLength) + public static void ExtendedCommand(NetState state, CircularBufferReader reader, int packetLength) { int packetId = reader.ReadUInt16(); @@ -130,18 +112,18 @@ public static class IncomingExtendedCommandPackets } else { - ph.OnReceive(state, reader, ref packetLength); + ph.OnReceive(state, reader, packetLength); } } - public static void ScreenSize(NetState state, CircularBufferReader reader, ref int packetLength) + public static void ScreenSize(NetState state, CircularBufferReader reader, int packetLength) { var width = reader.ReadInt32(); var unk = reader.ReadInt32(); } // TODO: Move out of the core - public static void PartyMessage(NetState state, CircularBufferReader reader, ref int packetLength) + public static void PartyMessage(NetState state, CircularBufferReader reader, int packetLength) { if (state.Mobile == null) { @@ -151,25 +133,25 @@ public static class IncomingExtendedCommandPackets switch (reader.ReadByte()) { case 0x01: - PartyMessage_AddMember(state, reader, ref packetLength); + PartyMessage_AddMember(state, reader, packetLength); break; case 0x02: - PartyMessage_RemoveMember(state, reader, ref packetLength); + PartyMessage_RemoveMember(state, reader, packetLength); break; case 0x03: - PartyMessage_PrivateMessage(state, reader, ref packetLength); + PartyMessage_PrivateMessage(state, reader, packetLength); break; case 0x04: - PartyMessage_PublicMessage(state, reader, ref packetLength); + PartyMessage_PublicMessage(state, reader, packetLength); break; case 0x06: - PartyMessage_SetCanLoot(state, reader, ref packetLength); + PartyMessage_SetCanLoot(state, reader, packetLength); break; case 0x08: - PartyMessage_Accept(state, reader, ref packetLength); + PartyMessage_Accept(state, reader, packetLength); break; case 0x09: - PartyMessage_Decline(state, reader, ref packetLength); + PartyMessage_Decline(state, reader, packetLength); break; default: reader.Trace(state); @@ -177,17 +159,17 @@ public static class IncomingExtendedCommandPackets } } - public static void PartyMessage_AddMember(NetState state, CircularBufferReader reader, ref int packetLength) + public static void PartyMessage_AddMember(NetState state, CircularBufferReader reader, int packetLength) { PartyCommands.Handler?.OnAdd(state.Mobile); } - public static void PartyMessage_RemoveMember(NetState state, CircularBufferReader reader, ref int packetLength) + public static void PartyMessage_RemoveMember(NetState state, CircularBufferReader reader, int packetLength) { PartyCommands.Handler?.OnRemove(state.Mobile, World.FindMobile((Serial)reader.ReadUInt32())); } - public static void PartyMessage_PrivateMessage(NetState state, CircularBufferReader reader, ref int packetLength) + public static void PartyMessage_PrivateMessage(NetState state, CircularBufferReader reader, int packetLength) { PartyCommands.Handler?.OnPrivateMessage( state.Mobile, @@ -196,27 +178,27 @@ public static class IncomingExtendedCommandPackets ); } - public static void PartyMessage_PublicMessage(NetState state, CircularBufferReader reader, ref int packetLength) + public static void PartyMessage_PublicMessage(NetState state, CircularBufferReader reader, int packetLength) { PartyCommands.Handler?.OnPublicMessage(state.Mobile, reader.ReadBigUniSafe()); } - public static void PartyMessage_SetCanLoot(NetState state, CircularBufferReader reader, ref int packetLength) + public static void PartyMessage_SetCanLoot(NetState state, CircularBufferReader reader, int packetLength) { PartyCommands.Handler?.OnSetCanLoot(state.Mobile, reader.ReadBoolean()); } - public static void PartyMessage_Accept(NetState state, CircularBufferReader reader, ref int packetLength) + public static void PartyMessage_Accept(NetState state, CircularBufferReader reader, int packetLength) { PartyCommands.Handler?.OnAccept(state.Mobile, World.FindMobile((Serial)reader.ReadUInt32())); } - public static void PartyMessage_Decline(NetState state, CircularBufferReader reader, ref int packetLength) + public static void PartyMessage_Decline(NetState state, CircularBufferReader reader, int packetLength) { PartyCommands.Handler?.OnDecline(state.Mobile, World.FindMobile((Serial)reader.ReadUInt32())); } - public static void Animate(NetState state, CircularBufferReader reader, ref int packetLength) + public static void Animate(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; @@ -240,7 +222,7 @@ public static class IncomingExtendedCommandPackets } } - public static void CastSpell(NetState state, CircularBufferReader reader, ref int packetLength) + public static void CastSpell(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; @@ -255,12 +237,12 @@ public static class IncomingExtendedCommandPackets EventSink.InvokeCastSpellRequest(from, spellID, spellbook); } - public static void ToggleFlying(NetState state, CircularBufferReader reader, ref int packetLength) + public static void ToggleFlying(NetState state, CircularBufferReader reader, int packetLength) { state.Mobile?.ToggleFlying(); } - public static void StunRequest(NetState state, CircularBufferReader reader, ref int packetLength) + public static void StunRequest(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; @@ -272,7 +254,7 @@ public static class IncomingExtendedCommandPackets EventSink.InvokeStunRequest(from); } - public static void DisarmRequest(NetState state, CircularBufferReader reader, ref int packetLength) + public static void DisarmRequest(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; @@ -284,7 +266,7 @@ public static class IncomingExtendedCommandPackets EventSink.InvokeDisarmRequest(from); } - public static void StatLockChange(NetState state, CircularBufferReader reader, ref int packetLength) + public static void StatLockChange(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; @@ -315,12 +297,12 @@ public static class IncomingExtendedCommandPackets } } - public static void CloseStatus(NetState state, CircularBufferReader reader, ref int packetLength) + public static void CloseStatus(NetState state, CircularBufferReader reader, int packetLength) { var serial = (Serial)reader.ReadUInt32(); } - public static void Language(NetState state, CircularBufferReader reader, ref int packetLength) + public static void Language(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; @@ -332,7 +314,7 @@ public static class IncomingExtendedCommandPackets from.Language = reader.ReadAscii(4); } - public static void QueryProperties(NetState state, CircularBufferReader reader, ref int packetLength) + public static void QueryProperties(NetState state, CircularBufferReader reader, int packetLength) { if (!ObjectPropertyList.Enabled) { @@ -364,7 +346,7 @@ public static class IncomingExtendedCommandPackets } } - public static void ContextMenuResponse(NetState state, CircularBufferReader reader, ref int packetLength) + public static void ContextMenuResponse(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; @@ -420,7 +402,7 @@ public static class IncomingExtendedCommandPackets } } - public static void ContextMenuRequest(NetState state, CircularBufferReader reader, ref int packetLength) + public static void ContextMenuRequest(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; var target = World.FindEntity((Serial)reader.ReadUInt32()); @@ -455,7 +437,7 @@ public static class IncomingExtendedCommandPackets } } - public static void BandageTarget(NetState state, CircularBufferReader reader, ref int packetLength) + public static void BandageTarget(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; @@ -490,21 +472,21 @@ public static class IncomingExtendedCommandPackets } } - public static void TargetedSpell(NetState state, CircularBufferReader reader, ref int packetLength) + public static void TargetedSpell(NetState state, CircularBufferReader reader, int packetLength) { var spellId = (short)(reader.ReadInt16() - 1); // zero based; EventSink.InvokeTargetedSpell(state.Mobile, World.FindEntity((Serial)reader.ReadUInt32()), spellId); } - public static void TargetedSkillUse(NetState state, CircularBufferReader reader, ref int packetLength) + public static void TargetedSkillUse(NetState state, CircularBufferReader reader, int packetLength) { var skillId = reader.ReadInt16(); EventSink.InvokeTargetedSkillUse(state.Mobile, World.FindEntity((Serial)reader.ReadUInt32()), skillId); } - public static void TargetByResourceMacro(NetState state, CircularBufferReader reader, ref int packetLength) + public static void TargetByResourceMacro(NetState state, CircularBufferReader reader, int packetLength) { var serial = (Serial)reader.ReadUInt32(); diff --git a/Projects/Server/Network/Packets/IncomingHousePackets.cs b/Projects/Server/Network/Packets/IncomingHousePackets.cs index b5969f56c..1d9925537 100644 --- a/Projects/Server/Network/Packets/IncomingHousePackets.cs +++ b/Projects/Server/Network/Packets/IncomingHousePackets.cs @@ -22,7 +22,7 @@ public static class IncomingHousePackets IncomingPackets.Register(0xFB, 2, false, ShowPublicHouseContent); } - public static void ShowPublicHouseContent(NetState state, CircularBufferReader reader, ref int packetLength) + public static void ShowPublicHouseContent(NetState state, CircularBufferReader reader, int packetLength) { var showPublicHouseContent = reader.ReadBoolean(); } diff --git a/Projects/Server/Network/Packets/IncomingItemPackets.cs b/Projects/Server/Network/Packets/IncomingItemPackets.cs index 0e3cf6601..06543cadf 100644 --- a/Projects/Server/Network/Packets/IncomingItemPackets.cs +++ b/Projects/Server/Network/Packets/IncomingItemPackets.cs @@ -24,13 +24,13 @@ public static class IncomingItemPackets public static void Configure() { IncomingPackets.Register(0x07, 7, true, LiftReq); - IncomingPackets.Register(0x08, 15, true, DropReq); + IncomingPackets.Register(new ContainerGridPacketHandler(0x08, 14, true, DropReq)); IncomingPackets.Register(0x13, 10, true, EquipReq); IncomingPackets.Register(0xEC, 0, false, EquipMacro); IncomingPackets.Register(0xED, 0, false, UnequipMacro); } - public static void LiftReq(NetState state, CircularBufferReader reader, ref int packetLength) + public static void LiftReq(NetState state, CircularBufferReader reader, int packetLength) { var serial = (Serial)reader.ReadUInt32(); int amount = reader.ReadUInt16(); @@ -39,7 +39,7 @@ public static class IncomingItemPackets state.Mobile.Lift(item, amount, out _, out _); } - public static void EquipReq(NetState state, CircularBufferReader reader, ref int packetLength) + public static void EquipReq(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; var item = from.Holding; @@ -64,20 +64,17 @@ public static class IncomingItemPackets item.ClearBounce(); } - public static void DropReq(NetState state, CircularBufferReader reader, ref int packetLength) + public static void DropReq(NetState state, CircularBufferReader reader, int packetLength) { reader.ReadInt32(); // serial, ignored int x = reader.ReadInt16(); int y = reader.ReadInt16(); int z = reader.ReadSByte(); + if (state.ContainerGridLines) { reader.ReadByte(); // Grid Location? } - else - { - packetLength -= 1; - } Serial dest = (Serial)reader.ReadUInt32(); @@ -110,7 +107,7 @@ public static class IncomingItemPackets } } - public static void DropReq6017(NetState state, CircularBufferReader reader, ref int packetLength) + public static void DropReq6017(NetState state, CircularBufferReader reader, int packetLength) { reader.ReadInt32(); // serial, ignored int x = reader.ReadInt16(); @@ -148,7 +145,7 @@ public static class IncomingItemPackets } } - public static void EquipMacro(NetState state, CircularBufferReader reader, ref int packetLength) + public static void EquipMacro(NetState state, CircularBufferReader reader, int packetLength) { int count = reader.ReadByte(); var serialList = new List(count); @@ -160,7 +157,7 @@ public static class IncomingItemPackets EventSink.InvokeEquipMacro(state.Mobile, serialList); } - public static void UnequipMacro(NetState state, CircularBufferReader reader, ref int packetLength) + public static void UnequipMacro(NetState state, CircularBufferReader reader, int packetLength) { int count = reader.ReadByte(); var layers = new List(count); diff --git a/Projects/Server/Network/Packets/IncomingMessagePackets.cs b/Projects/Server/Network/Packets/IncomingMessagePackets.cs index 0f25bf85e..8bea6bb45 100644 --- a/Projects/Server/Network/Packets/IncomingMessagePackets.cs +++ b/Projects/Server/Network/Packets/IncomingMessagePackets.cs @@ -46,7 +46,7 @@ public static class IncomingMessagePackets IncomingPackets.Register(0xAD, 0, true, UnicodeSpeech); } - public static void AsciiSpeech(NetState state, CircularBufferReader reader, ref int packetLength) + public static void AsciiSpeech(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; @@ -73,7 +73,7 @@ public static class IncomingMessagePackets from.DoSpeech(text, Array.Empty(), type, Utility.ClipDyedHue(hue)); } - public static void UnicodeSpeech(NetState state, CircularBufferReader reader, ref int packetLength) + public static void UnicodeSpeech(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; diff --git a/Projects/Server/Network/Packets/IncomingMobilePackets.cs b/Projects/Server/Network/Packets/IncomingMobilePackets.cs index 569fa430b..a612e4ea1 100644 --- a/Projects/Server/Network/Packets/IncomingMobilePackets.cs +++ b/Projects/Server/Network/Packets/IncomingMobilePackets.cs @@ -27,7 +27,7 @@ public static class IncomingMobilePackets IncomingPackets.Register(0x6F, 0, true, SecureTrade); } - public static void RenameRequest(NetState state, CircularBufferReader reader, ref int packetLength) + public static void RenameRequest(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; var targ = World.FindMobile((Serial)reader.ReadUInt32()); @@ -38,7 +38,7 @@ public static class IncomingMobilePackets } } - public static void MobileNameRequest(NetState state, CircularBufferReader reader, ref int packetLength) + public static void MobileNameRequest(NetState state, CircularBufferReader reader, int packetLength) { var m = World.FindMobile((Serial)reader.ReadUInt32()); @@ -48,7 +48,7 @@ public static class IncomingMobilePackets } } - public static void ProfileReq(NetState state, CircularBufferReader reader, ref int packetLength) + public static void ProfileReq(NetState state, CircularBufferReader reader, int packetLength) { int type = reader.ReadByte(); var serial = (Serial)reader.ReadUInt32(); @@ -88,7 +88,7 @@ public static class IncomingMobilePackets } } - public static void SecureTrade(NetState state, CircularBufferReader reader, ref int packetLength) + public static void SecureTrade(NetState state, CircularBufferReader reader, int packetLength) { switch (reader.ReadByte()) { diff --git a/Projects/Server/Network/Packets/IncomingMovementPackets.cs b/Projects/Server/Network/Packets/IncomingMovementPackets.cs index 0a82df9a7..9a361bfa2 100644 --- a/Projects/Server/Network/Packets/IncomingMovementPackets.cs +++ b/Projects/Server/Network/Packets/IncomingMovementPackets.cs @@ -78,7 +78,7 @@ public static class IncomingMovementPackets ns.SendTimeSyncResponse(); } - public static void MovementReq(NetState state, CircularBufferReader reader, ref int packetLength) + public static void MovementReq(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; diff --git a/Projects/Server/Network/Packets/IncomingPackets.cs b/Projects/Server/Network/Packets/IncomingPackets.cs index 71fbfd578..1eaec8c45 100644 --- a/Projects/Server/Network/Packets/IncomingPackets.cs +++ b/Projects/Server/Network/Packets/IncomingPackets.cs @@ -1,6 +1,6 @@ /************************************************************************* * ModernUO * - * Copyright (C) 2019-2021 - ModernUO Development Team * + * Copyright 2019-2022 - ModernUO Development Team * * Email: hi@modernuo.com * * File: IncomingPackets.cs * * * @@ -13,62 +13,43 @@ * along with this program. If not, see . * *************************************************************************/ -using System.Collections.Generic; using System.Runtime.CompilerServices; namespace Server.Network; public static class IncomingPackets { - private static readonly PacketHandler[] m_6017Handlers = new PacketHandler[0x100]; - - private static readonly EncodedPacketHandler[] m_EncodedHandlersLow = new EncodedPacketHandler[0x100]; - - private static readonly Dictionary m_EncodedHandlersHigh = - new(); + private static readonly EncodedPacketHandler[] _encodedHandlers = new EncodedPacketHandler[0x100]; public static PacketHandler[] Handlers { get; } = new PacketHandler[0x100]; - public static void Register(int packetID, int length, bool ingame, OnPacketReceive onReceive) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Register(int packetID, int length, bool ingame, OnPacketReceive onReceive) => + Register(new PacketHandler(packetID, length, ingame, onReceive)); + + public static void Register(PacketHandler packetHandler) { - Handlers[packetID] = new PacketHandler(packetID, length, ingame, onReceive); - m_6017Handlers[packetID] ??= new PacketHandler(packetID, length, ingame, onReceive); + Handlers[packetHandler.PacketID] = packetHandler; } public static PacketHandler GetHandler(int packetID) => Handlers[packetID]; public static void RegisterEncoded(int packetID, bool ingame, OnEncodedPacketReceive onReceive) { - if (packetID >= 0 && packetID < 0x100) + if (packetID is >= 0 and < 0x100) { - m_EncodedHandlersLow[packetID] = new EncodedPacketHandler(packetID, ingame, onReceive); - } - else - { - m_EncodedHandlersHigh[packetID] = new EncodedPacketHandler(packetID, ingame, onReceive); + _encodedHandlers[packetID] = new EncodedPacketHandler(packetID, ingame, onReceive); } } - public static EncodedPacketHandler GetEncodedHandler(int packetID) - { - if (packetID >= 0 && packetID < 0x100) - { - return m_EncodedHandlersLow[packetID]; - } - - m_EncodedHandlersHigh.TryGetValue(packetID, out var handler); - return handler; - } + public static EncodedPacketHandler GetEncodedHandler(int packetID) => + packetID is >= 0 and < 0x100 ? _encodedHandlers[packetID] : null; public static void RemoveEncodedHandler(int packetID) { - if (packetID >= 0 && packetID < 0x100) + if (packetID is >= 0 and < 0x100) { - m_EncodedHandlersLow[packetID] = null; - } - else - { - m_EncodedHandlersHigh.Remove(packetID); + _encodedHandlers[packetID] = null; } } diff --git a/Projects/Server/Network/Packets/IncomingPlayerPackets.cs b/Projects/Server/Network/Packets/IncomingPlayerPackets.cs index 2b7e14515..0a6f18c97 100644 --- a/Projects/Server/Network/Packets/IncomingPlayerPackets.cs +++ b/Projects/Server/Network/Packets/IncomingPlayerPackets.cs @@ -52,18 +52,18 @@ public static class IncomingPlayerPackets IncomingPackets.RegisterEncoded(0x32, true, QuestGumpRequest); } - public static void DeathStatusResponse(NetState state, CircularBufferReader reader, ref int packetLength) + public static void DeathStatusResponse(NetState state, CircularBufferReader reader, int packetLength) { // Ignored } - public static void RequestScrollWindow(NetState state, CircularBufferReader reader, ref int packetLength) + public static void RequestScrollWindow(NetState state, CircularBufferReader reader, int packetLength) { int lastTip = reader.ReadInt16(); int type = reader.ReadByte(); } - public static void AttackReq(NetState state, CircularBufferReader reader, ref int packetLength) + public static void AttackReq(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; @@ -80,7 +80,7 @@ public static class IncomingPlayerPackets } } - public static void HuePickerResponse(NetState state, CircularBufferReader reader, ref int packetLength) + public static void HuePickerResponse(NetState state, CircularBufferReader reader, int packetLength) { var serial = reader.ReadUInt32(); _ = reader.ReadInt16(); // Item ID @@ -97,7 +97,7 @@ public static class IncomingPlayerPackets } } - public static void SystemInfo(NetState state, CircularBufferReader reader, ref int packetLength) + public static void SystemInfo(NetState state, CircularBufferReader reader, int packetLength) { int v1 = reader.ReadByte(); int v2 = reader.ReadUInt16(); @@ -113,7 +113,7 @@ public static class IncomingPlayerPackets var v8 = reader.ReadInt32(); } - public static void TextCommand(NetState state, CircularBufferReader reader, ref int packetLength) + public static void TextCommand(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; @@ -208,7 +208,7 @@ public static class IncomingPlayerPackets } } - public static void AsciiPromptResponse(NetState state, CircularBufferReader reader, ref int packetLength) + public static void AsciiPromptResponse(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; @@ -244,7 +244,7 @@ public static class IncomingPlayerPackets } } - public static void UnicodePromptResponse(NetState state, CircularBufferReader reader, ref int packetLength) + public static void UnicodePromptResponse(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; @@ -281,7 +281,7 @@ public static class IncomingPlayerPackets } } - public static void MenuResponse(NetState state, CircularBufferReader reader, ref int packetLength) + public static void MenuResponse(NetState state, CircularBufferReader reader, int packetLength) { var serial = reader.ReadUInt32(); int menuID = reader.ReadInt16(); // unused in our implementation @@ -311,33 +311,33 @@ public static class IncomingPlayerPackets } } - public static void Disconnect(NetState state, CircularBufferReader reader, ref int packetLength) + public static void Disconnect(NetState state, CircularBufferReader reader, int packetLength) { var minusOne = reader.ReadInt32(); } - public static void ConfigurationFile(NetState state, CircularBufferReader reader, ref int packetLength) + public static void ConfigurationFile(NetState state, CircularBufferReader reader, int packetLength) { } - public static void LogoutReq(NetState state, CircularBufferReader reader, ref int packetLength) + public static void LogoutReq(NetState state, CircularBufferReader reader, int packetLength) { state.SendLogoutAck(); } - public static void ChangeSkillLock(NetState state, CircularBufferReader reader, ref int packetLength) + public static void ChangeSkillLock(NetState state, CircularBufferReader reader, int packetLength) { var s = state.Mobile.Skills[reader.ReadInt16()]; s?.SetLockNoRelay((SkillLock)reader.ReadByte()); } - public static void HelpRequest(NetState state, CircularBufferReader reader, ref int packetLength) + public static void HelpRequest(NetState state, CircularBufferReader reader, int packetLength) { EventSink.InvokeHelpRequest(state.Mobile); } - public static void DisplayGumpResponse(NetState state, CircularBufferReader reader, ref int packetLength) + public static void DisplayGumpResponse(NetState state, CircularBufferReader reader, int packetLength) { var serial = (Serial)reader.ReadUInt32(); var typeID = reader.ReadInt32(); @@ -479,13 +479,13 @@ public static class IncomingPlayerPackets } } - public static void SetWarMode(NetState state, CircularBufferReader reader, ref int packetLength) + public static void SetWarMode(NetState state, CircularBufferReader reader, int packetLength) { state.Mobile?.DelayChangeWarmode(reader.ReadBoolean()); } // TODO: Throttle/make this more safe - public static void Resynchronize(NetState state, CircularBufferReader reader, ref int packetLength) + public static void Resynchronize(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; @@ -502,17 +502,17 @@ public static class IncomingPlayerPackets state.Sequence = 0; } - public static void PingReq(NetState state, CircularBufferReader reader, ref int packetLength) + public static void PingReq(NetState state, CircularBufferReader reader, int packetLength) { state.SendPingAck(reader.ReadByte()); } - public static void SetUpdateRange(NetState state, CircularBufferReader reader, ref int packetLength) + public static void SetUpdateRange(NetState state, CircularBufferReader reader, int packetLength) { state.SendChangeUpdateRange(18); } - public static void MobileQuery(NetState state, CircularBufferReader reader, ref int packetLength) + public static void MobileQuery(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; if (from == null) @@ -549,7 +549,7 @@ public static class IncomingPlayerPackets } } - public static void CrashReport(NetState state, CircularBufferReader reader, ref int packetLength) + public static void CrashReport(NetState state, CircularBufferReader reader, int packetLength) { var clientMaj = reader.ReadByte(); var clientMin = reader.ReadByte(); @@ -593,11 +593,19 @@ public static class IncomingPlayerPackets EventSink.InvokeQuestGumpRequest(state.Mobile); } - public static void EncodedCommand(NetState state, CircularBufferReader reader, ref int packetLength) + public static void EncodedCommand(NetState state, CircularBufferReader reader, int packetLength) { var e = World.FindEntity((Serial)reader.ReadUInt32()); int packetId = reader.ReadUInt16(); + // We will add support if this is ever a real thing. + if (packetId > 0xFF) + { + var reason = $"Sent unsupported encoded packet (0xD7x{packetId:X4}"; + state.LogInfo(reason); + state.Disconnect(reason); + } + var ph = IncomingPackets.GetEncodedHandler(packetId); if (ph == null) @@ -608,15 +616,13 @@ public static class IncomingPlayerPackets if (ph.Ingame && state.Mobile == null) { - state.LogInfo( - "Sent in-game packet (0xD7x{0:X2}) before being attached to a mobile", - packetId - ); - state.Disconnect($"Sent in-game packet (0xD7x{packetId:X2}) before being attached to a mobile."); + var reason = $"Sent in-game packet (0xD7x{packetId:X4}) before being attached to a mobile."; + state.LogInfo(reason); + state.Disconnect(reason); } else if (ph.Ingame && state.Mobile.Deleted) { - state.Disconnect($"Sent in-game packet(0xD7x{packetId:X2}) but mobile is deleted."); + state.Disconnect($"Sent in-game packet(0xD7x{packetId:X4}) but mobile is deleted."); } else { diff --git a/Projects/Server/Network/Packets/IncomingTargetingPackets.cs b/Projects/Server/Network/Packets/IncomingTargetingPackets.cs index 1d03d85e9..e4bcd7342 100644 --- a/Projects/Server/Network/Packets/IncomingTargetingPackets.cs +++ b/Projects/Server/Network/Packets/IncomingTargetingPackets.cs @@ -25,7 +25,7 @@ public static class IncomingTargetingPackets IncomingPackets.Register(0x6C, 19, true, TargetResponse); } - public static void TargetResponse(NetState state, CircularBufferReader reader, ref int packetLength) + public static void TargetResponse(NetState state, CircularBufferReader reader, int packetLength) { int type = reader.ReadByte(); var targetID = reader.ReadInt32(); diff --git a/Projects/Server/Network/Packets/IncomingVendorPackets.cs b/Projects/Server/Network/Packets/IncomingVendorPackets.cs index 0a11dd2d4..e2e12a689 100644 --- a/Projects/Server/Network/Packets/IncomingVendorPackets.cs +++ b/Projects/Server/Network/Packets/IncomingVendorPackets.cs @@ -14,6 +14,7 @@ *************************************************************************/ using System.Collections.Generic; +using System.IO; namespace Server.Network; @@ -25,7 +26,7 @@ public static class IncomingVendorPackets IncomingPackets.Register(0x9F, 0, true, VendorSellReply); } - public static void VendorBuyReply(NetState state, CircularBufferReader reader, ref int packetLength) + public static void VendorBuyReply(NetState state, CircularBufferReader reader, int packetLength) { var vendor = World.FindMobile((Serial)reader.ReadUInt32()); @@ -65,7 +66,7 @@ public static class IncomingVendorPackets state.SendEndVendorBuy(vendor.Serial); } - public static void VendorSellReply(NetState state, CircularBufferReader reader, ref int packetLength) + public static void VendorSellReply(NetState state, CircularBufferReader reader, int packetLength) { var serial = (Serial)reader.ReadUInt32(); var vendor = World.FindMobile(serial); diff --git a/Projects/UOContent/Engines/Chat/ChatPackets.cs b/Projects/UOContent/Engines/Chat/ChatPackets.cs index 01b47b471..a74d63c0e 100644 --- a/Projects/UOContent/Engines/Chat/ChatPackets.cs +++ b/Projects/UOContent/Engines/Chat/ChatPackets.cs @@ -27,7 +27,7 @@ namespace Server.Engines.Chat IncomingPackets.Register(0xB3, 0, true, ChatAction); } - public static void OpenChatWindowRequest(NetState state, CircularBufferReader reader, ref int packetLength) + public static void OpenChatWindowRequest(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; @@ -48,7 +48,7 @@ namespace Server.Engines.Chat ChatUser.AddChatUser(from, chatName); } - public static void ChatAction(NetState state, CircularBufferReader reader, ref int packetLength) + public static void ChatAction(NetState state, CircularBufferReader reader, int packetLength) { if (!ChatSystem.Enabled) { diff --git a/Projects/UOContent/Engines/ML Quests/Gumps/RaceChangeGump.cs b/Projects/UOContent/Engines/ML Quests/Gumps/RaceChangeGump.cs index d5b6a0555..d19425fa8 100644 --- a/Projects/UOContent/Engines/ML Quests/Gumps/RaceChangeGump.cs +++ b/Projects/UOContent/Engines/ML Quests/Gumps/RaceChangeGump.cs @@ -193,7 +193,7 @@ namespace Server.Engines.MLQuests.Gumps return false; } - private static void RaceChangeReply(NetState state, CircularBufferReader reader, ref int packetLength) + private static void RaceChangeReply(NetState state, CircularBufferReader reader, int packetLength) { if (!m_Pending.TryGetValue(state, out var raceChangeState)) { diff --git a/Projects/UOContent/Engines/UltimaStore/UltimaStorePackets.cs b/Projects/UOContent/Engines/UltimaStore/UltimaStorePackets.cs index cb40edc26..24a3ba797 100644 --- a/Projects/UOContent/Engines/UltimaStore/UltimaStorePackets.cs +++ b/Projects/UOContent/Engines/UltimaStore/UltimaStorePackets.cs @@ -9,7 +9,7 @@ namespace Server.Engines.UltimaStore IncomingPackets.Register(0xFA, 1, true, UltimaStoreOpenRequest); } - public static void UltimaStoreOpenRequest(NetState state, CircularBufferReader reader, ref int packetLength) + public static void UltimaStoreOpenRequest(NetState state, CircularBufferReader reader, int packetLength) { state.Mobile.SendMessage("Ultima Store is not currently available."); } diff --git a/Projects/UOContent/Items/Books/BookPackets.cs b/Projects/UOContent/Items/Books/BookPackets.cs index af59afa86..5eb43d5a1 100644 --- a/Projects/UOContent/Items/Books/BookPackets.cs +++ b/Projects/UOContent/Items/Books/BookPackets.cs @@ -29,7 +29,7 @@ namespace Server.Items IncomingPackets.Register(0x93, 99, true, OldHeaderChange); } - public static void OldHeaderChange(NetState state, CircularBufferReader reader, ref int packetLength) + public static void OldHeaderChange(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; @@ -48,7 +48,7 @@ namespace Server.Items book.Author = Utility.FixHtml(author); } - public static void HeaderChange(NetState state, CircularBufferReader reader, ref int packetLength) + public static void HeaderChange(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; @@ -84,7 +84,7 @@ namespace Server.Items book.Author = Utility.FixHtml(author); } - public static void ContentChange(NetState state, CircularBufferReader reader, ref int packetLength) + public static void ContentChange(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; diff --git a/Projects/UOContent/Items/Bulletin Boards/BulletinBoardPackets.cs b/Projects/UOContent/Items/Bulletin Boards/BulletinBoardPackets.cs index 0eac35aab..2cca09634 100644 --- a/Projects/UOContent/Items/Bulletin Boards/BulletinBoardPackets.cs +++ b/Projects/UOContent/Items/Bulletin Boards/BulletinBoardPackets.cs @@ -48,7 +48,7 @@ namespace Server.Network return $"{seconds} second{(seconds == 1 ? "" : "s")}"; } - public static void BBClientRequest(NetState state, CircularBufferReader reader, ref int packetLength) + public static void BBClientRequest(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; diff --git a/Projects/UOContent/Items/Games/Mahjong/MahjongPackets.cs b/Projects/UOContent/Items/Games/Mahjong/MahjongPackets.cs index 601f676d4..fa958623e 100644 --- a/Projects/UOContent/Items/Games/Mahjong/MahjongPackets.cs +++ b/Projects/UOContent/Items/Games/Mahjong/MahjongPackets.cs @@ -61,7 +61,7 @@ namespace Server.Engines.Mahjong RegisterSubCommand(0x18, MoveDealerIndicator); } - public static void OnPacket(NetState state, CircularBufferReader reader, ref int packetLength) + public static void OnPacket(NetState state, CircularBufferReader reader, int packetLength) { var game = World.FindItem((Serial)reader.ReadUInt32()) as MahjongGame; diff --git a/Projects/UOContent/Items/Maps/MapItemPackets.cs b/Projects/UOContent/Items/Maps/MapItemPackets.cs index 2de7dd443..c98e34812 100644 --- a/Projects/UOContent/Items/Maps/MapItemPackets.cs +++ b/Projects/UOContent/Items/Maps/MapItemPackets.cs @@ -25,7 +25,7 @@ namespace Server.Network IncomingPackets.Register(0x56, 11, true, OnMapCommand); } - private static void OnMapCommand(NetState state, CircularBufferReader reader, ref int packetLength) + private static void OnMapCommand(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; diff --git a/Projects/UOContent/Misc/HardwareInfo.cs b/Projects/UOContent/Misc/HardwareInfo.cs index e3a651da7..20ef94ddc 100644 --- a/Projects/UOContent/Misc/HardwareInfo.cs +++ b/Projects/UOContent/Misc/HardwareInfo.cs @@ -141,7 +141,7 @@ namespace Server } } - public static void OnReceive(NetState state, CircularBufferReader reader, ref int packetLength) + public static void OnReceive(NetState state, CircularBufferReader reader, int packetLength) { reader.ReadByte(); // 1: <4.0.1a, 2>=4.0.1a diff --git a/Projects/UOContent/Misc/PacketThrottles.cs b/Projects/UOContent/Misc/PacketThrottles.cs index dda06aab8..a49f62aca 100644 --- a/Projects/UOContent/Misc/PacketThrottles.cs +++ b/Projects/UOContent/Misc/PacketThrottles.cs @@ -38,8 +38,8 @@ namespace Server.Network } else { - Delays[0x03] = 5; // Speech - Delays[0xAD] = 5; // Speech + Delays[0x03] = 25; // Speech + Delays[0xAD] = 25; // Speech Delays[0x75] = 500; // Rename request } @@ -141,7 +141,7 @@ namespace Server.Network return true; } - if (Core.TickCount < ns.GetPacketDelay(packetID) + Delays[packetID]) + if (Core.TickCount < ns.GetPacketTime(packetID) + Delays[packetID]) { drop = true; return false; diff --git a/Projects/UOContent/Multis/Houses/HouseFoundation.cs b/Projects/UOContent/Multis/Houses/HouseFoundation.cs index bd63938ec..d8c1a7176 100644 --- a/Projects/UOContent/Multis/Houses/HouseFoundation.cs +++ b/Projects/UOContent/Multis/Houses/HouseFoundation.cs @@ -1766,7 +1766,7 @@ namespace Server.Multis context.Foundation.SendInfoTo(state); } - public static void QueryDesignDetails(NetState state, CircularBufferReader reader, ref int packetLength) + public static void QueryDesignDetails(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; diff --git a/Projects/UOContent/Network/ConnectUO.cs b/Projects/UOContent/Network/ConnectUO.cs index fb4a51e29..12745c420 100644 --- a/Projects/UOContent/Network/ConnectUO.cs +++ b/Projects/UOContent/Network/ConnectUO.cs @@ -70,7 +70,7 @@ namespace Server.Network } } - public static void PollInfo(NetState ns, CircularBufferReader reader, ref int packetLength) + public static void PollInfo(NetState state, CircularBufferReader reader, int packetLength) { var version = reader.ReadByte(); @@ -83,21 +83,21 @@ namespace Server.Network if (!span.SequenceEqual(_token)) { - ns.Disconnect("Invalid token sent for ConnectUO"); + state.Disconnect("Invalid token sent for ConnectUO"); return; } } } - ns.LogInfo($"ConnectUO (v{version}) is requesting stats."); + state.LogInfo($"ConnectUO (v{version}) is requesting stats."); if (version > ConnectUOProtocolVersion) { Utility.PushColor(ConsoleColor.Yellow); - ns.LogInfo("Warning! ConnectUO (v{version}) is newer than what is supported."); + state.LogInfo("Warning! ConnectUO (v{version}) is newer than what is supported."); Utility.PopColor(); } - ns.SendServerPollInfo(); + state.SendServerPollInfo(); } public static void SendServerPollInfo(this NetState ns) diff --git a/Projects/UOContent/Network/MapUO.cs b/Projects/UOContent/Network/MapUO.cs index b0ddf0d75..92769f92b 100644 --- a/Projects/UOContent/Network/MapUO.cs +++ b/Projects/UOContent/Network/MapUO.cs @@ -36,14 +36,14 @@ namespace Server.Network public static void Register(int cmd, bool ingame, OnPacketReceive onReceive) => _handlers[cmd] = new PacketHandler(cmd, 0, ingame, onReceive); - public static void QueryGuildMemberLocations(NetState state, CircularBufferReader reader, ref int packetLength) + public static void QueryGuildMemberLocations(NetState state, CircularBufferReader reader, int packetLength) { Mobile from = state.Mobile; state.SendGuildMemberLocations(from, from.Guild as Guild, reader.ReadBoolean()); } - public static void QueryPartyMemberLocations(NetState state, CircularBufferReader reader, ref int packetLength) + public static void QueryPartyMemberLocations(NetState state, CircularBufferReader reader, int packetLength) { Mobile from = state.Mobile; var party = Party.Get(from); diff --git a/Projects/UOContent/Network/ProtocolExtensions.cs b/Projects/UOContent/Network/ProtocolExtensions.cs index c012bdb11..5c2be60ac 100644 --- a/Projects/UOContent/Network/ProtocolExtensions.cs +++ b/Projects/UOContent/Network/ProtocolExtensions.cs @@ -21,11 +21,11 @@ namespace Server.Network { var packetHandlers = new PacketHandler[0x100]; - void DecodeBundledPacket(NetState state, CircularBufferReader reader, ref int packetLength) + void DecodeBundledPacket(NetState state, CircularBufferReader reader, int packetLength) { int cmd = reader.ReadByte(); - PacketHandler ph = cmd >= 0 && cmd < packetHandlers.Length ? packetHandlers[cmd] : null; + PacketHandler ph = packetHandlers[cmd]; if (ph == null) { @@ -43,7 +43,7 @@ namespace Server.Network } else { - ph.OnReceive(state, reader, ref packetLength); + ph.OnReceive(state, reader, packetLength); } } diff --git a/Projects/UOContent/Network/UOGateway.cs b/Projects/UOContent/Network/UOGateway.cs index 2980760e4..3d9721f37 100644 --- a/Projects/UOContent/Network/UOGateway.cs +++ b/Projects/UOContent/Network/UOGateway.cs @@ -33,9 +33,9 @@ namespace Server.Network } } - public static void QueryCompactShardStats(NetState ns, CircularBufferReader reader, ref int packetLength) + public static void QueryCompactShardStats(NetState state, CircularBufferReader reader, int packetLength) { - ns.SendCompactShardStats( + state.SendCompactShardStats( (uint)(Core.TickCount / 1000), TcpServer.Instances.Count - 1, // Shame if you modify this! World.Items.Count, @@ -44,10 +44,10 @@ namespace Server.Network ); } - public static void QueryExtendedShardStats(NetState ns, CircularBufferReader reader, ref int packetLength) + public static void QueryExtendedShardStats(NetState state, CircularBufferReader reader, int packetLength) { const long ticksInHour = 1000 * 60 * 60; - ns.SendExtendedShardStats( + state.SendExtendedShardStats( ServerList.ServerName, (int)(Core.TickCount / ticksInHour), TcpServer.Instances.Count - 1, // Shame if you modify this! diff --git a/Projects/UOContent/Skills/Tracking/Tracking.cs b/Projects/UOContent/Skills/Tracking/Tracking.cs index ee7bfa99a..8e691702a 100644 --- a/Projects/UOContent/Skills/Tracking/Tracking.cs +++ b/Projects/UOContent/Skills/Tracking/Tracking.cs @@ -19,7 +19,7 @@ namespace Server.SkillHandlers SkillInfo.Table[(int)SkillName.Tracking].Callback = OnUse; } - public static void QuestArrow(NetState state, CircularBufferReader reader, ref int packetLength) + public static void QuestArrow(NetState state, CircularBufferReader reader, int packetLength) { if (state.Mobile is PlayerMobile from) { From 60991b7ab05a49ff17c385e08e6daa57ae5fbc7e Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Mon, 7 Mar 2022 22:43:30 -0800 Subject: [PATCH 096/213] fix: Deletes schema migration project (#954) --- ModernUO.sln | 8 -------- .../Schema Migrations/Run Schema Migrations.csproj | 13 ------------- 2 files changed, 21 deletions(-) delete mode 100644 Projects/Schema Migrations/Run Schema Migrations.csproj diff --git a/ModernUO.sln b/ModernUO.sln index 3251fb4a4..f42d55f2e 100644 --- a/ModernUO.sln +++ b/ModernUO.sln @@ -12,8 +12,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UOContent.Tests", "Projects EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Benchmarks", "Projects\Benchmarks\Benchmarks.csproj", "{38B7E4A1-FDDD-486C-98EE-BA7B13712528}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Run Schema Migrations", "Projects\Schema Migrations\Run Schema Migrations.csproj", "{75256276-FEAB-416C-9DB8-533FE816A0EF}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Analyze|x64 = Analyze|x64 @@ -51,12 +49,6 @@ Global {38B7E4A1-FDDD-486C-98EE-BA7B13712528}.Debug|x64.Build.0 = Debug|x64 {38B7E4A1-FDDD-486C-98EE-BA7B13712528}.Release|x64.ActiveCfg = Release|x64 {38B7E4A1-FDDD-486C-98EE-BA7B13712528}.Release|x64.Build.0 = Release|x64 - {75256276-FEAB-416C-9DB8-533FE816A0EF}.Analyze|x64.ActiveCfg = Analyze|x64 - {75256276-FEAB-416C-9DB8-533FE816A0EF}.Analyze|x64.Build.0 = Analyze|x64 - {75256276-FEAB-416C-9DB8-533FE816A0EF}.Debug|x64.ActiveCfg = Debug|x64 - {75256276-FEAB-416C-9DB8-533FE816A0EF}.Debug|x64.Build.0 = Debug|x64 - {75256276-FEAB-416C-9DB8-533FE816A0EF}.Release|x64.ActiveCfg = Release|x64 - {75256276-FEAB-416C-9DB8-533FE816A0EF}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Projects/Schema Migrations/Run Schema Migrations.csproj b/Projects/Schema Migrations/Run Schema Migrations.csproj deleted file mode 100644 index b671b550a..000000000 --- a/Projects/Schema Migrations/Run Schema Migrations.csproj +++ /dev/null @@ -1,13 +0,0 @@ - - - Schema_Migrations - - - - - - - - - - From 44bd129734d67c6bb820ba1557ef392b766c1121 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Thu, 10 Mar 2022 12:18:22 -0800 Subject: [PATCH 097/213] fix: Fixes mana insufficient message for newer clients. (#957) Publish 100 introduced the cliloc change for insufficient mana. This was rolled out starting with v7.0.65.4 on 6/22/2018. --- Projects/UOContent/Spells/Base/Spell.cs | 166 +++++++++++++----------- 1 file changed, 91 insertions(+), 75 deletions(-) diff --git a/Projects/UOContent/Spells/Base/Spell.cs b/Projects/UOContent/Spells/Base/Spell.cs index 78eea7bdc..c7631a7ee 100644 --- a/Projects/UOContent/Spells/Base/Spell.cs +++ b/Projects/UOContent/Spells/Base/Spell.cs @@ -459,6 +459,8 @@ namespace Server.Spells } } + private static ClientVersion _insufficientManaClientChange = new ClientVersion("7.0.65.4"); + public bool Cast() { StartCastTime = Core.TickCount; @@ -473,13 +475,19 @@ namespace Server.Spells return false; } - if (Scroll is BaseWand && Caster.Spell?.IsCasting == true) + var isCasting = Caster.Spell?.IsCasting == true; + var isWand = Scroll is BaseWand; + + if (isCasting) { - Caster.SendLocalizedMessage(502643); // You can not cast a spell while frozen. - } - else if (Caster.Spell?.IsCasting == true) - { - Caster.SendLocalizedMessage(502642); // You are already casting a spell. + if (isWand) + { + Caster.SendLocalizedMessage(502643); // You can not cast a spell while frozen. + } + else + { + Caster.SendLocalizedMessage(502642); // You are already casting a spell. + } } else if (BlockedByHorrificBeast && TransformationSpellHelper.UnderTransformation(Caster, typeof(HorrificBeastSpell)) || @@ -487,7 +495,7 @@ namespace Server.Spells { Caster.SendLocalizedMessage(1061091); // You cannot cast that spell in this form. } - else if (Scroll is not BaseWand && (Caster.Paralyzed || Caster.Frozen)) + else if (!isWand && (Caster.Paralyzed || Caster.Frozen)) { Caster.SendLocalizedMessage(502643); // You can not cast a spell while frozen. } @@ -502,76 +510,84 @@ namespace Server.Spells else if ((Caster as PlayerMobile)?.DuelContext?.AllowSpellCast(Caster, this) == false) { } - else if (Caster.Mana >= ScaleMana(GetMana())) - { - if (Caster.Spell == null && Caster.CheckSpellCast(this) && CheckCast() && - Caster.Region.OnBeginSpellCast(Caster, this)) - { - State = SpellState.Casting; - Caster.Spell = this; - - if (Scroll is not BaseWand && RevealOnCast) - { - Caster.RevealingAction(); - } - - SayMantra(); - - var castDelay = GetCastDelay(); - - if (ShowHandMovement && (Caster.Body.IsHuman || Caster.Player && Caster.Body.IsMonster)) - { - var count = (int)Math.Ceiling(castDelay.TotalSeconds / AnimateDelay.TotalSeconds); - - if (count != 0) - { - _animTimer = new AnimTimer(this, count); - _animTimer.Start(); - } - - if (Info.LeftHandEffect > 0) - { - Caster.FixedParticles(0, 10, 5, Info.LeftHandEffect, EffectLayer.LeftHand); - } - - if (Info.RightHandEffect > 0) - { - Caster.FixedParticles(0, 10, 5, Info.RightHandEffect, EffectLayer.RightHand); - } - } - - if (ClearHandsOnCast) - { - Caster.ClearHands(); - } - - if (Core.ML) - { - WeaponAbility.ClearCurrentAbility(Caster); - } - - _castTimer = new CastTimer(this, castDelay); - // m_CastTimer.Start(); - - OnBeginCast(); - - if (castDelay > TimeSpan.Zero) - { - _castTimer.Start(); - } - else - { - _castTimer.Tick(); - } - - return true; - } - - return false; - } else { - Caster.LocalOverheadMessage(MessageType.Regular, 0x22, 502625); // Insufficient mana + var requiredMana = ScaleMana(GetMana()); + + if (Caster.Mana >= requiredMana) + { + if (Caster.Spell == null && Caster.CheckSpellCast(this) && CheckCast() && + Caster.Region.OnBeginSpellCast(Caster, this)) + { + State = SpellState.Casting; + Caster.Spell = this; + + if (!isWand && RevealOnCast) + { + Caster.RevealingAction(); + } + + SayMantra(); + + var castDelay = GetCastDelay(); + + if (ShowHandMovement && (Caster.Body.IsHuman || Caster.Player && Caster.Body.IsMonster)) + { + var count = (int)Math.Ceiling(castDelay.TotalSeconds / AnimateDelay.TotalSeconds); + + if (count != 0) + { + _animTimer = new AnimTimer(this, count); + _animTimer.Start(); + } + + if (Info.LeftHandEffect > 0) + { + Caster.FixedParticles(0, 10, 5, Info.LeftHandEffect, EffectLayer.LeftHand); + } + + if (Info.RightHandEffect > 0) + { + Caster.FixedParticles(0, 10, 5, Info.RightHandEffect, EffectLayer.RightHand); + } + } + + if (ClearHandsOnCast) + { + Caster.ClearHands(); + } + + if (Core.ML) + { + WeaponAbility.ClearCurrentAbility(Caster); + } + + _castTimer = new CastTimer(this, castDelay); + // m_CastTimer.Start(); + + OnBeginCast(); + + if (castDelay > TimeSpan.Zero) + { + _castTimer.Start(); + } + else + { + _castTimer.Tick(); + } + + return true; + } + } + else if (Caster.NetState?.Version >= _insufficientManaClientChange) + { + // Insufficient mana. You must have at least ~1_MANA_REQUIREMENT~ Mana to use this spell. + Caster.LocalOverheadMessage(MessageType.Regular, 0x22, 502625, requiredMana.ToString()); + } + else + { + Caster.LocalOverheadMessage(MessageType.Regular, 0x22, 502625); // Insufficient mana + } } return false; From bdee7bc671c229235e1b5cd65fec88d9f21feb46 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Thu, 10 Mar 2022 22:55:06 -0800 Subject: [PATCH 098/213] fix: Fixes NPC slowness. (#955) * Adds the following configurations: * `movement.delay.npcMinDelay` - 0.1 - Pets or Non-monster NPCs * `movement.delay.npcMaxDelay` - 0.4 - Pets or Non-monster NPCs * `movement.delay.monsterMinDelay` - 0.4 - Non-pet Monsters or NPC vs Player Combat * `movement.delay.monsterMaxDelay` - 0.8 - Non-pet Monsters or NPC vs Player Combat * `movement.delay.monsterMinDex` - 150 - Dex maximum for delay by dex * `movement.delay.MinDex` - 190 - Dex maximum for delay by dex --- Projects/Server.Tests/Server.Tests.csproj | 3 - .../Configuration/ServerConfiguration.cs | 24 + .../Ethics/Evil/Mobiles/UnholyFamiliar.cs | 2 +- .../Ethics/Evil/Mobiles/UnholySteed.cs | 2 +- .../Ethics/Hero/Mobiles/HolyFamiliar.cs | 2 +- .../Engines/Ethics/Hero/Mobiles/HolySteed.cs | 2 +- .../Factions/Mobiles/FactionWarHorse.cs | 2 +- .../Mobiles/Guards/BaseFactionGuard.cs | 2 +- .../Khaldun/Mobiles/GrimmochDrummel.cs | 2 +- .../Khaldun/Mobiles/LysanderGathenwale.cs | 2 +- .../Engines/Khaldun/Mobiles/MorgBergen.cs | 2 +- .../Engines/Khaldun/Mobiles/TavaraSewel.cs | 2 +- .../ML Quests/Definitions/BlightedGrove.cs | 4 +- .../Plants/MiscMobiles/GiantIceWorm.cs | 2 +- .../Dark Tides/Mobiles/SummonedPaladin.cs | 2 +- .../Emino's Undertaking/Mobiles/Henchman.cs | 2 +- .../Haochi's Trials/Mobiles/CursedSoul.cs | 2 +- .../Haochi's Trials/Mobiles/DeadlyImp.cs | 2 +- .../Haochi's Trials/Mobiles/DiseasedCat.cs | 2 +- .../Haochi's Trials/Mobiles/FierceDragon.cs | 2 +- .../Haochi's Trials/Mobiles/InjuredWolf.cs | 2 +- .../Haochi's Trials/Mobiles/YoungNinja.cs | 2 +- .../Haochi's Trials/Mobiles/YoungRonin.cs | 2 +- .../Uzeraan Turmoil/Mobiles/MilitiaFighter.cs | 2 +- .../Halloween/2006/Engines/TrickOrTreat.cs | 2 +- .../Halloween/2009/Foods/CreepyCake.cs | 2 +- .../Halloween/2009/Foods/MrPlainsCookies.cs | 2 +- .../Halloween/2011/Mobiles/PumpkinHead.cs | 2 +- .../Halloween/2012/Engines/PlayerZombies.cs | 2 +- Projects/UOContent/Items/Food/Asian.cs | 18 +- Projects/UOContent/Items/Food/Bowls.cs | 22 +- Projects/UOContent/Items/Food/Food.cs | 22 +- Projects/UOContent/Items/Food/Fruits.cs | 2 +- .../Items/Special/Holiday/HolidayFoods.cs | 4 +- .../Items/Special/Holiday/PKHolidayStuff.cs | 2 +- .../Items/Talismans/TalismanSummons.cs | 2 +- .../Items/Weapons/Abilities/ForceOfNature.cs | 2 +- Projects/UOContent/Mobiles/AI/BaseAI.cs | 575 +++++++++--------- Projects/UOContent/Mobiles/AI/SpeedInfo.cs | 254 ++------ .../Mobiles/Animals/Bears/BlackBear.cs | 2 +- .../Mobiles/Animals/Bears/BrownBear.cs | 2 +- .../Mobiles/Animals/Bears/GrizzlyBear.cs | 2 +- .../Mobiles/Animals/Bears/PolarBear.cs | 2 +- .../Mobiles/Animals/Birds/Chicken.cs | 2 +- .../UOContent/Mobiles/Animals/Birds/Crane.cs | 2 +- .../UOContent/Mobiles/Animals/Birds/Eagle.cs | 2 +- .../Mobiles/Animals/Birds/Phoenix.cs | 2 +- .../Mobiles/Animals/Canines/DireWolf.cs | 2 +- .../Mobiles/Animals/Canines/GreyWolf.cs | 2 +- .../Mobiles/Animals/Canines/TimberWolf.cs | 2 +- .../Mobiles/Animals/Canines/WhiteWolf.cs | 2 +- .../UOContent/Mobiles/Animals/Cows/Bull.cs | 2 +- .../UOContent/Mobiles/Animals/Cows/Cow.cs | 2 +- .../Mobiles/Animals/Felines/Cougar.cs | 2 +- .../Mobiles/Animals/Felines/HellCat.cs | 2 +- .../Mobiles/Animals/Felines/Panther.cs | 2 +- .../Animals/Felines/PredatorHellCat.cs | 2 +- .../Mobiles/Animals/Felines/SnowLeopard.cs | 2 +- .../UOContent/Mobiles/Animals/Misc/Boar.cs | 2 +- .../Mobiles/Animals/Misc/BullFrog.cs | 2 +- .../UOContent/Mobiles/Animals/Misc/Dolphin.cs | 2 +- .../UOContent/Mobiles/Animals/Misc/Gaman.cs | 2 +- .../Mobiles/Animals/Misc/GiantToad.cs | 2 +- .../UOContent/Mobiles/Animals/Misc/Goat.cs | 2 +- .../UOContent/Mobiles/Animals/Misc/Gorilla.cs | 2 +- .../Mobiles/Animals/Misc/GreatHart.cs | 2 +- .../UOContent/Mobiles/Animals/Misc/Hind.cs | 2 +- .../UOContent/Mobiles/Animals/Misc/Llama.cs | 2 +- .../Mobiles/Animals/Misc/MountainGoat.cs | 2 +- .../Mobiles/Animals/Misc/PackHorse.cs | 2 +- .../Mobiles/Animals/Misc/PackLlama.cs | 2 +- .../UOContent/Mobiles/Animals/Misc/Pig.cs | 2 +- .../UOContent/Mobiles/Animals/Misc/Sheep.cs | 2 +- .../UOContent/Mobiles/Animals/Misc/Walrus.cs | 2 +- .../Mobiles/Animals/Mounts/BaseMount.cs | 2 +- .../UOContent/Mobiles/Animals/Mounts/Hiryu.cs | 2 +- .../UOContent/Mobiles/Animals/Mounts/Kirin.cs | 2 +- .../Mobiles/Animals/Mounts/LesserHiryu.cs | 2 +- .../Mobiles/Animals/Mounts/Unicorn.cs | 2 +- .../Animals/Mounts/War Horses/BaseWarHorse.cs | 2 +- .../Animals/Mounts/War Horses/CoMWarHorse.cs | 2 +- .../Mounts/War Horses/MinaxWarHorse.cs | 2 +- .../Animals/Mounts/War Horses/SLWarHorse.cs | 2 +- .../Animals/Mounts/War Horses/TBWarHorse.cs | 2 +- .../Mobiles/Animals/Reptiles/Alligator.cs | 2 +- .../Mobiles/Animals/Reptiles/GiantSerpent.cs | 2 +- .../Mobiles/Animals/Reptiles/IceSerpent.cs | 2 +- .../Mobiles/Animals/Reptiles/IceSnake.cs | 2 +- .../Mobiles/Animals/Reptiles/LavaLizard.cs | 2 +- .../Mobiles/Animals/Reptiles/LavaSerpent.cs | 2 +- .../Mobiles/Animals/Reptiles/LavaSnake.cs | 2 +- .../Mobiles/Animals/Reptiles/SilverSerpent.cs | 2 +- .../Mobiles/Animals/Reptiles/Snake.cs | 2 +- .../Mobiles/Animals/Rodents/GiantRat.cs | 2 +- .../Mobiles/Animals/Rodents/JackRabbit.cs | 2 +- .../Mobiles/Animals/Rodents/Rabbit.cs | 2 +- .../Mobiles/Animals/Rodents/SewerRat.cs | 2 +- .../Mobiles/Animals/Slimes/Jwilson.cs | 2 +- .../Town Critters/(UO 3D Only) Parrot.cs | 2 +- .../Mobiles/Animals/Town Critters/Bird.cs | 4 +- .../Mobiles/Animals/Town Critters/Cat.cs | 2 +- .../Mobiles/Animals/Town Critters/Dog.cs | 2 +- .../Mobiles/Animals/Town Critters/Rat.cs | 2 +- Projects/UOContent/Mobiles/BaseCreature.cs | 89 +-- .../Mobiles/Familiars/BaseFamiliar.cs | 2 +- .../Mobiles/Monsters/AOS/AbysmalHorror.cs | 2 +- .../Mobiles/Monsters/AOS/BoneDemon.cs | 2 +- .../Mobiles/Monsters/AOS/CrystalElemental.cs | 2 +- .../Mobiles/Monsters/AOS/DarknightCreeper.cs | 2 +- .../Mobiles/Monsters/AOS/DemonKnight.cs | 2 +- .../Mobiles/Monsters/AOS/Devourer.cs | 2 +- .../Mobiles/Monsters/AOS/FleshGolem.cs | 2 +- .../Mobiles/Monsters/AOS/FleshRenderer.cs | 2 +- .../Mobiles/Monsters/AOS/Gibberling.cs | 2 +- .../Mobiles/Monsters/AOS/GoreFiend.cs | 2 +- .../UOContent/Mobiles/Monsters/AOS/Impaler.cs | 2 +- .../Mobiles/Monsters/AOS/MoundOfMaggots.cs | 2 +- .../Mobiles/Monsters/AOS/PatchworkSkeleton.cs | 2 +- .../UOContent/Mobiles/Monsters/AOS/Ravager.cs | 2 +- .../Mobiles/Monsters/AOS/ShadowKnight.cs | 2 +- .../Mobiles/Monsters/AOS/SkitteringHopper.cs | 2 +- .../Mobiles/Monsters/AOS/Treefellow.cs | 2 +- .../Mobiles/Monsters/AOS/VampireBat.cs | 2 +- .../Mobiles/Monsters/AOS/WailingBanshee.cs | 2 +- .../Mobiles/Monsters/AOS/WandererOfTheVoid.cs | 2 +- .../Mobiles/Monsters/Ants/AntLion.cs | 2 +- .../Ants/BlackSolenInfiltratorQueen.cs | 2 +- .../Ants/BlackSolenInfiltratorWarrior.cs | 2 +- .../Mobiles/Monsters/Ants/BlackSolenQueen.cs | 2 +- .../Monsters/Ants/BlackSolenWarrior.cs | 2 +- .../Mobiles/Monsters/Ants/BlackSolenWorker.cs | 2 +- .../Monsters/Ants/RedSolenInfiltratorQueen.cs | 2 +- .../Ants/RedSolenInfiltratorWarrior.cs | 2 +- .../Mobiles/Monsters/Ants/RedSolenQueen.cs | 2 +- .../Mobiles/Monsters/Ants/RedSolenWarrior.cs | 2 +- .../Mobiles/Monsters/Ants/RedSolenWorker.cs | 2 +- .../Monsters/Arachnid/Magic/DreadSpider.cs | 2 +- .../Arachnid/Magic/TerathanAvenger.cs | 2 +- .../Arachnid/Magic/TerathanMatriarch.cs | 2 +- .../Monsters/Arachnid/Melee/FrostSpider.cs | 2 +- .../Arachnid/Melee/GiantBlackWidow.cs | 2 +- .../Monsters/Arachnid/Melee/GiantSpider.cs | 2 +- .../Monsters/Arachnid/Melee/TerathanDrone.cs | 2 +- .../Arachnid/Melee/TerathanWarrior.cs | 2 +- .../Monsters/Elemental/Magic/AcidElemental.cs | 2 +- .../Monsters/Elemental/Magic/AirElemental.cs | 2 +- .../Elemental/Magic/BloodElemental.cs | 2 +- .../Monsters/Elemental/Magic/Efreet.cs | 2 +- .../Monsters/Elemental/Magic/FireElemental.cs | 2 +- .../Monsters/Elemental/Magic/IceElemental.cs | 2 +- .../Elemental/Magic/PoisonElemental.cs | 2 +- .../Elemental/Magic/WaterElemental.cs | 2 +- .../Elemental/Melee/EarthElemental.cs | 2 +- .../Monsters/Elemental/Melee/SnowElemental.cs | 2 +- .../Monsters/Humanoid/Magic/AncientLich.cs | 2 +- .../Monsters/Humanoid/Magic/ArcaneDaemon.cs | 2 +- .../Mobiles/Monsters/Humanoid/Magic/Balron.cs | 2 +- .../Monsters/Humanoid/Magic/Betrayer.cs | 2 +- .../Mobiles/Monsters/Humanoid/Magic/Bogle.cs | 2 +- .../Monsters/Humanoid/Magic/BoneMagi.cs | 2 +- .../Mobiles/Monsters/Humanoid/Magic/Daemon.cs | 2 +- .../Monsters/Humanoid/Magic/ElderGazer.cs | 2 +- .../Monsters/Humanoid/Magic/EvilMage.cs | 2 +- .../Monsters/Humanoid/Magic/EvilMageLord.cs | 2 +- .../Monsters/Humanoid/Magic/FireGargoyle.cs | 2 +- .../Monsters/Humanoid/Magic/Gargoyle.cs | 2 +- .../Humanoid/Magic/GargoyleDestroyer.cs | 2 +- .../Humanoid/Magic/GargoyleEnforcer.cs | 2 +- .../Mobiles/Monsters/Humanoid/Magic/Gazer.cs | 2 +- .../Humanoid/Magic/GolemController.cs | 2 +- .../Monsters/Humanoid/Magic/IceFiend.cs | 2 +- .../Mobiles/Monsters/Humanoid/Magic/Imp.cs | 2 +- .../Mobiles/Monsters/Humanoid/Magic/Lich.cs | 2 +- .../Monsters/Humanoid/Magic/LichLord.cs | 2 +- .../Monsters/Humanoid/Magic/OrcishMage.cs | 2 +- .../Monsters/Humanoid/Magic/RatmanMage.cs | 2 +- .../Monsters/Humanoid/Magic/SavageShaman.cs | 2 +- .../Mobiles/Monsters/Humanoid/Magic/Shade.cs | 2 +- .../Monsters/Humanoid/Magic/SkeletalMage.cs | 2 +- .../Monsters/Humanoid/Magic/Spectre.cs | 2 +- .../Monsters/Humanoid/Magic/Succubus.cs | 2 +- .../Mobiles/Monsters/Humanoid/Magic/Titan.cs | 2 +- .../Mobiles/Monsters/Humanoid/Magic/Wraith.cs | 2 +- .../Monsters/Humanoid/Melee/ArcticOgreLord.cs | 2 +- .../Monsters/Humanoid/Melee/BoneKnight.cs | 2 +- .../Monsters/Humanoid/Melee/Brigand.cs | 2 +- .../Monsters/Humanoid/Melee/ChaosDaemon.cs | 2 +- .../Mobiles/Monsters/Humanoid/Melee/Cursed.cs | 2 +- .../Monsters/Humanoid/Melee/Cyclops.cs | 2 +- .../Monsters/Humanoid/Melee/Doppleganger.cs | 2 +- .../Monsters/Humanoid/Melee/ElfBrigand.cs | 2 +- .../Humanoid/Melee/EnslavedGargoyle.cs | 2 +- .../Mobiles/Monsters/Humanoid/Melee/Ettin.cs | 2 +- .../Monsters/Humanoid/Melee/Executioner.cs | 2 +- .../Monsters/Humanoid/Melee/FrostTroll.cs | 2 +- .../Monsters/Humanoid/Melee/GazerLarva.cs | 2 +- .../Mobiles/Monsters/Humanoid/Melee/Ghoul.cs | 2 +- .../Monsters/Humanoid/Melee/GreaterMongbat.cs | 2 +- .../Monsters/Humanoid/Melee/Guardian.cs | 2 +- .../Monsters/Humanoid/Melee/HeadlessOne.cs | 2 +- .../Monsters/Humanoid/Melee/HordeMinion.cs | 2 +- .../Monsters/Humanoid/Melee/Juggernaut.cs | 2 +- .../Humanoid/Melee/KhaldunRevenant.cs | 2 +- .../Humanoid/Melee/KhaldunSummoner.cs | 2 +- .../Monsters/Humanoid/Melee/KhaldunZealot.cs | 2 +- .../Mobiles/Monsters/Humanoid/Melee/Moloch.cs | 2 +- .../Monsters/Humanoid/Melee/Mongbat.cs | 2 +- .../Mobiles/Monsters/Humanoid/Melee/Mummy.cs | 2 +- .../Mobiles/Monsters/Humanoid/Melee/Ogre.cs | 2 +- .../Monsters/Humanoid/Melee/OgreLord.cs | 2 +- .../Mobiles/Monsters/Humanoid/Melee/Orc.cs | 2 +- .../Monsters/Humanoid/Melee/OrcBomber.cs | 2 +- .../Monsters/Humanoid/Melee/OrcBrute.cs | 2 +- .../Monsters/Humanoid/Melee/OrcCaptain.cs | 2 +- .../Monsters/Humanoid/Melee/OrcishLord.cs | 2 +- .../Mobiles/Monsters/Humanoid/Melee/Ratman.cs | 2 +- .../Monsters/Humanoid/Melee/RatmanArcher.cs | 2 +- .../Monsters/Humanoid/Melee/RestlessSoul.cs | 2 +- .../Monsters/Humanoid/Melee/RottingCorpse.cs | 2 +- .../Mobiles/Monsters/Humanoid/Melee/Savage.cs | 2 +- .../Monsters/Humanoid/Melee/SavageRider.cs | 2 +- .../Monsters/Humanoid/Melee/ShadowFiend.cs | 2 +- .../Monsters/Humanoid/Melee/SkeletalKnight.cs | 2 +- .../Monsters/Humanoid/Melee/Skeleton.cs | 2 +- .../Monsters/Humanoid/Melee/SpectralArmour.cs | 2 +- .../Monsters/Humanoid/Melee/StoneGargoyle.cs | 2 +- .../Monsters/Humanoid/Melee/StrongMongbat.cs | 2 +- .../Mobiles/Monsters/Humanoid/Melee/Troll.cs | 2 +- .../Mobiles/Monsters/Humanoid/Melee/Zombie.cs | 2 +- .../Monsters/LBR/Exodus/ExodusMinion.cs | 2 +- .../Monsters/LBR/Exodus/ExodusOverseer.cs | 2 +- .../Mobiles/Monsters/LBR/Jukas/JukaLord.cs | 2 +- .../Mobiles/Monsters/LBR/Jukas/JukaMage.cs | 2 +- .../Mobiles/Monsters/LBR/Jukas/JukaWarrior.cs | 2 +- .../Monsters/LBR/Meers/EnragedCreatures.cs | 2 +- .../Mobiles/Monsters/LBR/Meers/MeerCaptain.cs | 2 +- .../Mobiles/Monsters/LBR/Meers/MeerEternal.cs | 2 +- .../Mobiles/Monsters/LBR/Meers/MeerMage.cs | 2 +- .../Mobiles/Monsters/LBR/Meers/MeerWarrior.cs | 2 +- .../Mobiles/Monsters/ML/Animal/CuSidhe.cs | 2 +- .../Mobiles/Monsters/ML/Animal/Ferret.cs | 2 +- .../Monsters/ML/Animal/RagingGrizzlyBear.cs | 2 +- .../Mobiles/Monsters/ML/Animal/Squirrel.cs | 2 +- .../Monsters/ML/Blighted Grove/Hydra.cs | 4 +- .../ML/Humanoid/Magic/FetidEssence.cs | 2 +- .../ML/Humanoid/Magic/InterredGrizzle .cs | 2 +- .../Monsters/ML/Humanoid/Magic/MLDryad.cs | 2 +- .../Monsters/ML/Humanoid/Magic/Satyr.cs | 2 +- .../ML/Humanoid/Melee/CorruptedSoul.cs | 2 +- .../ML/Humanoid/Melee/FeralTreefellow.cs | 2 +- .../Monsters/ML/Humanoid/Melee/Minotaur.cs | 2 +- .../ML/Humanoid/Melee/MinotaurCaptain.cs | 2 +- .../ML/Humanoid/Melee/MinotaurScout.cs | 2 +- .../ML/Humanoid/Melee/PestilentBandage.cs | 2 +- .../ML/Humanoid/Melee/Tormented Minotaur.cs | 2 +- .../Monsters/ML/Humanoid/Melee/Troglodyte.cs | 2 +- .../Monsters/ML/Misc/Magic/GreaterDragon.cs | 2 +- .../Monsters/ML/Misc/Melee/CorrosiveSlime.cs | 2 +- .../ML/Prism of Light/CorporealBrume.cs | 2 +- .../ML/Prism of Light/CrystalDaemon.cs | 4 +- .../ML/Prism of Light/CrystalLatticeSeeker.cs | 6 +- .../ML/Prism of Light/CrystalVortex.cs | 6 +- .../ML/Prism of Light/MantraEffervescence.cs | 2 +- .../Monsters/ML/Prism of Light/Protector.cs | 4 +- .../ML/Prism of Light/UnfrozenMummy.cs | 6 +- .../Monsters/ML/Twisted Weald/Changeling.cs | 2 +- .../Monsters/Mammal/Melee/HellHound.cs | 2 +- .../Monsters/Mammal/Melee/VorpalBunny.cs | 2 +- .../Mobiles/Monsters/Misc/Magic/DarkWisp.cs | 2 +- .../Monsters/Misc/Magic/EtherealWarrior.cs | 2 +- .../Mobiles/Monsters/Misc/Magic/Pixie.cs | 2 +- .../Mobiles/Monsters/Misc/Magic/ShadowWisp.cs | 2 +- .../Mobiles/Monsters/Misc/Magic/Wisp.cs | 2 +- .../Mobiles/Monsters/Misc/Melee/Centaur.cs | 2 +- .../Monsters/Misc/Melee/EnergyVortex.cs | 2 +- .../Mobiles/Monsters/Misc/Melee/FrostOoze.cs | 2 +- .../Monsters/Misc/Melee/PlagueBeast.cs | 2 +- .../Monsters/Misc/Melee/PlagueBeastLord.cs | 2 +- .../Monsters/Misc/Melee/PlagueSpawn.cs | 2 +- .../Mobiles/Monsters/Misc/Melee/SandVortex.cs | 2 +- .../Mobiles/Monsters/Misc/Melee/Slime.cs | 2 +- .../Ore Elementals/AgapiteElemental.cs | 2 +- .../Ore Elementals/BronzeElemental.cs | 2 +- .../Ore Elementals/CopperElemental.cs | 2 +- .../Ore Elementals/DullCopperElemental.cs | 2 +- .../Ore Elementals/GoldenElemental.cs | 2 +- .../Ore Elementals/ShadowIronElemental.cs | 2 +- .../Ore Elementals/ValoriteElemental.cs | 2 +- .../Ore Elementals/VeriteElemental.cs | 2 +- .../Mobiles/Monsters/Plant/Magic/Reaper.cs | 2 +- .../Mobiles/Monsters/Plant/Melee/BogThing.cs | 2 +- .../Mobiles/Monsters/Plant/Melee/Bogling.cs | 2 +- .../Mobiles/Monsters/Plant/Melee/Corpser.cs | 2 +- .../Mobiles/Monsters/Plant/Melee/Quagmire.cs | 2 +- .../Monsters/Plant/Melee/SwampTentacle.cs | 2 +- .../Monsters/Plant/Melee/WhippingVine.cs | 2 +- .../Monsters/Reptile/Magic/AncientWyrm.cs | 2 +- .../Monsters/Reptile/Magic/DeepSeaSerpent.cs | 2 +- .../Mobiles/Monsters/Reptile/Magic/Dragon.cs | 2 +- .../Monsters/Reptile/Magic/Leviathan.cs | 2 +- .../Reptile/Magic/OphidianArchmage.cs | 2 +- .../Monsters/Reptile/Magic/OphidianMage.cs | 2 +- .../Reptile/Magic/OphidianMatriarch.cs | 2 +- .../Monsters/Reptile/Magic/SeaSerpent.cs | 2 +- .../Reptile/Magic/SerpentineDragon.cs | 2 +- .../Monsters/Reptile/Magic/ShadowWyrm.cs | 2 +- .../Monsters/Reptile/Magic/SkeletalDragon.cs | 2 +- .../Monsters/Reptile/Magic/WhiteWyrm.cs | 2 +- .../Mobiles/Monsters/Reptile/Melee/Drake.cs | 2 +- .../Mobiles/Monsters/Reptile/Melee/Harpy.cs | 2 +- .../Mobiles/Monsters/Reptile/Melee/Kraken.cs | 2 +- .../Monsters/Reptile/Melee/Lizardman.cs | 2 +- .../Monsters/Reptile/Melee/OphidianKnight.cs | 2 +- .../Monsters/Reptile/Melee/OphidianWarrior.cs | 2 +- .../Monsters/Reptile/Melee/Scorpion.cs | 2 +- .../Monsters/Reptile/Melee/StoneHarpy.cs | 2 +- .../Mobiles/Monsters/Reptile/Melee/Wyvern.cs | 2 +- .../Mobiles/Monsters/SE/BakeKitsune.cs | 2 +- .../Mobiles/Monsters/SE/DeathWatchBeetle.cs | 2 +- .../Mobiles/Monsters/SE/EliteNinja.cs | 2 +- .../Mobiles/Monsters/SE/FanDancer.cs | 2 +- .../Mobiles/Monsters/SE/FireBeetle.cs | 2 +- .../UOContent/Mobiles/Monsters/SE/Kappa.cs | 2 +- .../Mobiles/Monsters/SE/KazeKemono.cs | 2 +- .../Mobiles/Monsters/SE/LadyOfTheSnow.cs | 2 +- Projects/UOContent/Mobiles/Monsters/SE/Oni.cs | 2 +- .../UOContent/Mobiles/Monsters/SE/RaiJu.cs | 2 +- .../Mobiles/Monsters/SE/RevenantLion.cs | 2 +- .../UOContent/Mobiles/Monsters/SE/Ronin.cs | 2 +- .../Mobiles/Monsters/SE/RuneBeetle.cs | 2 +- .../Mobiles/Monsters/SE/TsukiWolf.cs | 2 +- .../UOContent/Mobiles/Monsters/SE/Yamandon.cs | 2 +- .../Mobiles/Monsters/SE/YomotsuElder.cs | 2 +- .../Mobiles/Monsters/SE/YomotsuPriest.cs | 2 +- .../Mobiles/Monsters/SE/YomotsuWarrior.cs | 2 +- .../Monsters/Summons/SummonedAirElemental.cs | 2 +- .../Monsters/Summons/SummonedDaemon.cs | 2 +- .../Summons/SummonedEarthElemental.cs | 2 +- .../Monsters/Summons/SummonedFireElemental.cs | 2 +- .../Summons/SummonedWaterElemental.cs | 2 +- .../Mobiles/Special/BaseShieldGuard.cs | 2 +- .../UOContent/Mobiles/Special/DarkGuardian.cs | 2 +- .../UOContent/Mobiles/Special/Harrower.cs | 2 +- .../Mobiles/Special/HarrowerTentacles.cs | 2 +- .../Mobiles/Special/ServantOfSemidar.cs | 2 +- Projects/UOContent/Mobiles/Townfolk/Actor.cs | 2 +- Projects/UOContent/Mobiles/Townfolk/Artist.cs | 2 +- Projects/UOContent/Mobiles/Townfolk/Gypsy.cs | 2 +- .../Mobiles/Townfolk/HarborMaster.cs | 2 +- Projects/UOContent/Mobiles/Townfolk/Ninja.cs | 2 +- .../UOContent/Mobiles/Townfolk/Samurai.cs | 2 +- .../UOContent/Mobiles/Townfolk/Sculptor.cs | 2 +- .../UOContent/Spells/Ninjitsu/MirrorImage.cs | 2 +- .../Spells/Spellweaving/Mobiles/ArcaneFey.cs | 2 +- .../Spellweaving/Mobiles/ArcaneFiend.cs | 2 +- .../Spells/Spellweaving/Mobiles/NatureFury.cs | 2 +- version.json | 2 +- 357 files changed, 767 insertions(+), 962 deletions(-) diff --git a/Projects/Server.Tests/Server.Tests.csproj b/Projects/Server.Tests/Server.Tests.csproj index b33bf4c7d..8c727c281 100644 --- a/Projects/Server.Tests/Server.Tests.csproj +++ b/Projects/Server.Tests/Server.Tests.csproj @@ -11,9 +11,6 @@ - - Data\Professions\LBR\prof.txt - diff --git a/Projects/Server/Configuration/ServerConfiguration.cs b/Projects/Server/Configuration/ServerConfiguration.cs index 77f76db2f..5cb173e62 100644 --- a/Projects/Server/Configuration/ServerConfiguration.cs +++ b/Projects/Server/Configuration/ServerConfiguration.cs @@ -67,6 +67,12 @@ public static class ServerConfiguration return Enum.TryParse(strValue, out T value) ? value : defaultValue; } + public static double GetSetting(string key, double defaultValue) + { + m_Settings.Settings.TryGetValue(key, out var strValue); + return double.TryParse(strValue, out var value) ? value : defaultValue; + } + public static T? GetSetting(string key) where T : struct, Enum { if (!m_Settings.Settings.TryGetValue(key, out var strValue)) @@ -168,6 +174,24 @@ public static class ServerConfiguration return value; } + public static double GetOrUpdateSetting(string key, double defaultValue) + { + double value; + + if (m_Settings.Settings.TryGetValue(key, out var strValue)) + { + value = double.TryParse(strValue, out value) ? value : defaultValue; + } + else + { + SetSetting(key, (value = defaultValue).ToString()); + } + + return value; + } + + public static void SetSetting(string key, double value) => SetSetting(key, value.ToString()); + public static void SetSetting(string key, TimeSpan value) => SetSetting(key, value.ToString()); public static void SetSetting(string key, int value) => SetSetting(key, value.ToString()); diff --git a/Projects/UOContent/Engines/Ethics/Evil/Mobiles/UnholyFamiliar.cs b/Projects/UOContent/Engines/Ethics/Evil/Mobiles/UnholyFamiliar.cs index 91d82e580..e0ee6d231 100644 --- a/Projects/UOContent/Engines/Ethics/Evil/Mobiles/UnholyFamiliar.cs +++ b/Projects/UOContent/Engines/Ethics/Evil/Mobiles/UnholyFamiliar.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles { [Constructible] public UnholyFamiliar() - : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + : base(AIType.AI_Melee) { Body = 99; BaseSoundID = 0xE5; diff --git a/Projects/UOContent/Engines/Ethics/Evil/Mobiles/UnholySteed.cs b/Projects/UOContent/Engines/Ethics/Evil/Mobiles/UnholySteed.cs index 5baa0466b..5546f571c 100644 --- a/Projects/UOContent/Engines/Ethics/Evil/Mobiles/UnholySteed.cs +++ b/Projects/UOContent/Engines/Ethics/Evil/Mobiles/UnholySteed.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles { [Constructible] public UnholySteed() - : base("a dark steed", 0x74, 0x3EA7, AIType.AI_Melee, FightMode.Aggressor, 10, 1, 0.2, 0.4) + : base("a dark steed", 0x74, 0x3EA7, AIType.AI_Melee, FightMode.Aggressor, 10, 1) { SetStr(496, 525); SetDex(86, 105); diff --git a/Projects/UOContent/Engines/Ethics/Hero/Mobiles/HolyFamiliar.cs b/Projects/UOContent/Engines/Ethics/Hero/Mobiles/HolyFamiliar.cs index b07570a89..7f67f8f06 100644 --- a/Projects/UOContent/Engines/Ethics/Hero/Mobiles/HolyFamiliar.cs +++ b/Projects/UOContent/Engines/Ethics/Hero/Mobiles/HolyFamiliar.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles { [Constructible] public HolyFamiliar() - : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + : base(AIType.AI_Melee) { Body = 100; BaseSoundID = 0xE5; diff --git a/Projects/UOContent/Engines/Ethics/Hero/Mobiles/HolySteed.cs b/Projects/UOContent/Engines/Ethics/Hero/Mobiles/HolySteed.cs index a3f088fd4..c6c41aa1e 100644 --- a/Projects/UOContent/Engines/Ethics/Hero/Mobiles/HolySteed.cs +++ b/Projects/UOContent/Engines/Ethics/Hero/Mobiles/HolySteed.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles { [Constructible] public HolySteed() - : base("a silver steed", 0x75, 0x3EA8, AIType.AI_Melee, FightMode.Aggressor, 10, 1, 0.2, 0.4) + : base("a silver steed", 0x75, 0x3EA8, AIType.AI_Melee, FightMode.Aggressor, 10, 1) { SetStr(496, 525); SetDex(86, 105); diff --git a/Projects/UOContent/Engines/Factions/Mobiles/FactionWarHorse.cs b/Projects/UOContent/Engines/Factions/Mobiles/FactionWarHorse.cs index a90e44678..e313de059 100644 --- a/Projects/UOContent/Engines/Factions/Mobiles/FactionWarHorse.cs +++ b/Projects/UOContent/Engines/Factions/Mobiles/FactionWarHorse.cs @@ -10,7 +10,7 @@ namespace Server.Factions [Constructible] public FactionWarHorse(Faction faction = null) - : base("a war horse", 0xE2, 0x3EA0, AIType.AI_Melee, FightMode.Aggressor, 10, 1, 0.2, 0.4) + : base("a war horse", 0xE2, 0x3EA0, AIType.AI_Melee, FightMode.Aggressor, 10, 1) { BaseSoundID = 0xA8; diff --git a/Projects/UOContent/Engines/Factions/Mobiles/Guards/BaseFactionGuard.cs b/Projects/UOContent/Engines/Factions/Mobiles/Guards/BaseFactionGuard.cs index aa7716781..5b59ecb6f 100644 --- a/Projects/UOContent/Engines/Factions/Mobiles/Guards/BaseFactionGuard.cs +++ b/Projects/UOContent/Engines/Factions/Mobiles/Guards/BaseFactionGuard.cs @@ -35,7 +35,7 @@ namespace Server.Factions private DateTime m_OrdersEnd; private Town m_Town; - public BaseFactionGuard(string title) : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public BaseFactionGuard(string title) : base(AIType.AI_Melee) { Orders = new Orders(this); Title = title; diff --git a/Projects/UOContent/Engines/Khaldun/Mobiles/GrimmochDrummel.cs b/Projects/UOContent/Engines/Khaldun/Mobiles/GrimmochDrummel.cs index 7adde3926..d18e54dc8 100644 --- a/Projects/UOContent/Engines/Khaldun/Mobiles/GrimmochDrummel.cs +++ b/Projects/UOContent/Engines/Khaldun/Mobiles/GrimmochDrummel.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class GrimmochDrummel : BaseCreature { [Constructible] - public GrimmochDrummel() : base(AIType.AI_Archer, FightMode.Closest, 10, 1, 0.2, 0.4) + public GrimmochDrummel() : base(AIType.AI_Archer) { Title = "the Cursed"; diff --git a/Projects/UOContent/Engines/Khaldun/Mobiles/LysanderGathenwale.cs b/Projects/UOContent/Engines/Khaldun/Mobiles/LysanderGathenwale.cs index c35736293..8d7f2cb3d 100644 --- a/Projects/UOContent/Engines/Khaldun/Mobiles/LysanderGathenwale.cs +++ b/Projects/UOContent/Engines/Khaldun/Mobiles/LysanderGathenwale.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class LysanderGathenwale : BaseCreature { [Constructible] - public LysanderGathenwale() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public LysanderGathenwale() : base(AIType.AI_Mage) { Title = "the Cursed"; diff --git a/Projects/UOContent/Engines/Khaldun/Mobiles/MorgBergen.cs b/Projects/UOContent/Engines/Khaldun/Mobiles/MorgBergen.cs index 6c6bf8f46..fa1a61a20 100644 --- a/Projects/UOContent/Engines/Khaldun/Mobiles/MorgBergen.cs +++ b/Projects/UOContent/Engines/Khaldun/Mobiles/MorgBergen.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class MorgBergen : BaseCreature { [Constructible] - public MorgBergen() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public MorgBergen() : base(AIType.AI_Melee) { Title = "the Cursed"; diff --git a/Projects/UOContent/Engines/Khaldun/Mobiles/TavaraSewel.cs b/Projects/UOContent/Engines/Khaldun/Mobiles/TavaraSewel.cs index c568c64f8..4e01e38b8 100644 --- a/Projects/UOContent/Engines/Khaldun/Mobiles/TavaraSewel.cs +++ b/Projects/UOContent/Engines/Khaldun/Mobiles/TavaraSewel.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class TavaraSewel : BaseCreature { [Constructible] - public TavaraSewel() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public TavaraSewel() : base(AIType.AI_Melee) { Title = "the Cursed"; diff --git a/Projects/UOContent/Engines/ML Quests/Definitions/BlightedGrove.cs b/Projects/UOContent/Engines/ML Quests/Definitions/BlightedGrove.cs index 31bf2a6de..26da2dce7 100644 --- a/Projects/UOContent/Engines/ML Quests/Definitions/BlightedGrove.cs +++ b/Projects/UOContent/Engines/ML Quests/Definitions/BlightedGrove.cs @@ -180,7 +180,7 @@ namespace Server.Engines.MLQuests.Definitions { [Constructible] public Jamal() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.2, 0.4) + : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the Fisherman"; Body = 400; @@ -224,7 +224,7 @@ namespace Server.Engines.MLQuests.Definitions { [Constructible] public Iosep() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.2, 0.4) + : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the Exporter"; Body = 400; diff --git a/Projects/UOContent/Engines/Plants/MiscMobiles/GiantIceWorm.cs b/Projects/UOContent/Engines/Plants/MiscMobiles/GiantIceWorm.cs index a882b772a..8ba3969f7 100644 --- a/Projects/UOContent/Engines/Plants/MiscMobiles/GiantIceWorm.cs +++ b/Projects/UOContent/Engines/Plants/MiscMobiles/GiantIceWorm.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class GiantIceWorm : BaseCreature { [Constructible] - public GiantIceWorm() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public GiantIceWorm() : base(AIType.AI_Melee) { Body = 89; BaseSoundID = 0xDC; diff --git a/Projects/UOContent/Engines/Quests/Dark Tides/Mobiles/SummonedPaladin.cs b/Projects/UOContent/Engines/Quests/Dark Tides/Mobiles/SummonedPaladin.cs index a4f020cb7..a01569975 100644 --- a/Projects/UOContent/Engines/Quests/Dark Tides/Mobiles/SummonedPaladin.cs +++ b/Projects/UOContent/Engines/Quests/Dark Tides/Mobiles/SummonedPaladin.cs @@ -9,7 +9,7 @@ namespace Server.Engines.Quests.Necro private PlayerMobile m_Necromancer; private bool m_ToDelete; - public SummonedPaladin(PlayerMobile necromancer) : base(AIType.AI_Melee, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public SummonedPaladin(PlayerMobile necromancer) : base(AIType.AI_Melee, FightMode.Aggressor) { m_Necromancer = necromancer; diff --git a/Projects/UOContent/Engines/Quests/Emino's Undertaking/Mobiles/Henchman.cs b/Projects/UOContent/Engines/Quests/Emino's Undertaking/Mobiles/Henchman.cs index 1d10745b6..d4e24e217 100644 --- a/Projects/UOContent/Engines/Quests/Emino's Undertaking/Mobiles/Henchman.cs +++ b/Projects/UOContent/Engines/Quests/Emino's Undertaking/Mobiles/Henchman.cs @@ -6,7 +6,7 @@ namespace Server.Engines.Quests.Ninja public class Henchman : BaseCreature { [Constructible] - public Henchman() : base(AIType.AI_Melee, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public Henchman() : base(AIType.AI_Melee, FightMode.Aggressor) { InitStats(45, 30, 5); diff --git a/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/CursedSoul.cs b/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/CursedSoul.cs index 5defbf092..151f85901 100644 --- a/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/CursedSoul.cs +++ b/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/CursedSoul.cs @@ -6,7 +6,7 @@ namespace Server.Engines.Quests.Samurai public class CursedSoul : BaseCreature { [Constructible] - public CursedSoul() : base(AIType.AI_Melee, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public CursedSoul() : base(AIType.AI_Melee, FightMode.Aggressor) { Body = 3; BaseSoundID = 471; diff --git a/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/DeadlyImp.cs b/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/DeadlyImp.cs index bc5cd2092..7d9085567 100644 --- a/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/DeadlyImp.cs +++ b/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/DeadlyImp.cs @@ -5,7 +5,7 @@ namespace Server.Engines.Quests.Samurai public class DeadlyImp : BaseCreature { [Constructible] - public DeadlyImp() : base(AIType.AI_Melee, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public DeadlyImp() : base(AIType.AI_Melee, FightMode.Aggressor) { Body = 74; BaseSoundID = 422; diff --git a/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/DiseasedCat.cs b/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/DiseasedCat.cs index 3b135a242..c73bbc558 100644 --- a/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/DiseasedCat.cs +++ b/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/DiseasedCat.cs @@ -5,7 +5,7 @@ namespace Server.Engines.Quests.Samurai public class DiseasedCat : BaseCreature { [Constructible] - public DiseasedCat() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public DiseasedCat() : base(AIType.AI_Animal, FightMode.Aggressor) { Body = 0xC9; Hue = Utility.RandomAnimalHue(); diff --git a/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/FierceDragon.cs b/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/FierceDragon.cs index 8e2016a15..914aec85e 100644 --- a/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/FierceDragon.cs +++ b/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/FierceDragon.cs @@ -5,7 +5,7 @@ namespace Server.Engines.Quests.Samurai public class FierceDragon : BaseCreature { [Constructible] - public FierceDragon() : base(AIType.AI_Melee, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public FierceDragon() : base(AIType.AI_Melee, FightMode.Aggressor) { Body = 103; BaseSoundID = 362; diff --git a/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/InjuredWolf.cs b/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/InjuredWolf.cs index 5bcf2fedf..fd7ab7078 100644 --- a/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/InjuredWolf.cs +++ b/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/InjuredWolf.cs @@ -5,7 +5,7 @@ namespace Server.Engines.Quests.Samurai public class InjuredWolf : BaseCreature { [Constructible] - public InjuredWolf() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public InjuredWolf() : base(AIType.AI_Animal, FightMode.Aggressor) { Body = 0xE1; BaseSoundID = 0xE5; diff --git a/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/YoungNinja.cs b/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/YoungNinja.cs index 130567bd9..f3b63e1b2 100644 --- a/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/YoungNinja.cs +++ b/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/YoungNinja.cs @@ -6,7 +6,7 @@ namespace Server.Engines.Quests.Samurai public class YoungNinja : BaseCreature { [Constructible] - public YoungNinja() : base(AIType.AI_Melee, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public YoungNinja() : base(AIType.AI_Melee, FightMode.Aggressor) { InitStats(45, 30, 5); SetHits(20, 30); diff --git a/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/YoungRonin.cs b/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/YoungRonin.cs index 98ddf1f45..c2f1aed70 100644 --- a/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/YoungRonin.cs +++ b/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/YoungRonin.cs @@ -6,7 +6,7 @@ namespace Server.Engines.Quests.Samurai public class YoungRonin : BaseCreature { [Constructible] - public YoungRonin() : base(AIType.AI_Melee, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public YoungRonin() : base(AIType.AI_Melee, FightMode.Aggressor) { InitStats(45, 30, 5); SetHits(10, 20); diff --git a/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Mobiles/MilitiaFighter.cs b/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Mobiles/MilitiaFighter.cs index ee0a3795c..34b3947a6 100644 --- a/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Mobiles/MilitiaFighter.cs +++ b/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Mobiles/MilitiaFighter.cs @@ -9,7 +9,7 @@ namespace Server.Engines.Quests.Haven public class MilitiaFighter : BaseCreature { [Constructible] - public MilitiaFighter() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public MilitiaFighter() : base(AIType.AI_Melee) { InitStats(40, 30, 5); Title = "the Militia Fighter"; diff --git a/Projects/UOContent/Holiday Stuff/Halloween/2006/Engines/TrickOrTreat.cs b/Projects/UOContent/Holiday Stuff/Halloween/2006/Engines/TrickOrTreat.cs index 3384eec0f..a1cc80e8b 100644 --- a/Projects/UOContent/Holiday Stuff/Halloween/2006/Engines/TrickOrTreat.cs +++ b/Projects/UOContent/Holiday Stuff/Halloween/2006/Engines/TrickOrTreat.cs @@ -276,7 +276,7 @@ namespace Server.Engines.Events private readonly Mobile m_From; public NaughtyTwin(Mobile from) - : base(AIType.AI_Melee, FightMode.None, 10, 1, 0.2, 0.4) + : base(AIType.AI_Melee, FightMode.None) { if (TrickOrTreat.CheckMobile(from)) { diff --git a/Projects/UOContent/Holiday Stuff/Halloween/2009/Foods/CreepyCake.cs b/Projects/UOContent/Holiday Stuff/Halloween/2009/Foods/CreepyCake.cs index e644f119f..605b1446c 100644 --- a/Projects/UOContent/Holiday Stuff/Halloween/2009/Foods/CreepyCake.cs +++ b/Projects/UOContent/Holiday Stuff/Halloween/2009/Foods/CreepyCake.cs @@ -8,7 +8,7 @@ public partial class CreepyCake : Food { [Constructible] - public CreepyCake() : base(0x9e9, 1) => Hue = 0x3E4; + public CreepyCake() : base(0x9e9) => Hue = 0x3E4; public override string DefaultName => "Creepy Cake"; } diff --git a/Projects/UOContent/Holiday Stuff/Halloween/2009/Foods/MrPlainsCookies.cs b/Projects/UOContent/Holiday Stuff/Halloween/2009/Foods/MrPlainsCookies.cs index 74f3cca82..7b70e3a31 100644 --- a/Projects/UOContent/Holiday Stuff/Halloween/2009/Foods/MrPlainsCookies.cs +++ b/Projects/UOContent/Holiday Stuff/Halloween/2009/Foods/MrPlainsCookies.cs @@ -4,7 +4,7 @@ public partial class MrPlainsCookies : Food { [Constructible] - public MrPlainsCookies() : base(0x160C, 1) + public MrPlainsCookies() : base(0x160C) { Weight = 1.0; FillFactor = 4; diff --git a/Projects/UOContent/Holiday Stuff/Halloween/2011/Mobiles/PumpkinHead.cs b/Projects/UOContent/Holiday Stuff/Halloween/2011/Mobiles/PumpkinHead.cs index a281b34f4..8f1a35d21 100644 --- a/Projects/UOContent/Holiday Stuff/Halloween/2011/Mobiles/PumpkinHead.cs +++ b/Projects/UOContent/Holiday Stuff/Halloween/2011/Mobiles/PumpkinHead.cs @@ -9,7 +9,7 @@ namespace Server.Mobiles { [Constructible] public PumpkinHead() - : base(Utility.RandomBool() ? AIType.AI_Melee : AIType.AI_Mage, FightMode.Closest, 10, 1, 0.05, 0.1) + : base(Utility.RandomBool() ? AIType.AI_Melee : AIType.AI_Mage) { Body = 1246 + Utility.Random(2); diff --git a/Projects/UOContent/Holiday Stuff/Halloween/2012/Engines/PlayerZombies.cs b/Projects/UOContent/Holiday Stuff/Halloween/2012/Engines/PlayerZombies.cs index 1bc77cf3b..cf1e2ad43 100644 --- a/Projects/UOContent/Holiday Stuff/Halloween/2012/Engines/PlayerZombies.cs +++ b/Projects/UOContent/Holiday Stuff/Halloween/2012/Engines/PlayerZombies.cs @@ -169,7 +169,7 @@ namespace Server.Engines.Events public override string DefaultName => _deadPlayer != null ? $"{_deadPlayer.Name}'s Zombie Skeleton" : "Zombie Skeleton"; public ZombieSkeleton(PlayerMobile player = null) - : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + : base(AIType.AI_Melee) { _deadPlayer = player; diff --git a/Projects/UOContent/Items/Food/Asian.cs b/Projects/UOContent/Items/Food/Asian.cs index 98b35e0c3..b7ea61a6b 100644 --- a/Projects/UOContent/Items/Food/Asian.cs +++ b/Projects/UOContent/Items/Food/Asian.cs @@ -27,7 +27,7 @@ namespace Server.Items public class WasabiClumps : Food { [Constructible] - public WasabiClumps() : base(0x24EB, 1) + public WasabiClumps() : base(0x24EB) { Stackable = false; Weight = 1.0; @@ -80,7 +80,7 @@ namespace Server.Items public class BentoBox : Food { [Constructible] - public BentoBox() : base(0x2836, 1) + public BentoBox() : base(0x2836) { Stackable = false; Weight = 5.0; @@ -120,7 +120,7 @@ namespace Server.Items public class SushiRolls : Food { [Constructible] - public SushiRolls() : base(0x283E, 1) + public SushiRolls() : base(0x283E) { Stackable = false; Weight = 3.0; @@ -149,7 +149,7 @@ namespace Server.Items public class SushiPlatter : Food { [Constructible] - public SushiPlatter() : base(0x2840, 1) + public SushiPlatter() : base(0x2840) { Stackable = Core.ML; Weight = 3.0; @@ -202,7 +202,7 @@ namespace Server.Items public class GreenTea : Food { [Constructible] - public GreenTea() : base(0x284C, 1) + public GreenTea() : base(0x284C) { Stackable = false; Weight = 4.0; @@ -231,7 +231,7 @@ namespace Server.Items public class MisoSoup : Food { [Constructible] - public MisoSoup() : base(0x284D, 1) + public MisoSoup() : base(0x284D) { Stackable = false; Weight = 4.0; @@ -260,7 +260,7 @@ namespace Server.Items public class WhiteMisoSoup : Food { [Constructible] - public WhiteMisoSoup() : base(0x284E, 1) + public WhiteMisoSoup() : base(0x284E) { Stackable = false; Weight = 4.0; @@ -289,7 +289,7 @@ namespace Server.Items public class RedMisoSoup : Food { [Constructible] - public RedMisoSoup() : base(0x284F, 1) + public RedMisoSoup() : base(0x284F) { Stackable = false; Weight = 4.0; @@ -318,7 +318,7 @@ namespace Server.Items public class AwaseMisoSoup : Food { [Constructible] - public AwaseMisoSoup() : base(0x2850, 1) + public AwaseMisoSoup() : base(0x2850) { Stackable = false; Weight = 4.0; diff --git a/Projects/UOContent/Items/Food/Bowls.cs b/Projects/UOContent/Items/Food/Bowls.cs index d4b485d51..b5b98522a 100644 --- a/Projects/UOContent/Items/Food/Bowls.cs +++ b/Projects/UOContent/Items/Food/Bowls.cs @@ -51,7 +51,7 @@ namespace Server.Items public class WoodenBowlOfCarrots : Food { [Constructible] - public WoodenBowlOfCarrots() : base(0x15F9, 1) + public WoodenBowlOfCarrots() : base(0x15F9) { Stackable = false; Weight = 1.0; @@ -91,7 +91,7 @@ namespace Server.Items public class WoodenBowlOfCorn : Food { [Constructible] - public WoodenBowlOfCorn() : base(0x15FA, 1) + public WoodenBowlOfCorn() : base(0x15FA) { Stackable = false; Weight = 1.0; @@ -131,7 +131,7 @@ namespace Server.Items public class WoodenBowlOfLettuce : Food { [Constructible] - public WoodenBowlOfLettuce() : base(0x15FB, 1) + public WoodenBowlOfLettuce() : base(0x15FB) { Stackable = false; Weight = 1.0; @@ -171,7 +171,7 @@ namespace Server.Items public class WoodenBowlOfPeas : Food { [Constructible] - public WoodenBowlOfPeas() : base(0x15FC, 1) + public WoodenBowlOfPeas() : base(0x15FC) { Stackable = false; Weight = 1.0; @@ -211,7 +211,7 @@ namespace Server.Items public class PewterBowlOfCarrots : Food { [Constructible] - public PewterBowlOfCarrots() : base(0x15FE, 1) + public PewterBowlOfCarrots() : base(0x15FE) { Stackable = false; Weight = 1.0; @@ -251,7 +251,7 @@ namespace Server.Items public class PewterBowlOfCorn : Food { [Constructible] - public PewterBowlOfCorn() : base(0x15FF, 1) + public PewterBowlOfCorn() : base(0x15FF) { Stackable = false; Weight = 1.0; @@ -291,7 +291,7 @@ namespace Server.Items public class PewterBowlOfLettuce : Food { [Constructible] - public PewterBowlOfLettuce() : base(0x1600, 1) + public PewterBowlOfLettuce() : base(0x1600) { Stackable = false; Weight = 1.0; @@ -331,7 +331,7 @@ namespace Server.Items public class PewterBowlOfPeas : Food { [Constructible] - public PewterBowlOfPeas() : base(0x1601, 1) + public PewterBowlOfPeas() : base(0x1601) { Stackable = false; Weight = 1.0; @@ -371,7 +371,7 @@ namespace Server.Items public class PewterBowlOfPotatos : Food { [Constructible] - public PewterBowlOfPotatos() : base(0x1602, 1) + public PewterBowlOfPotatos() : base(0x1602) { Stackable = false; Weight = 1.0; @@ -461,7 +461,7 @@ namespace Server.Items public class WoodenBowlOfStew : Food { [Constructible] - public WoodenBowlOfStew() : base(0x1604, 1) + public WoodenBowlOfStew() : base(0x1604) { Stackable = false; Weight = 2.0; @@ -501,7 +501,7 @@ namespace Server.Items public class WoodenBowlOfTomatoSoup : Food { [Constructible] - public WoodenBowlOfTomatoSoup() : base(0x1606, 1) + public WoodenBowlOfTomatoSoup() : base(0x1606) { Stackable = false; Weight = 2.0; diff --git a/Projects/UOContent/Items/Food/Food.cs b/Projects/UOContent/Items/Food/Food.cs index cc86ebe68..8110b24d4 100644 --- a/Projects/UOContent/Items/Food/Food.cs +++ b/Projects/UOContent/Items/Food/Food.cs @@ -534,7 +534,7 @@ namespace Server.Items public class Cake : Food { [Constructible] - public Cake() : base(0x9E9, 1) + public Cake() : base(0x9E9) { Stackable = false; Weight = 1.0; @@ -591,7 +591,7 @@ namespace Server.Items public class Cookies : Food { [Constructible] - public Cookies() : base(0x160b, 1) + public Cookies() : base(0x160b) { Stackable = Core.ML; Weight = 1.0; @@ -620,7 +620,7 @@ namespace Server.Items public class Muffins : Food { [Constructible] - public Muffins() : base(0x9eb, 1) + public Muffins() : base(0x9eb) { Stackable = false; Weight = 1.0; @@ -650,7 +650,7 @@ namespace Server.Items public class CheesePizza : Food { [Constructible] - public CheesePizza() : base(0x1040, 1) + public CheesePizza() : base(0x1040) { Stackable = false; Weight = 1.0; @@ -681,7 +681,7 @@ namespace Server.Items public class SausagePizza : Food { [Constructible] - public SausagePizza() : base(0x1040, 1) + public SausagePizza() : base(0x1040) { Stackable = false; Weight = 1.0; @@ -712,7 +712,7 @@ namespace Server.Items public class FruitPie : Food { [Constructible] - public FruitPie() : base(0x1041, 1) + public FruitPie() : base(0x1041) { Stackable = false; Weight = 1.0; @@ -743,7 +743,7 @@ namespace Server.Items public class MeatPie : Food { [Constructible] - public MeatPie() : base(0x1041, 1) + public MeatPie() : base(0x1041) { Stackable = false; Weight = 1.0; @@ -774,7 +774,7 @@ namespace Server.Items public class PumpkinPie : Food { [Constructible] - public PumpkinPie() : base(0x1041, 1) + public PumpkinPie() : base(0x1041) { Stackable = false; Weight = 1.0; @@ -805,7 +805,7 @@ namespace Server.Items public class ApplePie : Food { [Constructible] - public ApplePie() : base(0x1041, 1) + public ApplePie() : base(0x1041) { Stackable = false; Weight = 1.0; @@ -836,7 +836,7 @@ namespace Server.Items public class PeachCobbler : Food { [Constructible] - public PeachCobbler() : base(0x1041, 1) + public PeachCobbler() : base(0x1041) { Stackable = false; Weight = 1.0; @@ -867,7 +867,7 @@ namespace Server.Items public class Quiche : Food { [Constructible] - public Quiche() : base(0x1041, 1) + public Quiche() : base(0x1041) { Stackable = Core.ML; Weight = 1.0; diff --git a/Projects/UOContent/Items/Food/Fruits.cs b/Projects/UOContent/Items/Food/Fruits.cs index 7f6c377fb..90ec2b3bf 100644 --- a/Projects/UOContent/Items/Food/Fruits.cs +++ b/Projects/UOContent/Items/Food/Fruits.cs @@ -3,7 +3,7 @@ namespace Server.Items public class FruitBasket : Food { [Constructible] - public FruitBasket() : base(0x993, 1) + public FruitBasket() : base(0x993) { Weight = 2.0; FillFactor = 5; diff --git a/Projects/UOContent/Items/Special/Holiday/HolidayFoods.cs b/Projects/UOContent/Items/Special/Holiday/HolidayFoods.cs index 47d7fa94e..43ad98350 100644 --- a/Projects/UOContent/Items/Special/Holiday/HolidayFoods.cs +++ b/Projects/UOContent/Items/Special/Holiday/HolidayFoods.cs @@ -13,7 +13,7 @@ namespace Server.Items { } - public CandyCane(int itemID) : base(itemID, 1) + public CandyCane(int itemID) : base(itemID) { Stackable = false; LootType = LootType.Blessed; @@ -126,7 +126,7 @@ namespace Server.Items [Constructible] public GingerBreadCookie() - : base(Utility.RandomBool() ? 0x2be1 : 0x2be2, 1) + : base(Utility.RandomBool() ? 0x2be1 : 0x2be2) { Stackable = false; LootType = LootType.Blessed; diff --git a/Projects/UOContent/Items/Special/Holiday/PKHolidayStuff.cs b/Projects/UOContent/Items/Special/Holiday/PKHolidayStuff.cs index c772739cb..be141020c 100644 --- a/Projects/UOContent/Items/Special/Holiday/PKHolidayStuff.cs +++ b/Projects/UOContent/Items/Special/Holiday/PKHolidayStuff.cs @@ -65,7 +65,7 @@ namespace Server.Items public class Spam : Food { [Constructible] - public Spam() : base(0x1044, 1) + public Spam() : base(0x1044) { Stackable = false; LootType = LootType.Blessed; diff --git a/Projects/UOContent/Items/Talismans/TalismanSummons.cs b/Projects/UOContent/Items/Talismans/TalismanSummons.cs index e74dd8f4f..262334eb7 100644 --- a/Projects/UOContent/Items/Talismans/TalismanSummons.cs +++ b/Projects/UOContent/Items/Talismans/TalismanSummons.cs @@ -9,7 +9,7 @@ namespace Server.Mobiles { // public override bool IsInvulnerable => true; // TODO: Wailing banshees are NOT invulnerable, are any of the others? - public BaseTalismanSummon() : base(AIType.AI_Melee, FightMode.None, 10, 1, 0.2, 0.4) + public BaseTalismanSummon() : base(AIType.AI_Melee, FightMode.None) { // TODO: Stats/skills } diff --git a/Projects/UOContent/Items/Weapons/Abilities/ForceOfNature.cs b/Projects/UOContent/Items/Weapons/Abilities/ForceOfNature.cs index 17d4ffc8a..c3171dbd8 100644 --- a/Projects/UOContent/Items/Weapons/Abilities/ForceOfNature.cs +++ b/Projects/UOContent/Items/Weapons/Abilities/ForceOfNature.cs @@ -103,7 +103,7 @@ namespace Server.Items { int damage = Utility.RandomMinMax(15, 35); - AOS.Damage(From, From, damage, false, 0, 0, 0, 0, 0, 0, 100, false, false, false); + AOS.Damage(From, From, damage, false, 0, 0, 0, 0, 0, 0, 100); } } } diff --git a/Projects/UOContent/Mobiles/AI/BaseAI.cs b/Projects/UOContent/Mobiles/AI/BaseAI.cs index af010e7c4..e7d8c2994 100644 --- a/Projects/UOContent/Mobiles/AI/BaseAI.cs +++ b/Projects/UOContent/Mobiles/AI/BaseAI.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.IO; using Server.ContextMenus; using Server.Engines.Quests; using Server.Engines.Quests.Necro; @@ -810,31 +809,45 @@ namespace Server.Mobiles switch (Action) { case ActionType.Wander: - m_Mobile.OnActionWander(); - return DoActionWander(); + { + m_Mobile.OnActionWander(); + return DoActionWander(); + } case ActionType.Combat: - m_Mobile.OnActionCombat(); - return DoActionCombat(); + { + m_Mobile.OnActionCombat(); + return DoActionCombat(); + } case ActionType.Guard: - m_Mobile.OnActionGuard(); - return DoActionGuard(); + { + m_Mobile.OnActionGuard(); + return DoActionGuard(); + } case ActionType.Flee: - m_Mobile.OnActionFlee(); - return DoActionFlee(); + { + m_Mobile.OnActionFlee(); + return DoActionFlee(); + } case ActionType.Interact: - m_Mobile.OnActionInteract(); - return DoActionInteract(); + { + m_Mobile.OnActionInteract(); + return DoActionInteract(); + } case ActionType.Backoff: - m_Mobile.OnActionBackoff(); - return DoActionBackoff(); + { + m_Mobile.OnActionBackoff(); + return DoActionBackoff(); + } default: - return false; + { + return false; + } } } @@ -843,42 +856,54 @@ namespace Server.Mobiles switch (Action) { case ActionType.Wander: - m_Mobile.Warmode = false; - m_Mobile.Combatant = null; - m_Mobile.FocusMob = null; - m_Mobile.CurrentSpeed = m_Mobile.PassiveSpeed; - break; + { + m_Mobile.Warmode = false; + m_Mobile.Combatant = null; + m_Mobile.FocusMob = null; + m_Mobile.CurrentSpeed = m_Mobile.PassiveSpeed; + break; + } case ActionType.Combat: - m_Mobile.Warmode = true; - m_Mobile.FocusMob = null; - m_Mobile.CurrentSpeed = m_Mobile.ActiveSpeed; - break; + { + m_Mobile.Warmode = true; + m_Mobile.FocusMob = null; + m_Mobile.CurrentSpeed = m_Mobile.ActiveSpeed; + break; + } case ActionType.Guard: - m_Mobile.Warmode = true; - m_Mobile.FocusMob = null; - m_Mobile.Combatant = null; - m_Mobile.CurrentSpeed = m_Mobile.ActiveSpeed; - m_NextStopGuard = Core.TickCount + (int)TimeSpan.FromSeconds(10).TotalMilliseconds; - m_Mobile.CurrentSpeed = m_Mobile.ActiveSpeed; - break; + { + m_Mobile.Warmode = true; + m_Mobile.FocusMob = null; + m_Mobile.Combatant = null; + m_Mobile.CurrentSpeed = m_Mobile.ActiveSpeed; + m_NextStopGuard = Core.TickCount + (int)TimeSpan.FromSeconds(10).TotalMilliseconds; + m_Mobile.CurrentSpeed = m_Mobile.ActiveSpeed; + break; + } case ActionType.Flee: - m_Mobile.Warmode = true; - m_Mobile.FocusMob = null; - m_Mobile.CurrentSpeed = m_Mobile.ActiveSpeed; - break; + { + m_Mobile.Warmode = true; + m_Mobile.FocusMob = null; + m_Mobile.CurrentSpeed = m_Mobile.ActiveSpeed; + break; + } case ActionType.Interact: - m_Mobile.Warmode = false; - m_Mobile.CurrentSpeed = m_Mobile.PassiveSpeed; - break; + { + m_Mobile.Warmode = false; + m_Mobile.CurrentSpeed = m_Mobile.PassiveSpeed; + break; + } case ActionType.Backoff: - m_Mobile.Warmode = false; - m_Mobile.CurrentSpeed = m_Mobile.PassiveSpeed; - break; + { + m_Mobile.Warmode = false; + m_Mobile.CurrentSpeed = m_Mobile.PassiveSpeed; + break; + } } } @@ -1012,12 +1037,7 @@ namespace Server.Mobiles public virtual bool Obey() { - if (m_Mobile.Deleted) - { - return false; - } - - return m_Mobile.ControlOrder switch + var shouldObey = !m_Mobile.Deleted && m_Mobile.ControlOrder switch { OrderType.None => DoOrderNone(), OrderType.Come => DoOrderCome(), @@ -1034,6 +1054,15 @@ namespace Server.Mobiles OrderType.Transfer => DoOrderTransfer(), _ => false }; + + if (shouldObey) + { + // TODO: This might cause the movement timer to reset too often if someone is spamming commands. + // Test this thoroughly. + m_Mobile.ResetSpeeds(); + } + + return shouldObey; } public virtual void OnCurrentOrderChanged() @@ -1046,104 +1075,128 @@ namespace Server.Mobiles switch (m_Mobile.ControlOrder) { case OrderType.None: - m_Mobile.ControlMaster.RevealingAction(); - m_Mobile.Home = m_Mobile.Location; - m_Mobile.CurrentSpeed = m_Mobile.PassiveSpeed; - m_Mobile.PlaySound(m_Mobile.GetIdleSound()); - m_Mobile.Warmode = false; - m_Mobile.Combatant = null; - break; + { + m_Mobile.ControlMaster.RevealingAction(); + m_Mobile.Home = m_Mobile.Location; + m_Mobile.CurrentSpeed = m_Mobile.PassiveSpeed; + m_Mobile.PlaySound(m_Mobile.GetIdleSound()); + m_Mobile.Warmode = false; + m_Mobile.Combatant = null; + break; + } case OrderType.Come: - m_Mobile.ControlMaster.RevealingAction(); - m_Mobile.CurrentSpeed = m_Mobile.ActiveSpeed; - m_Mobile.PlaySound(m_Mobile.GetIdleSound()); - m_Mobile.Warmode = false; - m_Mobile.Combatant = null; - break; + { + m_Mobile.ControlMaster.RevealingAction(); + m_Mobile.CurrentSpeed = m_Mobile.ActiveSpeed; + m_Mobile.PlaySound(m_Mobile.GetIdleSound()); + m_Mobile.Warmode = false; + m_Mobile.Combatant = null; + break; + } case OrderType.Drop: - m_Mobile.ControlMaster.RevealingAction(); - m_Mobile.CurrentSpeed = m_Mobile.PassiveSpeed; - m_Mobile.PlaySound(m_Mobile.GetIdleSound()); - m_Mobile.Warmode = true; - m_Mobile.Combatant = null; - break; + { + m_Mobile.ControlMaster.RevealingAction(); + m_Mobile.CurrentSpeed = m_Mobile.PassiveSpeed; + m_Mobile.PlaySound(m_Mobile.GetIdleSound()); + m_Mobile.Warmode = true; + m_Mobile.Combatant = null; + break; + } case OrderType.Friend: case OrderType.Unfriend: - m_Mobile.ControlMaster.RevealingAction(); - break; + { + m_Mobile.ControlMaster.RevealingAction(); + break; + } case OrderType.Guard: - m_Mobile.ControlMaster.RevealingAction(); - m_Mobile.CurrentSpeed = m_Mobile.ActiveSpeed; - m_Mobile.PlaySound(m_Mobile.GetIdleSound()); - m_Mobile.Warmode = true; - m_Mobile.Combatant = null; - var petname = $"{m_Mobile.Name}"; - m_Mobile.ControlMaster.SendLocalizedMessage(1049671, petname); // ~1_PETNAME~ is now guarding you. - break; + { + m_Mobile.ControlMaster.RevealingAction(); + m_Mobile.CurrentSpeed = m_Mobile.ActiveSpeed; + m_Mobile.PlaySound(m_Mobile.GetIdleSound()); + m_Mobile.Warmode = true; + m_Mobile.Combatant = null; + var petname = $"{m_Mobile.Name}"; + m_Mobile.ControlMaster.SendLocalizedMessage(1049671, petname); // ~1_PETNAME~ is now guarding you. + break; + } case OrderType.Attack: - m_Mobile.ControlMaster.RevealingAction(); - m_Mobile.CurrentSpeed = m_Mobile.ActiveSpeed; - m_Mobile.PlaySound(m_Mobile.GetIdleSound()); + { + m_Mobile.ControlMaster.RevealingAction(); + m_Mobile.CurrentSpeed = m_Mobile.ActiveSpeed; + m_Mobile.PlaySound(m_Mobile.GetIdleSound()); - m_Mobile.Warmode = true; - m_Mobile.Combatant = null; - break; + m_Mobile.Warmode = true; + m_Mobile.Combatant = null; + break; + } case OrderType.Patrol: - m_Mobile.ControlMaster.RevealingAction(); - m_Mobile.CurrentSpeed = m_Mobile.ActiveSpeed; - m_Mobile.PlaySound(m_Mobile.GetIdleSound()); - m_Mobile.Warmode = false; - m_Mobile.Combatant = null; - break; + { + m_Mobile.ControlMaster.RevealingAction(); + m_Mobile.CurrentSpeed = m_Mobile.ActiveSpeed; + m_Mobile.PlaySound(m_Mobile.GetIdleSound()); + m_Mobile.Warmode = false; + m_Mobile.Combatant = null; + break; + } case OrderType.Release: - m_Mobile.ControlMaster.RevealingAction(); - m_Mobile.CurrentSpeed = m_Mobile.PassiveSpeed; - m_Mobile.PlaySound(m_Mobile.GetIdleSound()); - m_Mobile.Warmode = false; - m_Mobile.Combatant = null; - break; + { + m_Mobile.ControlMaster.RevealingAction(); + m_Mobile.CurrentSpeed = m_Mobile.PassiveSpeed; + m_Mobile.PlaySound(m_Mobile.GetIdleSound()); + m_Mobile.Warmode = false; + m_Mobile.Combatant = null; + break; + } case OrderType.Stay: - m_Mobile.ControlMaster.RevealingAction(); - m_Mobile.CurrentSpeed = m_Mobile.PassiveSpeed; - m_Mobile.PlaySound(m_Mobile.GetIdleSound()); - m_Mobile.Warmode = false; - m_Mobile.Combatant = null; - break; + { + m_Mobile.ControlMaster.RevealingAction(); + m_Mobile.CurrentSpeed = m_Mobile.PassiveSpeed; + m_Mobile.PlaySound(m_Mobile.GetIdleSound()); + m_Mobile.Warmode = false; + m_Mobile.Combatant = null; + break; + } case OrderType.Stop: - m_Mobile.ControlMaster.RevealingAction(); - m_Mobile.Home = m_Mobile.Location; - m_Mobile.CurrentSpeed = m_Mobile.PassiveSpeed; - m_Mobile.PlaySound(m_Mobile.GetIdleSound()); - m_Mobile.Warmode = false; - m_Mobile.Combatant = null; - break; + { + m_Mobile.ControlMaster.RevealingAction(); + m_Mobile.Home = m_Mobile.Location; + m_Mobile.CurrentSpeed = m_Mobile.PassiveSpeed; + m_Mobile.PlaySound(m_Mobile.GetIdleSound()); + m_Mobile.Warmode = false; + m_Mobile.Combatant = null; + break; + } case OrderType.Follow: - m_Mobile.ControlMaster.RevealingAction(); - m_Mobile.CurrentSpeed = m_Mobile.ActiveSpeed; - m_Mobile.PlaySound(m_Mobile.GetIdleSound()); + { + m_Mobile.ControlMaster.RevealingAction(); + m_Mobile.CurrentSpeed = m_Mobile.ActiveSpeed; + m_Mobile.PlaySound(m_Mobile.GetIdleSound()); - m_Mobile.Warmode = false; - m_Mobile.Combatant = null; - break; + m_Mobile.Warmode = false; + m_Mobile.Combatant = null; + break; + } case OrderType.Transfer: - m_Mobile.ControlMaster.RevealingAction(); - m_Mobile.CurrentSpeed = m_Mobile.PassiveSpeed; - m_Mobile.PlaySound(m_Mobile.GetIdleSound()); + { + m_Mobile.ControlMaster.RevealingAction(); + m_Mobile.CurrentSpeed = m_Mobile.PassiveSpeed; + m_Mobile.PlaySound(m_Mobile.GetIdleSound()); - m_Mobile.Warmode = false; - m_Mobile.Combatant = null; - break; + m_Mobile.Warmode = false; + m_Mobile.Combatant = null; + break; + } } } @@ -1824,32 +1877,50 @@ namespace Server.Mobiles switch (iRndMove) { case 0: - DoMove(Direction.Up); - break; + { + DoMove(Direction.Up); + break; + } case 1: - DoMove(Direction.North); - break; + { + DoMove(Direction.North); + break; + } case 2: - DoMove(Direction.Left); - break; + { + DoMove(Direction.Left); + break; + } case 3: - DoMove(Direction.West); - break; + { + DoMove(Direction.West); + break; + } case 5: - DoMove(Direction.Down); - break; + { + DoMove(Direction.Down); + break; + } case 6: - DoMove(Direction.South); - break; + { + DoMove(Direction.South); + break; + } case 7: - DoMove(Direction.Right); - break; + { + DoMove(Direction.Right); + break; + } case 8: - DoMove(Direction.East); - break; + { + DoMove(Direction.East); + break; + } default: - DoMove(m_Mobile.Direction); - break; + { + DoMove(m_Mobile.Direction); + break; + } } } } @@ -1857,100 +1928,24 @@ namespace Server.Mobiles public double TransformMoveDelay(double delay) { - var isPassive = delay == m_Mobile.PassiveSpeed; - var isControlled = m_Mobile.Controlled || m_Mobile.Summoned; + double max = m_Mobile.IsMonster ? SpeedInfo.MaxMonsterDelay : SpeedInfo.MaxDelay; - if (delay == 0.2) + if (!m_Mobile.IsDeadPet && (m_Mobile.ReduceSpeedWithDamage || m_Mobile.IsSubdued)) { - delay = 0.3; - } - else if (delay == 0.25) - { - delay = 0.45; - } - else if (delay == 0.3) - { - delay = 0.6; - } - else if (delay == 0.4) - { - delay = 0.9; - } - else if (delay == 0.5) - { - delay = 1.05; - } - else if (delay == 0.6) - { - delay = 1.2; - } - else if (delay == 0.8) - { - delay = 1.5; - } + double offset = m_Mobile.StamMax <= 0 ? 1.0 : m_Mobile.Stam / (double)m_Mobile.StamMax; - if (isPassive) - { - delay += 0.2; - } - - if (!isControlled) - { - delay += 0.1; - } - else if (m_Mobile.Controlled) - { - if (m_Mobile.ControlOrder == OrderType.Follow && m_Mobile.ControlTarget == m_Mobile.ControlMaster) + if (offset < 1.0) { - delay *= 0.5; + delay += (max - delay) * (1.0 - offset); } - - delay -= 0.075; } - if (m_Mobile.ReduceSpeedWithDamage || m_Mobile.IsSubdued) - { - var offset = (double)m_Mobile.Hits / m_Mobile.HitsMax; - - if (offset < 0.0) - { - offset = 0.0; - } - else if (offset > 1.0) - { - offset = 1.0; - } - - offset = 1.0 - offset; - - delay += offset * 0.8; - } - - if (delay < 0.0) - { - delay = 0.0; - } - - if (double.IsNaN(delay)) - { - using (var op = new StreamWriter("nan_transform.txt", true)) - { - op.WriteLine( - $"NaN in TransformMoveDelay: {Core.Now}, {GetType()}, {m_Mobile?.GetType()}, {m_Mobile.HitsMax}" - ); - } - - return 1.0; - } - - return delay; + return Math.Min(delay, max); } public virtual bool CheckMove() => Core.TickCount - NextMove >= 0; - public virtual bool DoMove(Direction d) => DoMove(d, false); - - public virtual bool DoMove(Direction d, bool badStateOk) + public virtual bool DoMove(Direction d, bool badStateOk = false) { var res = DoMoveImpl(d); @@ -2712,7 +2707,7 @@ namespace Server.Mobiles public virtual void OnCurrentSpeedChanged() { m_Timer.Stop(); - m_Timer.Delay = TimeSpan.FromSeconds(Utility.RandomDouble()); + m_Timer.Delay = TimeSpan.FromMilliseconds(Utility.Random(128) * 8); m_Timer.Interval = TimeSpan.FromSeconds(Math.Max(0.0, m_Mobile.CurrentSpeed)); m_Timer.Start(); } @@ -2740,70 +2735,72 @@ namespace Server.Mobiles public override void OnClick() { - if (!m_Mobile.Deleted && m_Mobile.Controlled && m_From.CheckAlive()) + if (m_Mobile.Deleted || !m_Mobile.Controlled || !m_From.CheckAlive()) { - if (m_Mobile.IsDeadPet && m_Order is OrderType.Guard or OrderType.Attack or OrderType.Transfer or OrderType.Drop) - { - return; - } + return; + } - var isOwner = m_From == m_Mobile.ControlMaster; - var isFriend = !isOwner && m_Mobile.IsPetFriend(m_From); + if (m_Mobile.IsDeadPet && m_Order is OrderType.Guard or OrderType.Attack or OrderType.Transfer or OrderType.Drop) + { + return; + } - if (!isOwner && !isFriend) - { - return; - } + var isOwner = m_From == m_Mobile.ControlMaster; + var isFriend = !isOwner && m_Mobile.IsPetFriend(m_From); - if (isFriend && m_Order != OrderType.Follow && m_Order != OrderType.Stay && m_Order != OrderType.Stop) - { - return; - } + if (!isOwner && !isFriend) + { + return; + } - switch (m_Order) - { - case OrderType.Follow: - case OrderType.Attack: - case OrderType.Transfer: - case OrderType.Friend: - case OrderType.Unfriend: + if (isFriend && m_Order != OrderType.Follow && m_Order != OrderType.Stay && m_Order != OrderType.Stop) + { + return; + } + + switch (m_Order) + { + case OrderType.Follow: + case OrderType.Attack: + case OrderType.Transfer: + case OrderType.Friend: + case OrderType.Unfriend: + { + if (m_Order == OrderType.Transfer && m_From.HasTrade) { - if (m_Order == OrderType.Transfer && m_From.HasTrade) - { - m_From.SendLocalizedMessage(1010507); // You cannot transfer a pet with a trade pending - } - else if (m_Order == OrderType.Friend && m_From.HasTrade) - { - m_From.SendLocalizedMessage(1070947); // You cannot friend a pet with a trade pending - } - else - { - m_AI.BeginPickTarget(m_From, m_Order); - } - - break; + m_From.SendLocalizedMessage(1010507); // You cannot transfer a pet with a trade pending } - case OrderType.Release: + else if (m_Order == OrderType.Friend && m_From.HasTrade) { - if (m_Mobile.Summoned) - { - goto default; - } - - m_From.SendGump(new ConfirmReleaseGump(m_From, m_Mobile)); - - break; + m_From.SendLocalizedMessage(1070947); // You cannot friend a pet with a trade pending } - default: + else { - if (m_Mobile.CheckControlChance(m_From)) - { - m_Mobile.ControlOrder = m_Order; - } - - break; + m_AI.BeginPickTarget(m_From, m_Order); } - } + + break; + } + case OrderType.Release: + { + if (m_Mobile.Summoned) + { + goto default; + } + + m_From.SendGump(new ConfirmReleaseGump(m_From, m_Mobile)); + + break; + } + default: + { + if (m_Mobile.CheckControlChance(m_From)) + { + m_Mobile.ControlOrder = m_Order; + } + + break; + } } } } @@ -2904,14 +2901,10 @@ namespace Server.Mobiles { var args = $"{to.Name}\t{from.Name}\t "; - from.SendLocalizedMessage( - 1043248, - args - ); // The pet refuses to be transferred because it will not obey ~1_NAME~.~3_BLANK~ - to.SendLocalizedMessage( - 1043249, - args - ); // The pet will not accept you as a master because it does not trust you.~3_BLANK~ + // The pet refuses to be transferred because it will not obey ~1_NAME~.~3_BLANK~ + from.SendLocalizedMessage(1043248, args); + // The pet will not accept you as a master because it does not trust you.~3_BLANK~ + to.SendLocalizedMessage(1043249, args); return false; } @@ -2919,14 +2912,10 @@ namespace Server.Mobiles { var args = $"{to.Name}\t{from.Name}\t "; - from.SendLocalizedMessage( - 1043250, - args - ); // The pet refuses to be transferred because it will not obey you sufficiently.~3_BLANK~ - to.SendLocalizedMessage( - 1043251, - args - ); // The pet will not accept you as a master because it does not trust ~2_NAME~.~3_BLANK~ + // The pet refuses to be transferred because it will not obey you sufficiently.~3_BLANK~ + from.SendLocalizedMessage(1043250, args); + // The pet will not accept you as a master because it does not trust ~2_NAME~.~3_BLANK~ + to.SendLocalizedMessage(1043251, args); } else if (accepted && to.Followers + m_Creature.ControlSlots > to.FollowersMax) { @@ -2986,10 +2975,8 @@ namespace Server.Mobiles var args = $"{from.Name}\t{m_Creature.Name}\t{to.Name}"; from.SendLocalizedMessage(1043253, args); // You have transferred your pet to ~3_GETTER~. - to.SendLocalizedMessage( - 1043252, - args - ); // ~1_NAME~ has transferred the allegiance of ~2_PET_NAME~ to you. + // ~1_NAME~ has transferred the allegiance of ~2_PET_NAME~ to you. + to.SendLocalizedMessage(1043252, args); } } } @@ -3004,7 +2991,7 @@ namespace Server.Mobiles public AITimer(BaseAI owner) : base( - TimeSpan.FromSeconds(Utility.RandomDouble()), + TimeSpan.FromSeconds(Utility.Random(128) * 8), TimeSpan.FromSeconds(Math.Max(0.0, owner.m_Mobile.CurrentSpeed)) ) { diff --git a/Projects/UOContent/Mobiles/AI/SpeedInfo.cs b/Projects/UOContent/Mobiles/AI/SpeedInfo.cs index a6403922f..0fbd3a62c 100644 --- a/Projects/UOContent/Mobiles/AI/SpeedInfo.cs +++ b/Projects/UOContent/Mobiles/AI/SpeedInfo.cs @@ -1,228 +1,50 @@ using System; -using System.Collections.Generic; -using Server.Factions; using Server.Mobiles; -namespace Server +namespace Server; + +public static class SpeedInfo { - public class SpeedInfo + public static double MinDelay { get; private set; } + public static double MaxDelay { get; private set; } + public static double MinMonsterDelay { get; private set; } + public static double MaxMonsterDelay { get; private set; } + + // Determines the maximum dex for delay by dex + public static int MaxDex { get; private set; } + public static int MaxMonsterDex { get; private set; } + + public static void Configure() { - // Should we use the new method of speeds? - private static readonly bool Enabled = true; + // Default speed determined by dex (0 -> 190) for non-monster NPCs including pets + MinDelay = ServerConfiguration.GetOrUpdateSetting("movement.delay.npcMinDelay", 0.1); + MaxDelay = ServerConfiguration.GetOrUpdateSetting("movement.delay.npcMaxDelay", 0.5); + MaxDex = ServerConfiguration.GetOrUpdateSetting("movement.delay.maxDex", 190); - private static Dictionary m_Table; + // Default speed determined by dex (0 -> 150) for monsters + MinMonsterDelay = ServerConfiguration.GetOrUpdateSetting("movement.delay.monsterMinDelay", 0.4); + MaxMonsterDelay = ServerConfiguration.GetOrUpdateSetting("movement.delay.monsterMaxDelay", 0.8); + MaxMonsterDex = ServerConfiguration.GetOrUpdateSetting("movement.delay.monsterMaxDex", 150); + } - private static readonly SpeedInfo[] m_Speeds = + public static void GetSpeeds(BaseCreature bc, out double activeSpeed, out double passiveSpeed) + { + var isMonster = bc.IsMonster; + var monsterDelay = isMonster || bc.InActivePVPCombat(); + var maxDex = isMonster ? MaxMonsterDex : MaxDex; + + var dex = Math.Clamp(bc.Dex, 25, maxDex); + + double min = monsterDelay ? MinMonsterDelay : MinDelay; + double max = monsterDelay ? MaxMonsterDelay : MaxDelay; + + if (bc.IsParagon) { - /* Slow */ - new( - 0.3, - 0.6, - new[] - { - typeof(AntLion), typeof(ArcticOgreLord), typeof(BogThing), - typeof(Bogle), typeof(BoneKnight), typeof(EarthElemental), - typeof(Ettin), typeof(FrostOoze), typeof(FrostTroll), - typeof(GazerLarva), typeof(Ghoul), typeof(Golem), - typeof(HeadlessOne), typeof(Jwilson), typeof(Mummy), - typeof(Ogre), typeof(OgreLord), typeof(PlagueBeast), - typeof(Quagmire), typeof(Rat), typeof(RottingCorpse), - typeof(SewerRat), typeof(Skeleton), typeof(Slime), - typeof(Zombie), typeof(Walrus), typeof(RestlessSoul), - typeof(CrystalElemental), typeof(DarknightCreeper), typeof(MoundOfMaggots), - typeof(Juggernaut), typeof(Yamandon), typeof(Serado) - } - ), - /* Fast */ - new( - 0.2, - 0.4, - new[] - { - typeof(LordOaks), typeof(Silvani), typeof(AirElemental), - typeof(AncientWyrm), typeof(Balron), typeof(BladeSpirits), - typeof(DreadSpider), typeof(Efreet), typeof(EtherealWarrior), - typeof(Lich), typeof(Nightmare), typeof(OphidianArchmage), - typeof(OphidianMage), typeof(OphidianWarrior), typeof(OphidianMatriarch), - typeof(OphidianKnight), typeof(PoisonElemental), typeof(Revenant), - typeof(SandVortex), typeof(SavageRider), typeof(SavageShaman), - typeof(SnowElemental), typeof(WhiteWyrm), typeof(Wisp), - typeof(DemonKnight), typeof(GiantBlackWidow), typeof(SummonedAirElemental), - typeof(LesserHiryu), typeof(Hiryu), typeof(LadyOfTheSnow), - typeof(RaiJu), typeof(Ronin), typeof(RuneBeetle), - typeof(Changeling), typeof(LadyJennifyr), typeof(LadyMarai), typeof(MasterJonath), - typeof(MasterMikael), typeof(MasterTheophilus), typeof(RedDeath), - typeof(SirPatrick), typeof(Miasma), typeof(Rend), - typeof(Grobu), typeof(Gnaw), typeof(Guile), - typeof(Irk), typeof(Spite), typeof(LadyLissith), - typeof(LadySabrix), typeof(Malefic), typeof(Silk), - typeof(Virulent) - // TODO: Where to put Lurg, Putrefier, Swoop and Pyre? They seem slower. - } - ), - /* Very Fast */ - new( - 0.175, - 0.350, - new[] - { - typeof(Barracoon), typeof(Mephitis), typeof(Neira), - typeof(Rikktor), typeof(Semidar), typeof(EnergyVortex), - typeof(EliteNinja), typeof(Pixie), typeof(SilverSerpent), - typeof(VorpalBunny), typeof(FleshRenderer), typeof(KhaldunRevenant), - typeof(FactionDragoon), typeof(FactionKnight), typeof(FactionPaladin), - typeof(FactionHenchman), typeof(FactionMercenary), typeof(FactionNecromancer), - typeof(FactionSorceress), typeof(FactionWizard), typeof(FactionBerserker), - typeof(FactionPaladin), typeof(Leviathan), typeof(FireBeetle), - typeof(FanDancer), typeof(FactionDeathKnight) - } - ), - /* Medium */ - new( - 0.25, - 0.5, - new[] - { - typeof(AcidElemental), typeof(AgapiteElemental), typeof(Alligator), - typeof(AncientLich), typeof(Betrayer), typeof(Bird), - typeof(BlackBear), typeof(BlackSolenInfiltratorQueen), typeof(BlackSolenInfiltratorWarrior), - typeof(BlackSolenQueen), typeof(BlackSolenWarrior), typeof(BlackSolenWorker), - typeof(BloodElemental), typeof(Boar), typeof(Bogling), - typeof(BoneMagi), typeof(Brigand), typeof(BronzeElemental), - typeof(BrownBear), typeof(Bull), typeof(BullFrog), - typeof(Cat), typeof(Centaur), typeof(ChaosDaemon), - typeof(Chicken), typeof(GolemController), typeof(CopperElemental), - typeof(CopperElemental), typeof(Cougar), typeof(Cow), - typeof(Cyclops), typeof(Daemon), typeof(DeepSeaSerpent), - typeof(DesertOstard), typeof(DireWolf), typeof(Dog), - typeof(Dolphin), typeof(Dragon), typeof(Drake), - typeof(DullCopperElemental), typeof(Eagle), typeof(ElderGazer), - typeof(EvilMage), typeof(EvilMageLord), typeof(Executioner), - typeof(Savage), typeof(FireElemental), typeof(FireGargoyle), - typeof(FireSteed), typeof(ForestOstard), typeof(FrenziedOstard), - typeof(FrostSpider), typeof(Gargoyle), typeof(Gazer), - typeof(IceSerpent), typeof(GiantRat), typeof(GiantSerpent), - typeof(GiantSpider), typeof(GiantToad), typeof(Goat), - typeof(GoldenElemental), typeof(Gorilla), typeof(GreatHart), - typeof(GreyWolf), typeof(GrizzlyBear), typeof(Guardian), - typeof(Harpy), typeof(Harrower), typeof(HellHound), - typeof(Hind), typeof(HordeMinion), typeof(Horse), - typeof(Horse), typeof(IceElemental), typeof(IceFiend), - typeof(IceSnake), typeof(Imp), typeof(JackRabbit), - typeof(Kirin), typeof(Kraken), typeof(PredatorHellCat), - typeof(LavaLizard), typeof(LavaSerpent), typeof(LavaSnake), - typeof(Lizardman), typeof(Llama), typeof(Mongbat), - typeof(StrongMongbat), typeof(MountainGoat), typeof(Orc), - typeof(OrcBomber), typeof(OrcBrute), typeof(OrcCaptain), - typeof(OrcishLord), typeof(OrcishMage), typeof(PackHorse), - typeof(PackLlama), typeof(Panther), typeof(Pig), - typeof(PlagueSpawn), typeof(PolarBear), typeof(Rabbit), - typeof(Ratman), typeof(RatmanArcher), typeof(RatmanMage), - typeof(RedSolenInfiltratorQueen), typeof(RedSolenInfiltratorWarrior), typeof(RedSolenQueen), - typeof(RedSolenWarrior), typeof(RedSolenWorker), typeof(RidableLlama), - typeof(Ridgeback), typeof(Scorpion), typeof(SeaSerpent), - typeof(SerpentineDragon), typeof(Shade), typeof(ShadowIronElemental), - typeof(ShadowWisp), typeof(ShadowWyrm), typeof(Sheep), - typeof(SilverSteed), typeof(SkeletalDragon), typeof(SkeletalMage), - typeof(SkeletalMount), typeof(HellCat), typeof(Snake), - typeof(SnowLeopard), typeof(SpectralArmour), typeof(Spectre), - typeof(StoneGargoyle), typeof(StoneHarpy), typeof(SwampDragon), - typeof(ScaledSwampDragon), typeof(SwampTentacle), typeof(TerathanAvenger), - typeof(TerathanDrone), typeof(TerathanMatriarch), typeof(TerathanWarrior), - typeof(TimberWolf), typeof(Titan), typeof(Troll), - typeof(Unicorn), typeof(ValoriteElemental), typeof(VeriteElemental), - typeof(CoMWarHorse), typeof(MinaxWarHorse), typeof(SLWarHorse), - typeof(TBWarHorse), typeof(WaterElemental), typeof(WhippingVine), - typeof(WhiteWolf), typeof(Wraith), typeof(Wyvern), - typeof(KhaldunZealot), typeof(KhaldunSummoner), typeof(SavageRidgeback), - typeof(LichLord), typeof(SkeletalKnight), typeof(SummonedDaemon), - typeof(SummonedEarthElemental), typeof(SummonedWaterElemental), typeof(SummonedFireElemental), - typeof(MeerWarrior), typeof(MeerEternal), typeof(MeerMage), - typeof(MeerCaptain), typeof(JukaLord), typeof(JukaMage), - typeof(JukaWarrior), typeof(AbysmalHorror), typeof(BoneDemon), - typeof(Devourer), typeof(FleshGolem), typeof(Gibberling), - typeof(GoreFiend), typeof(Impaler), typeof(PatchworkSkeleton), - typeof(Ravager), typeof(ShadowKnight), typeof(SkitteringHopper), - typeof(Treefellow), typeof(VampireBat), typeof(WailingBanshee), - typeof(WandererOfTheVoid), typeof(Cursed), typeof(GrimmochDrummel), - typeof(LysanderGathenwale), typeof(MorgBergen), typeof(ShadowFiend), - typeof(SpectralArmour), typeof(TavaraSewel), typeof(ArcaneDaemon), - typeof(Doppleganger), typeof(EnslavedGargoyle), typeof(ExodusMinion), - typeof(ExodusOverseer), typeof(GargoyleDestroyer), typeof(GargoyleEnforcer), - typeof(Moloch), typeof(BakeKitsune), typeof(DeathwatchBeetleHatchling), - typeof(Kappa), typeof(KazeKemono), typeof(DeathwatchBeetle), - typeof(TsukiWolf), typeof(YomotsuElder), typeof(YomotsuPriest), - typeof(YomotsuWarrior), typeof(RevenantLion), typeof(Oni), - typeof(Gaman), typeof(Crane), typeof(Beetle) - } - ) - }; - - public SpeedInfo(double activeSpeed, double passiveSpeed, Type[] types) - { - ActiveSpeed = activeSpeed; - PassiveSpeed = passiveSpeed; - Types = types; + min /= 2; + max = min + 0.5; } - public double ActiveSpeed { get; set; } - - public double PassiveSpeed { get; set; } - - public Type[] Types { get; set; } - - public static bool Contains(object obj) - { - if (!Enabled) - { - return false; - } - - if (m_Table == null) - { - LoadTable(); - } - - return m_Table!.ContainsKey(obj.GetType()); - } - - public static bool GetSpeeds(object obj, ref double activeSpeed, ref double passiveSpeed) - { - if (!Enabled) - { - return false; - } - - if (m_Table == null) - { - LoadTable(); - } - - if (!m_Table!.TryGetValue(obj.GetType(), out var sp)) - { - return false; - } - - activeSpeed = sp.ActiveSpeed; - passiveSpeed = sp.PassiveSpeed; - - return true; - } - - private static void LoadTable() - { - m_Table = new Dictionary(); - - for (var i = 0; i < m_Speeds.Length; ++i) - { - var info = m_Speeds[i]; - var types = info.Types; - - for (var j = 0; j < types.Length; ++j) - { - m_Table[types[j]] = info; - } - } - } + activeSpeed = Math.Max(max - (max - min) * ((double)dex / maxDex), min); + passiveSpeed = activeSpeed * 2; } } diff --git a/Projects/UOContent/Mobiles/Animals/Bears/BlackBear.cs b/Projects/UOContent/Mobiles/Animals/Bears/BlackBear.cs index 536a9a97e..c692f9286 100644 --- a/Projects/UOContent/Mobiles/Animals/Bears/BlackBear.cs +++ b/Projects/UOContent/Mobiles/Animals/Bears/BlackBear.cs @@ -4,7 +4,7 @@ namespace Server.Mobiles public class BlackBear : BaseCreature { [Constructible] - public BlackBear() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public BlackBear() : base(AIType.AI_Animal, FightMode.Aggressor) { Body = 211; BaseSoundID = 0xA3; diff --git a/Projects/UOContent/Mobiles/Animals/Bears/BrownBear.cs b/Projects/UOContent/Mobiles/Animals/Bears/BrownBear.cs index 1e3175411..781f7bb37 100644 --- a/Projects/UOContent/Mobiles/Animals/Bears/BrownBear.cs +++ b/Projects/UOContent/Mobiles/Animals/Bears/BrownBear.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class BrownBear : BaseCreature { [Constructible] - public BrownBear() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public BrownBear() : base(AIType.AI_Animal, FightMode.Aggressor) { Body = 167; BaseSoundID = 0xA3; diff --git a/Projects/UOContent/Mobiles/Animals/Bears/GrizzlyBear.cs b/Projects/UOContent/Mobiles/Animals/Bears/GrizzlyBear.cs index 56a40674c..709b2181a 100644 --- a/Projects/UOContent/Mobiles/Animals/Bears/GrizzlyBear.cs +++ b/Projects/UOContent/Mobiles/Animals/Bears/GrizzlyBear.cs @@ -4,7 +4,7 @@ namespace Server.Mobiles public class GrizzlyBear : BaseCreature { [Constructible] - public GrizzlyBear() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public GrizzlyBear() : base(AIType.AI_Animal, FightMode.Aggressor) { Body = 212; BaseSoundID = 0xA3; diff --git a/Projects/UOContent/Mobiles/Animals/Bears/PolarBear.cs b/Projects/UOContent/Mobiles/Animals/Bears/PolarBear.cs index eccc1716d..2931c8931 100644 --- a/Projects/UOContent/Mobiles/Animals/Bears/PolarBear.cs +++ b/Projects/UOContent/Mobiles/Animals/Bears/PolarBear.cs @@ -4,7 +4,7 @@ namespace Server.Mobiles public class PolarBear : BaseCreature { [Constructible] - public PolarBear() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public PolarBear() : base(AIType.AI_Animal, FightMode.Aggressor) { Body = 213; BaseSoundID = 0xA3; diff --git a/Projects/UOContent/Mobiles/Animals/Birds/Chicken.cs b/Projects/UOContent/Mobiles/Animals/Birds/Chicken.cs index 756de8844..bd8b7146b 100644 --- a/Projects/UOContent/Mobiles/Animals/Birds/Chicken.cs +++ b/Projects/UOContent/Mobiles/Animals/Birds/Chicken.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class Chicken : BaseCreature { [Constructible] - public Chicken() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public Chicken() : base(AIType.AI_Animal, FightMode.Aggressor) { Body = 0xD0; BaseSoundID = 0x6E; diff --git a/Projects/UOContent/Mobiles/Animals/Birds/Crane.cs b/Projects/UOContent/Mobiles/Animals/Birds/Crane.cs index 1cb10d33d..171a20fb5 100644 --- a/Projects/UOContent/Mobiles/Animals/Birds/Crane.cs +++ b/Projects/UOContent/Mobiles/Animals/Birds/Crane.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class Crane : BaseCreature { [Constructible] - public Crane() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public Crane() : base(AIType.AI_Animal, FightMode.Aggressor) { Body = 254; BaseSoundID = 0x4D7; diff --git a/Projects/UOContent/Mobiles/Animals/Birds/Eagle.cs b/Projects/UOContent/Mobiles/Animals/Birds/Eagle.cs index 593a2c694..4df82ef66 100644 --- a/Projects/UOContent/Mobiles/Animals/Birds/Eagle.cs +++ b/Projects/UOContent/Mobiles/Animals/Birds/Eagle.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class Eagle : BaseCreature { [Constructible] - public Eagle() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public Eagle() : base(AIType.AI_Animal, FightMode.Aggressor) { Body = 5; BaseSoundID = 0x2EE; diff --git a/Projects/UOContent/Mobiles/Animals/Birds/Phoenix.cs b/Projects/UOContent/Mobiles/Animals/Birds/Phoenix.cs index 49179359c..7c0befb94 100644 --- a/Projects/UOContent/Mobiles/Animals/Birds/Phoenix.cs +++ b/Projects/UOContent/Mobiles/Animals/Birds/Phoenix.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class Phoenix : BaseCreature { [Constructible] - public Phoenix() : base(AIType.AI_Mage, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public Phoenix() : base(AIType.AI_Mage, FightMode.Aggressor) { Body = 5; Hue = 0x674; diff --git a/Projects/UOContent/Mobiles/Animals/Canines/DireWolf.cs b/Projects/UOContent/Mobiles/Animals/Canines/DireWolf.cs index 2a6edf148..310338310 100644 --- a/Projects/UOContent/Mobiles/Animals/Canines/DireWolf.cs +++ b/Projects/UOContent/Mobiles/Animals/Canines/DireWolf.cs @@ -4,7 +4,7 @@ namespace Server.Mobiles public class DireWolf : BaseCreature { [Constructible] - public DireWolf() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public DireWolf() : base(AIType.AI_Melee) { Body = 23; BaseSoundID = 0xE5; diff --git a/Projects/UOContent/Mobiles/Animals/Canines/GreyWolf.cs b/Projects/UOContent/Mobiles/Animals/Canines/GreyWolf.cs index 195bcfadc..b0851992d 100644 --- a/Projects/UOContent/Mobiles/Animals/Canines/GreyWolf.cs +++ b/Projects/UOContent/Mobiles/Animals/Canines/GreyWolf.cs @@ -4,7 +4,7 @@ namespace Server.Mobiles public class GreyWolf : BaseCreature { [Constructible] - public GreyWolf() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public GreyWolf() : base(AIType.AI_Animal, FightMode.Aggressor) { Body = Utility.RandomList(25, 27); BaseSoundID = 0xE5; diff --git a/Projects/UOContent/Mobiles/Animals/Canines/TimberWolf.cs b/Projects/UOContent/Mobiles/Animals/Canines/TimberWolf.cs index f808128cf..a33ad2b89 100644 --- a/Projects/UOContent/Mobiles/Animals/Canines/TimberWolf.cs +++ b/Projects/UOContent/Mobiles/Animals/Canines/TimberWolf.cs @@ -4,7 +4,7 @@ namespace Server.Mobiles public class TimberWolf : BaseCreature { [Constructible] - public TimberWolf() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public TimberWolf() : base(AIType.AI_Animal, FightMode.Aggressor) { Body = 225; BaseSoundID = 0xE5; diff --git a/Projects/UOContent/Mobiles/Animals/Canines/WhiteWolf.cs b/Projects/UOContent/Mobiles/Animals/Canines/WhiteWolf.cs index bb57d611d..9a5d08d06 100644 --- a/Projects/UOContent/Mobiles/Animals/Canines/WhiteWolf.cs +++ b/Projects/UOContent/Mobiles/Animals/Canines/WhiteWolf.cs @@ -4,7 +4,7 @@ namespace Server.Mobiles public class WhiteWolf : BaseCreature { [Constructible] - public WhiteWolf() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public WhiteWolf() : base(AIType.AI_Animal, FightMode.Aggressor) { Body = Utility.RandomList(34, 37); BaseSoundID = 0xE5; diff --git a/Projects/UOContent/Mobiles/Animals/Cows/Bull.cs b/Projects/UOContent/Mobiles/Animals/Cows/Bull.cs index 3a495b6b4..2430532a0 100644 --- a/Projects/UOContent/Mobiles/Animals/Cows/Bull.cs +++ b/Projects/UOContent/Mobiles/Animals/Cows/Bull.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class Bull : BaseCreature { [Constructible] - public Bull() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public Bull() : base(AIType.AI_Animal, FightMode.Aggressor) { Body = Utility.RandomList(0xE8, 0xE9); BaseSoundID = 0x64; diff --git a/Projects/UOContent/Mobiles/Animals/Cows/Cow.cs b/Projects/UOContent/Mobiles/Animals/Cows/Cow.cs index 043012ed8..ea74e6425 100644 --- a/Projects/UOContent/Mobiles/Animals/Cows/Cow.cs +++ b/Projects/UOContent/Mobiles/Animals/Cows/Cow.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class Cow : BaseCreature { [Constructible] - public Cow() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public Cow() : base(AIType.AI_Animal, FightMode.Aggressor) { Body = Utility.RandomList(0xD8, 0xE7); BaseSoundID = 0x78; diff --git a/Projects/UOContent/Mobiles/Animals/Felines/Cougar.cs b/Projects/UOContent/Mobiles/Animals/Felines/Cougar.cs index ede2b5ae5..0dc46458d 100644 --- a/Projects/UOContent/Mobiles/Animals/Felines/Cougar.cs +++ b/Projects/UOContent/Mobiles/Animals/Felines/Cougar.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class Cougar : BaseCreature { [Constructible] - public Cougar() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public Cougar() : base(AIType.AI_Animal, FightMode.Aggressor) { Body = 63; BaseSoundID = 0x73; diff --git a/Projects/UOContent/Mobiles/Animals/Felines/HellCat.cs b/Projects/UOContent/Mobiles/Animals/Felines/HellCat.cs index b1742f463..346b50747 100644 --- a/Projects/UOContent/Mobiles/Animals/Felines/HellCat.cs +++ b/Projects/UOContent/Mobiles/Animals/Felines/HellCat.cs @@ -4,7 +4,7 @@ namespace Server.Mobiles public class HellCat : BaseCreature { [Constructible] - public HellCat() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public HellCat() : base(AIType.AI_Melee) { Body = 0xC9; Hue = Utility.RandomList(0x647, 0x650, 0x659, 0x662, 0x66B, 0x674); diff --git a/Projects/UOContent/Mobiles/Animals/Felines/Panther.cs b/Projects/UOContent/Mobiles/Animals/Felines/Panther.cs index 966d998a6..ff271a03b 100644 --- a/Projects/UOContent/Mobiles/Animals/Felines/Panther.cs +++ b/Projects/UOContent/Mobiles/Animals/Felines/Panther.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class Panther : BaseCreature { [Constructible] - public Panther() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public Panther() : base(AIType.AI_Animal, FightMode.Aggressor) { Body = 0xD6; Hue = 0x901; diff --git a/Projects/UOContent/Mobiles/Animals/Felines/PredatorHellCat.cs b/Projects/UOContent/Mobiles/Animals/Felines/PredatorHellCat.cs index 8dcf0286f..612497376 100644 --- a/Projects/UOContent/Mobiles/Animals/Felines/PredatorHellCat.cs +++ b/Projects/UOContent/Mobiles/Animals/Felines/PredatorHellCat.cs @@ -4,7 +4,7 @@ namespace Server.Mobiles public class PredatorHellCat : BaseCreature { [Constructible] - public PredatorHellCat() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public PredatorHellCat() : base(AIType.AI_Melee) { Body = 127; BaseSoundID = 0xBA; diff --git a/Projects/UOContent/Mobiles/Animals/Felines/SnowLeopard.cs b/Projects/UOContent/Mobiles/Animals/Felines/SnowLeopard.cs index 28f86bb0e..e0d0366e9 100644 --- a/Projects/UOContent/Mobiles/Animals/Felines/SnowLeopard.cs +++ b/Projects/UOContent/Mobiles/Animals/Felines/SnowLeopard.cs @@ -4,7 +4,7 @@ namespace Server.Mobiles public class SnowLeopard : BaseCreature { [Constructible] - public SnowLeopard() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public SnowLeopard() : base(AIType.AI_Animal, FightMode.Aggressor) { Body = Utility.RandomList(64, 65); BaseSoundID = 0x73; diff --git a/Projects/UOContent/Mobiles/Animals/Misc/Boar.cs b/Projects/UOContent/Mobiles/Animals/Misc/Boar.cs index 57dfbb36c..6763885b3 100644 --- a/Projects/UOContent/Mobiles/Animals/Misc/Boar.cs +++ b/Projects/UOContent/Mobiles/Animals/Misc/Boar.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class Boar : BaseCreature { [Constructible] - public Boar() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public Boar() : base(AIType.AI_Animal, FightMode.Aggressor) { Body = 0x122; BaseSoundID = 0xC4; diff --git a/Projects/UOContent/Mobiles/Animals/Misc/BullFrog.cs b/Projects/UOContent/Mobiles/Animals/Misc/BullFrog.cs index 7ef3d5fcd..139db24ab 100644 --- a/Projects/UOContent/Mobiles/Animals/Misc/BullFrog.cs +++ b/Projects/UOContent/Mobiles/Animals/Misc/BullFrog.cs @@ -4,7 +4,7 @@ namespace Server.Mobiles public class BullFrog : BaseCreature { [Constructible] - public BullFrog() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public BullFrog() : base(AIType.AI_Animal, FightMode.Aggressor) { Body = 81; Hue = Utility.RandomList(0x5AC, 0x5A3, 0x59A, 0x591, 0x588, 0x57F); diff --git a/Projects/UOContent/Mobiles/Animals/Misc/Dolphin.cs b/Projects/UOContent/Mobiles/Animals/Misc/Dolphin.cs index 7aae6d76a..2ae29cbbb 100644 --- a/Projects/UOContent/Mobiles/Animals/Misc/Dolphin.cs +++ b/Projects/UOContent/Mobiles/Animals/Misc/Dolphin.cs @@ -4,7 +4,7 @@ namespace Server.Mobiles { [Constructible] public Dolphin() - : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4) + : base(AIType.AI_Animal, FightMode.Aggressor) { Body = 0x97; BaseSoundID = 0x8A; diff --git a/Projects/UOContent/Mobiles/Animals/Misc/Gaman.cs b/Projects/UOContent/Mobiles/Animals/Misc/Gaman.cs index 380890a2c..e852e697a 100644 --- a/Projects/UOContent/Mobiles/Animals/Misc/Gaman.cs +++ b/Projects/UOContent/Mobiles/Animals/Misc/Gaman.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class Gaman : BaseCreature { [Constructible] - public Gaman() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public Gaman() : base(AIType.AI_Animal, FightMode.Aggressor) { Body = 248; diff --git a/Projects/UOContent/Mobiles/Animals/Misc/GiantToad.cs b/Projects/UOContent/Mobiles/Animals/Misc/GiantToad.cs index 6730d6b21..70342218a 100644 --- a/Projects/UOContent/Mobiles/Animals/Misc/GiantToad.cs +++ b/Projects/UOContent/Mobiles/Animals/Misc/GiantToad.cs @@ -4,7 +4,7 @@ namespace Server.Mobiles public class GiantToad : BaseCreature { [Constructible] - public GiantToad() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public GiantToad() : base(AIType.AI_Melee) { Body = 80; BaseSoundID = 0x26B; diff --git a/Projects/UOContent/Mobiles/Animals/Misc/Goat.cs b/Projects/UOContent/Mobiles/Animals/Misc/Goat.cs index 3e45ad600..67240f9fc 100644 --- a/Projects/UOContent/Mobiles/Animals/Misc/Goat.cs +++ b/Projects/UOContent/Mobiles/Animals/Misc/Goat.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class Goat : BaseCreature { [Constructible] - public Goat() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public Goat() : base(AIType.AI_Animal, FightMode.Aggressor) { Body = 0xD1; BaseSoundID = 0x99; diff --git a/Projects/UOContent/Mobiles/Animals/Misc/Gorilla.cs b/Projects/UOContent/Mobiles/Animals/Misc/Gorilla.cs index 9978d0118..70447f247 100644 --- a/Projects/UOContent/Mobiles/Animals/Misc/Gorilla.cs +++ b/Projects/UOContent/Mobiles/Animals/Misc/Gorilla.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class Gorilla : BaseCreature { [Constructible] - public Gorilla() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public Gorilla() : base(AIType.AI_Animal, FightMode.Aggressor) { Body = 0x1D; BaseSoundID = 0x9E; diff --git a/Projects/UOContent/Mobiles/Animals/Misc/GreatHart.cs b/Projects/UOContent/Mobiles/Animals/Misc/GreatHart.cs index 470c773b3..3681bfda6 100644 --- a/Projects/UOContent/Mobiles/Animals/Misc/GreatHart.cs +++ b/Projects/UOContent/Mobiles/Animals/Misc/GreatHart.cs @@ -4,7 +4,7 @@ namespace Server.Mobiles public class GreatHart : BaseCreature { [Constructible] - public GreatHart() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public GreatHart() : base(AIType.AI_Animal, FightMode.Aggressor) { Body = 0xEA; diff --git a/Projects/UOContent/Mobiles/Animals/Misc/Hind.cs b/Projects/UOContent/Mobiles/Animals/Misc/Hind.cs index 96ba6bc12..7aec10de9 100644 --- a/Projects/UOContent/Mobiles/Animals/Misc/Hind.cs +++ b/Projects/UOContent/Mobiles/Animals/Misc/Hind.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class Hind : BaseCreature { [Constructible] - public Hind() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public Hind() : base(AIType.AI_Animal, FightMode.Aggressor) { Body = 0xED; diff --git a/Projects/UOContent/Mobiles/Animals/Misc/Llama.cs b/Projects/UOContent/Mobiles/Animals/Misc/Llama.cs index e8f4976d5..b67b023ab 100644 --- a/Projects/UOContent/Mobiles/Animals/Misc/Llama.cs +++ b/Projects/UOContent/Mobiles/Animals/Misc/Llama.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class Llama : BaseCreature { [Constructible] - public Llama() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public Llama() : base(AIType.AI_Animal, FightMode.Aggressor) { Body = 0xDC; BaseSoundID = 0x3F3; diff --git a/Projects/UOContent/Mobiles/Animals/Misc/MountainGoat.cs b/Projects/UOContent/Mobiles/Animals/Misc/MountainGoat.cs index a0d403404..979d09153 100644 --- a/Projects/UOContent/Mobiles/Animals/Misc/MountainGoat.cs +++ b/Projects/UOContent/Mobiles/Animals/Misc/MountainGoat.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class MountainGoat : BaseCreature { [Constructible] - public MountainGoat() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public MountainGoat() : base(AIType.AI_Animal, FightMode.Aggressor) { Body = 88; BaseSoundID = 0x99; diff --git a/Projects/UOContent/Mobiles/Animals/Misc/PackHorse.cs b/Projects/UOContent/Mobiles/Animals/Misc/PackHorse.cs index dcb6b4f0d..ca5d8324e 100644 --- a/Projects/UOContent/Mobiles/Animals/Misc/PackHorse.cs +++ b/Projects/UOContent/Mobiles/Animals/Misc/PackHorse.cs @@ -7,7 +7,7 @@ namespace Server.Mobiles public class PackHorse : BaseCreature { [Constructible] - public PackHorse() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public PackHorse() : base(AIType.AI_Animal, FightMode.Aggressor) { Body = 291; BaseSoundID = 0xA8; diff --git a/Projects/UOContent/Mobiles/Animals/Misc/PackLlama.cs b/Projects/UOContent/Mobiles/Animals/Misc/PackLlama.cs index d916b6dba..8a523d840 100644 --- a/Projects/UOContent/Mobiles/Animals/Misc/PackLlama.cs +++ b/Projects/UOContent/Mobiles/Animals/Misc/PackLlama.cs @@ -7,7 +7,7 @@ namespace Server.Mobiles public class PackLlama : BaseCreature { [Constructible] - public PackLlama() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public PackLlama() : base(AIType.AI_Animal, FightMode.Aggressor) { Body = 292; BaseSoundID = 0x3F3; diff --git a/Projects/UOContent/Mobiles/Animals/Misc/Pig.cs b/Projects/UOContent/Mobiles/Animals/Misc/Pig.cs index cbc1e4ae8..7c0d3a4d5 100644 --- a/Projects/UOContent/Mobiles/Animals/Misc/Pig.cs +++ b/Projects/UOContent/Mobiles/Animals/Misc/Pig.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class Pig : BaseCreature { [Constructible] - public Pig() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public Pig() : base(AIType.AI_Animal, FightMode.Aggressor) { Body = 0xCB; BaseSoundID = 0xC4; diff --git a/Projects/UOContent/Mobiles/Animals/Misc/Sheep.cs b/Projects/UOContent/Mobiles/Animals/Misc/Sheep.cs index 04e21dd45..61c54ec44 100644 --- a/Projects/UOContent/Mobiles/Animals/Misc/Sheep.cs +++ b/Projects/UOContent/Mobiles/Animals/Misc/Sheep.cs @@ -9,7 +9,7 @@ namespace Server.Mobiles private DateTime m_NextWoolTime; [Constructible] - public Sheep() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public Sheep() : base(AIType.AI_Animal, FightMode.Aggressor) { Body = 0xCF; BaseSoundID = 0xD6; diff --git a/Projects/UOContent/Mobiles/Animals/Misc/Walrus.cs b/Projects/UOContent/Mobiles/Animals/Misc/Walrus.cs index 480744c5c..7fbd9001f 100644 --- a/Projects/UOContent/Mobiles/Animals/Misc/Walrus.cs +++ b/Projects/UOContent/Mobiles/Animals/Misc/Walrus.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class Walrus : BaseCreature { [Constructible] - public Walrus() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public Walrus() : base(AIType.AI_Animal, FightMode.Aggressor) { Body = 0xDD; BaseSoundID = 0xE0; diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/BaseMount.cs b/Projects/UOContent/Mobiles/Animals/Mounts/BaseMount.cs index 944ef0272..3e304765a 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/BaseMount.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/BaseMount.cs @@ -12,7 +12,7 @@ namespace Server.Mobiles public BaseMount( string name, int bodyID, int itemID, AIType aiType, FightMode fightMode, int rangePerception, - int rangeFight, double activeSpeed, double passiveSpeed + int rangeFight, double activeSpeed = -1, double passiveSpeed = -1 ) : base( aiType, fightMode, diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/Hiryu.cs b/Projects/UOContent/Mobiles/Animals/Mounts/Hiryu.cs index 5aac32a1f..2297300f6 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/Hiryu.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/Hiryu.cs @@ -11,7 +11,7 @@ namespace Server.Mobiles [Constructible] public Hiryu() - : base("a hiryu", 243, 0x3E94, AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + : base("a hiryu", 243, 0x3E94, AIType.AI_Melee, FightMode.Closest, 10, 1) { Hue = GetHue(); diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/Kirin.cs b/Projects/UOContent/Mobiles/Animals/Mounts/Kirin.cs index 58ae0a3fc..e229bbfdc 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/Kirin.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/Kirin.cs @@ -7,7 +7,7 @@ namespace Server.Mobiles public class Kirin : BaseMount { [Constructible] - public Kirin(string name = "a ki-rin") : base(name, 132, 0x3EAD, AIType.AI_Mage, FightMode.Evil, 10, 1, 0.2, 0.4) + public Kirin(string name = "a ki-rin") : base(name, 132, 0x3EAD, AIType.AI_Mage, FightMode.Evil, 10, 1) { BaseSoundID = 0x3C5; diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/LesserHiryu.cs b/Projects/UOContent/Mobiles/Animals/Mounts/LesserHiryu.cs index dafed75de..aa0be7316 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/LesserHiryu.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/LesserHiryu.cs @@ -11,7 +11,7 @@ namespace Server.Mobiles [Constructible] public LesserHiryu() - : base("a lesser hiryu", 243, 0x3E94, AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + : base("a lesser hiryu", 243, 0x3E94, AIType.AI_Melee, FightMode.Closest, 10, 1) { Hue = GetHue(); diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/Unicorn.cs b/Projects/UOContent/Mobiles/Animals/Mounts/Unicorn.cs index aa4e46202..12bd1434c 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/Unicorn.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/Unicorn.cs @@ -7,7 +7,7 @@ namespace Server.Mobiles public class Unicorn : BaseMount { [Constructible] - public Unicorn(string name = "a unicorn") : base(name, 0x7A, 0x3EB4, AIType.AI_Mage, FightMode.Evil, 10, 1, 0.2, 0.4) + public Unicorn(string name = "a unicorn") : base(name, 0x7A, 0x3EB4, AIType.AI_Mage, FightMode.Evil, 10, 1) { BaseSoundID = 0x4BC; diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/War Horses/BaseWarHorse.cs b/Projects/UOContent/Mobiles/Animals/Mounts/War Horses/BaseWarHorse.cs index a103a344d..5c32ee070 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/War Horses/BaseWarHorse.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/War Horses/BaseWarHorse.cs @@ -4,7 +4,7 @@ namespace Server.Mobiles { public BaseWarHorse( int bodyID, int itemID, AIType aiType, FightMode fightMode, int rangePerception, int rangeFight, - double activeSpeed, double passiveSpeed + double activeSpeed = -1, double passiveSpeed = -1 ) : base( "a war horse", bodyID, diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/War Horses/CoMWarHorse.cs b/Projects/UOContent/Mobiles/Animals/Mounts/War Horses/CoMWarHorse.cs index 0b18db03f..302d98f3c 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/War Horses/CoMWarHorse.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/War Horses/CoMWarHorse.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class CoMWarHorse : BaseWarHorse { [Constructible] - public CoMWarHorse() : base(0x77, 0x3EB1, AIType.AI_Melee, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public CoMWarHorse() : base(0x77, 0x3EB1, AIType.AI_Melee, FightMode.Aggressor, 10, 1) { } diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/War Horses/MinaxWarHorse.cs b/Projects/UOContent/Mobiles/Animals/Mounts/War Horses/MinaxWarHorse.cs index e116dabdb..eb42361c9 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/War Horses/MinaxWarHorse.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/War Horses/MinaxWarHorse.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class MinaxWarHorse : BaseWarHorse { [Constructible] - public MinaxWarHorse() : base(0x78, 0x3EAF, AIType.AI_Melee, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public MinaxWarHorse() : base(0x78, 0x3EAF, AIType.AI_Melee, FightMode.Aggressor, 10, 1) { } diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/War Horses/SLWarHorse.cs b/Projects/UOContent/Mobiles/Animals/Mounts/War Horses/SLWarHorse.cs index fb2e04c5d..037a671c5 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/War Horses/SLWarHorse.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/War Horses/SLWarHorse.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class SLWarHorse : BaseWarHorse { [Constructible] - public SLWarHorse() : base(0x79, 0x3EB0, AIType.AI_Melee, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public SLWarHorse() : base(0x79, 0x3EB0, AIType.AI_Melee, FightMode.Aggressor, 10, 1) { } diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/War Horses/TBWarHorse.cs b/Projects/UOContent/Mobiles/Animals/Mounts/War Horses/TBWarHorse.cs index aeced8675..ac65a8186 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/War Horses/TBWarHorse.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/War Horses/TBWarHorse.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class TBWarHorse : BaseWarHorse { [Constructible] - public TBWarHorse() : base(0x76, 0x3EB2, AIType.AI_Melee, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public TBWarHorse() : base(0x76, 0x3EB2, AIType.AI_Melee, FightMode.Aggressor, 10, 1) { } diff --git a/Projects/UOContent/Mobiles/Animals/Reptiles/Alligator.cs b/Projects/UOContent/Mobiles/Animals/Reptiles/Alligator.cs index 5522cdedc..35ae29e9a 100644 --- a/Projects/UOContent/Mobiles/Animals/Reptiles/Alligator.cs +++ b/Projects/UOContent/Mobiles/Animals/Reptiles/Alligator.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class Alligator : BaseCreature { [Constructible] - public Alligator() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public Alligator() : base(AIType.AI_Melee) { Body = 0xCA; BaseSoundID = 660; diff --git a/Projects/UOContent/Mobiles/Animals/Reptiles/GiantSerpent.cs b/Projects/UOContent/Mobiles/Animals/Reptiles/GiantSerpent.cs index c4258032c..8f23649a2 100644 --- a/Projects/UOContent/Mobiles/Animals/Reptiles/GiantSerpent.cs +++ b/Projects/UOContent/Mobiles/Animals/Reptiles/GiantSerpent.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles public class GiantSerpent : BaseCreature { [Constructible] - public GiantSerpent() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public GiantSerpent() : base(AIType.AI_Melee) { Body = 0x15; Hue = Utility.RandomSnakeHue(); diff --git a/Projects/UOContent/Mobiles/Animals/Reptiles/IceSerpent.cs b/Projects/UOContent/Mobiles/Animals/Reptiles/IceSerpent.cs index 17183f19e..030656723 100644 --- a/Projects/UOContent/Mobiles/Animals/Reptiles/IceSerpent.cs +++ b/Projects/UOContent/Mobiles/Animals/Reptiles/IceSerpent.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles public class IceSerpent : BaseCreature { [Constructible] - public IceSerpent() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public IceSerpent() : base(AIType.AI_Melee) { Body = 89; BaseSoundID = 219; diff --git a/Projects/UOContent/Mobiles/Animals/Reptiles/IceSnake.cs b/Projects/UOContent/Mobiles/Animals/Reptiles/IceSnake.cs index 751be390b..b4348cdc8 100644 --- a/Projects/UOContent/Mobiles/Animals/Reptiles/IceSnake.cs +++ b/Projects/UOContent/Mobiles/Animals/Reptiles/IceSnake.cs @@ -4,7 +4,7 @@ namespace Server.Mobiles public class IceSnake : BaseCreature { [Constructible] - public IceSnake() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public IceSnake() : base(AIType.AI_Melee) { Body = 52; Hue = 0x480; diff --git a/Projects/UOContent/Mobiles/Animals/Reptiles/LavaLizard.cs b/Projects/UOContent/Mobiles/Animals/Reptiles/LavaLizard.cs index ac0dfb0b0..caff4953f 100644 --- a/Projects/UOContent/Mobiles/Animals/Reptiles/LavaLizard.cs +++ b/Projects/UOContent/Mobiles/Animals/Reptiles/LavaLizard.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles public class LavaLizard : BaseCreature { [Constructible] - public LavaLizard() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public LavaLizard() : base(AIType.AI_Melee) { Body = 0xCE; Hue = Utility.RandomList(0x647, 0x650, 0x659, 0x662, 0x66B, 0x674); diff --git a/Projects/UOContent/Mobiles/Animals/Reptiles/LavaSerpent.cs b/Projects/UOContent/Mobiles/Animals/Reptiles/LavaSerpent.cs index f97697978..5e963937c 100644 --- a/Projects/UOContent/Mobiles/Animals/Reptiles/LavaSerpent.cs +++ b/Projects/UOContent/Mobiles/Animals/Reptiles/LavaSerpent.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles public class LavaSerpent : BaseCreature { [Constructible] - public LavaSerpent() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public LavaSerpent() : base(AIType.AI_Melee) { Body = 90; BaseSoundID = 219; diff --git a/Projects/UOContent/Mobiles/Animals/Reptiles/LavaSnake.cs b/Projects/UOContent/Mobiles/Animals/Reptiles/LavaSnake.cs index cd6434ba6..3b7cb2609 100644 --- a/Projects/UOContent/Mobiles/Animals/Reptiles/LavaSnake.cs +++ b/Projects/UOContent/Mobiles/Animals/Reptiles/LavaSnake.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles public class LavaSnake : BaseCreature { [Constructible] - public LavaSnake() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public LavaSnake() : base(AIType.AI_Melee) { Body = 52; Hue = Utility.RandomList(0x647, 0x650, 0x659, 0x662, 0x66B, 0x674); diff --git a/Projects/UOContent/Mobiles/Animals/Reptiles/SilverSerpent.cs b/Projects/UOContent/Mobiles/Animals/Reptiles/SilverSerpent.cs index 9be470ebe..9039c6281 100644 --- a/Projects/UOContent/Mobiles/Animals/Reptiles/SilverSerpent.cs +++ b/Projects/UOContent/Mobiles/Animals/Reptiles/SilverSerpent.cs @@ -7,7 +7,7 @@ namespace Server.Mobiles public class SilverSerpent : BaseCreature { [Constructible] - public SilverSerpent() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public SilverSerpent() : base(AIType.AI_Melee) { Body = 92; BaseSoundID = 219; diff --git a/Projects/UOContent/Mobiles/Animals/Reptiles/Snake.cs b/Projects/UOContent/Mobiles/Animals/Reptiles/Snake.cs index 4e8467de5..f89d0af66 100644 --- a/Projects/UOContent/Mobiles/Animals/Reptiles/Snake.cs +++ b/Projects/UOContent/Mobiles/Animals/Reptiles/Snake.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class Snake : BaseCreature { [Constructible] - public Snake() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public Snake() : base(AIType.AI_Melee) { Body = 52; Hue = Utility.RandomSnakeHue(); diff --git a/Projects/UOContent/Mobiles/Animals/Rodents/GiantRat.cs b/Projects/UOContent/Mobiles/Animals/Rodents/GiantRat.cs index cda852b99..6704129c6 100644 --- a/Projects/UOContent/Mobiles/Animals/Rodents/GiantRat.cs +++ b/Projects/UOContent/Mobiles/Animals/Rodents/GiantRat.cs @@ -4,7 +4,7 @@ namespace Server.Mobiles public class GiantRat : BaseCreature { [Constructible] - public GiantRat() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public GiantRat() : base(AIType.AI_Melee) { Body = 0xD7; BaseSoundID = 0x188; diff --git a/Projects/UOContent/Mobiles/Animals/Rodents/JackRabbit.cs b/Projects/UOContent/Mobiles/Animals/Rodents/JackRabbit.cs index 35504b199..e40cb6d41 100644 --- a/Projects/UOContent/Mobiles/Animals/Rodents/JackRabbit.cs +++ b/Projects/UOContent/Mobiles/Animals/Rodents/JackRabbit.cs @@ -4,7 +4,7 @@ namespace Server.Mobiles public class JackRabbit : BaseCreature { [Constructible] - public JackRabbit() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public JackRabbit() : base(AIType.AI_Animal, FightMode.Aggressor) { Body = 0xCD; Hue = 0x1BB; diff --git a/Projects/UOContent/Mobiles/Animals/Rodents/Rabbit.cs b/Projects/UOContent/Mobiles/Animals/Rodents/Rabbit.cs index 3592cb5da..173753f13 100644 --- a/Projects/UOContent/Mobiles/Animals/Rodents/Rabbit.cs +++ b/Projects/UOContent/Mobiles/Animals/Rodents/Rabbit.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class Rabbit : BaseCreature { [Constructible] - public Rabbit() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public Rabbit() : base(AIType.AI_Animal, FightMode.Aggressor) { Body = 205; diff --git a/Projects/UOContent/Mobiles/Animals/Rodents/SewerRat.cs b/Projects/UOContent/Mobiles/Animals/Rodents/SewerRat.cs index d2148adb8..6ccf7ed15 100644 --- a/Projects/UOContent/Mobiles/Animals/Rodents/SewerRat.cs +++ b/Projects/UOContent/Mobiles/Animals/Rodents/SewerRat.cs @@ -4,7 +4,7 @@ namespace Server.Mobiles public class SewerRat : BaseCreature { [Constructible] - public SewerRat() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public SewerRat() : base(AIType.AI_Melee) { Body = 238; BaseSoundID = 0xCC; diff --git a/Projects/UOContent/Mobiles/Animals/Slimes/Jwilson.cs b/Projects/UOContent/Mobiles/Animals/Slimes/Jwilson.cs index 2b0e90b42..5c6326e1b 100644 --- a/Projects/UOContent/Mobiles/Animals/Slimes/Jwilson.cs +++ b/Projects/UOContent/Mobiles/Animals/Slimes/Jwilson.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class Jwilson : BaseCreature { [Constructible] - public Jwilson() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public Jwilson() : base(AIType.AI_Melee) { Hue = Utility.RandomList(0x89C, 0x8A2, 0x8A8, 0x8AE); Body = 0x33; diff --git a/Projects/UOContent/Mobiles/Animals/Town Critters/(UO 3D Only) Parrot.cs b/Projects/UOContent/Mobiles/Animals/Town Critters/(UO 3D Only) Parrot.cs index 71cc1be60..c802c255f 100644 --- a/Projects/UOContent/Mobiles/Animals/Town Critters/(UO 3D Only) Parrot.cs +++ b/Projects/UOContent/Mobiles/Animals/Town Critters/(UO 3D Only) Parrot.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class Parrot : BaseCreature { [Constructible] - public Parrot() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public Parrot() : base(AIType.AI_Animal, FightMode.Aggressor) { Body = 831; VirtualArmor = Utility.Random(0, 6); diff --git a/Projects/UOContent/Mobiles/Animals/Town Critters/Bird.cs b/Projects/UOContent/Mobiles/Animals/Town Critters/Bird.cs index 4f99f8350..990c6a6bf 100644 --- a/Projects/UOContent/Mobiles/Animals/Town Critters/Bird.cs +++ b/Projects/UOContent/Mobiles/Animals/Town Critters/Bird.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class Bird : BaseCreature { [Constructible] - public Bird() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public Bird() : base(AIType.AI_Animal, FightMode.Aggressor) { if (Utility.RandomBool()) { @@ -82,7 +82,7 @@ namespace Server.Mobiles public class TropicalBird : BaseCreature { [Constructible] - public TropicalBird() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public TropicalBird() : base(AIType.AI_Animal, FightMode.Aggressor) { Hue = Utility.RandomBirdHue(); diff --git a/Projects/UOContent/Mobiles/Animals/Town Critters/Cat.cs b/Projects/UOContent/Mobiles/Animals/Town Critters/Cat.cs index e27517958..7d533c429 100644 --- a/Projects/UOContent/Mobiles/Animals/Town Critters/Cat.cs +++ b/Projects/UOContent/Mobiles/Animals/Town Critters/Cat.cs @@ -4,7 +4,7 @@ namespace Server.Mobiles public class Cat : BaseCreature { [Constructible] - public Cat() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public Cat() : base(AIType.AI_Animal, FightMode.Aggressor) { Body = 0xC9; Hue = Utility.RandomAnimalHue(); diff --git a/Projects/UOContent/Mobiles/Animals/Town Critters/Dog.cs b/Projects/UOContent/Mobiles/Animals/Town Critters/Dog.cs index cd2c4ce10..f88e2b00f 100644 --- a/Projects/UOContent/Mobiles/Animals/Town Critters/Dog.cs +++ b/Projects/UOContent/Mobiles/Animals/Town Critters/Dog.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class Dog : BaseCreature { [Constructible] - public Dog() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public Dog() : base(AIType.AI_Animal, FightMode.Aggressor) { Body = 0xD9; Hue = Utility.RandomAnimalHue(); diff --git a/Projects/UOContent/Mobiles/Animals/Town Critters/Rat.cs b/Projects/UOContent/Mobiles/Animals/Town Critters/Rat.cs index fad7e803a..c47ab5880 100644 --- a/Projects/UOContent/Mobiles/Animals/Town Critters/Rat.cs +++ b/Projects/UOContent/Mobiles/Animals/Town Critters/Rat.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class Rat : BaseCreature { [Constructible] - public Rat() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public Rat() : base(AIType.AI_Animal, FightMode.Aggressor) { Body = 238; BaseSoundID = 0xCC; diff --git a/Projects/UOContent/Mobiles/BaseCreature.cs b/Projects/UOContent/Mobiles/BaseCreature.cs index 1c0b91b4e..302f14043 100644 --- a/Projects/UOContent/Mobiles/BaseCreature.cs +++ b/Projects/UOContent/Mobiles/BaseCreature.cs @@ -152,7 +152,7 @@ namespace Server.Mobiles } } - public class BaseCreature : Mobile, IHonorTarget, IQuestGiver + public abstract class BaseCreature : Mobile, IHonorTarget, IQuestGiver { public enum Allegiance { @@ -197,16 +197,6 @@ namespace Server.Mobiles typeof(SkeletalMage), typeof(BoneMagi), typeof(PatchworkSkeleton) }; - private static readonly double[] m_StandardActiveSpeeds = - { - 0.175, 0.1, 0.15, 0.2, 0.25, 0.3, 0.4, 0.5, 0.6, 0.8 - }; - - private static readonly double[] m_StandardPassiveSpeeds = - { - 0.350, 0.2, 0.4, 0.5, 0.6, 0.8, 1.0, 1.2, 1.6, 2.0 - }; - private static Mobile m_NoDupeGuards; private static readonly bool EnableRummaging = true; @@ -332,11 +322,11 @@ namespace Server.Mobiles public BaseCreature( AIType ai, - FightMode mode, - int iRangePerception, - int iRangeFight, - double dActiveSpeed, - double dPassiveSpeed + FightMode mode = FightMode.Closest, + int iRangePerception = 10, + int iRangeFight = 1, + double activeSpeed = -1, + double passiveSpeed = -1 ) { if (iRangePerception == OldRangePerception) @@ -356,11 +346,16 @@ namespace Server.Mobiles m_Team = 0; - SpeedInfo.GetSpeeds(this, ref dActiveSpeed, ref dPassiveSpeed); - - ActiveSpeed = dActiveSpeed; - PassiveSpeed = dPassiveSpeed; - m_CurrentSpeed = dPassiveSpeed; + if (passiveSpeed < 0 || activeSpeed < 0) + { + ResetSpeeds(); + } + else + { + ActiveSpeed = activeSpeed; + PassiveSpeed = passiveSpeed; + CurrentSpeed = passiveSpeed; + } Debug = false; @@ -2005,42 +2000,6 @@ namespace Server.Mobiles Loyalty *= 10; } - var activeSpeed = ActiveSpeed; - var passiveSpeed = PassiveSpeed; - - SpeedInfo.GetSpeeds(this, ref activeSpeed, ref passiveSpeed); - - var isStandardActive = false; - for (var i = 0; !isStandardActive && i < m_StandardActiveSpeeds.Length; ++i) - { - isStandardActive = ActiveSpeed == m_StandardActiveSpeeds[i]; - } - - var isStandardPassive = false; - for (var i = 0; !isStandardPassive && i < m_StandardPassiveSpeeds.Length; ++i) - { - isStandardPassive = PassiveSpeed == m_StandardPassiveSpeeds[i]; - } - - if (isStandardActive && m_CurrentSpeed == ActiveSpeed) - { - m_CurrentSpeed = activeSpeed; - } - else if (isStandardPassive && m_CurrentSpeed == PassiveSpeed) - { - m_CurrentSpeed = passiveSpeed; - } - - if (isStandardActive && !m_Paragon) - { - ActiveSpeed = activeSpeed; - } - - if (isStandardPassive && !m_Paragon) - { - PassiveSpeed = passiveSpeed; - } - if (version >= 14) { RemoveIfUntamed = reader.ReadBool(); @@ -3041,6 +3000,12 @@ namespace Server.Mobiles return null; } + public virtual bool IsMonster => + !Controlled || GetMaster() is not BaseCreature { Controlled: true }; + + public bool InActivePVPCombat() => + Combatant is PlayerMobile && ControlOrder != OrderType.Follow; + public static List GetLootingRights(List damageEntries, int hitsMax) { var rights = new List(); @@ -4875,6 +4840,16 @@ namespace Server.Mobiles } } + // Reset speeds based on dex. Mainly used during construction and pet commands + public void ResetSpeeds(bool currentUseActive = false) + { + SpeedInfo.GetSpeeds(this, out var activeSpeed, out var passiveSpeed); + + ActiveSpeed = activeSpeed; + PassiveSpeed = passiveSpeed; + CurrentSpeed = currentUseActive ? activeSpeed : passiveSpeed; + } + public virtual void DropBackpack() { if (Backpack?.Items.Count > 0) diff --git a/Projects/UOContent/Mobiles/Familiars/BaseFamiliar.cs b/Projects/UOContent/Mobiles/Familiars/BaseFamiliar.cs index 0f48c3587..ac550132a 100644 --- a/Projects/UOContent/Mobiles/Familiars/BaseFamiliar.cs +++ b/Projects/UOContent/Mobiles/Familiars/BaseFamiliar.cs @@ -9,7 +9,7 @@ namespace Server.Mobiles private bool m_LastHidden; public BaseFamiliar() - : base(AIType.AI_Melee, FightMode.Closest, 10, 1, .1, .1) + : base(AIType.AI_Melee) { } diff --git a/Projects/UOContent/Mobiles/Monsters/AOS/AbysmalHorror.cs b/Projects/UOContent/Mobiles/Monsters/AOS/AbysmalHorror.cs index 074700bfc..c83a03e5c 100644 --- a/Projects/UOContent/Mobiles/Monsters/AOS/AbysmalHorror.cs +++ b/Projects/UOContent/Mobiles/Monsters/AOS/AbysmalHorror.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class AbysmalHorror : BaseCreature { [Constructible] - public AbysmalHorror() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public AbysmalHorror() : base(AIType.AI_Mage) { Body = 312; BaseSoundID = 0x451; diff --git a/Projects/UOContent/Mobiles/Monsters/AOS/BoneDemon.cs b/Projects/UOContent/Mobiles/Monsters/AOS/BoneDemon.cs index adbc7f5a1..75c9ef030 100644 --- a/Projects/UOContent/Mobiles/Monsters/AOS/BoneDemon.cs +++ b/Projects/UOContent/Mobiles/Monsters/AOS/BoneDemon.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class BoneDemon : BaseCreature { [Constructible] - public BoneDemon() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public BoneDemon() : base(AIType.AI_Mage) { Body = 308; BaseSoundID = 0x48D; diff --git a/Projects/UOContent/Mobiles/Monsters/AOS/CrystalElemental.cs b/Projects/UOContent/Mobiles/Monsters/AOS/CrystalElemental.cs index 3d1ba2821..d21249ff1 100644 --- a/Projects/UOContent/Mobiles/Monsters/AOS/CrystalElemental.cs +++ b/Projects/UOContent/Mobiles/Monsters/AOS/CrystalElemental.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class CrystalElemental : BaseCreature { [Constructible] - public CrystalElemental() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public CrystalElemental() : base(AIType.AI_Mage) { Body = 300; BaseSoundID = 278; diff --git a/Projects/UOContent/Mobiles/Monsters/AOS/DarknightCreeper.cs b/Projects/UOContent/Mobiles/Monsters/AOS/DarknightCreeper.cs index 71c166e82..880b8835e 100644 --- a/Projects/UOContent/Mobiles/Monsters/AOS/DarknightCreeper.cs +++ b/Projects/UOContent/Mobiles/Monsters/AOS/DarknightCreeper.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class DarknightCreeper : BaseCreature { [Constructible] - public DarknightCreeper() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public DarknightCreeper() : base(AIType.AI_Mage) { Name = NameList.RandomName("darknight creeper"); Body = 313; diff --git a/Projects/UOContent/Mobiles/Monsters/AOS/DemonKnight.cs b/Projects/UOContent/Mobiles/Monsters/AOS/DemonKnight.cs index caa5c72e5..ef61460ef 100644 --- a/Projects/UOContent/Mobiles/Monsters/AOS/DemonKnight.cs +++ b/Projects/UOContent/Mobiles/Monsters/AOS/DemonKnight.cs @@ -8,7 +8,7 @@ namespace Server.Mobiles private static bool m_InHere; [Constructible] - public DemonKnight() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public DemonKnight() : base(AIType.AI_Mage) { Name = NameList.RandomName("demon knight"); Title = "the Dark Father"; diff --git a/Projects/UOContent/Mobiles/Monsters/AOS/Devourer.cs b/Projects/UOContent/Mobiles/Monsters/AOS/Devourer.cs index 6e8417836..1055d3198 100644 --- a/Projects/UOContent/Mobiles/Monsters/AOS/Devourer.cs +++ b/Projects/UOContent/Mobiles/Monsters/AOS/Devourer.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class Devourer : BaseCreature { [Constructible] - public Devourer() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public Devourer() : base(AIType.AI_Mage) { Body = 303; BaseSoundID = 357; diff --git a/Projects/UOContent/Mobiles/Monsters/AOS/FleshGolem.cs b/Projects/UOContent/Mobiles/Monsters/AOS/FleshGolem.cs index a4b26857b..57be294ee 100644 --- a/Projects/UOContent/Mobiles/Monsters/AOS/FleshGolem.cs +++ b/Projects/UOContent/Mobiles/Monsters/AOS/FleshGolem.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class FleshGolem : BaseCreature { [Constructible] - public FleshGolem() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public FleshGolem() : base(AIType.AI_Melee) { Body = 304; BaseSoundID = 684; diff --git a/Projects/UOContent/Mobiles/Monsters/AOS/FleshRenderer.cs b/Projects/UOContent/Mobiles/Monsters/AOS/FleshRenderer.cs index e93ebdbed..f80fc7fde 100644 --- a/Projects/UOContent/Mobiles/Monsters/AOS/FleshRenderer.cs +++ b/Projects/UOContent/Mobiles/Monsters/AOS/FleshRenderer.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class FleshRenderer : BaseCreature { [Constructible] - public FleshRenderer() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public FleshRenderer() : base(AIType.AI_Melee) { Body = 315; diff --git a/Projects/UOContent/Mobiles/Monsters/AOS/Gibberling.cs b/Projects/UOContent/Mobiles/Monsters/AOS/Gibberling.cs index d870f5f6a..b0eac7a40 100644 --- a/Projects/UOContent/Mobiles/Monsters/AOS/Gibberling.cs +++ b/Projects/UOContent/Mobiles/Monsters/AOS/Gibberling.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class Gibberling : BaseCreature { [Constructible] - public Gibberling() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public Gibberling() : base(AIType.AI_Melee) { Body = 307; BaseSoundID = 422; diff --git a/Projects/UOContent/Mobiles/Monsters/AOS/GoreFiend.cs b/Projects/UOContent/Mobiles/Monsters/AOS/GoreFiend.cs index ed3b5ccad..2eaa2318f 100644 --- a/Projects/UOContent/Mobiles/Monsters/AOS/GoreFiend.cs +++ b/Projects/UOContent/Mobiles/Monsters/AOS/GoreFiend.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class GoreFiend : BaseCreature { [Constructible] - public GoreFiend() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public GoreFiend() : base(AIType.AI_Melee) { Body = 305; BaseSoundID = 224; diff --git a/Projects/UOContent/Mobiles/Monsters/AOS/Impaler.cs b/Projects/UOContent/Mobiles/Monsters/AOS/Impaler.cs index 4a80a1324..15272279a 100644 --- a/Projects/UOContent/Mobiles/Monsters/AOS/Impaler.cs +++ b/Projects/UOContent/Mobiles/Monsters/AOS/Impaler.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class Impaler : BaseCreature { [Constructible] - public Impaler() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public Impaler() : base(AIType.AI_Melee) { Name = NameList.RandomName("impaler"); Body = 306; diff --git a/Projects/UOContent/Mobiles/Monsters/AOS/MoundOfMaggots.cs b/Projects/UOContent/Mobiles/Monsters/AOS/MoundOfMaggots.cs index 84176bbd2..1e2a1321b 100644 --- a/Projects/UOContent/Mobiles/Monsters/AOS/MoundOfMaggots.cs +++ b/Projects/UOContent/Mobiles/Monsters/AOS/MoundOfMaggots.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class MoundOfMaggots : BaseCreature { [Constructible] - public MoundOfMaggots() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public MoundOfMaggots() : base(AIType.AI_Melee) { Body = 319; BaseSoundID = 898; diff --git a/Projects/UOContent/Mobiles/Monsters/AOS/PatchworkSkeleton.cs b/Projects/UOContent/Mobiles/Monsters/AOS/PatchworkSkeleton.cs index 3de36c43b..ea05afe33 100644 --- a/Projects/UOContent/Mobiles/Monsters/AOS/PatchworkSkeleton.cs +++ b/Projects/UOContent/Mobiles/Monsters/AOS/PatchworkSkeleton.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class PatchworkSkeleton : BaseCreature { [Constructible] - public PatchworkSkeleton() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public PatchworkSkeleton() : base(AIType.AI_Melee) { Body = 309; BaseSoundID = 0x48D; diff --git a/Projects/UOContent/Mobiles/Monsters/AOS/Ravager.cs b/Projects/UOContent/Mobiles/Monsters/AOS/Ravager.cs index 6e770b6f6..9c36f22b0 100644 --- a/Projects/UOContent/Mobiles/Monsters/AOS/Ravager.cs +++ b/Projects/UOContent/Mobiles/Monsters/AOS/Ravager.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class Ravager : BaseCreature { [Constructible] - public Ravager() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public Ravager() : base(AIType.AI_Melee) { Body = 314; BaseSoundID = 357; diff --git a/Projects/UOContent/Mobiles/Monsters/AOS/ShadowKnight.cs b/Projects/UOContent/Mobiles/Monsters/AOS/ShadowKnight.cs index 232be7b9f..762b4c371 100644 --- a/Projects/UOContent/Mobiles/Monsters/AOS/ShadowKnight.cs +++ b/Projects/UOContent/Mobiles/Monsters/AOS/ShadowKnight.cs @@ -10,7 +10,7 @@ namespace Server.Mobiles private TimerExecutionToken _soundTimerToken; [Constructible] - public ShadowKnight() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public ShadowKnight() : base(AIType.AI_Mage) { Name = NameList.RandomName("shadow knight"); Title = "the Shadow Knight"; diff --git a/Projects/UOContent/Mobiles/Monsters/AOS/SkitteringHopper.cs b/Projects/UOContent/Mobiles/Monsters/AOS/SkitteringHopper.cs index c88a3a9f2..a8552f711 100644 --- a/Projects/UOContent/Mobiles/Monsters/AOS/SkitteringHopper.cs +++ b/Projects/UOContent/Mobiles/Monsters/AOS/SkitteringHopper.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class SkitteringHopper : BaseCreature { [Constructible] - public SkitteringHopper() : base(AIType.AI_Melee, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public SkitteringHopper() : base(AIType.AI_Melee, FightMode.Aggressor) { Body = 302; BaseSoundID = 959; diff --git a/Projects/UOContent/Mobiles/Monsters/AOS/Treefellow.cs b/Projects/UOContent/Mobiles/Monsters/AOS/Treefellow.cs index b2850d857..8c4aa6082 100644 --- a/Projects/UOContent/Mobiles/Monsters/AOS/Treefellow.cs +++ b/Projects/UOContent/Mobiles/Monsters/AOS/Treefellow.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class Treefellow : BaseCreature { [Constructible] - public Treefellow() : base(AIType.AI_Melee, FightMode.Evil, 10, 1, 0.2, 0.4) + public Treefellow() : base(AIType.AI_Melee, FightMode.Evil) { Body = 301; diff --git a/Projects/UOContent/Mobiles/Monsters/AOS/VampireBat.cs b/Projects/UOContent/Mobiles/Monsters/AOS/VampireBat.cs index 9629f4a7d..d2ea234fb 100644 --- a/Projects/UOContent/Mobiles/Monsters/AOS/VampireBat.cs +++ b/Projects/UOContent/Mobiles/Monsters/AOS/VampireBat.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class VampireBat : BaseCreature { [Constructible] - public VampireBat() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public VampireBat() : base(AIType.AI_Melee) { Body = 317; BaseSoundID = 0x270; diff --git a/Projects/UOContent/Mobiles/Monsters/AOS/WailingBanshee.cs b/Projects/UOContent/Mobiles/Monsters/AOS/WailingBanshee.cs index ae86f37f7..0f1a447cd 100644 --- a/Projects/UOContent/Mobiles/Monsters/AOS/WailingBanshee.cs +++ b/Projects/UOContent/Mobiles/Monsters/AOS/WailingBanshee.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class WailingBanshee : BaseCreature { [Constructible] - public WailingBanshee() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public WailingBanshee() : base(AIType.AI_Melee) { Body = 310; BaseSoundID = 0x482; diff --git a/Projects/UOContent/Mobiles/Monsters/AOS/WandererOfTheVoid.cs b/Projects/UOContent/Mobiles/Monsters/AOS/WandererOfTheVoid.cs index 13051a7f8..8e3082de1 100644 --- a/Projects/UOContent/Mobiles/Monsters/AOS/WandererOfTheVoid.cs +++ b/Projects/UOContent/Mobiles/Monsters/AOS/WandererOfTheVoid.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class WandererOfTheVoid : BaseCreature { [Constructible] - public WandererOfTheVoid() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public WandererOfTheVoid() : base(AIType.AI_Mage) { Body = 316; BaseSoundID = 377; diff --git a/Projects/UOContent/Mobiles/Monsters/Ants/AntLion.cs b/Projects/UOContent/Mobiles/Monsters/Ants/AntLion.cs index 168d04296..47c4882a6 100644 --- a/Projects/UOContent/Mobiles/Monsters/Ants/AntLion.cs +++ b/Projects/UOContent/Mobiles/Monsters/Ants/AntLion.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles public class AntLion : BaseCreature { [Constructible] - public AntLion() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public AntLion() : base(AIType.AI_Melee) { Body = 787; BaseSoundID = 1006; diff --git a/Projects/UOContent/Mobiles/Monsters/Ants/BlackSolenInfiltratorQueen.cs b/Projects/UOContent/Mobiles/Monsters/Ants/BlackSolenInfiltratorQueen.cs index b3a787080..7d2bd5d5e 100644 --- a/Projects/UOContent/Mobiles/Monsters/Ants/BlackSolenInfiltratorQueen.cs +++ b/Projects/UOContent/Mobiles/Monsters/Ants/BlackSolenInfiltratorQueen.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class BlackSolenInfiltratorQueen : BaseCreature { [Constructible] - public BlackSolenInfiltratorQueen() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public BlackSolenInfiltratorQueen() : base(AIType.AI_Melee) { Body = 807; BaseSoundID = 959; diff --git a/Projects/UOContent/Mobiles/Monsters/Ants/BlackSolenInfiltratorWarrior.cs b/Projects/UOContent/Mobiles/Monsters/Ants/BlackSolenInfiltratorWarrior.cs index 6a89e2c20..9e2c8ed18 100644 --- a/Projects/UOContent/Mobiles/Monsters/Ants/BlackSolenInfiltratorWarrior.cs +++ b/Projects/UOContent/Mobiles/Monsters/Ants/BlackSolenInfiltratorWarrior.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class BlackSolenInfiltratorWarrior : BaseCreature { [Constructible] - public BlackSolenInfiltratorWarrior() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public BlackSolenInfiltratorWarrior() : base(AIType.AI_Melee) { Body = 806; BaseSoundID = 959; diff --git a/Projects/UOContent/Mobiles/Monsters/Ants/BlackSolenQueen.cs b/Projects/UOContent/Mobiles/Monsters/Ants/BlackSolenQueen.cs index c6168f6dc..527b4b4ca 100644 --- a/Projects/UOContent/Mobiles/Monsters/Ants/BlackSolenQueen.cs +++ b/Projects/UOContent/Mobiles/Monsters/Ants/BlackSolenQueen.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles public class BlackSolenQueen : BaseCreature { [Constructible] - public BlackSolenQueen() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public BlackSolenQueen() : base(AIType.AI_Melee) { Body = 807; BaseSoundID = 959; diff --git a/Projects/UOContent/Mobiles/Monsters/Ants/BlackSolenWarrior.cs b/Projects/UOContent/Mobiles/Monsters/Ants/BlackSolenWarrior.cs index 4c493f49b..341c9fc51 100644 --- a/Projects/UOContent/Mobiles/Monsters/Ants/BlackSolenWarrior.cs +++ b/Projects/UOContent/Mobiles/Monsters/Ants/BlackSolenWarrior.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles public class BlackSolenWarrior : BaseCreature { [Constructible] - public BlackSolenWarrior() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public BlackSolenWarrior() : base(AIType.AI_Melee) { Body = 806; BaseSoundID = 959; diff --git a/Projects/UOContent/Mobiles/Monsters/Ants/BlackSolenWorker.cs b/Projects/UOContent/Mobiles/Monsters/Ants/BlackSolenWorker.cs index 383784b1b..3ab873c82 100644 --- a/Projects/UOContent/Mobiles/Monsters/Ants/BlackSolenWorker.cs +++ b/Projects/UOContent/Mobiles/Monsters/Ants/BlackSolenWorker.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class BlackSolenWorker : BaseCreature { [Constructible] - public BlackSolenWorker() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public BlackSolenWorker() : base(AIType.AI_Melee) { Body = 805; BaseSoundID = 959; diff --git a/Projects/UOContent/Mobiles/Monsters/Ants/RedSolenInfiltratorQueen.cs b/Projects/UOContent/Mobiles/Monsters/Ants/RedSolenInfiltratorQueen.cs index eaaf4105f..997f65955 100644 --- a/Projects/UOContent/Mobiles/Monsters/Ants/RedSolenInfiltratorQueen.cs +++ b/Projects/UOContent/Mobiles/Monsters/Ants/RedSolenInfiltratorQueen.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class RedSolenInfiltratorQueen : BaseCreature { [Constructible] - public RedSolenInfiltratorQueen() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public RedSolenInfiltratorQueen() : base(AIType.AI_Melee) { Body = 783; BaseSoundID = 959; diff --git a/Projects/UOContent/Mobiles/Monsters/Ants/RedSolenInfiltratorWarrior.cs b/Projects/UOContent/Mobiles/Monsters/Ants/RedSolenInfiltratorWarrior.cs index 71584f6de..afd41fd2a 100644 --- a/Projects/UOContent/Mobiles/Monsters/Ants/RedSolenInfiltratorWarrior.cs +++ b/Projects/UOContent/Mobiles/Monsters/Ants/RedSolenInfiltratorWarrior.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class RedSolenInfiltratorWarrior : BaseCreature { [Constructible] - public RedSolenInfiltratorWarrior() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public RedSolenInfiltratorWarrior() : base(AIType.AI_Melee) { Body = 782; BaseSoundID = 959; diff --git a/Projects/UOContent/Mobiles/Monsters/Ants/RedSolenQueen.cs b/Projects/UOContent/Mobiles/Monsters/Ants/RedSolenQueen.cs index fbdf85c47..4e491e070 100644 --- a/Projects/UOContent/Mobiles/Monsters/Ants/RedSolenQueen.cs +++ b/Projects/UOContent/Mobiles/Monsters/Ants/RedSolenQueen.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles public class RedSolenQueen : BaseCreature { [Constructible] - public RedSolenQueen() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public RedSolenQueen() : base(AIType.AI_Melee) { Body = 783; BaseSoundID = 959; diff --git a/Projects/UOContent/Mobiles/Monsters/Ants/RedSolenWarrior.cs b/Projects/UOContent/Mobiles/Monsters/Ants/RedSolenWarrior.cs index 4a0ba00d0..0f3ce8f46 100644 --- a/Projects/UOContent/Mobiles/Monsters/Ants/RedSolenWarrior.cs +++ b/Projects/UOContent/Mobiles/Monsters/Ants/RedSolenWarrior.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles public class RedSolenWarrior : BaseCreature { [Constructible] - public RedSolenWarrior() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public RedSolenWarrior() : base(AIType.AI_Melee) { Body = 782; BaseSoundID = 959; diff --git a/Projects/UOContent/Mobiles/Monsters/Ants/RedSolenWorker.cs b/Projects/UOContent/Mobiles/Monsters/Ants/RedSolenWorker.cs index 896920266..6443c286b 100644 --- a/Projects/UOContent/Mobiles/Monsters/Ants/RedSolenWorker.cs +++ b/Projects/UOContent/Mobiles/Monsters/Ants/RedSolenWorker.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class RedSolenWorker : BaseCreature { [Constructible] - public RedSolenWorker() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public RedSolenWorker() : base(AIType.AI_Melee) { Body = 781; BaseSoundID = 959; diff --git a/Projects/UOContent/Mobiles/Monsters/Arachnid/Magic/DreadSpider.cs b/Projects/UOContent/Mobiles/Monsters/Arachnid/Magic/DreadSpider.cs index 8fe4d981d..794b52aab 100644 --- a/Projects/UOContent/Mobiles/Monsters/Arachnid/Magic/DreadSpider.cs +++ b/Projects/UOContent/Mobiles/Monsters/Arachnid/Magic/DreadSpider.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class DreadSpider : BaseCreature { [Constructible] - public DreadSpider() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public DreadSpider() : base(AIType.AI_Mage) { Body = 11; BaseSoundID = 1170; diff --git a/Projects/UOContent/Mobiles/Monsters/Arachnid/Magic/TerathanAvenger.cs b/Projects/UOContent/Mobiles/Monsters/Arachnid/Magic/TerathanAvenger.cs index 1dca6c6c4..7bac271bc 100644 --- a/Projects/UOContent/Mobiles/Monsters/Arachnid/Magic/TerathanAvenger.cs +++ b/Projects/UOContent/Mobiles/Monsters/Arachnid/Magic/TerathanAvenger.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class TerathanAvenger : BaseCreature { [Constructible] - public TerathanAvenger() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public TerathanAvenger() : base(AIType.AI_Mage) { Body = 152; BaseSoundID = 0x24D; diff --git a/Projects/UOContent/Mobiles/Monsters/Arachnid/Magic/TerathanMatriarch.cs b/Projects/UOContent/Mobiles/Monsters/Arachnid/Magic/TerathanMatriarch.cs index fbec2457a..29a77e6fa 100644 --- a/Projects/UOContent/Mobiles/Monsters/Arachnid/Magic/TerathanMatriarch.cs +++ b/Projects/UOContent/Mobiles/Monsters/Arachnid/Magic/TerathanMatriarch.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class TerathanMatriarch : BaseCreature { [Constructible] - public TerathanMatriarch() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public TerathanMatriarch() : base(AIType.AI_Mage) { Body = 72; BaseSoundID = 599; diff --git a/Projects/UOContent/Mobiles/Monsters/Arachnid/Melee/FrostSpider.cs b/Projects/UOContent/Mobiles/Monsters/Arachnid/Melee/FrostSpider.cs index 09021bbba..2c551f41c 100644 --- a/Projects/UOContent/Mobiles/Monsters/Arachnid/Melee/FrostSpider.cs +++ b/Projects/UOContent/Mobiles/Monsters/Arachnid/Melee/FrostSpider.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class FrostSpider : BaseCreature { [Constructible] - public FrostSpider() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public FrostSpider() : base(AIType.AI_Melee) { Body = 20; BaseSoundID = 0x388; diff --git a/Projects/UOContent/Mobiles/Monsters/Arachnid/Melee/GiantBlackWidow.cs b/Projects/UOContent/Mobiles/Monsters/Arachnid/Melee/GiantBlackWidow.cs index 9649635ae..26d69c88a 100644 --- a/Projects/UOContent/Mobiles/Monsters/Arachnid/Melee/GiantBlackWidow.cs +++ b/Projects/UOContent/Mobiles/Monsters/Arachnid/Melee/GiantBlackWidow.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class GiantBlackWidow : BaseCreature { [Constructible] - public GiantBlackWidow() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public GiantBlackWidow() : base(AIType.AI_Melee) { Body = 0x9D; BaseSoundID = 0x388; // TODO: validate diff --git a/Projects/UOContent/Mobiles/Monsters/Arachnid/Melee/GiantSpider.cs b/Projects/UOContent/Mobiles/Monsters/Arachnid/Melee/GiantSpider.cs index dbe2c6852..1b967de50 100644 --- a/Projects/UOContent/Mobiles/Monsters/Arachnid/Melee/GiantSpider.cs +++ b/Projects/UOContent/Mobiles/Monsters/Arachnid/Melee/GiantSpider.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class GiantSpider : BaseCreature { [Constructible] - public GiantSpider() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public GiantSpider() : base(AIType.AI_Melee) { Body = 28; BaseSoundID = 0x388; diff --git a/Projects/UOContent/Mobiles/Monsters/Arachnid/Melee/TerathanDrone.cs b/Projects/UOContent/Mobiles/Monsters/Arachnid/Melee/TerathanDrone.cs index ddc2fe0a9..6d6b107b0 100644 --- a/Projects/UOContent/Mobiles/Monsters/Arachnid/Melee/TerathanDrone.cs +++ b/Projects/UOContent/Mobiles/Monsters/Arachnid/Melee/TerathanDrone.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class TerathanDrone : BaseCreature { [Constructible] - public TerathanDrone() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public TerathanDrone() : base(AIType.AI_Melee) { Body = 71; BaseSoundID = 594; diff --git a/Projects/UOContent/Mobiles/Monsters/Arachnid/Melee/TerathanWarrior.cs b/Projects/UOContent/Mobiles/Monsters/Arachnid/Melee/TerathanWarrior.cs index aa48250f3..b26d22a95 100644 --- a/Projects/UOContent/Mobiles/Monsters/Arachnid/Melee/TerathanWarrior.cs +++ b/Projects/UOContent/Mobiles/Monsters/Arachnid/Melee/TerathanWarrior.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class TerathanWarrior : BaseCreature { [Constructible] - public TerathanWarrior() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public TerathanWarrior() : base(AIType.AI_Melee) { Body = 70; BaseSoundID = 589; diff --git a/Projects/UOContent/Mobiles/Monsters/Elemental/Magic/AcidElemental.cs b/Projects/UOContent/Mobiles/Monsters/Elemental/Magic/AcidElemental.cs index b0fb9541a..32377ffd4 100644 --- a/Projects/UOContent/Mobiles/Monsters/Elemental/Magic/AcidElemental.cs +++ b/Projects/UOContent/Mobiles/Monsters/Elemental/Magic/AcidElemental.cs @@ -4,7 +4,7 @@ namespace Server.Mobiles public class AcidElemental : BaseCreature { [Constructible] - public AcidElemental() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public AcidElemental() : base(AIType.AI_Mage) { Body = 0x9E; BaseSoundID = 278; diff --git a/Projects/UOContent/Mobiles/Monsters/Elemental/Magic/AirElemental.cs b/Projects/UOContent/Mobiles/Monsters/Elemental/Magic/AirElemental.cs index 2e292c837..fc9a25a53 100644 --- a/Projects/UOContent/Mobiles/Monsters/Elemental/Magic/AirElemental.cs +++ b/Projects/UOContent/Mobiles/Monsters/Elemental/Magic/AirElemental.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class AirElemental : BaseCreature { [Constructible] - public AirElemental() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public AirElemental() : base(AIType.AI_Mage) { Body = 13; Hue = 0x4001; diff --git a/Projects/UOContent/Mobiles/Monsters/Elemental/Magic/BloodElemental.cs b/Projects/UOContent/Mobiles/Monsters/Elemental/Magic/BloodElemental.cs index 81898c98a..d7d9ab5bc 100644 --- a/Projects/UOContent/Mobiles/Monsters/Elemental/Magic/BloodElemental.cs +++ b/Projects/UOContent/Mobiles/Monsters/Elemental/Magic/BloodElemental.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class BloodElemental : BaseCreature { [Constructible] - public BloodElemental() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public BloodElemental() : base(AIType.AI_Mage) { Body = 159; BaseSoundID = 278; diff --git a/Projects/UOContent/Mobiles/Monsters/Elemental/Magic/Efreet.cs b/Projects/UOContent/Mobiles/Monsters/Elemental/Magic/Efreet.cs index 469f59827..85a47aa8c 100644 --- a/Projects/UOContent/Mobiles/Monsters/Elemental/Magic/Efreet.cs +++ b/Projects/UOContent/Mobiles/Monsters/Elemental/Magic/Efreet.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class Efreet : BaseCreature { [Constructible] - public Efreet() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public Efreet() : base(AIType.AI_Mage) { Body = 131; BaseSoundID = 768; diff --git a/Projects/UOContent/Mobiles/Monsters/Elemental/Magic/FireElemental.cs b/Projects/UOContent/Mobiles/Monsters/Elemental/Magic/FireElemental.cs index e8ad5fb70..9549c1fe0 100644 --- a/Projects/UOContent/Mobiles/Monsters/Elemental/Magic/FireElemental.cs +++ b/Projects/UOContent/Mobiles/Monsters/Elemental/Magic/FireElemental.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class FireElemental : BaseCreature { [Constructible] - public FireElemental() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public FireElemental() : base(AIType.AI_Mage) { Body = 15; BaseSoundID = 838; diff --git a/Projects/UOContent/Mobiles/Monsters/Elemental/Magic/IceElemental.cs b/Projects/UOContent/Mobiles/Monsters/Elemental/Magic/IceElemental.cs index b55d93c93..f64ff2a4d 100644 --- a/Projects/UOContent/Mobiles/Monsters/Elemental/Magic/IceElemental.cs +++ b/Projects/UOContent/Mobiles/Monsters/Elemental/Magic/IceElemental.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class IceElemental : BaseCreature { [Constructible] - public IceElemental() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public IceElemental() : base(AIType.AI_Mage) { Body = 161; BaseSoundID = 268; diff --git a/Projects/UOContent/Mobiles/Monsters/Elemental/Magic/PoisonElemental.cs b/Projects/UOContent/Mobiles/Monsters/Elemental/Magic/PoisonElemental.cs index d0061309e..4aca1fb01 100644 --- a/Projects/UOContent/Mobiles/Monsters/Elemental/Magic/PoisonElemental.cs +++ b/Projects/UOContent/Mobiles/Monsters/Elemental/Magic/PoisonElemental.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class PoisonElemental : BaseCreature { [Constructible] - public PoisonElemental() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public PoisonElemental() : base(AIType.AI_Mage) { Body = 162; BaseSoundID = 263; diff --git a/Projects/UOContent/Mobiles/Monsters/Elemental/Magic/WaterElemental.cs b/Projects/UOContent/Mobiles/Monsters/Elemental/Magic/WaterElemental.cs index f9ccba620..e3df50c68 100644 --- a/Projects/UOContent/Mobiles/Monsters/Elemental/Magic/WaterElemental.cs +++ b/Projects/UOContent/Mobiles/Monsters/Elemental/Magic/WaterElemental.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class WaterElemental : BaseCreature { [Constructible] - public WaterElemental() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public WaterElemental() : base(AIType.AI_Mage) { Body = 16; BaseSoundID = 278; diff --git a/Projects/UOContent/Mobiles/Monsters/Elemental/Melee/EarthElemental.cs b/Projects/UOContent/Mobiles/Monsters/Elemental/Melee/EarthElemental.cs index 7af2c20c0..2ac62b633 100644 --- a/Projects/UOContent/Mobiles/Monsters/Elemental/Melee/EarthElemental.cs +++ b/Projects/UOContent/Mobiles/Monsters/Elemental/Melee/EarthElemental.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class EarthElemental : BaseCreature { [Constructible] - public EarthElemental() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public EarthElemental() : base(AIType.AI_Melee) { Body = 14; BaseSoundID = 268; diff --git a/Projects/UOContent/Mobiles/Monsters/Elemental/Melee/SnowElemental.cs b/Projects/UOContent/Mobiles/Monsters/Elemental/Melee/SnowElemental.cs index 0b4ef83c4..123cac148 100644 --- a/Projects/UOContent/Mobiles/Monsters/Elemental/Melee/SnowElemental.cs +++ b/Projects/UOContent/Mobiles/Monsters/Elemental/Melee/SnowElemental.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class SnowElemental : BaseCreature { [Constructible] - public SnowElemental() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public SnowElemental() : base(AIType.AI_Melee) { Body = 163; BaseSoundID = 263; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/AncientLich.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/AncientLich.cs index 9018c87e6..be0856d36 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/AncientLich.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/AncientLich.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class AncientLich : BaseCreature { [Constructible] - public AncientLich() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public AncientLich() : base(AIType.AI_Mage) { Name = NameList.RandomName("ancient lich"); Body = 78; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/ArcaneDaemon.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/ArcaneDaemon.cs index d283f8996..3666b3872 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/ArcaneDaemon.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/ArcaneDaemon.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class ArcaneDaemon : BaseCreature { [Constructible] - public ArcaneDaemon() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public ArcaneDaemon() : base(AIType.AI_Mage) { Body = 0x310; BaseSoundID = 0x47D; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Balron.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Balron.cs index c0132e5cb..1948e1ce1 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Balron.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Balron.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class Balron : BaseCreature { [Constructible] - public Balron() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public Balron() : base(AIType.AI_Mage) { Name = NameList.RandomName("balron"); Body = 40; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Betrayer.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Betrayer.cs index 79a0a4b31..d65b6bb5f 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Betrayer.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Betrayer.cs @@ -10,7 +10,7 @@ namespace Server.Mobiles private bool m_Stunning; [Constructible] - public Betrayer() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public Betrayer() : base(AIType.AI_Mage) { Body = 767; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Bogle.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Bogle.cs index 07831fb92..b90623cda 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Bogle.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Bogle.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class Bogle : BaseCreature { [Constructible] - public Bogle() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public Bogle() : base(AIType.AI_Mage) { Body = 153; BaseSoundID = 0x482; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/BoneMagi.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/BoneMagi.cs index 2eabcc511..dcc897d7e 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/BoneMagi.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/BoneMagi.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles public class BoneMagi : BaseCreature { [Constructible] - public BoneMagi() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public BoneMagi() : base(AIType.AI_Mage) { Body = 148; BaseSoundID = 451; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Daemon.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Daemon.cs index 18de26c29..5d582c802 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Daemon.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Daemon.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles public class Daemon : BaseCreature { [Constructible] - public Daemon() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public Daemon() : base(AIType.AI_Mage) { Name = NameList.RandomName("daemon"); Body = 9; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/ElderGazer.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/ElderGazer.cs index 827953361..376ad67e2 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/ElderGazer.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/ElderGazer.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class ElderGazer : BaseCreature { [Constructible] - public ElderGazer() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public ElderGazer() : base(AIType.AI_Mage) { Body = 22; BaseSoundID = 377; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/EvilMage.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/EvilMage.cs index 508ee434b..e2929ae18 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/EvilMage.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/EvilMage.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles public partial class EvilMage : BaseCreature { [Constructible] - public EvilMage() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public EvilMage() : base(AIType.AI_Mage) { Name = NameList.RandomName("evil mage"); Title = "the evil mage"; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/EvilMageLord.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/EvilMageLord.cs index 897983ebe..197f4acd0 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/EvilMageLord.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/EvilMageLord.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles public partial class EvilMageLord : BaseCreature { [Constructible] - public EvilMageLord() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public EvilMageLord() : base(AIType.AI_Mage) { Name = NameList.RandomName("evil mage lord"); Body = Core.UOR ? Utility.Random(125, 2) : 0x190; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/FireGargoyle.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/FireGargoyle.cs index b86c9eca3..8595d6001 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/FireGargoyle.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/FireGargoyle.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class FireGargoyle : BaseCreature { [Constructible] - public FireGargoyle() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public FireGargoyle() : base(AIType.AI_Mage) { Name = NameList.RandomName("fire gargoyle"); Body = 130; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Gargoyle.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Gargoyle.cs index 599390b49..b09605b71 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Gargoyle.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Gargoyle.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class Gargoyle : BaseCreature { [Constructible] - public Gargoyle() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public Gargoyle() : base(AIType.AI_Mage) { Body = 4; BaseSoundID = 372; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/GargoyleDestroyer.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/GargoyleDestroyer.cs index 26fa9b698..24b4bd053 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/GargoyleDestroyer.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/GargoyleDestroyer.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class GargoyleDestroyer : BaseCreature { [Constructible] - public GargoyleDestroyer() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public GargoyleDestroyer() : base(AIType.AI_Mage) { Body = 0x2F3; BaseSoundID = 0x174; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/GargoyleEnforcer.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/GargoyleEnforcer.cs index 242c8dffc..9a0c01753 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/GargoyleEnforcer.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/GargoyleEnforcer.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class GargoyleEnforcer : BaseCreature { [Constructible] - public GargoyleEnforcer() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public GargoyleEnforcer() : base(AIType.AI_Mage) { Body = 0x2F2; BaseSoundID = 0x174; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Gazer.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Gazer.cs index 47aa1d08a..ed9e35dcb 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Gazer.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Gazer.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class Gazer : BaseCreature { [Constructible] - public Gazer() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public Gazer() : base(AIType.AI_Mage) { Body = 22; BaseSoundID = 377; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/GolemController.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/GolemController.cs index b76607323..87bbf8c41 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/GolemController.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/GolemController.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class GolemController : BaseCreature { [Constructible] - public GolemController() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public GolemController() : base(AIType.AI_Mage) { Name = NameList.RandomName("golem controller"); Title = "the controller"; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/IceFiend.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/IceFiend.cs index 8fa4cf347..513386a59 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/IceFiend.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/IceFiend.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class IceFiend : BaseCreature { [Constructible] - public IceFiend() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public IceFiend() : base(AIType.AI_Mage) { Body = 43; BaseSoundID = 357; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Imp.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Imp.cs index 43747d769..6bc8a560b 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Imp.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Imp.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class Imp : BaseCreature { [Constructible] - public Imp() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public Imp() : base(AIType.AI_Mage) { Body = 74; BaseSoundID = 422; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Lich.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Lich.cs index 75926f12b..96b93a502 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Lich.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Lich.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class Lich : BaseCreature { [Constructible] - public Lich() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public Lich() : base(AIType.AI_Mage) { Body = 24; BaseSoundID = 0x3E9; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/LichLord.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/LichLord.cs index 1717af145..3d29c14f9 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/LichLord.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/LichLord.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class LichLord : BaseCreature { [Constructible] - public LichLord() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public LichLord() : base(AIType.AI_Mage) { Body = 79; BaseSoundID = 412; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/OrcishMage.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/OrcishMage.cs index 0eb72f21c..b45d3f8db 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/OrcishMage.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/OrcishMage.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles public class OrcishMage : BaseCreature { [Constructible] - public OrcishMage() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public OrcishMage() : base(AIType.AI_Mage) { Body = 140; BaseSoundID = 0x45A; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/RatmanMage.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/RatmanMage.cs index c9c3944f3..64ed0626e 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/RatmanMage.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/RatmanMage.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class RatmanMage : BaseCreature { [Constructible] - public RatmanMage() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public RatmanMage() : base(AIType.AI_Mage) { Name = NameList.RandomName("ratman"); Body = 0x8F; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/SavageShaman.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/SavageShaman.cs index 29904bf35..9952033a3 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/SavageShaman.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/SavageShaman.cs @@ -8,7 +8,7 @@ namespace Server.Mobiles public class SavageShaman : BaseCreature { [Constructible] - public SavageShaman() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public SavageShaman() : base(AIType.AI_Mage) { Name = NameList.RandomName("savage shaman"); diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Shade.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Shade.cs index 06fc00dd9..6a9a04e17 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Shade.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Shade.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class Shade : BaseCreature { [Constructible] - public Shade() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public Shade() : base(AIType.AI_Mage) { Body = 26; Hue = 0x4001; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/SkeletalMage.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/SkeletalMage.cs index ad767f10d..c40390a17 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/SkeletalMage.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/SkeletalMage.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class SkeletalMage : BaseCreature { [Constructible] - public SkeletalMage() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public SkeletalMage() : base(AIType.AI_Mage) { Body = 148; BaseSoundID = 451; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Spectre.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Spectre.cs index fdff55b9b..c1e311333 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Spectre.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Spectre.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class Spectre : BaseCreature { [Constructible] - public Spectre() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public Spectre() : base(AIType.AI_Mage) { Body = 26; Hue = 0x4001; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Succubus.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Succubus.cs index 2af283bf4..0b43262fe 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Succubus.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Succubus.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class Succubus : BaseCreature { [Constructible] - public Succubus() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public Succubus() : base(AIType.AI_Mage) { Body = 149; BaseSoundID = 0x4B0; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Titan.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Titan.cs index 3dba46e41..0cbf87790 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Titan.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Titan.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class Titan : BaseCreature { [Constructible] - public Titan() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public Titan() : base(AIType.AI_Mage) { Body = 76; BaseSoundID = 609; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Wraith.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Wraith.cs index 51d506ef4..0806091db 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Wraith.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Wraith.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class Wraith : BaseCreature { [Constructible] - public Wraith() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public Wraith() : base(AIType.AI_Mage) { Body = 26; Hue = 0x4001; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/ArcticOgreLord.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/ArcticOgreLord.cs index 0c516ccb8..3f6f75985 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/ArcticOgreLord.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/ArcticOgreLord.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles public class ArcticOgreLord : BaseCreature { [Constructible] - public ArcticOgreLord() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public ArcticOgreLord() : base(AIType.AI_Melee) { Body = 135; BaseSoundID = 427; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/BoneKnight.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/BoneKnight.cs index e11ac3186..c64589ffc 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/BoneKnight.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/BoneKnight.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class BoneKnight : BaseCreature { [Constructible] - public BoneKnight() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public BoneKnight() : base(AIType.AI_Melee) { Body = 57; BaseSoundID = 451; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Brigand.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Brigand.cs index 936c0397a..8d687f6b6 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Brigand.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Brigand.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class Brigand : BaseCreature { [Constructible] - public Brigand() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public Brigand() : base(AIType.AI_Melee) { SpeechHue = Utility.RandomDyedHue(); Title = "the brigand"; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/ChaosDaemon.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/ChaosDaemon.cs index 643516358..e2279f04b 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/ChaosDaemon.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/ChaosDaemon.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class ChaosDaemon : BaseCreature { [Constructible] - public ChaosDaemon() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public ChaosDaemon() : base(AIType.AI_Melee) { Body = 792; BaseSoundID = 0x3E9; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Cursed.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Cursed.cs index 352cd3ae2..8bc329b6c 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Cursed.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Cursed.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class Cursed : BaseCreature { [Constructible] - public Cursed() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public Cursed() : base(AIType.AI_Melee) { Title = "the Cursed"; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Cyclops.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Cyclops.cs index edc0183ad..1317d9a9a 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Cyclops.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Cyclops.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class Cyclops : BaseCreature { [Constructible] - public Cyclops() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public Cyclops() : base(AIType.AI_Melee) { Body = 75; BaseSoundID = 604; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Doppleganger.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Doppleganger.cs index 255977082..6f85f2edc 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Doppleganger.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Doppleganger.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class Doppleganger : BaseCreature { [Constructible] - public Doppleganger() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public Doppleganger() : base(AIType.AI_Melee) { Body = 0x309; BaseSoundID = 0x451; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/ElfBrigand.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/ElfBrigand.cs index 6e12d56d4..9dee70647 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/ElfBrigand.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/ElfBrigand.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles public class ElfBrigand : BaseCreature { [Constructible] - public ElfBrigand() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public ElfBrigand() : base(AIType.AI_Melee) { SpeechHue = Utility.RandomDyedHue(); Title = "the brigand"; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/EnslavedGargoyle.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/EnslavedGargoyle.cs index 22111a70d..ec29a7df1 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/EnslavedGargoyle.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/EnslavedGargoyle.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class EnslavedGargoyle : BaseCreature { [Constructible] - public EnslavedGargoyle() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public EnslavedGargoyle() : base(AIType.AI_Melee) { Body = 0x2F1; BaseSoundID = 0x174; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Ettin.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Ettin.cs index e41162e7b..23641dd69 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Ettin.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Ettin.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class Ettin : BaseCreature { [Constructible] - public Ettin() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public Ettin() : base(AIType.AI_Melee) { Body = 18; BaseSoundID = 367; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Executioner.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Executioner.cs index e241fb044..e5b2a9ea8 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Executioner.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Executioner.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class Executioner : BaseCreature { [Constructible] - public Executioner() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public Executioner() : base(AIType.AI_Melee) { SpeechHue = Utility.RandomDyedHue(); Title = "the executioner"; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/FrostTroll.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/FrostTroll.cs index e96b21cdf..da5904924 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/FrostTroll.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/FrostTroll.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class FrostTroll : BaseCreature { [Constructible] - public FrostTroll() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public FrostTroll() : base(AIType.AI_Melee) { Body = 55; BaseSoundID = 461; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/GazerLarva.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/GazerLarva.cs index 7bbac091b..8a1209573 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/GazerLarva.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/GazerLarva.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class GazerLarva : BaseCreature { [Constructible] - public GazerLarva() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public GazerLarva() : base(AIType.AI_Melee) { Body = 778; BaseSoundID = 377; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Ghoul.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Ghoul.cs index f3130d9b7..2fb04ef1a 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Ghoul.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Ghoul.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class Ghoul : BaseCreature { [Constructible] - public Ghoul() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public Ghoul() : base(AIType.AI_Melee) { Body = 153; BaseSoundID = 0x482; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/GreaterMongbat.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/GreaterMongbat.cs index 4fcf786af..fff738990 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/GreaterMongbat.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/GreaterMongbat.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class GreaterMongbat : BaseCreature { [Constructible] - public GreaterMongbat() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public GreaterMongbat() : base(AIType.AI_Melee) { Body = 39; BaseSoundID = 422; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Guardian.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Guardian.cs index cb868762e..d6cec9f56 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Guardian.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Guardian.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class Guardian : BaseCreature { [Constructible] - public Guardian() : base(AIType.AI_Archer, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public Guardian() : base(AIType.AI_Archer, FightMode.Aggressor) { InitStats(100, 125, 25); Title = "the guardian"; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/HeadlessOne.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/HeadlessOne.cs index 0934f9f8c..5abf05236 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/HeadlessOne.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/HeadlessOne.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class HeadlessOne : BaseCreature { [Constructible] - public HeadlessOne() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public HeadlessOne() : base(AIType.AI_Melee) { Body = 31; Hue = Race.Human.RandomSkinHue() & 0x7FFF; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/HordeMinion.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/HordeMinion.cs index b1fc8822f..416792596 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/HordeMinion.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/HordeMinion.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class HordeMinion : BaseCreature { [Constructible] - public HordeMinion() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public HordeMinion() : base(AIType.AI_Melee) { Body = 776; BaseSoundID = 357; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Juggernaut.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Juggernaut.cs index 483d3a274..f241746f5 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Juggernaut.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Juggernaut.cs @@ -9,7 +9,7 @@ namespace Server.Mobiles private bool m_Stunning; [Constructible] - public Juggernaut() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.3, 0.6) + public Juggernaut() : base(AIType.AI_Melee) { Body = 768; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/KhaldunRevenant.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/KhaldunRevenant.cs index 501300865..fe00b9402 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/KhaldunRevenant.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/KhaldunRevenant.cs @@ -11,7 +11,7 @@ namespace Server.Mobiles private readonly Mobile m_Target; - public KhaldunRevenant(Mobile target) : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.18, 0.36) + public KhaldunRevenant(Mobile target) : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.175, 0.35) { Body = 0x3CA; Hue = 0x41CE; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/KhaldunSummoner.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/KhaldunSummoner.cs index 1b35f0f50..b69b0b3ac 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/KhaldunSummoner.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/KhaldunSummoner.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class KhaldunSummoner : BaseCreature { [Constructible] - public KhaldunSummoner() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public KhaldunSummoner() : base(AIType.AI_Mage) { Body = 0x190; Title = "the Summoner"; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/KhaldunZealot.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/KhaldunZealot.cs index da25b342c..45c5d3b62 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/KhaldunZealot.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/KhaldunZealot.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class KhaldunZealot : BaseCreature { [Constructible] - public KhaldunZealot() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public KhaldunZealot() : base(AIType.AI_Melee) { Body = 0x190; Title = "the Knight"; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Moloch.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Moloch.cs index 75d8d80ba..b54a19af3 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Moloch.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Moloch.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class Moloch : BaseCreature { [Constructible] - public Moloch() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public Moloch() : base(AIType.AI_Melee) { Body = 0x311; BaseSoundID = 0x300; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Mongbat.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Mongbat.cs index b4628c2cc..fe691470f 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Mongbat.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Mongbat.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class Mongbat : BaseCreature { [Constructible] - public Mongbat() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public Mongbat() : base(AIType.AI_Melee) { Body = 39; BaseSoundID = 422; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Mummy.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Mummy.cs index d345cf974..ebef3ae20 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Mummy.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Mummy.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles public class Mummy : BaseCreature { [Constructible] - public Mummy() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.4, 0.8) + public Mummy() : base(AIType.AI_Melee) { Body = 154; BaseSoundID = 471; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Ogre.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Ogre.cs index cb68c9464..06eaf0413 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Ogre.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Ogre.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class Ogre : BaseCreature { [Constructible] - public Ogre() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public Ogre() : base(AIType.AI_Melee) { Body = 1; BaseSoundID = 427; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/OgreLord.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/OgreLord.cs index a3305cd0c..e147daf55 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/OgreLord.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/OgreLord.cs @@ -7,7 +7,7 @@ namespace Server.Mobiles public class OgreLord : BaseCreature { [Constructible] - public OgreLord() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public OgreLord() : base(AIType.AI_Melee) { Body = 83; BaseSoundID = 427; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Orc.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Orc.cs index acb5c1e3b..1c9556b47 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Orc.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Orc.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles public class Orc : BaseCreature { [Constructible] - public Orc() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public Orc() : base(AIType.AI_Melee) { Name = NameList.RandomName("orc"); Body = 17; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/OrcBomber.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/OrcBomber.cs index c55426b2f..1b2ff2afb 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/OrcBomber.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/OrcBomber.cs @@ -10,7 +10,7 @@ namespace Server.Mobiles private int m_Thrown; [Constructible] - public OrcBomber() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public OrcBomber() : base(AIType.AI_Melee) { Body = 182; BaseSoundID = 0x45A; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/OrcBrute.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/OrcBrute.cs index d07b31a81..34c4c410a 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/OrcBrute.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/OrcBrute.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles public class OrcBrute : BaseCreature { [Constructible] - public OrcBrute() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public OrcBrute() : base(AIType.AI_Melee) { Body = 189; BaseSoundID = 0x45A; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/OrcCaptain.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/OrcCaptain.cs index 417de8bca..2130ec3a6 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/OrcCaptain.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/OrcCaptain.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles public class OrcCaptain : BaseCreature { [Constructible] - public OrcCaptain() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public OrcCaptain() : base(AIType.AI_Melee) { Name = NameList.RandomName("orc"); Body = 7; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/OrcishLord.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/OrcishLord.cs index e43631519..c6e6a0a62 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/OrcishLord.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/OrcishLord.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles public class OrcishLord : BaseCreature { [Constructible] - public OrcishLord() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public OrcishLord() : base(AIType.AI_Melee) { Body = 138; BaseSoundID = 0x45A; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Ratman.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Ratman.cs index 9bac39e79..6eea3204a 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Ratman.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Ratman.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class Ratman : BaseCreature { [Constructible] - public Ratman() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public Ratman() : base(AIType.AI_Melee) { Name = NameList.RandomName("ratman"); Body = 42; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/RatmanArcher.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/RatmanArcher.cs index b8ac7f09c..579932c2f 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/RatmanArcher.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/RatmanArcher.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles public class RatmanArcher : BaseCreature { [Constructible] - public RatmanArcher() : base(AIType.AI_Archer, FightMode.Closest, 10, 1, 0.2, 0.4) + public RatmanArcher() : base(AIType.AI_Archer) { Name = NameList.RandomName("ratman"); Body = 0x8E; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/RestlessSoul.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/RestlessSoul.cs index dfcae9946..76b8cf239 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/RestlessSoul.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/RestlessSoul.cs @@ -7,7 +7,7 @@ namespace Server.Mobiles public class RestlessSoul : BaseCreature { [Constructible] - public RestlessSoul() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.4, 0.8) + public RestlessSoul() : base(AIType.AI_Melee) { Body = 0x3CA; Hue = 0x453; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/RottingCorpse.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/RottingCorpse.cs index 48dc7bfe4..284dd8fba 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/RottingCorpse.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/RottingCorpse.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class RottingCorpse : BaseCreature { [Constructible] - public RottingCorpse() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public RottingCorpse() : base(AIType.AI_Melee) { Body = 155; BaseSoundID = 471; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Savage.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Savage.cs index 54e899533..2b8a53ebb 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Savage.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Savage.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles public class Savage : BaseCreature { [Constructible] - public Savage() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public Savage() : base(AIType.AI_Melee) { Name = NameList.RandomName("savage"); diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/SavageRider.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/SavageRider.cs index ad74f08ae..193e709fc 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/SavageRider.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/SavageRider.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles public class SavageRider : BaseCreature { [Constructible] - public SavageRider() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.15, 0.4) + public SavageRider() : base(AIType.AI_Melee) { Name = NameList.RandomName("savage rider"); diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/ShadowFiend.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/ShadowFiend.cs index 1003a2724..064e2221c 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/ShadowFiend.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/ShadowFiend.cs @@ -8,7 +8,7 @@ namespace Server.Mobiles private UnhideTimer m_Timer; [Constructible] - public ShadowFiend() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public ShadowFiend() : base(AIType.AI_Melee) { Body = 0xA8; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/SkeletalKnight.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/SkeletalKnight.cs index 0d3fe161e..0f1bf65f5 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/SkeletalKnight.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/SkeletalKnight.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class SkeletalKnight : BaseCreature { [Constructible] - public SkeletalKnight() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public SkeletalKnight() : base(AIType.AI_Melee) { Body = 147; BaseSoundID = 451; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Skeleton.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Skeleton.cs index b1df50d4c..9d8ff90ef 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Skeleton.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Skeleton.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class Skeleton : BaseCreature { [Constructible] - public Skeleton() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public Skeleton() : base(AIType.AI_Melee) { Body = Utility.RandomList(50, 56); BaseSoundID = 0x48D; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/SpectralArmour.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/SpectralArmour.cs index 7c46d85f5..8c4269d96 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/SpectralArmour.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/SpectralArmour.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class SpectralArmour : BaseCreature { [Constructible] - public SpectralArmour() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public SpectralArmour() : base(AIType.AI_Melee) { Body = 637; Hue = 0x8026; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/StoneGargoyle.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/StoneGargoyle.cs index fe65c0fb5..e66d5796a 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/StoneGargoyle.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/StoneGargoyle.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class StoneGargoyle : BaseCreature { [Constructible] - public StoneGargoyle() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public StoneGargoyle() : base(AIType.AI_Melee) { Body = 67; BaseSoundID = 0x174; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/StrongMongbat.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/StrongMongbat.cs index 1d942c9da..49cc7ae65 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/StrongMongbat.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/StrongMongbat.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class StrongMongbat : BaseCreature { [Constructible] - public StrongMongbat() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public StrongMongbat() : base(AIType.AI_Melee) { Body = 39; BaseSoundID = 422; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Troll.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Troll.cs index 5b47fd587..ff0bc02d4 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Troll.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Troll.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class Troll : BaseCreature { [Constructible] - public Troll() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public Troll() : base(AIType.AI_Melee) { Body = Utility.RandomList(53, 54); BaseSoundID = 461; diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Zombie.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Zombie.cs index dc886d409..bbb2f36b8 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Zombie.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Zombie.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class Zombie : BaseCreature { [Constructible] - public Zombie() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public Zombie() : base(AIType.AI_Melee) { Body = 3; BaseSoundID = 471; diff --git a/Projects/UOContent/Mobiles/Monsters/LBR/Exodus/ExodusMinion.cs b/Projects/UOContent/Mobiles/Monsters/LBR/Exodus/ExodusMinion.cs index 9d2cc5581..f70c42bb2 100644 --- a/Projects/UOContent/Mobiles/Monsters/LBR/Exodus/ExodusMinion.cs +++ b/Projects/UOContent/Mobiles/Monsters/LBR/Exodus/ExodusMinion.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class ExodusMinion : BaseCreature { [Constructible] - public ExodusMinion() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public ExodusMinion() : base(AIType.AI_Melee) { Body = 0x2F5; diff --git a/Projects/UOContent/Mobiles/Monsters/LBR/Exodus/ExodusOverseer.cs b/Projects/UOContent/Mobiles/Monsters/LBR/Exodus/ExodusOverseer.cs index 09aa5a9d7..18aeed356 100644 --- a/Projects/UOContent/Mobiles/Monsters/LBR/Exodus/ExodusOverseer.cs +++ b/Projects/UOContent/Mobiles/Monsters/LBR/Exodus/ExodusOverseer.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class ExodusOverseer : BaseCreature { [Constructible] - public ExodusOverseer() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public ExodusOverseer() : base(AIType.AI_Melee) { Body = 0x2F4; diff --git a/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/JukaLord.cs b/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/JukaLord.cs index 55fa320db..aac42f25e 100644 --- a/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/JukaLord.cs +++ b/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/JukaLord.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class JukaLord : BaseCreature { [Constructible] - public JukaLord() : base(AIType.AI_Archer, FightMode.Closest, 10, 3, 0.2, 0.4) + public JukaLord() : base(AIType.AI_Archer, FightMode.Closest, 10, 3) { Body = 766; diff --git a/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/JukaMage.cs b/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/JukaMage.cs index eff006e42..cbbad4177 100644 --- a/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/JukaMage.cs +++ b/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/JukaMage.cs @@ -10,7 +10,7 @@ namespace Server.Mobiles private DateTime m_NextAbilityTime; [Constructible] - public JukaMage() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public JukaMage() : base(AIType.AI_Mage) { Body = 765; diff --git a/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/JukaWarrior.cs b/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/JukaWarrior.cs index 57d256753..22e9160b1 100644 --- a/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/JukaWarrior.cs +++ b/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/JukaWarrior.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles public class JukaWarrior : BaseCreature { [Constructible] - public JukaWarrior() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public JukaWarrior() : base(AIType.AI_Melee) { Body = 764; diff --git a/Projects/UOContent/Mobiles/Monsters/LBR/Meers/EnragedCreatures.cs b/Projects/UOContent/Mobiles/Monsters/LBR/Meers/EnragedCreatures.cs index d6b4fbfb6..cb3996be4 100644 --- a/Projects/UOContent/Mobiles/Monsters/LBR/Meers/EnragedCreatures.cs +++ b/Projects/UOContent/Mobiles/Monsters/LBR/Meers/EnragedCreatures.cs @@ -151,7 +151,7 @@ namespace Server.Mobiles public class BaseEnraged : BaseCreature { public BaseEnraged(Mobile summoner) - : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + : base(AIType.AI_Melee) { SetStr(50, 200); SetDex(50, 200); diff --git a/Projects/UOContent/Mobiles/Monsters/LBR/Meers/MeerCaptain.cs b/Projects/UOContent/Mobiles/Monsters/LBR/Meers/MeerCaptain.cs index 0cbe3214b..6be4fcdc7 100644 --- a/Projects/UOContent/Mobiles/Monsters/LBR/Meers/MeerCaptain.cs +++ b/Projects/UOContent/Mobiles/Monsters/LBR/Meers/MeerCaptain.cs @@ -9,7 +9,7 @@ namespace Server.Mobiles private DateTime m_NextAbilityTime; [Constructible] - public MeerCaptain() : base(AIType.AI_Archer, FightMode.Evil, 10, 1, 0.2, 0.4) + public MeerCaptain() : base(AIType.AI_Archer, FightMode.Evil) { Body = 773; diff --git a/Projects/UOContent/Mobiles/Monsters/LBR/Meers/MeerEternal.cs b/Projects/UOContent/Mobiles/Monsters/LBR/Meers/MeerEternal.cs index feb53f272..d7f064620 100644 --- a/Projects/UOContent/Mobiles/Monsters/LBR/Meers/MeerEternal.cs +++ b/Projects/UOContent/Mobiles/Monsters/LBR/Meers/MeerEternal.cs @@ -8,7 +8,7 @@ namespace Server.Mobiles private DateTime m_NextAbilityTime; [Constructible] - public MeerEternal() : base(AIType.AI_Mage, FightMode.Evil, 10, 1, 0.2, 0.4) + public MeerEternal() : base(AIType.AI_Mage, FightMode.Evil) { Body = 772; diff --git a/Projects/UOContent/Mobiles/Monsters/LBR/Meers/MeerMage.cs b/Projects/UOContent/Mobiles/Monsters/LBR/Meers/MeerMage.cs index 3d171a090..ce509df11 100644 --- a/Projects/UOContent/Mobiles/Monsters/LBR/Meers/MeerMage.cs +++ b/Projects/UOContent/Mobiles/Monsters/LBR/Meers/MeerMage.cs @@ -12,7 +12,7 @@ namespace Server.Mobiles private DateTime m_NextAbilityTime; [Constructible] - public MeerMage() : base(AIType.AI_Mage, FightMode.Evil, 10, 1, 0.2, 0.4) + public MeerMage() : base(AIType.AI_Mage, FightMode.Evil) { Body = 770; diff --git a/Projects/UOContent/Mobiles/Monsters/LBR/Meers/MeerWarrior.cs b/Projects/UOContent/Mobiles/Monsters/LBR/Meers/MeerWarrior.cs index 5019d678f..c56872294 100644 --- a/Projects/UOContent/Mobiles/Monsters/LBR/Meers/MeerWarrior.cs +++ b/Projects/UOContent/Mobiles/Monsters/LBR/Meers/MeerWarrior.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles public class MeerWarrior : BaseCreature { [Constructible] - public MeerWarrior() : base(AIType.AI_Melee, FightMode.Evil, 10, 1, 0.2, 0.4) + public MeerWarrior() : base(AIType.AI_Melee, FightMode.Evil) { Body = 771; diff --git a/Projects/UOContent/Mobiles/Monsters/ML/Animal/CuSidhe.cs b/Projects/UOContent/Mobiles/Monsters/ML/Animal/CuSidhe.cs index ff7c2ff5f..a06b0fa9f 100644 --- a/Projects/UOContent/Mobiles/Monsters/ML/Animal/CuSidhe.cs +++ b/Projects/UOContent/Mobiles/Monsters/ML/Animal/CuSidhe.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class CuSidhe : BaseMount { [Constructible] - public CuSidhe(string name = null) : base(name, 277, 0x3E91, AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public CuSidhe(string name = null) : base(name, 277, 0x3E91, AIType.AI_Animal, FightMode.Aggressor, 10, 1) { var chance = Utility.RandomDouble() * 23301; diff --git a/Projects/UOContent/Mobiles/Monsters/ML/Animal/Ferret.cs b/Projects/UOContent/Mobiles/Monsters/ML/Animal/Ferret.cs index cb578515f..413886152 100644 --- a/Projects/UOContent/Mobiles/Monsters/ML/Animal/Ferret.cs +++ b/Projects/UOContent/Mobiles/Monsters/ML/Animal/Ferret.cs @@ -15,7 +15,7 @@ namespace Server.Mobiles private bool m_CanTalk; [Constructible] - public Ferret() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public Ferret() : base(AIType.AI_Animal, FightMode.Aggressor) { Body = 0x117; diff --git a/Projects/UOContent/Mobiles/Monsters/ML/Animal/RagingGrizzlyBear.cs b/Projects/UOContent/Mobiles/Monsters/ML/Animal/RagingGrizzlyBear.cs index dfceeec83..d02acc83e 100644 --- a/Projects/UOContent/Mobiles/Monsters/ML/Animal/RagingGrizzlyBear.cs +++ b/Projects/UOContent/Mobiles/Monsters/ML/Animal/RagingGrizzlyBear.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class RagingGrizzlyBear : BaseCreature { [Constructible] - public RagingGrizzlyBear() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public RagingGrizzlyBear() : base(AIType.AI_Animal, FightMode.Aggressor) { Body = 212; BaseSoundID = 0xA3; diff --git a/Projects/UOContent/Mobiles/Monsters/ML/Animal/Squirrel.cs b/Projects/UOContent/Mobiles/Monsters/ML/Animal/Squirrel.cs index a94614772..1749f7d73 100644 --- a/Projects/UOContent/Mobiles/Monsters/ML/Animal/Squirrel.cs +++ b/Projects/UOContent/Mobiles/Monsters/ML/Animal/Squirrel.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class Squirrel : BaseCreature { [Constructible] - public Squirrel() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public Squirrel() : base(AIType.AI_Animal, FightMode.Aggressor) { Body = 0x116; diff --git a/Projects/UOContent/Mobiles/Monsters/ML/Blighted Grove/Hydra.cs b/Projects/UOContent/Mobiles/Monsters/ML/Blighted Grove/Hydra.cs index 6a8b5c609..b4b5e06f9 100644 --- a/Projects/UOContent/Mobiles/Monsters/ML/Blighted Grove/Hydra.cs +++ b/Projects/UOContent/Mobiles/Monsters/ML/Blighted Grove/Hydra.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles { [Constructible] public Hydra() - : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + : base(AIType.AI_Melee) { Body = 0x109; BaseSoundID = 0x16A; @@ -67,7 +67,7 @@ namespace Server.Mobiles // TODO: uncomment once added if (Utility.RandomDouble() < 0.2) c.DropItem( new ParrotItem() ); - + if (Utility.RandomDouble() < 0.05) c.DropItem( new ThorvaldsMedallion() ); */ diff --git a/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Magic/FetidEssence.cs b/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Magic/FetidEssence.cs index d5fd88ad8..59f9fdf57 100644 --- a/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Magic/FetidEssence.cs +++ b/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Magic/FetidEssence.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class FetidEssence : BaseCreature { [Constructible] - public FetidEssence() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public FetidEssence() : base(AIType.AI_Mage) { Body = 273; diff --git a/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Magic/InterredGrizzle .cs b/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Magic/InterredGrizzle .cs index 4b6df14d4..216656535 100644 --- a/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Magic/InterredGrizzle .cs +++ b/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Magic/InterredGrizzle .cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class InterredGrizzle : BaseCreature { [Constructible] - public InterredGrizzle() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public InterredGrizzle() : base(AIType.AI_Mage) { Body = 259; diff --git a/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Magic/MLDryad.cs b/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Magic/MLDryad.cs index d3a1589ae..e5175f0b7 100644 --- a/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Magic/MLDryad.cs +++ b/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Magic/MLDryad.cs @@ -10,7 +10,7 @@ namespace Server.Mobiles private DateTime m_NextUndress; [Constructible] - public MLDryad() : base(AIType.AI_Mage, FightMode.Evil, 10, 1, 0.2, 0.4) + public MLDryad() : base(AIType.AI_Mage, FightMode.Evil) { Body = 266; BaseSoundID = 0x57B; diff --git a/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Magic/Satyr.cs b/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Magic/Satyr.cs index 38ff955e2..c67242b21 100644 --- a/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Magic/Satyr.cs +++ b/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Magic/Satyr.cs @@ -15,7 +15,7 @@ namespace Server.Mobiles private DateTime m_NextUndress; [Constructible] - public Satyr() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public Satyr() : base(AIType.AI_Animal, FightMode.Aggressor) { Body = 271; BaseSoundID = 0x586; diff --git a/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Melee/CorruptedSoul.cs b/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Melee/CorruptedSoul.cs index 9c1ab08a5..5fe6bb7b5 100644 --- a/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Melee/CorruptedSoul.cs +++ b/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Melee/CorruptedSoul.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class CorruptedSoul : BaseCreature { [Constructible] - public CorruptedSoul() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, .1, 5) + public CorruptedSoul() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.1, 5) { Body = 0x3CA; Hue = 0x453; diff --git a/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Melee/FeralTreefellow.cs b/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Melee/FeralTreefellow.cs index f375eeb4e..9dd6f72ab 100644 --- a/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Melee/FeralTreefellow.cs +++ b/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Melee/FeralTreefellow.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles public class FeralTreefellow : BaseCreature { [Constructible] - public FeralTreefellow() : base(AIType.AI_Melee, FightMode.Evil, 10, 1, 0.2, 0.4) + public FeralTreefellow() : base(AIType.AI_Melee, FightMode.Evil) { Body = 301; diff --git a/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Melee/Minotaur.cs b/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Melee/Minotaur.cs index 7fb8be852..3df0abe45 100644 --- a/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Melee/Minotaur.cs +++ b/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Melee/Minotaur.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class Minotaur : BaseCreature { [Constructible] - public Minotaur() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) // NEED TO CHECK + public Minotaur() : base(AIType.AI_Melee) // NEED TO CHECK { Body = 263; diff --git a/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Melee/MinotaurCaptain.cs b/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Melee/MinotaurCaptain.cs index 701dd75a7..8bf35b72e 100644 --- a/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Melee/MinotaurCaptain.cs +++ b/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Melee/MinotaurCaptain.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class MinotaurCaptain : BaseCreature { [Constructible] - public MinotaurCaptain() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) // NEED TO CHECK + public MinotaurCaptain() : base(AIType.AI_Melee) // NEED TO CHECK { Body = 280; diff --git a/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Melee/MinotaurScout.cs b/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Melee/MinotaurScout.cs index ca8842240..e61b6de4d 100644 --- a/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Melee/MinotaurScout.cs +++ b/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Melee/MinotaurScout.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class MinotaurScout : BaseCreature { [Constructible] - public MinotaurScout() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) // NEED TO CHECK + public MinotaurScout() : base(AIType.AI_Melee) // NEED TO CHECK { Body = 281; diff --git a/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Melee/PestilentBandage.cs b/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Melee/PestilentBandage.cs index 321dd1f10..abe05b461 100644 --- a/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Melee/PestilentBandage.cs +++ b/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Melee/PestilentBandage.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class PestilentBandage : BaseCreature { [Constructible] - public PestilentBandage() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) // NEED TO CHECK + public PestilentBandage() : base(AIType.AI_Melee) // NEED TO CHECK { Body = 154; Hue = 0x515; diff --git a/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Melee/Tormented Minotaur.cs b/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Melee/Tormented Minotaur.cs index 25cbf5d27..703960d84 100644 --- a/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Melee/Tormented Minotaur.cs +++ b/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Melee/Tormented Minotaur.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class TormentedMinotaur : BaseCreature { [Constructible] - public TormentedMinotaur() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public TormentedMinotaur() : base(AIType.AI_Melee) { Body = 262; diff --git a/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Melee/Troglodyte.cs b/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Melee/Troglodyte.cs index e47f077c2..b2bfcffa1 100644 --- a/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Melee/Troglodyte.cs +++ b/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Melee/Troglodyte.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class Troglodyte : BaseCreature { [Constructible] - public Troglodyte() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) // NEED TO CHECK + public Troglodyte() : base(AIType.AI_Melee) // NEED TO CHECK { Body = 267; BaseSoundID = 0x59F; diff --git a/Projects/UOContent/Mobiles/Monsters/ML/Misc/Magic/GreaterDragon.cs b/Projects/UOContent/Mobiles/Monsters/ML/Misc/Magic/GreaterDragon.cs index d62c27d4f..671c1925f 100644 --- a/Projects/UOContent/Mobiles/Monsters/ML/Misc/Magic/GreaterDragon.cs +++ b/Projects/UOContent/Mobiles/Monsters/ML/Misc/Magic/GreaterDragon.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles public class GreaterDragon : BaseCreature { [Constructible] - public GreaterDragon() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.3, 0.5) + public GreaterDragon() : base(AIType.AI_Mage) { Body = Utility.RandomList(12, 59); BaseSoundID = 362; diff --git a/Projects/UOContent/Mobiles/Monsters/ML/Misc/Melee/CorrosiveSlime.cs b/Projects/UOContent/Mobiles/Monsters/ML/Misc/Melee/CorrosiveSlime.cs index b54b44d78..b30c65035 100644 --- a/Projects/UOContent/Mobiles/Monsters/ML/Misc/Melee/CorrosiveSlime.cs +++ b/Projects/UOContent/Mobiles/Monsters/ML/Misc/Melee/CorrosiveSlime.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class CorrosiveSlime : BaseCreature { [Constructible] - public CorrosiveSlime() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public CorrosiveSlime() : base(AIType.AI_Melee) { Body = 51; BaseSoundID = 456; diff --git a/Projects/UOContent/Mobiles/Monsters/ML/Prism of Light/CorporealBrume.cs b/Projects/UOContent/Mobiles/Monsters/ML/Prism of Light/CorporealBrume.cs index 0c6c772c5..31a16b7dd 100644 --- a/Projects/UOContent/Mobiles/Monsters/ML/Prism of Light/CorporealBrume.cs +++ b/Projects/UOContent/Mobiles/Monsters/ML/Prism of Light/CorporealBrume.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles { [Constructible] public CorporealBrume() - : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + : base(AIType.AI_Melee) { Body = 0x104; // TODO: Verify BaseSoundID = 0x56B; diff --git a/Projects/UOContent/Mobiles/Monsters/ML/Prism of Light/CrystalDaemon.cs b/Projects/UOContent/Mobiles/Monsters/ML/Prism of Light/CrystalDaemon.cs index b2e6726a5..a77d90e36 100644 --- a/Projects/UOContent/Mobiles/Monsters/ML/Prism of Light/CrystalDaemon.cs +++ b/Projects/UOContent/Mobiles/Monsters/ML/Prism of Light/CrystalDaemon.cs @@ -4,7 +4,7 @@ namespace Server.Mobiles { [Constructible] public CrystalDaemon() - : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + : base(AIType.AI_Mage) { Body = 0x310; Hue = 0x3E8; @@ -46,7 +46,7 @@ namespace Server.Mobiles public override void OnDeath( Container c ) { base.OnDeath( c ); - + if (Utility.RandomDouble() < 0.4) c.DropItem( new ScatteredCrystals() ); } diff --git a/Projects/UOContent/Mobiles/Monsters/ML/Prism of Light/CrystalLatticeSeeker.cs b/Projects/UOContent/Mobiles/Monsters/ML/Prism of Light/CrystalLatticeSeeker.cs index c0af63279..20f7859ef 100644 --- a/Projects/UOContent/Mobiles/Monsters/ML/Prism of Light/CrystalLatticeSeeker.cs +++ b/Projects/UOContent/Mobiles/Monsters/ML/Prism of Light/CrystalLatticeSeeker.cs @@ -4,7 +4,7 @@ namespace Server.Mobiles { [Constructible] public CrystalLatticeSeeker() - : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + : base(AIType.AI_Mage) { Body = 0x7B; Hue = 0x47E; @@ -52,10 +52,10 @@ namespace Server.Mobiles public override void OnDeath( Container c ) { base.OnDeath( c ); - + if (Utility.RandomDouble() < 0.75) c.DropItem( new CrystallineFragments() ); - + if (Utility.RandomDouble() < 0.07) c.DropItem( new PiecesOfCrystal() ); } diff --git a/Projects/UOContent/Mobiles/Monsters/ML/Prism of Light/CrystalVortex.cs b/Projects/UOContent/Mobiles/Monsters/ML/Prism of Light/CrystalVortex.cs index e20773064..b2c70f1c0 100644 --- a/Projects/UOContent/Mobiles/Monsters/ML/Prism of Light/CrystalVortex.cs +++ b/Projects/UOContent/Mobiles/Monsters/ML/Prism of Light/CrystalVortex.cs @@ -4,7 +4,7 @@ namespace Server.Mobiles { [Constructible] public CrystalVortex() - : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + : base(AIType.AI_Melee) { Body = 0xD; Hue = 0x2B2; @@ -59,10 +59,10 @@ namespace Server.Mobiles public override void OnDeath( Container c ) { base.OnDeath( c ); - + if (Utility.RandomDouble() < 0.75) c.DropItem( new CrystallineFragments() ); - + if (Utility.RandomDouble() < 0.06) c.DropItem( new JaggedCrystals() ); } diff --git a/Projects/UOContent/Mobiles/Monsters/ML/Prism of Light/MantraEffervescence.cs b/Projects/UOContent/Mobiles/Monsters/ML/Prism of Light/MantraEffervescence.cs index d1a0f67b2..7b6904de1 100644 --- a/Projects/UOContent/Mobiles/Monsters/ML/Prism of Light/MantraEffervescence.cs +++ b/Projects/UOContent/Mobiles/Monsters/ML/Prism of Light/MantraEffervescence.cs @@ -4,7 +4,7 @@ namespace Server.Mobiles { [Constructible] public MantraEffervescence() - : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + : base(AIType.AI_Mage) { Body = 0x111; BaseSoundID = 0x56E; diff --git a/Projects/UOContent/Mobiles/Monsters/ML/Prism of Light/Protector.cs b/Projects/UOContent/Mobiles/Monsters/ML/Prism of Light/Protector.cs index 6b57008a1..88abdc8c4 100644 --- a/Projects/UOContent/Mobiles/Monsters/ML/Prism of Light/Protector.cs +++ b/Projects/UOContent/Mobiles/Monsters/ML/Prism of Light/Protector.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles { [Constructible] public Protector() - : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + : base(AIType.AI_Melee) { Body = 401; Female = true; @@ -86,7 +86,7 @@ namespace Server.Mobiles public override void OnDeath( Container c ) { base.OnDeath( c ); - + if (Utility.RandomDouble() < 0.4) c.DropItem( new ProtectorsEssence() ); } diff --git a/Projects/UOContent/Mobiles/Monsters/ML/Prism of Light/UnfrozenMummy.cs b/Projects/UOContent/Mobiles/Monsters/ML/Prism of Light/UnfrozenMummy.cs index 56ca7f095..453a7fdf4 100644 --- a/Projects/UOContent/Mobiles/Monsters/ML/Prism of Light/UnfrozenMummy.cs +++ b/Projects/UOContent/Mobiles/Monsters/ML/Prism of Light/UnfrozenMummy.cs @@ -4,7 +4,7 @@ namespace Server.Mobiles { [Constructible] public UnfrozenMummy() - : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.4, 0.8) + : base(AIType.AI_Mage) { Body = 0x9B; Hue = 0x480; @@ -46,10 +46,10 @@ namespace Server.Mobiles public override void OnDeath( Container c ) { base.OnDeath( c ); - + if (Utility.RandomDouble() < 0.6) c.DropItem( new BrokenCrystals() ); - + if (Utility.RandomDouble() < 0.1) c.DropItem( new ParrotItem() ); } diff --git a/Projects/UOContent/Mobiles/Monsters/ML/Twisted Weald/Changeling.cs b/Projects/UOContent/Mobiles/Monsters/ML/Twisted Weald/Changeling.cs index c57b62524..5a14803c2 100644 --- a/Projects/UOContent/Mobiles/Monsters/ML/Twisted Weald/Changeling.cs +++ b/Projects/UOContent/Mobiles/Monsters/ML/Twisted Weald/Changeling.cs @@ -27,7 +27,7 @@ namespace Server.Mobiles [Constructible] public Changeling() - : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + : base(AIType.AI_Mage) { Body = 264; Hue = DefaultHue; diff --git a/Projects/UOContent/Mobiles/Monsters/Mammal/Melee/HellHound.cs b/Projects/UOContent/Mobiles/Monsters/Mammal/Melee/HellHound.cs index d98775042..9c9942d45 100644 --- a/Projects/UOContent/Mobiles/Monsters/Mammal/Melee/HellHound.cs +++ b/Projects/UOContent/Mobiles/Monsters/Mammal/Melee/HellHound.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class HellHound : BaseCreature { [Constructible] - public HellHound() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public HellHound() : base(AIType.AI_Melee) { Body = 98; BaseSoundID = 229; diff --git a/Projects/UOContent/Mobiles/Monsters/Mammal/Melee/VorpalBunny.cs b/Projects/UOContent/Mobiles/Monsters/Mammal/Melee/VorpalBunny.cs index c386b5cae..c62860bca 100644 --- a/Projects/UOContent/Mobiles/Monsters/Mammal/Melee/VorpalBunny.cs +++ b/Projects/UOContent/Mobiles/Monsters/Mammal/Melee/VorpalBunny.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles public class VorpalBunny : BaseCreature { [Constructible] - public VorpalBunny() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public VorpalBunny() : base(AIType.AI_Melee) { Body = 205; Hue = 0x480; diff --git a/Projects/UOContent/Mobiles/Monsters/Misc/Magic/DarkWisp.cs b/Projects/UOContent/Mobiles/Monsters/Misc/Magic/DarkWisp.cs index 0bbb5ee34..4dc452690 100644 --- a/Projects/UOContent/Mobiles/Monsters/Misc/Magic/DarkWisp.cs +++ b/Projects/UOContent/Mobiles/Monsters/Misc/Magic/DarkWisp.cs @@ -8,7 +8,7 @@ namespace Server.Mobiles public class DarkWisp : BaseCreature { [Constructible] - public DarkWisp() : base(AIType.AI_Mage, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public DarkWisp() : base(AIType.AI_Mage, FightMode.Aggressor) { Body = 165; BaseSoundID = 466; diff --git a/Projects/UOContent/Mobiles/Monsters/Misc/Magic/EtherealWarrior.cs b/Projects/UOContent/Mobiles/Monsters/Misc/Magic/EtherealWarrior.cs index 1a1317ea0..f09582850 100644 --- a/Projects/UOContent/Mobiles/Monsters/Misc/Magic/EtherealWarrior.cs +++ b/Projects/UOContent/Mobiles/Monsters/Misc/Magic/EtherealWarrior.cs @@ -10,7 +10,7 @@ namespace Server.Mobiles private DateTime m_NextResurrect; [Constructible] - public EtherealWarrior() : base(AIType.AI_Mage, FightMode.Evil, 10, 1, 0.2, 0.4) + public EtherealWarrior() : base(AIType.AI_Mage, FightMode.Evil) { Name = NameList.RandomName("ethereal warrior"); Body = 123; diff --git a/Projects/UOContent/Mobiles/Monsters/Misc/Magic/Pixie.cs b/Projects/UOContent/Mobiles/Monsters/Misc/Magic/Pixie.cs index 245d76f30..abacd88f5 100644 --- a/Projects/UOContent/Mobiles/Monsters/Misc/Magic/Pixie.cs +++ b/Projects/UOContent/Mobiles/Monsters/Misc/Magic/Pixie.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class Pixie : BaseCreature { [Constructible] - public Pixie() : base(AIType.AI_Mage, FightMode.Evil, 10, 1, 0.2, 0.4) + public Pixie() : base(AIType.AI_Mage, FightMode.Evil) { Name = NameList.RandomName("pixie"); Body = 128; diff --git a/Projects/UOContent/Mobiles/Monsters/Misc/Magic/ShadowWisp.cs b/Projects/UOContent/Mobiles/Monsters/Misc/Magic/ShadowWisp.cs index 451acc6d8..b88b25c73 100644 --- a/Projects/UOContent/Mobiles/Monsters/Misc/Magic/ShadowWisp.cs +++ b/Projects/UOContent/Mobiles/Monsters/Misc/Magic/ShadowWisp.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class ShadowWisp : BaseCreature { [Constructible] - public ShadowWisp() : base(AIType.AI_Mage, FightMode.Aggressor, 10, 1, 0.3, 0.6) + public ShadowWisp() : base(AIType.AI_Mage, FightMode.Aggressor, 10, 1, 0.25, 0.5) { Body = 165; BaseSoundID = 466; diff --git a/Projects/UOContent/Mobiles/Monsters/Misc/Magic/Wisp.cs b/Projects/UOContent/Mobiles/Monsters/Misc/Magic/Wisp.cs index 613b6b574..b4122c834 100644 --- a/Projects/UOContent/Mobiles/Monsters/Misc/Magic/Wisp.cs +++ b/Projects/UOContent/Mobiles/Monsters/Misc/Magic/Wisp.cs @@ -10,7 +10,7 @@ namespace Server.Mobiles public class Wisp : BaseCreature { [Constructible] - public Wisp() : base(AIType.AI_Mage, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public Wisp() : base(AIType.AI_Mage, FightMode.Aggressor) { Body = 58; BaseSoundID = 466; diff --git a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/Centaur.cs b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/Centaur.cs index 7ac9b6286..4df4c37ef 100644 --- a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/Centaur.cs +++ b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/Centaur.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class Centaur : BaseCreature { [Constructible] - public Centaur() : base(AIType.AI_Melee, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public Centaur() : base(AIType.AI_Melee, FightMode.Aggressor) { Name = NameList.RandomName("centaur"); Body = 101; diff --git a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/EnergyVortex.cs b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/EnergyVortex.cs index a69586bc3..ae7a1517b 100644 --- a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/EnergyVortex.cs +++ b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/EnergyVortex.cs @@ -7,7 +7,7 @@ namespace Server.Mobiles { [Constructible] public EnergyVortex() - : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + : base(AIType.AI_Melee) { if (Core.SE && Utility.RandomDouble() < 0.002) // Per OSI FoF, it's a 1/500 chance. { diff --git a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/FrostOoze.cs b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/FrostOoze.cs index b4e4e5577..52e5704aa 100644 --- a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/FrostOoze.cs +++ b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/FrostOoze.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class FrostOoze : BaseCreature { [Constructible] - public FrostOoze() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public FrostOoze() : base(AIType.AI_Melee) { Body = 94; BaseSoundID = 456; diff --git a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/PlagueBeast.cs b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/PlagueBeast.cs index 263e86462..aec74b455 100644 --- a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/PlagueBeast.cs +++ b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/PlagueBeast.cs @@ -10,7 +10,7 @@ namespace Server.Mobiles private int m_DevourGoal; [Constructible] - public PlagueBeast() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public PlagueBeast() : base(AIType.AI_Melee) { Body = 775; diff --git a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/PlagueBeastLord.cs b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/PlagueBeastLord.cs index 0e69a4bb1..bd71a9d14 100644 --- a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/PlagueBeastLord.cs +++ b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/PlagueBeastLord.cs @@ -9,7 +9,7 @@ namespace Server.Mobiles private DecayTimer m_Timer; [Constructible] - public PlagueBeastLord() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public PlagueBeastLord() : base(AIType.AI_Melee) { Body = 775; BaseSoundID = 679; diff --git a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/PlagueSpawn.cs b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/PlagueSpawn.cs index e1ca92246..856dd233c 100644 --- a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/PlagueSpawn.cs +++ b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/PlagueSpawn.cs @@ -7,7 +7,7 @@ namespace Server.Mobiles public class PlagueSpawn : BaseCreature { [Constructible] - public PlagueSpawn(Mobile owner = null) : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public PlagueSpawn(Mobile owner = null) : base(AIType.AI_Melee) { Owner = owner; ExpireTime = Core.Now + TimeSpan.FromMinutes(1.0); diff --git a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/SandVortex.cs b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/SandVortex.cs index 6674e685e..289149080 100644 --- a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/SandVortex.cs +++ b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/SandVortex.cs @@ -8,7 +8,7 @@ namespace Server.Mobiles private DateTime m_NextAttack; [Constructible] - public SandVortex() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public SandVortex() : base(AIType.AI_Melee) { Body = 790; BaseSoundID = 263; diff --git a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/Slime.cs b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/Slime.cs index 1ba5420a2..5e43b8a29 100644 --- a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/Slime.cs +++ b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/Slime.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class Slime : BaseCreature { [Constructible] - public Slime() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public Slime() : base(AIType.AI_Melee) { Body = 51; BaseSoundID = 456; diff --git a/Projects/UOContent/Mobiles/Monsters/Ore Elementals/AgapiteElemental.cs b/Projects/UOContent/Mobiles/Monsters/Ore Elementals/AgapiteElemental.cs index 600e7f2b2..4afc602e6 100644 --- a/Projects/UOContent/Mobiles/Monsters/Ore Elementals/AgapiteElemental.cs +++ b/Projects/UOContent/Mobiles/Monsters/Ore Elementals/AgapiteElemental.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class AgapiteElemental : BaseCreature { [Constructible] - public AgapiteElemental(int oreAmount = 2) : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public AgapiteElemental(int oreAmount = 2) : base(AIType.AI_Melee) { Body = 107; BaseSoundID = 268; diff --git a/Projects/UOContent/Mobiles/Monsters/Ore Elementals/BronzeElemental.cs b/Projects/UOContent/Mobiles/Monsters/Ore Elementals/BronzeElemental.cs index a9da2c0f7..3ff35fc5d 100644 --- a/Projects/UOContent/Mobiles/Monsters/Ore Elementals/BronzeElemental.cs +++ b/Projects/UOContent/Mobiles/Monsters/Ore Elementals/BronzeElemental.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class BronzeElemental : BaseCreature { [Constructible] - public BronzeElemental(int oreAmount = 2) : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public BronzeElemental(int oreAmount = 2) : base(AIType.AI_Melee) { // TODO: Gas attack Body = 108; diff --git a/Projects/UOContent/Mobiles/Monsters/Ore Elementals/CopperElemental.cs b/Projects/UOContent/Mobiles/Monsters/Ore Elementals/CopperElemental.cs index 52c7319f4..e076e2c3f 100644 --- a/Projects/UOContent/Mobiles/Monsters/Ore Elementals/CopperElemental.cs +++ b/Projects/UOContent/Mobiles/Monsters/Ore Elementals/CopperElemental.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class CopperElemental : BaseCreature { [Constructible] - public CopperElemental(int oreAmount = 2) : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public CopperElemental(int oreAmount = 2) : base(AIType.AI_Melee) { Body = 109; BaseSoundID = 268; diff --git a/Projects/UOContent/Mobiles/Monsters/Ore Elementals/DullCopperElemental.cs b/Projects/UOContent/Mobiles/Monsters/Ore Elementals/DullCopperElemental.cs index 6ba9e2e5d..e5c12b5e4 100644 --- a/Projects/UOContent/Mobiles/Monsters/Ore Elementals/DullCopperElemental.cs +++ b/Projects/UOContent/Mobiles/Monsters/Ore Elementals/DullCopperElemental.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class DullCopperElemental : BaseCreature { [Constructible] - public DullCopperElemental(int oreAmount = 2) : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public DullCopperElemental(int oreAmount = 2) : base(AIType.AI_Melee) { Body = 110; BaseSoundID = 268; diff --git a/Projects/UOContent/Mobiles/Monsters/Ore Elementals/GoldenElemental.cs b/Projects/UOContent/Mobiles/Monsters/Ore Elementals/GoldenElemental.cs index b412dc8de..33efe5d66 100644 --- a/Projects/UOContent/Mobiles/Monsters/Ore Elementals/GoldenElemental.cs +++ b/Projects/UOContent/Mobiles/Monsters/Ore Elementals/GoldenElemental.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class GoldenElemental : BaseCreature { [Constructible] - public GoldenElemental(int oreAmount = 2) : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public GoldenElemental(int oreAmount = 2) : base(AIType.AI_Melee) { Body = 166; BaseSoundID = 268; diff --git a/Projects/UOContent/Mobiles/Monsters/Ore Elementals/ShadowIronElemental.cs b/Projects/UOContent/Mobiles/Monsters/Ore Elementals/ShadowIronElemental.cs index c3d4b32e2..41c978361 100644 --- a/Projects/UOContent/Mobiles/Monsters/Ore Elementals/ShadowIronElemental.cs +++ b/Projects/UOContent/Mobiles/Monsters/Ore Elementals/ShadowIronElemental.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class ShadowIronElemental : BaseCreature { [Constructible] - public ShadowIronElemental(int oreAmount = 2) : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public ShadowIronElemental(int oreAmount = 2) : base(AIType.AI_Melee) { Body = 111; BaseSoundID = 268; diff --git a/Projects/UOContent/Mobiles/Monsters/Ore Elementals/ValoriteElemental.cs b/Projects/UOContent/Mobiles/Monsters/Ore Elementals/ValoriteElemental.cs index 6c4654249..7bad63bfd 100644 --- a/Projects/UOContent/Mobiles/Monsters/Ore Elementals/ValoriteElemental.cs +++ b/Projects/UOContent/Mobiles/Monsters/Ore Elementals/ValoriteElemental.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class ValoriteElemental : BaseCreature { [Constructible] - public ValoriteElemental(int oreAmount = 2) : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public ValoriteElemental(int oreAmount = 2) : base(AIType.AI_Melee) { // TODO: Gas attack Body = 112; diff --git a/Projects/UOContent/Mobiles/Monsters/Ore Elementals/VeriteElemental.cs b/Projects/UOContent/Mobiles/Monsters/Ore Elementals/VeriteElemental.cs index 23ecc6a0e..8aaf413fc 100644 --- a/Projects/UOContent/Mobiles/Monsters/Ore Elementals/VeriteElemental.cs +++ b/Projects/UOContent/Mobiles/Monsters/Ore Elementals/VeriteElemental.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class VeriteElemental : BaseCreature { [Constructible] - public VeriteElemental(int oreAmount = 2) : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public VeriteElemental(int oreAmount = 2) : base(AIType.AI_Melee) { Body = 113; BaseSoundID = 268; diff --git a/Projects/UOContent/Mobiles/Monsters/Plant/Magic/Reaper.cs b/Projects/UOContent/Mobiles/Monsters/Plant/Magic/Reaper.cs index ce16242dc..66dc20fe8 100644 --- a/Projects/UOContent/Mobiles/Monsters/Plant/Magic/Reaper.cs +++ b/Projects/UOContent/Mobiles/Monsters/Plant/Magic/Reaper.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class Reaper : BaseCreature { [Constructible] - public Reaper() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public Reaper() : base(AIType.AI_Mage) { Body = 47; BaseSoundID = 442; diff --git a/Projects/UOContent/Mobiles/Monsters/Plant/Melee/BogThing.cs b/Projects/UOContent/Mobiles/Monsters/Plant/Melee/BogThing.cs index 8f7528997..5a05f47f6 100644 --- a/Projects/UOContent/Mobiles/Monsters/Plant/Melee/BogThing.cs +++ b/Projects/UOContent/Mobiles/Monsters/Plant/Melee/BogThing.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles public class BogThing : BaseCreature { [Constructible] - public BogThing() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.6, 1.2) + public BogThing() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.3, 0.6) { Body = 780; diff --git a/Projects/UOContent/Mobiles/Monsters/Plant/Melee/Bogling.cs b/Projects/UOContent/Mobiles/Monsters/Plant/Melee/Bogling.cs index acfc3cfae..f736e7563 100644 --- a/Projects/UOContent/Mobiles/Monsters/Plant/Melee/Bogling.cs +++ b/Projects/UOContent/Mobiles/Monsters/Plant/Melee/Bogling.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles public class Bogling : BaseCreature { [Constructible] - public Bogling() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public Bogling() : base(AIType.AI_Melee) { Body = 779; BaseSoundID = 422; diff --git a/Projects/UOContent/Mobiles/Monsters/Plant/Melee/Corpser.cs b/Projects/UOContent/Mobiles/Monsters/Plant/Melee/Corpser.cs index 16917fa89..5fa465692 100644 --- a/Projects/UOContent/Mobiles/Monsters/Plant/Melee/Corpser.cs +++ b/Projects/UOContent/Mobiles/Monsters/Plant/Melee/Corpser.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class Corpser : BaseCreature { [Constructible] - public Corpser() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public Corpser() : base(AIType.AI_Melee) { Body = 8; BaseSoundID = 684; diff --git a/Projects/UOContent/Mobiles/Monsters/Plant/Melee/Quagmire.cs b/Projects/UOContent/Mobiles/Monsters/Plant/Melee/Quagmire.cs index 851e8789d..b551b7d3f 100644 --- a/Projects/UOContent/Mobiles/Monsters/Plant/Melee/Quagmire.cs +++ b/Projects/UOContent/Mobiles/Monsters/Plant/Melee/Quagmire.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class Quagmire : BaseCreature { [Constructible] - public Quagmire() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.4, 0.8) + public Quagmire() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.3, 0.6) { Body = 789; BaseSoundID = 352; diff --git a/Projects/UOContent/Mobiles/Monsters/Plant/Melee/SwampTentacle.cs b/Projects/UOContent/Mobiles/Monsters/Plant/Melee/SwampTentacle.cs index 119bc2aa8..8f9b68779 100644 --- a/Projects/UOContent/Mobiles/Monsters/Plant/Melee/SwampTentacle.cs +++ b/Projects/UOContent/Mobiles/Monsters/Plant/Melee/SwampTentacle.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class SwampTentacle : BaseCreature { [Constructible] - public SwampTentacle() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public SwampTentacle() : base(AIType.AI_Melee) { Body = 66; BaseSoundID = 352; diff --git a/Projects/UOContent/Mobiles/Monsters/Plant/Melee/WhippingVine.cs b/Projects/UOContent/Mobiles/Monsters/Plant/Melee/WhippingVine.cs index fe57af0ba..8fdf40f0d 100644 --- a/Projects/UOContent/Mobiles/Monsters/Plant/Melee/WhippingVine.cs +++ b/Projects/UOContent/Mobiles/Monsters/Plant/Melee/WhippingVine.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class WhippingVine : BaseCreature { [Constructible] - public WhippingVine() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public WhippingVine() : base(AIType.AI_Melee) { Body = 8; Hue = 0x851; diff --git a/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/AncientWyrm.cs b/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/AncientWyrm.cs index 092ce3d13..d98ed9fb7 100644 --- a/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/AncientWyrm.cs +++ b/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/AncientWyrm.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class AncientWyrm : BaseCreature { [Constructible] - public AncientWyrm() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public AncientWyrm() : base(AIType.AI_Mage) { Body = 46; BaseSoundID = 362; diff --git a/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/DeepSeaSerpent.cs b/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/DeepSeaSerpent.cs index f96df532b..6d4d2dc50 100644 --- a/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/DeepSeaSerpent.cs +++ b/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/DeepSeaSerpent.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class DeepSeaSerpent : BaseCreature { [Constructible] - public DeepSeaSerpent() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public DeepSeaSerpent() : base(AIType.AI_Mage) { Body = 150; BaseSoundID = 447; diff --git a/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/Dragon.cs b/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/Dragon.cs index cfdd61f66..9847941cc 100644 --- a/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/Dragon.cs +++ b/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/Dragon.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class Dragon : BaseCreature { [Constructible] - public Dragon() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public Dragon() : base(AIType.AI_Mage) { Body = Utility.RandomList(12, 59); BaseSoundID = 362; diff --git a/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/Leviathan.cs b/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/Leviathan.cs index a66b989df..272b8a85c 100644 --- a/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/Leviathan.cs +++ b/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/Leviathan.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles public class Leviathan : BaseCreature { [Constructible] - public Leviathan(Mobile fisher = null) : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public Leviathan(Mobile fisher = null) : base(AIType.AI_Mage) { Fisher = fisher; diff --git a/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/OphidianArchmage.cs b/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/OphidianArchmage.cs index aee35bbdf..783d73265 100644 --- a/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/OphidianArchmage.cs +++ b/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/OphidianArchmage.cs @@ -10,7 +10,7 @@ namespace Server.Mobiles }; [Constructible] - public OphidianArchmage() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public OphidianArchmage() : base(AIType.AI_Mage) { Name = m_Names.RandomElement(); Body = 85; diff --git a/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/OphidianMage.cs b/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/OphidianMage.cs index ddbe1ad58..e1964962e 100644 --- a/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/OphidianMage.cs +++ b/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/OphidianMage.cs @@ -10,7 +10,7 @@ namespace Server.Mobiles }; [Constructible] - public OphidianMage() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public OphidianMage() : base(AIType.AI_Mage) { Name = m_Names.RandomElement(); Body = 85; diff --git a/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/OphidianMatriarch.cs b/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/OphidianMatriarch.cs index 4847acc1d..3da099941 100644 --- a/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/OphidianMatriarch.cs +++ b/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/OphidianMatriarch.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class OphidianMatriarch : BaseCreature { [Constructible] - public OphidianMatriarch() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public OphidianMatriarch() : base(AIType.AI_Mage) { Body = 87; BaseSoundID = 644; diff --git a/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/SeaSerpent.cs b/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/SeaSerpent.cs index e142dfb0b..8fe8eca12 100644 --- a/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/SeaSerpent.cs +++ b/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/SeaSerpent.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles public class SeaSerpent : BaseCreature { [Constructible] - public SeaSerpent() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public SeaSerpent() : base(AIType.AI_Mage) { Body = 150; BaseSoundID = 447; diff --git a/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/SerpentineDragon.cs b/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/SerpentineDragon.cs index 16e103d6f..0da6c0d54 100644 --- a/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/SerpentineDragon.cs +++ b/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/SerpentineDragon.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class SerpentineDragon : BaseCreature { [Constructible] - public SerpentineDragon() : base(AIType.AI_Mage, FightMode.Evil, 10, 1, 0.2, 0.4) + public SerpentineDragon() : base(AIType.AI_Mage, FightMode.Evil) { Body = 103; BaseSoundID = 362; diff --git a/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/ShadowWyrm.cs b/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/ShadowWyrm.cs index 3043112b4..dae5c0e0b 100644 --- a/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/ShadowWyrm.cs +++ b/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/ShadowWyrm.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class ShadowWyrm : BaseCreature { [Constructible] - public ShadowWyrm() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public ShadowWyrm() : base(AIType.AI_Mage) { Body = 106; BaseSoundID = 362; diff --git a/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/SkeletalDragon.cs b/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/SkeletalDragon.cs index 1ca9c3303..646aafd59 100644 --- a/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/SkeletalDragon.cs +++ b/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/SkeletalDragon.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class SkeletalDragon : BaseCreature { [Constructible] - public SkeletalDragon() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public SkeletalDragon() : base(AIType.AI_Mage) { Body = 104; BaseSoundID = 0x488; diff --git a/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/WhiteWyrm.cs b/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/WhiteWyrm.cs index a3bb53046..37524dbe6 100644 --- a/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/WhiteWyrm.cs +++ b/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/WhiteWyrm.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class WhiteWyrm : BaseCreature { [Constructible] - public WhiteWyrm() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public WhiteWyrm() : base(AIType.AI_Mage) { Body = Utility.RandomBool() ? 180 : 49; BaseSoundID = 362; diff --git a/Projects/UOContent/Mobiles/Monsters/Reptile/Melee/Drake.cs b/Projects/UOContent/Mobiles/Monsters/Reptile/Melee/Drake.cs index 2b4af117b..ff14ed9c0 100644 --- a/Projects/UOContent/Mobiles/Monsters/Reptile/Melee/Drake.cs +++ b/Projects/UOContent/Mobiles/Monsters/Reptile/Melee/Drake.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class Drake : BaseCreature { [Constructible] - public Drake() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public Drake() : base(AIType.AI_Melee) { Body = Utility.RandomList(60, 61); BaseSoundID = 362; diff --git a/Projects/UOContent/Mobiles/Monsters/Reptile/Melee/Harpy.cs b/Projects/UOContent/Mobiles/Monsters/Reptile/Melee/Harpy.cs index fe6ca4a7d..c3c490f84 100644 --- a/Projects/UOContent/Mobiles/Monsters/Reptile/Melee/Harpy.cs +++ b/Projects/UOContent/Mobiles/Monsters/Reptile/Melee/Harpy.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class Harpy : BaseCreature { [Constructible] - public Harpy() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public Harpy() : base(AIType.AI_Melee) { Body = 30; BaseSoundID = 402; diff --git a/Projects/UOContent/Mobiles/Monsters/Reptile/Melee/Kraken.cs b/Projects/UOContent/Mobiles/Monsters/Reptile/Melee/Kraken.cs index 119930286..19f3281a2 100644 --- a/Projects/UOContent/Mobiles/Monsters/Reptile/Melee/Kraken.cs +++ b/Projects/UOContent/Mobiles/Monsters/Reptile/Melee/Kraken.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class Kraken : BaseCreature { [Constructible] - public Kraken() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public Kraken() : base(AIType.AI_Melee) { Body = 77; BaseSoundID = 353; diff --git a/Projects/UOContent/Mobiles/Monsters/Reptile/Melee/Lizardman.cs b/Projects/UOContent/Mobiles/Monsters/Reptile/Melee/Lizardman.cs index 7b79bf063..b8fd3ee4f 100644 --- a/Projects/UOContent/Mobiles/Monsters/Reptile/Melee/Lizardman.cs +++ b/Projects/UOContent/Mobiles/Monsters/Reptile/Melee/Lizardman.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class Lizardman : BaseCreature { [Constructible] - public Lizardman() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public Lizardman() : base(AIType.AI_Melee) { Name = NameList.RandomName("lizardman"); Body = Utility.RandomList(35, 36); diff --git a/Projects/UOContent/Mobiles/Monsters/Reptile/Melee/OphidianKnight.cs b/Projects/UOContent/Mobiles/Monsters/Reptile/Melee/OphidianKnight.cs index f530a516e..90a1b36e9 100644 --- a/Projects/UOContent/Mobiles/Monsters/Reptile/Melee/OphidianKnight.cs +++ b/Projects/UOContent/Mobiles/Monsters/Reptile/Melee/OphidianKnight.cs @@ -12,7 +12,7 @@ namespace Server.Mobiles }; [Constructible] - public OphidianKnight() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public OphidianKnight() : base(AIType.AI_Melee) { Name = m_Names.RandomElement(); Body = 86; diff --git a/Projects/UOContent/Mobiles/Monsters/Reptile/Melee/OphidianWarrior.cs b/Projects/UOContent/Mobiles/Monsters/Reptile/Melee/OphidianWarrior.cs index 5a76ecb86..afce1e001 100644 --- a/Projects/UOContent/Mobiles/Monsters/Reptile/Melee/OphidianWarrior.cs +++ b/Projects/UOContent/Mobiles/Monsters/Reptile/Melee/OphidianWarrior.cs @@ -9,7 +9,7 @@ namespace Server.Mobiles }; [Constructible] - public OphidianWarrior() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public OphidianWarrior() : base(AIType.AI_Melee) { Name = m_Names.RandomElement(); Body = 86; diff --git a/Projects/UOContent/Mobiles/Monsters/Reptile/Melee/Scorpion.cs b/Projects/UOContent/Mobiles/Monsters/Reptile/Melee/Scorpion.cs index 14db2e1e6..c3d172d7b 100644 --- a/Projects/UOContent/Mobiles/Monsters/Reptile/Melee/Scorpion.cs +++ b/Projects/UOContent/Mobiles/Monsters/Reptile/Melee/Scorpion.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class Scorpion : BaseCreature { [Constructible] - public Scorpion() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public Scorpion() : base(AIType.AI_Melee) { Body = 48; BaseSoundID = 397; diff --git a/Projects/UOContent/Mobiles/Monsters/Reptile/Melee/StoneHarpy.cs b/Projects/UOContent/Mobiles/Monsters/Reptile/Melee/StoneHarpy.cs index 3af776b96..39861b586 100644 --- a/Projects/UOContent/Mobiles/Monsters/Reptile/Melee/StoneHarpy.cs +++ b/Projects/UOContent/Mobiles/Monsters/Reptile/Melee/StoneHarpy.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class StoneHarpy : BaseCreature { [Constructible] - public StoneHarpy() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public StoneHarpy() : base(AIType.AI_Melee) { Body = 73; BaseSoundID = 402; diff --git a/Projects/UOContent/Mobiles/Monsters/Reptile/Melee/Wyvern.cs b/Projects/UOContent/Mobiles/Monsters/Reptile/Melee/Wyvern.cs index 25cb30493..36361e746 100644 --- a/Projects/UOContent/Mobiles/Monsters/Reptile/Melee/Wyvern.cs +++ b/Projects/UOContent/Mobiles/Monsters/Reptile/Melee/Wyvern.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class Wyvern : BaseCreature { [Constructible] - public Wyvern() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public Wyvern() : base(AIType.AI_Melee) { Body = 62; BaseSoundID = 362; diff --git a/Projects/UOContent/Mobiles/Monsters/SE/BakeKitsune.cs b/Projects/UOContent/Mobiles/Monsters/SE/BakeKitsune.cs index a4d405e88..0bc626613 100644 --- a/Projects/UOContent/Mobiles/Monsters/SE/BakeKitsune.cs +++ b/Projects/UOContent/Mobiles/Monsters/SE/BakeKitsune.cs @@ -12,7 +12,7 @@ namespace Server.Mobiles private TimerExecutionToken _disguiseTimerToken; [Constructible] - public BakeKitsune() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public BakeKitsune() : base(AIType.AI_Mage) { Body = 246; diff --git a/Projects/UOContent/Mobiles/Monsters/SE/DeathWatchBeetle.cs b/Projects/UOContent/Mobiles/Monsters/SE/DeathWatchBeetle.cs index 90d36b4fc..37b92ee25 100644 --- a/Projects/UOContent/Mobiles/Monsters/SE/DeathWatchBeetle.cs +++ b/Projects/UOContent/Mobiles/Monsters/SE/DeathWatchBeetle.cs @@ -7,7 +7,7 @@ namespace Server.Mobiles public class DeathwatchBeetle : BaseCreature { [Constructible] - public DeathwatchBeetle() : base(AIType.AI_Melee, Core.ML ? FightMode.Aggressor : FightMode.Closest, 10, 1, 0.2, 0.4) + public DeathwatchBeetle() : base(AIType.AI_Melee, Core.ML ? FightMode.Aggressor : FightMode.Closest) { Body = 242; diff --git a/Projects/UOContent/Mobiles/Monsters/SE/EliteNinja.cs b/Projects/UOContent/Mobiles/Monsters/SE/EliteNinja.cs index dc87d356d..8d21aa003 100644 --- a/Projects/UOContent/Mobiles/Monsters/SE/EliteNinja.cs +++ b/Projects/UOContent/Mobiles/Monsters/SE/EliteNinja.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class EliteNinja : BaseCreature { [Constructible] - public EliteNinja() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public EliteNinja() : base(AIType.AI_Melee) { SpeechHue = Utility.RandomDyedHue(); Hue = Race.Human.RandomSkinHue(); diff --git a/Projects/UOContent/Mobiles/Monsters/SE/FanDancer.cs b/Projects/UOContent/Mobiles/Monsters/SE/FanDancer.cs index 49b738f19..637af3571 100644 --- a/Projects/UOContent/Mobiles/Monsters/SE/FanDancer.cs +++ b/Projects/UOContent/Mobiles/Monsters/SE/FanDancer.cs @@ -10,7 +10,7 @@ namespace Server.Mobiles private static readonly HashSet m_Table = new(); [Constructible] - public FanDancer() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public FanDancer() : base(AIType.AI_Melee) { Body = 247; BaseSoundID = 0x372; diff --git a/Projects/UOContent/Mobiles/Monsters/SE/FireBeetle.cs b/Projects/UOContent/Mobiles/Monsters/SE/FireBeetle.cs index 9e24b2336..b6ea95b88 100644 --- a/Projects/UOContent/Mobiles/Monsters/SE/FireBeetle.cs +++ b/Projects/UOContent/Mobiles/Monsters/SE/FireBeetle.cs @@ -7,7 +7,7 @@ namespace Server.Mobiles public class FireBeetle : BaseMount { [Constructible] - public FireBeetle() : base("a fire beetle", 0xA9, 0x3E95, AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public FireBeetle() : base("a fire beetle", 0xA9, 0x3E95, AIType.AI_Melee, FightMode.Closest, 10, 1) { SetStr(300); SetDex(100); diff --git a/Projects/UOContent/Mobiles/Monsters/SE/Kappa.cs b/Projects/UOContent/Mobiles/Monsters/SE/Kappa.cs index 5abb5deb5..f10e68ba1 100644 --- a/Projects/UOContent/Mobiles/Monsters/SE/Kappa.cs +++ b/Projects/UOContent/Mobiles/Monsters/SE/Kappa.cs @@ -10,7 +10,7 @@ namespace Server.Mobiles private static readonly Dictionary m_Table = new(); [Constructible] - public Kappa() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public Kappa() : base(AIType.AI_Melee) { Body = 240; diff --git a/Projects/UOContent/Mobiles/Monsters/SE/KazeKemono.cs b/Projects/UOContent/Mobiles/Monsters/SE/KazeKemono.cs index 05ebec43e..2eacb266b 100644 --- a/Projects/UOContent/Mobiles/Monsters/SE/KazeKemono.cs +++ b/Projects/UOContent/Mobiles/Monsters/SE/KazeKemono.cs @@ -12,7 +12,7 @@ namespace Server.Mobiles [Constructible] public KazeKemono() - : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + : base(AIType.AI_Mage) { Body = 196; BaseSoundID = 655; diff --git a/Projects/UOContent/Mobiles/Monsters/SE/LadyOfTheSnow.cs b/Projects/UOContent/Mobiles/Monsters/SE/LadyOfTheSnow.cs index cd3af17f3..17881e488 100644 --- a/Projects/UOContent/Mobiles/Monsters/SE/LadyOfTheSnow.cs +++ b/Projects/UOContent/Mobiles/Monsters/SE/LadyOfTheSnow.cs @@ -11,7 +11,7 @@ namespace Server.Mobiles [Constructible] public LadyOfTheSnow() - : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + : base(AIType.AI_Mage) { Body = 252; BaseSoundID = 0x482; diff --git a/Projects/UOContent/Mobiles/Monsters/SE/Oni.cs b/Projects/UOContent/Mobiles/Monsters/SE/Oni.cs index a75708399..fa5c6a6bc 100644 --- a/Projects/UOContent/Mobiles/Monsters/SE/Oni.cs +++ b/Projects/UOContent/Mobiles/Monsters/SE/Oni.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class Oni : BaseCreature { [Constructible] - public Oni() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public Oni() : base(AIType.AI_Mage) { Body = 241; diff --git a/Projects/UOContent/Mobiles/Monsters/SE/RaiJu.cs b/Projects/UOContent/Mobiles/Monsters/SE/RaiJu.cs index b0d92e70c..73019d70c 100644 --- a/Projects/UOContent/Mobiles/Monsters/SE/RaiJu.cs +++ b/Projects/UOContent/Mobiles/Monsters/SE/RaiJu.cs @@ -8,7 +8,7 @@ namespace Server.Mobiles private static readonly HashSet m_Table = new(); [Constructible] - public RaiJu() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public RaiJu() : base(AIType.AI_Melee) { Body = 199; BaseSoundID = 0x346; diff --git a/Projects/UOContent/Mobiles/Monsters/SE/RevenantLion.cs b/Projects/UOContent/Mobiles/Monsters/SE/RevenantLion.cs index 50e336676..52da6b4dc 100644 --- a/Projects/UOContent/Mobiles/Monsters/SE/RevenantLion.cs +++ b/Projects/UOContent/Mobiles/Monsters/SE/RevenantLion.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class RevenantLion : BaseCreature { [Constructible] - public RevenantLion() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public RevenantLion() : base(AIType.AI_Mage) { Body = 251; diff --git a/Projects/UOContent/Mobiles/Monsters/SE/Ronin.cs b/Projects/UOContent/Mobiles/Monsters/SE/Ronin.cs index b7c8e51b6..91ca622e6 100644 --- a/Projects/UOContent/Mobiles/Monsters/SE/Ronin.cs +++ b/Projects/UOContent/Mobiles/Monsters/SE/Ronin.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class Ronin : BaseCreature { [Constructible] - public Ronin() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public Ronin() : base(AIType.AI_Melee) { SpeechHue = Utility.RandomDyedHue(); Hue = Race.Human.RandomSkinHue(); diff --git a/Projects/UOContent/Mobiles/Monsters/SE/RuneBeetle.cs b/Projects/UOContent/Mobiles/Monsters/SE/RuneBeetle.cs index b705c518f..8825b753d 100644 --- a/Projects/UOContent/Mobiles/Monsters/SE/RuneBeetle.cs +++ b/Projects/UOContent/Mobiles/Monsters/SE/RuneBeetle.cs @@ -10,7 +10,7 @@ namespace Server.Mobiles private static readonly Dictionary m_Table = new(); [Constructible] - public RuneBeetle() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public RuneBeetle() : base(AIType.AI_Mage) { Body = 244; diff --git a/Projects/UOContent/Mobiles/Monsters/SE/TsukiWolf.cs b/Projects/UOContent/Mobiles/Monsters/SE/TsukiWolf.cs index 54ed25ea7..8a389b035 100644 --- a/Projects/UOContent/Mobiles/Monsters/SE/TsukiWolf.cs +++ b/Projects/UOContent/Mobiles/Monsters/SE/TsukiWolf.cs @@ -11,7 +11,7 @@ namespace Server.Mobiles [Constructible] public TsukiWolf() - : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + : base(AIType.AI_Melee) { Body = 250; Hue = Utility.Random(3) == 0 ? Utility.RandomNeutralHue() : 0; diff --git a/Projects/UOContent/Mobiles/Monsters/SE/Yamandon.cs b/Projects/UOContent/Mobiles/Monsters/SE/Yamandon.cs index 7e7856efb..b475c769c 100644 --- a/Projects/UOContent/Mobiles/Monsters/SE/Yamandon.cs +++ b/Projects/UOContent/Mobiles/Monsters/SE/Yamandon.cs @@ -7,7 +7,7 @@ namespace Server.Mobiles public class Yamandon : BaseCreature { [Constructible] - public Yamandon() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public Yamandon() : base(AIType.AI_Melee) { Body = 249; diff --git a/Projects/UOContent/Mobiles/Monsters/SE/YomotsuElder.cs b/Projects/UOContent/Mobiles/Monsters/SE/YomotsuElder.cs index b323bbb82..4a6a2e4c6 100644 --- a/Projects/UOContent/Mobiles/Monsters/SE/YomotsuElder.cs +++ b/Projects/UOContent/Mobiles/Monsters/SE/YomotsuElder.cs @@ -7,7 +7,7 @@ namespace Server.Mobiles public class YomotsuElder : BaseCreature { [Constructible] - public YomotsuElder() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public YomotsuElder() : base(AIType.AI_Melee) { Body = 255; BaseSoundID = 0x452; diff --git a/Projects/UOContent/Mobiles/Monsters/SE/YomotsuPriest.cs b/Projects/UOContent/Mobiles/Monsters/SE/YomotsuPriest.cs index e443a15a4..00dd628c6 100644 --- a/Projects/UOContent/Mobiles/Monsters/SE/YomotsuPriest.cs +++ b/Projects/UOContent/Mobiles/Monsters/SE/YomotsuPriest.cs @@ -7,7 +7,7 @@ namespace Server.Mobiles public class YomotsuPriest : BaseCreature { [Constructible] - public YomotsuPriest() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public YomotsuPriest() : base(AIType.AI_Mage) { Body = 253; BaseSoundID = 0x452; diff --git a/Projects/UOContent/Mobiles/Monsters/SE/YomotsuWarrior.cs b/Projects/UOContent/Mobiles/Monsters/SE/YomotsuWarrior.cs index b4bcac395..22973b4aa 100644 --- a/Projects/UOContent/Mobiles/Monsters/SE/YomotsuWarrior.cs +++ b/Projects/UOContent/Mobiles/Monsters/SE/YomotsuWarrior.cs @@ -7,7 +7,7 @@ namespace Server.Mobiles public class YomotsuWarrior : BaseCreature { [Constructible] - public YomotsuWarrior() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public YomotsuWarrior() : base(AIType.AI_Melee) { Body = 245; BaseSoundID = 0x452; diff --git a/Projects/UOContent/Mobiles/Monsters/Summons/SummonedAirElemental.cs b/Projects/UOContent/Mobiles/Monsters/Summons/SummonedAirElemental.cs index bc733ae92..d430af376 100644 --- a/Projects/UOContent/Mobiles/Monsters/Summons/SummonedAirElemental.cs +++ b/Projects/UOContent/Mobiles/Monsters/Summons/SummonedAirElemental.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class SummonedAirElemental : BaseCreature { [Constructible] - public SummonedAirElemental() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public SummonedAirElemental() : base(AIType.AI_Mage) { Body = 13; Hue = 0x4001; diff --git a/Projects/UOContent/Mobiles/Monsters/Summons/SummonedDaemon.cs b/Projects/UOContent/Mobiles/Monsters/Summons/SummonedDaemon.cs index 776d5dba8..0f4bbcbd3 100644 --- a/Projects/UOContent/Mobiles/Monsters/Summons/SummonedDaemon.cs +++ b/Projects/UOContent/Mobiles/Monsters/Summons/SummonedDaemon.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class SummonedDaemon : BaseCreature { [Constructible] - public SummonedDaemon() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public SummonedDaemon() : base(AIType.AI_Mage) { Name = NameList.RandomName("daemon"); Body = Core.AOS ? 10 : 9; diff --git a/Projects/UOContent/Mobiles/Monsters/Summons/SummonedEarthElemental.cs b/Projects/UOContent/Mobiles/Monsters/Summons/SummonedEarthElemental.cs index b7d499ed7..d1fd54a2b 100644 --- a/Projects/UOContent/Mobiles/Monsters/Summons/SummonedEarthElemental.cs +++ b/Projects/UOContent/Mobiles/Monsters/Summons/SummonedEarthElemental.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class SummonedEarthElemental : BaseCreature { [Constructible] - public SummonedEarthElemental() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public SummonedEarthElemental() : base(AIType.AI_Melee) { Body = 14; BaseSoundID = 268; diff --git a/Projects/UOContent/Mobiles/Monsters/Summons/SummonedFireElemental.cs b/Projects/UOContent/Mobiles/Monsters/Summons/SummonedFireElemental.cs index e76e2a472..19d8f5662 100644 --- a/Projects/UOContent/Mobiles/Monsters/Summons/SummonedFireElemental.cs +++ b/Projects/UOContent/Mobiles/Monsters/Summons/SummonedFireElemental.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class SummonedFireElemental : BaseCreature { [Constructible] - public SummonedFireElemental() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public SummonedFireElemental() : base(AIType.AI_Mage) { Body = 15; BaseSoundID = 838; diff --git a/Projects/UOContent/Mobiles/Monsters/Summons/SummonedWaterElemental.cs b/Projects/UOContent/Mobiles/Monsters/Summons/SummonedWaterElemental.cs index 1228bb03d..1a08bedd0 100644 --- a/Projects/UOContent/Mobiles/Monsters/Summons/SummonedWaterElemental.cs +++ b/Projects/UOContent/Mobiles/Monsters/Summons/SummonedWaterElemental.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class SummonedWaterElemental : BaseCreature { [Constructible] - public SummonedWaterElemental() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public SummonedWaterElemental() : base(AIType.AI_Mage) { Body = 16; BaseSoundID = 278; diff --git a/Projects/UOContent/Mobiles/Special/BaseShieldGuard.cs b/Projects/UOContent/Mobiles/Special/BaseShieldGuard.cs index 85eaaaba4..a978383c2 100644 --- a/Projects/UOContent/Mobiles/Special/BaseShieldGuard.cs +++ b/Projects/UOContent/Mobiles/Special/BaseShieldGuard.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles { public abstract class BaseShieldGuard : BaseCreature { - public BaseShieldGuard() : base(AIType.AI_Melee, FightMode.Aggressor, 14, 1, 0.8, 1.6) + public BaseShieldGuard() : base(AIType.AI_Melee, FightMode.Aggressor, 14) { InitStats(1000, 1000, 1000); Title = "the guard"; diff --git a/Projects/UOContent/Mobiles/Special/DarkGuardian.cs b/Projects/UOContent/Mobiles/Special/DarkGuardian.cs index 2e6bbeca2..6f2326973 100644 --- a/Projects/UOContent/Mobiles/Special/DarkGuardian.cs +++ b/Projects/UOContent/Mobiles/Special/DarkGuardian.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class DarkGuardian : BaseCreature { [Constructible] - public DarkGuardian() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public DarkGuardian() : base(AIType.AI_Mage) { Body = 78; BaseSoundID = 0x3E9; diff --git a/Projects/UOContent/Mobiles/Special/Harrower.cs b/Projects/UOContent/Mobiles/Special/Harrower.cs index 967f2fb3a..cd6ba03c9 100644 --- a/Projects/UOContent/Mobiles/Special/Harrower.cs +++ b/Projects/UOContent/Mobiles/Special/Harrower.cs @@ -48,7 +48,7 @@ namespace Server.Mobiles private bool m_TrueForm; [Constructible] - public Harrower() : base(AIType.AI_Mage, FightMode.Closest, 18, 1, 0.2, 0.4) + public Harrower() : base(AIType.AI_Mage, FightMode.Closest, 18) { Instances.Add(this); Body = 146; diff --git a/Projects/UOContent/Mobiles/Special/HarrowerTentacles.cs b/Projects/UOContent/Mobiles/Special/HarrowerTentacles.cs index d0521bb08..eb98639d4 100644 --- a/Projects/UOContent/Mobiles/Special/HarrowerTentacles.cs +++ b/Projects/UOContent/Mobiles/Special/HarrowerTentacles.cs @@ -7,7 +7,7 @@ namespace Server.Mobiles private DrainTimer m_Timer; [Constructible] - public HarrowerTentacles(Mobile harrower = null) : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + public HarrowerTentacles(Mobile harrower = null) : base(AIType.AI_Melee) { Harrower = harrower; Body = 129; diff --git a/Projects/UOContent/Mobiles/Special/ServantOfSemidar.cs b/Projects/UOContent/Mobiles/Special/ServantOfSemidar.cs index d7cd010ba..8aec98cf3 100644 --- a/Projects/UOContent/Mobiles/Special/ServantOfSemidar.cs +++ b/Projects/UOContent/Mobiles/Special/ServantOfSemidar.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class ServantOfSemidar : BaseCreature { [Constructible] - public ServantOfSemidar() : base(AIType.AI_Melee, FightMode.None, 10, 1, 0.2, 0.4) => Body = 0x26; + public ServantOfSemidar() : base(AIType.AI_Melee, FightMode.None) => Body = 0x26; public ServantOfSemidar(Serial serial) : base(serial) { diff --git a/Projects/UOContent/Mobiles/Townfolk/Actor.cs b/Projects/UOContent/Mobiles/Townfolk/Actor.cs index 60feea63f..6b0352779 100644 --- a/Projects/UOContent/Mobiles/Townfolk/Actor.cs +++ b/Projects/UOContent/Mobiles/Townfolk/Actor.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class Actor : BaseCreature { [Constructible] - public Actor() : base(AIType.AI_Animal, FightMode.None, 10, 1, 0.2, 0.4) + public Actor() : base(AIType.AI_Animal, FightMode.None) { InitStats(31, 41, 51); diff --git a/Projects/UOContent/Mobiles/Townfolk/Artist.cs b/Projects/UOContent/Mobiles/Townfolk/Artist.cs index 2945fa96b..dd72595c9 100644 --- a/Projects/UOContent/Mobiles/Townfolk/Artist.cs +++ b/Projects/UOContent/Mobiles/Townfolk/Artist.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles { [Constructible] public Artist() - : base(AIType.AI_Animal, FightMode.None, 10, 1, 0.2, 0.4) + : base(AIType.AI_Animal, FightMode.None) { InitStats(31, 41, 51); diff --git a/Projects/UOContent/Mobiles/Townfolk/Gypsy.cs b/Projects/UOContent/Mobiles/Townfolk/Gypsy.cs index ca5ee2ed6..ff01a3247 100644 --- a/Projects/UOContent/Mobiles/Townfolk/Gypsy.cs +++ b/Projects/UOContent/Mobiles/Townfolk/Gypsy.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles { [Constructible] public Gypsy() - : base(AIType.AI_Animal, FightMode.None, 10, 1, 0.2, 0.4) + : base(AIType.AI_Animal, FightMode.None) { InitStats(31, 41, 51); diff --git a/Projects/UOContent/Mobiles/Townfolk/HarborMaster.cs b/Projects/UOContent/Mobiles/Townfolk/HarborMaster.cs index 2d03f6099..b3c9eea4b 100644 --- a/Projects/UOContent/Mobiles/Townfolk/HarborMaster.cs +++ b/Projects/UOContent/Mobiles/Townfolk/HarborMaster.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles { [Constructible] public HarborMaster() - : base(AIType.AI_Animal, FightMode.None, 10, 1, 0.2, 0.4) + : base(AIType.AI_Animal, FightMode.None) { InitStats(31, 41, 51); diff --git a/Projects/UOContent/Mobiles/Townfolk/Ninja.cs b/Projects/UOContent/Mobiles/Townfolk/Ninja.cs index 91f4e0667..d7ff674a3 100644 --- a/Projects/UOContent/Mobiles/Townfolk/Ninja.cs +++ b/Projects/UOContent/Mobiles/Townfolk/Ninja.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class Ninja : BaseCreature { [Constructible] - public Ninja() : base(AIType.AI_Melee, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public Ninja() : base(AIType.AI_Melee, FightMode.Aggressor) { Title = "the ninja"; diff --git a/Projects/UOContent/Mobiles/Townfolk/Samurai.cs b/Projects/UOContent/Mobiles/Townfolk/Samurai.cs index 86d28bae2..3f4022367 100644 --- a/Projects/UOContent/Mobiles/Townfolk/Samurai.cs +++ b/Projects/UOContent/Mobiles/Townfolk/Samurai.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class Samurai : BaseCreature { [Constructible] - public Samurai() : base(AIType.AI_Melee, FightMode.Aggressor, 10, 1, 0.2, 0.4) + public Samurai() : base(AIType.AI_Melee, FightMode.Aggressor) { Title = "the samurai"; diff --git a/Projects/UOContent/Mobiles/Townfolk/Sculptor.cs b/Projects/UOContent/Mobiles/Townfolk/Sculptor.cs index 00b6de015..26034b762 100644 --- a/Projects/UOContent/Mobiles/Townfolk/Sculptor.cs +++ b/Projects/UOContent/Mobiles/Townfolk/Sculptor.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles { [Constructible] public Sculptor() - : base(AIType.AI_Animal, FightMode.None, 10, 1, 0.2, 0.4) + : base(AIType.AI_Animal, FightMode.None) { InitStats(31, 41, 51); diff --git a/Projects/UOContent/Spells/Ninjitsu/MirrorImage.cs b/Projects/UOContent/Spells/Ninjitsu/MirrorImage.cs index 4444a19c0..896d01456 100644 --- a/Projects/UOContent/Spells/Ninjitsu/MirrorImage.cs +++ b/Projects/UOContent/Spells/Ninjitsu/MirrorImage.cs @@ -128,7 +128,7 @@ namespace Server.Mobiles { private Mobile m_Caster; - public Clone(Mobile caster) : base(AIType.AI_Melee, FightMode.None, 10, 1, 0.2, 0.4) + public Clone(Mobile caster) : base(AIType.AI_Melee, FightMode.None) { m_Caster = caster; diff --git a/Projects/UOContent/Spells/Spellweaving/Mobiles/ArcaneFey.cs b/Projects/UOContent/Spells/Spellweaving/Mobiles/ArcaneFey.cs index d93e03c44..3f1defbde 100644 --- a/Projects/UOContent/Spells/Spellweaving/Mobiles/ArcaneFey.cs +++ b/Projects/UOContent/Spells/Spellweaving/Mobiles/ArcaneFey.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class ArcaneFey : BaseCreature { [Constructible] - public ArcaneFey() : base(AIType.AI_Mage, FightMode.Evil, 10, 1, 0.2, 0.4) + public ArcaneFey() : base(AIType.AI_Mage, FightMode.Evil) { Name = NameList.RandomName("pixie"); Body = 128; diff --git a/Projects/UOContent/Spells/Spellweaving/Mobiles/ArcaneFiend.cs b/Projects/UOContent/Spells/Spellweaving/Mobiles/ArcaneFiend.cs index 3b44cca14..6041979af 100644 --- a/Projects/UOContent/Spells/Spellweaving/Mobiles/ArcaneFiend.cs +++ b/Projects/UOContent/Spells/Spellweaving/Mobiles/ArcaneFiend.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class ArcaneFiend : BaseCreature { [Constructible] - public ArcaneFiend() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) + public ArcaneFiend() : base(AIType.AI_Mage) { Body = 74; BaseSoundID = 422; diff --git a/Projects/UOContent/Spells/Spellweaving/Mobiles/NatureFury.cs b/Projects/UOContent/Spells/Spellweaving/Mobiles/NatureFury.cs index 0c0d7f7ac..effcf7802 100644 --- a/Projects/UOContent/Spells/Spellweaving/Mobiles/NatureFury.cs +++ b/Projects/UOContent/Spells/Spellweaving/Mobiles/NatureFury.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles { [Constructible] public NatureFury() - : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) + : base(AIType.AI_Melee) { Body = 0x33; Hue = 0x4001; diff --git a/version.json b/version.json index dd101024d..f1698afbc 100644 --- a/version.json +++ b/version.json @@ -1,4 +1,4 @@ { "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", - "version": "0.8.3" + "version": "0.9.0" } From 16c4268b54967afbced0c490d7aa704f550d829d Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Fri, 11 Mar 2022 01:45:03 -0800 Subject: [PATCH 099/213] fix: Fixes file reading. (#958) .NET 6 introduced a breaking change where lseek and sys-calls are not used for reading and file streams. This effectively broke out native reader. Since the file reading is fairly optimized, and honestly we don't need it to be "fast" in this case, I have removed the native reader. https://devblogs.microsoft.com/dotnet/file-io-improvements-in-dotnet-6/ --- Projects/Server/NativeReader.cs | 62 ------------------- Projects/Server/TileMatrix/TileMatrix.cs | 22 +++---- Projects/Server/TileMatrix/TileMatrixPatch.cs | 13 ++-- 3 files changed, 16 insertions(+), 81 deletions(-) delete mode 100644 Projects/Server/NativeReader.cs diff --git a/Projects/Server/NativeReader.cs b/Projects/Server/NativeReader.cs deleted file mode 100644 index 0b6dc1d41..000000000 --- a/Projects/Server/NativeReader.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System; -using System.IO; -using System.Runtime.InteropServices; -using System.Threading; - -namespace Server -{ - public static class NativeReader - { - private static readonly INativeReader m_NativeReader; - - static NativeReader() => m_NativeReader = Core.Unix ? new NativeReaderUnix() : new NativeReaderWin32(); - - public static unsafe int Read(FileStream source, void* buffer, int length) => Read(source, buffer, 0, length); - - public static unsafe int Read(FileStream source, void* buffer, int bufferIndex, int length) => - m_NativeReader.Read(source, buffer, bufferIndex, length); - } - - public interface INativeReader - { - unsafe int Read(FileStream source, void* buffer, int bufferIndex, int length); - } - - public sealed class NativeReaderWin32 : INativeReader - { - internal class UnsafeNativeMethods - { - [DllImport("kernel32")] - internal static extern unsafe bool ReadFile(IntPtr hFile, void* lpBuffer, uint nNumberOfBytesToRead, ref uint lpNumberOfBytesRead, NativeOverlapped* lpOverlapped); - } - - public unsafe int Read(FileStream source, void* buffer, int bufferIndex, int length) => InternalRead(source, buffer, bufferIndex, length); - - internal static unsafe int InternalRead(FileStream source, void* buffer, int bufferIndex, int length) - { - var byteCount = 0U; - - if (UnsafeNativeMethods.ReadFile(source.SafeFileHandle!.DangerousGetHandle(), (byte*)buffer + bufferIndex, (uint)length, ref byteCount, null)) - { - return (int)byteCount; - } - - return -1; - } - } - - public sealed class NativeReaderUnix : INativeReader - { - internal class UnsafeNativeMethods - { - [DllImport("libc")] - internal static extern unsafe int read(IntPtr ptr, void* buffer, int length); - } - - public unsafe int Read(FileStream source, void* buffer, int bufferIndex, int length) => - InternalRead(source, buffer, bufferIndex, length); - - internal unsafe int InternalRead(FileStream source, void* buffer, int bufferIndex, int length) => - UnsafeNativeMethods.read(source.SafeFileHandle!.DangerousGetHandle(), (byte*)buffer + bufferIndex, length); - } -} diff --git a/Projects/Server/TileMatrix/TileMatrix.cs b/Projects/Server/TileMatrix/TileMatrix.cs index aaea1f638..03dfcb755 100644 --- a/Projects/Server/TileMatrix/TileMatrix.cs +++ b/Projects/Server/TileMatrix/TileMatrix.cs @@ -71,9 +71,9 @@ namespace Server if (fileIndex != 0x7F) { - fileIndex = Pre6000ClientSupport && mapID == 1 ? 0 : fileIndex; + var mapFileIndex = Pre6000ClientSupport && mapID == 1 ? 0 : fileIndex; - var mapPath = Core.FindDataFile($"map{fileIndex}.mul", false); + var mapPath = Core.FindDataFile($"map{mapFileIndex}.mul", false); if (mapPath != null) { @@ -81,7 +81,7 @@ namespace Server } else { - mapPath = Core.FindDataFile($"map{fileIndex}LegacyMUL.uop", false); + mapPath = Core.FindDataFile($"map{mapFileIndex}LegacyMUL.uop", false); if (mapPath != null) { @@ -90,11 +90,11 @@ namespace Server } else { - logger.Warning($"map{fileIndex}.mul was not found."); + logger.Warning($"map{mapFileIndex}.mul was not found."); } } - var indexPath = Core.FindDataFile($"staidx{fileIndex}.mul", false); + var indexPath = Core.FindDataFile($"staidx{mapFileIndex}.mul", false); if (indexPath != null) { @@ -103,10 +103,10 @@ namespace Server } else { - logger.Warning($"staidx{fileIndex}.mul was not found."); + logger.Warning($"staidx{mapFileIndex}.mul was not found."); } - var staticsPath = Core.FindDataFile($"statics{fileIndex}.mul", false); + var staticsPath = Core.FindDataFile($"statics{mapFileIndex}.mul", false); if (staticsPath != null) { @@ -137,7 +137,7 @@ namespace Server _staticPatches = new int[BlockWidth][]; _landPatches = new int[BlockWidth][]; - Patch = new TileMatrixPatch(this, mapID); + Patch = new TileMatrixPatch(this, fileIndex); } public StaticTile[][][] EmptyStaticBlock => _emptyStaticBlock; @@ -365,11 +365,11 @@ namespace Server m_TileBuffer = new StaticTile[count]; } - var staTiles = m_TileBuffer; //new StaticTile[tileCount]; + var staTiles = m_TileBuffer; fixed (StaticTile* pTiles = staTiles) { - NativeReader.Read(DataStream, pTiles, length); + DataStream.Read(new Span(pTiles, length)); if (m_Lists == null) { @@ -455,7 +455,7 @@ namespace Server fixed (LandTile* pTiles = tiles) { - NativeReader.Read(MapStream, pTiles, 192); + MapStream.Read(new Span(pTiles, 192)); } return tiles; diff --git a/Projects/Server/TileMatrix/TileMatrixPatch.cs b/Projects/Server/TileMatrix/TileMatrixPatch.cs index 2e876a348..7c55949fe 100644 --- a/Projects/Server/TileMatrix/TileMatrixPatch.cs +++ b/Projects/Server/TileMatrix/TileMatrixPatch.cs @@ -1,6 +1,7 @@ using System; using System.IO; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; namespace Server { @@ -63,10 +64,9 @@ namespace Server fsData.Seek(4, SeekOrigin.Current); var tiles = new LandTile[64]; - fixed (LandTile* pTiles = tiles) { - NativeReader.Read(fsData, pTiles, 192); + fsData.Read(new Span(pTiles, 192)); } matrix.SetLandBlock(x, y, tiles); @@ -81,8 +81,8 @@ namespace Server using var fsData = new FileStream(dataPath, FileMode.Open, FileAccess.Read, FileShare.Read); using var fsIndex = new FileStream(indexPath, FileMode.Open, FileAccess.Read, FileShare.Read); using var fsLookup = new FileStream(lookupPath, FileMode.Open, FileAccess.Read, FileShare.Read); - var indexReader = new BinaryReader(fsIndex); - var lookupReader = new BinaryReader(fsLookup); + using var indexReader = new BinaryReader(fsIndex); + using var lookupReader = new BinaryReader(fsLookup); var count = (int)(indexReader.BaseStream.Length / 4); @@ -127,7 +127,7 @@ namespace Server fixed (StaticTile* pTiles = staTiles) { - NativeReader.Read(fsData, pTiles, length); + fsData.Read(new Span(pTiles, length)); StaticTile* pCur = pTiles, pEnd = pTiles + tileCount; @@ -153,9 +153,6 @@ namespace Server } } - indexReader.Close(); - lookupReader.Close(); - return count; } } From 1ec3636951a066ad9b306ff2d4aac90e702a0be1 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Tue, 15 Mar 2022 10:18:27 -0700 Subject: [PATCH 100/213] fix: Fixes speed issues (#959) - [X] Removes all speeds in constructors since _they aren't used anyways_. - [X] Adjusted timers according to the _time transformations in RunUO_. --- Distribution/Data/npc-speeds.json | 139 ++++ Projects/Server/Utilities/Utility.cs | 15 + .../ML Quests/Definitions/AGhostOfCovetous.cs | 16 +- .../Engines/ML Quests/Definitions/Bedlam.cs | 15 +- .../ML Quests/Definitions/Britannia.cs | 10 +- .../ML Quests/Definitions/Heartwood.cs | 240 +++--- .../Engines/ML Quests/Definitions/Heritage.cs | 19 +- .../ML Quests/Definitions/HonestBeggar.cs | 10 +- .../Engines/ML Quests/Definitions/Ilshenar.cs | 15 +- .../Engines/ML Quests/Definitions/Malas.cs | 5 +- .../ML Quests/Definitions/MistakenIdentity.cs | 15 +- .../Definitions/NewHavenSkillTraining.cs | 78 +- .../ML Quests/Definitions/NewHavenTraining.cs | 60 +- .../ML Quests/Definitions/Sanctuary.cs | 49 +- .../ML Quests/Definitions/Spellweaving.cs | 20 +- .../ML Quests/Definitions/TheAncientWorld.cs | 5 +- .../ML Quests/Definitions/UnfadingMemories.cs | 10 +- .../ML Quests/Mobiles/BoonCollector.cs | 4 +- Projects/UOContent/Mobiles/AI/BaseAI.cs | 47 +- .../UOContent/Mobiles/AI/LegacySpeedInfo.cs | 77 ++ Projects/UOContent/Mobiles/AI/MageAI.cs | 39 +- Projects/UOContent/Mobiles/AI/SpeedInfo.cs | 17 +- .../Mobiles/Animals/Mounts/BaseMount.cs | 13 +- .../Mobiles/Animals/Mounts/Beetle.cs | 12 +- .../Mobiles/Animals/Mounts/DesertOstard.cs | 12 +- .../Mobiles/Animals/Mounts/Ethereals.cs | 3 +- .../Mobiles/Animals/Mounts/FireSteed.cs | 12 +- .../Mobiles/Animals/Mounts/ForestOstard.cs | 12 +- .../Mobiles/Animals/Mounts/FrenziedOstard.cs | 12 +- .../Mobiles/Animals/Mounts/HellSteed.cs | 12 +- .../UOContent/Mobiles/Animals/Mounts/Hiryu.cs | 3 +- .../UOContent/Mobiles/Animals/Mounts/Horse.cs | 12 +- .../UOContent/Mobiles/Animals/Mounts/Kirin.cs | 2 +- .../Mobiles/Animals/Mounts/LesserHiryu.cs | 3 +- .../Mobiles/Animals/Mounts/Nightmare.cs | 7 +- .../Mobiles/Animals/Mounts/RidableLlama.cs | 11 +- .../Mobiles/Animals/Mounts/Ridgeback.cs | 12 +- .../Mobiles/Animals/Mounts/SavageRidgeback.cs | 12 +- .../Animals/Mounts/ScaledSwampDragon.cs | 12 +- .../Mobiles/Animals/Mounts/SeaHorse.cs | 13 +- .../Mobiles/Animals/Mounts/SilverSteed.cs | 14 +- .../Mobiles/Animals/Mounts/SkeletalMount.cs | 13 +- .../Mobiles/Animals/Mounts/SwampDragon.cs | 12 +- .../Mobiles/Animals/Mounts/Unicorn.cs | 6 +- .../Animals/Mounts/War Horses/BaseWarHorse.cs | 8 +- .../Animals/Mounts/War Horses/CoMWarHorse.cs | 2 +- .../Mounts/War Horses/MinaxWarHorse.cs | 2 +- .../Animals/Mounts/War Horses/SLWarHorse.cs | 2 +- .../Animals/Mounts/War Horses/TBWarHorse.cs | 2 +- Projects/UOContent/Mobiles/BaseCreature.cs | 70 +- .../Mobiles/Monsters/AOS/Revenant.cs | 11 +- .../Humanoid/Melee/KhaldunRevenant.cs | 4 +- .../Monsters/LBR/Jukas/ChaosDragoon.cs | 4 +- .../Monsters/LBR/Jukas/ChaosDragoonElite.cs | 5 +- .../ML/Humanoid/Melee/CorruptedSoul.cs | 4 +- .../Mobiles/Monsters/ML/Labyrinth/Miasma.cs | 4 +- .../Monsters/ML/Misc/Melee/Reptalon.cs | 4 +- .../Mobiles/Monsters/Misc/Magic/ShadowWisp.cs | 2 +- .../Monsters/Misc/Melee/AnimatedWeapon.cs | 3 +- .../Monsters/Misc/Melee/BladeSpirits.cs | 4 +- .../Mobiles/Monsters/Misc/Melee/Golem.cs | 4 +- .../Mobiles/Monsters/Plant/Melee/BogThing.cs | 2 +- .../Mobiles/Monsters/Plant/Melee/Quagmire.cs | 2 +- .../Monsters/SE/DeathWatchBeetleHatchling.cs | 9 +- .../UOContent/Mobiles/Special/BaseChampion.cs | 3 +- Projects/UOContent/Mobiles/Special/Dummy.cs | 163 ---- .../Mobiles/Special/DummySpecific.cs | 784 ------------------ .../UOContent/Mobiles/Special/Mephitis.cs | 2 + Projects/UOContent/Mobiles/Special/Paragon.cs | 26 +- Projects/UOContent/Mobiles/Special/Semidar.cs | 2 + Projects/UOContent/Mobiles/Special/Silvani.cs | 4 +- .../Mobiles/Townfolk/BaseEscortable.cs | 5 +- .../UOContent/Mobiles/Vendors/BaseVendor.cs | 4 +- 73 files changed, 755 insertions(+), 1511 deletions(-) create mode 100644 Distribution/Data/npc-speeds.json create mode 100644 Projects/UOContent/Mobiles/AI/LegacySpeedInfo.cs delete mode 100644 Projects/UOContent/Mobiles/Special/Dummy.cs delete mode 100644 Projects/UOContent/Mobiles/Special/DummySpecific.cs diff --git a/Distribution/Data/npc-speeds.json b/Distribution/Data/npc-speeds.json new file mode 100644 index 000000000..b2b376d92 --- /dev/null +++ b/Distribution/Data/npc-speeds.json @@ -0,0 +1,139 @@ +[ + { + "name": "Slow", + "active": 0.6, + "passive": 1.2, + "types": [ + "AntLion", "ArcticOgreLord", "BogThing", + "Bogle", "BoneKnight", "EarthElemental", + "Ettin", "FrostOoze", "FrostTroll", + "GazerLarva", "Ghoul", "Golem", + "HeadlessOne", "Jwilson", "Mummy", + "Ogre", "OgreLord", "PlagueBeast", + "Quagmire", "Rat", "RottingCorpse", + "SewerRat", "Skeleton", "Slime", + "Zombie", "Walrus", "RestlessSoul", + "CrystalElemental", "DarknightCreeper", "MoundOfMaggots", + "Juggernaut", "Yamandon", "Serado" + ] + }, + { + "name": "Fast", + "active": 0.4, + "passive": 0.8, + "types": [ + "LordOaks", "Silvani", "AirElemental", + "AncientWyrm", "Balron", "BladeSpirits", + "DreadSpider", "Efreet", "EtherealWarrior", + "Lich", "Nightmare", "OphidianArchmage", + "OphidianMage", "OphidianWarrior", "OphidianMatriarch", + "OphidianKnight", "PoisonElemental", "Revenant", + "SandVortex", "SavageRider", "SavageShaman", + "SnowElemental", "WhiteWyrm", "Wisp", + "DemonKnight", "GiantBlackWidow", "SummonedAirElemental", + "LesserHiryu", "Hiryu", "LadyOfTheSnow", + "RaiJu", "Ronin", "RuneBeetle", + "Changeling", "LadyJennifyr", "LadyMarai", "MasterJonath", + "MasterMikael", "MasterTheophilus", "RedDeath", + "SirPatrick", "Miasma", "Rend", + "Grobu", "Gnaw", "Guile", + "Irk", "Spite", "LadyLissith", + "LadySabrix", "Malefic", "Silk", + "Virulent", "SeaHorse" + ] + }, + { + "name": "Very Fast", + "active": 0.35, + "passive": 0.7, + "types": [ + "Barracoon", "Mephitis", "Neira", + "Rikktor", "Semidar", "EnergyVortex", + "EliteNinja", "Pixie", "SilverSerpent", + "VorpalBunny", "FleshRenderer", "KhaldunRevenant", + "FactionDragoon", "FactionKnight", "FactionPaladin", + "FactionHenchman", "FactionMercenary", "FactionNecromancer", + "FactionSorceress", "FactionWizard", "FactionBerserker", + "FactionPaladin", "Leviathan", "FireBeetle", + "FanDancer", "FactionDeathKnight" + ] + }, + { + "name": "Medium", + "active": 0.5, + "passive": 1.0, + "types": [ + "AcidElemental", "AgapiteElemental", "Alligator", + "AncientLich", "Betrayer", "Bird", + "BlackBear", "BlackSolenInfiltratorQueen", "BlackSolenInfiltratorWarrior", + "BlackSolenQueen", "BlackSolenWarrior", "BlackSolenWorker", + "BloodElemental", "Boar", "Bogling", + "BoneMagi", "Brigand", "BronzeElemental", + "BrownBear", "Bull", "BullFrog", + "Cat", "Centaur", "ChaosDaemon", + "Chicken", "GolemController", "CopperElemental", + "CopperElemental", "Cougar", "Cow", + "Cyclops", "Daemon", "DeepSeaSerpent", + "DesertOstard", "DireWolf", "Dog", + "Dolphin", "Dragon", "Drake", + "DullCopperElemental", "Eagle", "ElderGazer", + "EvilMage", "EvilMageLord", "Executioner", + "Savage", "FireElemental", "FireGargoyle", + "FireSteed", "ForestOstard", "FrenziedOstard", + "FrostSpider", "Gargoyle", "Gazer", + "IceSerpent", "GiantRat", "GiantSerpent", + "GiantSpider", "GiantToad", "Goat", + "GoldenElemental", "Gorilla", "GreatHart", + "GreyWolf", "GrizzlyBear", "Guardian", + "Harpy", "Harrower", "HellHound", + "Hind", "HordeMinion", "Horse", + "Horse", "IceElemental", "IceFiend", + "IceSnake", "Imp", "JackRabbit", + "Kirin", "Kraken", "PredatorHellCat", + "LavaLizard", "LavaSerpent", "LavaSnake", + "Lizardman", "Llama", "Mongbat", + "StrongMongbat", "MountainGoat", "Orc", + "OrcBomber", "OrcBrute", "OrcCaptain", + "OrcishLord", "OrcishMage", "PackHorse", + "PackLlama", "Panther", "Pig", + "PlagueSpawn", "PolarBear", "Rabbit", + "Ratman", "RatmanArcher", "RatmanMage", + "RedSolenInfiltratorQueen", "RedSolenInfiltratorWarrior", "RedSolenQueen", + "RedSolenWarrior", "RedSolenWorker", "RidableLlama", + "Ridgeback", "Scorpion", "SeaSerpent", + "SerpentineDragon", "Shade", "ShadowIronElemental", + "ShadowWisp", "ShadowWyrm", "Sheep", + "SilverSteed", "SkeletalDragon", "SkeletalMage", + "SkeletalMount", "HellCat", "Snake", + "SnowLeopard", "SpectralArmour", "Spectre", + "StoneGargoyle", "StoneHarpy", "SwampDragon", + "ScaledSwampDragon", "SwampTentacle", "TerathanAvenger", + "TerathanDrone", "TerathanMatriarch", "TerathanWarrior", + "TimberWolf", "Titan", "Troll", + "Unicorn", "ValoriteElemental", "VeriteElemental", + "CoMWarHorse", "MinaxWarHorse", "SLWarHorse", + "TBWarHorse", "WaterElemental", "WhippingVine", + "WhiteWolf", "Wraith", "Wyvern", + "KhaldunZealot", "KhaldunSummoner", "SavageRidgeback", + "LichLord", "SkeletalKnight", "SummonedDaemon", + "SummonedEarthElemental", "SummonedWaterElemental", "SummonedFireElemental", + "MeerWarrior", "MeerEternal", "MeerMage", + "MeerCaptain", "JukaLord", "JukaMage", + "JukaWarrior", "AbysmalHorror", "BoneDemon", + "Devourer", "FleshGolem", "Gibberling", + "GoreFiend", "Impaler", "PatchworkSkeleton", + "Ravager", "ShadowKnight", "SkitteringHopper", + "Treefellow", "VampireBat", "WailingBanshee", + "WandererOfTheVoid", "Cursed", "GrimmochDrummel", + "LysanderGathenwale", "MorgBergen", "ShadowFiend", + "SpectralArmour", "TavaraSewel", "ArcaneDaemon", + "Doppleganger", "EnslavedGargoyle", "ExodusMinion", + "ExodusOverseer", "GargoyleDestroyer", "GargoyleEnforcer", + "Moloch", "BakeKitsune", "DeathwatchBeetleHatchling", + "Kappa", "KazeKemono", "DeathwatchBeetle", + "TsukiWolf", "YomotsuElder", "YomotsuPriest", + "YomotsuWarrior", "RevenantLion", "Oni", + "Gaman", "Crane", "Beetle" + ] + } +] diff --git a/Projects/Server/Utilities/Utility.cs b/Projects/Server/Utilities/Utility.cs index faba17ece..7d16d62b0 100644 --- a/Projects/Server/Utilities/Utility.cs +++ b/Projects/Server/Utilities/Utility.cs @@ -1019,6 +1019,21 @@ namespace Server [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool RandomBool() => RandomSources.Source.NextBool(); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double RandomMinMax(double min, double max) + { + if (min > max) + { + (min, max) = (max, min); + } + else if (min == max) + { + return min; + } + + return min + RandomSources.Source.NextDouble() * (max - min); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint RandomMinMax(uint min, uint max) { diff --git a/Projects/UOContent/Engines/ML Quests/Definitions/AGhostOfCovetous.cs b/Projects/UOContent/Engines/ML Quests/Definitions/AGhostOfCovetous.cs index 754d1d8f0..63ebe8524 100644 --- a/Projects/UOContent/Engines/ML Quests/Definitions/AGhostOfCovetous.cs +++ b/Projects/UOContent/Engines/ML Quests/Definitions/AGhostOfCovetous.cs @@ -97,7 +97,7 @@ namespace Server.Engines.MLQuests.Definitions { [Constructible] public Ben() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the Apprentice Necromancer"; Body = 0x190; @@ -107,6 +107,7 @@ namespace Server.Engines.MLQuests.Definitions FacialHairItemID = 0x204C; FacialHairHue = 0x463; + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); AddItem(new Backpack()); @@ -142,13 +143,13 @@ namespace Server.Engines.MLQuests.Definitions public class Frederic : BaseCreature { [Constructible] - public Frederic() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Frederic() : base(AIType.AI_Vendor, FightMode.None, 2) { Body = 0x1A; Hue = 0x455; Frozen = true; + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); } @@ -178,14 +179,15 @@ namespace Server.Engines.MLQuests.Definitions public class Leon : BaseCreature { [Constructible] - public Leon() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Leon() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the Alchemist"; Race = Race.Human; Body = 0x190; Female = false; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -221,8 +223,7 @@ namespace Server.Engines.MLQuests.Definitions public class Andros : BaseCreature { [Constructible] - public Andros() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Andros() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the Blacksmith"; Body = 0x190; @@ -232,6 +233,7 @@ namespace Server.Engines.MLQuests.Definitions HairItemID = 0x2049; HairHue = 0x45E; + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); AddItem(new Backpack()); diff --git a/Projects/UOContent/Engines/ML Quests/Definitions/Bedlam.cs b/Projects/UOContent/Engines/ML Quests/Definitions/Bedlam.cs index f0d7b5daf..390262e51 100644 --- a/Projects/UOContent/Engines/ML Quests/Definitions/Bedlam.cs +++ b/Projects/UOContent/Engines/ML Quests/Definitions/Bedlam.cs @@ -69,14 +69,15 @@ namespace Server.Engines.MLQuests.Definitions public class Kia : BaseCreature { [Constructible] - public Kia() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Kia() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the student"; Race = Race.Human; Body = 0x191; Female = true; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -113,14 +114,15 @@ namespace Server.Engines.MLQuests.Definitions public class Emerillo : BaseCreature { [Constructible] - public Emerillo() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Emerillo() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the cook"; Race = Race.Human; Body = 0x190; Female = false; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -165,14 +167,15 @@ namespace Server.Engines.MLQuests.Definitions public class Nythalia : BaseCreature { [Constructible] - public Nythalia() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Nythalia() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the student"; Race = Race.Human; Body = 0x191; Female = true; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); diff --git a/Projects/UOContent/Engines/ML Quests/Definitions/Britannia.cs b/Projects/UOContent/Engines/ML Quests/Definitions/Britannia.cs index 7226809c2..5f3b2ce96 100644 --- a/Projects/UOContent/Engines/ML Quests/Definitions/Britannia.cs +++ b/Projects/UOContent/Engines/ML Quests/Definitions/Britannia.cs @@ -108,14 +108,15 @@ namespace Server.Engines.MLQuests.Definitions public class Aurelia : BaseCreature { [Constructible] - public Aurelia() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Aurelia() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the Architect's Daughter"; Race = Race.Human; Body = 0x191; Female = true; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -162,12 +163,13 @@ namespace Server.Engines.MLQuests.Definitions public class SkeletonOfSzandor : BaseCreature { [Constructible] - public SkeletonOfSzandor() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public SkeletonOfSzandor() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the Late Architect"; Hue = 0x83F2; // TODO: Random human hue? Why??? Body = 0x32; + + SetSpeed(0.5, 2); InitStats(100, 100, 25); } diff --git a/Projects/UOContent/Engines/ML Quests/Definitions/Heartwood.cs b/Projects/UOContent/Engines/ML Quests/Definitions/Heartwood.cs index 20e0216f3..1dd07828e 100644 --- a/Projects/UOContent/Engines/ML Quests/Definitions/Heartwood.cs +++ b/Projects/UOContent/Engines/ML Quests/Definitions/Heartwood.cs @@ -2004,14 +2004,15 @@ namespace Server.Engines.MLQuests.Definitions public class Saril : BaseCreature { [Constructible] - public Saril() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Saril() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the guard"; Race = Race.Elf; Body = 0x25E; Female = true; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -2070,14 +2071,15 @@ namespace Server.Engines.MLQuests.Definitions public class Cailla : BaseCreature { [Constructible] - public Cailla() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Cailla() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the guard"; Race = Race.Elf; Body = 0x25E; Female = true; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -2137,14 +2139,15 @@ namespace Server.Engines.MLQuests.Definitions public class Tamm : BaseCreature { [Constructible] - public Tamm() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Tamm() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the guard"; Race = Race.Elf; Body = 0x25D; Female = false; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -2202,14 +2205,15 @@ namespace Server.Engines.MLQuests.Definitions public class Landy : BaseCreature { [Constructible] - public Landy() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Landy() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the soil nurturer"; Race = Race.Elf; Body = 0x25D; Female = false; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -2268,14 +2272,15 @@ namespace Server.Engines.MLQuests.Definitions public class Alejaha : BaseCreature { [Constructible] - public Alejaha() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Alejaha() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the wise"; Race = Race.Elf; Body = 0x25E; Female = true; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -2333,14 +2338,15 @@ namespace Server.Engines.MLQuests.Definitions public class Mielan : BaseCreature { [Constructible] - public Mielan() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Mielan() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the arcanist"; Race = Race.Elf; Body = 0x25D; Female = false; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -2396,14 +2402,15 @@ namespace Server.Engines.MLQuests.Definitions public class Ciala : BaseCreature { [Constructible] - public Ciala() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Ciala() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the arborist"; Race = Race.Elf; Body = 0x25E; Female = true; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -2467,14 +2474,15 @@ namespace Server.Engines.MLQuests.Definitions public class Aniel : BaseCreature { [Constructible] - public Aniel() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Aniel() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the arborist"; Race = Race.Elf; Body = 0x25D; Female = false; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -2530,14 +2538,15 @@ namespace Server.Engines.MLQuests.Definitions public class Aulan : BaseCreature { [Constructible] - public Aulan() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Aulan() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the expeditionist"; Race = Race.Elf; Body = 0x25D; Female = false; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -2607,14 +2616,15 @@ namespace Server.Engines.MLQuests.Definitions public class Brinnae : BaseCreature { [Constructible] - public Brinnae() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Brinnae() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the wise"; Race = Race.Elf; Body = 0x25E; Female = true; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -2666,14 +2676,15 @@ namespace Server.Engines.MLQuests.Definitions public class Caelas : BaseCreature { [Constructible] - public Caelas() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Caelas() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the wise"; Race = Race.Elf; Body = 0x25D; Female = false; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -2729,14 +2740,15 @@ namespace Server.Engines.MLQuests.Definitions public class Clehin : BaseCreature { [Constructible] - public Clehin() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Clehin() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the soil nurturer"; Race = Race.Elf; Body = 0x25E; Female = true; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -2790,14 +2802,15 @@ namespace Server.Engines.MLQuests.Definitions public class Cloorne : BaseCreature { [Constructible] - public Cloorne() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Cloorne() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the expeditionist"; Race = Race.Elf; Body = 0x25D; Female = false; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -2866,14 +2879,15 @@ namespace Server.Engines.MLQuests.Definitions public class Salaenih : BaseCreature { [Constructible] - public Salaenih() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Salaenih() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the expeditionist"; Race = Race.Elf; Body = 0x25E; Female = true; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -2949,14 +2963,15 @@ namespace Server.Engines.MLQuests.Definitions public class Vilo : BaseCreature { [Constructible] - public Vilo() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Vilo() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the guard"; Race = Race.Elf; Body = 0x25D; Female = false; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -3016,14 +3031,15 @@ namespace Server.Engines.MLQuests.Definitions public class Tholef : BaseCreature { [Constructible] - public Tholef() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Tholef() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the grape tender"; Race = Race.Elf; Body = 0x25D; Female = false; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -3085,14 +3101,15 @@ namespace Server.Engines.MLQuests.Definitions public class Tillanil : BaseCreature { [Constructible] - public Tillanil() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Tillanil() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the grape tender"; Race = Race.Elf; Body = 0x25E; Female = true; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -3147,14 +3164,15 @@ namespace Server.Engines.MLQuests.Definitions public class Waelian : BaseCreature { [Constructible] - public Waelian() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Waelian() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the trinket weaver"; Race = Race.Elf; Body = 0x25D; Female = false; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -3216,14 +3234,15 @@ namespace Server.Engines.MLQuests.Definitions public class Sleen : BaseCreature { [Constructible] - public Sleen() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Sleen() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the trinket weaver"; Race = Race.Elf; Body = 0x25E; Female = true; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -3279,14 +3298,15 @@ namespace Server.Engines.MLQuests.Definitions public class Unoelil : BaseCreature { [Constructible] - public Unoelil() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Unoelil() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the bark weaver"; Race = Race.Elf; Body = 0x25E; Female = true; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -3341,14 +3361,15 @@ namespace Server.Engines.MLQuests.Definitions public class Anolly : BaseCreature { [Constructible] - public Anolly() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Anolly() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the bark weaver"; Race = Race.Elf; Body = 0x25D; Female = false; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -3390,14 +3411,15 @@ namespace Server.Engines.MLQuests.Definitions public class Jusae : BaseCreature { [Constructible] - public Jusae() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Jusae() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the bowcrafter"; Race = Race.Elf; Body = 0x25D; Female = false; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -3462,14 +3484,15 @@ namespace Server.Engines.MLQuests.Definitions public class Cillitha : BaseCreature { [Constructible] - public Cillitha() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Cillitha() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the bowcrafter"; Race = Race.Elf; Body = 0x25E; Female = true; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -3524,14 +3547,15 @@ namespace Server.Engines.MLQuests.Definitions public class Lohn : BaseCreature { [Constructible] - public Lohn() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Lohn() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the metal weaver"; Race = Race.Elf; Body = 0x25D; Female = false; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -3593,14 +3617,15 @@ namespace Server.Engines.MLQuests.Definitions public class Olla : BaseCreature { [Constructible] - public Olla() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Olla() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the metal weaver"; Race = Race.Elf; Body = 0x25E; Female = true; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -3657,14 +3682,15 @@ namespace Server.Engines.MLQuests.Definitions public class Thallary : BaseCreature { [Constructible] - public Thallary() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Thallary() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the cloth weaver"; Race = Race.Elf; Body = 0x25D; Female = false; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -3720,14 +3746,15 @@ namespace Server.Engines.MLQuests.Definitions public class Ahie : BaseCreature { [Constructible] - public Ahie() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Ahie() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the cloth weaver"; Race = Race.Elf; Body = 0x25E; Female = true; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -3782,14 +3809,15 @@ namespace Server.Engines.MLQuests.Definitions public class Tyeelor : BaseCreature { [Constructible] - public Tyeelor() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Tyeelor() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the expeditionist"; Race = Race.Elf; Body = 0x25D; Female = false; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -3845,14 +3873,15 @@ namespace Server.Engines.MLQuests.Definitions public class Athailon : BaseCreature { [Constructible] - public Athailon() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Athailon() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the expeditionist"; Race = Race.Elf; Body = 0x25E; Female = true; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -3906,14 +3935,15 @@ namespace Server.Engines.MLQuests.Definitions public class ElderTaellia : BaseCreature { [Constructible] - public ElderTaellia() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public ElderTaellia() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the wise"; Race = Race.Elf; Body = 0x25E; Female = true; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -3950,14 +3980,15 @@ namespace Server.Engines.MLQuests.Definitions public class ElderMallew : BaseCreature { [Constructible] - public ElderMallew() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public ElderMallew() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the wise"; Race = Race.Elf; Body = 0x25D; Female = false; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -4007,14 +4038,15 @@ namespace Server.Engines.MLQuests.Definitions public class ElderAbbein : BaseCreature { [Constructible] - public ElderAbbein() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public ElderAbbein() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the wise"; Race = Race.Elf; Body = 0x25E; Female = true; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -4050,14 +4082,15 @@ namespace Server.Engines.MLQuests.Definitions public class ElderVicaie : BaseCreature { [Constructible] - public ElderVicaie() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public ElderVicaie() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the wise"; Race = Race.Elf; Body = 0x25E; Female = true; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -4098,14 +4131,15 @@ namespace Server.Engines.MLQuests.Definitions public class ElderJothan : BaseCreature { [Constructible] - public ElderJothan() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public ElderJothan() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the wise"; Race = Race.Elf; Body = 0x25D; Female = false; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -4143,14 +4177,15 @@ namespace Server.Engines.MLQuests.Definitions public class ElderAlethanian : BaseCreature { [Constructible] - public ElderAlethanian() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public ElderAlethanian() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the wise"; Race = Race.Elf; Body = 0x25E; Female = true; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -4188,14 +4223,15 @@ namespace Server.Engines.MLQuests.Definitions public class Rebinil : BaseCreature { [Constructible] - public Rebinil() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Rebinil() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the healer"; Race = Race.Elf; Body = 0x25E; Female = true; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -4231,14 +4267,15 @@ namespace Server.Engines.MLQuests.Definitions public class Aluniol : BaseCreature { [Constructible] - public Aluniol() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Aluniol() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the healer"; Race = Race.Elf; Body = 0x25D; Female = false; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -4274,14 +4311,15 @@ namespace Server.Engines.MLQuests.Definitions public class Olaeni : BaseCreature { [Constructible] - public Olaeni() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Olaeni() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the thaumaturgist"; Race = Race.Elf; Body = 0x25E; Female = true; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -4318,14 +4356,15 @@ namespace Server.Engines.MLQuests.Definitions public class Bolaevin : BaseCreature { [Constructible] - public Bolaevin() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Bolaevin() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the arcanist"; Race = Race.Elf; Body = 0x25D; Female = false; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -4368,14 +4407,15 @@ namespace Server.Engines.MLQuests.Definitions public class LorekeeperAneen : BaseCreature { [Constructible] - public LorekeeperAneen() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public LorekeeperAneen() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the keeper of tradition"; Race = Race.Elf; Body = 0x25D; Female = false; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -4411,14 +4451,15 @@ namespace Server.Engines.MLQuests.Definitions public class Daelas : BaseCreature { [Constructible] - public Daelas() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Daelas() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the arborist"; Race = Race.Elf; Body = 0x25D; Female = false; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -4463,14 +4504,15 @@ namespace Server.Engines.MLQuests.Definitions public class Alelle : BaseCreature { [Constructible] - public Alelle() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Alelle() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the arborist"; Race = Race.Elf; Body = 0x25E; Female = true; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -4519,14 +4561,15 @@ namespace Server.Engines.MLQuests.Definitions public class LorekeeperNillaen : BaseCreature { [Constructible] - public LorekeeperNillaen() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public LorekeeperNillaen() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the keeper of tradition"; Race = Race.Elf; Body = 0x25E; Female = true; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -4570,14 +4613,15 @@ namespace Server.Engines.MLQuests.Definitions public class LorekeeperRyal : BaseCreature { [Constructible] - public LorekeeperRyal() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public LorekeeperRyal() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the keeper of tradition"; Race = Race.Elf; Body = 0x25D; Female = false; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -4634,14 +4678,15 @@ namespace Server.Engines.MLQuests.Definitions public class Braen : BaseCreature { [Constructible] - public Braen() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Braen() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the thaumaturgist"; Race = Race.Elf; Body = 0x25D; Female = false; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -4689,14 +4734,15 @@ namespace Server.Engines.MLQuests.Definitions public class ElderAcob : BaseCreature { [Constructible] - public ElderAcob() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public ElderAcob() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the wise"; Race = Race.Elf; Body = 0x25D; Female = false; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -4743,14 +4789,15 @@ namespace Server.Engines.MLQuests.Definitions public class LorekeeperCalendor : BaseCreature { [Constructible] - public LorekeeperCalendor() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public LorekeeperCalendor() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the keeper of tradition"; Race = Race.Elf; Body = 0x25E; Female = true; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -4798,14 +4845,15 @@ namespace Server.Engines.MLQuests.Definitions public class LorekeeperSiarra : BaseCreature { [Constructible] - public LorekeeperSiarra() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public LorekeeperSiarra() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the keeper of tradition"; Race = Race.Elf; Body = 0x25E; Female = true; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); diff --git a/Projects/UOContent/Engines/ML Quests/Definitions/Heritage.cs b/Projects/UOContent/Engines/ML Quests/Definitions/Heritage.cs index 4284e0906..92fa5d7bb 100644 --- a/Projects/UOContent/Engines/ML Quests/Definitions/Heritage.cs +++ b/Projects/UOContent/Engines/ML Quests/Definitions/Heritage.cs @@ -278,12 +278,12 @@ namespace Server.Engines.MLQuests.Definitions public class Enigma : BaseCreature { [Constructible] - public Enigma() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Enigma() : base(AIType.AI_Vendor, FightMode.None, 2) { Body = 788; BaseSoundID = 0x3EE; + SetSpeed(0.5, 2); InitStats(100, 100, 25); } @@ -616,12 +616,13 @@ namespace Server.Engines.MLQuests.Definitions public class Sledge : BaseCreature { [Constructible] - public Sledge() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Sledge() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the Versatile"; Body = 400; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); AddItem(new Tunic(Utility.RandomNeutralHue())); @@ -671,12 +672,13 @@ namespace Server.Engines.MLQuests.Definitions public class Patricus : BaseCreature { [Constructible] - public Patricus() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Patricus() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the Trader"; Body = 400; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); AddItem(new FancyShirt(Utility.RandomNeutralHue())); @@ -713,13 +715,14 @@ namespace Server.Engines.MLQuests.Definitions public class Belulah : BaseCreature { [Constructible] - public Belulah() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Belulah() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the scorned"; Female = true; Body = 401; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); diff --git a/Projects/UOContent/Engines/ML Quests/Definitions/HonestBeggar.cs b/Projects/UOContent/Engines/ML Quests/Definitions/HonestBeggar.cs index 3173d8179..d9f5a2bdb 100644 --- a/Projects/UOContent/Engines/ML Quests/Definitions/HonestBeggar.cs +++ b/Projects/UOContent/Engines/ML Quests/Definitions/HonestBeggar.cs @@ -55,14 +55,15 @@ namespace Server.Engines.MLQuests.Definitions public class Evan : BaseCreature { [Constructible] - public Evan() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Evan() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the Beggar"; Race = Race.Human; Body = 0x190; Female = false; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -98,14 +99,15 @@ namespace Server.Engines.MLQuests.Definitions public class Regina : BaseCreature { [Constructible] - public Regina() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Regina() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the Noble"; Race = Race.Human; Body = 0x191; Female = true; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); diff --git a/Projects/UOContent/Engines/ML Quests/Definitions/Ilshenar.cs b/Projects/UOContent/Engines/ML Quests/Definitions/Ilshenar.cs index 394010258..3d9967a7a 100644 --- a/Projects/UOContent/Engines/ML Quests/Definitions/Ilshenar.cs +++ b/Projects/UOContent/Engines/ML Quests/Definitions/Ilshenar.cs @@ -174,12 +174,13 @@ namespace Server.Engines.MLQuests.Definitions public class GrandpaCharley : BaseCreature { [Constructible] - public GrandpaCharley() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public GrandpaCharley() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the farmer"; Body = 400; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); var hairHue = 0x3B2 + Utility.Random(2); @@ -226,14 +227,15 @@ namespace Server.Engines.MLQuests.Definitions public class Jelrice : BaseCreature { [Constructible] - public Jelrice() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Jelrice() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the trader"; Race = Race.Human; Body = 0x191; Female = true; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -276,14 +278,15 @@ namespace Server.Engines.MLQuests.Definitions public class Yorus : BaseCreature { [Constructible] - public Yorus() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Yorus() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the tinker"; Race = Race.Human; Body = 0x190; Female = false; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); diff --git a/Projects/UOContent/Engines/ML Quests/Definitions/Malas.cs b/Projects/UOContent/Engines/ML Quests/Definitions/Malas.cs index 5e3d974ea..0c60b8265 100644 --- a/Projects/UOContent/Engines/ML Quests/Definitions/Malas.cs +++ b/Projects/UOContent/Engines/ML Quests/Definitions/Malas.cs @@ -27,14 +27,15 @@ namespace Server.Engines.MLQuests.Definitions public class Drithen : BaseCreature { [Constructible] - public Drithen() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Drithen() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the Fierce"; Race = Race.Human; Body = 0x190; Female = false; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); AddItem(new Backpack()); diff --git a/Projects/UOContent/Engines/ML Quests/Definitions/MistakenIdentity.cs b/Projects/UOContent/Engines/ML Quests/Definitions/MistakenIdentity.cs index 057188b8d..cb07d63cb 100644 --- a/Projects/UOContent/Engines/ML Quests/Definitions/MistakenIdentity.cs +++ b/Projects/UOContent/Engines/ML Quests/Definitions/MistakenIdentity.cs @@ -195,14 +195,15 @@ namespace Server.Engines.MLQuests.Definitions public class Aernya : BaseCreature { [Constructible] - public Aernya() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Aernya() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the Mistress of Admissions"; Race = Race.Human; Body = 0x191; Female = true; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -241,14 +242,15 @@ namespace Server.Engines.MLQuests.Definitions public class Gorrow : BaseCreature { [Constructible] - public Gorrow() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Gorrow() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the Mayor"; Race = Race.Human; Body = 0x190; Female = false; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); AddItem(new Backpack()); @@ -298,14 +300,15 @@ namespace Server.Engines.MLQuests.Definitions public class MasterGnosos : BaseCreature { [Constructible] - public MasterGnosos() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public MasterGnosos() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the necromancer"; Race = Race.Human; Body = 0x190; Female = false; Hue = 0x83E8; + + SetSpeed(0.5, 2); InitStats(100, 100, 25); HairItemID = 0x2049; diff --git a/Projects/UOContent/Engines/ML Quests/Definitions/NewHavenSkillTraining.cs b/Projects/UOContent/Engines/ML Quests/Definitions/NewHavenSkillTraining.cs index d0d38411c..5e4535cd1 100644 --- a/Projects/UOContent/Engines/ML Quests/Definitions/NewHavenSkillTraining.cs +++ b/Projects/UOContent/Engines/ML Quests/Definitions/NewHavenSkillTraining.cs @@ -654,6 +654,7 @@ namespace Server.Engines.MLQuests.Definitions FacialHairItemID = 0x204D; FacialHairHue = 0x47D; + SetSpeed(0.5, 2); InitStats(100, 100, 25); SetSkill(SkillName.Anatomy, 120.0); @@ -708,8 +709,7 @@ namespace Server.Engines.MLQuests.Definitions public class Dimethro : BaseCreature { [Constructible] - public Dimethro() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Dimethro() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the Wrestling Instructor"; Body = 0x190; @@ -719,6 +719,7 @@ namespace Server.Engines.MLQuests.Definitions FacialHairItemID = 0x204D; FacialHairHue = 0x455; + SetSpeed(0.5, 2); InitStats(100, 100, 25); SetSkill(SkillName.EvalInt, 120.0); @@ -767,8 +768,7 @@ namespace Server.Engines.MLQuests.Definitions public class Churchill : BaseCreature { [Constructible] - public Churchill() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Churchill() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the Mace Fighting Instructor"; Body = 0x190; @@ -776,6 +776,7 @@ namespace Server.Engines.MLQuests.Definitions HairItemID = 0x203C; HairHue = 0x455; + SetSpeed(0.5, 2); InitStats(100, 100, 25); SetSkill(SkillName.Anatomy, 120.0); @@ -854,6 +855,7 @@ namespace Server.Engines.MLQuests.Definitions HairHue = 0x47D; Female = true; + SetSpeed(0.5, 2); InitStats(100, 100, 25); SetSkill(SkillName.Anatomy, 120.0); @@ -927,8 +929,7 @@ namespace Server.Engines.MLQuests.Definitions public class Recaro : BaseCreature { [Constructible] - public Recaro() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Recaro() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the Fencer Instructor"; Body = 0x190; @@ -938,6 +939,7 @@ namespace Server.Engines.MLQuests.Definitions FacialHairItemID = 0x204D; FacialHairHue = 0x455; + SetSpeed(0.5, 2); InitStats(100, 100, 25); SetSkill(SkillName.Anatomy, 120.0); @@ -1011,8 +1013,7 @@ namespace Server.Engines.MLQuests.Definitions public class AldenArmstrong : BaseCreature { [Constructible] - public AldenArmstrong() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public AldenArmstrong() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the Tactics Instructor"; Body = 0x190; @@ -1020,6 +1021,7 @@ namespace Server.Engines.MLQuests.Definitions HairItemID = 0x203B; HairHue = 0x44E; + SetSpeed(0.5, 2); InitStats(100, 100, 25); SetSkill(SkillName.Anatomy, 120.0); @@ -1076,8 +1078,7 @@ namespace Server.Engines.MLQuests.Definitions public class Jockles : BaseCreature { [Constructible] - public Jockles() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Jockles() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the Swordsmanship Instructor"; Body = 0x190; @@ -1085,6 +1086,7 @@ namespace Server.Engines.MLQuests.Definitions HairItemID = 0x203C; HairHue = 0x8A7; + SetSpeed(0.5, 2); InitStats(100, 100, 25); SetSkill(SkillName.Anatomy, 120.0); @@ -1137,14 +1139,14 @@ namespace Server.Engines.MLQuests.Definitions public class TylAriadne : BaseCreature { [Constructible] - public TylAriadne() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public TylAriadne() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the Parrying Instructor"; Body = 0x190; Hue = 0x8374; HairItemID = 0; + SetSpeed(0.5, 2); InitStats(100, 100, 25); SetSkill(SkillName.Anatomy, 120.0); @@ -1218,8 +1220,7 @@ namespace Server.Engines.MLQuests.Definitions public class Alefian : BaseCreature { [Constructible] - public Alefian() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Alefian() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the Resisting Spells Instructor"; Body = 0x190; @@ -1227,6 +1228,7 @@ namespace Server.Engines.MLQuests.Definitions HairItemID = 0x203D; HairHue = 0x457; + SetSpeed(0.5, 2); InitStats(100, 100, 25); SetSkill(SkillName.EvalInt, 120.0); @@ -1274,8 +1276,7 @@ namespace Server.Engines.MLQuests.Definitions public class Gustar : BaseCreature { [Constructible] - public Gustar() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Gustar() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the Meditation Instructor"; Body = 0x190; @@ -1283,6 +1284,7 @@ namespace Server.Engines.MLQuests.Definitions HairItemID = 0x203B; HairHue = 0x455; + SetSpeed(0.5, 2); InitStats(100, 100, 25); SetSkill(SkillName.EvalInt, 120.0); @@ -1356,8 +1358,7 @@ namespace Server.Engines.MLQuests.Definitions public class Jillian : BaseCreature { [Constructible] - public Jillian() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Jillian() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the Inscription Instructor"; Body = 0x191; @@ -1366,6 +1367,7 @@ namespace Server.Engines.MLQuests.Definitions HairItemID = 0x203D; HairHue = 0x455; + SetSpeed(0.5, 2); InitStats(100, 100, 25); SetSkill(SkillName.EvalInt, 120.0); @@ -1413,8 +1415,7 @@ namespace Server.Engines.MLQuests.Definitions public class Kaelynna : BaseCreature { [Constructible] - public Kaelynna() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Kaelynna() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the Magery Instructor"; Body = 0x191; @@ -1423,6 +1424,7 @@ namespace Server.Engines.MLQuests.Definitions HairItemID = 0x203C; HairHue = 0x47D; + SetSpeed(0.5, 2); InitStats(100, 100, 25); SetSkill(SkillName.EvalInt, 120.0); @@ -1470,8 +1472,7 @@ namespace Server.Engines.MLQuests.Definitions public class Mithneral : BaseCreature { [Constructible] - public Mithneral() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Mithneral() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the Evaluating Intelligence Instructor"; Body = 0x190; @@ -1479,6 +1480,7 @@ namespace Server.Engines.MLQuests.Definitions HairItemID = 0x203C; HairHue = 0x455; + SetSpeed(0.5, 2); InitStats(100, 100, 25); SetSkill(SkillName.EvalInt, 120.0); @@ -1540,6 +1542,7 @@ namespace Server.Engines.MLQuests.Definitions HairItemID = 0x203D; HairHue = 0x46C; + SetSpeed(0.5, 2); InitStats(100, 100, 25); SetSkill(SkillName.ArmsLore, 120.0); @@ -1591,8 +1594,7 @@ namespace Server.Engines.MLQuests.Definitions public class AndreasVesalius : BaseCreature { [Constructible] - public AndreasVesalius() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public AndreasVesalius() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the Anatomy Instructor"; Body = 0x190; @@ -1602,6 +1604,7 @@ namespace Server.Engines.MLQuests.Definitions FacialHairItemID = 0x203E; FacialHairHue = 0x477; + SetSpeed(0.5, 2); InitStats(100, 100, 25); SetSkill(SkillName.Anatomy, 120.0); @@ -1651,8 +1654,7 @@ namespace Server.Engines.MLQuests.Definitions public class Avicenna : BaseCreature { [Constructible] - public Avicenna() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Avicenna() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the Healing Instructor"; Body = 0x190; @@ -1660,6 +1662,7 @@ namespace Server.Engines.MLQuests.Definitions HairItemID = 0x203B; HairHue = 0x477; + SetSpeed(0.5, 2); InitStats(100, 100, 25); SetSkill(SkillName.Anatomy, 120.0); @@ -1708,8 +1711,7 @@ namespace Server.Engines.MLQuests.Definitions public class SarsmeaSmythe : BaseCreature { [Constructible] - public SarsmeaSmythe() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public SarsmeaSmythe() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the Focus Instructor"; Body = 0x191; @@ -1718,6 +1720,7 @@ namespace Server.Engines.MLQuests.Definitions HairItemID = 0x203C; HairHue = 0x456; + SetSpeed(0.5, 2); InitStats(100, 100, 25); SetSkill(SkillName.Anatomy, 120.0); @@ -1840,12 +1843,12 @@ namespace Server.Engines.MLQuests.Definitions public class Chiyo : BaseCreature { [Constructible] - public Chiyo() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Chiyo() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the Hiding Instructor"; Body = 0xF7; + SetSpeed(0.5, 2); InitStats(100, 100, 25); SetSkill(SkillName.Hiding, 120.0); @@ -1889,8 +1892,7 @@ namespace Server.Engines.MLQuests.Definitions public class Jun : BaseCreature { [Constructible] - public Jun() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Jun() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the Stealth Instructor"; Body = 0x190; @@ -1898,6 +1900,7 @@ namespace Server.Engines.MLQuests.Definitions HairItemID = 0x203B; HairHue = 0x455; + SetSpeed(0.5, 2); InitStats(100, 100, 25); SetSkill(SkillName.Hiding, 120.0); @@ -1949,8 +1952,7 @@ namespace Server.Engines.MLQuests.Definitions public class Walker : BaseCreature { [Constructible] - public Walker() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Walker() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the Tracking Instructor"; Body = 0x190; @@ -1960,6 +1962,7 @@ namespace Server.Engines.MLQuests.Definitions FacialHairItemID = 0x204B; FacialHairHue = 0x47D; + SetSpeed(0.5, 2); InitStats(100, 100, 25); SetSkill(SkillName.Hiding, 120.0); @@ -2097,6 +2100,7 @@ namespace Server.Engines.MLQuests.Definitions HairItemID = 0x203D; HairHue = 0x457; + SetSpeed(0.5, 2); InitStats(100, 100, 25); SetSkill(SkillName.Magery, 120.0); @@ -2176,6 +2180,7 @@ namespace Server.Engines.MLQuests.Definitions HairItemID = 0x203C; HairHue = 0x455; + SetSpeed(0.5, 2); InitStats(100, 100, 25); SetSkill(SkillName.Magery, 120.0); @@ -2225,8 +2230,7 @@ namespace Server.Engines.MLQuests.Definitions public class JacobWaltz : BaseCreature { [Constructible] - public JacobWaltz() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public JacobWaltz() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the Miner Instructor"; Body = 0x190; @@ -2236,6 +2240,7 @@ namespace Server.Engines.MLQuests.Definitions FacialHairItemID = 0x204D; FacialHairHue = 0x44E; + SetSpeed(0.5, 2); InitStats(100, 100, 25); SetSkill(SkillName.ArmsLore, 120.0); @@ -2296,6 +2301,7 @@ namespace Server.Engines.MLQuests.Definitions HairItemID = 0x203B; HairHue = 0x47B; + SetSpeed(0.5, 2); InitStats(100, 100, 25); SetSkill(SkillName.ArmsLore, 120.0); diff --git a/Projects/UOContent/Engines/ML Quests/Definitions/NewHavenTraining.cs b/Projects/UOContent/Engines/ML Quests/Definitions/NewHavenTraining.cs index 3eeccc7b0..97ebd7e94 100644 --- a/Projects/UOContent/Engines/ML Quests/Definitions/NewHavenTraining.cs +++ b/Projects/UOContent/Engines/ML Quests/Definitions/NewHavenTraining.cs @@ -262,14 +262,15 @@ namespace Server.Engines.MLQuests.Definitions public class Andric : BaseCreature { [Constructible] - public Andric() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Andric() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the archer trainer"; Race = Race.Human; Body = 0x190; Female = false; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -340,14 +341,15 @@ namespace Server.Engines.MLQuests.Definitions public class Kashiel : BaseCreature { [Constructible] - public Kashiel() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Kashiel() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the archer"; Race = Race.Human; Body = 0x191; Female = true; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -402,14 +404,15 @@ namespace Server.Engines.MLQuests.Definitions public class Asandos : BaseCreature { [Constructible] - public Asandos() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Asandos() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the chef"; Race = Race.Human; Body = 0x190; Female = false; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -462,14 +465,15 @@ namespace Server.Engines.MLQuests.Definitions public class Clairesse : BaseCreature { [Constructible] - public Clairesse() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Clairesse() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the servant"; Race = Race.Human; Body = 0x191; Female = true; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -518,14 +522,15 @@ namespace Server.Engines.MLQuests.Definitions public class Gervis : BaseCreature { [Constructible] - public Gervis() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Gervis() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the blacksmith trainer"; Race = Race.Human; Body = 0x190; Female = false; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -586,14 +591,15 @@ namespace Server.Engines.MLQuests.Definitions public class Mugg : BaseCreature { [Constructible] - public Mugg() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Mugg() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the miner"; Race = Race.Human; Body = 0x190; Female = false; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -639,14 +645,15 @@ namespace Server.Engines.MLQuests.Definitions public class Lowel : BaseCreature { [Constructible] - public Lowel() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Lowel() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the carpenter"; Race = Race.Human; Body = 0x190; Female = false; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -697,14 +704,15 @@ namespace Server.Engines.MLQuests.Definitions public class Lyle : BaseCreature { [Constructible] - public Lyle() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Lyle() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the mage"; Race = Race.Human; Body = 0x190; Female = false; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -753,14 +761,15 @@ namespace Server.Engines.MLQuests.Definitions public class Nibbet : BaseCreature { [Constructible] - public Nibbet() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Nibbet() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the tinker"; Race = Race.Human; Body = 0x190; Female = false; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -798,14 +807,15 @@ namespace Server.Engines.MLQuests.Definitions public class Norton : BaseCreature { [Constructible] - public Norton() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Norton() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the fisher"; Race = Race.Human; Body = 0x190; Female = false; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -856,14 +866,15 @@ namespace Server.Engines.MLQuests.Definitions public class Sadrah : BaseCreature { [Constructible] - public Sadrah() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Sadrah() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the courier"; Race = Race.Human; Body = 0x191; Female = true; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -916,14 +927,15 @@ namespace Server.Engines.MLQuests.Definitions public class Hargrove : BaseCreature { [Constructible] - public Hargrove() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Hargrove() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the Lumberjack"; Race = Race.Human; Body = 0x190; Female = false; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2); InitStats(100, 100, 25); Utility.AssignRandomHair(this); diff --git a/Projects/UOContent/Engines/ML Quests/Definitions/Sanctuary.cs b/Projects/UOContent/Engines/ML Quests/Definitions/Sanctuary.cs index 97a363595..5424438d0 100644 --- a/Projects/UOContent/Engines/ML Quests/Definitions/Sanctuary.cs +++ b/Projects/UOContent/Engines/ML Quests/Definitions/Sanctuary.cs @@ -762,13 +762,15 @@ namespace Server.Engines.MLQuests.Definitions { [Constructible] public Beotham() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the bowcrafter"; Race = Race.Elf; Body = 0x25D; Female = false; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -828,14 +830,15 @@ namespace Server.Engines.MLQuests.Definitions public class Danoel : BaseCreature { [Constructible] - public Danoel() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Danoel() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the metal weaver"; Race = Race.Elf; Body = 0x25D; Female = false; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -886,14 +889,15 @@ namespace Server.Engines.MLQuests.Definitions public class Tallinin : BaseCreature { [Constructible] - public Tallinin() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Tallinin() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the cloth weaver"; Race = Race.Elf; Body = 0x25E; Female = true; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -947,14 +951,15 @@ namespace Server.Engines.MLQuests.Definitions public class Tiana : BaseCreature { [Constructible] - public Tiana() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Tiana() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the guard"; Race = Race.Elf; Body = 0x25E; Female = true; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -1018,14 +1023,15 @@ namespace Server.Engines.MLQuests.Definitions public class LorekeeperOolua : BaseCreature { [Constructible] - public LorekeeperOolua() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public LorekeeperOolua() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the keeper of tradition"; Race = Race.Elf; Body = 0x25E; Female = true; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -1075,14 +1081,15 @@ namespace Server.Engines.MLQuests.Definitions public class LorekeeperRollarn : BaseCreature { [Constructible] - public LorekeeperRollarn() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public LorekeeperRollarn() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the keeper of tradition"; Race = Race.Elf; Body = 0x25D; Female = false; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -1143,14 +1150,15 @@ namespace Server.Engines.MLQuests.Definitions public class Dallid : BaseCreature { [Constructible] - public Dallid() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Dallid() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the cook"; Race = Race.Elf; Body = 0x25D; Female = false; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -1206,14 +1214,15 @@ namespace Server.Engines.MLQuests.Definitions public class Canir : BaseCreature { [Constructible] - public Canir() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Canir() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the thaumaturgist"; Race = Race.Elf; Body = 0x25E; Female = true; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -1267,14 +1276,15 @@ namespace Server.Engines.MLQuests.Definitions public class Yellienir : BaseCreature { [Constructible] - public Yellienir() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Yellienir() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the bark weaver"; Race = Race.Elf; Body = 0x25E; Female = true; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -1313,14 +1323,15 @@ namespace Server.Engines.MLQuests.Definitions public class ElderOnallan : BaseCreature { [Constructible] - public ElderOnallan() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public ElderOnallan() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the wise"; Race = Race.Elf; Body = 0x25D; Female = false; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); diff --git a/Projects/UOContent/Engines/ML Quests/Definitions/Spellweaving.cs b/Projects/UOContent/Engines/ML Quests/Definitions/Spellweaving.cs index 38104cf18..edfbfa3f7 100644 --- a/Projects/UOContent/Engines/ML Quests/Definitions/Spellweaving.cs +++ b/Projects/UOContent/Engines/ML Quests/Definitions/Spellweaving.cs @@ -493,14 +493,15 @@ namespace Server.Engines.MLQuests.Definitions public class Aeluva : BaseCreature { [Constructible] - public Aeluva() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2.0) + public Aeluva() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the arcanist"; Race = Race.Elf; Female = true; Body = 606; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -552,13 +553,14 @@ namespace Server.Engines.MLQuests.Definitions public class Koole : BaseCreature { [Constructible] - public Koole() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2.0) + public Koole() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the arcanist"; Race = Race.Elf; Body = 605; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -622,14 +624,15 @@ namespace Server.Engines.MLQuests.Definitions public class Synaeva : BaseCreature { [Constructible] - public Synaeva() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2.0) + public Synaeva() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the arcanist"; Race = Race.Elf; Female = true; Body = 606; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -682,14 +685,15 @@ namespace Server.Engines.MLQuests.Definitions public class ElderBrae : BaseCreature { [Constructible] - public ElderBrae() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2.0) + public ElderBrae() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the wise"; Race = Race.Elf; Female = true; Body = 606; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); diff --git a/Projects/UOContent/Engines/ML Quests/Definitions/TheAncientWorld.cs b/Projects/UOContent/Engines/ML Quests/Definitions/TheAncientWorld.cs index 61a66f811..37d732311 100644 --- a/Projects/UOContent/Engines/ML Quests/Definitions/TheAncientWorld.cs +++ b/Projects/UOContent/Engines/ML Quests/Definitions/TheAncientWorld.cs @@ -98,14 +98,15 @@ namespace Server.Engines.MLQuests.Definitions public class LorekeeperBroolol : BaseCreature { [Constructible] - public LorekeeperBroolol() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public LorekeeperBroolol() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the keeper of tradition"; Race = Race.Elf; Body = 0x25E; Female = true; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); diff --git a/Projects/UOContent/Engines/ML Quests/Definitions/UnfadingMemories.cs b/Projects/UOContent/Engines/ML Quests/Definitions/UnfadingMemories.cs index cfa189062..fec2e21be 100644 --- a/Projects/UOContent/Engines/ML Quests/Definitions/UnfadingMemories.cs +++ b/Projects/UOContent/Engines/ML Quests/Definitions/UnfadingMemories.cs @@ -83,14 +83,15 @@ namespace Server.Engines.MLQuests.Definitions public class Emilio : BaseCreature { [Constructible] - public Emilio() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Emilio() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the Tortured Artist"; Race = Race.Human; Body = 0x190; Female = false; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -130,14 +131,15 @@ namespace Server.Engines.MLQuests.Definitions public class Thalia : BaseCreature { [Constructible] - public Thalia() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public Thalia() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the Bride"; Race = Race.Human; Body = 0x191; Female = true; Hue = Race.RandomSkinHue(); + + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); diff --git a/Projects/UOContent/Engines/ML Quests/Mobiles/BoonCollector.cs b/Projects/UOContent/Engines/ML Quests/Mobiles/BoonCollector.cs index 9ab500594..b6c00bcc4 100644 --- a/Projects/UOContent/Engines/ML Quests/Mobiles/BoonCollector.cs +++ b/Projects/UOContent/Engines/ML Quests/Mobiles/BoonCollector.cs @@ -12,9 +12,9 @@ namespace Server.Engines.MLQuests.Mobiles { private InternalTimer m_Timer; - public DoneQuestCollector() - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public DoneQuestCollector() : base(AIType.AI_Vendor, FightMode.None, 2) { + SetSpeed(0.5, 2.0); } public DoneQuestCollector(Serial serial) diff --git a/Projects/UOContent/Mobiles/AI/BaseAI.cs b/Projects/UOContent/Mobiles/AI/BaseAI.cs index e7d8c2994..dc6e47c81 100644 --- a/Projects/UOContent/Mobiles/AI/BaseAI.cs +++ b/Projects/UOContent/Mobiles/AI/BaseAI.cs @@ -1037,7 +1037,7 @@ namespace Server.Mobiles public virtual bool Obey() { - var shouldObey = !m_Mobile.Deleted && m_Mobile.ControlOrder switch + return !m_Mobile.Deleted && m_Mobile.ControlOrder switch { OrderType.None => DoOrderNone(), OrderType.Come => DoOrderCome(), @@ -1054,15 +1054,6 @@ namespace Server.Mobiles OrderType.Transfer => DoOrderTransfer(), _ => false }; - - if (shouldObey) - { - // TODO: This might cause the movement timer to reset too often if someone is spamming commands. - // Test this thoroughly. - m_Mobile.ResetSpeeds(); - } - - return shouldObey; } public virtual void OnCurrentOrderChanged() @@ -1377,6 +1368,10 @@ namespace Server.Mobiles { m_Mobile.CurrentSpeed = 0.1; } + else if (m_Mobile.CurrentSpeed == m_Mobile.ActiveSpeed && m_Mobile.ControlTarget == m_Mobile.ControlMaster) + { + m_Mobile.CurrentSpeed = Math.Max(SpeedInfo.MinDelay, m_Mobile.CurrentSpeed * 0.5); + } } } } @@ -1928,19 +1923,23 @@ namespace Server.Mobiles public double TransformMoveDelay(double delay) { - double max = m_Mobile.IsMonster ? SpeedInfo.MaxMonsterDelay : SpeedInfo.MaxDelay; + // Non-monsters in PVP combat (like pets) are penalized + if (!m_Mobile.IsMonster && m_Mobile.InActivePVPCombat() && delay <= SpeedInfo.MaxDelay) + { + delay += 0.4; + } if (!m_Mobile.IsDeadPet && (m_Mobile.ReduceSpeedWithDamage || m_Mobile.IsSubdued)) { - double offset = m_Mobile.StamMax <= 0 ? 1.0 : m_Mobile.Stam / (double)m_Mobile.StamMax; + double offset = m_Mobile.StamMax <= 0 ? 1.0 : Math.Max(0, m_Mobile.Stam) / (double)m_Mobile.StamMax; if (offset < 1.0) { - delay += (max - delay) * (1.0 - offset); + delay += delay * (1.0 - offset); } } - return Math.Min(delay, max); + return delay; } public virtual bool CheckMove() => Core.TickCount - NextMove >= 0; @@ -2696,20 +2695,20 @@ namespace Server.Mobiles { if (!m_Timer.Running) { - m_Timer.Delay = TimeSpan.Zero; + // We want to randomize the time at which the AI activates. + // This triggers when a mob is first created since it moves from the internal map to it's added location + // If we spawn lots of mobs, we don't want their AI synchronized exactly. + m_Timer.Delay = TimeSpan.FromMilliseconds(Utility.Random(48) * 8); m_Timer.Start(); } } /* - * The mobile changed it speed, we must adjust the timer + * The mobile changed speeds, we must adjust the timer */ public virtual void OnCurrentSpeedChanged() { - m_Timer.Stop(); - m_Timer.Delay = TimeSpan.FromMilliseconds(Utility.Random(128) * 8); m_Timer.Interval = TimeSpan.FromSeconds(Math.Max(0.0, m_Mobile.CurrentSpeed)); - m_Timer.Start(); } private class InternalEntry : ContextMenuEntry @@ -2989,14 +2988,12 @@ namespace Server.Mobiles { private readonly BaseAI m_Owner; - public AITimer(BaseAI owner) - : base( - TimeSpan.FromSeconds(Utility.Random(128) * 8), - TimeSpan.FromSeconds(Math.Max(0.0, owner.m_Mobile.CurrentSpeed)) - ) + public AITimer(BaseAI owner) : base( + TimeSpan.FromMilliseconds(Utility.Random(96) * 8), + TimeSpan.FromSeconds(Math.Max(0.0, owner.m_Mobile.CurrentSpeed)) + ) { m_Owner = owner; - m_Owner.m_NextDetectHidden = Core.TickCount; } diff --git a/Projects/UOContent/Mobiles/AI/LegacySpeedInfo.cs b/Projects/UOContent/Mobiles/AI/LegacySpeedInfo.cs new file mode 100644 index 000000000..d4182b3b9 --- /dev/null +++ b/Projects/UOContent/Mobiles/AI/LegacySpeedInfo.cs @@ -0,0 +1,77 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text.Json.Serialization; +using Server.Json; +using Server.Logging; + +namespace Server; + +public class LegacySpeedInfo +{ + private static readonly ILogger logger = LogFactory.GetLogger(typeof(LegacySpeedInfo)); + + private const string _tablePath = "Data/npc-speeds.json"; + private static Dictionary m_Table; + + public static bool Enabled { get; private set; } + + public static bool GetSpeeds(Type type, out double activeSpeed, out double passiveSpeed) + { + if (!(Enabled && m_Table.TryGetValue(type, out var sp))) + { + activeSpeed = 0; + passiveSpeed = 0; + return false; + } + + activeSpeed = sp.ActiveSpeed; + passiveSpeed = sp.PassiveSpeed; + + return true; + } + + public static void Configure() + { + Enabled = ServerConfiguration.GetSetting("movement.delay.useLegacySpeeds", !Core.HS); + + if (!Enabled) + { + return; + } + + var path = Path.Combine(Core.BaseDirectory, _tablePath); + if (!File.Exists(path)) + { + logger.Warning($"Cannot find {path}. Disabling legacy speed system."); + Enabled = false; + return; + } + + var speeds = JsonConfig.Deserialize(path); + + m_Table = new Dictionary(); + + for (var i = 0; i < speeds.Length; ++i) + { + var info = speeds[i]; + + foreach (var type in info.Types) + { + m_Table[type] = info; + } + } + } + + public record LegacySpeedEntry + { + [JsonPropertyName("active")] + public double ActiveSpeed { get; init; } + + [JsonPropertyName("passive")] + public double PassiveSpeed { get; init; } + + [JsonPropertyName("types")] + public HashSet Types { get; init; } + } +} diff --git a/Projects/UOContent/Mobiles/AI/MageAI.cs b/Projects/UOContent/Mobiles/AI/MageAI.cs index 9088e27f3..a27240072 100644 --- a/Projects/UOContent/Mobiles/AI/MageAI.cs +++ b/Projects/UOContent/Mobiles/AI/MageAI.cs @@ -72,12 +72,7 @@ namespace Server.Mobiles return false; } - if (ProcessTarget()) - { - return true; - } - - return base.Think(); + return ProcessTarget() || base.Think(); } public virtual double ScaleBySkill(double v, SkillName skill) => v * m_Mobile.Skills[skill].Value / 100; @@ -387,12 +382,9 @@ namespace Server.Mobiles { if (!SmartAI) { - if (ScaleBySkill(DispelChance, SkillName.Magery) > Utility.RandomDouble()) - { - return new DispelSpell(m_Mobile); - } - - return ChooseSpell(toDispel); + return ScaleBySkill(DispelChance, SkillName.Magery) > Utility.RandomDouble() + ? new DispelSpell(m_Mobile) + : ChooseSpell(toDispel); } var spell = CheckCastHealingSpell(); @@ -743,13 +735,11 @@ namespace Server.Mobiles if (m_Mobile.Hits < m_Mobile.HitsMax * 20 / 100) { // We are low on health, should we flee? - bool flee; if (m_Mobile.Hits < c.Hits) { // We are more hurt than them - var diff = c.Hits - m_Mobile.Hits; flee = Utility.Random(0, 100) > 10 + diff; // (10 + diff)% chance to flee @@ -772,7 +762,6 @@ namespace Server.Mobiles if (m_Mobile.Spell == null && Core.TickCount - m_NextCastTime >= 0 && m_Mobile.InRange(c, Core.ML ? 10 : 12)) { // We are ready to cast a spell - Spell spell; var toDispel = FindDispelTarget(true); @@ -788,18 +777,18 @@ namespace Server.Mobiles spell = DoDispel(toDispel); } - else if (SmartAI && m_Combo != -1) // We are doing a spell combo - { - spell = DoCombo(c); - } - else if (SmartAI && c.Spell is HealSpell or GreaterHealSpell && !c.Poisoned - ) // They have a heal spell out - { - spell = new PoisonSpell(m_Mobile); - } else { - spell = ChooseSpell(c); + spell = SmartAI switch + { + // We are doing a spell combo + true when m_Combo != -1 => DoCombo(c), + // They have a heal spell out + true when + !c.Poisoned && + c.Spell is HealSpell or GreaterHealSpell => new PoisonSpell(m_Mobile), + _ => ChooseSpell(c) + }; } // Now we have a spell picked diff --git a/Projects/UOContent/Mobiles/AI/SpeedInfo.cs b/Projects/UOContent/Mobiles/AI/SpeedInfo.cs index 0fbd3a62c..36811f37a 100644 --- a/Projects/UOContent/Mobiles/AI/SpeedInfo.cs +++ b/Projects/UOContent/Mobiles/AI/SpeedInfo.cs @@ -29,20 +29,19 @@ public static class SpeedInfo public static void GetSpeeds(BaseCreature bc, out double activeSpeed, out double passiveSpeed) { + // Legacy is used if it is enabled, and the type is in the table + if (LegacySpeedInfo.GetSpeeds(bc.GetType(), out activeSpeed, out passiveSpeed)) + { + return; + } + var isMonster = bc.IsMonster; - var monsterDelay = isMonster || bc.InActivePVPCombat(); var maxDex = isMonster ? MaxMonsterDex : MaxDex; var dex = Math.Clamp(bc.Dex, 25, maxDex); - double min = monsterDelay ? MinMonsterDelay : MinDelay; - double max = monsterDelay ? MaxMonsterDelay : MaxDelay; - - if (bc.IsParagon) - { - min /= 2; - max = min + 0.5; - } + double min = isMonster ? MinMonsterDelay : MinDelay; + double max = isMonster ? MaxMonsterDelay : MaxDelay; activeSpeed = Math.Max(max - (max - min) * ((double)dex / maxDex), min); passiveSpeed = activeSpeed * 2; diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/BaseMount.cs b/Projects/UOContent/Mobiles/Animals/Mounts/BaseMount.cs index 3e304765a..fcffd9646 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/BaseMount.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/BaseMount.cs @@ -11,16 +11,9 @@ namespace Server.Mobiles private Mobile m_Rider; public BaseMount( - string name, int bodyID, int itemID, AIType aiType, FightMode fightMode, int rangePerception, - int rangeFight, double activeSpeed = -1, double passiveSpeed = -1 - ) : base( - aiType, - fightMode, - rangePerception, - rangeFight, - activeSpeed, - passiveSpeed - ) + string name, int bodyID, int itemID, AIType aiType, FightMode fightMode = FightMode.Closest, + int rangePerception = 10, int rangeFight = 1 + ) : base(aiType, fightMode, rangePerception, rangeFight) { Name = name; Body = bodyID; diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/Beetle.cs b/Projects/UOContent/Mobiles/Animals/Mounts/Beetle.cs index 2a0ed620e..053385ab0 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/Beetle.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/Beetle.cs @@ -7,17 +7,7 @@ namespace Server.Mobiles public class Beetle : BaseMount { [Constructible] - public Beetle(string name = "a giant beetle") : base( - name, - 0x317, - 0x3EBC, - AIType.AI_Melee, - FightMode.Closest, - 10, - 1, - 0.25, - 0.5 - ) + public Beetle(string name = "a giant beetle") : base(name, 0x317, 0x3EBC, AIType.AI_Melee) { SetStr(300); SetDex(100); diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/DesertOstard.cs b/Projects/UOContent/Mobiles/Animals/Mounts/DesertOstard.cs index ec67254a9..e2e7516f6 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/DesertOstard.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/DesertOstard.cs @@ -3,17 +3,7 @@ namespace Server.Mobiles public class DesertOstard : BaseMount { [Constructible] - public DesertOstard(string name = "a desert ostard") : base( - name, - 0xD2, - 0x3EA3, - AIType.AI_Animal, - FightMode.Aggressor, - 10, - 1, - 0.2, - 0.4 - ) + public DesertOstard(string name = "a desert ostard") : base(name, 0xD2, 0x3EA3, AIType.AI_Animal, FightMode.Aggressor) { BaseSoundID = 0x270; diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/Ethereals.cs b/Projects/UOContent/Mobiles/Animals/Mounts/Ethereals.cs index d97216fce..83edbf3e2 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/Ethereals.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/Ethereals.cs @@ -13,8 +13,7 @@ namespace Server.Mobiles private Mobile m_Rider; [Constructible] - public EtherealMount(int itemID, int mountID) - : base(itemID) + public EtherealMount(int itemID, int mountID) : base(itemID) { m_MountedID = mountID; m_RegularID = itemID; diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/FireSteed.cs b/Projects/UOContent/Mobiles/Animals/Mounts/FireSteed.cs index cc5eba47f..5dfdd5e18 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/FireSteed.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/FireSteed.cs @@ -6,17 +6,7 @@ namespace Server.Mobiles public class FireSteed : BaseMount { [Constructible] - public FireSteed(string name = "a fire steed") : base( - name, - 0xBE, - 0x3E9E, - AIType.AI_Melee, - FightMode.Closest, - 10, - 1, - 0.2, - 0.4 - ) + public FireSteed(string name = "a fire steed") : base(name, 0xBE, 0x3E9E, AIType.AI_Melee) { BaseSoundID = 0xA8; diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/ForestOstard.cs b/Projects/UOContent/Mobiles/Animals/Mounts/ForestOstard.cs index c8a7cce51..c7b764afe 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/ForestOstard.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/ForestOstard.cs @@ -3,17 +3,7 @@ namespace Server.Mobiles public class ForestOstard : BaseMount { [Constructible] - public ForestOstard(string name = "a forest ostard") : base( - name, - 0xDB, - 0x3EA5, - AIType.AI_Animal, - FightMode.Aggressor, - 10, - 1, - 0.2, - 0.4 - ) + public ForestOstard(string name = "a forest ostard") : base(name, 0xDB, 0x3EA5, AIType.AI_Animal, FightMode.Aggressor) { Hue = Utility.RandomSlimeHue() | 0x8000; diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/FrenziedOstard.cs b/Projects/UOContent/Mobiles/Animals/Mounts/FrenziedOstard.cs index 33e7b144b..98425336e 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/FrenziedOstard.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/FrenziedOstard.cs @@ -3,17 +3,7 @@ namespace Server.Mobiles public class FrenziedOstard : BaseMount { [Constructible] - public FrenziedOstard(string name = "a frenzied ostard") : base( - name, - 0xDA, - 0x3EA4, - AIType.AI_Melee, - FightMode.Closest, - 10, - 1, - 0.2, - 0.4 - ) + public FrenziedOstard(string name = "a frenzied ostard") : base(name, 0xDA, 0x3EA4, AIType.AI_Melee) { Hue = Race.Human.RandomHairHue() | 0x8000; diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/HellSteed.cs b/Projects/UOContent/Mobiles/Animals/Mounts/HellSteed.cs index 1c2479baa..5d00d1ab3 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/HellSteed.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/HellSteed.cs @@ -3,17 +3,7 @@ namespace Server.Mobiles public class HellSteed : BaseMount { [Constructible] - public HellSteed(string name = "a hellsteed") : base( - name, - 793, - 0x3EBB, - AIType.AI_Animal, - FightMode.Aggressor, - 10, - 1, - 0.2, - 0.4 - ) + public HellSteed(string name = "a hellsteed") : base(name, 793, 0x3EBB, AIType.AI_Animal, FightMode.Aggressor) { SetStats(this); } diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/Hiryu.cs b/Projects/UOContent/Mobiles/Animals/Mounts/Hiryu.cs index 2297300f6..aea42872d 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/Hiryu.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/Hiryu.cs @@ -10,8 +10,7 @@ namespace Server.Mobiles private static readonly Dictionary m_Table = new(); [Constructible] - public Hiryu() - : base("a hiryu", 243, 0x3E94, AIType.AI_Melee, FightMode.Closest, 10, 1) + public Hiryu() : base("a hiryu", 243, 0x3E94, AIType.AI_Melee) { Hue = GetHue(); diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/Horse.cs b/Projects/UOContent/Mobiles/Animals/Mounts/Horse.cs index 7a31777a4..297215d03 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/Horse.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/Horse.cs @@ -17,17 +17,7 @@ namespace Server.Mobiles }; [Constructible] - public Horse(string name = "a horse") : base( - name, - 0xE2, - 0x3EA0, - AIType.AI_Animal, - FightMode.Aggressor, - 10, - 1, - 0.2, - 0.4 - ) + public Horse(string name = "a horse") : base(name, 0xE2, 0x3EA0, AIType.AI_Animal, FightMode.Aggressor) { var random = Utility.Random(4); diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/Kirin.cs b/Projects/UOContent/Mobiles/Animals/Mounts/Kirin.cs index e229bbfdc..842f4233e 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/Kirin.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/Kirin.cs @@ -7,7 +7,7 @@ namespace Server.Mobiles public class Kirin : BaseMount { [Constructible] - public Kirin(string name = "a ki-rin") : base(name, 132, 0x3EAD, AIType.AI_Mage, FightMode.Evil, 10, 1) + public Kirin(string name = "a ki-rin") : base(name, 132, 0x3EAD, AIType.AI_Mage, FightMode.Evil) { BaseSoundID = 0x3C5; diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/LesserHiryu.cs b/Projects/UOContent/Mobiles/Animals/Mounts/LesserHiryu.cs index aa0be7316..f6c0167fc 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/LesserHiryu.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/LesserHiryu.cs @@ -10,8 +10,7 @@ namespace Server.Mobiles private static readonly Dictionary m_Table = new(); [Constructible] - public LesserHiryu() - : base("a lesser hiryu", 243, 0x3E94, AIType.AI_Melee, FightMode.Closest, 10, 1) + public LesserHiryu() : base("a lesser hiryu", 243, 0x3E94, AIType.AI_Melee) { Hue = GetHue(); diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/Nightmare.cs b/Projects/UOContent/Mobiles/Animals/Mounts/Nightmare.cs index 447a0947c..6c058f86c 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/Nightmare.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/Nightmare.cs @@ -9,12 +9,7 @@ namespace Server.Mobiles name, 0x74, 0x3EA7, - AIType.AI_Mage, - FightMode.Closest, - 10, - 1, - 0.2, - 0.4 + AIType.AI_Mage ) { BaseSoundID = Core.AOS ? 0xA8 : 0x16A; diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/RidableLlama.cs b/Projects/UOContent/Mobiles/Animals/Mounts/RidableLlama.cs index d35d8ef1a..7ba192f45 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/RidableLlama.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/RidableLlama.cs @@ -3,16 +3,7 @@ namespace Server.Mobiles public class RidableLlama : BaseMount { [Constructible] - public RidableLlama(string name = "a ridable llama") : base( - name, - 0xDC, - 0x3EA6, - AIType.AI_Animal, - FightMode.Aggressor, - 10, - 1, - 0.2, - 0.4 + public RidableLlama(string name = "a ridable llama") : base(name, 0xDC, 0x3EA6, AIType.AI_Animal, FightMode.Aggressor ) { BaseSoundID = 0x3F3; diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/Ridgeback.cs b/Projects/UOContent/Mobiles/Animals/Mounts/Ridgeback.cs index f92bcebf7..93345b7c2 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/Ridgeback.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/Ridgeback.cs @@ -3,17 +3,7 @@ namespace Server.Mobiles public class Ridgeback : BaseMount { [Constructible] - public Ridgeback(string name = "a ridgeback") : base( - name, - 187, - 0x3EBA, - AIType.AI_Animal, - FightMode.Aggressor, - 10, - 1, - 0.2, - 0.4 - ) + public Ridgeback(string name = "a ridgeback") : base(name, 187, 0x3EBA, AIType.AI_Animal, FightMode.Aggressor) { BaseSoundID = 0x3F3; diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/SavageRidgeback.cs b/Projects/UOContent/Mobiles/Animals/Mounts/SavageRidgeback.cs index ad1292e19..b8bfc6615 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/SavageRidgeback.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/SavageRidgeback.cs @@ -3,17 +3,7 @@ namespace Server.Mobiles public class SavageRidgeback : BaseMount { [Constructible] - public SavageRidgeback(string name = "a savage ridgeback") : base( - name, - 188, - 0x3EB8, - AIType.AI_Melee, - FightMode.Aggressor, - 10, - 1, - 0.2, - 0.4 - ) + public SavageRidgeback(string name = "a savage ridgeback") : base(name, 188, 0x3EB8, AIType.AI_Melee, FightMode.Aggressor) { BaseSoundID = 0x3F3; diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/ScaledSwampDragon.cs b/Projects/UOContent/Mobiles/Animals/Mounts/ScaledSwampDragon.cs index 045dd8e25..4705c668a 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/ScaledSwampDragon.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/ScaledSwampDragon.cs @@ -3,17 +3,7 @@ namespace Server.Mobiles public class ScaledSwampDragon : BaseMount { [Constructible] - public ScaledSwampDragon(string name = "a swamp dragon") : base( - name, - 0x31F, - 0x3EBE, - AIType.AI_Melee, - FightMode.Aggressor, - 10, - 1, - 0.2, - 0.4 - ) + public ScaledSwampDragon(string name = "a swamp dragon") : base(name, 0x31F, 0x3EBE, AIType.AI_Melee, FightMode.Aggressor) { SetStr(201, 300); SetDex(66, 85); diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/SeaHorse.cs b/Projects/UOContent/Mobiles/Animals/Mounts/SeaHorse.cs index 0729514cd..be56e80a6 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/SeaHorse.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/SeaHorse.cs @@ -3,18 +3,9 @@ namespace Server.Mobiles public class SeaHorse : BaseMount { [Constructible] - public SeaHorse(string name = "a sea horse") : base( - name, - 0x90, - 0x3EB3, - AIType.AI_Animal, - FightMode.Aggressor, - 10, - 1, - 0.2, - 0.4 - ) + public SeaHorse(string name = "a sea horse") : base(name, 0x90, 0x3EB3, AIType.AI_Animal, FightMode.Aggressor) { + SetSpeed(0.4, 0.8); InitStats(Utility.Random(50, 30), Utility.Random(50, 30), 10); Skills.MagicResist.Base = 25.0 + Utility.RandomDouble() * 5.0; Skills.Wrestling.Base = 35.0 + Utility.RandomDouble() * 10.0; diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/SilverSteed.cs b/Projects/UOContent/Mobiles/Animals/Mounts/SilverSteed.cs index 3ffe7159a..d8ed1fafe 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/SilverSteed.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/SilverSteed.cs @@ -3,18 +3,10 @@ namespace Server.Mobiles public class SilverSteed : BaseMount { [Constructible] - public SilverSteed(string name = "a silver steed") : base( - name, - 0x75, - 0x3EA8, - AIType.AI_Animal, - FightMode.Aggressor, - 10, - 1, - 0.2, - 0.4 - ) + public SilverSteed(string name = "a silver steed") : base(name, 0x75, 0x3EA8, AIType.AI_Animal, FightMode.Aggressor) { + SetSpeed(0.55, 1.1); + InitStats(Utility.Random(50, 30), Utility.Random(50, 30), 10); Skills.MagicResist.Base = 25.0 + Utility.RandomDouble() * 5.0; Skills.Wrestling.Base = 35.0 + Utility.RandomDouble() * 10.0; diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/SkeletalMount.cs b/Projects/UOContent/Mobiles/Animals/Mounts/SkeletalMount.cs index eb14bdb2f..4e14da8ea 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/SkeletalMount.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/SkeletalMount.cs @@ -3,18 +3,9 @@ namespace Server.Mobiles public class SkeletalMount : BaseMount { [Constructible] - public SkeletalMount(string name = null) : base( - name, - 793, - 0x3EBB, - AIType.AI_Animal, - FightMode.Aggressor, - 10, - 1, - 0.2, - 0.4 - ) + public SkeletalMount(string name = null) : base(name, 793, 0x3EBB, AIType.AI_Animal, FightMode.Aggressor) { + SetSpeed(0.55, 1.1); SetStr(91, 100); SetDex(46, 55); SetInt(46, 60); diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/SwampDragon.cs b/Projects/UOContent/Mobiles/Animals/Mounts/SwampDragon.cs index 44d6de6fd..3e08164d1 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/SwampDragon.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/SwampDragon.cs @@ -11,17 +11,7 @@ namespace Server.Mobiles private bool m_HasBarding; [Constructible] - public SwampDragon(string name = "a swamp dragon") : base( - name, - 0x31A, - 0x3EBD, - AIType.AI_Melee, - FightMode.Aggressor, - 10, - 1, - 0.2, - 0.4 - ) + public SwampDragon(string name = "a swamp dragon") : base(name, 0x31A, 0x3EBD, AIType.AI_Melee, FightMode.Aggressor) { BaseSoundID = 0x16A; diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/Unicorn.cs b/Projects/UOContent/Mobiles/Animals/Mounts/Unicorn.cs index 12bd1434c..23b101675 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/Unicorn.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/Unicorn.cs @@ -7,7 +7,7 @@ namespace Server.Mobiles public class Unicorn : BaseMount { [Constructible] - public Unicorn(string name = "a unicorn") : base(name, 0x7A, 0x3EB4, AIType.AI_Mage, FightMode.Evil, 10, 1) + public Unicorn(string name = "a unicorn") : base(name, 0x7A, 0x3EB4, AIType.AI_Mage, FightMode.Evil) { BaseSoundID = 0x4BC; @@ -87,8 +87,8 @@ namespace Server.Mobiles if (chanceToCure > Utility.Random(100)) { - if (Rider.CurePoison(this) - ) // TODO: Confirm if mount is the one flagged for curing it or the rider is + // TODO: Confirm if mount is the one flagged for curing it or the rider is + if (Rider.CurePoison(this)) { Rider.LocalOverheadMessage( MessageType.Regular, diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/War Horses/BaseWarHorse.cs b/Projects/UOContent/Mobiles/Animals/Mounts/War Horses/BaseWarHorse.cs index 5c32ee070..26d9d646c 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/War Horses/BaseWarHorse.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/War Horses/BaseWarHorse.cs @@ -3,8 +3,8 @@ namespace Server.Mobiles public abstract class BaseWarHorse : BaseMount { public BaseWarHorse( - int bodyID, int itemID, AIType aiType, FightMode fightMode, int rangePerception, int rangeFight, - double activeSpeed = -1, double passiveSpeed = -1 + int bodyID, int itemID, AIType aiType = AIType.AI_Melee, FightMode fightMode = FightMode.Aggressor, + int rangePerception = 10, int rangeFight = 1 ) : base( "a war horse", bodyID, @@ -12,9 +12,7 @@ namespace Server.Mobiles aiType, fightMode, rangePerception, - rangeFight, - activeSpeed, - passiveSpeed + rangeFight ) { BaseSoundID = 0xA8; diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/War Horses/CoMWarHorse.cs b/Projects/UOContent/Mobiles/Animals/Mounts/War Horses/CoMWarHorse.cs index 302d98f3c..c8d6c98ff 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/War Horses/CoMWarHorse.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/War Horses/CoMWarHorse.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class CoMWarHorse : BaseWarHorse { [Constructible] - public CoMWarHorse() : base(0x77, 0x3EB1, AIType.AI_Melee, FightMode.Aggressor, 10, 1) + public CoMWarHorse() : base(0x77, 0x3EB1) { } diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/War Horses/MinaxWarHorse.cs b/Projects/UOContent/Mobiles/Animals/Mounts/War Horses/MinaxWarHorse.cs index eb42361c9..f05d4cf06 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/War Horses/MinaxWarHorse.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/War Horses/MinaxWarHorse.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class MinaxWarHorse : BaseWarHorse { [Constructible] - public MinaxWarHorse() : base(0x78, 0x3EAF, AIType.AI_Melee, FightMode.Aggressor, 10, 1) + public MinaxWarHorse() : base(0x78, 0x3EAF) { } diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/War Horses/SLWarHorse.cs b/Projects/UOContent/Mobiles/Animals/Mounts/War Horses/SLWarHorse.cs index 037a671c5..14418a816 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/War Horses/SLWarHorse.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/War Horses/SLWarHorse.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class SLWarHorse : BaseWarHorse { [Constructible] - public SLWarHorse() : base(0x79, 0x3EB0, AIType.AI_Melee, FightMode.Aggressor, 10, 1) + public SLWarHorse() : base(0x79, 0x3EB0) { } diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/War Horses/TBWarHorse.cs b/Projects/UOContent/Mobiles/Animals/Mounts/War Horses/TBWarHorse.cs index ac65a8186..d3fd30dbe 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/War Horses/TBWarHorse.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/War Horses/TBWarHorse.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class TBWarHorse : BaseWarHorse { [Constructible] - public TBWarHorse() : base(0x76, 0x3EB2, AIType.AI_Melee, FightMode.Aggressor, 10, 1) + public TBWarHorse() : base(0x76, 0x3EB2) { } diff --git a/Projects/UOContent/Mobiles/BaseCreature.cs b/Projects/UOContent/Mobiles/BaseCreature.cs index 302f14043..c80a70bf2 100644 --- a/Projects/UOContent/Mobiles/BaseCreature.cs +++ b/Projects/UOContent/Mobiles/BaseCreature.cs @@ -324,9 +324,10 @@ namespace Server.Mobiles AIType ai, FightMode mode = FightMode.Closest, int iRangePerception = 10, - int iRangeFight = 1, - double activeSpeed = -1, - double passiveSpeed = -1 + int iRangeFight = 1 + // , + // double activeSpeed = 0, + // double passiveSpeed = 0 ) { if (iRangePerception == OldRangePerception) @@ -344,18 +345,18 @@ namespace Server.Mobiles FightMode = mode; - m_Team = 0; + // if (activeSpeed > 0 && passiveSpeed > 0) + // { + // ActiveSpeed = activeSpeed; + // PassiveSpeed = passiveSpeed; + // CurrentSpeed = passiveSpeed; + // } + // else + // { + // CurrentSpeed = SpeedInfo.MaxMonsterDelay * 2; + // } - if (passiveSpeed < 0 || activeSpeed < 0) - { - ResetSpeeds(); - } - else - { - ActiveSpeed = activeSpeed; - PassiveSpeed = passiveSpeed; - CurrentSpeed = passiveSpeed; - } + m_Team = 0; Debug = false; @@ -685,16 +686,23 @@ namespace Server.Mobiles [CommandProperty(AccessLevel.GameMaster)] public double PassiveSpeed { get; set; } + [CommandProperty(AccessLevel.GameMaster)] + public double SpeedMod { get; set; } + [CommandProperty(AccessLevel.GameMaster)] public double CurrentSpeed { - get => TargetLocation != null ? 0.3 : m_CurrentSpeed; + get => TargetLocation != null ? 0.3 : SpeedMod <= 0 ? m_CurrentSpeed : SpeedMod; set { if (m_CurrentSpeed != value) { m_CurrentSpeed = value; - AIObject?.OnCurrentSpeedChanged(); + + if (SpeedMod <= 0) + { + AIObject?.OnCurrentSpeedChanged(); + } } } } @@ -1370,6 +1378,14 @@ namespace Server.Mobiles } } + public override void OnRawDexChange(int oldValue) + { + if (oldValue != RawDex && ActiveSpeed <= 0 && PassiveSpeed <= 0) + { + ResetSpeeds(); + } + } + public override void OnBeforeSpawn(Point3D location, Map m) { if (Paragon.CheckConvert(this, location, m)) @@ -2573,7 +2589,6 @@ namespace Server.Mobiles if (m_IdleReleaseTime > DateTime.MinValue) { // idling... - if (Core.Now >= m_IdleReleaseTime) { m_IdleReleaseTime = DateTime.MinValue; @@ -3000,11 +3015,12 @@ namespace Server.Mobiles return null; } - public virtual bool IsMonster => - !Controlled || GetMaster() is not BaseCreature { Controlled: true }; + public virtual bool IsMonster => !Controlled || (GetMaster() as BaseCreature)?.IsMonster == true; public bool InActivePVPCombat() => - Combatant is PlayerMobile && ControlOrder != OrderType.Follow; + ControlOrder != OrderType.Follow && + Combatant is PlayerMobile || + Combatant is BaseCreature { Controlled: true } bc && bc.GetMaster() is PlayerMobile; public static List GetLootingRights(List damageEntries, int hitsMax) { @@ -3382,6 +3398,8 @@ namespace Server.Mobiles ControlOrder = OrderType.None; Guild = null; + ResetSpeeds(); + Delta(MobileDelta.Noto); } else @@ -3414,6 +3432,8 @@ namespace Server.Mobiles m_DeleteTimer = null; } + ResetSpeeds(true); + Delta(MobileDelta.Noto); } @@ -4561,6 +4581,13 @@ namespace Server.Mobiles return false; } + public void SetSpeed(double active, double passive) + { + ActiveSpeed = active; + PassiveSpeed = passive; + CurrentSpeed = PassiveSpeed; + } + public void SetDamage(int val) { m_DamageMin = val; @@ -4840,8 +4867,7 @@ namespace Server.Mobiles } } - // Reset speeds based on dex. Mainly used during construction and pet commands - public void ResetSpeeds(bool currentUseActive = false) + public virtual void ResetSpeeds(bool currentUseActive = false) { SpeedInfo.GetSpeeds(this, out var activeSpeed, out var passiveSpeed); diff --git a/Projects/UOContent/Mobiles/Monsters/AOS/Revenant.cs b/Projects/UOContent/Mobiles/Monsters/AOS/Revenant.cs index 5ce83b7e4..72517630f 100644 --- a/Projects/UOContent/Mobiles/Monsters/AOS/Revenant.cs +++ b/Projects/UOContent/Mobiles/Monsters/AOS/Revenant.cs @@ -8,14 +8,7 @@ namespace Server.Mobiles private readonly DateTime m_ExpireTime; private readonly Mobile m_Target; - public Revenant(Mobile caster, Mobile target, TimeSpan duration) : base( - AIType.AI_Melee, - FightMode.Closest, - 10, - 1, - 0.18, - 0.36 - ) + public Revenant(Mobile caster, Mobile target, TimeSpan duration) : base(AIType.AI_Melee) { Body = 400; Hue = 1; @@ -26,6 +19,8 @@ namespace Server.Mobiles m_Target = target; m_ExpireTime = Core.Now + duration; + SetSpeed(0.25, 0.55); + SetStr(200); SetDex(150); SetInt(150); diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/KhaldunRevenant.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/KhaldunRevenant.cs index fe00b9402..02210c9f1 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/KhaldunRevenant.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/KhaldunRevenant.cs @@ -11,7 +11,7 @@ namespace Server.Mobiles private readonly Mobile m_Target; - public KhaldunRevenant(Mobile target) : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.175, 0.35) + public KhaldunRevenant(Mobile target) : base(AIType.AI_Melee) { Body = 0x3CA; Hue = 0x41CE; @@ -19,6 +19,8 @@ namespace Server.Mobiles m_Target = target; m_ExpireTime = Core.Now + TimeSpan.FromMinutes(10.0); + SetSpeed(0.25, 0.55); + SetStr(401, 500); SetDex(296, 315); SetInt(101, 200); diff --git a/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/ChaosDragoon.cs b/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/ChaosDragoon.cs index c139720cb..26eeb161c 100644 --- a/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/ChaosDragoon.cs +++ b/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/ChaosDragoon.cs @@ -5,11 +5,13 @@ namespace Server.Mobiles public class ChaosDragoon : BaseCreature { [Constructible] - public ChaosDragoon() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.15, 0.4) + public ChaosDragoon() : base(AIType.AI_Melee) { Body = 0x190; Hue = Race.Human.RandomSkinHue(); + SetSpeed(0.25, 0.55); + SetStr(176, 225); SetDex(81, 95); SetInt(61, 85); diff --git a/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/ChaosDragoonElite.cs b/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/ChaosDragoonElite.cs index 839f9b117..fea4c1383 100644 --- a/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/ChaosDragoonElite.cs +++ b/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/ChaosDragoonElite.cs @@ -5,12 +5,13 @@ namespace Server.Mobiles public class ChaosDragoonElite : BaseCreature { [Constructible] - public ChaosDragoonElite() - : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.15, 0.4) + public ChaosDragoonElite() : base(AIType.AI_Mage) { Body = 0x190; Hue = Race.Human.RandomSkinHue(); + SetSpeed(0.25, 0.55); + SetStr(276, 350); SetDex(66, 90); SetInt(126, 150); diff --git a/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Melee/CorruptedSoul.cs b/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Melee/CorruptedSoul.cs index 5fe6bb7b5..a65b126d8 100644 --- a/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Melee/CorruptedSoul.cs +++ b/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Melee/CorruptedSoul.cs @@ -3,11 +3,13 @@ namespace Server.Mobiles public class CorruptedSoul : BaseCreature { [Constructible] - public CorruptedSoul() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.1, 5) + public CorruptedSoul() : base(AIType.AI_Melee) { Body = 0x3CA; Hue = 0x453; + SetSpeed(0.25, 5); + SetStr(102, 115); SetDex(101, 115); SetInt(203, 215); diff --git a/Projects/UOContent/Mobiles/Monsters/ML/Labyrinth/Miasma.cs b/Projects/UOContent/Mobiles/Monsters/ML/Labyrinth/Miasma.cs index ab70964d3..2e8ba905c 100644 --- a/Projects/UOContent/Mobiles/Monsters/ML/Labyrinth/Miasma.cs +++ b/Projects/UOContent/Mobiles/Monsters/ML/Labyrinth/Miasma.cs @@ -11,6 +11,8 @@ namespace Server.Mobiles Hue = 0x8FD; + SetSpeed(0.1, 0.6); + SetStr(255, 847); SetDex(145, 428); SetInt(26, 380); @@ -44,7 +46,7 @@ namespace Server.Mobiles public override void OnDeath( Container c ) { base.OnDeath( c ); - + if (Utility.RandomDouble() < 0.025) { switch ( Utility.Random( 16 ) ) diff --git a/Projects/UOContent/Mobiles/Monsters/ML/Misc/Melee/Reptalon.cs b/Projects/UOContent/Mobiles/Monsters/ML/Misc/Melee/Reptalon.cs index 20c23967d..e057936ce 100644 --- a/Projects/UOContent/Mobiles/Monsters/ML/Misc/Melee/Reptalon.cs +++ b/Projects/UOContent/Mobiles/Monsters/ML/Misc/Melee/Reptalon.cs @@ -5,10 +5,12 @@ namespace Server.Mobiles public class Reptalon : BaseMount { [Constructible] - public Reptalon() : base("a reptalon", 0x114, 0x3E90, AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.35) + public Reptalon() : base("a reptalon", 0x114, 0x3E90, AIType.AI_Melee) { BaseSoundID = 0x16A; + SetSpeed(0.25, 0.55); + SetStr(1001, 1025); SetDex(152, 164); SetInt(251, 289); diff --git a/Projects/UOContent/Mobiles/Monsters/Misc/Magic/ShadowWisp.cs b/Projects/UOContent/Mobiles/Monsters/Misc/Magic/ShadowWisp.cs index b88b25c73..6e8025f81 100644 --- a/Projects/UOContent/Mobiles/Monsters/Misc/Magic/ShadowWisp.cs +++ b/Projects/UOContent/Mobiles/Monsters/Misc/Magic/ShadowWisp.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class ShadowWisp : BaseCreature { [Constructible] - public ShadowWisp() : base(AIType.AI_Mage, FightMode.Aggressor, 10, 1, 0.25, 0.5) + public ShadowWisp() : base(AIType.AI_Mage, FightMode.Aggressor) { Body = 165; BaseSoundID = 466; diff --git a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/AnimatedWeapon.cs b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/AnimatedWeapon.cs index dc3d09d98..47844cae7 100644 --- a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/AnimatedWeapon.cs +++ b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/AnimatedWeapon.cs @@ -5,8 +5,7 @@ namespace Server.Mobiles public class AnimatedWeapon : BaseCreature { [Constructible] - public AnimatedWeapon(Mobile caster, int level) - : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.3, 0.6) + public AnimatedWeapon(Mobile caster, int level) : base(AIType.AI_Melee) { Body = 692; diff --git a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/BladeSpirits.cs b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/BladeSpirits.cs index bcd9ed8ba..710c5420c 100644 --- a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/BladeSpirits.cs +++ b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/BladeSpirits.cs @@ -6,11 +6,11 @@ namespace Server.Mobiles public class BladeSpirits : BaseCreature { [Constructible] - public BladeSpirits() - : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.3, 0.6) + public BladeSpirits() : base(AIType.AI_Melee) { Body = 574; + SetSpeed(0.6, 1.25); SetStr(150); SetDex(150); SetInt(100); diff --git a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/Golem.cs b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/Golem.cs index 46f1a0535..7dc6ffe5c 100644 --- a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/Golem.cs +++ b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/Golem.cs @@ -9,7 +9,7 @@ namespace Server.Mobiles private bool m_Stunning; [Constructible] - public Golem(bool summoned = false, double scalar = 1.0) : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.4, 0.8) + public Golem(bool summoned = false, double scalar = 1.0) : base(AIType.AI_Melee) { Body = 752; @@ -18,6 +18,8 @@ namespace Server.Mobiles Hue = 2101; } + SetSpeed(0.9, 1.5); + SetStr((int)(251 * scalar), (int)(350 * scalar)); SetDex((int)(76 * scalar), (int)(100 * scalar)); SetInt((int)(101 * scalar), (int)(150 * scalar)); diff --git a/Projects/UOContent/Mobiles/Monsters/Plant/Melee/BogThing.cs b/Projects/UOContent/Mobiles/Monsters/Plant/Melee/BogThing.cs index 5a05f47f6..b2b1cbc93 100644 --- a/Projects/UOContent/Mobiles/Monsters/Plant/Melee/BogThing.cs +++ b/Projects/UOContent/Mobiles/Monsters/Plant/Melee/BogThing.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles public class BogThing : BaseCreature { [Constructible] - public BogThing() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.3, 0.6) + public BogThing() : base(AIType.AI_Melee) { Body = 780; diff --git a/Projects/UOContent/Mobiles/Monsters/Plant/Melee/Quagmire.cs b/Projects/UOContent/Mobiles/Monsters/Plant/Melee/Quagmire.cs index b551b7d3f..42ab21e28 100644 --- a/Projects/UOContent/Mobiles/Monsters/Plant/Melee/Quagmire.cs +++ b/Projects/UOContent/Mobiles/Monsters/Plant/Melee/Quagmire.cs @@ -3,7 +3,7 @@ namespace Server.Mobiles public class Quagmire : BaseCreature { [Constructible] - public Quagmire() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.3, 0.6) + public Quagmire() : base(AIType.AI_Melee) { Body = 789; BaseSoundID = 352; diff --git a/Projects/UOContent/Mobiles/Monsters/SE/DeathWatchBeetleHatchling.cs b/Projects/UOContent/Mobiles/Monsters/SE/DeathWatchBeetleHatchling.cs index 07033c5c6..83302820e 100644 --- a/Projects/UOContent/Mobiles/Monsters/SE/DeathWatchBeetleHatchling.cs +++ b/Projects/UOContent/Mobiles/Monsters/SE/DeathWatchBeetleHatchling.cs @@ -6,14 +6,7 @@ namespace Server.Mobiles public class DeathwatchBeetleHatchling : BaseCreature { [Constructible] - public DeathwatchBeetleHatchling() : base( - AIType.AI_Melee, - Core.ML ? FightMode.Aggressor : FightMode.Closest, - 10, - 1, - 0.2, - 0.4 - ) + public DeathwatchBeetleHatchling() : base(AIType.AI_Melee, Core.ML ? FightMode.Aggressor : FightMode.Closest) { Body = 242; diff --git a/Projects/UOContent/Mobiles/Special/BaseChampion.cs b/Projects/UOContent/Mobiles/Special/BaseChampion.cs index 732016313..4983292da 100644 --- a/Projects/UOContent/Mobiles/Special/BaseChampion.cs +++ b/Projects/UOContent/Mobiles/Special/BaseChampion.cs @@ -7,8 +7,9 @@ namespace Server.Mobiles { public abstract class BaseChampion : BaseCreature { - public BaseChampion(AIType aiType, FightMode mode = FightMode.Closest) : base(aiType, mode, 18, 1, 0.1, 0.2) + public BaseChampion(AIType aiType, FightMode mode = FightMode.Closest) : base(aiType, mode, 18) { + SetSpeed(0.25, 0.55); } public BaseChampion(Serial serial) : base(serial) diff --git a/Projects/UOContent/Mobiles/Special/Dummy.cs b/Projects/UOContent/Mobiles/Special/Dummy.cs deleted file mode 100644 index c56d03f61..000000000 --- a/Projects/UOContent/Mobiles/Special/Dummy.cs +++ /dev/null @@ -1,163 +0,0 @@ -using System; -using Server.Items; - -namespace Server.Mobiles -{ - /// - /// This is a test creature - /// You can set its value in game - /// It die after 5 minutes, so your test server stay clean - /// Create a macro to help your creation "[add Dummy 1 15 7 -1 0.5 2" - /// A iTeam of negative will set a faction at random - /// Say Kill if you want them to die - /// - public class Dummy : BaseCreature - { - public Timer m_Timer; - - [Constructible] - public Dummy( - AIType iAI, FightMode iFightMode, int iRangePerception, int iRangeFight, double dActiveSpeed, - double dPassiveSpeed - ) : base(iAI, iFightMode, iRangePerception, iRangeFight, dActiveSpeed, dPassiveSpeed) - { - Body = 400 + Utility.Random(2); - Hue = Race.Human.RandomSkinHue(); - - Skills.DetectHidden.Base = 100; - Skills.MagicResist.Base = 120; - - Team = Utility.Random(3); - - var iHue = 20 + Team * 40; - var jHue = 25 + Team * 40; - - Utility.AssignRandomHair(this, iHue); - - var glv = new LeatherGloves(); - glv.Hue = iHue; - glv.LootType = LootType.Newbied; - AddItem(glv); - - Container pack = new Backpack(); - - pack.Movable = false; - - AddItem(pack); - - m_Timer = new AutokillTimer(this); - m_Timer.Start(); - } - - public Dummy(Serial serial) : base(serial) - { - m_Timer = new AutokillTimer(this); - m_Timer.Start(); - } - - 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 override bool HandlesOnSpeech(Mobile from) - { - if (from.AccessLevel >= AccessLevel.GameMaster) - { - return true; - } - - return base.HandlesOnSpeech(from); - } - - public override void OnSpeech(SpeechEventArgs e) - { - base.OnSpeech(e); - - if (e.Mobile.AccessLevel >= AccessLevel.GameMaster) - { - if (e.Speech == "kill") - { - m_Timer.Stop(); - m_Timer.Delay = TimeSpan.FromSeconds(Utility.Random(1, 5)); - m_Timer.Start(); - } - } - } - - public override void OnTeamChange() - { - var iHue = 20 + Team * 40; - var jHue = 25 + Team * 40; - - var item = FindItemOnLayer(Layer.OuterTorso); - - if (item != null) - { - item.Hue = jHue; - } - - item = FindItemOnLayer(Layer.Helm); - - if (item != null) - { - item.Hue = iHue; - } - - item = FindItemOnLayer(Layer.Gloves); - - if (item != null) - { - item.Hue = iHue; - } - - item = FindItemOnLayer(Layer.Shoes); - - if (item != null) - { - item.Hue = iHue; - } - - HairHue = iHue; - - item = FindItemOnLayer(Layer.MiddleTorso); - - if (item != null) - { - item.Hue = iHue; - } - - item = FindItemOnLayer(Layer.OuterLegs); - - if (item != null) - { - item.Hue = iHue; - } - } - - private class AutokillTimer : Timer - { - private readonly Dummy m_Owner; - - public AutokillTimer(Dummy owner) : base(TimeSpan.FromMinutes(5.0)) - { - m_Owner = owner; - } - - protected override void OnTick() - { - m_Owner.Kill(); - Stop(); - } - } - } -} diff --git a/Projects/UOContent/Mobiles/Special/DummySpecific.cs b/Projects/UOContent/Mobiles/Special/DummySpecific.cs deleted file mode 100644 index 560de2b43..000000000 --- a/Projects/UOContent/Mobiles/Special/DummySpecific.cs +++ /dev/null @@ -1,784 +0,0 @@ -using Server.Items; -using Server.Spells.First; -using Server.Spells.Third; - -namespace Server.Mobiles -{ - /// - /// This is a test creature - /// You can set its value in game - /// It die after 5 minutes, so your test server stay clean - /// Create a macro to help your creation "[add Dummy 1 15 7 -1 0.5 2" - /// A iTeam of negative will set a faction at random - /// Say Kill if you want them to die - /// - public class DummyMace : Dummy - { - [Constructible] - public DummyMace() : base(AIType.AI_Melee, FightMode.Closest, 15, 1, 0.2, 0.6) - { - // A Dummy Macer - var iHue = 20 + Team * 40; - var jHue = 25 + Team * 40; - - // Skills and Stats - InitStats(125, 125, 90); - Skills.Macing.Base = 120; - Skills.Anatomy.Base = 120; - Skills.Healing.Base = 120; - Skills.Tactics.Base = 120; - - // Equip - var war = new WarHammer(); - war.Movable = true; - war.Crafter = this; - war.Quality = WeaponQuality.Regular; - AddItem(war); - - var bts = new Boots(); - bts.Hue = iHue; - AddItem(bts); - - var cht = new ChainChest(); - cht.Movable = false; - cht.LootType = LootType.Newbied; - cht.Crafter = RawName; - cht.Quality = ArmorQuality.Regular; - AddItem(cht); - - var chl = new ChainLegs(); - chl.Movable = false; - chl.LootType = LootType.Newbied; - chl.Crafter = RawName; - chl.Quality = ArmorQuality.Regular; - AddItem(chl); - - var pla = new PlateArms(); - pla.Movable = false; - pla.LootType = LootType.Newbied; - pla.Crafter = RawName; - pla.Quality = ArmorQuality.Regular; - AddItem(pla); - - var band = new Bandage(50); - AddToBackpack(band); - } - - public DummyMace(Serial serial) : base(serial) - { - } - - public override string DefaultName => "Macer"; - - 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 DummyFence : Dummy - { - [Constructible] - public DummyFence() : base(AIType.AI_Melee, FightMode.Closest, 15, 1, 0.2, 0.6) - { - // A Dummy Fencer - var iHue = 20 + Team * 40; - var jHue = 25 + Team * 40; - - // Skills and Stats - InitStats(125, 125, 90); - Skills.Fencing.Base = 120; - Skills.Anatomy.Base = 120; - Skills.Healing.Base = 120; - Skills.Tactics.Base = 120; - - // Equip - var ssp = new Spear(); - ssp.Movable = true; - ssp.Crafter = this; - ssp.Quality = WeaponQuality.Regular; - AddItem(ssp); - - var snd = new Boots(); - snd.Hue = iHue; - snd.LootType = LootType.Newbied; - AddItem(snd); - - var cht = new ChainChest(); - cht.Movable = false; - cht.LootType = LootType.Newbied; - cht.Crafter = RawName; - cht.Quality = ArmorQuality.Regular; - AddItem(cht); - - var chl = new ChainLegs(); - chl.Movable = false; - chl.LootType = LootType.Newbied; - chl.Crafter = RawName; - chl.Quality = ArmorQuality.Regular; - AddItem(chl); - - var pla = new PlateArms(); - pla.Movable = false; - pla.LootType = LootType.Newbied; - pla.Crafter = RawName; - pla.Quality = ArmorQuality.Regular; - AddItem(pla); - - var band = new Bandage(50); - AddToBackpack(band); - } - - public DummyFence(Serial serial) : base(serial) - { - } - - public override string DefaultName => "Fencer"; - - 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 DummySword : Dummy - { - [Constructible] - public DummySword() : base(AIType.AI_Melee, FightMode.Closest, 15, 1, 0.2, 0.6) - { - // A Dummy Swordsman - var iHue = 20 + Team * 40; - var jHue = 25 + Team * 40; - - // Skills and Stats - InitStats(125, 125, 90); - Skills.Swords.Base = 120; - Skills.Anatomy.Base = 120; - Skills.Healing.Base = 120; - Skills.Tactics.Base = 120; - Skills.Parry.Base = 120; - - // Equip - var kat = new Katana(); - kat.Crafter = this; - kat.Movable = true; - kat.Quality = WeaponQuality.Regular; - AddItem(kat); - - var bts = new Boots(); - bts.Hue = iHue; - AddItem(bts); - - var cht = new ChainChest(); - cht.Movable = false; - cht.LootType = LootType.Newbied; - cht.Crafter = RawName; - cht.Quality = ArmorQuality.Regular; - AddItem(cht); - - var chl = new ChainLegs(); - chl.Movable = false; - chl.LootType = LootType.Newbied; - chl.Crafter = RawName; - chl.Quality = ArmorQuality.Regular; - AddItem(chl); - - var pla = new PlateArms(); - pla.Movable = false; - pla.LootType = LootType.Newbied; - pla.Crafter = RawName; - pla.Quality = ArmorQuality.Regular; - AddItem(pla); - - var band = new Bandage(50); - AddToBackpack(band); - } - - public DummySword(Serial serial) : base(serial) - { - } - - public override string DefaultName => "Swordsman"; - - 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 DummyNox : Dummy - { - [Constructible] - public DummyNox() : base(AIType.AI_Mage, FightMode.Closest, 15, 1, 0.2, 0.6) - { - // A Dummy Nox or Pure Mage - var iHue = 20 + Team * 40; - var jHue = 25 + Team * 40; - - // Skills and Stats - InitStats(90, 90, 125); - Skills.Magery.Base = 120; - Skills.EvalInt.Base = 120; - Skills.Inscribe.Base = 100; - Skills.Wrestling.Base = 120; - Skills.Meditation.Base = 120; - Skills.Poisoning.Base = 100; - - // Equip - var book = new Spellbook(); - book.Movable = false; - book.LootType = LootType.Newbied; - book.Content = 0xFFFFFFFFFFFFFFFF; - AddItem(book); - - var kilt = new Kilt(); - kilt.Hue = jHue; - AddItem(kilt); - - var snd = new Sandals(); - snd.Hue = iHue; - snd.LootType = LootType.Newbied; - AddItem(snd); - - var skc = new SkullCap(); - skc.Hue = iHue; - AddItem(skc); - - // Spells - AddSpellAttack(typeof(MagicArrowSpell)); - AddSpellAttack(typeof(WeakenSpell)); - AddSpellAttack(typeof(FireballSpell)); - AddSpellDefense(typeof(WallOfStoneSpell)); - AddSpellDefense(typeof(HealSpell)); - } - - public DummyNox(Serial serial) : base(serial) - { - } - - public override string DefaultName => "Nox Mage"; - - 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 DummyStun : Dummy - { - [Constructible] - public DummyStun() : base(AIType.AI_Mage, FightMode.Closest, 15, 1, 0.2, 0.6) - { - // A Dummy Stun Mage - var iHue = 20 + Team * 40; - var jHue = 25 + Team * 40; - - // Skills and Stats - InitStats(90, 90, 125); - Skills.Magery.Base = 100; - Skills.EvalInt.Base = 120; - Skills.Anatomy.Base = 80; - Skills.Wrestling.Base = 80; - Skills.Meditation.Base = 100; - Skills.Poisoning.Base = 100; - - // Equip - var book = new Spellbook(); - book.Movable = false; - book.LootType = LootType.Newbied; - book.Content = 0xFFFFFFFFFFFFFFFF; - AddItem(book); - - var lea = new LeatherArms(); - lea.Movable = false; - lea.LootType = LootType.Newbied; - lea.Crafter = RawName; - lea.Quality = ArmorQuality.Regular; - AddItem(lea); - - var lec = new LeatherChest(); - lec.Movable = false; - lec.LootType = LootType.Newbied; - lec.Crafter = RawName; - lec.Quality = ArmorQuality.Regular; - AddItem(lec); - - var leg = new LeatherGorget(); - leg.Movable = false; - leg.LootType = LootType.Newbied; - leg.Crafter = RawName; - leg.Quality = ArmorQuality.Regular; - AddItem(leg); - - var lel = new LeatherLegs(); - lel.Movable = false; - lel.LootType = LootType.Newbied; - lel.Crafter = RawName; - lel.Quality = ArmorQuality.Regular; - AddItem(lel); - - var bts = new Boots(); - bts.Hue = iHue; - AddItem(bts); - - var cap = new Cap(); - cap.Hue = iHue; - AddItem(cap); - - // Spells - AddSpellAttack(typeof(MagicArrowSpell)); - AddSpellAttack(typeof(WeakenSpell)); - AddSpellAttack(typeof(FireballSpell)); - AddSpellDefense(typeof(WallOfStoneSpell)); - AddSpellDefense(typeof(HealSpell)); - } - - public DummyStun(Serial serial) : base(serial) - { - } - - public override string DefaultName => "Stun Mage"; - - 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 DummySuper : Dummy - { - [Constructible] - public DummySuper() : base(AIType.AI_Mage, FightMode.Closest, 15, 1, 0.2, 0.6) - { - // A Dummy Super Mage - var iHue = 20 + Team * 40; - var jHue = 25 + Team * 40; - - // Skills and Stats - InitStats(125, 125, 125); - Skills.Magery.Base = 120; - Skills.EvalInt.Base = 120; - Skills.Anatomy.Base = 120; - Skills.Wrestling.Base = 120; - Skills.Meditation.Base = 120; - Skills.Poisoning.Base = 100; - Skills.Inscribe.Base = 100; - - // Equip - var book = new Spellbook(); - book.Movable = false; - book.LootType = LootType.Newbied; - book.Content = 0xFFFFFFFFFFFFFFFF; - AddItem(book); - - var lea = new LeatherArms(); - lea.Movable = false; - lea.LootType = LootType.Newbied; - lea.Crafter = RawName; - lea.Quality = ArmorQuality.Regular; - AddItem(lea); - - var lec = new LeatherChest(); - lec.Movable = false; - lec.LootType = LootType.Newbied; - lec.Crafter = RawName; - lec.Quality = ArmorQuality.Regular; - AddItem(lec); - - var leg = new LeatherGorget(); - leg.Movable = false; - leg.LootType = LootType.Newbied; - leg.Crafter = RawName; - leg.Quality = ArmorQuality.Regular; - AddItem(leg); - - var lel = new LeatherLegs(); - lel.Movable = false; - lel.LootType = LootType.Newbied; - lel.Crafter = RawName; - lel.Quality = ArmorQuality.Regular; - AddItem(lel); - - var snd = new Sandals(); - snd.Hue = iHue; - snd.LootType = LootType.Newbied; - AddItem(snd); - - var jhat = new JesterHat(); - jhat.Hue = iHue; - AddItem(jhat); - - var dblt = new Doublet(); - dblt.Hue = iHue; - AddItem(dblt); - - // Spells - AddSpellAttack(typeof(MagicArrowSpell)); - AddSpellAttack(typeof(WeakenSpell)); - AddSpellAttack(typeof(FireballSpell)); - AddSpellDefense(typeof(WallOfStoneSpell)); - AddSpellDefense(typeof(HealSpell)); - } - - public DummySuper(Serial serial) : base(serial) - { - } - - public override string DefaultName => "Super Mage"; - - 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 DummyHealer : Dummy - { - [Constructible] - public DummyHealer() : base(AIType.AI_Healer, FightMode.Closest, 15, 1, 0.2, 0.6) - { - // A Dummy Healer Mage - var iHue = 20 + Team * 40; - var jHue = 25 + Team * 40; - - // Skills and Stats - InitStats(125, 125, 125); - Skills.Magery.Base = 120; - Skills.EvalInt.Base = 120; - Skills.Anatomy.Base = 120; - Skills.Wrestling.Base = 120; - Skills.Meditation.Base = 120; - Skills.Healing.Base = 100; - - // Equip - var book = new Spellbook(); - book.Movable = false; - book.LootType = LootType.Newbied; - book.Content = 0xFFFFFFFFFFFFFFFF; - AddItem(book); - - var lea = new LeatherArms(); - lea.Movable = false; - lea.LootType = LootType.Newbied; - lea.Crafter = RawName; - lea.Quality = ArmorQuality.Regular; - AddItem(lea); - - var lec = new LeatherChest(); - lec.Movable = false; - lec.LootType = LootType.Newbied; - lec.Crafter = RawName; - lec.Quality = ArmorQuality.Regular; - AddItem(lec); - - var leg = new LeatherGorget(); - leg.Movable = false; - leg.LootType = LootType.Newbied; - leg.Crafter = RawName; - leg.Quality = ArmorQuality.Regular; - AddItem(leg); - - var lel = new LeatherLegs(); - lel.Movable = false; - lel.LootType = LootType.Newbied; - lel.Crafter = RawName; - lel.Quality = ArmorQuality.Regular; - AddItem(lel); - - var snd = new Sandals(); - snd.Hue = iHue; - snd.LootType = LootType.Newbied; - AddItem(snd); - - var cap = new Cap(); - cap.Hue = iHue; - AddItem(cap); - - var robe = new Robe(); - robe.Hue = iHue; - AddItem(robe); - } - - public DummyHealer(Serial serial) : base(serial) - { - } - - public override string DefaultName => "Healer"; - - 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 DummyAssassin : Dummy - { - [Constructible] - public DummyAssassin() : base(AIType.AI_Melee, FightMode.Closest, 15, 1, 0.2, 0.6) - { - // A Dummy Hybrid Assassin - var iHue = 20 + Team * 40; - var jHue = 25 + Team * 40; - - // Skills and Stats - InitStats(105, 105, 105); - Skills.Magery.Base = 120; - Skills.EvalInt.Base = 120; - Skills.Swords.Base = 120; - Skills.Tactics.Base = 120; - Skills.Meditation.Base = 120; - Skills.Poisoning.Base = 100; - - // Equip - var book = new Spellbook(); - book.Movable = false; - book.LootType = LootType.Newbied; - book.Content = 0xFFFFFFFFFFFFFFFF; - AddToBackpack(book); - - var kat = new Katana(); - kat.Movable = false; - kat.LootType = LootType.Newbied; - kat.Crafter = this; - kat.Poison = Poison.Deadly; - kat.PoisonCharges = 12; - kat.Quality = WeaponQuality.Regular; - AddToBackpack(kat); - - var lea = new LeatherArms(); - lea.Movable = false; - lea.LootType = LootType.Newbied; - lea.Crafter = RawName; - lea.Quality = ArmorQuality.Regular; - AddItem(lea); - - var lec = new LeatherChest(); - lec.Movable = false; - lec.LootType = LootType.Newbied; - lec.Crafter = RawName; - lec.Quality = ArmorQuality.Regular; - AddItem(lec); - - var leg = new LeatherGorget(); - leg.Movable = false; - leg.LootType = LootType.Newbied; - leg.Crafter = RawName; - leg.Quality = ArmorQuality.Regular; - AddItem(leg); - - var lel = new LeatherLegs(); - lel.Movable = false; - lel.LootType = LootType.Newbied; - lel.Crafter = RawName; - lel.Quality = ArmorQuality.Regular; - AddItem(lel); - - var snd = new Sandals(); - snd.Hue = iHue; - snd.LootType = LootType.Newbied; - AddItem(snd); - - var cap = new Cap(); - cap.Hue = iHue; - AddItem(cap); - - var robe = new Robe(); - robe.Hue = iHue; - AddItem(robe); - - var pota = new DeadlyPoisonPotion(); - pota.LootType = LootType.Newbied; - AddToBackpack(pota); - - var potb = new DeadlyPoisonPotion(); - potb.LootType = LootType.Newbied; - AddToBackpack(potb); - - var potc = new DeadlyPoisonPotion(); - potc.LootType = LootType.Newbied; - AddToBackpack(potc); - - var potd = new DeadlyPoisonPotion(); - potd.LootType = LootType.Newbied; - AddToBackpack(potd); - - var band = new Bandage(50); - AddToBackpack(band); - } - - public DummyAssassin(Serial serial) : base(serial) - { - } - - public override string DefaultName => "Hybrid Assassin"; - - 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(); - } - } - - [TypeAlias("Server.Mobiles.DummyTheif")] - public class DummyThief : Dummy - { - [Constructible] - public DummyThief() : base(AIType.AI_Thief, FightMode.Closest, 15, 1, 0.2, 0.6) - { - // A Dummy Hybrid Thief - var iHue = 20 + Team * 40; - var jHue = 25 + Team * 40; - - // Skills and Stats - InitStats(105, 105, 105); - Skills.Healing.Base = 120; - Skills.Anatomy.Base = 120; - Skills.Stealing.Base = 120; - Skills.ArmsLore.Base = 100; - Skills.Meditation.Base = 120; - Skills.Wrestling.Base = 120; - - // Equip - var book = new Spellbook(); - book.Movable = false; - book.LootType = LootType.Newbied; - book.Content = 0xFFFFFFFFFFFFFFFF; - AddItem(book); - - var lea = new LeatherArms(); - lea.Movable = false; - lea.LootType = LootType.Newbied; - lea.Crafter = RawName; - lea.Quality = ArmorQuality.Regular; - AddItem(lea); - - var lec = new LeatherChest(); - lec.Movable = false; - lec.LootType = LootType.Newbied; - lec.Crafter = RawName; - lec.Quality = ArmorQuality.Regular; - AddItem(lec); - - var leg = new LeatherGorget(); - leg.Movable = false; - leg.LootType = LootType.Newbied; - leg.Crafter = RawName; - leg.Quality = ArmorQuality.Regular; - AddItem(leg); - - var lel = new LeatherLegs(); - lel.Movable = false; - lel.LootType = LootType.Newbied; - lel.Crafter = RawName; - lel.Quality = ArmorQuality.Regular; - AddItem(lel); - - var snd = new Sandals(); - snd.Hue = iHue; - snd.LootType = LootType.Newbied; - AddItem(snd); - - var cap = new Cap(); - cap.Hue = iHue; - AddItem(cap); - - var robe = new Robe(); - robe.Hue = iHue; - AddItem(robe); - - var band = new Bandage(50); - AddToBackpack(band); - } - - public DummyThief(Serial serial) : base(serial) - { - } - - public override string DefaultName => "Hybrid Thief"; - - 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/Mobiles/Special/Mephitis.cs b/Projects/UOContent/Mobiles/Special/Mephitis.cs index f6af38c11..f7bfe79d5 100644 --- a/Projects/UOContent/Mobiles/Special/Mephitis.cs +++ b/Projects/UOContent/Mobiles/Special/Mephitis.cs @@ -12,6 +12,8 @@ namespace Server.Mobiles Body = 173; BaseSoundID = 0x183; + SetSpeed(0.1, 0.6); + SetStr(505, 1000); SetDex(102, 300); SetInt(402, 600); diff --git a/Projects/UOContent/Mobiles/Special/Paragon.cs b/Projects/UOContent/Mobiles/Special/Paragon.cs index feb1c4b84..be9c805e3 100644 --- a/Projects/UOContent/Mobiles/Special/Paragon.cs +++ b/Projects/UOContent/Mobiles/Special/Paragon.cs @@ -6,15 +6,15 @@ namespace Server.Mobiles { public static class Paragon { - public static double ChestChance = .10; // Chance that a paragon will carry a paragon chest - public static double ChocolateIngredientChance = .20; // Chance that a paragon will drop a chocolatiering ingredient + public const double ChestChance = 0.10; // Chance that a paragon will carry a paragon chest + public const double ChocolateIngredientChance = 0.20; // Chance that a paragon will drop a chocolatiering ingredient public static Map[] Maps = { Map.Ilshenar }; - private static readonly TimeSpan FastRegenRate = TimeSpan.FromSeconds(.5); + private static readonly TimeSpan FastRegenRate = TimeSpan.FromSeconds(0.5); private static readonly TimeSpan CPUSaverRate = TimeSpan.FromSeconds(2); public static Type[] Artifacts = @@ -36,15 +36,15 @@ namespace Server.Mobiles public static int Hue = 0x501; // Paragon hue // Buffs - public static double HitsBuff = 5.0; - public static double StrBuff = 1.05; - public static double IntBuff = 1.20; - public static double DexBuff = 1.20; - public static double SkillsBuff = 1.20; - public static double SpeedBuff = 1.20; - public static double FameBuff = 1.40; - public static double KarmaBuff = 1.40; - public static int DamageBuff = 5; + public const double HitsBuff = 5.0; + public const double StrBuff = 1.05; + public const double IntBuff = 1.20; + public const double DexBuff = 1.20; + public const double SkillsBuff = 1.20; + public const double SpeedBuff = 1.20; + public const double FameBuff = 1.40; + public const double KarmaBuff = 1.40; + public const int DamageBuff = 5; public static void Convert(BaseCreature bc) { @@ -186,7 +186,7 @@ namespace Server.Mobiles fame = 32000; } - var chance = 1 / Math.Round(20.0 - fame / 3200); + var chance = 1 / Math.Round(20.0 - fame / 3200.0); return chance > Utility.RandomDouble(); } diff --git a/Projects/UOContent/Mobiles/Special/Semidar.cs b/Projects/UOContent/Mobiles/Special/Semidar.cs index e6092bd43..f2227a90b 100644 --- a/Projects/UOContent/Mobiles/Special/Semidar.cs +++ b/Projects/UOContent/Mobiles/Special/Semidar.cs @@ -12,6 +12,8 @@ namespace Server.Mobiles Body = 174; BaseSoundID = 0x4B0; + SetSpeed(0.1, 0.6); + SetStr(502, 600); SetDex(102, 200); SetInt(601, 750); diff --git a/Projects/UOContent/Mobiles/Special/Silvani.cs b/Projects/UOContent/Mobiles/Special/Silvani.cs index d23bd0221..cdd9c0e75 100644 --- a/Projects/UOContent/Mobiles/Special/Silvani.cs +++ b/Projects/UOContent/Mobiles/Special/Silvani.cs @@ -3,11 +3,13 @@ namespace Server.Mobiles public class Silvani : BaseCreature { [Constructible] - public Silvani() : base(AIType.AI_Mage, FightMode.Evil, 18, 1, 0.1, 0.2) + public Silvani() : base(AIType.AI_Mage, FightMode.Evil, 18) { Body = 176; BaseSoundID = 0x467; + SetSpeed(0.25, 0.55); + SetStr(253, 400); SetDex(157, 850); SetInt(503, 800); diff --git a/Projects/UOContent/Mobiles/Townfolk/BaseEscortable.cs b/Projects/UOContent/Mobiles/Townfolk/BaseEscortable.cs index 21dbb152b..e7726c6c8 100644 --- a/Projects/UOContent/Mobiles/Townfolk/BaseEscortable.cs +++ b/Projects/UOContent/Mobiles/Townfolk/BaseEscortable.cs @@ -92,9 +92,10 @@ namespace Server.Mobiles private MLQuest m_MLQuest; [Constructible] - public BaseEscortable() - : base(AIType.AI_Melee, FightMode.Aggressor, 22, 1, 0.2, 1.0) + public BaseEscortable() : base(AIType.AI_Melee, FightMode.Aggressor, 22) { + SetSpeed(0.3, 1.0); + InitBody(); InitOutfit(); diff --git a/Projects/UOContent/Mobiles/Vendors/BaseVendor.cs b/Projects/UOContent/Mobiles/Vendors/BaseVendor.cs index 712ba2698..ddd4a87e7 100644 --- a/Projects/UOContent/Mobiles/Vendors/BaseVendor.cs +++ b/Projects/UOContent/Mobiles/Vendors/BaseVendor.cs @@ -52,9 +52,9 @@ namespace Server.Mobiles } } - public BaseVendor(string title = null) - : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) + public BaseVendor(string title = null) : base(AIType.AI_Vendor, FightMode.None, 2) { + SetSpeed(0.5, 2); LoadSBInfo(); Title = title; From c64e3e3ba89c6cd5c236d0f3a0fd1942d988a60c Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Tue, 15 Mar 2022 19:39:52 -0700 Subject: [PATCH 101/213] fix: Fixes bad movement checks (#960) --- .../UOContent/Engines/Pathing/Movement.cs | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/Projects/UOContent/Engines/Pathing/Movement.cs b/Projects/UOContent/Engines/Pathing/Movement.cs index 1b733bea3..3a4a5acec 100644 --- a/Projects/UOContent/Engines/Pathing/Movement.cs +++ b/Projects/UOContent/Engines/Pathing/Movement.cs @@ -406,7 +406,15 @@ namespace Server.Movement var notWater = !itemData.Wet; - if (!itemData.Surface && itemData.Impassable && (!canSwim || notWater) || cantWalk && notWater) + /* + * To move we must satisfy the following: + * 1. Item is a _passable_ surface and Mob can walk -or- + * 2. Item is water and Mob can swim + */ + if ( + (!itemData.Surface || itemData.Impassable) && (!canSwim || notWater) || + cantWalk && notWater + ) { continue; } @@ -477,7 +485,17 @@ namespace Server.Movement var notWater = !itemData.Wet; - if (item.Movable || !itemData.Surface && itemData.Impassable && (!canSwim || notWater) || cantWalk && notWater) + /* + * To move we must satisfy the following: + * 1. Item is not movable + * 2. Item is a _passable_ surface and Mob can walk -or- + * Item is water and Mob can swim + */ + if ( + item.Movable || + (!itemData.Surface || itemData.Impassable) && (!canSwim || notWater) || + cantWalk && notWater + ) { continue; } @@ -581,7 +599,7 @@ namespace Server.Movement return moveIsOk; } - private bool CanMoveOver(Mobile m, Mobile t) => + private static bool CanMoveOver(Mobile m, Mobile t) => !t.Alive || !m.Alive || t.IsDeadBondedPet || m.IsDeadBondedPet || t.Hidden && t.AccessLevel > AccessLevel.Player; private void GetStartZ(Mobile m, Map map, Point3D loc, List itemList, out int zLow, out int zTop) From 1e5b1a11a8e087a036c68f65305bf511004195f9 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Tue, 15 Mar 2022 20:02:40 -0700 Subject: [PATCH 102/213] fix: Cleans up unused code (#961) --- Projects/UOContent/Mobiles/BaseCreature.cs | 86 +++------------------- 1 file changed, 10 insertions(+), 76 deletions(-) diff --git a/Projects/UOContent/Mobiles/BaseCreature.cs b/Projects/UOContent/Mobiles/BaseCreature.cs index c80a70bf2..44ba6a520 100644 --- a/Projects/UOContent/Mobiles/BaseCreature.cs +++ b/Projects/UOContent/Mobiles/BaseCreature.cs @@ -21,7 +21,6 @@ using Server.Spells.Necromancy; using Server.Spells.Sixth; using Server.Spells.Spellweaving; using Server.Targeting; -using Server.Utilities; namespace Server.Mobiles { @@ -249,9 +248,6 @@ namespace Server.Mobiles typeof(Gold) }; - private readonly List m_SpellAttack; // List of attack spell/power - private readonly List m_SpellDefense; // List of defensive spell/power - private bool _summoned; private bool m_bTamable; @@ -360,9 +356,6 @@ namespace Server.Mobiles Debug = false; - m_SpellAttack = new List(); - m_SpellDefense = new List(); - m_Controlled = false; m_ControlMaster = null; ControlTarget = null; @@ -390,9 +383,6 @@ namespace Server.Mobiles public BaseCreature(Serial serial) : base(serial) { - m_SpellAttack = new List(); - m_SpellDefense = new List(); - Debug = false; } @@ -1689,7 +1679,7 @@ namespace Server.Mobiles { base.Serialize(writer); - writer.Write(19); // version + writer.Write(20); // version writer.Write((int)m_CurrentAI); writer.Write((int)m_DefaultAI); @@ -1710,18 +1700,6 @@ namespace Server.Mobiles // Version 1 writer.Write(RangeHome); - writer.Write(m_SpellAttack.Count); - for (var i = 0; i < m_SpellAttack.Count; i++) - { - writer.Write(m_SpellAttack[i].ToString()); - } - - writer.Write(m_SpellDefense.Count); - for (var i = 0; i < m_SpellDefense.Count; i++) - { - writer.Write(m_SpellDefense[i].ToString()); - } - // Version 2 writer.Write((int)FightMode); @@ -1854,27 +1832,20 @@ namespace Server.Mobiles { RangeHome = reader.ReadInt(); - var iCount = reader.ReadInt(); - for (var i = 0; i < iCount; i++) + if (version < 20) { - var str = reader.ReadString(); - var type = Type.GetType(str); - - if (type != null) + // Spell Attacks + var iCount = reader.ReadInt(); // Count + for (var i = 0; i < iCount; i++) { - m_SpellAttack.Add(type); + reader.ReadString(); // Spell Type } - } - iCount = reader.ReadInt(); - for (var i = 0; i < iCount; i++) - { - var str = reader.ReadString(); - var type = Type.GetType(str); - - if (type != null) + // Spell Defenses + iCount = reader.ReadInt(); // Count + for (var i = 0; i < iCount; i++) { - m_SpellDefense.Add(type); + reader.ReadString(); // Spell Type } } } @@ -2769,43 +2740,6 @@ namespace Server.Mobiles } } - public void AddSpellAttack(Type type) - { - m_SpellAttack.Add(type); - } - - public void AddSpellDefense(Type type) - { - m_SpellDefense.Add(type); - } - - public Spell GetAttackSpellRandom() => m_SpellAttack.RandomElement()?.CreateInstance(this, null); - - public Spell GetDefenseSpellRandom() => m_SpellDefense.RandomElement()?.CreateInstance(this, null); - - public Spell GetSpellSpecific(Type type) - { - int i; - - for (i = 0; i < m_SpellAttack.Count; i++) - { - if (m_SpellAttack[i] == type) - { - return type.CreateInstance(this, null); - } - } - - for (i = 0; i < m_SpellDefense.Count; i++) - { - if (m_SpellDefense[i] == type) - { - return type.CreateInstance(this, null); - } - } - - return null; - } - public override void OnDoubleClick(Mobile from) { if (from.AccessLevel >= AccessLevel.GameMaster && !Body.IsHuman) From 89f3a0522cd86142c435e325821136b441184304 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Fri, 18 Mar 2022 12:56:42 -0700 Subject: [PATCH 103/213] fix: Round 3 of speed updates for NPCs (#963) - [X] Fixes mobs having 0 speed. - [X] Fixes mobs missing legacy speeds. --- Distribution/Data/npc-speeds.json | 25 +++++++++++++------ .../Ethics/Evil/Mobiles/UnholyFamiliar.cs | 3 +-- .../Mobiles/Guards/BaseFactionGuard.cs | 1 + .../Dark Tides/Mobiles/SummonedPaladin.cs | 1 + .../Emino's Undertaking/Mobiles/Henchman.cs | 1 + .../Haochi's Trials/Mobiles/CursedSoul.cs | 1 + .../Haochi's Trials/Mobiles/DeadlyImp.cs | 1 + .../Haochi's Trials/Mobiles/DiseasedCat.cs | 1 + .../Haochi's Trials/Mobiles/FierceDragon.cs | 1 + .../Haochi's Trials/Mobiles/InjuredWolf.cs | 1 + .../Haochi's Trials/Mobiles/YoungNinja.cs | 1 + .../Haochi's Trials/Mobiles/YoungRonin.cs | 1 + .../Uzeraan Turmoil/Mobiles/MilitiaFighter.cs | 1 + .../Halloween/2006/Engines/TrickOrTreat.cs | 4 +-- .../Halloween/2012/Engines/PlayerZombies.cs | 7 +++--- .../Items/Talismans/TalismanSummons.cs | 1 + Projects/UOContent/Mobiles/BaseCreature.cs | 19 +++++--------- .../Mobiles/Familiars/BaseFamiliar.cs | 4 +-- .../Monsters/LBR/Jukas/ChaosDragoon.cs | 2 +- .../Monsters/LBR/Jukas/ChaosDragoonElite.cs | 2 +- .../Monsters/LBR/Meers/EnragedCreatures.cs | 23 +++++------------ .../Mobiles/Monsters/ML/Animal/Ferret.cs | 1 + .../Monsters/ML/Animal/RagingGrizzlyBear.cs | 1 + .../Mobiles/Monsters/ML/Animal/Squirrel.cs | 1 + .../Monsters/ML/Blighted Grove/Hydra.cs | 3 +-- .../Monsters/Misc/Melee/BladeSpirits.cs | 2 +- .../Monsters/Misc/Melee/EnergyVortex.cs | 3 +-- .../Mobiles/Monsters/SE/KazeKemono.cs | 6 ++--- .../Mobiles/Monsters/SE/LadyOfTheSnow.cs | 3 +-- .../Mobiles/Monsters/SE/TsukiWolf.cs | 3 +-- .../Mobiles/Special/BaseShieldGuard.cs | 1 + Projects/UOContent/Mobiles/Townfolk/Actor.cs | 1 + Projects/UOContent/Mobiles/Townfolk/Artist.cs | 4 +-- Projects/UOContent/Mobiles/Townfolk/Gypsy.cs | 4 +-- .../Mobiles/Townfolk/HarborMaster.cs | 4 +-- .../UOContent/Mobiles/Townfolk/Sculptor.cs | 4 +-- .../UOContent/Spells/Ninjitsu/MirrorImage.cs | 1 + .../Spells/Spellweaving/Mobiles/ArcaneFey.cs | 1 + .../Spellweaving/Mobiles/ArcaneFiend.cs | 1 + .../Spells/Spellweaving/Mobiles/NatureFury.cs | 4 +-- 40 files changed, 76 insertions(+), 73 deletions(-) diff --git a/Distribution/Data/npc-speeds.json b/Distribution/Data/npc-speeds.json index b2b376d92..ea3146211 100644 --- a/Distribution/Data/npc-speeds.json +++ b/Distribution/Data/npc-speeds.json @@ -2,7 +2,7 @@ { "name": "Slow", "active": 0.6, - "passive": 1.2, + "passive": 1.4, "types": [ "AntLion", "ArcticOgreLord", "BogThing", "Bogle", "BoneKnight", "EarthElemental", @@ -14,13 +14,14 @@ "SewerRat", "Skeleton", "Slime", "Zombie", "Walrus", "RestlessSoul", "CrystalElemental", "DarknightCreeper", "MoundOfMaggots", - "Juggernaut", "Yamandon", "Serado" + "Juggernaut", "Yamandon", "Serado", + "GreaterDragon", "PlagueBeastLord" ] }, { "name": "Fast", - "active": 0.4, - "passive": 0.8, + "active": 0.3, + "passive": 1.0, "types": [ "LordOaks", "Silvani", "AirElemental", "AncientWyrm", "Balron", "BladeSpirits", @@ -39,12 +40,18 @@ "Grobu", "Gnaw", "Guile", "Irk", "Spite", "LadyLissith", "LadySabrix", "Malefic", "Silk", - "Virulent", "SeaHorse" + "Virulent", "SeaHorse", "UnholyFamiliar", + "HolyFamiliar", "GiantIceWorm", "Phoenix", + "Succubus", "EnragedRabbit", "EnragedHind", + "EnragedHart", "EnragedBlackBear", "EnragedEagle", + "RagingGrizzlyBear", "CorrosiveSlime", "DarkWisp", + "DarkGuardian", "HarrowerTentacles", "ServantOfSemidar", + "Ninja", "Samurai" ] }, { "name": "Very Fast", - "active": 0.35, + "active": 0.25, "passive": 0.7, "types": [ "Barracoon", "Mephitis", "Neira", @@ -61,7 +68,7 @@ { "name": "Medium", "active": 0.5, - "passive": 1.0, + "passive": 1.2, "types": [ "AcidElemental", "AgapiteElemental", "Alligator", "AncientLich", "Betrayer", "Bird", @@ -133,7 +140,9 @@ "Kappa", "KazeKemono", "DeathwatchBeetle", "TsukiWolf", "YomotsuElder", "YomotsuPriest", "YomotsuWarrior", "RevenantLion", "Oni", - "Gaman", "Crane", "Beetle" + "Gaman", "Crane", "Beetle", + "Parrot", "ElfBrigand", "GreaterMongbat", + "AnimatedWeapon", "Reaper", "Corpser" ] } ] diff --git a/Projects/UOContent/Engines/Ethics/Evil/Mobiles/UnholyFamiliar.cs b/Projects/UOContent/Engines/Ethics/Evil/Mobiles/UnholyFamiliar.cs index e0ee6d231..2b05632e9 100644 --- a/Projects/UOContent/Engines/Ethics/Evil/Mobiles/UnholyFamiliar.cs +++ b/Projects/UOContent/Engines/Ethics/Evil/Mobiles/UnholyFamiliar.cs @@ -5,8 +5,7 @@ namespace Server.Mobiles public class UnholyFamiliar : BaseCreature { [Constructible] - public UnholyFamiliar() - : base(AIType.AI_Melee) + public UnholyFamiliar() : base(AIType.AI_Melee) { Body = 99; BaseSoundID = 0xE5; diff --git a/Projects/UOContent/Engines/Factions/Mobiles/Guards/BaseFactionGuard.cs b/Projects/UOContent/Engines/Factions/Mobiles/Guards/BaseFactionGuard.cs index 5b59ecb6f..ebabde5c0 100644 --- a/Projects/UOContent/Engines/Factions/Mobiles/Guards/BaseFactionGuard.cs +++ b/Projects/UOContent/Engines/Factions/Mobiles/Guards/BaseFactionGuard.cs @@ -37,6 +37,7 @@ namespace Server.Factions public BaseFactionGuard(string title) : base(AIType.AI_Melee) { + SetSpeed(0.3, 1.0); Orders = new Orders(this); Title = title; diff --git a/Projects/UOContent/Engines/Quests/Dark Tides/Mobiles/SummonedPaladin.cs b/Projects/UOContent/Engines/Quests/Dark Tides/Mobiles/SummonedPaladin.cs index a01569975..6164a70f0 100644 --- a/Projects/UOContent/Engines/Quests/Dark Tides/Mobiles/SummonedPaladin.cs +++ b/Projects/UOContent/Engines/Quests/Dark Tides/Mobiles/SummonedPaladin.cs @@ -13,6 +13,7 @@ namespace Server.Engines.Quests.Necro { m_Necromancer = necromancer; + SetSpeed(0.3, 1.0); InitStats(45, 30, 5); Title = "the Paladin"; diff --git a/Projects/UOContent/Engines/Quests/Emino's Undertaking/Mobiles/Henchman.cs b/Projects/UOContent/Engines/Quests/Emino's Undertaking/Mobiles/Henchman.cs index d4e24e217..69d17d058 100644 --- a/Projects/UOContent/Engines/Quests/Emino's Undertaking/Mobiles/Henchman.cs +++ b/Projects/UOContent/Engines/Quests/Emino's Undertaking/Mobiles/Henchman.cs @@ -8,6 +8,7 @@ namespace Server.Engines.Quests.Ninja [Constructible] public Henchman() : base(AIType.AI_Melee, FightMode.Aggressor) { + SetSpeed(0.3, 1.0); InitStats(45, 30, 5); Hue = Race.Human.RandomSkinHue(); diff --git a/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/CursedSoul.cs b/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/CursedSoul.cs index 151f85901..4e9e4b2d2 100644 --- a/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/CursedSoul.cs +++ b/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/CursedSoul.cs @@ -11,6 +11,7 @@ namespace Server.Engines.Quests.Samurai Body = 3; BaseSoundID = 471; + SetSpeed(0.3, 1.0); SetStr(20, 40); SetDex(40, 60); SetInt(15, 25); diff --git a/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/DeadlyImp.cs b/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/DeadlyImp.cs index 7d9085567..abfcf594b 100644 --- a/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/DeadlyImp.cs +++ b/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/DeadlyImp.cs @@ -11,6 +11,7 @@ namespace Server.Engines.Quests.Samurai BaseSoundID = 422; Hue = 0x66A; + SetSpeed(0.3, 1.0); SetStr(91, 115); SetDex(61, 80); SetInt(86, 105); diff --git a/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/DiseasedCat.cs b/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/DiseasedCat.cs index c73bbc558..6b47e683d 100644 --- a/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/DiseasedCat.cs +++ b/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/DiseasedCat.cs @@ -11,6 +11,7 @@ namespace Server.Engines.Quests.Samurai Hue = Utility.RandomAnimalHue(); BaseSoundID = 0x69; + SetSpeed(0.3, 1.0); SetStr(9); SetDex(35); SetInt(5); diff --git a/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/FierceDragon.cs b/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/FierceDragon.cs index 914aec85e..010514878 100644 --- a/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/FierceDragon.cs +++ b/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/FierceDragon.cs @@ -10,6 +10,7 @@ namespace Server.Engines.Quests.Samurai Body = 103; BaseSoundID = 362; + SetSpeed(0.3, 1.0); SetStr(6000, 6020); SetDex(0); SetInt(850, 870); diff --git a/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/InjuredWolf.cs b/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/InjuredWolf.cs index fd7ab7078..484342255 100644 --- a/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/InjuredWolf.cs +++ b/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/InjuredWolf.cs @@ -12,6 +12,7 @@ namespace Server.Engines.Quests.Samurai Hue = Utility.RandomAnimalHue(); + SetSpeed(0.3, 1.0); SetStr(10, 20); SetDex(45, 65); SetInt(10, 15); diff --git a/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/YoungNinja.cs b/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/YoungNinja.cs index f3b63e1b2..51d97861a 100644 --- a/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/YoungNinja.cs +++ b/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/YoungNinja.cs @@ -8,6 +8,7 @@ namespace Server.Engines.Quests.Samurai [Constructible] public YoungNinja() : base(AIType.AI_Melee, FightMode.Aggressor) { + SetSpeed(0.3, 1.0); InitStats(45, 30, 5); SetHits(20, 30); diff --git a/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/YoungRonin.cs b/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/YoungRonin.cs index c2f1aed70..29644ffbd 100644 --- a/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/YoungRonin.cs +++ b/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/YoungRonin.cs @@ -8,6 +8,7 @@ namespace Server.Engines.Quests.Samurai [Constructible] public YoungRonin() : base(AIType.AI_Melee, FightMode.Aggressor) { + SetSpeed(0.3, 1.0); InitStats(45, 30, 5); SetHits(10, 20); diff --git a/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Mobiles/MilitiaFighter.cs b/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Mobiles/MilitiaFighter.cs index 34b3947a6..505add3d7 100644 --- a/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Mobiles/MilitiaFighter.cs +++ b/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Mobiles/MilitiaFighter.cs @@ -11,6 +11,7 @@ namespace Server.Engines.Quests.Haven [Constructible] public MilitiaFighter() : base(AIType.AI_Melee) { + SetSpeed(0.3, 1.0); InitStats(40, 30, 5); Title = "the Militia Fighter"; diff --git a/Projects/UOContent/Holiday Stuff/Halloween/2006/Engines/TrickOrTreat.cs b/Projects/UOContent/Holiday Stuff/Halloween/2006/Engines/TrickOrTreat.cs index a1cc80e8b..c66f1ccf2 100644 --- a/Projects/UOContent/Holiday Stuff/Halloween/2006/Engines/TrickOrTreat.cs +++ b/Projects/UOContent/Holiday Stuff/Halloween/2006/Engines/TrickOrTreat.cs @@ -275,9 +275,9 @@ namespace Server.Engines.Events private readonly Mobile m_From; - public NaughtyTwin(Mobile from) - : base(AIType.AI_Melee, FightMode.None) + public NaughtyTwin(Mobile from) : base(AIType.AI_Melee, FightMode.None) { + SetSpeed(0.3, 1.0); if (TrickOrTreat.CheckMobile(from)) { Body = from.Body; diff --git a/Projects/UOContent/Holiday Stuff/Halloween/2012/Engines/PlayerZombies.cs b/Projects/UOContent/Holiday Stuff/Halloween/2012/Engines/PlayerZombies.cs index cf1e2ad43..c24d2572f 100644 --- a/Projects/UOContent/Holiday Stuff/Halloween/2012/Engines/PlayerZombies.cs +++ b/Projects/UOContent/Holiday Stuff/Halloween/2012/Engines/PlayerZombies.cs @@ -145,8 +145,7 @@ namespace Server.Engines.Events public partial class PlayerBones : BaseContainer { [Constructible] - public PlayerBones(string name) - : base(Utility.RandomMinMax(0x0ECA, 0x0ED2)) + public PlayerBones(string name) : base(Utility.RandomMinMax(0x0ECA, 0x0ED2)) { Name = $"{name}'s bones"; @@ -168,14 +167,14 @@ namespace Server.Engines.Events public override string DefaultName => _deadPlayer != null ? $"{_deadPlayer.Name}'s Zombie Skeleton" : "Zombie Skeleton"; - public ZombieSkeleton(PlayerMobile player = null) - : base(AIType.AI_Melee) + public ZombieSkeleton(PlayerMobile player = null) : base(AIType.AI_Melee) { _deadPlayer = player; Body = 0x93; BaseSoundID = 0x1c3; + SetSpeed(0.3, 1.0); SetStr(500); SetDex(500); SetInt(500); diff --git a/Projects/UOContent/Items/Talismans/TalismanSummons.cs b/Projects/UOContent/Items/Talismans/TalismanSummons.cs index 262334eb7..4f8a4ddf9 100644 --- a/Projects/UOContent/Items/Talismans/TalismanSummons.cs +++ b/Projects/UOContent/Items/Talismans/TalismanSummons.cs @@ -11,6 +11,7 @@ namespace Server.Mobiles public BaseTalismanSummon() : base(AIType.AI_Melee, FightMode.None) { + SetSpeed(0.3, 1.0); // TODO: Stats/skills } diff --git a/Projects/UOContent/Mobiles/BaseCreature.cs b/Projects/UOContent/Mobiles/BaseCreature.cs index 44ba6a520..a57f8443a 100644 --- a/Projects/UOContent/Mobiles/BaseCreature.cs +++ b/Projects/UOContent/Mobiles/BaseCreature.cs @@ -321,9 +321,6 @@ namespace Server.Mobiles FightMode mode = FightMode.Closest, int iRangePerception = 10, int iRangeFight = 1 - // , - // double activeSpeed = 0, - // double passiveSpeed = 0 ) { if (iRangePerception == OldRangePerception) @@ -341,16 +338,12 @@ namespace Server.Mobiles FightMode = mode; - // if (activeSpeed > 0 && passiveSpeed > 0) - // { - // ActiveSpeed = activeSpeed; - // PassiveSpeed = passiveSpeed; - // CurrentSpeed = passiveSpeed; - // } - // else - // { - // CurrentSpeed = SpeedInfo.MaxMonsterDelay * 2; - // } + if (LegacySpeedInfo.Enabled && LegacySpeedInfo.GetSpeeds(GetType(), out var activeSpeed, out var passiveSpeed)) + { + ActiveSpeed = activeSpeed; + PassiveSpeed = passiveSpeed; + CurrentSpeed = passiveSpeed; + } m_Team = 0; diff --git a/Projects/UOContent/Mobiles/Familiars/BaseFamiliar.cs b/Projects/UOContent/Mobiles/Familiars/BaseFamiliar.cs index ac550132a..dba69c327 100644 --- a/Projects/UOContent/Mobiles/Familiars/BaseFamiliar.cs +++ b/Projects/UOContent/Mobiles/Familiars/BaseFamiliar.cs @@ -8,9 +8,9 @@ namespace Server.Mobiles { private bool m_LastHidden; - public BaseFamiliar() - : base(AIType.AI_Melee) + public BaseFamiliar() : base(AIType.AI_Melee) { + SetSpeed(0.1, 0.1); } public BaseFamiliar(Serial serial) : base(serial) diff --git a/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/ChaosDragoon.cs b/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/ChaosDragoon.cs index 26eeb161c..f55806873 100644 --- a/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/ChaosDragoon.cs +++ b/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/ChaosDragoon.cs @@ -10,7 +10,7 @@ namespace Server.Mobiles Body = 0x190; Hue = Race.Human.RandomSkinHue(); - SetSpeed(0.25, 0.55); + SetSpeed(0.25, 1.0); SetStr(176, 225); SetDex(81, 95); diff --git a/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/ChaosDragoonElite.cs b/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/ChaosDragoonElite.cs index fea4c1383..331056eb8 100644 --- a/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/ChaosDragoonElite.cs +++ b/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/ChaosDragoonElite.cs @@ -10,7 +10,7 @@ namespace Server.Mobiles Body = 0x190; Hue = Race.Human.RandomSkinHue(); - SetSpeed(0.25, 0.55); + SetSpeed(0.25, 1.0); SetStr(276, 350); SetDex(66, 90); diff --git a/Projects/UOContent/Mobiles/Monsters/LBR/Meers/EnragedCreatures.cs b/Projects/UOContent/Mobiles/Monsters/LBR/Meers/EnragedCreatures.cs index cb3996be4..2a09bf7b9 100644 --- a/Projects/UOContent/Mobiles/Monsters/LBR/Meers/EnragedCreatures.cs +++ b/Projects/UOContent/Mobiles/Monsters/LBR/Meers/EnragedCreatures.cs @@ -150,29 +150,18 @@ namespace Server.Mobiles public class BaseEnraged : BaseCreature { - public BaseEnraged(Mobile summoner) - : base(AIType.AI_Melee) + public BaseEnraged(Mobile summoner) : base(AIType.AI_Melee) { SetStr(50, 200); SetDex(50, 200); - SetHits(50, 200); - SetStam(50, 200); /* - On OSI, all stats are random 50-200, but - str is never less than hits, and dex is never - less than stam. + * On OSI, all stats are random 50-200, but + * str is never less than hits, and dex is never + * less than stam. */ - - if (Str < Hits) - { - Str = Hits; - } - - if (Dex < Stam) - { - Dex = Stam; - } + SetHits(50, Str); + SetStam(50, Dex); Karma = -1000; Tamable = false; diff --git a/Projects/UOContent/Mobiles/Monsters/ML/Animal/Ferret.cs b/Projects/UOContent/Mobiles/Monsters/ML/Animal/Ferret.cs index 413886152..9441427ae 100644 --- a/Projects/UOContent/Mobiles/Monsters/ML/Animal/Ferret.cs +++ b/Projects/UOContent/Mobiles/Monsters/ML/Animal/Ferret.cs @@ -19,6 +19,7 @@ namespace Server.Mobiles { Body = 0x117; + SetSpeed(0.3, 1.0); SetStr(41, 48); SetDex(55); SetInt(75); diff --git a/Projects/UOContent/Mobiles/Monsters/ML/Animal/RagingGrizzlyBear.cs b/Projects/UOContent/Mobiles/Monsters/ML/Animal/RagingGrizzlyBear.cs index d02acc83e..e2d67ddca 100644 --- a/Projects/UOContent/Mobiles/Monsters/ML/Animal/RagingGrizzlyBear.cs +++ b/Projects/UOContent/Mobiles/Monsters/ML/Animal/RagingGrizzlyBear.cs @@ -8,6 +8,7 @@ namespace Server.Mobiles Body = 212; BaseSoundID = 0xA3; + SetSpeed(0.3, 1.0); SetStr(1251, 1550); SetDex(801, 1050); SetInt(151, 400); diff --git a/Projects/UOContent/Mobiles/Monsters/ML/Animal/Squirrel.cs b/Projects/UOContent/Mobiles/Monsters/ML/Animal/Squirrel.cs index 1749f7d73..3ca9ff581 100644 --- a/Projects/UOContent/Mobiles/Monsters/ML/Animal/Squirrel.cs +++ b/Projects/UOContent/Mobiles/Monsters/ML/Animal/Squirrel.cs @@ -7,6 +7,7 @@ namespace Server.Mobiles { Body = 0x116; + SetSpeed(0.3, 1.0); SetStr(44, 50); SetDex(35); SetInt(5); diff --git a/Projects/UOContent/Mobiles/Monsters/ML/Blighted Grove/Hydra.cs b/Projects/UOContent/Mobiles/Monsters/ML/Blighted Grove/Hydra.cs index b4b5e06f9..a9c563b0b 100644 --- a/Projects/UOContent/Mobiles/Monsters/ML/Blighted Grove/Hydra.cs +++ b/Projects/UOContent/Mobiles/Monsters/ML/Blighted Grove/Hydra.cs @@ -5,8 +5,7 @@ namespace Server.Mobiles public class Hydra : BaseCreature { [Constructible] - public Hydra() - : base(AIType.AI_Melee) + public Hydra() : base(AIType.AI_Melee) { Body = 0x109; BaseSoundID = 0x16A; diff --git a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/BladeSpirits.cs b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/BladeSpirits.cs index 710c5420c..0f88661c9 100644 --- a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/BladeSpirits.cs +++ b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/BladeSpirits.cs @@ -10,7 +10,7 @@ namespace Server.Mobiles { Body = 574; - SetSpeed(0.6, 1.25); + SetSpeed(0.5, 1.2); SetStr(150); SetDex(150); SetInt(100); diff --git a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/EnergyVortex.cs b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/EnergyVortex.cs index ae7a1517b..f081cedff 100644 --- a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/EnergyVortex.cs +++ b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/EnergyVortex.cs @@ -6,8 +6,7 @@ namespace Server.Mobiles public class EnergyVortex : BaseCreature { [Constructible] - public EnergyVortex() - : base(AIType.AI_Melee) + public EnergyVortex() : base(AIType.AI_Melee) { if (Core.SE && Utility.RandomDouble() < 0.002) // Per OSI FoF, it's a 1/500 chance. { diff --git a/Projects/UOContent/Mobiles/Monsters/SE/KazeKemono.cs b/Projects/UOContent/Mobiles/Monsters/SE/KazeKemono.cs index 2eacb266b..d4810186c 100644 --- a/Projects/UOContent/Mobiles/Monsters/SE/KazeKemono.cs +++ b/Projects/UOContent/Mobiles/Monsters/SE/KazeKemono.cs @@ -7,12 +7,10 @@ namespace Server.Mobiles { private static readonly Dictionary m_FlurryOfTwigsTable = new(); - private static readonly Dictionary m_ChlorophylBlastTable = - new(); + private static readonly Dictionary m_ChlorophylBlastTable = new(); [Constructible] - public KazeKemono() - : base(AIType.AI_Mage) + public KazeKemono() : base(AIType.AI_Mage) { Body = 196; BaseSoundID = 655; diff --git a/Projects/UOContent/Mobiles/Monsters/SE/LadyOfTheSnow.cs b/Projects/UOContent/Mobiles/Monsters/SE/LadyOfTheSnow.cs index 17881e488..46d841731 100644 --- a/Projects/UOContent/Mobiles/Monsters/SE/LadyOfTheSnow.cs +++ b/Projects/UOContent/Mobiles/Monsters/SE/LadyOfTheSnow.cs @@ -10,8 +10,7 @@ namespace Server.Mobiles private static readonly Dictionary m_Table = new(); [Constructible] - public LadyOfTheSnow() - : base(AIType.AI_Mage) + public LadyOfTheSnow() : base(AIType.AI_Mage) { Body = 252; BaseSoundID = 0x482; diff --git a/Projects/UOContent/Mobiles/Monsters/SE/TsukiWolf.cs b/Projects/UOContent/Mobiles/Monsters/SE/TsukiWolf.cs index 8a389b035..6ff33c378 100644 --- a/Projects/UOContent/Mobiles/Monsters/SE/TsukiWolf.cs +++ b/Projects/UOContent/Mobiles/Monsters/SE/TsukiWolf.cs @@ -10,8 +10,7 @@ namespace Server.Mobiles private static readonly Dictionary m_Table = new(); [Constructible] - public TsukiWolf() - : base(AIType.AI_Melee) + public TsukiWolf() : base(AIType.AI_Melee) { Body = 250; Hue = Utility.Random(3) == 0 ? Utility.RandomNeutralHue() : 0; diff --git a/Projects/UOContent/Mobiles/Special/BaseShieldGuard.cs b/Projects/UOContent/Mobiles/Special/BaseShieldGuard.cs index a978383c2..829cea481 100644 --- a/Projects/UOContent/Mobiles/Special/BaseShieldGuard.cs +++ b/Projects/UOContent/Mobiles/Special/BaseShieldGuard.cs @@ -7,6 +7,7 @@ namespace Server.Mobiles { public BaseShieldGuard() : base(AIType.AI_Melee, FightMode.Aggressor, 14) { + SetSpeed(0.5, 2.0); InitStats(1000, 1000, 1000); Title = "the guard"; diff --git a/Projects/UOContent/Mobiles/Townfolk/Actor.cs b/Projects/UOContent/Mobiles/Townfolk/Actor.cs index 6b0352779..38078b040 100644 --- a/Projects/UOContent/Mobiles/Townfolk/Actor.cs +++ b/Projects/UOContent/Mobiles/Townfolk/Actor.cs @@ -7,6 +7,7 @@ namespace Server.Mobiles [Constructible] public Actor() : base(AIType.AI_Animal, FightMode.None) { + SetSpeed(0.6, 1.2); InitStats(31, 41, 51); SpeechHue = Utility.RandomDyedHue(); diff --git a/Projects/UOContent/Mobiles/Townfolk/Artist.cs b/Projects/UOContent/Mobiles/Townfolk/Artist.cs index dd72595c9..4f6276882 100644 --- a/Projects/UOContent/Mobiles/Townfolk/Artist.cs +++ b/Projects/UOContent/Mobiles/Townfolk/Artist.cs @@ -5,9 +5,9 @@ namespace Server.Mobiles public class Artist : BaseCreature { [Constructible] - public Artist() - : base(AIType.AI_Animal, FightMode.None) + public Artist() : base(AIType.AI_Animal, FightMode.None) { + SetSpeed(0.6, 1.2); InitStats(31, 41, 51); SetSkill(SkillName.Healing, 36, 68); diff --git a/Projects/UOContent/Mobiles/Townfolk/Gypsy.cs b/Projects/UOContent/Mobiles/Townfolk/Gypsy.cs index ff01a3247..b6cc02447 100644 --- a/Projects/UOContent/Mobiles/Townfolk/Gypsy.cs +++ b/Projects/UOContent/Mobiles/Townfolk/Gypsy.cs @@ -5,9 +5,9 @@ namespace Server.Mobiles public class Gypsy : BaseCreature { [Constructible] - public Gypsy() - : base(AIType.AI_Animal, FightMode.None) + public Gypsy() : base(AIType.AI_Animal, FightMode.None) { + SetSpeed(0.6, 1.2); InitStats(31, 41, 51); SpeechHue = Utility.RandomDyedHue(); diff --git a/Projects/UOContent/Mobiles/Townfolk/HarborMaster.cs b/Projects/UOContent/Mobiles/Townfolk/HarborMaster.cs index b3c9eea4b..50b2edd3f 100644 --- a/Projects/UOContent/Mobiles/Townfolk/HarborMaster.cs +++ b/Projects/UOContent/Mobiles/Townfolk/HarborMaster.cs @@ -5,9 +5,9 @@ namespace Server.Mobiles public class HarborMaster : BaseCreature { [Constructible] - public HarborMaster() - : base(AIType.AI_Animal, FightMode.None) + public HarborMaster() : base(AIType.AI_Animal, FightMode.None) { + SetSpeed(0.6, 1.2); InitStats(31, 41, 51); SetSkill(SkillName.Mining, 36, 68); diff --git a/Projects/UOContent/Mobiles/Townfolk/Sculptor.cs b/Projects/UOContent/Mobiles/Townfolk/Sculptor.cs index 26034b762..2ce527740 100644 --- a/Projects/UOContent/Mobiles/Townfolk/Sculptor.cs +++ b/Projects/UOContent/Mobiles/Townfolk/Sculptor.cs @@ -5,9 +5,9 @@ namespace Server.Mobiles public class Sculptor : BaseCreature { [Constructible] - public Sculptor() - : base(AIType.AI_Animal, FightMode.None) + public Sculptor() : base(AIType.AI_Animal, FightMode.None) { + SetSpeed(0.6, 1.2); InitStats(31, 41, 51); SpeechHue = Utility.RandomDyedHue(); diff --git a/Projects/UOContent/Spells/Ninjitsu/MirrorImage.cs b/Projects/UOContent/Spells/Ninjitsu/MirrorImage.cs index 896d01456..ed4712940 100644 --- a/Projects/UOContent/Spells/Ninjitsu/MirrorImage.cs +++ b/Projects/UOContent/Spells/Ninjitsu/MirrorImage.cs @@ -130,6 +130,7 @@ namespace Server.Mobiles public Clone(Mobile caster) : base(AIType.AI_Melee, FightMode.None) { + SetSpeed(0.3, 1.0); m_Caster = caster; Body = caster.Body; diff --git a/Projects/UOContent/Spells/Spellweaving/Mobiles/ArcaneFey.cs b/Projects/UOContent/Spells/Spellweaving/Mobiles/ArcaneFey.cs index 3f1defbde..243dffd13 100644 --- a/Projects/UOContent/Spells/Spellweaving/Mobiles/ArcaneFey.cs +++ b/Projects/UOContent/Spells/Spellweaving/Mobiles/ArcaneFey.cs @@ -9,6 +9,7 @@ namespace Server.Mobiles Body = 128; BaseSoundID = 0x467; + SetSpeed(0.3, 1.0); SetStr(20); SetDex(150); SetInt(125); diff --git a/Projects/UOContent/Spells/Spellweaving/Mobiles/ArcaneFiend.cs b/Projects/UOContent/Spells/Spellweaving/Mobiles/ArcaneFiend.cs index 6041979af..34300b5aa 100644 --- a/Projects/UOContent/Spells/Spellweaving/Mobiles/ArcaneFiend.cs +++ b/Projects/UOContent/Spells/Spellweaving/Mobiles/ArcaneFiend.cs @@ -8,6 +8,7 @@ namespace Server.Mobiles Body = 74; BaseSoundID = 422; + SetSpeed(0.3, 1.0); SetStr(55); SetDex(40); SetInt(60); diff --git a/Projects/UOContent/Spells/Spellweaving/Mobiles/NatureFury.cs b/Projects/UOContent/Spells/Spellweaving/Mobiles/NatureFury.cs index effcf7802..61bad44b1 100644 --- a/Projects/UOContent/Spells/Spellweaving/Mobiles/NatureFury.cs +++ b/Projects/UOContent/Spells/Spellweaving/Mobiles/NatureFury.cs @@ -5,12 +5,12 @@ namespace Server.Mobiles public class NatureFury : BaseCreature { [Constructible] - public NatureFury() - : base(AIType.AI_Melee) + public NatureFury() : base(AIType.AI_Melee) { Body = 0x33; Hue = 0x4001; + SetSpeed(0.3, 1.0); SetStr(150); SetDex(150); SetInt(100); From daf89686d107f6d2aab51e9f5d0f6f14a731b767 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Fri, 18 Mar 2022 19:49:50 -0700 Subject: [PATCH 104/213] chore: Updates CI/CD to use .NET 6.0.201 (#964) --- .github/workflows/build-test.yml | 2 +- azure-pipelines.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 3a2b28871..2b30cb304 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -26,7 +26,7 @@ jobs: - name: Setup .NET 6 uses: actions/setup-dotnet@v1 with: - dotnet-version: 6.0.100 + dotnet-version: 6.0.201 - name: Build run: ./publish.cmd - name: Test diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 38df04622..a47ff4c5e 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -18,7 +18,7 @@ jobs: displayName: 'Install .NET 6' inputs: packageType: sdk - version: 6.0.100 + version: 6.0.201 - task: NuGetAuthenticate@0 - script: ./publish.cmd Release win displayName: 'Build' @@ -62,7 +62,7 @@ jobs: displayName: 'Install .NET 6' inputs: packageType: sdk - version: 6.0.100 + version: 6.0.201 - task: NuGetAuthenticate@0 - script: ./publish.cmd Release $(os) displayName: 'Build' From 23532db6030b67d9edf6ca532b843c22ff39ec95 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 20 Mar 2022 19:20:54 -0700 Subject: [PATCH 105/213] fix: Cleans up LINQ calls. (#965) - [X] Removes several `ToList()` uses with `PooledRefQueue` - [X] Adds a `PeekRandom` to PooledRefQueue - [X] Updates EV/BS so they dispel each other in a more efficient manner. - [X] Fixes Firebomb so it works like a normal firefield. - [X] Fixes field spells so they aren't unnecessarily using a Point3D ref more than necessary. - [X] Removes extra allocation in campfire by using reverse loop. - [X] Removes other LINQ calls that aren't needed. --- Projects/Benchmarks/Benchmarks.csproj | 2 +- .../Benchmarks/Map/MapEntitiesSelectors.cs | 6 +- .../Benchmarks/Map/MapItemSelectors.cs | 4 +- .../Benchmarks/Map/MapMobileSelectors.cs | 7 +- .../Benchmarks/Map/MapMultiSelectors.cs | 7 +- .../Benchmarks/Map/MapMultiTilesSelectors.cs | 8 +- Projects/Server.Tests/Server.Tests.csproj | 4 +- .../Tests/Collections/PooledRefQueueTests.cs | 102 +++++++++++++ Projects/Server/Collections/PooledRefQueue.cs | 16 ++ Projects/Server/Random/RandomSources.cs | 12 +- Projects/Server/Utilities/Utility.cs | 11 ++ .../UOContent.Tests/UOContent.Tests.csproj | 4 +- .../Study of the Solen Hive/NestArea.cs | 29 +++- .../Treasures of Tokuno/TreasuresOfTokuno.cs | 86 +++++------ .../Gumps/BaseImageTileButtonsGump.cs | 4 +- .../Halloween/2009/Engines/PumpkinPatch.cs | 24 +-- .../Halloween/2012/Engines/PlayerZombies.cs | 11 +- Projects/UOContent/Items/Misc/Firebomb.cs | 139 ++++-------------- .../Items/Skill Items/Camping/Campfire.cs | 38 +++-- .../Items/Skill Items/Misc/FireHorn.cs | 38 +++-- .../Weapons/Abilities/WhirlwindAttack.cs | 36 +++-- .../Mobiles/Familiars/HordeMinion.cs | 28 ++-- .../UOContent/Mobiles/Familiars/ShadowWisp.cs | 24 +-- .../Monsters/Humanoid/Melee/OrcBrute.cs | 11 +- .../Mobiles/Monsters/LBR/Meers/MeerEternal.cs | 86 ++++++----- .../Monsters/Misc/Melee/BladeSpirits.cs | 30 ++-- .../Monsters/Misc/Melee/EnergyVortex.cs | 30 ++-- .../UOContent/Mobiles/Special/Harrower.cs | 28 ++-- Projects/UOContent/Multis/Houses/BaseHouse.cs | 22 ++- Projects/UOContent/Skills/SpiritSpeak.cs | 11 +- .../UOContent/Skills/Tracking/Tracking.cs | 20 ++- Projects/UOContent/Spells/Base/SpellHelper.cs | 4 +- .../Spells/Bushido/MomentumStrike.cs | 20 ++- .../UOContent/Spells/Chivalry/DispelEvil.cs | 20 ++- .../UOContent/Spells/Eighth/Earthquake.cs | 23 ++- .../UOContent/Spells/Fifth/PoisonField.cs | 11 +- Projects/UOContent/Spells/Fourth/FireField.cs | 23 ++- .../UOContent/Spells/Seventh/EnergyField.cs | 27 ++-- .../UOContent/Spells/Sixth/ParalyzeField.cs | 14 +- .../UOContent/Spells/Third/WallOfStone.cs | 12 +- 40 files changed, 585 insertions(+), 447 deletions(-) create mode 100644 Projects/Server.Tests/Tests/Collections/PooledRefQueueTests.cs diff --git a/Projects/Benchmarks/Benchmarks.csproj b/Projects/Benchmarks/Benchmarks.csproj index ca226bba4..2720cb6da 100644 --- a/Projects/Benchmarks/Benchmarks.csproj +++ b/Projects/Benchmarks/Benchmarks.csproj @@ -11,7 +11,7 @@ - + diff --git a/Projects/Benchmarks/Benchmarks/Map/MapEntitiesSelectors.cs b/Projects/Benchmarks/Benchmarks/Map/MapEntitiesSelectors.cs index 7348824c8..7c70d3056 100644 --- a/Projects/Benchmarks/Benchmarks/Map/MapEntitiesSelectors.cs +++ b/Projects/Benchmarks/Benchmarks/Map/MapEntitiesSelectors.cs @@ -14,7 +14,7 @@ namespace Benchmarks.EntitiesSelectors public class MapEntitiesSelectors { private static readonly Sector sector = new(); - private static readonly Point3D[] locations = new[] { new Point3D(0, 0, 0), new Point3D(50, 50, 0) }; + private static readonly Point3D[] locations = { new Point3D(0, 0, 0), new Point3D(50, 50, 0) }; public static Rectangle2D[] BoundsArray() => new[] { @@ -501,8 +501,8 @@ namespace Benchmarks.EntitiesSelectors public class Sector { - public List BItems { get; set; } = new List(); - public List Mobiles { get; set; } = new List(); + public List BItems { get; set; } = new(); + public List Mobiles { get; set; } = new(); } public struct BItemWhereHyper : NetFabric.Hyperlinq.IFunction diff --git a/Projects/Benchmarks/Benchmarks/Map/MapItemSelectors.cs b/Projects/Benchmarks/Benchmarks/Map/MapItemSelectors.cs index 8eb1758d2..43f5179c0 100644 --- a/Projects/Benchmarks/Benchmarks/Map/MapItemSelectors.cs +++ b/Projects/Benchmarks/Benchmarks/Map/MapItemSelectors.cs @@ -20,7 +20,7 @@ namespace Benchmarks.ItemSelectors public class MapItemSelectors { private static readonly Sector sector = new(); - private static readonly Point3D[] locations = new[] { new Point3D(0, 0, 0), new Point3D(50, 50, 0) }; + private static readonly Point3D[] locations = { new Point3D(0, 0, 0), new Point3D(50, 50, 0) }; public static Rectangle2D[] BoundsArray() => new[] { @@ -352,7 +352,7 @@ namespace Benchmarks.ItemSelectors public class Sector { - public List BItems { get; set; } = new List(); + public List BItems { get; set; } = new(); } public struct BItemWhere : StructLinq.IFunction where T : BItem diff --git a/Projects/Benchmarks/Benchmarks/Map/MapMobileSelectors.cs b/Projects/Benchmarks/Benchmarks/Map/MapMobileSelectors.cs index c9932070f..a259981f0 100644 --- a/Projects/Benchmarks/Benchmarks/Map/MapMobileSelectors.cs +++ b/Projects/Benchmarks/Benchmarks/Map/MapMobileSelectors.cs @@ -2,7 +2,6 @@ using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Jobs; using NetFabric.Hyperlinq; using Server; -using StructLinq; using System; using System.Collections.Generic; using System.Linq; @@ -15,7 +14,7 @@ namespace Benchmarks.MobileSelectors public class MapMobileSelectors { private static readonly Sector sector = new(); - private static readonly Point3D[] locations = new[] { new Point3D(0, 0, 0), new Point3D(50, 50, 0) }; + private static readonly Point3D[] locations = { new Point3D(0, 0, 0), new Point3D(50, 50, 0) }; public static Rectangle2D[] BoundsArray() => new[] { @@ -224,10 +223,10 @@ namespace Benchmarks.MobileSelectors { public MobileDerived(Point3D location) : base(location) { } } - + public class Sector { - public List Mobiles { get; set; } = new List(); + public List Mobiles { get; set; } = new(); } public struct MobileWhereHyper : NetFabric.Hyperlinq.IFunction where T : Mobile diff --git a/Projects/Benchmarks/Benchmarks/Map/MapMultiSelectors.cs b/Projects/Benchmarks/Benchmarks/Map/MapMultiSelectors.cs index e5c6605f5..233d6b5e4 100644 --- a/Projects/Benchmarks/Benchmarks/Map/MapMultiSelectors.cs +++ b/Projects/Benchmarks/Benchmarks/Map/MapMultiSelectors.cs @@ -2,7 +2,6 @@ using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Jobs; using NetFabric.Hyperlinq; using Server; -using StructLinq; using System; using System.Collections.Generic; using System.Linq; @@ -15,7 +14,7 @@ namespace Benchmarks.MultiSelectors public class MapMultiSelectors { private static readonly Sector sector = new(); - private static readonly Point3D[] locations = new[] { new Point3D(0, 0, 0), new Point3D(50, 50, 0) }; + private static readonly Point3D[] locations = { new Point3D(0, 0, 0), new Point3D(50, 50, 0) }; public static Rectangle2D[] BoundsArray() => new[] { @@ -291,10 +290,10 @@ namespace Benchmarks.MultiSelectors public class Sector { - public List Multis { get; set; } = new List(); + public List Multis { get; set; } = new(); } - public struct MultiWhereHyper : NetFabric.Hyperlinq.IFunction + public struct MultiWhereHyper : IFunction { private readonly Rectangle2D bounds; diff --git a/Projects/Benchmarks/Benchmarks/Map/MapMultiTilesSelectors.cs b/Projects/Benchmarks/Benchmarks/Map/MapMultiTilesSelectors.cs index 553016f93..8f77aee25 100644 --- a/Projects/Benchmarks/Benchmarks/Map/MapMultiTilesSelectors.cs +++ b/Projects/Benchmarks/Benchmarks/Map/MapMultiTilesSelectors.cs @@ -1,8 +1,6 @@ using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Jobs; -using NetFabric.Hyperlinq; using Server; -using StructLinq; using System; using System.Collections.Generic; using System.Linq; @@ -14,7 +12,7 @@ namespace Benchmarks.MultiTilesSelectors public class MapMultiTilesSelectors { private static readonly Sector sector = new(); - private static readonly Point3D[] locations = new[] { new Point3D(0, 0, 0), new Point3D(50, 50, 0) }; + private static readonly Point3D[] locations = { new Point3D(0, 0, 0), new Point3D(50, 50, 0) }; public static Rectangle2D[] BoundsArray() => new[] { @@ -55,7 +53,7 @@ namespace Benchmarks.MultiTilesSelectors return toRet; } - + [Benchmark(Baseline = true)] public int SelectMultiTilesLinq() { @@ -347,6 +345,6 @@ namespace Benchmarks.MultiTilesSelectors public class Sector { - public List Multis { get; set; } = new List(); + public List Multis { get; set; } = new(); } } diff --git a/Projects/Server.Tests/Server.Tests.csproj b/Projects/Server.Tests/Server.Tests.csproj index 8c727c281..b310c4f69 100644 --- a/Projects/Server.Tests/Server.Tests.csproj +++ b/Projects/Server.Tests/Server.Tests.csproj @@ -3,8 +3,8 @@ false - - + + diff --git a/Projects/Server.Tests/Tests/Collections/PooledRefQueueTests.cs b/Projects/Server.Tests/Tests/Collections/PooledRefQueueTests.cs new file mode 100644 index 000000000..a9d3576b0 --- /dev/null +++ b/Projects/Server.Tests/Tests/Collections/PooledRefQueueTests.cs @@ -0,0 +1,102 @@ +using System; +using Moq; +using Server.Collections; +using Server.Random; +using Xunit; + +namespace Server.Tests; + +public sealed class PooledRefQueueTests : IDisposable +{ + public void Dispose() => RandomSources.SetRng(null); + + private static void PrepareRng(int queueCount, int rngValue) + { + Mock mockRng = new Mock(); + mockRng + .Setup(rng => rng.Next(It.IsAny())) + .Returns( + (int size) => + { + Assert.Equal(queueCount, size); + return rngValue; + } + ); + + RandomSources.SetRng(mockRng.Object); + } + + [Fact] + public void TestPeekRandom1() + { + // Random value for _head = 0, _tail = 5, _size = 5, + using var queue = PooledRefQueue.Create(10); + queue.Enqueue(0); + queue.Enqueue(1); + queue.Enqueue(2); + queue.Enqueue(3); // <----- + queue.Enqueue(4); + queue.Enqueue(5); + + PrepareRng(6, 3); + Assert.Equal(3, queue.PeekRandom()); + } + + [Fact] + public void TestPeekRandom2() + { + // Random value for _head = 3, _tail = 10, _size = 7, + using var queue = PooledRefQueue.Create(10); + queue.Enqueue(0); + queue.Enqueue(1); + queue.Enqueue(2); + + queue.Enqueue(3); + queue.Enqueue(4); + queue.Enqueue(5); + queue.Enqueue(6); // <--- + queue.Enqueue(7); + queue.Enqueue(8); + queue.Enqueue(9); + + queue.Dequeue(); + queue.Dequeue(); + queue.Dequeue(); + + PrepareRng(7, 3); + Assert.Equal(6, queue.PeekRandom()); + } + + [Theory] + [InlineData(3, 6)] + [InlineData(8, 11)] + [InlineData(6, 9)] + [InlineData(7, 10)] + public void TestPeekRandom3(int rngValue, int expectedIndex) + { + // Random value for _head = 3, _tail = 2, _size = 10, + using var queue = PooledRefQueue.Create(10); + queue.Enqueue(0); + queue.Enqueue(1); + queue.Enqueue(2); + + queue.Enqueue(3); + queue.Enqueue(4); + queue.Enqueue(5); + queue.Enqueue(6); + queue.Enqueue(7); + queue.Enqueue(8); + queue.Enqueue(9); + + queue.Dequeue(); + queue.Dequeue(); + queue.Dequeue(); + + queue.Enqueue(10); + queue.Enqueue(11); + queue.Enqueue(12); + + PrepareRng(10, rngValue); + Assert.Equal(expectedIndex, queue.PeekRandom()); + } +} diff --git a/Projects/Server/Collections/PooledRefQueue.cs b/Projects/Server/Collections/PooledRefQueue.cs index 577e7f6f4..9c8ea81b0 100644 --- a/Projects/Server/Collections/PooledRefQueue.cs +++ b/Projects/Server/Collections/PooledRefQueue.cs @@ -180,6 +180,22 @@ namespace Server.Collections return _array[_head]; } + public T PeekRandom() + { + if (_size == 0) + { + ThrowForEmptyQueue(); + } + + var index = _head + Utility.Random(_size); + if (index >= _array.Length) + { + index -= _array.Length; + } + + return _array[index]; + } + public bool TryPeek([MaybeNullWhen(false)] out T result) { if (_size == 0) diff --git a/Projects/Server/Random/RandomSources.cs b/Projects/Server/Random/RandomSources.cs index d99add499..49f8a6188 100644 --- a/Projects/Server/Random/RandomSources.cs +++ b/Projects/Server/Random/RandomSources.cs @@ -17,10 +17,14 @@ namespace Server.Random { public static class RandomSources { - private static IRandomSource m_Source; - private static IRandomSource m_SecureSource; + private static IRandomSource _source; + private static IRandomSource _secureSource; - public static IRandomSource Source => m_Source ??= new Xoshiro256PlusPlus(); - public static IRandomSource SecureSource => m_SecureSource ??= new SecureRandom(); + public static IRandomSource Source => _source ??= new Xoshiro256PlusPlus(); + public static IRandomSource SecureSource => _secureSource ??= new SecureRandom(); + + public static void SetRng(IRandomSource newSource) => _source = newSource; + + public static void SetSecureRng(IRandomSource newSource) => _secureSource = newSource; } } diff --git a/Projects/Server/Utilities/Utility.cs b/Projects/Server/Utilities/Utility.cs index 7d16d62b0..30f25b577 100644 --- a/Projects/Server/Utilities/Utility.cs +++ b/Projects/Server/Utilities/Utility.cs @@ -920,6 +920,7 @@ namespace Server return total + bonus; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Shuffle(this IList list) { var count = list.Count; @@ -930,6 +931,7 @@ namespace Server } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Shuffle(this Span list) { var count = list.Length; @@ -1094,6 +1096,15 @@ namespace Server [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double RandomDouble() => RandomSources.Source.NextDouble(); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Point3D RandomPointIn(Rectangle2D rect, Map map) + { + var x = Random(rect.X, rect.Width); + var y = Random(rect.Y, rect.Height); + + return new Point3D(x, y, map.GetAverageZ(x, y)); + } + /// /// Random pink, blue, green, orange, red or yellow hue /// diff --git a/Projects/UOContent.Tests/UOContent.Tests.csproj b/Projects/UOContent.Tests/UOContent.Tests.csproj index fc960bae1..38f0fc1bd 100644 --- a/Projects/UOContent.Tests/UOContent.Tests.csproj +++ b/Projects/UOContent.Tests/UOContent.Tests.csproj @@ -3,8 +3,8 @@ false - - + + diff --git a/Projects/UOContent/Engines/Quests/Study of the Solen Hive/NestArea.cs b/Projects/UOContent/Engines/Quests/Study of the Solen Hive/NestArea.cs index bc93f6289..2a14b34db 100644 --- a/Projects/UOContent/Engines/Quests/Study of the Solen Hive/NestArea.cs +++ b/Projects/UOContent/Engines/Quests/Study of the Solen Hive/NestArea.cs @@ -1,5 +1,3 @@ -using System.Linq; - namespace Server.Engines.Quests.Naturalist { public class NestArea @@ -38,7 +36,22 @@ namespace Server.Engines.Quests.Naturalist m_Rects = rects; } - public static int NonSpecialCount => m_Areas.Count(area => !area.Special); + public static int NonSpecialCount + { + get + { + int count = 0; + foreach (var area in m_Areas) + { + if (!area.Special) + { + count++; + } + } + + return count; + } + } public bool Special { get; } @@ -60,7 +73,15 @@ namespace Server.Engines.Quests.Naturalist public static NestArea Find(Point3D p) { - return m_Areas.FirstOrDefault(area => area.Contains(p)); + foreach (var area in m_Areas) + { + if (area.Contains(p)) + { + return area; + } + } + + return null; } public static NestArea GetByID(int id) diff --git a/Projects/UOContent/Engines/Treasures of Tokuno/TreasuresOfTokuno.cs b/Projects/UOContent/Engines/Treasures of Tokuno/TreasuresOfTokuno.cs index a4d2ede01..4e1ff18fb 100644 --- a/Projects/UOContent/Engines/Treasures of Tokuno/TreasuresOfTokuno.cs +++ b/Projects/UOContent/Engines/Treasures of Tokuno/TreasuresOfTokuno.cs @@ -151,7 +151,7 @@ namespace Server.Misc pm.ToTTotalMonsterFame += (int)(bc.Fame * (1 + Math.Sqrt(pm.Luck) / 100)); - // This is the Exponentional regression with only 2 datapoints. + // This is the Exponential regression with only 2 data points. // A log. func would also work, but it didn't make as much sense. // This function isn't OSI exact being that I don't know OSI's func they used ;p var x = pm.ToTTotalMonsterFame; @@ -269,10 +269,8 @@ namespace Server.Mobiles { if (pm.ToTItemsTurnedIn >= TreasuresOfTokuno.ItemsPerReward) { - SayTo( - pm, - 1070980 - ); // Congratulations! You have turned in enough minor treasures to earn a greater reward. + // Congratulations! You have turned in enough minor treasures to earn a greater reward. + SayTo(pm, 1070980); pm.CloseGump(); // Sanity @@ -285,18 +283,16 @@ namespace Server.Mobiles { if (pm.ToTItemsTurnedIn == 0) { - SayTo( - pm, - 1071013 - ); // Bring me 10 of the lost treasures of Tokuno and I will reward you with a valuable item. + // Bring me 10 of the lost treasures of Tokuno and I will reward you with a valuable item. + SayTo(pm, 1071013); } else { SayTo( pm, - 1070981, + 1070981, // You have turned in ~1_COUNT~ minor artifacts. Turn in ~2_NUM~ to receive a reward. $"{pm.ToTItemsTurnedIn}\t{TreasuresOfTokuno.ItemsPerReward}" - ); // You have turned in ~1_COUNT~ minor artifacts. Turn in ~2_NUM~ to receive a reward. + ); } var buttons = ToTTurnInGump.FindRedeemableItems(pm); @@ -342,34 +338,26 @@ namespace Server.Gumps { private readonly Mobile m_Collector; - public ToTTurnInGump(Mobile collector, List buttons) : base( - 1071012, - buttons.ToList() - ) // Click a minor artifact to give it to Ihara Soko. - => - m_Collector = collector; + // Click a minor artifact to give it to Ihara Soko. + public ToTTurnInGump(Mobile collector, List buttons) + : base(1071012, buttons) => m_Collector = collector; - public static List FindRedeemableItems(Mobile m) + public static List FindRedeemableItems(Mobile m) { var pack = m.Backpack; if (pack == null) { - return new List(); + return new List(); } - var buttons = new List(); + var buttons = new List(); var items = pack.FindItemsByType(TreasuresOfTokuno.LesserArtifactsTotal); for (var i = 0; i < items.Length; i++) { var item = items[i]; - if (item is ChestOfHeirlooms heirlooms && !heirlooms.Locked) - { - continue; - } - - if (item is ChestOfHeirlooms ofHeirlooms && ofHeirlooms.TrapLevel != 10) + if (item is ChestOfHeirlooms heirlooms && (!heirlooms.Locked || heirlooms.TrapLevel != 10)) { continue; } @@ -400,10 +388,8 @@ namespace Server.Gumps if (++pm.ToTItemsTurnedIn >= TreasuresOfTokuno.ItemsPerReward) { - m_Collector.SayTo( - pm, - 1070980 - ); // Congratulations! You have turned in enough minor treasures to earn a greater reward. + // Congratulations! You have turned in enough minor treasures to earn a greater reward. + m_Collector.SayTo(pm, 1070980); pm.CloseGump(); // Sanity @@ -416,9 +402,9 @@ namespace Server.Gumps { m_Collector.SayTo( pm, - 1070981, + 1070981, // You have turned in ~1_COUNT~ minor artifacts. Turn in ~2_NUM~ to receive a reward. $"{pm.ToTItemsTurnedIn}\t{TreasuresOfTokuno.ItemsPerReward}" - ); // You have turned in ~1_COUNT~ minor artifacts. Turn in ~2_NUM~ to receive a reward. + ); var buttons = FindRedeemableItems(pm); @@ -440,19 +426,17 @@ namespace Server.Gumps if (pm.ToTItemsTurnedIn == 0) { - m_Collector.SayTo( - pm, - 1071013 - ); // Bring me 10 of the lost treasures of Tokuno and I will reward you with a valuable item. + // Bring me 10 of the lost treasures of Tokuno and I will reward you with a valuable item. + m_Collector.SayTo(pm, 1071013); } - else if (pm.ToTItemsTurnedIn < TreasuresOfTokuno.ItemsPerReward - ) // This case should ALWAYS be true with this gump, jsut a sanity check + // This case should ALWAYS be true with this gump, just a sanity check + else if (pm.ToTItemsTurnedIn < TreasuresOfTokuno.ItemsPerReward) { m_Collector.SayTo( pm, - 1070981, + 1070981, // You have turned in ~1_COUNT~ minor artifacts. Turn in ~2_NUM~ to receive a reward. $"{pm.ToTItemsTurnedIn}\t{TreasuresOfTokuno.ItemsPerReward}" - ); // You have turned in ~1_COUNT~ minor artifacts. Turn in ~2_NUM~ to receive a reward. + ); } else { @@ -611,11 +595,9 @@ namespace Server.Gumps pm.ToTItemsTurnedIn -= TreasuresOfTokuno.ItemsPerReward; m_Collector.SayTo( pm, - 1070984, - item.Name == null || item.Name.Length <= 0 - ? $"#{item.LabelNumber}" - : item.Name - ); // You have earned the gratitude of the Empire. I have placed the ~1_OBJTYPE~ in your backpack. + 1070984, // You have earned the gratitude of the Empire. I have placed the ~1_OBJTYPE~ in your backpack. + item.Name?.Length > 0 ? item.Name : $"#{item.LabelNumber}" + ); } else { @@ -634,19 +616,17 @@ namespace Server.Gumps if (pm.ToTItemsTurnedIn == 0) { - m_Collector.SayTo( - pm, - 1071013 - ); // Bring me 10 of the lost treasures of Tokuno and I will reward you with a valuable item. + // Bring me 10 of the lost treasures of Tokuno and I will reward you with a valuable item. + m_Collector.SayTo(pm, 1071013); } - else if (pm.ToTItemsTurnedIn < TreasuresOfTokuno.ItemsPerReward - ) // This and above case should ALWAYS be FALSE with this gump, jsut a sanity check + // This and above case should ALWAYS be FALSE with this gump, jsut a sanity check + else if (pm.ToTItemsTurnedIn < TreasuresOfTokuno.ItemsPerReward) { m_Collector.SayTo( pm, - 1070981, + 1070981, // You have turned in ~1_COUNT~ minor artifacts. Turn in ~2_NUM~ to receive a reward. $"{pm.ToTItemsTurnedIn}\t{TreasuresOfTokuno.ItemsPerReward}" - ); // You have turned in ~1_COUNT~ minor artifacts. Turn in ~2_NUM~ to receive a reward. + ); } else { diff --git a/Projects/UOContent/Gumps/BaseImageTileButtonsGump.cs b/Projects/UOContent/Gumps/BaseImageTileButtonsGump.cs index ad2dbcb5c..18602b84a 100644 --- a/Projects/UOContent/Gumps/BaseImageTileButtonsGump.cs +++ b/Projects/UOContent/Gumps/BaseImageTileButtonsGump.cs @@ -53,8 +53,8 @@ namespace Server.Gumps { } - public BaseImageTileButtonsGump(TextDefinition header, ImageTileButtonInfo[] buttons) : - base(10, 10) // Coords are 0, o on OSI, intentional difference + // Coords are 0, 0 on OSI, intentional difference + public BaseImageTileButtonsGump(TextDefinition header, ImageTileButtonInfo[] buttons) : base(10, 10) { Buttons = buttons; AddPage(0); diff --git a/Projects/UOContent/Holiday Stuff/Halloween/2009/Engines/PumpkinPatch.cs b/Projects/UOContent/Holiday Stuff/Halloween/2009/Engines/PumpkinPatch.cs index cf00181eb..93c797c3a 100644 --- a/Projects/UOContent/Holiday Stuff/Halloween/2009/Engines/PumpkinPatch.cs +++ b/Projects/UOContent/Holiday Stuff/Halloween/2009/Engines/PumpkinPatch.cs @@ -1,5 +1,4 @@ using System; -using System.Linq; using Server.Events.Halloween; using Server.Items; @@ -51,22 +50,23 @@ namespace Server.Engines.Events var rect = m_PumpkinFields[i]; var spawncount = rect.Height * rect.Width / 20; - var pumpkins = map.GetItemsInBounds(rect).OfType().Count(); + var eable = map.GetItemsInBounds(rect); + var pumpkins = 0; + foreach (var p in eable) + { + if (pumpkins++ >= spawncount) + { + break; + } + } + + eable.Free(); if (spawncount > pumpkins) { - new HalloweenPumpkin().MoveToWorld(RandomPointIn(rect, map), map); + new HalloweenPumpkin().MoveToWorld(Utility.RandomPointIn(rect, map), map); } } } - - private static Point3D RandomPointIn(Rectangle2D rect, Map map) - { - var x = Utility.Random(rect.X, rect.Width); - var y = Utility.Random(rect.Y, rect.Height); - var z = map.GetAverageZ(x, y); - - return new Point3D(x, y, z); - } } } diff --git a/Projects/UOContent/Holiday Stuff/Halloween/2012/Engines/PlayerZombies.cs b/Projects/UOContent/Holiday Stuff/Halloween/2012/Engines/PlayerZombies.cs index c24d2572f..20fd8e5ea 100644 --- a/Projects/UOContent/Holiday Stuff/Halloween/2012/Engines/PlayerZombies.cs +++ b/Projects/UOContent/Holiday Stuff/Halloween/2012/Engines/PlayerZombies.cs @@ -115,8 +115,7 @@ namespace Server.Engines.Events } var map = Utility.RandomBool() ? Map.Trammel : Map.Felucca; - - var home = GetRandomPointInRect(m_Cemetaries.RandomElement(), map); + var home = Utility.RandomPointIn(m_Cemetaries.RandomElement(), map); if (map.CanSpawnMobile(home)) { @@ -131,14 +130,6 @@ namespace Server.Engines.Events _deathQueue.Remove(player); } } - - private static Point3D GetRandomPointInRect(Rectangle2D rect, Map map) - { - var x = Utility.Random(rect.X, rect.Width); - var y = Utility.Random(rect.Y, rect.Height); - - return new Point3D(x, y, map.GetAverageZ(x, y)); - } } [Serializable(0, false)] diff --git a/Projects/UOContent/Items/Misc/Firebomb.cs b/Projects/UOContent/Items/Misc/Firebomb.cs index 60433972e..1c7f9a602 100644 --- a/Projects/UOContent/Items/Misc/Firebomb.cs +++ b/Projects/UOContent/Items/Misc/Firebomb.cs @@ -1,8 +1,9 @@ using System; using System.Collections.Generic; -using System.Linq; +using Server.Collections; using Server.Network; using Server.Spells; +using Server.Spells.Fourth; using Server.Targeting; namespace Server.Items @@ -10,6 +11,7 @@ namespace Server.Items public class Firebomb : Item { private Mobile m_LitBy; + private Point3D _thrownFromLocation; private int m_Ticks; private TimerExecutionToken _timerToken; private List m_Users; @@ -138,24 +140,34 @@ namespace Server.Items else if (RootParent == null) { var eable = Map.GetMobilesInRange(Location, 1); - var toDamage = eable.ToList(); - - eable.Free(); - - for (var i = 0; i < toDamage.Count; ++i) + using var targets = PooledRefQueue.Create(); + foreach (var m in eable) { - var victim = toDamage[i]; - - if (m_LitBy == null || SpellHelper.ValidIndirectTarget(m_LitBy, victim) && - m_LitBy.CanBeHarmful(victim, false)) + if (m_LitBy == null || SpellHelper.ValidIndirectTarget(m_LitBy, m) && + m_LitBy.CanBeHarmful(m, false)) { - m_LitBy?.DoHarmful(victim); - - AOS.Damage(victim, m_LitBy, Utility.Random(3) + 4, 0, 100, 0, 0, 0); + targets.Enqueue(m); } } + eable.Free(); - new FirebombField(m_LitBy, toDamage).MoveToWorld(Location, Map); + while (targets.Count > 0) + { + var victim = targets.Dequeue(); + m_LitBy?.DoHarmful(victim); + AOS.Damage(victim, m_LitBy, Utility.Random(3) + 4, 0, 100, 0, 0, 0); + } + + var loc = _thrownFromLocation; + var eastToWest = SpellHelper.GetEastToWest(loc, Location); + Effects.PlaySound(loc, Map, 0x20C); + var itemID = eastToWest ? 0x398C : 0x3996; + + for (var i = -2; i <= 2; ++i) + { + var targetLoc = new Point3D(eastToWest ? loc.X + i : loc.X, eastToWest ? loc.Y : loc.Y + i, loc.Z); + new FireFieldSpell.FireFieldItem(itemID, targetLoc, m_LitBy, Map, TimeSpan.FromSeconds(9), i); + } } _timerToken.Cancel(); @@ -178,12 +190,12 @@ namespace Server.Items } SpellHelper.GetSurfaceTop(ref p); - var loc = new Point3D(p); + _thrownFromLocation = new Point3D(p); var map = Map; from.RevealingAction(); - var to = p as IEntity ?? new Entity(Serial.Zero, loc, map); + var to = p as IEntity ?? new Entity(Serial.Zero, _thrownFromLocation, map); Effects.SendMovingEffect(from, to, ItemID, 7, 0, false, false, Hue); @@ -195,7 +207,7 @@ namespace Server.Items return; } - MoveToWorld(loc, map); + MoveToWorld(_thrownFromLocation, map); } ); Internalize(); @@ -203,9 +215,7 @@ namespace Server.Items private class ThrowTarget : Target { - public ThrowTarget(Firebomb bomb) - : base(12, true, TargetFlags.None) => - Bomb = bomb; + public ThrowTarget(Firebomb bomb) : base(12, true, TargetFlags.None) => Bomb = bomb; public Firebomb Bomb { get; } @@ -215,93 +225,4 @@ namespace Server.Items } } } - - public class FirebombField : Item - { - private readonly List m_Burning; - private readonly DateTime m_Expire; - private readonly Mobile m_LitBy; - private TimerExecutionToken _timerToken; - - public FirebombField(Mobile litBy, List toDamage) : base(0x376A) - { - Movable = false; - m_LitBy = litBy; - m_Expire = Core.Now + TimeSpan.FromSeconds(10); - m_Burning = toDamage; - Timer.StartTimer(TimeSpan.FromSeconds(1.0), TimeSpan.FromSeconds(1.0), OnFirebombFieldTimerTick, out _timerToken); - } - - public FirebombField(Serial serial) : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) - { - // Don't serialize these... - } - - public override void Deserialize(IGenericReader reader) - { - } - - public override bool OnMoveOver(Mobile m) - { - if (ItemID == 0x398C && m_LitBy == null || - SpellHelper.ValidIndirectTarget(m_LitBy, m) && m_LitBy.CanBeHarmful(m, false)) - { - m_LitBy?.DoHarmful(m); - - AOS.Damage(m, m_LitBy, 2, 0, 100, 0, 0, 0); - m.PlaySound(0x208); - - if (!m_Burning.Contains(m)) - { - m_Burning.Add(m); - } - } - - return true; - } - - private void OnFirebombFieldTimerTick() - { - if (Deleted) - { - _timerToken.Cancel(); - return; - } - - if (ItemID == 0x376A) - { - ItemID = 0x398C; - return; - } - - for (var i = 0; i < m_Burning.Count;) - { - var victim = m_Burning[i]; - - if (victim.Location == Location && victim.Map == Map && - (m_LitBy == null || SpellHelper.ValidIndirectTarget(m_LitBy, victim) && - m_LitBy.CanBeHarmful(victim, false))) - { - m_LitBy?.DoHarmful(victim); - - AOS.Damage(victim, m_LitBy, Utility.Random(3) + 4, 0, 100, 0, 0, 0); - ++i; - } - else - { - m_Burning.RemoveAt(i); - } - } - - if (Core.Now >= m_Expire) - { - _timerToken.Cancel(); - Delete(); - } - } - } } diff --git a/Projects/UOContent/Items/Skill Items/Camping/Campfire.cs b/Projects/UOContent/Items/Skill Items/Camping/Campfire.cs index 424199d15..54b4f0410 100644 --- a/Projects/UOContent/Items/Skill Items/Camping/Campfire.cs +++ b/Projects/UOContent/Items/Skill Items/Camping/Campfire.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; using Server.Mobiles; namespace Server.Items @@ -58,20 +57,26 @@ namespace Server.Items switch (value) { case CampfireStatus.Burning: - ItemID = 0xDE3; - Light = LightType.Circle300; - break; + { + ItemID = 0xDE3; + Light = LightType.Circle300; + break; + } case CampfireStatus.Extinguishing: - ItemID = 0xDE9; - Light = LightType.Circle150; - break; + { + ItemID = 0xDE9; + Light = LightType.Circle150; + break; + } default: - ItemID = 0xDEA; - Light = LightType.ArchedWindowEast; - ClearEntries(); - break; + { + ItemID = 0xDEA; + Light = LightType.ArchedWindowEast; + ClearEntries(); + break; + } } } } @@ -111,8 +116,10 @@ namespace Server.Items return; } - foreach (var entry in m_Entries.ToList()) + for (var i = m_Entries.Count - 1; i >= 0; i--) { + var entry = m_Entries[i]; + if (!entry.Valid || entry.Player.NetState == null) { RemoveEntry(entry); @@ -149,10 +156,13 @@ namespace Server.Items return; } - foreach (var entry in m_Entries.ToList()) + foreach (var entry in m_Entries) { - RemoveEntry(entry); + m_Table.Remove(entry.Player); } + + m_Entries.Clear(); + m_Entries.TrimExcess(); } public override void OnAfterDelete() diff --git a/Projects/UOContent/Items/Skill Items/Misc/FireHorn.cs b/Projects/UOContent/Items/Skill Items/Misc/FireHorn.cs index 6f35e8b82..edd2eeb4d 100644 --- a/Projects/UOContent/Items/Skill Items/Misc/FireHorn.cs +++ b/Projects/UOContent/Items/Skill Items/Misc/FireHorn.cs @@ -1,5 +1,5 @@ using System; -using System.Linq; +using Server.Collections; using Server.Network; using Server.Spells; using Server.Targeting; @@ -100,27 +100,23 @@ namespace Server.Items true ); - var eable = from.Map.GetMobilesInRange(new Point3D(loc), 2); - var playerVsPlayer = false; - var targets = eable.Where( - m => + var eable = from.Map.GetMobilesInRange(loc, 2); + + using var targets = PooledRefQueue.Create(); + foreach (var m in eable) + { + if (from != m && SpellHelper.ValidIndirectTarget(from, m) && from.CanBeHarmful(m, false) && + (!Core.AOS || from.InLOS(m))) + { + targets.Enqueue(m); + + if (m.Player) { - if (from == m || !SpellHelper.ValidIndirectTarget(from, m) || !from.CanBeHarmful(m, false) - || Core.AOS && !from.InLOS(m)) - { - return false; - } - - if (m.Player) - { - playerVsPlayer = true; - } - - return true; + playerVsPlayer = true; } - ) - .ToList(); + } + } eable.Free(); @@ -178,9 +174,9 @@ namespace Server.Items damage /= targets.Count; } - for (var i = 0; i < targets.Count; ++i) + while (targets.Count > 0) { - var m = targets[i]; + var m = targets.Dequeue(); var toDeal = damage; diff --git a/Projects/UOContent/Items/Weapons/Abilities/WhirlwindAttack.cs b/Projects/UOContent/Items/Weapons/Abilities/WhirlwindAttack.cs index 32496a2a7..4b0004bac 100644 --- a/Projects/UOContent/Items/Weapons/Abilities/WhirlwindAttack.cs +++ b/Projects/UOContent/Items/Weapons/Abilities/WhirlwindAttack.cs @@ -1,5 +1,5 @@ using System; -using System.Linq; +using Server.Collections; using Server.Spells; namespace Server.Items @@ -36,23 +36,30 @@ namespace Server.Items attacker.FixedEffect(0x3728, 10, 15); attacker.PlaySound(0x2A1); - var targets = attacker.GetMobilesInRange(1) - .Where( - m => - m?.Deleted == false && m != defender && m != attacker && - SpellHelper.ValidIndirectTarget(attacker, m) && - m.Map == attacker.Map && m.Alive && attacker.CanSee(m) && attacker.CanBeHarmful(m) && - attacker.InRange(m, weapon.MaxRange) && attacker.InLOS(m) - ) - .ToList(); + var eable = attacker.GetMobilesInRange(1); + using var queue = PooledRefQueue.Create(); - if (targets.Count <= 0) + foreach (var m in eable) + { + if (m?.Deleted == false && m != defender && m != attacker && + m.Map == attacker.Map && m.Alive && + SpellHelper.ValidIndirectTarget(attacker, m) && + attacker.CanSee(m) && attacker.CanBeHarmful(m) && + attacker.InRange(m, weapon.MaxRange) && attacker.InLOS(m)) + { + queue.Enqueue(m); + } + } + + eable.Free(); + + if (queue.Count <= 0) { return; } var bushido = attacker.Skills.Bushido.Value; - var damageBonus = 1.0 + Math.Pow(targets.Count * bushido / 60, 2) / 100; + var damageBonus = 1.0 + Math.Pow(queue.Count * bushido / 60, 2) / 100; if (damageBonus > 2.0) { @@ -61,10 +68,9 @@ namespace Server.Items attacker.RevealingAction(); - for (var i = 0; i < targets.Count; ++i) + while (queue.Count > 0) { - var m = targets[i]; - + var m = queue.Dequeue(); attacker.SendLocalizedMessage(1060161); // The whirling attack strikes a target! m.SendLocalizedMessage(1060162); // You are struck by the whirling attack and take damage! diff --git a/Projects/UOContent/Mobiles/Familiars/HordeMinion.cs b/Projects/UOContent/Mobiles/Familiars/HordeMinion.cs index e1be900ac..96bb1a49d 100644 --- a/Projects/UOContent/Mobiles/Familiars/HordeMinion.cs +++ b/Projects/UOContent/Mobiles/Familiars/HordeMinion.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using System.Linq; +using Server.Collections; using Server.ContextMenus; using Server.Gumps; using Server.Items; @@ -76,12 +76,24 @@ namespace Server.Mobiles return; } - var eable = GetItemsInRange(2).Where(item => item.Movable && item.Stackable); - - var pickedUp = 0; - + var eable = GetItemsInRange(2); + using var queue = PooledRefQueue.Create(); foreach (var item in eable) { + if (item.Movable && item.Stackable) + { + queue.Enqueue(item); + } + } + + eable.Free(); + + var pickedUp = 3; + + while (pickedUp > 0 && queue.Count > 0) + { + var item = queue.Dequeue(); + if (!pack.CheckHold(this, item, false, true)) { return; @@ -97,11 +109,7 @@ namespace Server.Mobiles } Drop(this, Point3D.Zero); - - if (++pickedUp == 3) - { - break; - } + pickedUp--; } } diff --git a/Projects/UOContent/Mobiles/Familiars/ShadowWisp.cs b/Projects/UOContent/Mobiles/Familiars/ShadowWisp.cs index 6ad276cc2..786c2d12b 100644 --- a/Projects/UOContent/Mobiles/Familiars/ShadowWisp.cs +++ b/Projects/UOContent/Mobiles/Familiars/ShadowWisp.cs @@ -1,5 +1,5 @@ using System; -using System.Linq; +using Server.Collections; namespace Server.Mobiles { @@ -70,16 +70,20 @@ namespace Server.Mobiles return; } - var list = GetMobilesInRange(5) - .Where( - m => - m.Player && m.Alive && !m.IsDeadBondedPet && m.Karma <= 0 && m.AccessLevel < AccessLevel.Counselor - ) - .ToList(); - - for (var i = 0; i < list.Count; ++i) + var eable = GetMobilesInRange(5); + using var queue = PooledRefQueue.Create(); + foreach (var m in eable) { - var m = list[i]; + if (m.Player && m.Alive && !m.IsDeadBondedPet && m.Karma <= 0 && m.AccessLevel < AccessLevel.Counselor) + { + queue.Enqueue(m); + } + } + eable.Free(); + + while (queue.Count > 0) + { + var m = queue.Dequeue(); var friendly = true; for (var j = 0; friendly && j < caster.Aggressors.Count; ++j) diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/OrcBrute.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/OrcBrute.cs index 34c4c410a..69deb37ae 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/OrcBrute.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/OrcBrute.cs @@ -1,4 +1,3 @@ -using System.Linq; using Server.Items; namespace Server.Mobiles @@ -120,8 +119,16 @@ namespace Server.Mobiles } var eable = GetMobilesInRange(10); + var count = 0; + foreach (var m in eable) + { + if (++count == 10) + { + break; + } + } - if (eable.Count() < 10) + if (count < 10) { BaseCreature orc = new SpawnedOrcishLord { Team = Team }; diff --git a/Projects/UOContent/Mobiles/Monsters/LBR/Meers/MeerEternal.cs b/Projects/UOContent/Mobiles/Monsters/LBR/Meers/MeerEternal.cs index d7f064620..4b78c5108 100644 --- a/Projects/UOContent/Mobiles/Monsters/LBR/Meers/MeerEternal.cs +++ b/Projects/UOContent/Mobiles/Monsters/LBR/Meers/MeerEternal.cs @@ -1,5 +1,5 @@ using System; -using System.Linq; +using Server.Collections; namespace Server.Mobiles { @@ -84,45 +84,43 @@ namespace Server.Mobiles private void DoAreaLeech_Finish() { var eable = GetMobilesInRange(6); - var list = eable.Where(m => CanBeHarmful(m) && IsEnemy(m)).ToList(); + using var queue = PooledRefQueue.Create(); + foreach (var m in eable) + { + if (CanBeHarmful(m) && IsEnemy(m)) + { + queue.Enqueue(m); + } + } eable.Free(); - if (list.Count == 0) + if (queue.Count == 0) { Say(true, "Bah! You have escaped my grasp this time, mortal!"); + return; } - else + + double scalar = queue.Count switch { - double scalar; + 1 => 0.75, + 2 => 0.50, + _ => 0.25 + }; - if (list.Count == 1) - { - scalar = 0.75; - } - else if (list.Count == 2) - { - scalar = 0.50; - } - else - { - scalar = 0.25; - } + while (queue.Count > 0) + { + var m = queue.Dequeue(); - for (var i = 0; i < list.Count; ++i) - { - var m = list[i]; + var damage = (int)(m.Hits * scalar) + Utility.RandomMinMax(-5, 5); - var damage = (int)(m.Hits * scalar) + Utility.RandomMinMax(-5, 5); + m.MovingParticles(this, 0x36F4, 1, 0, false, false, 32, 0, 9535, 1, 0, (EffectLayer)255, 0x100); + m.MovingParticles(this, 0x0001, 1, 0, false, true, 32, 0, 9535, 9536, 0, (EffectLayer)255, 0); - m.MovingParticles(this, 0x36F4, 1, 0, false, false, 32, 0, 9535, 1, 0, (EffectLayer)255, 0x100); - m.MovingParticles(this, 0x0001, 1, 0, false, true, 32, 0, 9535, 9536, 0, (EffectLayer)255, 0); - - DoHarmful(m); - Hits += AOS.Damage(m, this, Math.Max(damage, 1), 100, 0, 0, 0, 0); - } - - Say(true, "If I cannot cleanse thy soul, I will destroy it!"); + DoHarmful(m); + Hits += AOS.Damage(m, this, Math.Max(damage, 1), 100, 0, 0, 0, 0); } + + Say(true, "If I cannot cleanse thy soul, I will destroy it!"); } private void DoFocusedLeech(Mobile combatant, string message) @@ -172,20 +170,28 @@ namespace Server.Mobiles switch (ability) { case 0: - DoFocusedLeech(combatant, "Thine essence will fill my withering body with strength!"); - break; + { + DoFocusedLeech(combatant, "Thine essence will fill my withering body with strength!"); + break; + } case 1: - DoFocusedLeech( - combatant, - "I rebuke thee, worm, and cleanse thy vile spirit of its tainted blood!" - ); - break; + { + DoFocusedLeech( + combatant, + "I rebuke thee, worm, and cleanse thy vile spirit of its tainted blood!" + ); + break; + } case 2: - DoFocusedLeech(combatant, "I devour your life's essence to strengthen my resolve!"); - break; + { + DoFocusedLeech(combatant, "I devour your life's essence to strengthen my resolve!"); + break; + } case 3: - DoAreaLeech(); - break; + { + DoAreaLeech(); + break; + } // TODO: Resurrect ability } } diff --git a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/BladeSpirits.cs b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/BladeSpirits.cs index 0f88661c9..374ae412e 100644 --- a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/BladeSpirits.cs +++ b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/BladeSpirits.cs @@ -1,5 +1,6 @@ using System; -using System.Linq; +using System.Buffers; +using Server.Collections; namespace Server.Mobiles { @@ -72,17 +73,28 @@ namespace Server.Mobiles if (Core.SE && Summoned) { var eable = GetMobilesInRange(5); - var spiritsOrVortexes = eable - .Where(m => m is EnergyVortex or BladeSpirits && ((BaseCreature)m).Summoned) - .ToList(); - + using var queue = PooledRefQueue.Create(); + foreach (var m in eable) + { + if (m is EnergyVortex or BladeSpirits && ((BaseCreature)m).Summoned) + { + queue.Enqueue(m); + } + } eable.Free(); - while (spiritsOrVortexes.Count > 6) + var amount = queue.Count - 6; + if (amount > 0) { - var random = spiritsOrVortexes.RandomElement(); - Dispel(random); - spiritsOrVortexes.Remove(random); + var mobs = queue.ToPooledArray(); + mobs.Shuffle(); + + while (amount > 0) + { + Dispel(mobs[amount--]); + } + + ArrayPool.Shared.Return(mobs); } } diff --git a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/EnergyVortex.cs b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/EnergyVortex.cs index f081cedff..145b85b6d 100644 --- a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/EnergyVortex.cs +++ b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/EnergyVortex.cs @@ -1,5 +1,6 @@ using System; -using System.Linq; +using System.Buffers; +using Server.Collections; namespace Server.Mobiles { @@ -78,17 +79,28 @@ namespace Server.Mobiles if (Core.SE && Summoned) { var eable = GetMobilesInRange(5); - var spiritsOrVortexes = eable - .Where(m => m is EnergyVortex or BladeSpirits && ((BaseCreature)m).Summoned) - .ToList(); - + using var queue = PooledRefQueue.Create(); + foreach (var m in eable) + { + if (m is EnergyVortex or BladeSpirits && ((BaseCreature)m).Summoned) + { + queue.Enqueue(m); + } + } eable.Free(); - while (spiritsOrVortexes.Count > 6) + var amount = queue.Count - 6; + if (amount > 0) { - var random = spiritsOrVortexes.RandomElement(); - Dispel(random); - spiritsOrVortexes.Remove(random); + var mobs = queue.ToPooledArray(); + mobs.Shuffle(); + + while (amount > 0) + { + Dispel(mobs[amount--]); + } + + ArrayPool.Shared.Return(mobs); } } diff --git a/Projects/UOContent/Mobiles/Special/Harrower.cs b/Projects/UOContent/Mobiles/Special/Harrower.cs index cd6ba03c9..ad0779270 100644 --- a/Projects/UOContent/Mobiles/Special/Harrower.cs +++ b/Projects/UOContent/Mobiles/Special/Harrower.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; using Server.Items; using Server.Spells; @@ -570,8 +569,17 @@ namespace Server.Mobiles return; } - var toTeleport = m_Owner.GetMobilesInRange(16) - .FirstOrDefault(mob => mob != m_Owner && mob.Player && m_Owner.CanBeHarmful(mob) && m_Owner.CanSee(mob)); + var eable = m_Owner.GetMobilesInRange(16); + Mobile toTeleport = null; + foreach (var m in eable) + { + if (m != m_Owner && m.Player && m_Owner.CanBeHarmful(m) && m_Owner.CanSee(m)) + { + toTeleport = m; + break; + } + } + eable.Free(); if (toTeleport == null) { @@ -602,33 +610,31 @@ namespace Server.Mobiles } } - var m = toTeleport; + var from = toTeleport.Location; - var from = m.Location; - - m.Location = to; + toTeleport.Location = to; SpellHelper.Turn(m_Owner, toTeleport); SpellHelper.Turn(toTeleport, m_Owner); - m.ProcessDelta(); + toTeleport.ProcessDelta(); Effects.SendLocationParticles( - EffectItem.Create(from, m.Map, EffectItem.DefaultDuration), + EffectItem.Create(from, toTeleport.Map, EffectItem.DefaultDuration), 0x3728, 10, 10, 2023 ); Effects.SendLocationParticles( - EffectItem.Create(to, m.Map, EffectItem.DefaultDuration), + EffectItem.Create(to, toTeleport.Map, EffectItem.DefaultDuration), 0x3728, 10, 10, 5023 ); - m.PlaySound(0x1FE); + toTeleport.PlaySound(0x1FE); m_Owner.Combatant = toTeleport; } diff --git a/Projects/UOContent/Multis/Houses/BaseHouse.cs b/Projects/UOContent/Multis/Houses/BaseHouse.cs index 66cef968e..272bba2cf 100644 --- a/Projects/UOContent/Multis/Houses/BaseHouse.cs +++ b/Projects/UOContent/Multis/Houses/BaseHouse.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; using Server.Accounting; +using Server.Collections; using Server.ContextMenus; using Server.Ethics; using Server.Guilds; @@ -3227,16 +3228,21 @@ namespace Server.Multis private void FixLockdowns_Sandbox() { - var conts = LockDowns?.Where(item => item is Container).ToList(); - - if (conts == null) + if (LockDowns?.Count > 0) { - return; - } + using var queue = PooledRefQueue.Create(); + foreach (var item in LockDowns) + { + if (item is Container) + { + queue.Enqueue(item); + } + } - foreach (var cont in conts) - { - SetLockdown(cont, true, true); + while (queue.Count > 0) + { + SetLockdown(queue.Dequeue(), true, true); + } } } diff --git a/Projects/UOContent/Skills/SpiritSpeak.cs b/Projects/UOContent/Skills/SpiritSpeak.cs index 69b40fcf8..4a2ac0ab0 100644 --- a/Projects/UOContent/Skills/SpiritSpeak.cs +++ b/Projects/UOContent/Skills/SpiritSpeak.cs @@ -1,5 +1,4 @@ using System; -using System.Linq; using Server.Items; using Server.Network; using Server.Spells; @@ -134,7 +133,15 @@ namespace Server.SkillHandlers public override void OnCast() { var eable = Caster.GetItemsInRange(3); - var toChannel = eable.FirstOrDefault(corpse => !corpse.Channeled); + Corpse toChannel = null; + foreach (var corpse in eable) + { + if (!corpse.Channeled) + { + toChannel = corpse; + break; + } + } eable.Free(); var min = 1 + (int)(Caster.Skills.SpiritSpeak.Value * 0.25); diff --git a/Projects/UOContent/Skills/Tracking/Tracking.cs b/Projects/UOContent/Skills/Tracking/Tracking.cs index 8e691702a..4cd3f52ad 100644 --- a/Projects/UOContent/Skills/Tracking/Tracking.cs +++ b/Projects/UOContent/Skills/Tracking/Tracking.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; using Server.Gumps; using Server.Mobiles; using Server.Network; @@ -210,13 +209,18 @@ namespace Server.SkillHandlers var range = 10 + (int)(from.Skills.Tracking.Value / 10); - var list = from.GetMobilesInRange(range) - .Where( - m => m != from && (!Core.AOS || m.Alive) && - (!m.Hidden || m.AccessLevel == AccessLevel.Player || from.AccessLevel > m.AccessLevel) && - check(m) && CheckDifficulty(from, m) - ) - .ToList(); + var eable = from.GetMobilesInRange(range); + var list = new List(); + foreach (var m in eable) + { + if (m != from && (!Core.AOS || m.Alive) && + (!m.Hidden || m.AccessLevel == AccessLevel.Player || from.AccessLevel > m.AccessLevel) && + check(m) && CheckDifficulty(from, m)) + { + list.Add(m); + } + } + eable.Free(); if (list.Count > 0) { diff --git a/Projects/UOContent/Spells/Base/SpellHelper.cs b/Projects/UOContent/Spells/Base/SpellHelper.cs index ea9ec4131..6cd1a8f5b 100644 --- a/Projects/UOContent/Spells/Base/SpellHelper.cs +++ b/Projects/UOContent/Spells/Base/SpellHelper.cs @@ -256,14 +256,14 @@ namespace Server.Spells return false; } - public static bool GetEastToWest(IPoint3D from,IPoint3D target) + public static bool GetEastToWest(Point3D from, Point3D target) { var dx = from.X - target.X; var dy = from.Y - target.Y; var rx = (dx - dy) * 44; var ry = (dx + dy) * 44; - return (rx >= 0 && ry < 0) || (ry >= 0 && rx < 0); + return rx >= 0 && ry < 0 || ry >= 0 && rx < 0; } public static bool CanRevealCaster(Mobile m) => m is BaseCreature { Controlled: false }; diff --git a/Projects/UOContent/Spells/Bushido/MomentumStrike.cs b/Projects/UOContent/Spells/Bushido/MomentumStrike.cs index 5513c5429..3fbe7b592 100644 --- a/Projects/UOContent/Spells/Bushido/MomentumStrike.cs +++ b/Projects/UOContent/Spells/Bushido/MomentumStrike.cs @@ -1,4 +1,5 @@ using System.Linq; +using Server.Collections; namespace Server.Spells.Bushido { @@ -21,12 +22,17 @@ namespace Server.Spells.Bushido var weapon = attacker.Weapon; - var targets = attacker.GetMobilesInRange(weapon.MaxRange) - .Where(m => m != defender) - .Where(m => m.Combatant == attacker) - .ToList(); + var eable = attacker.GetMobilesInRange(weapon.MaxRange); + using var queue = PooledRefQueue.Create(); + foreach (var m in eable) + { + if (m != defender && m.Combatant == attacker) + { + queue.Enqueue(m); + } + } - if (targets.Count <= 0) + if (queue.Count <= 0) { attacker.SendLocalizedMessage(1063123); // There are no valid targets to attack! return; @@ -37,7 +43,7 @@ namespace Server.Spells.Bushido return; } - var target = targets.RandomElement(); + Mobile target = queue.PeekRandom(); var damageBonus = attacker.Skills.Bushido.Value / 100.0; @@ -47,7 +53,7 @@ namespace Server.Spells.Bushido } attacker.SendLocalizedMessage(1063171); // You transfer the momentum of your weapon into another enemy! - target.SendLocalizedMessage(1063172); // You were hit by the momentum of a Samurai's weapon! + target!.SendLocalizedMessage(1063172); // You were hit by the momentum of a Samurai's weapon! target.FixedParticles(0x37B9, 1, 4, 0x251D, 0, 0, EffectLayer.Waist); diff --git a/Projects/UOContent/Spells/Chivalry/DispelEvil.cs b/Projects/UOContent/Spells/Chivalry/DispelEvil.cs index d70ef6859..b09d6a2dd 100644 --- a/Projects/UOContent/Spells/Chivalry/DispelEvil.cs +++ b/Projects/UOContent/Spells/Chivalry/DispelEvil.cs @@ -1,5 +1,5 @@ using System; -using System.Linq; +using Server.Collections; using Server.Items; using Server.Mobiles; using Server.Spells.Necromancy; @@ -46,11 +46,21 @@ namespace Server.Spells.Chivalry var chiv = Caster.Skills.Chivalry.Value; - var targets = Caster.GetMobilesInRange(8) - .Where(m => Caster != m && SpellHelper.ValidIndirectTarget(Caster, m) && Caster.CanBeHarmful(m, false)); - - foreach (var m in targets) + var eable = Caster.GetMobilesInRange(8); + using var queue = PooledRefQueue.Create(); + foreach (var m in eable) { + if (Caster != m && SpellHelper.ValidIndirectTarget(Caster, m) && Caster.CanBeHarmful(m, false)) + { + queue.Enqueue(m); + } + } + eable.Free(); + + while (queue.Count > 0) + { + var m = queue.Dequeue(); + if (m is BaseCreature bc) { if (bc.Summoned && !bc.IsAnimatedDead) diff --git a/Projects/UOContent/Spells/Eighth/Earthquake.cs b/Projects/UOContent/Spells/Eighth/Earthquake.cs index ffa480feb..f821a49fc 100644 --- a/Projects/UOContent/Spells/Eighth/Earthquake.cs +++ b/Projects/UOContent/Spells/Eighth/Earthquake.cs @@ -1,5 +1,5 @@ using System; -using System.Linq; +using Server.Collections; namespace Server.Spells.Eighth { @@ -37,14 +37,21 @@ namespace Server.Spells.Eighth return; } - var targets = Caster.GetMobilesInRange(1 + (int)(Caster.Skills.Magery.Value / 15.0)) - .Where( - m => Caster != m && SpellHelper.ValidIndirectTarget(Caster, m) && Caster.CanBeHarmful(m, false) && - (!Core.AOS || Caster.InLOS(m)) - ); - - foreach (var m in targets) + var eable = Caster.GetMobilesInRange(1 + (int)(Caster.Skills.Magery.Value / 15.0)); + using var queue = PooledRefQueue.Create(); + foreach (var m in eable) { + if (Caster != m && SpellHelper.ValidIndirectTarget(Caster, m) && Caster.CanBeHarmful(m, false) && + (!Core.AOS || Caster.InLOS(m))) + { + queue.Enqueue(m); + } + } + + while (queue.Count > 0) + { + var m = queue.Dequeue(); + int damage; if (Core.AOS) diff --git a/Projects/UOContent/Spells/Fifth/PoisonField.cs b/Projects/UOContent/Spells/Fifth/PoisonField.cs index 8a55f0d0b..80bada423 100644 --- a/Projects/UOContent/Spells/Fifth/PoisonField.cs +++ b/Projects/UOContent/Spells/Fifth/PoisonField.cs @@ -30,22 +30,21 @@ namespace Server.Spells.Fifth if (SpellHelper.CheckTown(p, Caster) && CheckSequence()) { SpellHelper.Turn(Caster, p); - SpellHelper.GetSurfaceTop(ref p); - var eastToWest = SpellHelper.GetEastToWest(Caster.Location, p); + var loc = new Point3D(p); + var eastToWest = SpellHelper.GetEastToWest(Caster.Location, loc); - Effects.PlaySound(new Point3D(p), Caster.Map, 0x20B); + Effects.PlaySound(loc, Caster.Map, 0x20B); var itemID = eastToWest ? 0x3915 : 0x3922; - var duration = TimeSpan.FromSeconds(3 + Caster.Skills.Magery.Fixed / 25); for (var i = -2; i <= 2; ++i) { - var loc = new Point3D(eastToWest ? p.X + i : p.X, eastToWest ? p.Y : p.Y + i, p.Z); + var targetLoc = new Point3D(eastToWest ? loc.X + i : loc.X, eastToWest ? loc.Y : loc.Y + i, loc.Z); - new InternalItem(itemID, loc, Caster, Caster.Map, duration, i); + new InternalItem(itemID, targetLoc, Caster, Caster.Map, duration, i); } } diff --git a/Projects/UOContent/Spells/Fourth/FireField.cs b/Projects/UOContent/Spells/Fourth/FireField.cs index c3979af90..91ca1b8bb 100644 --- a/Projects/UOContent/Spells/Fourth/FireField.cs +++ b/Projects/UOContent/Spells/Fourth/FireField.cs @@ -33,28 +33,23 @@ namespace Server.Spells.Fourth SpellHelper.GetSurfaceTop(ref p); - var eastToWest = SpellHelper.GetEastToWest(Caster.Location, p); + var loc = new Point3D(p); - Effects.PlaySound(new Point3D(p), Caster.Map, 0x20C); + var eastToWest = SpellHelper.GetEastToWest(Caster.Location, loc); + + Effects.PlaySound(loc, Caster.Map, 0x20C); var itemID = eastToWest ? 0x398C : 0x3996; - TimeSpan duration; - - if (Core.AOS) - { - duration = TimeSpan.FromSeconds((15 + Caster.Skills.Magery.Fixed / 5.0) / 4.0); - } - else - { - duration = TimeSpan.FromSeconds(4.0 + Caster.Skills.Magery.Value * 0.5); - } + var duration = Core.AOS + ? TimeSpan.FromSeconds((15 + Caster.Skills.Magery.Fixed / 5.0) / 4.0) + : TimeSpan.FromSeconds(4.0 + Caster.Skills.Magery.Value * 0.5); for (var i = -2; i <= 2; ++i) { - var loc = new Point3D(eastToWest ? p.X + i : p.X, eastToWest ? p.Y : p.Y + i, p.Z); + var targetLoc = new Point3D(eastToWest ? loc.X + i : loc.X, eastToWest ? loc.Y : loc.Y + i, loc.Z); - new FireFieldItem(itemID, loc, Caster, Caster.Map, duration, i); + new FireFieldItem(itemID, targetLoc, Caster, Caster.Map, duration, i); } } diff --git a/Projects/UOContent/Spells/Seventh/EnergyField.cs b/Projects/UOContent/Spells/Seventh/EnergyField.cs index bf5c5c019..5c5900a08 100644 --- a/Projects/UOContent/Spells/Seventh/EnergyField.cs +++ b/Projects/UOContent/Spells/Seventh/EnergyField.cs @@ -30,42 +30,35 @@ namespace Server.Spells.Seventh if (SpellHelper.CheckTown(p, Caster) && CheckSequence()) { SpellHelper.Turn(Caster, p); - SpellHelper.GetSurfaceTop(ref p); - var eastToWest = SpellHelper.GetEastToWest(Caster.Location, p); + var loc = new Point3D(p); - Effects.PlaySound(new Point3D(p), Caster.Map, 0x20B); + var eastToWest = SpellHelper.GetEastToWest(Caster.Location, loc); - TimeSpan duration; + Effects.PlaySound(loc, Caster.Map, 0x20B); - if (Core.AOS) - { - duration = TimeSpan.FromSeconds((15 + Caster.Skills.Magery.Fixed / 5) / 7.0); - } - else - { - // (28% of magery) + 2.0 seconds - duration = TimeSpan.FromSeconds(Caster.Skills.Magery.Value * 0.28 + 2.0); - } + TimeSpan duration = Core.AOS + ? TimeSpan.FromSeconds((15 + Caster.Skills.Magery.Fixed / 5) / 7.0) + : TimeSpan.FromSeconds(Caster.Skills.Magery.Value * 0.28 + 2.0); var itemID = eastToWest ? 0x3946 : 0x3956; for (var i = -2; i <= 2; ++i) { - var loc = new Point3D(eastToWest ? p.X + i : p.X, eastToWest ? p.Y : p.Y + i, p.Z); - var canFit = SpellHelper.AdjustField(ref loc, Caster.Map, 12, false); + var targetLoc = new Point3D(eastToWest ? loc.X + i : loc.X, eastToWest ? loc.Y : loc.Y + i, loc.Z); + var canFit = SpellHelper.AdjustField(ref targetLoc, Caster.Map, 12, false); if (!canFit) { continue; } - Item item = new InternalItem(loc, Caster.Map, duration, itemID, Caster); + Item item = new InternalItem(targetLoc, Caster.Map, duration, itemID, Caster); item.ProcessDelta(); Effects.SendLocationParticles( - EffectItem.Create(loc, Caster.Map, EffectItem.DefaultDuration), + EffectItem.Create(targetLoc, Caster.Map, EffectItem.DefaultDuration), 0x376A, 9, 10, diff --git a/Projects/UOContent/Spells/Sixth/ParalyzeField.cs b/Projects/UOContent/Spells/Sixth/ParalyzeField.cs index 8a018caba..0edd387b3 100644 --- a/Projects/UOContent/Spells/Sixth/ParalyzeField.cs +++ b/Projects/UOContent/Spells/Sixth/ParalyzeField.cs @@ -29,12 +29,12 @@ namespace Server.Spells.Sixth if (SpellHelper.CheckTown(p, Caster) && CheckSequence()) { SpellHelper.Turn(Caster, p); - SpellHelper.GetSurfaceTop(ref p); - var eastToWest = SpellHelper.GetEastToWest(Caster.Location, p); + var loc = new Point3D(p); + var eastToWest = SpellHelper.GetEastToWest(Caster.Location, loc); - Effects.PlaySound(new Point3D(p), Caster.Map, 0x20B); + Effects.PlaySound(loc, Caster.Map, 0x20B); var itemID = eastToWest ? 0x3967 : 0x3979; @@ -42,18 +42,18 @@ namespace Server.Spells.Sixth for (var i = -2; i <= 2; ++i) { - var loc = new Point3D(eastToWest ? p.X + i : p.X, eastToWest ? p.Y : p.Y + i, p.Z); + var targetLoc = new Point3D(eastToWest ? loc.X + i : loc.X, eastToWest ? loc.Y : loc.Y + i, loc.Z); - if (!SpellHelper.AdjustField(ref loc, Caster.Map, 12, false)) + if (!SpellHelper.AdjustField(ref targetLoc, Caster.Map, 12, false)) { continue; } - Item item = new InternalItem(Caster, itemID, loc, Caster.Map, duration); + Item item = new InternalItem(Caster, itemID, targetLoc, Caster.Map, duration); item.ProcessDelta(); Effects.SendLocationParticles( - EffectItem.Create(loc, Caster.Map, EffectItem.DefaultDuration), + EffectItem.Create(targetLoc, Caster.Map, EffectItem.DefaultDuration), 0x376A, 9, 10, diff --git a/Projects/UOContent/Spells/Third/WallOfStone.cs b/Projects/UOContent/Spells/Third/WallOfStone.cs index 98d239a07..094374a86 100644 --- a/Projects/UOContent/Spells/Third/WallOfStone.cs +++ b/Projects/UOContent/Spells/Third/WallOfStone.cs @@ -30,14 +30,16 @@ namespace Server.Spells.Third SpellHelper.GetSurfaceTop(ref p); - var eastToWest = SpellHelper.GetEastToWest(Caster.Location, p); + var loc = new Point3D(p); - Effects.PlaySound(new Point3D(p), Caster.Map, 0x1F6); + var eastToWest = SpellHelper.GetEastToWest(Caster.Location, loc); + + Effects.PlaySound(loc, Caster.Map, 0x1F6); for (var i = -1; i <= 1; ++i) { - var loc = new Point3D(eastToWest ? p.X + i : p.X, eastToWest ? p.Y : p.Y + i, p.Z); - var canFit = SpellHelper.AdjustField(ref loc, Caster.Map, 22, true); + var targetLoc = new Point3D(eastToWest ? p.X + i : p.X, eastToWest ? p.Y : p.Y + i, p.Z); + var canFit = SpellHelper.AdjustField(ref targetLoc, Caster.Map, 22, true); // Effects.SendLocationParticles( EffectItem.Create( loc, Caster.Map, EffectItem.DefaultDuration ), 0x376A, 9, 10, 5025 ); @@ -46,7 +48,7 @@ namespace Server.Spells.Third continue; } - Item item = new InternalItem(loc, Caster.Map, Caster); + Item item = new InternalItem(targetLoc, Caster.Map, Caster); Effects.SendLocationParticles(item, 0x376A, 9, 10, 5025); From 0925a2d435fbd793b9f681fbcd9ff9e1a3d4a46c Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 20 Mar 2022 23:15:59 -0700 Subject: [PATCH 106/213] fix: Cleans up Point checks and removes statics (#966) - [X] Removes static freezing/unfreezing. Use other tools for this. - [X] Cleans up IPoint3D allocations - [X] Removes IPoint3D constructors since the compiler may not optimize the constructor path and allow allocations. Note: Instead of `new Point3D(m)`, do something like `new Point3D(m.Location)`. Sorry for the inconvenience. In the long run this will prevent abuse of hot paths that will cause performance issues. --- Projects/Server/Geometry/Point2D.cs | 2 +- Projects/Server/Geometry/Point3D.cs | 8 +- Projects/Server/Maps/Map.cs | 14 +- Projects/Server/Regions/Region.cs | 4 +- .../UOContent/Commands/BoundingBoxPicker.cs | 14 +- .../Commands/Generic/Commands/Commands.cs | 16 +- .../Commands/Object Creation/AddGump.cs | 24 +- Projects/UOContent/Commands/Statics.cs | 780 ------------------ .../Items/Power Faction Items/StormsEye.cs | 4 +- Projects/UOContent/Gumps/AdminGump.cs | 10 - .../UOContent/Gumps/Props/SetPoint2DGump.cs | 9 +- .../UOContent/Items/Misc/InteriorDecorator.cs | 4 +- .../UOContent/Multis/Boats/BaseBoatDeed.cs | 2 +- .../UOContent/Multis/Boats/BaseDockedBoat.cs | 40 +- Projects/UOContent/Multis/Deeds.cs | 77 +- .../Multis/Houses/HousePlacementTool.cs | 64 +- .../Multis/Houses/HouseTeleporter.cs | 10 +- Projects/UOContent/Targets/MoveTarget.cs | 60 +- 18 files changed, 184 insertions(+), 958 deletions(-) delete mode 100644 Projects/UOContent/Commands/Statics.cs diff --git a/Projects/Server/Geometry/Point2D.cs b/Projects/Server/Geometry/Point2D.cs index 8e42236d3..0f1dba7d2 100644 --- a/Projects/Server/Geometry/Point2D.cs +++ b/Projects/Server/Geometry/Point2D.cs @@ -47,7 +47,7 @@ namespace Server m_Y = y; } - public Point2D(IPoint2D p) : this(p.X, p.Y) + public Point2D(Point2D p) : this(p.X, p.Y) { } diff --git a/Projects/Server/Geometry/Point3D.cs b/Projects/Server/Geometry/Point3D.cs index 80588ef6d..6a65b7c26 100644 --- a/Projects/Server/Geometry/Point3D.cs +++ b/Projects/Server/Geometry/Point3D.cs @@ -14,6 +14,7 @@ *************************************************************************/ using System; +using System.Runtime.CompilerServices; namespace Server { @@ -49,11 +50,16 @@ namespace Server set => m_Z = value; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public Point3D(IPoint3D p) : this(p.X, p.Y, p.Z) { } - public Point3D(IPoint2D p, int z) : this(p.X, p.Y, z) + public Point3D(Point3D p) : this(p.X, p.Y, p.Z) + { + } + + public Point3D(Point2D p, int z) : this(p.X, p.Y, z) { } diff --git a/Projects/Server/Maps/Map.cs b/Projects/Server/Maps/Map.cs index 7f5e87d1f..a6fcad289 100644 --- a/Projects/Server/Maps/Map.cs +++ b/Projects/Server/Maps/Map.cs @@ -4,6 +4,7 @@ using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; +using System.Runtime.CompilerServices; using Server.Items; using Server.Logging; using Server.Network; @@ -809,17 +810,22 @@ namespace Server return surface; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Bound(int x, int y, out int newX, out int newY) { newX = Math.Clamp(x, 0, Width - 1); newY = Math.Clamp(y, 0, Height - 1); } + public Point2D Bound(Point3D p) + { + Bound(p.m_X, p.m_Y, out var x, out var y); + return new Point2D(x, y); + } + public Point2D Bound(Point2D p) { - var x = Math.Clamp(p.m_X, 0, Width - 1); - var y = Math.Clamp(p.m_Y, 0, Height - 1); - + Bound(p.m_X, p.m_Y, out var x, out var y); return new Point2D(x, y); } @@ -1086,7 +1092,7 @@ namespace Server } else if (o is IPoint3D d) { - p = new Point3D(d); + p = new Point3D(d.X, d.Y, d.Z); } else { diff --git a/Projects/Server/Regions/Region.cs b/Projects/Server/Regions/Region.cs index f6a9a1ae5..01054532d 100644 --- a/Projects/Server/Regions/Region.cs +++ b/Projects/Server/Regions/Region.cs @@ -330,8 +330,8 @@ namespace Server { var rect = Area[i]; - var start = Map.Bound(new Point2D(rect.Start)); - var end = Map.Bound(new Point2D(rect.End)); + var start = Map.Bound(new Point2D(rect.Start.X, rect.Start.Y)); + var end = Map.Bound(new Point2D(rect.End.X, rect.Start.Y)); var startSector = Map.GetSector(start); var endSector = Map.GetSector(end); diff --git a/Projects/UOContent/Commands/BoundingBoxPicker.cs b/Projects/UOContent/Commands/BoundingBoxPicker.cs index fa6c1028b..4212c87fa 100644 --- a/Projects/UOContent/Commands/BoundingBoxPicker.cs +++ b/Projects/UOContent/Commands/BoundingBoxPicker.cs @@ -37,20 +37,22 @@ namespace Server protected override void OnTarget(Mobile from, object targeted) { - if (targeted is not IPoint3D p) + if (targeted is not IPoint3D ip) { return; } - if (p is Item item) + Point3D p = ip switch { - p = item.GetWorldTop(); - } + Item item => item.GetWorldTop(), + Mobile m => m.Location, + _ => new Point3D(ip) + }; if (m_First) { from.SendMessage("Target another location to complete the bounding box."); - from.Target = new PickTarget(new Point3D(p), false, from.Map, m_Callback); + from.Target = new PickTarget(p, false, from.Map, m_Callback); } else if (from.Map != m_Map) { @@ -59,7 +61,7 @@ namespace Server else if (m_Map != null && m_Map != Map.Internal && m_Callback != null) { var start = m_Store; - var end = new Point3D(p); + var end = p; Utility.FixPoints(ref start, ref end); diff --git a/Projects/UOContent/Commands/Generic/Commands/Commands.cs b/Projects/UOContent/Commands/Generic/Commands/Commands.cs index 944b267b1..6d8630976 100644 --- a/Projects/UOContent/Commands/Generic/Commands/Commands.cs +++ b/Projects/UOContent/Commands/Generic/Commands/Commands.cs @@ -554,21 +554,19 @@ namespace Server.Commands.Generic public override void Execute(CommandEventArgs e, object obj) { - if (obj is not IPoint3D p) + if (obj is not IPoint3D ip) { return; } - if (p is Item item) + Point3D p = ip switch { - p = item.GetWorldTop(); - } - else if (p is Mobile m) - { - p = m.Location; - } + Item item => item.GetWorldTop(), + Mobile m => m.Location, + _ => new Point3D(ip) + }; - Add.Invoke(e.Mobile, new Point3D(p), new Point3D(p), e.Arguments); + Add.Invoke(e.Mobile, p, p, e.Arguments); } } diff --git a/Projects/UOContent/Commands/Object Creation/AddGump.cs b/Projects/UOContent/Commands/Object Creation/AddGump.cs index bf7890052..2c093052f 100644 --- a/Projects/UOContent/Commands/Object Creation/AddGump.cs +++ b/Projects/UOContent/Commands/Object Creation/AddGump.cs @@ -282,19 +282,21 @@ namespace Server.Gumps protected override void OnTarget(Mobile from, object o) { - if (o is IPoint3D p) + if (o is not IPoint3D ip) { - p = p switch - { - Item item => item.GetWorldTop(), - Mobile m => m.Location, - _ => p - }; - - Commands.Add.Invoke(from, new Point3D(p), new Point3D(p), new[] { m_Type.Name }); - - from.Target = new InternalTarget(m_Type, m_SearchResults, m_SearchString, m_Page); + return; } + + Point3D p = ip switch + { + Item item => item.GetWorldTop(), + Mobile m => m.Location, + _ => new Point3D(ip) + }; + + Commands.Add.Invoke(from, new Point3D(p), new Point3D(p), new[] { m_Type.Name }); + + from.Target = new InternalTarget(m_Type, m_SearchResults, m_SearchString, m_Page); } protected override void OnTargetCancel(Mobile from, TargetCancelType cancelType) diff --git a/Projects/UOContent/Commands/Statics.cs b/Projects/UOContent/Commands/Statics.cs deleted file mode 100644 index 8a64c3021..000000000 --- a/Projects/UOContent/Commands/Statics.cs +++ /dev/null @@ -1,780 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using Server.Commands; -using Server.Gumps; -using Server.Items; - -namespace Server -{ - public static class Statics - { - public delegate void FreezeCallback(Mobile from, bool okay, StateInfo si); - - private const string BaseFreezeWarning = "{0} " + - "Those items will be removed from the world and placed into the server data files. " + - "Other players will not see the changes unless you distribute your data files to them.

" + - "This operation may not complete unless the server and client are using different data files. " + - "If you receive a message stating 'output data files could not be opened,' then you are probably sharing data files. " + - "Create a new directory for the world data files (statics*.mul and staidx*.mul) and add that to Scritps/Misc/DataPath.cs.

" + - "The change will be in effect immediately on the server, however, you must restart your client and update it's data files for the changes to become visible. " + - "It is strongly recommended that you make backup of the data files mentioned above. " + - "Do you wish to proceed?"; - - private const string BaseUnfreezeWarning = "{0} " + - "Those items will be removed from the static files and exchanged with unmovable dynamic items. " + - "Other players will not see the changes unless you distribute your data files to them.

" + - "This operation may not complete unless the server and client are using different data files. " + - "If you receive a message stating 'output data files could not be opened,' then you are probably sharing data files. " + - "Create a new directory for the world data files (statics*.mul and staidx*.mul) and add that to Scritps/Misc/DataPath.cs.

" + - "The change will be in effect immediately on the server, however, you must restart your client and update it's data files for the changes to become visible. " + - "It is strongly recommended that you make backup of the data files mentioned above. " + - "Do you wish to proceed?"; - - private static readonly Point3D NullP3D = new(int.MinValue, int.MinValue, int.MinValue); - - private static byte[] m_Buffer; - - private static StaticTile[] m_TileBuffer = new StaticTile[128]; - - public static void Initialize() - { - CommandSystem.Register("Freeze", AccessLevel.Administrator, Freeze_OnCommand); - CommandSystem.Register("FreezeMap", AccessLevel.Administrator, FreezeMap_OnCommand); - CommandSystem.Register("FreezeWorld", AccessLevel.Administrator, FreezeWorld_OnCommand); - - CommandSystem.Register("Unfreeze", AccessLevel.Administrator, Unfreeze_OnCommand); - CommandSystem.Register("UnfreezeMap", AccessLevel.Administrator, UnfreezeMap_OnCommand); - CommandSystem.Register("UnfreezeWorld", AccessLevel.Administrator, UnfreezeWorld_OnCommand); - } - - [Usage("Freeze")] - [Description("Makes a targeted area of dynamic items static.")] - public static void Freeze_OnCommand(CommandEventArgs e) - { - var from = e.Mobile; - BoundingBoxPicker.Begin(from, (map, start, end) => FreezeBox_Callback(from, map, start, end)); - } - - [Usage("FreezeMap")] - [Description("Makes every dynamic item in your map static.")] - public static void FreezeMap_OnCommand(CommandEventArgs e) - { - var from = e.Mobile; - var map = from.Map; - - if (map != null && map != Map.Internal) - { - SendWarning( - from, - "You are about to freeze all items in {0}.", - BaseFreezeWarning, - map, - NullP3D, - NullP3D, - FreezeWarning_Callback - ); - } - } - - [Usage("FreezeWorld")] - [Description("Makes every dynamic item on all maps static.")] - public static void FreezeWorld_OnCommand(CommandEventArgs e) - { - SendWarning( - e.Mobile, - "You are about to freeze every item on every map.", - BaseFreezeWarning, - null, - NullP3D, - NullP3D, - FreezeWarning_Callback - ); - } - - public static void SendWarning( - Mobile m, string header, string baseWarning, Map map, Point3D start, Point3D end, - FreezeCallback callback - ) - { - m.SendGump( - new WarningGump( - 1060635, - 30720, - string.Format(baseWarning, string.Format(header, map)), - 0xFFC000, - 420, - 400, - okay => callback(m, okay, new StateInfo(map, start, end)) - ) - ); - } - - private static void FreezeBox_Callback(Mobile from, Map map, Point3D start, Point3D end) - { - SendWarning( - from, - "You are about to freeze a section of items.", - BaseFreezeWarning, - map, - start, - end, - FreezeWarning_Callback - ); - } - - private static void FreezeWarning_Callback(Mobile from, bool okay, StateInfo si) - { - if (!okay) - { - return; - } - - Freeze(from, si.m_Map, si.m_Start, si.m_End); - } - - public static void Freeze(Mobile from, Map targetMap, Point3D start3d, Point3D end3d) - { - var mapTable = new Dictionary>(); - - if (start3d == NullP3D && end3d == NullP3D) - { - if (targetMap == null) - { - CommandLogging.WriteLine( - from, - "{0} {1} invoking freeze for every item in every map", - from.AccessLevel, - CommandLogging.Format(from) - ); - } - else - { - CommandLogging.WriteLine( - from, - "{0} {1} invoking freeze for every item in {0}", - from.AccessLevel, - CommandLogging.Format(from), - targetMap - ); - } - - foreach (var item in World.Items.Values) - { - if (targetMap != null && item.Map != targetMap) - { - continue; - } - - if (item.Parent != null) - { - continue; - } - - if (item is Static or BaseFloor or BaseWall) - { - var itemMap = item.Map; - - if (itemMap == null || itemMap == Map.Internal) - { - continue; - } - - if (!mapTable.TryGetValue(itemMap, out var table)) - { - mapTable[itemMap] = table = new Dictionary(); - } - - var p = new Point2D(item.X >> 3, item.Y >> 3); - - if (!table.TryGetValue(p, out var state)) - { - table[p] = state = new DeltaState(p); - } - - state.m_List.Add(item); - } - } - } - else if (targetMap != null) - { - Point2D start = targetMap.Bound(new Point2D(start3d)), end = targetMap.Bound(new Point2D(end3d)); - - CommandLogging.WriteLine( - from, - "{0} {1} invoking freeze from {2} to {3} in {4}", - from.AccessLevel, - CommandLogging.Format(from), - start, - end, - targetMap - ); - - var eable = - targetMap.GetItemsInBounds(new Rectangle2D(start.X, start.Y, end.X - start.X + 1, end.Y - start.Y + 1)); - - foreach (var item in eable) - { - if (item is Static or BaseFloor or BaseWall) - { - var itemMap = item.Map; - - if (itemMap == null || itemMap == Map.Internal) - { - continue; - } - - if (!mapTable.TryGetValue(itemMap, out var table)) - { - mapTable[itemMap] = table = new Dictionary(); - } - - var p = new Point2D(item.X >> 3, item.Y >> 3); - - if (!table.TryGetValue(p, out var state)) - { - table[p] = state = new DeltaState(p); - } - - state.m_List.Add(item); - } - } - - eable.Free(); - } - - if (mapTable.Count == 0) - { - from.SendGump( - new NoticeGump( - 1060637, - 30720, - "No freezable items were found. Only the following item types are frozen:
- Static
- BaseFloor
- BaseWall", - 0xFFC000, - 320, - 240 - ) - ); - return; - } - - var badDataFile = false; - - var totalFrozen = 0; - - foreach (var de in mapTable) - { - var map = de.Key; - var table = de.Value; - - var matrix = map.Tiles; - - using var idxStream = OpenWrite(matrix.IndexStream); - using var mulStream = OpenWrite(matrix.DataStream); - if (idxStream == null || mulStream == null) - { - badDataFile = true; - continue; - } - - var idxReader = new BinaryReader(idxStream); - - var idxWriter = new BinaryWriter(idxStream); - var mulWriter = new BinaryWriter(mulStream); - - foreach (var state in table.Values) - { - var oldTiles = ReadStaticBlock( - idxReader, - mulStream, - state.m_X, - state.m_Y, - matrix.BlockWidth, - matrix.BlockHeight, - out var oldTileCount - ); - - if (oldTileCount < 0) - { - continue; - } - - var newTileCount = 0; - var newTiles = new StaticTile[state.m_List.Count]; - - for (var i = 0; i < state.m_List.Count; ++i) - { - var item = state.m_List[i]; - - var xOffset = item.X - state.m_X * 8; - var yOffset = item.Y - state.m_Y * 8; - - if (xOffset is < 0 or >= 8 || yOffset is < 0 or >= 8) - { - continue; - } - - var newTile = new StaticTile( - (ushort)item.ItemID, - (byte)xOffset, - (byte)yOffset, - (sbyte)item.Z, - (short)item.Hue - ); - - newTiles[newTileCount++] = newTile; - - item.Delete(); - - ++totalFrozen; - } - - var mulPos = -1; - var length = -1; - var extra = 0; - - if (oldTileCount + newTileCount > 0) - { - mulWriter.Seek(0, SeekOrigin.End); - - mulPos = (int)mulWriter.BaseStream.Position; - length = (oldTileCount + newTileCount) * 7; - extra = 1; - - for (var i = 0; i < oldTileCount; ++i) - { - var toWrite = oldTiles[i]; - - mulWriter.Write((ushort)toWrite.ID); - mulWriter.Write((byte)toWrite.X); - mulWriter.Write((byte)toWrite.Y); - mulWriter.Write((sbyte)toWrite.Z); - mulWriter.Write((short)toWrite.Hue); - } - - for (var i = 0; i < newTileCount; ++i) - { - var toWrite = newTiles[i]; - - mulWriter.Write((ushort)toWrite.ID); - mulWriter.Write((byte)toWrite.X); - mulWriter.Write((byte)toWrite.Y); - mulWriter.Write((sbyte)toWrite.Z); - mulWriter.Write((short)toWrite.Hue); - } - - mulWriter.Flush(); - } - - var idxPos = (state.m_X * matrix.BlockHeight + state.m_Y) * 12; - - idxWriter.Seek(idxPos, SeekOrigin.Begin); - idxWriter.Write(mulPos); - idxWriter.Write(length); - idxWriter.Write(extra); - - idxWriter.Flush(); - - matrix.SetStaticBlock(state.m_X, state.m_Y, null); - } - } - - if (totalFrozen == 0 && badDataFile) - { - from.SendGump( - new NoticeGump( - 1060637, - 30720, - "Output data files could not be opened and the freeze operation has been aborted.

This probably means your server and client are using the same data files. Instructions on how to resolve this can be found in the first warning window.", - 0xFFC000, - 320, - 240 - ) - ); - } - else - { - from.SendGump( - new NoticeGump( - 1060637, - 30720, - $"Freeze operation completed successfully.

{totalFrozen} item{(totalFrozen != 1 ? "s were" : " was")} frozen.

You must restart your client and update it's data files to see the changes.", - 0xFFC000, - 320, - 240 - ) - ); - } - } - - [Usage("Unfreeze")] - [Description("Makes a targeted area of static items dynamic.")] - public static void Unfreeze_OnCommand(CommandEventArgs e) - { - var from = e.Mobile; - BoundingBoxPicker.Begin(from, (map, start, end) => UnfreezeBox_Callback(from, map, start, end)); - } - - [Usage("UnfreezeMap")] - [Description("Makes every static item in your map dynamic.")] - public static void UnfreezeMap_OnCommand(CommandEventArgs e) - { - var map = e.Mobile.Map; - - if (map != null && map != Map.Internal) - { - SendWarning( - e.Mobile, - "You are about to unfreeze all items in {0}.", - BaseUnfreezeWarning, - map, - NullP3D, - NullP3D, - UnfreezeWarning_Callback - ); - } - } - - [Usage("UnfreezeWorld")] - [Description("Makes every static item on all maps dynamic.")] - public static void UnfreezeWorld_OnCommand(CommandEventArgs e) - { - SendWarning( - e.Mobile, - "You are about to unfreeze every item on every map.", - BaseUnfreezeWarning, - null, - NullP3D, - NullP3D, - UnfreezeWarning_Callback - ); - } - - private static void UnfreezeBox_Callback(Mobile from, Map map, Point3D start, Point3D end) - { - SendWarning( - from, - "You are about to unfreeze a section of items.", - BaseUnfreezeWarning, - map, - start, - end, - UnfreezeWarning_Callback - ); - } - - private static void UnfreezeWarning_Callback(Mobile from, bool okay, StateInfo si) - { - if (!okay) - { - return; - } - - Unfreeze(from, si.m_Map, si.m_Start, si.m_End); - } - - private static void DoUnfreeze(Map map, Point2D start, Point2D end, ref bool badDataFile, ref int totalUnfrozen) - { - start = map.Bound(start); - end = map.Bound(end); - - var xStartBlock = start.X >> 3; - var yStartBlock = start.Y >> 3; - var xEndBlock = end.X >> 3; - var yEndBlock = end.Y >> 3; - - int xTileStart = start.X, yTileStart = start.Y; - int xTileWidth = end.X - start.X + 1, yTileHeight = end.Y - start.Y + 1; - - var matrix = map.Tiles; - - using var idxStream = OpenWrite(matrix.IndexStream); - using var mulStream = OpenWrite(matrix.DataStream); - if (idxStream == null || mulStream == null) - { - badDataFile = true; - return; - } - - var idxReader = new BinaryReader(idxStream); - - var idxWriter = new BinaryWriter(idxStream); - var mulWriter = new BinaryWriter(mulStream); - - for (var x = xStartBlock; x <= xEndBlock; ++x) - { - for (var y = yStartBlock; y <= yEndBlock; ++y) - { - var oldTiles = ReadStaticBlock( - idxReader, - mulStream, - x, - y, - matrix.BlockWidth, - matrix.BlockHeight, - out var oldTileCount - ); - - if (oldTileCount < 0) - { - continue; - } - - var newTileCount = 0; - var newTiles = new StaticTile[oldTileCount]; - - int baseX = (x << 3) - xTileStart, baseY = (y << 3) - yTileStart; - - for (var i = 0; i < oldTileCount; ++i) - { - var oldTile = oldTiles[i]; - - var px = baseX + oldTile.X; - var py = baseY + oldTile.Y; - - if (px < 0 || px >= xTileWidth || py < 0 || py >= yTileHeight) - { - newTiles[newTileCount++] = oldTile; - } - else - { - ++totalUnfrozen; - - Item item = new Static(oldTile.ID); - - item.Hue = oldTile.Hue; - - item.MoveToWorld(new Point3D(px + xTileStart, py + yTileStart, oldTile.Z), map); - } - } - - var mulPos = -1; - var length = -1; - var extra = 0; - - if (newTileCount > 0) - { - mulWriter.Seek(0, SeekOrigin.End); - - mulPos = (int)mulWriter.BaseStream.Position; - length = newTileCount * 7; - extra = 1; - - for (var i = 0; i < newTileCount; ++i) - { - var toWrite = newTiles[i]; - - mulWriter.Write((ushort)toWrite.ID); - mulWriter.Write((byte)toWrite.X); - mulWriter.Write((byte)toWrite.Y); - mulWriter.Write((sbyte)toWrite.Z); - mulWriter.Write((short)toWrite.Hue); - } - - mulWriter.Flush(); - } - - var idxPos = (x * matrix.BlockHeight + y) * 12; - - idxWriter.Seek(idxPos, SeekOrigin.Begin); - idxWriter.Write(mulPos); - idxWriter.Write(length); - idxWriter.Write(extra); - - idxWriter.Flush(); - - matrix.SetStaticBlock(x, y, null); - } - } - } - - public static void DoUnfreeze(Map map, ref bool badDataFile, ref int totalUnfrozen) - { - DoUnfreeze(map, Point2D.Zero, new Point2D(map.Width - 1, map.Height - 1), ref badDataFile, ref totalUnfrozen); - } - - public static void Unfreeze(Mobile from, Map map, Point3D start, Point3D end) - { - var totalUnfrozen = 0; - var badDataFile = false; - - if (map == null) - { - CommandLogging.WriteLine( - from, - "{0} {1} invoking unfreeze for every item in every map", - from.AccessLevel, - CommandLogging.Format(from) - ); - - DoUnfreeze(Map.Felucca, ref badDataFile, ref totalUnfrozen); - DoUnfreeze(Map.Trammel, ref badDataFile, ref totalUnfrozen); - DoUnfreeze(Map.Ilshenar, ref badDataFile, ref totalUnfrozen); - DoUnfreeze(Map.Malas, ref badDataFile, ref totalUnfrozen); - DoUnfreeze(Map.Tokuno, ref badDataFile, ref totalUnfrozen); - } - else if (start == NullP3D && end == NullP3D) - { - CommandLogging.WriteLine( - from, - "{0} {1} invoking unfreeze for every item in {2}", - from.AccessLevel, - CommandLogging.Format(from), - map - ); - - DoUnfreeze(map, ref badDataFile, ref totalUnfrozen); - } - else - { - CommandLogging.WriteLine( - from, - "{0} {1} invoking unfreeze from {2} to {3} in {4}", - from.AccessLevel, - CommandLogging.Format(from), - new Point2D(start), - new Point2D(end), - map - ); - - DoUnfreeze(map, new Point2D(start), new Point2D(end), ref badDataFile, ref totalUnfrozen); - } - - if (totalUnfrozen == 0 && badDataFile) - { - from.SendGump( - new NoticeGump( - 1060637, - 30720, - "Output data files could not be opened and the unfreeze operation has been aborted.

This probably means your server and client are using the same data files. Instructions on how to resolve this can be found in the first warning window.", - 0xFFC000, - 320, - 240 - ) - ); - } - else - { - from.SendGump( - new NoticeGump( - 1060637, - 30720, - $"Unfreeze operation completed successfully.

{totalUnfrozen} item{(totalUnfrozen != 1 ? "s were" : " was")} unfrozen.

You must restart your client and update it's data files to see the changes.", - 0xFFC000, - 320, - 240 - ) - ); - } - } - - private static FileStream OpenWrite(FileStream orig) - { - if (orig == null) - { - return null; - } - - try - { - return new FileStream(orig.Name, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite); - } - catch - { - return null; - } - } - - private static StaticTile[] ReadStaticBlock( - BinaryReader idxReader, FileStream mulStream, int x, int y, int width, - int height, out int count - ) - { - try - { - if (x < 0 || x >= width || y < 0 || y >= height) - { - count = -1; - return m_TileBuffer; - } - - idxReader.BaseStream.Seek((x * height + y) * 12, SeekOrigin.Begin); - - var lookup = idxReader.ReadInt32(); - var length = idxReader.ReadInt32(); - - if (lookup < 0 || length <= 0) - { - count = 0; - } - else - { - count = length / 7; - - mulStream.Seek(lookup, SeekOrigin.Begin); - - if (m_TileBuffer.Length < count) - { - m_TileBuffer = new StaticTile[count]; - } - - var staTiles = m_TileBuffer; - - if (m_Buffer == null || length > m_Buffer.Length) - { - m_Buffer = GC.AllocateUninitializedArray(length); - } - - mulStream.Read(m_Buffer, 0, length); - - var index = 0; - - for (var i = 0; i < count; ++i) - { - staTiles[i] - .Set( - (ushort)(m_Buffer[index++] | (m_Buffer[index++] << 8)), - m_Buffer[index++], - m_Buffer[index++], - (sbyte)m_Buffer[index++], - (short)(m_Buffer[index++] | (m_Buffer[index++] << 8)) - ); - } - } - } - catch - { - count = -1; - } - - return m_TileBuffer; - } - - private class DeltaState - { - public readonly List m_List; - public readonly int m_X; - public readonly int m_Y; - - public DeltaState(Point2D p) - { - m_X = p.X; - m_Y = p.Y; - m_List = new List(); - } - } - - public class StateInfo - { - public Map m_Map; - public Point3D m_Start, m_End; - - public StateInfo(Map map, Point3D start, Point3D end) - { - m_Map = map; - m_Start = start; - m_End = end; - } - } - } -} diff --git a/Projects/UOContent/Engines/Factions/Items/Power Faction Items/StormsEye.cs b/Projects/UOContent/Engines/Factions/Items/Power Faction Items/StormsEye.cs index 5d6d2729b..dcddde70e 100644 --- a/Projects/UOContent/Engines/Factions/Items/Power Faction Items/StormsEye.cs +++ b/Projects/UOContent/Engines/Factions/Items/Power Faction Items/StormsEye.cs @@ -95,7 +95,7 @@ namespace Server foreach (var m in eable) { if (from.CanBeHarmful(m, false) && - m.InLOS(new Point3D(origin, origin.Z + 1)) && + m.InLOS(new Point3D(origin.X, origin.Y, origin.Z + 1)) && Faction.Find(m) != null) { targets.Add(from); @@ -118,7 +118,7 @@ namespace Server } Effects.SendMovingEffect( - new Entity(Serial.Zero, new Point3D(origin, origin.Z + 4), facet), + new Entity(Serial.Zero, new Point3D(origin.X, origin.Y, origin.Z + 4), facet), mob, 14068, 1, diff --git a/Projects/UOContent/Gumps/AdminGump.cs b/Projects/UOContent/Gumps/AdminGump.cs index 7f1b1deb6..74dd03fbe 100644 --- a/Projects/UOContent/Gumps/AdminGump.cs +++ b/Projects/UOContent/Gumps/AdminGump.cs @@ -261,16 +261,6 @@ namespace Server.Gumps AddButtonLabeled(20, 225, GetButtonID(3, 104), "Doors"); AddButtonLabeled(220, 225, GetButtonID(3, 105), "Signs"); - AddHtml(20, 275, 400, 30, Color(Center("Statics"), LabelColor32)); - - AddButtonLabeled(20, 300, GetButtonID(3, 110), "Freeze (Target)"); - AddButtonLabeled(20, 325, GetButtonID(3, 111), "Freeze (World)"); - AddButtonLabeled(20, 350, GetButtonID(3, 112), "Freeze (Map)"); - - AddButtonLabeled(220, 300, GetButtonID(3, 120), "Unfreeze (Target)"); - AddButtonLabeled(220, 325, GetButtonID(3, 121), "Unfreeze (World)"); - AddButtonLabeled(220, 350, GetButtonID(3, 122), "Unfreeze (Map)"); - goto case AdminGumpPage.Administer; } case AdminGumpPage.Administer_Server: diff --git a/Projects/UOContent/Gumps/Props/SetPoint2DGump.cs b/Projects/UOContent/Gumps/Props/SetPoint2DGump.cs index 0e82aedf4..04de9076e 100644 --- a/Projects/UOContent/Gumps/Props/SetPoint2DGump.cs +++ b/Projects/UOContent/Gumps/Props/SetPoint2DGump.cs @@ -115,7 +115,7 @@ namespace Server.Gumps { case 1: // Current location { - toSet = new Point2D(m_Mobile.Location); + toSet = new Point2D(m_Mobile.Location.X, m_Mobile.Location.Y); shouldSet = true; shouldSend = true; @@ -194,12 +194,13 @@ namespace Server.Gumps protected override void OnTarget(Mobile from, object targeted) { - if (targeted is IPoint3D p) + if (targeted is IPoint3D point3D) { try { - CommandLogging.LogChangeProperty(m_Mobile, m_Object, m_Property.Name, new Point2D(p).ToString()); - m_Property.SetValue(m_Object, new Point2D(p), null); + var p = new Point2D(point3D.X, point3D.Y); + CommandLogging.LogChangeProperty(m_Mobile, m_Object, m_Property.Name, p.ToString()); + m_Property.SetValue(m_Object, p, null); m_PropertiesGump.OnValueChanged(m_Object, m_Property); } catch diff --git a/Projects/UOContent/Items/Misc/InteriorDecorator.cs b/Projects/UOContent/Items/Misc/InteriorDecorator.cs index 493816a5e..8e40f2f12 100644 --- a/Projects/UOContent/Items/Misc/InteriorDecorator.cs +++ b/Projects/UOContent/Items/Misc/InteriorDecorator.cs @@ -320,7 +320,7 @@ namespace Server.Items if (floorZ > int.MinValue && item.Z < floorZ + 15) // Confirmed : no height checks here { - item.Location = new Point3D(item.Location, item.Z + 1); + item.Location = new Point3D(item.Location.X, item.Location.Y, item.Z + 1); } else { @@ -334,7 +334,7 @@ namespace Server.Items if (floorZ > int.MinValue && item.Z > GetFloorZ(item)) { - item.Location = new Point3D(item.Location, item.Z - 1); + item.Location = new Point3D(item.Location.X, item.Location.Y, item.Z - 1); } else { diff --git a/Projects/UOContent/Multis/Boats/BaseBoatDeed.cs b/Projects/UOContent/Multis/Boats/BaseBoatDeed.cs index eabf02198..3c00b4b6e 100644 --- a/Projects/UOContent/Multis/Boats/BaseBoatDeed.cs +++ b/Projects/UOContent/Multis/Boats/BaseBoatDeed.cs @@ -176,7 +176,7 @@ namespace Server.Multis { if (ip is Item item) { - ip = item.GetWorldTop(); + ip = from; } var p = new Point3D(ip); diff --git a/Projects/UOContent/Multis/Boats/BaseDockedBoat.cs b/Projects/UOContent/Multis/Boats/BaseDockedBoat.cs index f4c681837..6a7a86d85 100644 --- a/Projects/UOContent/Multis/Boats/BaseDockedBoat.cs +++ b/Projects/UOContent/Multis/Boats/BaseDockedBoat.cs @@ -194,29 +194,31 @@ namespace Server.Multis protected override void OnTarget(Mobile from, object o) { - if (o is IPoint3D ip) + if (o is not IPoint3D ip) { - if (ip is Item item) - { - ip = item.GetWorldTop(); - } + return; + } - var p = new Point3D(ip); + Point3D p = ip switch + { + Item item => item.GetWorldTop(), + Mobile m => m.Location, + _ => new Point3D(ip) + }; - var region = Region.Find(p, from.Map); + var region = Region.Find(p, from.Map); - if (region.IsPartOf()) - { - from.SendLocalizedMessage(502488); // You can not place a ship inside a dungeon. - } - else if (region.IsPartOf() || region.IsPartOf()) - { - from.SendLocalizedMessage(1042549); // A boat may not be placed in this area. - } - else - { - m_Model.OnPlacement(from, p); - } + if (region.IsPartOf()) + { + from.SendLocalizedMessage(502488); // You can not place a ship inside a dungeon. + } + else if (region.IsPartOf() || region.IsPartOf()) + { + from.SendLocalizedMessage(1042549); // A boat may not be placed in this area. + } + else + { + m_Model.OnPlacement(from, p); } } } diff --git a/Projects/UOContent/Multis/Deeds.cs b/Projects/UOContent/Multis/Deeds.cs index 7b9f41356..b537cec5e 100644 --- a/Projects/UOContent/Multis/Deeds.cs +++ b/Projects/UOContent/Multis/Deeds.cs @@ -11,41 +11,41 @@ namespace Server.Multis.Deeds protected override void OnTarget(Mobile from, object o) { - if (o is IPoint3D ip) + if (o is not IPoint3D ip) { - if (ip is Item item) - { - ip = item.GetWorldTop(); - } + return; + } - var p = new Point3D(ip); + Point3D p = ip switch + { + Item item => item.GetWorldTop(), + Mobile m => m.Location, + _ => new Point3D(ip) + }; - var reg = Region.Find(new Point3D(p), from.Map); + var reg = Region.Find(p, from.Map); - if (from.AccessLevel >= AccessLevel.GameMaster || reg.AllowHousing(from, p)) - { - m_Deed.OnPlacement(from, p); - } - else if (reg.IsPartOf()) - { - from.SendLocalizedMessage( - 501270 - ); // Lord British has decreed a 'no build' period, thus you cannot build this house at this time. - } - else if (reg.IsPartOf() || reg.IsPartOf()) - { - from.SendLocalizedMessage( - 1043287 - ); // The house could not be created here. Either something is blocking the house, or the house would not be on valid terrain. - } - else if (reg.IsPartOf()) - { - from.SendLocalizedMessage(1150493); // You must have a deed for this plot of land in order to build here. - } - else - { - from.SendLocalizedMessage(501265); // Housing can not be created in this area. - } + if (from.AccessLevel >= AccessLevel.GameMaster || reg.AllowHousing(from, p)) + { + m_Deed.OnPlacement(from, p); + } + else if (reg.IsPartOf()) + { + // Lord British has decreed a 'no build' period, thus you cannot build this house at this time. + from.SendLocalizedMessage(501270); + } + else if (reg.IsPartOf() || reg.IsPartOf()) + { + // The house could not be created here. Either something is blocking the house, or the house would not be on valid terrain. + from.SendLocalizedMessage(1043287); + } + else if (reg.IsPartOf()) + { + from.SendLocalizedMessage(1150493); // You must have a deed for this plot of land in order to build here. + } + else + { + from.SendLocalizedMessage(501265); // Housing can not be created in this area. } } } @@ -184,9 +184,8 @@ namespace Server.Multis.Deeds case HousePlacementResult.BadStatic: case HousePlacementResult.BadRegionHidden: { - from.SendLocalizedMessage( - 1043287 - ); // The house could not be created here. Either something is blocking the house, or the house would not be on valid terrain. + // The house could not be created here. Either something is blocking the house, or the house would not be on valid terrain. + from.SendLocalizedMessage(1043287); break; } case HousePlacementResult.NoSurface: @@ -203,16 +202,14 @@ namespace Server.Multis.Deeds } case HousePlacementResult.BadRegionTemp: { - from.SendLocalizedMessage( - 501270 - ); // Lord British has decreed a 'no build' period, thus you cannot build this house at this time. + // Lord British has decreed a 'no build' period, thus you cannot build this house at this time. + from.SendLocalizedMessage(501270); break; } case HousePlacementResult.BadRegionRaffle: { - from.SendLocalizedMessage( - 1150493 - ); // You must have a deed for this plot of land in order to build here. + // You must have a deed for this plot of land in order to build here. + from.SendLocalizedMessage(1150493); break; } } diff --git a/Projects/UOContent/Multis/Houses/HousePlacementTool.cs b/Projects/UOContent/Multis/Houses/HousePlacementTool.cs index 19eafcb53..cc8d5aa31 100644 --- a/Projects/UOContent/Multis/Houses/HousePlacementTool.cs +++ b/Projects/UOContent/Multis/Houses/HousePlacementTool.cs @@ -250,46 +250,46 @@ namespace Server.Items protected override void OnTarget(Mobile from, object o) { + if (o is not IPoint3D ip) + { + return; + } + if (!from.CheckAlive() || from.Backpack?.FindItemByType() == null) { return; } - if (o is IPoint3D ip) + Point3D p = ip switch { - if (ip is Item item) - { - ip = item.GetWorldTop(); - } + Item item => item.GetWorldTop(), + Mobile m => m.Location, + _ => new Point3D(ip) + }; - var p = new Point3D(ip); + var reg = Region.Find(p, from.Map); - var reg = Region.Find(new Point3D(p), from.Map); - - if (from.AccessLevel >= AccessLevel.GameMaster || reg.AllowHousing(from, p)) - { - m_Placed = m_Entry.OnPlacement(from, p); - } - else if (reg.IsPartOf()) - { - from.SendLocalizedMessage( - 501270 - ); // Lord British has decreed a 'no build' period, thus you cannot build this house at this time. - } - else if (reg.IsPartOf() || reg.IsPartOf()) - { - from.SendLocalizedMessage( - 1043287 - ); // The house could not be created here. Either something is blocking the house, or the house would not be on valid terrain. - } - else if (reg.IsPartOf()) - { - from.SendLocalizedMessage(1150493); // You must have a deed for this plot of land in order to build here. - } - else - { - from.SendLocalizedMessage(501265); // Housing can not be created in this area. - } + if (from.AccessLevel >= AccessLevel.GameMaster || reg.AllowHousing(from, p)) + { + m_Placed = m_Entry.OnPlacement(from, p); + } + else if (reg.IsPartOf()) + { + // Lord British has decreed a 'no build' period, thus you cannot build this house at this time. + from.SendLocalizedMessage(501270); + } + else if (reg.IsPartOf() || reg.IsPartOf()) + { + // The house could not be created here. Either something is blocking the house, or the house would not be on valid terrain. + from.SendLocalizedMessage(1043287); + } + else if (reg.IsPartOf()) + { + from.SendLocalizedMessage(1150493); // You must have a deed for this plot of land in order to build here. + } + else + { + from.SendLocalizedMessage(501265); // Housing can not be created in this area. } } diff --git a/Projects/UOContent/Multis/Houses/HouseTeleporter.cs b/Projects/UOContent/Multis/Houses/HouseTeleporter.cs index e1ba1320d..5e7826120 100644 --- a/Projects/UOContent/Multis/Houses/HouseTeleporter.cs +++ b/Projects/UOContent/Multis/Houses/HouseTeleporter.cs @@ -155,9 +155,7 @@ namespace Server.Items return; } - var m = m_Mobile; - - if (m.Location != m_Teleporter.Location || m.Map != m_Teleporter.Map) + if (m_Mobile.Location != m_Teleporter.Location || m_Mobile.Map != m_Teleporter.Map) { return; } @@ -165,11 +163,11 @@ namespace Server.Items var p = target.GetWorldTop(); var map = target.Map; - BaseCreature.TeleportPets(m, p, map); + BaseCreature.TeleportPets(m_Mobile, p, map); - m.MoveToWorld(p, map); + m_Mobile.MoveToWorld(p, map); - if (m.Hidden && m.AccessLevel != AccessLevel.Player) + if (m_Mobile.Hidden && m_Mobile.AccessLevel != AccessLevel.Player) { return; } diff --git a/Projects/UOContent/Targets/MoveTarget.cs b/Projects/UOContent/Targets/MoveTarget.cs index 078fa5437..884f9367a 100644 --- a/Projects/UOContent/Targets/MoveTarget.cs +++ b/Projects/UOContent/Targets/MoveTarget.cs @@ -12,41 +12,45 @@ namespace Server.Targets protected override void OnTarget(Mobile from, object o) { - if (o is IPoint3D p) + if (o is not IPoint3D ip) { - if (!BaseCommand.IsAccessible(from, m_Object)) - { - from.SendLocalizedMessage(500447); // That is not accessible. - return; - } + return; + } - if (p is Item pItem) - { - p = pItem.GetWorldTop(); - } + if (!BaseCommand.IsAccessible(from, m_Object)) + { + from.SendLocalizedMessage(500447); // That is not accessible. + return; + } - CommandLogging.WriteLine( - from, - "{0} {1} moving {2} to {3}", - from.AccessLevel, - CommandLogging.Format(from), - CommandLogging.Format(m_Object), - new Point3D(p) - ); + Point3D p = ip switch + { + Item i => i.GetWorldTop(), + Mobile m => m.Location, + _ => new Point3D(ip) + }; - if (m_Object is Item item) + CommandLogging.WriteLine( + from, + "{0} {1} moving {2} to {3}", + from.AccessLevel, + CommandLogging.Format(from), + CommandLogging.Format(m_Object), + p + ); + + if (m_Object is Item item) + { + if (!item.Deleted) { - if (!item.Deleted) - { - item.MoveToWorld(new Point3D(p), from.Map); - } + item.MoveToWorld(p, from.Map); } - else if (m_Object is Mobile m) + } + else if (m_Object is Mobile m) + { + if (!m.Deleted) { - if (!m.Deleted) - { - m.MoveToWorld(new Point3D(p), from.Map); - } + m.MoveToWorld(p, from.Map); } } } From 76fddcbccd294642261c9d39000c91ea243b54a9 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Tue, 22 Mar 2022 09:58:24 -0700 Subject: [PATCH 107/213] feat: Adds a single threaded array pool (#967) ## Added Feature Adds a single threaded array pool that works exactly the same as `ArrayPool.Shared`. The `STArrayPool.Shared` can only be used on a single thread, the main game thread of the server. Note: Unlike the built-in array pool, there is no hook into the _GC Gen 2_. This means to relieve potentially high memory pressure, `ArrayPool.Shared.Trim()` must be called. The pool will only release arrays _after two successive calls within 10 seconds or longer_. If the server is at less than 70% total memory usage, or the server is not going to use this pool for something egregious, then don't bother ever calling Trim(). ## Changes - [X] Fixes ArrayPool calls that should be cleared due to references. - [X] Benchmarks against ArrayPool with 4+ rented arrays deep of the same length. - [x] Unit tests --- .../Collections/BenchmarkPooledRefQueue.cs | 95 +++++ .../Collections/BenchmarkSTArray.cs | 92 +++++ Projects/Benchmarks/Program.cs | 4 +- .../Tests/Buffers/STArrayPoolTests.cs | 71 ++++ Projects/Server/Collections/PooledRefQueue.cs | 24 +- Projects/Server/Collections/STArrayPool.cs | 324 ++++++++++++++++++ Projects/Server/Maps/Map.cs | 2 +- .../Monsters/Misc/Melee/BladeSpirits.cs | 2 +- .../Monsters/Misc/Melee/EnergyVortex.cs | 2 +- 9 files changed, 604 insertions(+), 12 deletions(-) create mode 100644 Projects/Benchmarks/Benchmarks/Collections/BenchmarkPooledRefQueue.cs create mode 100644 Projects/Benchmarks/Benchmarks/Collections/BenchmarkSTArray.cs create mode 100644 Projects/Server.Tests/Tests/Buffers/STArrayPoolTests.cs create mode 100644 Projects/Server/Collections/STArrayPool.cs diff --git a/Projects/Benchmarks/Benchmarks/Collections/BenchmarkPooledRefQueue.cs b/Projects/Benchmarks/Benchmarks/Collections/BenchmarkPooledRefQueue.cs new file mode 100644 index 000000000..f72dcd7af --- /dev/null +++ b/Projects/Benchmarks/Benchmarks/Collections/BenchmarkPooledRefQueue.cs @@ -0,0 +1,95 @@ +using System.Buffers; +using System.Collections.Generic; +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Jobs; +using Server.Buffers; +using Server.Collections; + +namespace Benchmarks +{ + [MemoryDiagnoser] + [SimpleJob(RuntimeMoniker.Net60)] + public class BenchmarkPooledRefQueue + { + [GlobalSetup] + public void Setup() + { + // Allocate + var arrays = new long[16][]; + for (var i = 0; i < 16; i++) + { + arrays[i] = ArrayPool.Shared.Rent(64); + } + + var stArrays = new long[16][]; + for (var i = 0; i < 16; i++) + { + stArrays[i] = STArrayPool.Shared.Rent(64); + } + + for (var i = 0; i < 16; i++) + { + ArrayPool.Shared.Return(arrays[i]); + } + + for (var i = 0; i < 16; i++) + { + STArrayPool.Shared.Return(stArrays[i]); + } + } + + [Benchmark] + public void UseQueue() + { + for (var i = 0; i < 8; i++) + { + var queue = new Queue(); + for (var j = 0; j < 32; j++) + { + queue.Enqueue(j); + } + + for (var j = 0; j < 32; j++) + { + var num = queue.Dequeue(); + } + } + } + + [Benchmark] + public void UsePooledRefQueue() + { + for (var i = 0; i < 8; i++) + { + using var queue = PooledRefQueue.Create(); + for (var j = 0; j < 32; j++) + { + queue.Enqueue(j); + } + + for (var j = 0; j < 32; j++) + { + var num = queue.Dequeue(); + } + } + } + + [Benchmark] + public void UsePooledRefQueueMT() + { + for (var i = 0; i < 8; i++) + { + using var queue = PooledRefQueue.CreateMT(); + for (var j = 0; j < 32; j++) + { + queue.Enqueue(j); + } + + for (var j = 0; j < 32; j++) + { + var num = queue.Dequeue(); + } + } + } + } +} diff --git a/Projects/Benchmarks/Benchmarks/Collections/BenchmarkSTArray.cs b/Projects/Benchmarks/Benchmarks/Collections/BenchmarkSTArray.cs new file mode 100644 index 000000000..78be46dd9 --- /dev/null +++ b/Projects/Benchmarks/Benchmarks/Collections/BenchmarkSTArray.cs @@ -0,0 +1,92 @@ +using System.Buffers; +using System.Collections.Generic; +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Jobs; +using Server.Buffers; + +namespace Benchmarks +{ + [MemoryDiagnoser] + [SimpleJob(RuntimeMoniker.Net60)] + public class BenchmarkSTArray + { + private static long[][] arrays = new long[16][]; + private static long[][] stArrays = new long[16][]; + private static long[][] newArrays = new long[16][]; + private static Queue[] newQueue = new Queue[16]; + + [GlobalSetup] + public void Setup() + { + // Allocate + arrays = new long[16][]; + for (var i = 0; i < 16; i++) + { + arrays[i] = ArrayPool.Shared.Rent(64); + } + + stArrays = new long[16][]; + for (var i = 0; i < 16; i++) + { + stArrays[i] = STArrayPool.Shared.Rent(64); + } + + for (var i = 0; i < 16; i++) + { + ArrayPool.Shared.Return(arrays[i]); + } + + for (var i = 0; i < 16; i++) + { + STArrayPool.Shared.Return(stArrays[i]); + } + } + + [Benchmark] + public void ArrayPool() + { + for (var i = 0; i < 8; i++) + { + arrays[i] = ArrayPool.Shared.Rent(64); + } + + for (var i = 0; i < 8; i++) + { + ArrayPool.Shared.Return(arrays[i], true); + } + } + + [Benchmark] + public void STArrayPool() + { + for (var i = 0; i < 8; i++) + { + arrays[i] = STArrayPool.Shared.Rent(64); + } + + for (var i = 0; i < 8; i++) + { + STArrayPool.Shared.Return(arrays[i], true); + } + } + + [Benchmark] + public void NewArray() + { + for (var i = 0; i < 8; i++) + { + newArrays[i] = new long[64]; + } + } + + [Benchmark] + public void NewQueue() + { + for (var i = 0; i < 8; i++) + { + newQueue[i] = new Queue(); + newQueue[i].EnsureCapacity(64); + } + } + } +} diff --git a/Projects/Benchmarks/Program.cs b/Projects/Benchmarks/Program.cs index e86c18d19..286664e06 100644 --- a/Projects/Benchmarks/Program.cs +++ b/Projects/Benchmarks/Program.cs @@ -26,7 +26,9 @@ namespace Benchmarks //var mapMobilesSelectors = BenchmarkRunner.Run(); //var mapMultiTilesSelectors = BenchmarkRunner.Run(); //var mapMultiSelectors = BenchmarkRunner.Run(); - var mapItemsSelectors = BenchmarkRunner.Run(); + // var mapItemsSelectors = BenchmarkRunner.Run(); + // var stArray = BenchmarkRunner.Run(); + var pooledRefQueue = BenchmarkRunner.Run(); } } } diff --git a/Projects/Server.Tests/Tests/Buffers/STArrayPoolTests.cs b/Projects/Server.Tests/Tests/Buffers/STArrayPoolTests.cs new file mode 100644 index 000000000..8b6ea0551 --- /dev/null +++ b/Projects/Server.Tests/Tests/Buffers/STArrayPoolTests.cs @@ -0,0 +1,71 @@ +using System; +using Server.Buffers; +using Xunit; + +namespace Server.Tests.Tests.Buffers; + +public class STArrayPoolTests +{ + [Theory] + [InlineData(0, 0)] + [InlineData(2, 16)] + [InlineData(56, 64)] + [InlineData(120, 128)] + [InlineData(65535, 65536)] + [InlineData(1024 * 1024 * 15, 1024 * 1024 * 16)] + public void ValidMinimumLengths(int requestedLength, int expectedLength) + { + var arr = STArrayPool.Shared.Rent(requestedLength); + Assert.Equal(expectedLength, arr.Length); + } + + [Fact] + public void NegativeLengthThrows() + { + Assert.Throws( + () => + { + var arr = STArrayPool.Shared.Rent(-1); + } + ); + } + + [Fact] + public void CachesOnlyUpToCPUCountPerBucket() + { + STArrayPool.Shared.ResetForTesting(); + + var cores = Environment.ProcessorCount; + var arrays1 = new byte[cores * 8 + 2][]; // 1 for the cache, and 8 * CPU for the stacks + var weakReferences1 = new WeakReference[cores * 8 + 2]; + + var arrays2 = new byte[cores * 8 + 2][]; // 1 for the cache, and 8 * CPU for the stacks + var weakReferences2 = new WeakReference[cores * 8 + 2]; + + for (var i = 0; i < arrays1.Length; i++) + { + arrays1[i] = STArrayPool.Shared.Rent(32); + weakReferences1[i] = new WeakReference(arrays1[i]); + + arrays2[i] = STArrayPool.Shared.Rent(64); + weakReferences2[i] = new WeakReference(arrays1[i]); + } + + for (var i = 0; i < arrays1.Length; i++) + { + STArrayPool.Shared.Return(arrays1[i]); + arrays1[i] = null; + + STArrayPool.Shared.Return(arrays2[i]); + arrays2[i] = null; + } + + GC.Collect(); + for (var i = 0; i < weakReferences1.Length; i++) + { + // When the last one is returned, the one right before it is dropped. + Assert.Equal(i != weakReferences1.Length - 2, weakReferences1[i].IsAlive); + Assert.Equal(i != weakReferences2.Length - 2, weakReferences2[i].IsAlive); + } + } +} diff --git a/Projects/Server/Collections/PooledRefQueue.cs b/Projects/Server/Collections/PooledRefQueue.cs index 9c8ea81b0..3959f0631 100644 --- a/Projects/Server/Collections/PooledRefQueue.cs +++ b/Projects/Server/Collections/PooledRefQueue.cs @@ -6,6 +6,7 @@ using System.Buffers; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; +using Server.Buffers; namespace Server.Collections { @@ -19,20 +20,25 @@ namespace Server.Collections private int _head; // The index from which to dequeue if the queue isn't empty. private int _tail; // The index at which to enqueue if the queue isn't full. private int _size; // Number of elements. + private bool _mt; private int _version; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static PooledRefQueue Create(int capacity = 32) => new(capacity); + public static PooledRefQueue Create(int capacity = 32, bool mt = false) => new(capacity, mt); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static PooledRefQueue CreateMT(int capacity = 32) => new(capacity, true); // Creates a queue with room for capacity objects. The default grow factor // is used. - public PooledRefQueue(int capacity) + public PooledRefQueue(int capacity, bool mt = false) { + _mt = mt; _array = capacity switch { < 0 => throw new ArgumentOutOfRangeException(nameof(capacity), capacity, CollectionThrowStrings.ArgumentOutOfRange_NeedNonNegNum), 0 => Array.Empty(), - _ => ArrayPool.Shared.Rent(capacity) + _ => (mt ? ArrayPool.Shared : STArrayPool.Shared).Rent(capacity) }; _head = 0; @@ -254,14 +260,14 @@ namespace Server.Collections return arr; } - public T[] ToPooledArray() + public T[] ToPooledArray(bool mt = false) { if (_size == 0) { return Array.Empty(); } - T[] arr = ArrayPool.Shared.Rent(_size); + T[] arr = (mt ? ArrayPool.Shared : STArrayPool.Shared).Rent(_size); if (_head < _tail) { @@ -280,7 +286,7 @@ namespace Server.Collections // must be >= _size. private void SetCapacity(int capacity) { - T[] newarray = ArrayPool.Shared.Rent(capacity); + T[] newarray = (_mt ? ArrayPool.Shared : STArrayPool.Shared).Rent(capacity); if (_size > 0) { if (_head < _tail) @@ -296,7 +302,8 @@ namespace Server.Collections if (_array.Length > 0) { - ArrayPool.Shared.Return(_array, true); + Clear(); + (_mt ? ArrayPool.Shared : STArrayPool.Shared).Return(_array); } _array = newarray; @@ -377,7 +384,8 @@ namespace Server.Collections var array = _array; if (array.Length > 0) { - ArrayPool.Shared.Return(array, true); + Clear(); + (_mt ? ArrayPool.Shared : STArrayPool.Shared).Return(array); } this = default; diff --git a/Projects/Server/Collections/STArrayPool.cs b/Projects/Server/Collections/STArrayPool.cs new file mode 100644 index 000000000..72ddca91b --- /dev/null +++ b/Projects/Server/Collections/STArrayPool.cs @@ -0,0 +1,324 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Buffers; +using System.Diagnostics; +using System.Numerics; +using System.Runtime.CompilerServices; + +namespace Server.Buffers; + +/** + * Adaptation of the ArrayPool.Shared (TlsOverPerCoreLockedStacksArrayPool) for single threaded *unsafe* usage. + */ +public class STArrayPool : ArrayPool +{ + private const int StackArraySize = 8; + private const int BucketCount = 27; // SelectBucketIndex(1024 * 1024 * 1024 + 1) + private static readonly STArrayPool _shared = new(); + + public static STArrayPool Shared => _shared; + + private static STArray[] _cacheBuckets; + private STArrayStack[] _buckets = new STArrayStack[BucketCount]; + + private STArrayPool() {} + + public override T[] Rent(int minimumLength) + { + T[] buffer; + + var bucketIndex = SelectBucketIndex(minimumLength); + var cachedBuckets = _cacheBuckets; + if (cachedBuckets is not null && (uint)bucketIndex < (uint)cachedBuckets.Length) + { + buffer = cachedBuckets[bucketIndex].Array; + if (buffer is not null) + { + cachedBuckets[bucketIndex].Array = null; + return buffer; + } + } + + var buckets = _buckets; + if ((uint)bucketIndex < (uint)buckets.Length) + { + var b = buckets[bucketIndex]; + if (b is not null) + { + buffer = b.TryPop(); + if (buffer is not null) + { + return buffer; + } + } + + minimumLength = GetMaxSizeForBucket(bucketIndex); + } + + if (minimumLength == 0) + { + // We aren't renting. + return Array.Empty(); + } + + if (minimumLength < 0) + { + throw new ArgumentOutOfRangeException(nameof(minimumLength)); + } + + buffer = GC.AllocateUninitializedArray(minimumLength); + return buffer; + } + + public override void Return(T[] array, bool clearArray = false) + { + if (array is null) + { + throw new ArgumentNullException(nameof(array)); + } + + var bucketIndex = SelectBucketIndex(array.Length); + var cacheBuckets = _cacheBuckets ?? InitializeBuckets(); + + if ((uint)bucketIndex < (uint)_cacheBuckets!.Length) + { + if (clearArray) + { + Array.Clear(array); + } + + if (array.Length != GetMaxSizeForBucket(bucketIndex)) + { + throw new ArgumentException("Buffer is not from the pool", nameof(array)); + } + + ref var bucketArray = ref cacheBuckets[bucketIndex]; + var prev = bucketArray.Array; + bucketArray = new STArray(array); + if (prev is not null) + { + var bucket = _buckets[bucketIndex] ?? CreateBucketStack(bucketIndex); + bucket.TryPush(prev); + } + } + } + + public void ResetForTesting() + { + if (Core.IsRunningFromXUnit) + { + _cacheBuckets = null; + _buckets = new STArrayStack[BucketCount]; + } + } + + public bool Trim() + { + var ticks = Core.TickCount; + var pressure = GetMemoryPressure(); + + var buckets = _buckets; + for (var i = 0; i < buckets.Length; i++) + { + buckets[i]?.Trim(ticks, pressure, GetMaxSizeForBucket(i)); + } + + // Under high pressure, release all cached buckets + if (pressure == MemoryPressure.High) + { + Array.Clear(_cacheBuckets); + } + else + { + uint threshold = pressure switch + { + MemoryPressure.Medium => 10000, + _ => 30000, + }; + + var cacheBuckets = _cacheBuckets; + for (var i = 0; i < cacheBuckets.Length; i++) + { + ref var b = ref cacheBuckets[i]; + + if (b.Array is null) + { + continue; + } + + var lastSeen = b.Ticks; + if (lastSeen == 0) + { + b.Ticks = ticks; + } + else if (ticks - lastSeen >= threshold) + { + b.Array = null; + } + } + } + + return true; + } + + private STArrayStack CreateBucketStack(int bucketIndex) + { + return _buckets[bucketIndex] = new STArrayStack(); + } + + private STArray[] InitializeBuckets() + { + Debug.Assert(_cacheBuckets is null, $"Non-null {nameof(_cacheBuckets)}"); + var buckets = new STArray[BucketCount]; + return _cacheBuckets = buckets; + } + + // Buffers are bucketed so that a request between 2^(n-1) + 1 and 2^n is given a buffer of 2^n + // Bucket index is log2(bufferSize - 1) with the exception that buffers between 1 and 16 bytes + // are combined, and the index is slid down by 3 to compensate. + // Zero is a valid bufferSize, and it is assigned the highest bucket index so that zero-length + // buffers are not retained by the pool. The pool will return the Array.Empty singleton for these. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static int SelectBucketIndex(int bufferSize) => BitOperations.Log2((uint)bufferSize - 1 | 15) - 3; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static int GetMaxSizeForBucket(int binIndex) + { + int maxSize = 16 << binIndex; + Debug.Assert(maxSize >= 0); + return maxSize; + } + + internal enum MemoryPressure + { + Low, + Medium, + High + } + + internal static MemoryPressure GetMemoryPressure() + { + GCMemoryInfo memoryInfo = GC.GetGCMemoryInfo(); + + if (memoryInfo.MemoryLoadBytes >= memoryInfo.HighMemoryLoadThresholdBytes * 0.90) + { + return MemoryPressure.High; + } + + if (memoryInfo.MemoryLoadBytes >= memoryInfo.HighMemoryLoadThresholdBytes * 0.70) + { + return MemoryPressure.Medium; + } + + return MemoryPressure.Low; + } + + private sealed class STArrayStack + { + // Maximum buffers we will store in our stack + private readonly T[][] _arrays = new T[StackArraySize * Environment.ProcessorCount][]; + private int _count; + private long _ticks; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryPush(T[] array) + { + var arrays = _arrays; + var count = _count; + if ((uint)count < (uint)_arrays.Length) + { + arrays[count] = array; + _count = count + 1; + return true; + } + + return false; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public T[] TryPop() + { + var arrays = _arrays; + var count = _count - 1; + if ((uint)count < (uint)arrays.Length) + { + var arr = arrays[count]; + arrays[count] = null; + _count = count; + return arr; + } + + return null; + } + + public void Trim(long now, MemoryPressure pressure, int bucketSize) + { + if (_count == 0) + { + return; + } + + // 10 seconds under high pressure, otherwise 60 seconds + var threshold = pressure == MemoryPressure.High ? 10000 : 60000; + + if (_ticks == 0) + { + _ticks = now; + return; + } + + if (now - _ticks <= threshold) + { + return; + } + + int trimCount = 1; + switch (pressure) + { + case MemoryPressure.Medium: + { + trimCount = 2; + break; + } + case MemoryPressure.High: + { + if (bucketSize > 16384) + { + trimCount++; + } + + var size = Unsafe.SizeOf(); + if (size > 32) + { + trimCount += 2; + } + else if (size > 16) + { + trimCount++; + } + + break; + } + } + + while (_count > 0 && trimCount-- > 0) + { + _arrays[--_count] = null; + } + } + } + + private struct STArray + { + public T[] Array; + public long Ticks; + + public STArray(T[] array) + { + Array = array; + Ticks = 0; + } + } +} diff --git a/Projects/Server/Maps/Map.cs b/Projects/Server/Maps/Map.cs index a6fcad289..9c93f772d 100644 --- a/Projects/Server/Maps/Map.cs +++ b/Projects/Server/Maps/Map.cs @@ -691,7 +691,7 @@ namespace Server } } - ArrayPool.Shared.Return(items); + ArrayPool.Shared.Return(items, true); } /* This could probably be re-implemented if necessary (perhaps via an ITile interface?). diff --git a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/BladeSpirits.cs b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/BladeSpirits.cs index 374ae412e..8f326bc5f 100644 --- a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/BladeSpirits.cs +++ b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/BladeSpirits.cs @@ -94,7 +94,7 @@ namespace Server.Mobiles Dispel(mobs[amount--]); } - ArrayPool.Shared.Return(mobs); + ArrayPool.Shared.Return(mobs, true); } } diff --git a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/EnergyVortex.cs b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/EnergyVortex.cs index 145b85b6d..66f808bcc 100644 --- a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/EnergyVortex.cs +++ b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/EnergyVortex.cs @@ -100,7 +100,7 @@ namespace Server.Mobiles Dispel(mobs[amount--]); } - ArrayPool.Shared.Return(mobs); + ArrayPool.Shared.Return(mobs, true); } } From 14b63ca48e392ad5cfd2c3ca0a5cc21084e80f59 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Tue, 22 Mar 2022 20:07:32 -0700 Subject: [PATCH 108/213] fix: Updates ArrayPool to STArrayPool for performance. (#968) --- .../Server.Tests/Tests/Network/PipeTests.cs | 10 +- .../{Collections => Buffers}/STArrayPool.cs | 0 Projects/Server/Buffers/SpanWriter.cs | 752 ++--- Projects/Server/Buffers/ValueStringBuilder.cs | 916 +++--- .../Collections/PooledOrderedHashSet.cs | 943 +++--- Projects/Server/Maps/Map.cs | 2807 ++++++++--------- .../Network/Packets/OutgoingGumpPackets.cs | 7 +- .../Network/Packets/PacketContainerBuilder.cs | 10 +- Projects/Server/Text/StringHelpers.cs | 465 ++- .../Monsters/Misc/Melee/BladeSpirits.cs | 199 +- .../Monsters/Misc/Melee/EnergyVortex.cs | 219 +- 11 files changed, 3163 insertions(+), 3165 deletions(-) rename Projects/Server/{Collections => Buffers}/STArrayPool.cs (100%) diff --git a/Projects/Server.Tests/Tests/Network/PipeTests.cs b/Projects/Server.Tests/Tests/Network/PipeTests.cs index ab4556dc6..31b9baaa3 100644 --- a/Projects/Server.Tests/Tests/Network/PipeTests.cs +++ b/Projects/Server.Tests/Tests/Network/PipeTests.cs @@ -11,7 +11,7 @@ namespace Server.Tests.Network { private async void DelayedExecute(Action action) { - await Task.Delay(5); + await Task.Delay(1); action(); } @@ -130,8 +130,12 @@ namespace Server.Tests.Network continue; } - result.CopyFrom(new[] { expected_value, expected_value, expected_value, expected_value, expected_value, expected_value, expected_value, expected_value, - expected_value, expected_value, expected_value, expected_value, expected_value, expected_value, expected_value, expected_value }); + result.CopyFrom(new[] { + expected_value, expected_value, expected_value, expected_value, + expected_value, expected_value, expected_value, expected_value, + expected_value, expected_value, expected_value, expected_value, + expected_value, expected_value, expected_value, expected_value + }); writer.Advance(16); count += 16; diff --git a/Projects/Server/Collections/STArrayPool.cs b/Projects/Server/Buffers/STArrayPool.cs similarity index 100% rename from Projects/Server/Collections/STArrayPool.cs rename to Projects/Server/Buffers/STArrayPool.cs diff --git a/Projects/Server/Buffers/SpanWriter.cs b/Projects/Server/Buffers/SpanWriter.cs index 607e226a2..89981cc5e 100644 --- a/Projects/Server/Buffers/SpanWriter.cs +++ b/Projects/Server/Buffers/SpanWriter.cs @@ -1,6 +1,6 @@ /************************************************************************* * ModernUO * - * Copyright 2019-2020 - ModernUO Development Team * + * Copyright 2019-2022 - ModernUO Development Team * * Email: hi@modernuo.com * * File: SpanWriter.cs * * * @@ -22,40 +22,41 @@ using System.Runtime.InteropServices; using System.Text; using Microsoft.Toolkit.HighPerformance; using Server; +using Server.Buffers; using Server.Text; -namespace System.Buffers +namespace System.Buffers; + +public ref struct SpanWriter { - public ref struct SpanWriter + private readonly bool _resize; + private byte[] _arrayToReturnToPool; + private Span _buffer; + private int _position; + + public int BytesWritten { get; private set; } + + public int Position { - private readonly bool _resize; - private byte[] _arrayToReturnToPool; - private Span _buffer; - private int _position; - - public int BytesWritten { get; private set; } - - public int Position + get => _position; + private set { - get => _position; - private set - { - _position = value; + _position = value; - if (value > BytesWritten) - { - BytesWritten = value; - } + if (value > BytesWritten) + { + BytesWritten = value; } } + } - public int Capacity => _buffer.Length; + public int Capacity => _buffer.Length; - public ReadOnlySpan Span => _buffer[..Position]; + public ReadOnlySpan Span => _buffer[..Position]; - public Span RawBuffer => _buffer; + public Span RawBuffer => _buffer; - /** + /** * Converts the writer to a Span using a SpanOwner. * If the buffer was stackalloc, it will be copied to a rented buffer. * Otherwise the existing rented buffer is used. @@ -64,395 +65,394 @@ namespace System.Buffers * Do not use the SpanWriter after calling this method. * This method will effectively dispose of the SpanWriter and is therefore considered terminal. */ - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public SpanOwner ToSpan() + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public SpanOwner ToSpan() + { + var toReturn = _arrayToReturnToPool; + + SpanOwner apo; + if (_position == 0) { - var toReturn = _arrayToReturnToPool; - - SpanOwner apo; - if (_position == 0) - { - apo = new SpanOwner(_position, Array.Empty()); - if (toReturn != null) - { - ArrayPool.Shared.Return(toReturn); - } - } - else if (toReturn != null) - { - apo = new SpanOwner(_position, toReturn); - } - else - { - var buffer = ArrayPool.Shared.Rent(_position); - _buffer.CopyTo(buffer); - apo = new SpanOwner(_position, buffer); - } - - this = default; // Don't allow two references to the same buffer - return apo; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public SpanWriter(Span initialBuffer, bool resize = false) - { - _resize = resize; - _buffer = initialBuffer; - _position = 0; - BytesWritten = 0; - _arrayToReturnToPool = null; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public SpanWriter(int initialCapacity, bool resize = false) - { - _resize = resize; - _arrayToReturnToPool = ArrayPool.Shared.Rent(initialCapacity); - _buffer = _arrayToReturnToPool; - _position = 0; - BytesWritten = 0; - } - - [MethodImpl(MethodImplOptions.NoInlining)] - private void Grow(int additionalCapacity) - { - var newSize = Math.Max(BytesWritten + additionalCapacity, _buffer.Length * 2); - byte[] poolArray = ArrayPool.Shared.Rent(newSize); - - _buffer[..BytesWritten].CopyTo(poolArray); - - byte[] toReturn = _arrayToReturnToPool; - _buffer = _arrayToReturnToPool = poolArray; + apo = new SpanOwner(_position, Array.Empty()); if (toReturn != null) { - ArrayPool.Shared.Return(toReturn); + STArrayPool.Shared.Return(toReturn); } } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void GrowIfNeeded(int count) + else if (toReturn != null) { - if (_position + count > _buffer.Length) + apo = new SpanOwner(_position, toReturn); + } + else + { + var buffer = STArrayPool.Shared.Rent(_position); + _buffer.CopyTo(buffer); + apo = new SpanOwner(_position, buffer); + } + + this = default; // Don't allow two references to the same buffer + return apo; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public SpanWriter(Span initialBuffer, bool resize = false) + { + _resize = resize; + _buffer = initialBuffer; + _position = 0; + BytesWritten = 0; + _arrayToReturnToPool = null; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public SpanWriter(int initialCapacity, bool resize = false) + { + _resize = resize; + _arrayToReturnToPool = STArrayPool.Shared.Rent(initialCapacity); + _buffer = _arrayToReturnToPool; + _position = 0; + BytesWritten = 0; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private void Grow(int additionalCapacity) + { + var newSize = Math.Max(BytesWritten + additionalCapacity, _buffer.Length * 2); + byte[] poolArray = STArrayPool.Shared.Rent(newSize); + + _buffer[..BytesWritten].CopyTo(poolArray); + + byte[] toReturn = _arrayToReturnToPool; + _buffer = _arrayToReturnToPool = poolArray; + if (toReturn != null) + { + STArrayPool.Shared.Return(toReturn); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void GrowIfNeeded(int count) + { + if (_position + count > _buffer.Length) + { + if (!_resize) { - if (!_resize) - { - throw new OutOfMemoryException(); - } - - Grow(count); - } - } - - public ref byte GetPinnableReference() => ref MemoryMarshal.GetReference(_buffer); - - public void EnsureCapacity(int capacity) - { - if (capacity > _buffer.Length) - { - if (!_resize) - { - throw new OutOfMemoryException(); - } - - Grow(capacity - BytesWritten); - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe void Write(bool value) - { - GrowIfNeeded(1); - _buffer[Position++] = *(byte*)&value; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(byte value) - { - GrowIfNeeded(1); - _buffer[Position++] = value; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(sbyte value) - { - GrowIfNeeded(1); - _buffer[Position++] = (byte)value; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(short value) - { - GrowIfNeeded(2); - BinaryPrimitives.WriteInt16BigEndian(_buffer[_position..], value); - Position += 2; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void WriteLE(short value) - { - GrowIfNeeded(2); - BinaryPrimitives.WriteInt16LittleEndian(_buffer[_position..], value); - Position += 2; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(ushort value) - { - GrowIfNeeded(2); - BinaryPrimitives.WriteUInt16BigEndian(_buffer[_position..], value); - Position += 2; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void WriteLE(ushort value) - { - GrowIfNeeded(2); - BinaryPrimitives.WriteUInt16LittleEndian(_buffer[_position..], value); - Position += 2; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(int value) - { - GrowIfNeeded(4); - BinaryPrimitives.WriteInt32BigEndian(_buffer[_position..], value); - Position += 4; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void WriteLE(int value) - { - GrowIfNeeded(4); - BinaryPrimitives.WriteInt32LittleEndian(_buffer[_position..], value); - Position += 4; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(uint value) - { - GrowIfNeeded(4); - BinaryPrimitives.WriteUInt32BigEndian(_buffer[_position..], value); - Position += 4; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(Serial serial) => Write(serial.Value); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void WriteLE(uint value) - { - GrowIfNeeded(4); - BinaryPrimitives.WriteUInt32LittleEndian(_buffer[_position..], value); - Position += 4; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(long value) - { - GrowIfNeeded(8); - BinaryPrimitives.WriteInt64BigEndian(_buffer[_position..], value); - Position += 8; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(ulong value) - { - GrowIfNeeded(8); - BinaryPrimitives.WriteUInt64BigEndian(_buffer[_position..], value); - Position += 8; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(ReadOnlySpan buffer) - { - var count = buffer.Length; - GrowIfNeeded(count); - buffer.CopyTo(_buffer[_position..]); - Position += count; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void WriteAscii(char chr) => Write((byte)chr); - - public void WriteString(string value, Encoding encoding, int fixedLength = -1) where T : struct, IEquatable - { - int sizeT = Unsafe.SizeOf(); - - if (sizeT > 2) - { - throw new InvalidConstraintException("WriteString only accepts byte, sbyte, char, short, and ushort as a constraint"); + throw new OutOfMemoryException(); } - value ??= string.Empty; + Grow(count); + } + } - var charLength = Math.Min(fixedLength > -1 ? fixedLength : value.Length, value.Length); - var src = value.AsSpan(0, charLength); + public ref byte GetPinnableReference() => ref MemoryMarshal.GetReference(_buffer); - var byteCount = fixedLength > -1 ? fixedLength * sizeT : encoding.GetByteCount(value); - if (byteCount == 0) + public void EnsureCapacity(int capacity) + { + if (capacity > _buffer.Length) + { + if (!_resize) { - return; + throw new OutOfMemoryException(); } - GrowIfNeeded(byteCount); + Grow(capacity - BytesWritten); + } + } - var bytesWritten = encoding.GetBytes(src, _buffer[_position..]); - Position += bytesWritten; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe void Write(bool value) + { + GrowIfNeeded(1); + _buffer[Position++] = *(byte*)&value; + } - if (fixedLength > -1) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Write(byte value) + { + GrowIfNeeded(1); + _buffer[Position++] = value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Write(sbyte value) + { + GrowIfNeeded(1); + _buffer[Position++] = (byte)value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Write(short value) + { + GrowIfNeeded(2); + BinaryPrimitives.WriteInt16BigEndian(_buffer[_position..], value); + Position += 2; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteLE(short value) + { + GrowIfNeeded(2); + BinaryPrimitives.WriteInt16LittleEndian(_buffer[_position..], value); + Position += 2; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Write(ushort value) + { + GrowIfNeeded(2); + BinaryPrimitives.WriteUInt16BigEndian(_buffer[_position..], value); + Position += 2; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteLE(ushort value) + { + GrowIfNeeded(2); + BinaryPrimitives.WriteUInt16LittleEndian(_buffer[_position..], value); + Position += 2; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Write(int value) + { + GrowIfNeeded(4); + BinaryPrimitives.WriteInt32BigEndian(_buffer[_position..], value); + Position += 4; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteLE(int value) + { + GrowIfNeeded(4); + BinaryPrimitives.WriteInt32LittleEndian(_buffer[_position..], value); + Position += 4; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Write(uint value) + { + GrowIfNeeded(4); + BinaryPrimitives.WriteUInt32BigEndian(_buffer[_position..], value); + Position += 4; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Write(Serial serial) => Write(serial.Value); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteLE(uint value) + { + GrowIfNeeded(4); + BinaryPrimitives.WriteUInt32LittleEndian(_buffer[_position..], value); + Position += 4; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Write(long value) + { + GrowIfNeeded(8); + BinaryPrimitives.WriteInt64BigEndian(_buffer[_position..], value); + Position += 8; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Write(ulong value) + { + GrowIfNeeded(8); + BinaryPrimitives.WriteUInt64BigEndian(_buffer[_position..], value); + Position += 8; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Write(ReadOnlySpan buffer) + { + var count = buffer.Length; + GrowIfNeeded(count); + buffer.CopyTo(_buffer[_position..]); + Position += count; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteAscii(char chr) => Write((byte)chr); + + public void WriteString(string value, Encoding encoding, int fixedLength = -1) where T : struct, IEquatable + { + int sizeT = Unsafe.SizeOf(); + + if (sizeT > 2) + { + throw new InvalidConstraintException("WriteString only accepts byte, sbyte, char, short, and ushort as a constraint"); + } + + value ??= string.Empty; + + var charLength = Math.Min(fixedLength > -1 ? fixedLength : value.Length, value.Length); + var src = value.AsSpan(0, charLength); + + var byteCount = fixedLength > -1 ? fixedLength * sizeT : encoding.GetByteCount(value); + if (byteCount == 0) + { + return; + } + + GrowIfNeeded(byteCount); + + var bytesWritten = encoding.GetBytes(src, _buffer[_position..]); + Position += bytesWritten; + + if (fixedLength > -1) + { + var extra = fixedLength * sizeT - bytesWritten; + if (extra > 0) { - var extra = fixedLength * sizeT - bytesWritten; - if (extra > 0) - { - Clear(extra); - } + Clear(extra); } } + } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void WriteLittleUni(string value) => WriteString(value, TextEncoding.UnicodeLE); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteLittleUni(string value) => WriteString(value, TextEncoding.UnicodeLE); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void WriteLittleUniNull(string value) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteLittleUniNull(string value) + { + WriteString(value, TextEncoding.UnicodeLE); + Write((ushort)0); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteLittleUni(string value, int fixedLength) => WriteString(value, TextEncoding.UnicodeLE, fixedLength); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteBigUni(string value) => WriteString(value, TextEncoding.Unicode); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteBigUniNull(string value) + { + WriteString(value, TextEncoding.Unicode); + Write((ushort)0); // '\0' + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteBigUni(string value, int fixedLength) => WriteString(value, TextEncoding.Unicode, fixedLength); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteUTF8(string value) => WriteString(value, TextEncoding.UTF8); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteUTF8Null(string value) + { + WriteString(value, TextEncoding.UTF8); + Write((byte)0); // '\0' + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteAscii(string value) => WriteString(value, Encoding.ASCII); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteAsciiNull(string value) + { + WriteString(value, Encoding.ASCII); + Write((byte)0); // '\0' + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteAscii(string value, int fixedLength) => WriteString(value, Encoding.ASCII, fixedLength); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Clear(int count) + { + GrowIfNeeded(count); + _buffer.Slice(_position, count).Clear(); + Position += count; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int Seek(int offset, SeekOrigin origin) + { + Debug.Assert( + origin != SeekOrigin.End || _resize || offset <= 0, + "Attempting to seek to a position beyond capacity using SeekOrigin.End without resize" + ); + + Debug.Assert( + origin != SeekOrigin.End || offset >= -_buffer.Length, + + "Attempting to seek to a negative position using SeekOrigin.End" + ); + + Debug.Assert( + origin != SeekOrigin.Begin || offset >= 0, + "Attempting to seek to a negative position using SeekOrigin.Begin" + ); + + Debug.Assert( + origin != SeekOrigin.Begin || _resize || offset <= _buffer.Length, + "Attempting to seek to a position beyond the capacity using SeekOrigin.Begin without resize" + ); + + Debug.Assert( + origin != SeekOrigin.Current || _position + offset >= 0, + "Attempting to seek to a negative position using SeekOrigin.Current" + ); + + Debug.Assert( + origin != SeekOrigin.Current || _resize || _position + offset <= _buffer.Length, + "Attempting to seek to a position beyond the capacity using SeekOrigin.Current without resize" + ); + + var newPosition = Math.Max(0, origin switch { - WriteString(value, TextEncoding.UnicodeLE); - Write((ushort)0); + SeekOrigin.Current => _position + offset, + SeekOrigin.End => BytesWritten + offset, + _ => offset // Begin + }); + + if (newPosition >= _buffer.Length) + { + Grow(newPosition - _buffer.Length + 1); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void WriteLittleUni(string value, int fixedLength) => WriteString(value, TextEncoding.UnicodeLE, fixedLength); + return Position = newPosition; + } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void WriteBigUni(string value) => WriteString(value, TextEncoding.Unicode); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void WriteBigUniNull(string value) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Dispose() + { + byte[] toReturn = _arrayToReturnToPool; + this = default; // for safety, to avoid using pooled array if this instance is erroneously appended to again + if (toReturn != null) { - WriteString(value, TextEncoding.Unicode); - Write((ushort)0); // '\0' + STArrayPool.Shared.Return(toReturn); + } + } + + public struct SpanOwner : IDisposable + { + private readonly int _length; + private readonly byte[] _arrayToReturnToPool; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal SpanOwner(int length, byte[] buffer) + { + _length = length; + _arrayToReturnToPool = buffer; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void WriteBigUni(string value, int fixedLength) => WriteString(value, TextEncoding.Unicode, fixedLength); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void WriteUTF8(string value) => WriteString(value, TextEncoding.UTF8); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void WriteUTF8Null(string value) + public Span Span { - WriteString(value, TextEncoding.UTF8); - Write((byte)0); // '\0' - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void WriteAscii(string value) => WriteString(value, Encoding.ASCII); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void WriteAsciiNull(string value) - { - WriteString(value, Encoding.ASCII); - Write((byte)0); // '\0' - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void WriteAscii(string value, int fixedLength) => WriteString(value, Encoding.ASCII, fixedLength); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Clear(int count) - { - GrowIfNeeded(count); - _buffer.Slice(_position, count).Clear(); - Position += count; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public int Seek(int offset, SeekOrigin origin) - { - Debug.Assert( - origin != SeekOrigin.End || _resize || offset <= 0, - "Attempting to seek to a position beyond capacity using SeekOrigin.End without resize" - ); - - Debug.Assert( - origin != SeekOrigin.End || offset >= -_buffer.Length, - - "Attempting to seek to a negative position using SeekOrigin.End" - ); - - Debug.Assert( - origin != SeekOrigin.Begin || offset >= 0, - "Attempting to seek to a negative position using SeekOrigin.Begin" - ); - - Debug.Assert( - origin != SeekOrigin.Begin || _resize || offset <= _buffer.Length, - "Attempting to seek to a position beyond the capacity using SeekOrigin.Begin without resize" - ); - - Debug.Assert( - origin != SeekOrigin.Current || _position + offset >= 0, - "Attempting to seek to a negative position using SeekOrigin.Current" - ); - - Debug.Assert( - origin != SeekOrigin.Current || _resize || _position + offset <= _buffer.Length, - "Attempting to seek to a position beyond the capacity using SeekOrigin.Current without resize" - ); - - var newPosition = Math.Max(0, origin switch - { - SeekOrigin.Current => _position + offset, - SeekOrigin.End => BytesWritten + offset, - _ => offset // Begin - }); - - if (newPosition >= _buffer.Length) - { - Grow(newPosition - _buffer.Length + 1); - } - - return Position = newPosition; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => MemoryMarshal.CreateSpan(ref _arrayToReturnToPool.DangerousGetReference(), _length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Dispose() { byte[] toReturn = _arrayToReturnToPool; - this = default; // for safety, to avoid using pooled array if this instance is erroneously appended to again - if (toReturn != null) + this = default; + if (_length > 0) { - ArrayPool.Shared.Return(toReturn); - } - } - - public struct SpanOwner : IDisposable - { - private readonly int _length; - private readonly byte[] _arrayToReturnToPool; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal SpanOwner(int length, byte[] buffer) - { - _length = length; - _arrayToReturnToPool = buffer; - } - - public Span Span - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => MemoryMarshal.CreateSpan(ref _arrayToReturnToPool.DangerousGetReference(), _length); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Dispose() - { - byte[] toReturn = _arrayToReturnToPool; - this = default; - if (_length > 0) - { - ArrayPool.Shared.Return(toReturn); - } + STArrayPool.Shared.Return(toReturn); } } } diff --git a/Projects/Server/Buffers/ValueStringBuilder.cs b/Projects/Server/Buffers/ValueStringBuilder.cs index 1beda97f8..316c2960e 100644 --- a/Projects/Server/Buffers/ValueStringBuilder.cs +++ b/Projects/Server/Buffers/ValueStringBuilder.cs @@ -2,473 +2,471 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; -using System.Buffers; using System.Globalization; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -namespace Server.Buffers +namespace Server.Buffers; + +public ref struct ValueStringBuilder { - public ref struct ValueStringBuilder + private char[] _arrayToReturnToPool; + private Span _chars; + private int _length; + + // If this ctor is used, you cannot pass in stackalloc ROS for append/replace. + public ValueStringBuilder(ReadOnlySpan initialString) : this(initialString.Length) { - private char[] _arrayToReturnToPool; - private Span _chars; - private int _length; + Append(initialString); + } - // If this ctor is used, you cannot pass in stackalloc ROS for append/replace. - public ValueStringBuilder(ReadOnlySpan initialString) : this(initialString.Length) + public ValueStringBuilder(ReadOnlySpan initialString, Span initialBuffer) : this(initialBuffer) + { + Append(initialString); + } + + public ValueStringBuilder(Span initialBuffer) + { + _arrayToReturnToPool = null; + _chars = initialBuffer; + _length = 0; + } + + // If this ctor is used, you cannot pass in stackalloc ROS for append/replace. + public ValueStringBuilder(int initialCapacity) + { + _arrayToReturnToPool = STArrayPool.Shared.Rent(initialCapacity); + _chars = _arrayToReturnToPool; + _length = 0; + } + + public int Length => _length; + + public int Capacity => _chars.Length; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Reset() + { + _length = 0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void EnsureCapacity(int capacity) + { + if (capacity > _chars.Length) { - Append(initialString); - } - - public ValueStringBuilder(ReadOnlySpan initialString, Span initialBuffer) : this(initialBuffer) - { - Append(initialString); - } - - public ValueStringBuilder(Span initialBuffer) - { - _arrayToReturnToPool = null; - _chars = initialBuffer; - _length = 0; - } - - // If this ctor is used, you cannot pass in stackalloc ROS for append/replace. - public ValueStringBuilder(int initialCapacity) - { - _arrayToReturnToPool = ArrayPool.Shared.Rent(initialCapacity); - _chars = _arrayToReturnToPool; - _length = 0; - } - - public int Length => _length; - - public int Capacity => _chars.Length; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Reset() - { - _length = 0; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void EnsureCapacity(int capacity) - { - if (capacity > _chars.Length) - { - Grow(capacity - Length); - } - } - - /// - /// Get a pinnable reference to the builder. - /// Does not ensure there is a null char after - /// This overload is pattern matched in the C# 7.3+ compiler so you can omit - /// the explicit method call, and write eg "fixed (char* c = builder)" - /// - public ref char GetPinnableReference() => ref MemoryMarshal.GetReference(_chars); - - /// - /// Get a pinnable reference to the builder. - /// - /// Ensures that the builder has a null char after - public ref char GetPinnableReference(bool terminate) - { - if (terminate) - { - EnsureCapacity(_length + 1); - _chars[_length] = '\0'; - } - return ref MemoryMarshal.GetReference(_chars); - } - - public ref char this[int index] => ref _chars[index]; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override string ToString() => _chars[.._length].ToString(); - - /// Returns the underlying storage of the builder. - public Span RawChars => _chars; - - /// - /// Returns a span around the contents of the builder. - /// - /// Ensures that the builder has a null char after - public ReadOnlySpan AsSpan(bool terminate) - { - if (terminate) - { - EnsureCapacity(_length + 1); - _chars[_length] = '\0'; - } - return _chars[.._length]; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public ReadOnlySpan AsSpan() => _chars[.._length]; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public ReadOnlySpan AsSpan(int start) => _chars[start..]; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public ReadOnlySpan AsSpan(int start, int length) => _chars.Slice(start, length); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool TryCopyTo(Span destination, out int charsWritten) - { - if (_chars[.._length].TryCopyTo(destination)) - { - charsWritten = _length; - return true; - } - - charsWritten = 0; - return false; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Insert(int index, char value, int count) - { - if (_length > _chars.Length - count) - { - Grow(count); - } - - int remaining = _length - index; - _chars.Slice(index, remaining).CopyTo(_chars[(index + count)..]); - _chars.Slice(index, count).Fill(value); - _length += count; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Insert(int index, string s) - { - if (s == null) - { - return; - } - - int count = s.Length; - - if (_length > _chars.Length - count) - { - Grow(count); - } - - int remaining = _length - index; - _chars.Slice(index, remaining).CopyTo(_chars[(index + count)..]); - s.AsSpan().CopyTo(_chars[index..]); - _length += count; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(char c) - { - int pos = _length; - if ((uint)pos < (uint)_chars.Length) - { - _chars[pos] = c; - _length = pos + 1; - } - else - { - GrowAndAppend(c); - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(int value, NumberFormatInfo info = null) - { - if (value >= 0) - { - Append((uint)value); - return; - } - - Append((info ?? NumberFormatInfo.CurrentInfo).NegativeSign); - Append((uint)-value); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe void Append(uint value) - { - int bufferLength = value.CountDigits(); - - int pos = _length; - if ((uint)pos + (uint)bufferLength >= _chars.Length) - { - Grow(bufferLength); - } - - if (bufferLength == 1) - { - _chars[pos] = (char)(value + '0'); - _length = pos + 1; - return; - } - - fixed (char* buffer = _chars[pos..]) - { - char* p = buffer + bufferLength; - do - { - value = Utility.DivRem(value, 10, out uint remainder); - *--p = (char)(remainder + '0'); - } while (value != 0); - } - - _length = pos + bufferLength; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(string s) - { - if (s == null) - { - return; - } - - int pos = _length; - if (s.Length == 1 && (uint)pos < (uint)_chars.Length) // very common case, e.g. appending strings from NumberFormatInfo like separators, percent symbols, etc. - { - _chars[pos] = s[0]; - _length = pos + 1; - } - else - { - AppendSlow(s); - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(string s) - { - if (s == null) - { - return; - } - - // very common case, e.g. appending strings from NumberFormatInfo like separators, percent symbols, etc. - if (s.Length == 1) - { - Append(s[0]); - } - else - { - AppendSlow(s); - } - - Append(Environment.NewLine); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void AppendSlow(string s) - { - int pos = _length; - if (pos > _chars.Length - s.Length) - { - Grow(s.Length); - } - - s.AsSpan().CopyTo(_chars[pos..]); - _length += s.Length; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(char c, int count) - { - if (_length > _chars.Length - count) - { - Grow(count); - } - - Span dst = _chars.Slice(_length, count); - for (int i = 0; i < dst.Length; i++) - { - dst[i] = c; - } - _length += count; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe void Append(char* value, int length) - { - int pos = _length; - if (pos > _chars.Length - length) - { - Grow(length); - } - - Span dst = _chars.Slice(_length, length); - for (int i = 0; i < dst.Length; i++) - { - dst[i] = *value++; - } - _length += length; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(ReadOnlySpan value) - { - int pos = _length; - if (pos > _chars.Length - value.Length) - { - Grow(value.Length); - } - - value.CopyTo(_chars[_length..]); - _length += value.Length; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Span AppendSpan(int length) - { - int origPos = _length; - if (origPos > _chars.Length - length) - { - Grow(length); - } - - _length = origPos + length; - return _chars.Slice(origPos, length); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - private void GrowAndAppend(char c) - { - Grow(1); - Append(c); - } - -#nullable enable - /// - /// Resize the internal buffer either by doubling current buffer size or - /// by adding to - /// whichever is greater. - /// - /// - /// Number of chars requested beyond current position. - /// - [MethodImpl(MethodImplOptions.NoInlining)] - private void Grow(int additionalCapacityBeyondPos) - { - char[] poolArray = ArrayPool.Shared.Rent(Math.Max(_length + additionalCapacityBeyondPos, _chars.Length * 2)); - - _chars[.._length].CopyTo(poolArray); - - char[] toReturn = _arrayToReturnToPool; - _chars = _arrayToReturnToPool = poolArray; - if (toReturn != null) - { - ArrayPool.Shared.Return(toReturn); - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Dispose() - { - char[] toReturn = _arrayToReturnToPool; - this = default; // for safety, to avoid using pooled array if this instance is erroneously appended to again - if (toReturn != null) - { - ArrayPool.Shared.Return(toReturn); - } - } -#nullable restore - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ReplaceAny(ReadOnlySpan oldChars, ReadOnlySpan newChars, int startIndex, int count) - { - int currentLength = _length; - if ((uint)startIndex > (uint)currentLength) - { - throw new ArgumentOutOfRangeException(nameof(startIndex)); - } - - if (count < 0 || startIndex > currentLength - count) - { - throw new ArgumentOutOfRangeException(nameof(count)); - } - - var slice = _chars; - - while (true) - { - var indexOf = slice.IndexOfAny(oldChars); - if (indexOf == -1) - { - break; - } - - var chr = slice[indexOf]; - - slice[indexOf] = newChars[oldChars.IndexOf(chr)]; - slice = slice[(indexOf + 1)..]; - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Replace(char oldChar, char newChar, int startIndex, int count) - { - int currentLength = _length; - if ((uint)startIndex > (uint)currentLength) - { - throw new ArgumentOutOfRangeException(nameof(startIndex)); - } - - if (count < 0 || startIndex > currentLength - count) - { - throw new ArgumentOutOfRangeException(nameof(count)); - } - - var slice = _chars; - - while (true) - { - var indexOf = slice.IndexOf(oldChar); - if (indexOf == -1) - { - break; - } - - slice[indexOf] = newChar; - slice = slice[(indexOf + 1)..]; - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Remove(int startIndex, int length) - { - if (length < 0) - { - throw new ArgumentOutOfRangeException(nameof(length)); - } - - if (startIndex < 0) - { - throw new ArgumentOutOfRangeException(nameof(startIndex)); - } - - if (length > _length - startIndex) - { - throw new ArgumentOutOfRangeException(nameof(length)); - } - - if (startIndex == 0) - { - _chars = _chars[length..]; - } - else if (startIndex + length == _length) - { - _chars = _chars[..startIndex]; - } - else - { - // Somewhere in the middle, this will be slow - _chars[(startIndex + length)..].CopyTo(_chars[startIndex..]); - } - - _length -= length; + Grow(capacity - Length); } } + + /// + /// Get a pinnable reference to the builder. + /// Does not ensure there is a null char after + /// This overload is pattern matched in the C# 7.3+ compiler so you can omit + /// the explicit method call, and write eg "fixed (char* c = builder)" + /// + public ref char GetPinnableReference() => ref MemoryMarshal.GetReference(_chars); + + /// + /// Get a pinnable reference to the builder. + /// + /// Ensures that the builder has a null char after + public ref char GetPinnableReference(bool terminate) + { + if (terminate) + { + EnsureCapacity(_length + 1); + _chars[_length] = '\0'; + } + return ref MemoryMarshal.GetReference(_chars); + } + + public ref char this[int index] => ref _chars[index]; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override string ToString() => _chars[.._length].ToString(); + + /// Returns the underlying storage of the builder. + public Span RawChars => _chars; + + /// + /// Returns a span around the contents of the builder. + /// + /// Ensures that the builder has a null char after + public ReadOnlySpan AsSpan(bool terminate) + { + if (terminate) + { + EnsureCapacity(_length + 1); + _chars[_length] = '\0'; + } + return _chars[.._length]; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ReadOnlySpan AsSpan() => _chars[.._length]; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ReadOnlySpan AsSpan(int start) => _chars[start..]; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ReadOnlySpan AsSpan(int start, int length) => _chars.Slice(start, length); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryCopyTo(Span destination, out int charsWritten) + { + if (_chars[.._length].TryCopyTo(destination)) + { + charsWritten = _length; + return true; + } + + charsWritten = 0; + return false; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Insert(int index, char value, int count) + { + if (_length > _chars.Length - count) + { + Grow(count); + } + + int remaining = _length - index; + _chars.Slice(index, remaining).CopyTo(_chars[(index + count)..]); + _chars.Slice(index, count).Fill(value); + _length += count; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Insert(int index, string s) + { + if (s == null) + { + return; + } + + int count = s.Length; + + if (_length > _chars.Length - count) + { + Grow(count); + } + + int remaining = _length - index; + _chars.Slice(index, remaining).CopyTo(_chars[(index + count)..]); + s.AsSpan().CopyTo(_chars[index..]); + _length += count; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(char c) + { + int pos = _length; + if ((uint)pos < (uint)_chars.Length) + { + _chars[pos] = c; + _length = pos + 1; + } + else + { + GrowAndAppend(c); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(int value, NumberFormatInfo info = null) + { + if (value >= 0) + { + Append((uint)value); + return; + } + + Append((info ?? NumberFormatInfo.CurrentInfo).NegativeSign); + Append((uint)-value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe void Append(uint value) + { + int bufferLength = value.CountDigits(); + + int pos = _length; + if ((uint)pos + (uint)bufferLength >= _chars.Length) + { + Grow(bufferLength); + } + + if (bufferLength == 1) + { + _chars[pos] = (char)(value + '0'); + _length = pos + 1; + return; + } + + fixed (char* buffer = _chars[pos..]) + { + char* p = buffer + bufferLength; + do + { + value = Utility.DivRem(value, 10, out uint remainder); + *--p = (char)(remainder + '0'); + } while (value != 0); + } + + _length = pos + bufferLength; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(string s) + { + if (s == null) + { + return; + } + + int pos = _length; + if (s.Length == 1 && (uint)pos < (uint)_chars.Length) // very common case, e.g. appending strings from NumberFormatInfo like separators, percent symbols, etc. + { + _chars[pos] = s[0]; + _length = pos + 1; + } + else + { + AppendSlow(s); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(string s) + { + if (s == null) + { + return; + } + + // very common case, e.g. appending strings from NumberFormatInfo like separators, percent symbols, etc. + if (s.Length == 1) + { + Append(s[0]); + } + else + { + AppendSlow(s); + } + + Append(Environment.NewLine); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void AppendSlow(string s) + { + int pos = _length; + if (pos > _chars.Length - s.Length) + { + Grow(s.Length); + } + + s.AsSpan().CopyTo(_chars[pos..]); + _length += s.Length; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(char c, int count) + { + if (_length > _chars.Length - count) + { + Grow(count); + } + + Span dst = _chars.Slice(_length, count); + for (int i = 0; i < dst.Length; i++) + { + dst[i] = c; + } + _length += count; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe void Append(char* value, int length) + { + int pos = _length; + if (pos > _chars.Length - length) + { + Grow(length); + } + + Span dst = _chars.Slice(_length, length); + for (int i = 0; i < dst.Length; i++) + { + dst[i] = *value++; + } + _length += length; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(ReadOnlySpan value) + { + int pos = _length; + if (pos > _chars.Length - value.Length) + { + Grow(value.Length); + } + + value.CopyTo(_chars[_length..]); + _length += value.Length; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Span AppendSpan(int length) + { + int origPos = _length; + if (origPos > _chars.Length - length) + { + Grow(length); + } + + _length = origPos + length; + return _chars.Slice(origPos, length); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private void GrowAndAppend(char c) + { + Grow(1); + Append(c); + } + +#nullable enable + /// + /// Resize the internal buffer either by doubling current buffer size or + /// by adding to + /// whichever is greater. + /// + /// + /// Number of chars requested beyond current position. + /// + [MethodImpl(MethodImplOptions.NoInlining)] + private void Grow(int additionalCapacityBeyondPos) + { + char[] poolArray = STArrayPool.Shared.Rent(Math.Max(_length + additionalCapacityBeyondPos, _chars.Length * 2)); + + _chars[.._length].CopyTo(poolArray); + + char[] toReturn = _arrayToReturnToPool; + _chars = _arrayToReturnToPool = poolArray; + if (toReturn != null) + { + STArrayPool.Shared.Return(toReturn); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Dispose() + { + char[] toReturn = _arrayToReturnToPool; + this = default; // for safety, to avoid using pooled array if this instance is erroneously appended to again + if (toReturn != null) + { + STArrayPool.Shared.Return(toReturn); + } + } +#nullable restore + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ReplaceAny(ReadOnlySpan oldChars, ReadOnlySpan newChars, int startIndex, int count) + { + int currentLength = _length; + if ((uint)startIndex > (uint)currentLength) + { + throw new ArgumentOutOfRangeException(nameof(startIndex)); + } + + if (count < 0 || startIndex > currentLength - count) + { + throw new ArgumentOutOfRangeException(nameof(count)); + } + + var slice = _chars; + + while (true) + { + var indexOf = slice.IndexOfAny(oldChars); + if (indexOf == -1) + { + break; + } + + var chr = slice[indexOf]; + + slice[indexOf] = newChars[oldChars.IndexOf(chr)]; + slice = slice[(indexOf + 1)..]; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Replace(char oldChar, char newChar, int startIndex, int count) + { + int currentLength = _length; + if ((uint)startIndex > (uint)currentLength) + { + throw new ArgumentOutOfRangeException(nameof(startIndex)); + } + + if (count < 0 || startIndex > currentLength - count) + { + throw new ArgumentOutOfRangeException(nameof(count)); + } + + var slice = _chars; + + while (true) + { + var indexOf = slice.IndexOf(oldChar); + if (indexOf == -1) + { + break; + } + + slice[indexOf] = newChar; + slice = slice[(indexOf + 1)..]; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Remove(int startIndex, int length) + { + if (length < 0) + { + throw new ArgumentOutOfRangeException(nameof(length)); + } + + if (startIndex < 0) + { + throw new ArgumentOutOfRangeException(nameof(startIndex)); + } + + if (length > _length - startIndex) + { + throw new ArgumentOutOfRangeException(nameof(length)); + } + + if (startIndex == 0) + { + _chars = _chars[length..]; + } + else if (startIndex + length == _length) + { + _chars = _chars[..startIndex]; + } + else + { + // Somewhere in the middle, this will be slow + _chars[(startIndex + length)..].CopyTo(_chars[startIndex..]); + } + + _length -= length; + } } diff --git a/Projects/Server/Collections/PooledOrderedHashSet.cs b/Projects/Server/Collections/PooledOrderedHashSet.cs index 4a6e51f1b..8853918ba 100644 --- a/Projects/Server/Collections/PooledOrderedHashSet.cs +++ b/Projects/Server/Collections/PooledOrderedHashSet.cs @@ -14,590 +14,589 @@ *************************************************************************/ using System; -using System.Buffers; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Runtime.CompilerServices; using Microsoft.Collections.Extensions; +using Server.Buffers; -namespace Server.Collections +namespace Server.Collections; + +[DebuggerDisplay("Count = {Count}")] +public class PooledOrderedHashSet : IList, IDisposable { - [DebuggerDisplay("Count = {Count}")] - public class PooledOrderedHashSet : IList, IDisposable + private struct Entry { - private struct Entry - { - public uint HashCode; - public TValue Value; - public int Next; // the index of the next item in the same bucket, -1 if last - } + public uint HashCode; + public TValue Value; + public int Next; // the index of the next item in the same bucket, -1 if last + } - private static readonly Entry[] InitialEntries = new Entry[1]; - private int[] _buckets = HashHelpers.SizeOneIntArray; - private int _bucketsLength = 1; - private Entry[] _entries = InitialEntries; - private int _entriesLength = 1; - private ulong _fastModMultiplier; - private int _count; - private int _version; + private static readonly Entry[] InitialEntries = new Entry[1]; + private int[] _buckets = HashHelpers.SizeOneIntArray; + private int _bucketsLength = 1; + private Entry[] _entries = InitialEntries; + private int _entriesLength = 1; + private ulong _fastModMultiplier; + private int _count; + private int _version; #nullable enable - private readonly IEqualityComparer? _comparer; + private readonly IEqualityComparer? _comparer; #nullable disable - public int Count => _count; + public int Count => _count; #nullable enable - public IEqualityComparer? Comparer => _comparer; + public IEqualityComparer? Comparer => _comparer; #nullable disable - public PooledOrderedHashSet() - : this(0) + public PooledOrderedHashSet() + : this(0) + { + } + + public PooledOrderedHashSet(IEqualityComparer comparer) + : this(0, comparer) + { + } + + public PooledOrderedHashSet(int capacity, IEqualityComparer comparer = null) + { + if (capacity < 0) { + throw new ArgumentOutOfRangeException(nameof(capacity)); } - public PooledOrderedHashSet(IEqualityComparer comparer) - : this(0, comparer) + if (capacity > 0) { + int newSize = HashHelpers.GetPrime(capacity); + _buckets = STArrayPool.Shared.Rent(newSize); + _bucketsLength = newSize; + _entries = STArrayPool.Shared.Rent(newSize); + _entriesLength = newSize; + _fastModMultiplier = HashHelpers.GetFastModMultiplier((uint)newSize); } - public PooledOrderedHashSet(int capacity, IEqualityComparer comparer = null) + if (comparer != EqualityComparer.Default) { - if (capacity < 0) - { - throw new ArgumentOutOfRangeException(nameof(capacity)); - } + _comparer = comparer; + } + } - if (capacity > 0) - { - int newSize = HashHelpers.GetPrime(capacity); - _buckets = ArrayPool.Shared.Rent(newSize); - _bucketsLength = newSize; - _entries = ArrayPool.Shared.Rent(newSize); - _entriesLength = newSize; - _fastModMultiplier = HashHelpers.GetFastModMultiplier((uint)newSize); - } - - if (comparer != EqualityComparer.Default) - { - _comparer = comparer; - } + public PooledOrderedHashSet(IEnumerable collection, IEqualityComparer comparer = null) + : this((collection as ICollection)?.Count ?? 0, comparer) + { + if (collection == null) + { + throw new ArgumentNullException(nameof(collection)); } - public PooledOrderedHashSet(IEnumerable collection, IEqualityComparer comparer = null) - : this((collection as ICollection)?.Count ?? 0, comparer) + foreach (TValue value in collection) { - if (collection == null) - { - throw new ArgumentNullException(nameof(collection)); - } - - foreach (TValue value in collection) - { - Add(value); - } + Add(value); } + } - public bool Contains(TValue item) => TryGetValue(item, out var value) && EqualityComparer.Default.Equals(value); + public bool Contains(TValue item) => TryGetValue(item, out var value) && EqualityComparer.Default.Equals(value); - public void Clear() + public void Clear() + { + if (_count > 0) { - if (_count > 0) - { - Array.Clear(_buckets, 0, _bucketsLength); - Array.Clear(_entries, 0, _count); - _count = 0; - ++_version; - } - } - - public Enumerator GetEnumerator() => new(this); - - void ICollection.Add(TValue item) => TryAdd(item); - - public bool Add(TValue item) => TryAdd(item); - - public int GetOrAdd(TValue value) => TryInsert(null, value); - - public int IndexOf(TValue value) => IndexOf(value, out _); - - public void Insert(int index, TValue value) - { - if ((uint)index > (uint)Count) - { - throw new ArgumentOutOfRangeException(nameof(index), CollectionThrowStrings.ArgumentOutOfRange_Index); - } - - TryInsert(index, value); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private ref int GetBucketRef(uint hashCode) - { - int[] buckets = _buckets!; - return ref buckets[HashHelpers.FastMod(hashCode, (uint)_bucketsLength, _fastModMultiplier)]; - } - - public bool Remove(TValue value) - { - int index = IndexOf(value); - if (index >= 0) - { - RemoveAt(index); - return true; - } - - return false; - } - - public void RemoveAt(int index) - { - int count = Count; - if ((uint)index >= (uint)count) - { - throw new ArgumentOutOfRangeException(nameof(index), CollectionThrowStrings.ArgumentOutOfRange_Index); - } - - // Remove the entry from the bucket - RemoveEntryFromBucket(index); - - // Decrement the indices > index - Entry[] entries = _entries; - for (int i = index + 1; i < count; ++i) - { - entries[i - 1] = entries[i]; - UpdateBucketIndex(i, incrementAmount: -1); - } - --_count; - entries[_count] = default; + Array.Clear(_buckets, 0, _bucketsLength); + Array.Clear(_entries, 0, _count); + _count = 0; ++_version; } + } - public bool TryAdd(TValue value) => TryInsert(null, value) != _count - 1; + public Enumerator GetEnumerator() => new(this); - public bool TryGetValue(TValue value, out TValue actualValue) + void ICollection.Add(TValue item) => TryAdd(item); + + public bool Add(TValue item) => TryAdd(item); + + public int GetOrAdd(TValue value) => TryInsert(null, value); + + public int IndexOf(TValue value) => IndexOf(value, out _); + + public void Insert(int index, TValue value) + { + if ((uint)index > (uint)Count) { - int index = IndexOf(value); - if (index >= 0) - { - actualValue = _entries[index].Value; - return true; - } - - actualValue = default; - return false; + throw new ArgumentOutOfRangeException(nameof(index), CollectionThrowStrings.ArgumentOutOfRange_Index); } - public TValue this[int index] + TryInsert(index, value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private ref int GetBucketRef(uint hashCode) + { + int[] buckets = _buckets!; + return ref buckets[HashHelpers.FastMod(hashCode, (uint)_bucketsLength, _fastModMultiplier)]; + } + + public bool Remove(TValue value) + { + int index = IndexOf(value); + if (index >= 0) { - get - { - if ((uint)index >= (uint)Count) - { - throw new ArgumentOutOfRangeException(nameof(index), CollectionThrowStrings.ArgumentOutOfRange_Index); - } - - return _entries[index].Value; - } - set - { - if ((uint)index >= (uint)Count) - { - throw new ArgumentOutOfRangeException(nameof(index), CollectionThrowStrings.ArgumentOutOfRange_Index); - } - - TValue v = value; - int foundIndex = IndexOf(v, out uint hashCode); - if (foundIndex < 0) - { - RemoveEntryFromBucket(index); - Entry entry = new Entry { HashCode = hashCode, Value = value }; - AddEntryToBucket(ref entry, index, _buckets, _bucketsLength); - _entries[index] = entry; - ++_version; - } - else if (foundIndex == index) - { - ref Entry entry = ref _entries[index]; - entry.Value = value; - } - else - { - throw new ArgumentException(string.Format(CollectionThrowStrings.Argument_AddingDuplicate, v.ToString())); - } - } + RemoveAt(index); + return true; } - public bool IsReadOnly => false; + return false; + } - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - - public void CopyTo(TValue[] array, int arrayIndex) + public void RemoveAt(int index) + { + int count = Count; + if ((uint)index >= (uint)count) { - if (array == null) - { - throw new ArgumentNullException(nameof(array)); - } - - if ((uint)arrayIndex > (uint)array.Length) - { - throw new ArgumentOutOfRangeException(nameof(arrayIndex), CollectionThrowStrings.ArgumentOutOfRange_NeedNonNegNum); - } - - int count = Count; - if (array.Length - arrayIndex < count) - { - throw new ArgumentException(CollectionThrowStrings.Arg_ArrayPlusOffTooSmall); - } - - Entry[] entries = _entries; - for (int i = 0; i < count; ++i) - { - Entry entry = entries[i]; - array[i + arrayIndex] = entry.Value; - } + throw new ArgumentOutOfRangeException(nameof(index), CollectionThrowStrings.ArgumentOutOfRange_Index); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private Entry[] Resize(int newSize) + // Remove the entry from the bucket + RemoveEntryFromBucket(index); + + // Decrement the indices > index + Entry[] entries = _entries; + for (int i = index + 1; i < count; ++i) { - int[] newBuckets = _buckets.Length < newSize ? ArrayPool.Shared.Rent(newSize) : _buckets; - Entry[] newEntries = _entries.Length < newSize ? ArrayPool.Shared.Rent(newSize) : _entries; + entries[i - 1] = entries[i]; + UpdateBucketIndex(i, incrementAmount: -1); + } + --_count; + entries[_count] = default; + ++_version; + } - int count = Count; - Array.Copy(_entries, newEntries, count); + public bool TryAdd(TValue value) => TryInsert(null, value) != _count - 1; - _fastModMultiplier = HashHelpers.GetFastModMultiplier((uint)newSize); - - for (int i = 0; i < count; ++i) - { - AddEntryToBucket(ref newEntries[i], i, newBuckets, newSize); - } - - var oldBuckets = _buckets; - var oldEntries = _entries; - - if (oldBuckets.Length > 1 && oldBuckets != newBuckets) - { - ArrayPool.Shared.Return(oldBuckets, true); - } - - if (oldEntries.Length > 1 && oldEntries != newEntries) - { - ArrayPool.Shared.Return(oldEntries, true); - } - - _buckets = newBuckets; - _bucketsLength = newSize; - _entries = newEntries; - _entriesLength = newSize; - return newEntries; + public bool TryGetValue(TValue value, out TValue actualValue) + { + int index = IndexOf(value); + if (index >= 0) + { + actualValue = _entries[index].Value; + return true; } -#nullable enable - private int IndexOf(TValue value, out uint hashCode) + actualValue = default; + return false; + } + + public TValue this[int index] + { + get { - ref int bucket = ref Unsafe.NullRef(); - int i; - - IEqualityComparer? comparer = _comparer; - if (comparer == null) + if ((uint)index >= (uint)Count) { - hashCode = (uint)value.GetHashCode(); - bucket = ref GetBucketRef(hashCode); - i = bucket - 1; + throw new ArgumentOutOfRangeException(nameof(index), CollectionThrowStrings.ArgumentOutOfRange_Index); + } - if (i >= 0) - { - if (typeof(TValue).IsValueType) - { - // ValueType: Devirtualize with EqualityComparer.Default intrinsic - Entry[] entries = _entries; - int collisionCount = 0; - do - { - Entry entry = entries[i]; - if (entry.HashCode == hashCode && EqualityComparer.Default.Equals(entry.Value, value)) - { - break; - } + return _entries[index].Value; + } + set + { + if ((uint)index >= (uint)Count) + { + throw new ArgumentOutOfRangeException(nameof(index), CollectionThrowStrings.ArgumentOutOfRange_Index); + } - i = entry.Next; - if (collisionCount >= _entriesLength) - { - // The chain of entries forms a loop; which means a concurrent update has happened. - // Break out of the loop and throw, rather than looping forever. - throw new InvalidOperationException( - CollectionThrowStrings.InvalidOperation_ConcurrentOperationsNotSupported - ); - } - - ++collisionCount; - } while (i >= 0); - } - else - { - // Object type: Shared Generic, EqualityComparer.Default won't devirtualize (https://github.com/dotnet/runtime/issues/10050), - // so cache in a local rather than get EqualityComparer per loop iteration. - var defaultComparer = EqualityComparer.Default; - Entry[] entries = _entries; - int collisionCount = 0; - do - { - Entry entry = entries[i]; - if (entry.HashCode == hashCode && defaultComparer.Equals(entry.Value, value)) - { - break; - } - - i = entry.Next; - if (collisionCount >= _entriesLength) - { - // The chain of entries forms a loop; which means a concurrent update has happened. - // Break out of the loop and throw, rather than looping forever. - throw new InvalidOperationException( - CollectionThrowStrings.InvalidOperation_ConcurrentOperationsNotSupported - ); - } - - ++collisionCount; - } while (i >= 0); - } - } + TValue v = value; + int foundIndex = IndexOf(v, out uint hashCode); + if (foundIndex < 0) + { + RemoveEntryFromBucket(index); + Entry entry = new Entry { HashCode = hashCode, Value = value }; + AddEntryToBucket(ref entry, index, _buckets, _bucketsLength); + _entries[index] = entry; + ++_version; + } + else if (foundIndex == index) + { + ref Entry entry = ref _entries[index]; + entry.Value = value; } else { - hashCode = (uint)comparer.GetHashCode(value); - bucket = ref GetBucketRef(hashCode); - i = bucket - 1; - if (i >= 0) + throw new ArgumentException(string.Format(CollectionThrowStrings.Argument_AddingDuplicate, v.ToString())); + } + } + } + + public bool IsReadOnly => false; + + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + public void CopyTo(TValue[] array, int arrayIndex) + { + if (array == null) + { + throw new ArgumentNullException(nameof(array)); + } + + if ((uint)arrayIndex > (uint)array.Length) + { + throw new ArgumentOutOfRangeException(nameof(arrayIndex), CollectionThrowStrings.ArgumentOutOfRange_NeedNonNegNum); + } + + int count = Count; + if (array.Length - arrayIndex < count) + { + throw new ArgumentException(CollectionThrowStrings.Arg_ArrayPlusOffTooSmall); + } + + Entry[] entries = _entries; + for (int i = 0; i < count; ++i) + { + Entry entry = entries[i]; + array[i + arrayIndex] = entry.Value; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private Entry[] Resize(int newSize) + { + int[] newBuckets = _buckets.Length < newSize ? STArrayPool.Shared.Rent(newSize) : _buckets; + Entry[] newEntries = _entries.Length < newSize ? STArrayPool.Shared.Rent(newSize) : _entries; + + int count = Count; + Array.Copy(_entries, newEntries, count); + + _fastModMultiplier = HashHelpers.GetFastModMultiplier((uint)newSize); + + for (int i = 0; i < count; ++i) + { + AddEntryToBucket(ref newEntries[i], i, newBuckets, newSize); + } + + var oldBuckets = _buckets; + var oldEntries = _entries; + + if (oldBuckets.Length > 1 && oldBuckets != newBuckets) + { + STArrayPool.Shared.Return(oldBuckets, true); + } + + if (oldEntries.Length > 1 && oldEntries != newEntries) + { + STArrayPool.Shared.Return(oldEntries, true); + } + + _buckets = newBuckets; + _bucketsLength = newSize; + _entries = newEntries; + _entriesLength = newSize; + return newEntries; + } + +#nullable enable + private int IndexOf(TValue value, out uint hashCode) + { + ref int bucket = ref Unsafe.NullRef(); + int i; + + IEqualityComparer? comparer = _comparer; + if (comparer == null) + { + hashCode = (uint)value.GetHashCode(); + bucket = ref GetBucketRef(hashCode); + i = bucket - 1; + + if (i >= 0) + { + if (typeof(TValue).IsValueType) { + // ValueType: Devirtualize with EqualityComparer.Default intrinsic Entry[] entries = _entries; int collisionCount = 0; do { Entry entry = entries[i]; - if (entry.HashCode == hashCode && comparer.Equals(entry.Value, value)) + if (entry.HashCode == hashCode && EqualityComparer.Default.Equals(entry.Value, value)) { break; } + i = entry.Next; if (collisionCount >= _entriesLength) { // The chain of entries forms a loop; which means a concurrent update has happened. // Break out of the loop and throw, rather than looping forever. - throw new InvalidOperationException(CollectionThrowStrings.InvalidOperation_ConcurrentOperationsNotSupported); + throw new InvalidOperationException( + CollectionThrowStrings.InvalidOperation_ConcurrentOperationsNotSupported + ); } + + ++collisionCount; + } while (i >= 0); + } + else + { + // Object type: Shared Generic, EqualityComparer.Default won't devirtualize (https://github.com/dotnet/runtime/issues/10050), + // so cache in a local rather than get EqualityComparer per loop iteration. + var defaultComparer = EqualityComparer.Default; + Entry[] entries = _entries; + int collisionCount = 0; + do + { + Entry entry = entries[i]; + if (entry.HashCode == hashCode && defaultComparer.Equals(entry.Value, value)) + { + break; + } + + i = entry.Next; + if (collisionCount >= _entriesLength) + { + // The chain of entries forms a loop; which means a concurrent update has happened. + // Break out of the loop and throw, rather than looping forever. + throw new InvalidOperationException( + CollectionThrowStrings.InvalidOperation_ConcurrentOperationsNotSupported + ); + } + ++collisionCount; } while (i >= 0); } } - - return i; } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private int TryInsert(int? index, TValue value) + else { - int i = IndexOf(value, out uint hashCode); - return i >= 0 ? i : AddInternal(index, value, hashCode); + hashCode = (uint)comparer.GetHashCode(value); + bucket = ref GetBucketRef(hashCode); + i = bucket - 1; + if (i >= 0) + { + Entry[] entries = _entries; + int collisionCount = 0; + do + { + Entry entry = entries[i]; + if (entry.HashCode == hashCode && comparer.Equals(entry.Value, value)) + { + break; + } + i = entry.Next; + if (collisionCount >= _entriesLength) + { + // The chain of entries forms a loop; which means a concurrent update has happened. + // Break out of the loop and throw, rather than looping forever. + throw new InvalidOperationException(CollectionThrowStrings.InvalidOperation_ConcurrentOperationsNotSupported); + } + ++collisionCount; + } while (i >= 0); + } } - private int AddInternal(int? index, TValue value, uint hashCode) + return i; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private int TryInsert(int? index, TValue value) + { + int i = IndexOf(value, out uint hashCode); + return i >= 0 ? i : AddInternal(index, value, hashCode); + } + + private int AddInternal(int? index, TValue value, uint hashCode) + { + Entry[] entries = _entries; + // Check if resize is needed + int count = Count; + if (_entriesLength == count || entries.Length == 1) { - Entry[] entries = _entries; - // Check if resize is needed - int count = Count; - if (_entriesLength == count || entries.Length == 1) - { - entries = Resize(HashHelpers.ExpandPrime(_entriesLength)); - } - - // Increment indices >= index; - int actualIndex = index ?? count; - for (int i = count - 1; i >= actualIndex; --i) - { - entries[i + 1] = entries[i]; - UpdateBucketIndex(i, incrementAmount: 1); - } - - ref Entry entry = ref entries[actualIndex]; - entry.HashCode = hashCode; - entry.Value = value; - AddEntryToBucket(ref entry, actualIndex, _buckets, _bucketsLength); - ++_count; - ++_version; - return actualIndex; + entries = Resize(HashHelpers.ExpandPrime(_entriesLength)); } + + // Increment indices >= index; + int actualIndex = index ?? count; + for (int i = count - 1; i >= actualIndex; --i) + { + entries[i + 1] = entries[i]; + UpdateBucketIndex(i, incrementAmount: 1); + } + + ref Entry entry = ref entries[actualIndex]; + entry.HashCode = hashCode; + entry.Value = value; + AddEntryToBucket(ref entry, actualIndex, _buckets, _bucketsLength); + ++_count; + ++_version; + return actualIndex; + } #nullable restore - // Returns the index of the next entry in the bucket - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void AddEntryToBucket(ref Entry entry, int entryIndex, int[] buckets, int bucketsLength) - { - ref int b = ref buckets[(int)(entry.HashCode % (uint)bucketsLength)]; - entry.Next = b - 1; - b = entryIndex + 1; - } + // Returns the index of the next entry in the bucket + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void AddEntryToBucket(ref Entry entry, int entryIndex, int[] buckets, int bucketsLength) + { + ref int b = ref buckets[(int)(entry.HashCode % (uint)bucketsLength)]; + entry.Next = b - 1; + b = entryIndex + 1; + } - private void RemoveEntryFromBucket(int entryIndex) + private void RemoveEntryFromBucket(int entryIndex) + { + Entry[] entries = _entries; + Entry entry = entries[entryIndex]; + ref int bucket = ref GetBucketRef(entry.HashCode); + // Bucket was pointing to removed entry. Update it to point to the next in the chain + if (bucket == entryIndex + 1) { - Entry[] entries = _entries; - Entry entry = entries[entryIndex]; - ref int bucket = ref GetBucketRef(entry.HashCode); - // Bucket was pointing to removed entry. Update it to point to the next in the chain - if (bucket == entryIndex + 1) + bucket = entry.Next + 1; + } + else + { + // Start at the entry the bucket points to, and walk the chain until we find the entry with the index we want to remove, then fix the chain + int i = bucket - 1; + int collisionCount = 0; + while (true) { - bucket = entry.Next + 1; - } - else - { - // Start at the entry the bucket points to, and walk the chain until we find the entry with the index we want to remove, then fix the chain - int i = bucket - 1; - int collisionCount = 0; - while (true) + ref Entry e = ref entries[i]; + if (e.Next == entryIndex) { - ref Entry e = ref entries[i]; - if (e.Next == entryIndex) - { - e.Next = entry.Next; - return; - } - i = e.Next; - if (collisionCount >= _entriesLength) - { - // The chain of entries forms a loop; which means a concurrent update has happened. - // Break out of the loop and throw, rather than looping forever. - throw new InvalidOperationException(CollectionThrowStrings.InvalidOperation_ConcurrentOperationsNotSupported); - } - ++collisionCount; + e.Next = entry.Next; + return; } + i = e.Next; + if (collisionCount >= _entriesLength) + { + // The chain of entries forms a loop; which means a concurrent update has happened. + // Break out of the loop and throw, rather than looping forever. + throw new InvalidOperationException(CollectionThrowStrings.InvalidOperation_ConcurrentOperationsNotSupported); + } + ++collisionCount; } } + } - private void UpdateBucketIndex(int entryIndex, int incrementAmount) + private void UpdateBucketIndex(int entryIndex, int incrementAmount) + { + Entry[] entries = _entries; + Entry entry = entries[entryIndex]; + ref int bucket = ref GetBucketRef(entry.HashCode); + // Bucket was pointing to entry. Increment the index by incrementAmount. + if (bucket == entryIndex + 1) { - Entry[] entries = _entries; - Entry entry = entries[entryIndex]; - ref int bucket = ref GetBucketRef(entry.HashCode); - // Bucket was pointing to entry. Increment the index by incrementAmount. - if (bucket == entryIndex + 1) + bucket += incrementAmount; + } + else + { + // Start at the entry the bucket points to, and walk the chain until we find the entry with the index we want to increment. + int i = bucket - 1; + int collisionCount = 0; + while (true) { - bucket += incrementAmount; - } - else - { - // Start at the entry the bucket points to, and walk the chain until we find the entry with the index we want to increment. - int i = bucket - 1; - int collisionCount = 0; - while (true) + ref Entry e = ref entries[i]; + if (e.Next == entryIndex) { - ref Entry e = ref entries[i]; - if (e.Next == entryIndex) - { - e.Next += incrementAmount; - return; - } - i = e.Next; - if (collisionCount >= _entriesLength) - { - // The chain of entries forms a loop; which means a concurrent update has happened. - // Break out of the loop and throw, rather than looping forever. - throw new InvalidOperationException(CollectionThrowStrings.InvalidOperation_ConcurrentOperationsNotSupported); - } - ++collisionCount; + e.Next += incrementAmount; + return; } + i = e.Next; + if (collisionCount >= _entriesLength) + { + // The chain of entries forms a loop; which means a concurrent update has happened. + // Break out of the loop and throw, rather than looping forever. + throw new InvalidOperationException(CollectionThrowStrings.InvalidOperation_ConcurrentOperationsNotSupported); + } + ++collisionCount; } } + } - public struct Enumerator : IEnumerator + public struct Enumerator : IEnumerator + { + private readonly PooledOrderedHashSet _PooledOrderedHashSet; + private readonly int _version; + private int _index; + private TValue _current; + + public TValue Current => _current; + + object IEnumerator.Current => _current; + + internal Enumerator(PooledOrderedHashSet PooledOrderedHashSet) { - private readonly PooledOrderedHashSet _PooledOrderedHashSet; - private readonly int _version; - private int _index; - private TValue _current; - - public TValue Current => _current; - - object IEnumerator.Current => _current; - - internal Enumerator(PooledOrderedHashSet PooledOrderedHashSet) - { - _PooledOrderedHashSet = PooledOrderedHashSet; - _version = PooledOrderedHashSet._version; - _index = 0; - _current = default; - } - - public void Dispose() - { - } - - public bool MoveNext() - { - if (_version != _PooledOrderedHashSet._version) - { - throw new InvalidOperationException(CollectionThrowStrings.InvalidOperation_EnumFailedVersion); - } - - if (_index < _PooledOrderedHashSet.Count) - { - Entry entry = _PooledOrderedHashSet._entries[_index]; - _current = entry.Value; - ++_index; - return true; - } - _current = default; - return false; - } - - void IEnumerator.Reset() - { - if (_version != _PooledOrderedHashSet._version) - { - throw new InvalidOperationException(CollectionThrowStrings.InvalidOperation_EnumFailedVersion); - } - - _index = 0; - _current = default; - } + _PooledOrderedHashSet = PooledOrderedHashSet; + _version = PooledOrderedHashSet._version; + _index = 0; + _current = default; } public void Dispose() { - if (_buckets.Length > 1) - { - ArrayPool.Shared.Return(_buckets, true); - } - - if (_entries.Length > 1) - { - ArrayPool.Shared.Return(_entries, true); - } - - _buckets = HashHelpers.SizeOneIntArray; - _entries = InitialEntries; - _count = 0; - - GC.SuppressFinalize(this); } - ~PooledOrderedHashSet() + public bool MoveNext() { - if (_buckets.Length > 1) + if (_version != _PooledOrderedHashSet._version) { - ArrayPool.Shared.Return(_buckets, true); + throw new InvalidOperationException(CollectionThrowStrings.InvalidOperation_EnumFailedVersion); } - if (_entries.Length > 1) + if (_index < _PooledOrderedHashSet.Count) { - ArrayPool.Shared.Return(_entries, true); + Entry entry = _PooledOrderedHashSet._entries[_index]; + _current = entry.Value; + ++_index; + return true; + } + _current = default; + return false; + } + + void IEnumerator.Reset() + { + if (_version != _PooledOrderedHashSet._version) + { + throw new InvalidOperationException(CollectionThrowStrings.InvalidOperation_EnumFailedVersion); } - _buckets = HashHelpers.SizeOneIntArray; - _entries = InitialEntries; - _count = 0; + _index = 0; + _current = default; } } + + public void Dispose() + { + if (_buckets.Length > 1) + { + STArrayPool.Shared.Return(_buckets, true); + } + + if (_entries.Length > 1) + { + STArrayPool.Shared.Return(_entries, true); + } + + _buckets = HashHelpers.SizeOneIntArray; + _entries = InitialEntries; + _count = 0; + + GC.SuppressFinalize(this); + } + + ~PooledOrderedHashSet() + { + if (_buckets.Length > 1) + { + STArrayPool.Shared.Return(_buckets, true); + } + + if (_entries.Length > 1) + { + STArrayPool.Shared.Return(_entries, true); + } + + _buckets = HashHelpers.SizeOneIntArray; + _entries = InitialEntries; + _count = 0; + } } diff --git a/Projects/Server/Maps/Map.cs b/Projects/Server/Maps/Map.cs index 9c93f772d..e11ae4bd1 100644 --- a/Projects/Server/Maps/Map.cs +++ b/Projects/Server/Maps/Map.cs @@ -1,751 +1,774 @@ using System; -using System.Buffers; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Runtime.CompilerServices; +using Server.Buffers; using Server.Items; using Server.Logging; using Server.Network; using Server.Targeting; -namespace Server +namespace Server; + +[Flags] +public enum MapRules { - [Flags] - public enum MapRules + None = 0x0000, + Internal = 0x0001, // Internal map (used for dragging, commodity deeds, etc) + FreeMovement = 0x0002, // Anyone can move over anyone else without taking stamina loss + BeneficialRestrictions = 0x0004, // Disallow performing beneficial actions on criminals/murderers + HarmfulRestrictions = 0x0008, // Disallow performing harmful actions on innocents + TrammelRules = FreeMovement | BeneficialRestrictions | HarmfulRestrictions, + FeluccaRules = None +} + +public interface IPooledEnumerable : IEnumerable +{ + void Free(); +} + +public interface IPooledEnumerable : IPooledEnumerable, IEnumerable +{ +} + +public static class PooledEnumeration +{ + public delegate IEnumerable Selector(Sector sector, Rectangle2D bounds); + + static PooledEnumeration() { - None = 0x0000, - Internal = 0x0001, // Internal map (used for dragging, commodity deeds, etc) - FreeMovement = 0x0002, // Anyone can move over anyone else without taking stamina loss - BeneficialRestrictions = 0x0004, // Disallow performing beneficial actions on criminals/murderers - HarmfulRestrictions = 0x0008, // Disallow performing harmful actions on innocents - TrammelRules = FreeMovement | BeneficialRestrictions | HarmfulRestrictions, - FeluccaRules = None + ClientSelector = SelectClients; + EntitySelector = SelectEntities; + MobileSelector = SelectMobiles; + ItemSelector = SelectItems; + MultiSelector = SelectMultis; + MultiTileSelector = SelectMultiTiles; } - public interface IPooledEnumerable : IEnumerable + public static Selector ClientSelector { get; set; } + public static Selector EntitySelector { get; set; } + public static Selector MobileSelector { get; set; } + public static Selector ItemSelector { get; set; } + public static Selector MultiSelector { get; set; } + public static Selector MultiTileSelector { get; set; } + + public static IEnumerable SelectClients(Sector s, Rectangle2D bounds) { - void Free(); + var clients = new List(s.Clients.Count); + foreach (var client in s.Clients) + { + var m = client.Mobile; + + if (m?.Deleted == false && bounds.Contains(m.Location)) + { + clients.Add(client); + } + } + + return clients; } - public interface IPooledEnumerable : IPooledEnumerable, IEnumerable + public static IEnumerable SelectEntities(Sector s, Rectangle2D bounds) { - } - - public static class PooledEnumeration - { - public delegate IEnumerable Selector(Sector sector, Rectangle2D bounds); - - static PooledEnumeration() + var entities = new List(s.Mobiles.Count + s.Items.Count); + for (int i = s.Mobiles.Count - 1, j = s.Items.Count - 1; i >= 0 || j >= 0; --i, --j) { - ClientSelector = SelectClients; - EntitySelector = SelectEntities; - MobileSelector = SelectMobiles; - ItemSelector = SelectItems; - MultiSelector = SelectMultis; - MultiTileSelector = SelectMultiTiles; - } - - public static Selector ClientSelector { get; set; } - public static Selector EntitySelector { get; set; } - public static Selector MobileSelector { get; set; } - public static Selector ItemSelector { get; set; } - public static Selector MultiSelector { get; set; } - public static Selector MultiTileSelector { get; set; } - - public static IEnumerable SelectClients(Sector s, Rectangle2D bounds) - { - var clients = new List(s.Clients.Count); - foreach (var client in s.Clients) + if (j >= 0) { - var m = client.Mobile; - - if (m?.Deleted == false && bounds.Contains(m.Location)) - { - clients.Add(client); - } - } - - return clients; - } - - public static IEnumerable SelectEntities(Sector s, Rectangle2D bounds) - { - var entities = new List(s.Mobiles.Count + s.Items.Count); - for (int i = s.Mobiles.Count - 1, j = s.Items.Count - 1; i >= 0 || j >= 0; --i, --j) - { - if (j >= 0) - { - Item item = s.Items[j]; - if (item is { Deleted: false, Parent: null } && bounds.Contains(item.Location)) - { - entities.Add(item); - } - } - - if (i >= 0) - { - Mobile mob = s.Mobiles[i]; - if (mob is { Deleted: false } && bounds.Contains(mob.Location)) - { - entities.Add(mob); - } - } - } - return entities; - } - - public static IEnumerable SelectMobiles(Sector s, Rectangle2D bounds) where T : Mobile - { - var entities = new List(s.Mobiles.Count); - for (int i = s.Mobiles.Count - 1; i >= 0; --i) - { - if (s.Mobiles[i] is T { Deleted: false } mob && bounds.Contains(mob.Location)) - { - entities.Add(mob); - } - } - return entities; - } - - public static IEnumerable SelectItems(Sector s, Rectangle2D bounds) where T : Item - { - var entities = new List(s.Items.Count); - for (int i = s.Items.Count - 1; i >= 0; --i) - { - if (s.Items[i] is T { Deleted: false, Parent: null } item && bounds.Contains(item.Location)) + Item item = s.Items[j]; + if (item is { Deleted: false, Parent: null } && bounds.Contains(item.Location)) { entities.Add(item); } } - return entities; - } - public static IEnumerable SelectMultis(Sector s, Rectangle2D bounds) - { - var entities = new List(s.Multis.Count); - for (int i = s.Multis.Count - 1; i >= 0; --i) + if (i >= 0) { - BaseMulti multi = s.Multis[i]; - if (multi is { Deleted: false } && bounds.Contains(multi.Location)) + Mobile mob = s.Mobiles[i]; + if (mob is { Deleted: false } && bounds.Contains(mob.Location)) { - entities.Add(multi); + entities.Add(mob); } } - return entities; } + return entities; + } - public static IEnumerable SelectMultiTiles(Sector s, Rectangle2D bounds) + public static IEnumerable SelectMobiles(Sector s, Rectangle2D bounds) where T : Mobile + { + var entities = new List(s.Mobiles.Count); + for (int i = s.Mobiles.Count - 1; i >= 0; --i) { - for (int l = s.Multis.Count - 1; l >= 0; --l) + if (s.Mobiles[i] is T { Deleted: false } mob && bounds.Contains(mob.Location)) { - BaseMulti o = s.Multis[l]; - if (o?.Deleted != false) + entities.Add(mob); + } + } + return entities; + } + + public static IEnumerable SelectItems(Sector s, Rectangle2D bounds) where T : Item + { + var entities = new List(s.Items.Count); + for (int i = s.Items.Count - 1; i >= 0; --i) + { + if (s.Items[i] is T { Deleted: false, Parent: null } item && bounds.Contains(item.Location)) + { + entities.Add(item); + } + } + return entities; + } + + public static IEnumerable SelectMultis(Sector s, Rectangle2D bounds) + { + var entities = new List(s.Multis.Count); + for (int i = s.Multis.Count - 1; i >= 0; --i) + { + BaseMulti multi = s.Multis[i]; + if (multi is { Deleted: false } && bounds.Contains(multi.Location)) + { + entities.Add(multi); + } + } + return entities; + } + + public static IEnumerable SelectMultiTiles(Sector s, Rectangle2D bounds) + { + for (int l = s.Multis.Count - 1; l >= 0; --l) + { + BaseMulti o = s.Multis[l]; + if (o?.Deleted != false) + { + continue; + } + + MultiComponentList c = o.Components; + + int x, y, xo, yo; + StaticTile[] t, r; + + for (x = bounds.Start.X; x < bounds.End.X; x++) + { + xo = x - (o.X + c.Min.X); + + if (xo < 0 || xo >= c.Width) { continue; } - MultiComponentList c = o.Components; - - int x, y, xo, yo; - StaticTile[] t, r; - - for (x = bounds.Start.X; x < bounds.End.X; x++) + for (y = bounds.Start.Y; y < bounds.End.Y; y++) { - xo = x - (o.X + c.Min.X); + yo = y - (o.Y + c.Min.Y); - if (xo < 0 || xo >= c.Width) + if (yo < 0 || yo >= c.Height) { continue; } - for (y = bounds.Start.Y; y < bounds.End.Y; y++) + t = c.Tiles[xo][yo]; + + if (t.Length <= 0) { - yo = y - (o.Y + c.Min.Y); - - if (yo < 0 || yo >= c.Height) - { - continue; - } - - t = c.Tiles[xo][yo]; - - if (t.Length <= 0) - { - continue; - } - - r = new StaticTile[t.Length]; - - for (var i = 0; i < t.Length; i++) - { - r[i] = t[i]; - r[i].Z += o.Z; - } - - yield return r; + continue; } + + r = new StaticTile[t.Length]; + + for (var i = 0; i < t.Length; i++) + { + r[i] = t[i]; + r[i].Z += o.Z; + } + + yield return r; } } } - - public static Map.PooledEnumerable GetClients(Map map, Rectangle2D bounds) => - Map.PooledEnumerable.Instantiate(map, bounds, ClientSelector ?? SelectClients); - - public static Map.PooledEnumerable GetEntities(Map map, Rectangle2D bounds) => - Map.PooledEnumerable.Instantiate(map, bounds, EntitySelector ?? SelectEntities); - - public static Map.PooledEnumerable GetMobiles(Map map, Rectangle2D bounds) => - GetMobiles(map, bounds); - - public static Map.PooledEnumerable GetMobiles(Map map, Rectangle2D bounds) where T : Mobile => - Map.PooledEnumerable.Instantiate(map, bounds, SelectMobiles); - - public static Map.PooledEnumerable GetItems(Map map, Rectangle2D bounds) where T : Item => - Map.PooledEnumerable.Instantiate(map, bounds, SelectItems); - - public static Map.PooledEnumerable GetMultis(Map map, Rectangle2D bounds) => - Map.PooledEnumerable.Instantiate(map, bounds, MultiSelector ?? SelectMultis); - - public static Map.PooledEnumerable GetMultiTiles(Map map, Rectangle2D bounds) => - Map.PooledEnumerable.Instantiate(map, bounds, MultiTileSelector ?? SelectMultiTiles); - - public static IEnumerable EnumerateSectors(Map map, Rectangle2D bounds) - { - if (map == null || map == Map.Internal) - { - yield break; - } - - var x1 = bounds.Start.X; - var y1 = bounds.Start.Y; - var x2 = bounds.End.X; - var y2 = bounds.End.Y; - - if (!Bound(map, ref x1, ref y1, ref x2, ref y2, out var xSector, out var ySector)) - { - yield break; - } - - var index = 0; - - while (NextSector(map, x1, y1, x2, y2, ref index, ref xSector, ref ySector, out var s)) - { - yield return s; - } - } - - public static bool Bound( - Map map, - ref int x1, - ref int y1, - ref int x2, - ref int y2, - out int xSector, - out int ySector - ) - { - if (map == null || map == Map.Internal) - { - xSector = ySector = 0; - return false; - } - - map.Bound(x1, y1, out x1, out y1); - map.Bound(x2 - 1, y2 - 1, out x2, out y2); - - x1 >>= Map.SectorShift; - y1 >>= Map.SectorShift; - x2 >>= Map.SectorShift; - y2 >>= Map.SectorShift; - - xSector = x1; - ySector = y1; - - return true; - } - - private static bool NextSector( - Map map, - int x1, - int y1, - int x2, - int y2, - ref int index, - ref int xSector, - ref int ySector, - out Sector s - ) - { - if (map == null) - { - s = null; - xSector = ySector = 0; - return false; - } - - if (map == Map.Internal) - { - s = map.InvalidSector; - xSector = ySector = 0; - return false; - } - - if (index++ > 0) - { - if (++ySector > y2) - { - ySector = y1; - - if (++xSector > x2) - { - xSector = x1; - - s = map.InvalidSector; - return false; - } - } - } - - s = map.GetRealSector(xSector, ySector); - return true; - } } - [Parsable] - public sealed class Map : IComparable + public static Map.PooledEnumerable GetClients(Map map, Rectangle2D bounds) => + Map.PooledEnumerable.Instantiate(map, bounds, ClientSelector ?? SelectClients); + + public static Map.PooledEnumerable GetEntities(Map map, Rectangle2D bounds) => + Map.PooledEnumerable.Instantiate(map, bounds, EntitySelector ?? SelectEntities); + + public static Map.PooledEnumerable GetMobiles(Map map, Rectangle2D bounds) => + GetMobiles(map, bounds); + + public static Map.PooledEnumerable GetMobiles(Map map, Rectangle2D bounds) where T : Mobile => + Map.PooledEnumerable.Instantiate(map, bounds, SelectMobiles); + + public static Map.PooledEnumerable GetItems(Map map, Rectangle2D bounds) where T : Item => + Map.PooledEnumerable.Instantiate(map, bounds, SelectItems); + + public static Map.PooledEnumerable GetMultis(Map map, Rectangle2D bounds) => + Map.PooledEnumerable.Instantiate(map, bounds, MultiSelector ?? SelectMultis); + + public static Map.PooledEnumerable GetMultiTiles(Map map, Rectangle2D bounds) => + Map.PooledEnumerable.Instantiate(map, bounds, MultiTileSelector ?? SelectMultiTiles); + + public static IEnumerable EnumerateSectors(Map map, Rectangle2D bounds) { - public const int SectorSize = 16; - public const int SectorShift = 4; - public const int SectorActiveRange = 2; - - private static ILogger _logger; - private static ILogger Logger => _logger ??= LogFactory.GetLogger(typeof(Map)); - - private readonly int m_FileIndex; - private readonly Sector[][] m_Sectors; - private readonly int m_SectorsHeight; - - private readonly int m_SectorsWidth; - - private readonly object tileLock = new(); - private Region m_DefaultRegion; - - private string m_Name; - - private TileMatrix m_Tiles; - - public Map(int mapID, int mapIndex, int fileIndex, int width, int height, int season, string name, MapRules rules) + if (map == null || map == Map.Internal) { - MapID = mapID; - MapIndex = mapIndex; - m_FileIndex = fileIndex; - Width = width; - Height = height; - Season = season; - m_Name = name; - Rules = rules; - Regions = new Dictionary(StringComparer.OrdinalIgnoreCase); - InvalidSector = new Sector(0, 0, this); - m_SectorsWidth = width >> SectorShift; - m_SectorsHeight = height >> SectorShift; - m_Sectors = new Sector[m_SectorsWidth][]; + yield break; } - public static Map[] Maps { get; } = new Map[0x100]; + var x1 = bounds.Start.X; + var y1 = bounds.Start.Y; + var x2 = bounds.End.X; + var y2 = bounds.End.Y; - public static Map Felucca => Maps[0]; - public static Map Trammel => Maps[1]; - public static Map Ilshenar => Maps[2]; - public static Map Malas => Maps[3]; - public static Map Tokuno => Maps[4]; - public static Map TerMur => Maps[5]; - public static Map Internal => Maps[0x7F]; - - public static List AllMaps { get; } = new(); - - public int Season { get; set; } - - public TileMatrix Tiles + if (!Bound(map, ref x1, ref y1, ref x2, ref y2, out var xSector, out var ySector)) { - get - { - if (m_Tiles == null) - { - lock (tileLock) - { - m_Tiles = new TileMatrix(this, m_FileIndex, MapID, Width, Height); - } - } + yield break; + } - return m_Tiles; + var index = 0; + + while (NextSector(map, x1, y1, x2, y2, ref index, ref xSector, ref ySector, out var s)) + { + yield return s; + } + } + + public static bool Bound( + Map map, + ref int x1, + ref int y1, + ref int x2, + ref int y2, + out int xSector, + out int ySector + ) + { + if (map == null || map == Map.Internal) + { + xSector = ySector = 0; + return false; + } + + map.Bound(x1, y1, out x1, out y1); + map.Bound(x2 - 1, y2 - 1, out x2, out y2); + + x1 >>= Map.SectorShift; + y1 >>= Map.SectorShift; + x2 >>= Map.SectorShift; + y2 >>= Map.SectorShift; + + xSector = x1; + ySector = y1; + + return true; + } + + private static bool NextSector( + Map map, + int x1, + int y1, + int x2, + int y2, + ref int index, + ref int xSector, + ref int ySector, + out Sector s + ) + { + if (map == null) + { + s = null; + xSector = ySector = 0; + return false; + } + + if (map == Map.Internal) + { + s = map.InvalidSector; + xSector = ySector = 0; + return false; + } + + if (index++ > 0) + { + if (++ySector > y2) + { + ySector = y1; + + if (++xSector > x2) + { + xSector = x1; + + s = map.InvalidSector; + return false; + } } } - public int MapID { get; } + s = map.GetRealSector(xSector, ySector); + return true; + } +} - public int MapIndex { get; } +[Parsable] +public sealed class Map : IComparable +{ + public const int SectorSize = 16; + public const int SectorShift = 4; + public const int SectorActiveRange = 2; - public int Width { get; } + private static ILogger _logger; + private static ILogger Logger => _logger ??= LogFactory.GetLogger(typeof(Map)); - public int Height { get; } + private readonly int m_FileIndex; + private readonly Sector[][] m_Sectors; + private readonly int m_SectorsHeight; - public Dictionary Regions { get; } + private readonly int m_SectorsWidth; - public Region DefaultRegion + private readonly object tileLock = new(); + private Region m_DefaultRegion; + + private string m_Name; + + private TileMatrix m_Tiles; + + public Map(int mapID, int mapIndex, int fileIndex, int width, int height, int season, string name, MapRules rules) + { + MapID = mapID; + MapIndex = mapIndex; + m_FileIndex = fileIndex; + Width = width; + Height = height; + Season = season; + m_Name = name; + Rules = rules; + Regions = new Dictionary(StringComparer.OrdinalIgnoreCase); + InvalidSector = new Sector(0, 0, this); + m_SectorsWidth = width >> SectorShift; + m_SectorsHeight = height >> SectorShift; + m_Sectors = new Sector[m_SectorsWidth][]; + } + + public static Map[] Maps { get; } = new Map[0x100]; + + public static Map Felucca => Maps[0]; + public static Map Trammel => Maps[1]; + public static Map Ilshenar => Maps[2]; + public static Map Malas => Maps[3]; + public static Map Tokuno => Maps[4]; + public static Map TerMur => Maps[5]; + public static Map Internal => Maps[0x7F]; + + public static List AllMaps { get; } = new(); + + public int Season { get; set; } + + public TileMatrix Tiles + { + get { - get => m_DefaultRegion ??= new Region(null, this, 0, Array.Empty()); - set => m_DefaultRegion = value; - } - - public MapRules Rules { get; set; } - - public Sector InvalidSector { get; } - - public string Name - { - get + if (m_Tiles == null) { - if (this == Internal && m_Name != "Internal") + lock (tileLock) { - Logger.Warning($"Internal map name was '{m_Name}'\n{new StackTrace()}"); - m_Name = "Internal"; + m_Tiles = new TileMatrix(this, m_FileIndex, MapID, Width, Height); } - - return m_Name; } - set + + return m_Tiles; + } + } + + public int MapID { get; } + + public int MapIndex { get; } + + public int Width { get; } + + public int Height { get; } + + public Dictionary Regions { get; } + + public Region DefaultRegion + { + get => m_DefaultRegion ??= new Region(null, this, 0, Array.Empty()); + set => m_DefaultRegion = value; + } + + public MapRules Rules { get; set; } + + public Sector InvalidSector { get; } + + public string Name + { + get + { + if (this == Internal && m_Name != "Internal") { - if (this == Internal && value != "Internal") - { - Logger.Warning($"Attempted to set internal map name to '{value}'\n{new StackTrace()}"); + Logger.Warning($"Internal map name was '{m_Name}'\n{new StackTrace()}"); + m_Name = "Internal"; + } - value = "Internal"; - } + return m_Name; + } + set + { + if (this == Internal && value != "Internal") + { + Logger.Warning($"Attempted to set internal map name to '{value}'\n{new StackTrace()}"); - m_Name = value; + value = "Internal"; + } + + m_Name = value; + } + } + + public static int[] InvalidLandTiles { get; set; } = { 0x244 }; + + public static int MaxLOSDistance { get; set; } = 25; + + public int CompareTo(Map other) => other == null ? -1 : MapID.CompareTo(other.MapID); + + public static string[] GetMapNames() + { + var mapCount = 0; + for (var i = 0; i < Maps.Length; i++) + { + var map = Maps[i]; + if (map != null) + { + mapCount++; } } - public static int[] InvalidLandTiles { get; set; } = { 0x244 }; - - public static int MaxLOSDistance { get; set; } = 25; - - public int CompareTo(Map other) => other == null ? -1 : MapID.CompareTo(other.MapID); - - public static string[] GetMapNames() + var mapNames = new string[mapCount]; + for (int i = 0, mIndex = 0; i < Maps.Length; i++) { - var mapCount = 0; - for (var i = 0; i < Maps.Length; i++) + var map = Maps[i]; + if (map != null) { - var map = Maps[i]; - if (map != null) - { - mapCount++; - } + mapNames[mIndex++] = map.Name; } - - var mapNames = new string[mapCount]; - for (int i = 0, mIndex = 0; i < Maps.Length; i++) - { - var map = Maps[i]; - if (map != null) - { - mapNames[mIndex++] = map.Name; - } - } - - return mapNames; } - public static Map[] GetMapValues() + return mapNames; + } + + public static Map[] GetMapValues() + { + var mapCount = 0; + for (var i = 0; i < Maps.Length; i++) { - var mapCount = 0; - for (var i = 0; i < Maps.Length; i++) + var map = Maps[i]; + if (map != null) { - var map = Maps[i]; - if (map != null) - { - mapCount++; - } + mapCount++; } - - var mapValues = new Map[mapCount]; - for (int i = 0, mIndex = 0; i < Maps.Length; i++) - { - var map = Maps[i]; - if (map != null) - { - mapValues[mIndex++] = map; - } - } - - return mapValues; } - public static Map Parse(string value) + var mapValues = new Map[mapCount]; + for (int i = 0, mIndex = 0; i < Maps.Length; i++) { - if (string.IsNullOrWhiteSpace(value)) + var map = Maps[i]; + if (map != null) { - return null; + mapValues[mIndex++] = map; } + } - if (value.InsensitiveEquals("Internal")) - { - return Internal; - } - - if (!int.TryParse(value, out var index)) - { - index = -1; - } - else if (index == 127) - { - return Internal; - } - - for (int i = 0; i < Maps.Length; i++) - { - var map = Maps[i]; - if (map == null) - { - continue; - } - - if (index >= 0 && map.MapIndex == index || map.Name.InsensitiveEquals(value)) - { - return map; - } - } + return mapValues; + } + public static Map Parse(string value) + { + if (string.IsNullOrWhiteSpace(value)) + { return null; } - public override string ToString() => Name; - - public int GetAverageZ(int x, int y) + if (value.InsensitiveEquals("Internal")) { - GetAverageZ(x, y, out _, out var avg, out _); - return avg; + return Internal; } - public void GetAverageZ(int x, int y, out int z, out int avg, out int top) + if (!int.TryParse(value, out var index)) { - var zTop = Tiles.GetLandTile(x, y).Z; - var zLeft = Tiles.GetLandTile(x, y + 1).Z; - var zRight = Tiles.GetLandTile(x + 1, y).Z; - var zBottom = Tiles.GetLandTile(x + 1, y + 1).Z; - - z = zTop; - if (zLeft < z) - { - z = zLeft; - } - - if (zRight < z) - { - z = zRight; - } - - if (zBottom < z) - { - z = zBottom; - } - - top = zTop; - if (zLeft > top) - { - top = zLeft; - } - - if (zRight > top) - { - top = zRight; - } - - if (zBottom > top) - { - top = zBottom; - } - - avg = (zTop - zBottom).Abs() > (zLeft - zRight).Abs() - ? FloorAverage(zLeft, zRight) - : FloorAverage(zTop, zBottom); + index = -1; + } + else if (index == 127) + { + return Internal; } - private static int FloorAverage(int a, int b) + for (int i = 0; i < Maps.Length; i++) { - var v = a + b; - - if (v < 0) + var map = Maps[i]; + if (map == null) { - --v; + continue; } - return v / 2; + if (index >= 0 && map.MapIndex == index || map.Name.InsensitiveEquals(value)) + { + return map; + } } - public IPooledEnumerable GetMultiTilesAt(int x, int y) => - PooledEnumeration.GetMultiTiles(this, new Rectangle2D(x, y, 1, 1)); + return null; + } - private static void AcquireFixItems(Map map, int x, int y, Item[] pool, out int length) + public override string ToString() => Name; + + public int GetAverageZ(int x, int y) + { + GetAverageZ(x, y, out _, out var avg, out _); + return avg; + } + + public void GetAverageZ(int x, int y, out int z, out int avg, out int top) + { + var zTop = Tiles.GetLandTile(x, y).Z; + var zLeft = Tiles.GetLandTile(x, y + 1).Z; + var zRight = Tiles.GetLandTile(x + 1, y).Z; + var zBottom = Tiles.GetLandTile(x + 1, y + 1).Z; + + z = zTop; + if (zLeft < z) { - length = 0; - if (map == null || map == Internal || x < 0 || x > map.Width || y < 0 || y > map.Height) - { - return; - } + z = zLeft; + } - var eable = map.GetItemsInRange(new Point3D(x, y, 0), 0); - foreach (var item in eable) + if (zRight < z) + { + z = zRight; + } + + if (zBottom < z) + { + z = zBottom; + } + + top = zTop; + if (zLeft > top) + { + top = zLeft; + } + + if (zRight > top) + { + top = zRight; + } + + if (zBottom > top) + { + top = zBottom; + } + + avg = (zTop - zBottom).Abs() > (zLeft - zRight).Abs() + ? FloorAverage(zLeft, zRight) + : FloorAverage(zTop, zBottom); + } + + private static int FloorAverage(int a, int b) + { + var v = a + b; + + if (v < 0) + { + --v; + } + + return v / 2; + } + + public IPooledEnumerable GetMultiTilesAt(int x, int y) => + PooledEnumeration.GetMultiTiles(this, new Rectangle2D(x, y, 1, 1)); + + private static void AcquireFixItems(Map map, int x, int y, Item[] pool, out int length) + { + length = 0; + if (map == null || map == Internal || x < 0 || x > map.Width || y < 0 || y > map.Height) + { + return; + } + + var eable = map.GetItemsInRange(new Point3D(x, y, 0), 0); + foreach (var item in eable) + { + if (item is not BaseMulti && item.ItemID <= TileData.MaxItemValue) { - if (item is not BaseMulti && item.ItemID <= TileData.MaxItemValue) + if (length == 128) { - if (length == 128) - { - break; - } + break; + } - pool[length++] = item; + pool[length++] = item; + } + } + + eable.Free(); + + Array.Sort(pool, 0, length, ZComparer.Default); + } + + public void FixColumn(int x, int y) + { + var landTile = Tiles.GetLandTile(x, y); + var tiles = Tiles.GetStaticTiles(x, y, true); + + GetAverageZ(x, y, out _, out var landAvg, out _); + + var items = STArrayPool.Shared.Rent(128); + AcquireFixItems(this, x, y, items, out var length); + + for (var i = 0; i < length; i++) + { + var toFix = items[i]; + + if (!toFix.Movable) + { + continue; + } + + var z = int.MinValue; + var currentZ = toFix.Z; + + if (!landTile.Ignored && landAvg <= currentZ) + { + z = landAvg; + } + + foreach (var tile in tiles) + { + var id = TileData.ItemTable[tile.ID & TileData.MaxItemValue]; + + var checkZ = tile.Z; + var checkTop = checkZ + id.CalcHeight; + + if (checkTop == checkZ && !id.Surface) + { + ++checkTop; + } + + if (checkTop > z && checkTop <= currentZ) + { + z = checkTop; } } - eable.Free(); - - Array.Sort(pool, 0, length, ZComparer.Default); - } - - public void FixColumn(int x, int y) - { - var landTile = Tiles.GetLandTile(x, y); - var tiles = Tiles.GetStaticTiles(x, y, true); - - GetAverageZ(x, y, out _, out var landAvg, out _); - - var items = ArrayPool.Shared.Rent(128); - AcquireFixItems(this, x, y, items, out var length); - - for (var i = 0; i < length; i++) + for (var j = 0; j < length; ++j) { - var toFix = items[i]; - - if (!toFix.Movable) + if (j == i) { continue; } - var z = int.MinValue; - var currentZ = toFix.Z; + var item = items[j]; + var id = item.ItemData; - if (!landTile.Ignored && landAvg <= currentZ) + var checkZ = item.Z; + var checkTop = checkZ + id.CalcHeight; + + if (checkTop == checkZ && !id.Surface) { - z = landAvg; + ++checkTop; } - foreach (var tile in tiles) + if (checkTop > z && checkTop <= currentZ) { - var id = TileData.ItemTable[tile.ID & TileData.MaxItemValue]; - - var checkZ = tile.Z; - var checkTop = checkZ + id.CalcHeight; - - if (checkTop == checkZ && !id.Surface) - { - ++checkTop; - } - - if (checkTop > z && checkTop <= currentZ) - { - z = checkTop; - } - } - - for (var j = 0; j < length; ++j) - { - if (j == i) - { - continue; - } - - var item = items[j]; - var id = item.ItemData; - - var checkZ = item.Z; - var checkTop = checkZ + id.CalcHeight; - - if (checkTop == checkZ && !id.Surface) - { - ++checkTop; - } - - if (checkTop > z && checkTop <= currentZ) - { - z = checkTop; - } - } - - if (z != int.MinValue) - { - toFix.Location = new Point3D(toFix.X, toFix.Y, z); + z = checkTop; } } - ArrayPool.Shared.Return(items, true); - } - - /* This could probably be re-implemented if necessary (perhaps via an ITile interface?). - public List GetTilesAt( Point2D p, bool items, bool land, bool statics ) - { - List list = new List(); - - if (this == Internal) - return list; - - if (land) - list.Add( Tiles.GetLandTile( p.m_X, p.m_Y ) ); - - if (statics) - list.AddRange( Tiles.GetStaticTiles( p.m_X, p.m_Y, true ) ); - - if (items) - { - Sector sector = GetSector( p ); - - foreach ( Item item in sector.Items ) - if (item.AtWorldPoint( p.m_X, p.m_Y )) - list.Add( new StaticTile( (ushort)item.ItemID, (sbyte) item.Z ) ); - } - - return list; - } - */ - - /// - /// Gets the highest surface that is lower than . - /// - /// The reference point. - /// A surface or . - public object GetTopSurface(Point3D p) - { - if (this == Internal) + if (z != int.MinValue) { - return null; + toFix.Location = new Point3D(toFix.X, toFix.Y, z); } + } - object surface = null; - var surfaceZ = int.MinValue; + STArrayPool.Shared.Return(items, true); + } - var lt = Tiles.GetLandTile(p.X, p.Y); + /* This could probably be re-implemented if necessary (perhaps via an ITile interface?). + public List GetTilesAt( Point2D p, bool items, bool land, bool statics ) + { + List list = new List(); - if (!lt.Ignored) + if (this == Internal) + return list; + + if (land) + list.Add( Tiles.GetLandTile( p.m_X, p.m_Y ) ); + + if (statics) + list.AddRange( Tiles.GetStaticTiles( p.m_X, p.m_Y, true ) ); + + if (items) + { + Sector sector = GetSector( p ); + + foreach ( Item item in sector.Items ) + if (item.AtWorldPoint( p.m_X, p.m_Y )) + list.Add( new StaticTile( (ushort)item.ItemID, (sbyte) item.Z ) ); + } + + return list; + } + */ + + /// + /// Gets the highest surface that is lower than . + /// + /// The reference point. + /// A surface or . + public object GetTopSurface(Point3D p) + { + if (this == Internal) + { + return null; + } + + object surface = null; + var surfaceZ = int.MinValue; + + var lt = Tiles.GetLandTile(p.X, p.Y); + + if (!lt.Ignored) + { + var avgZ = GetAverageZ(p.X, p.Y); + + if (avgZ <= p.Z) { - var avgZ = GetAverageZ(p.X, p.Y); + surface = lt; + surfaceZ = avgZ; - if (avgZ <= p.Z) + if (surfaceZ == p.Z) { - surface = lt; - surfaceZ = avgZ; + return surface; + } + } + } + + var staticTiles = Tiles.GetStaticTiles(p.X, p.Y, true); + + for (var i = 0; i < staticTiles.Length; i++) + { + var tile = staticTiles[i]; + var id = TileData.ItemTable[tile.ID & TileData.MaxItemValue]; + + if (id.Surface || id.Wet) + { + var tileZ = tile.Z + id.CalcHeight; + + if (tileZ > surfaceZ && tileZ <= p.Z) + { + surface = tile; + surfaceZ = tileZ; if (surfaceZ == p.Z) { @@ -753,22 +776,27 @@ namespace Server } } } + } - var staticTiles = Tiles.GetStaticTiles(p.X, p.Y, true); + var sector = GetSector(p.X, p.Y); - for (var i = 0; i < staticTiles.Length; i++) + for (var i = 0; i < sector.Items.Count; i++) + { + var item = sector.Items[i]; + + if (item is not BaseMulti && item.ItemID <= TileData.MaxItemValue && item.AtWorldPoint(p.X, p.Y) && + !item.Movable) { - var tile = staticTiles[i]; - var id = TileData.ItemTable[tile.ID & TileData.MaxItemValue]; + var id = item.ItemData; if (id.Surface || id.Wet) { - var tileZ = tile.Z + id.CalcHeight; + var itemZ = item.Z + id.CalcHeight; - if (tileZ > surfaceZ && tileZ <= p.Z) + if (itemZ > surfaceZ && itemZ <= p.Z) { - surface = tile; - surfaceZ = tileZ; + surface = item; + surfaceZ = itemZ; if (surfaceZ == p.Z) { @@ -777,913 +805,884 @@ namespace Server } } } + } - var sector = GetSector(p.X, p.Y); + return surface; + } - for (var i = 0; i < sector.Items.Count; i++) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Bound(int x, int y, out int newX, out int newY) + { + newX = Math.Clamp(x, 0, Width - 1); + newY = Math.Clamp(y, 0, Height - 1); + } + + public Point2D Bound(Point3D p) + { + Bound(p.m_X, p.m_Y, out var x, out var y); + return new Point2D(x, y); + } + + public Point2D Bound(Point2D p) + { + Bound(p.m_X, p.m_Y, out var x, out var y); + return new Point2D(x, y); + } + + public void ActivateSectors(int cx, int cy) + { + for (var x = cx - SectorActiveRange; x <= cx + SectorActiveRange; ++x) + { + for (var y = cy - SectorActiveRange; y <= cy + SectorActiveRange; ++y) { - var item = sector.Items[i]; - - if (item is not BaseMulti && item.ItemID <= TileData.MaxItemValue && item.AtWorldPoint(p.X, p.Y) && - !item.Movable) + var sect = GetRealSector(x, y); + if (sect != InvalidSector) { - var id = item.ItemData; - - if (id.Surface || id.Wet) - { - var itemZ = item.Z + id.CalcHeight; - - if (itemZ > surfaceZ && itemZ <= p.Z) - { - surface = item; - surfaceZ = itemZ; - - if (surfaceZ == p.Z) - { - return surface; - } - } - } + sect.Activate(); } } - - return surface; } + } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Bound(int x, int y, out int newX, out int newY) + public void DeactivateSectors(int cx, int cy) + { + for (var x = cx - SectorActiveRange; x <= cx + SectorActiveRange; ++x) { - newX = Math.Clamp(x, 0, Width - 1); - newY = Math.Clamp(y, 0, Height - 1); - } - - public Point2D Bound(Point3D p) - { - Bound(p.m_X, p.m_Y, out var x, out var y); - return new Point2D(x, y); - } - - public Point2D Bound(Point2D p) - { - Bound(p.m_X, p.m_Y, out var x, out var y); - return new Point2D(x, y); - } - - public void ActivateSectors(int cx, int cy) - { - for (var x = cx - SectorActiveRange; x <= cx + SectorActiveRange; ++x) + for (var y = cy - SectorActiveRange; y <= cy + SectorActiveRange; ++y) { - for (var y = cy - SectorActiveRange; y <= cy + SectorActiveRange; ++y) + var sect = GetRealSector(x, y); + if (sect != InvalidSector && !PlayersInRange(sect, SectorActiveRange)) { - var sect = GetRealSector(x, y); - if (sect != InvalidSector) - { - sect.Activate(); - } + sect.Deactivate(); + } + } + } + } + + private bool PlayersInRange(Sector sect, int range) + { + for (var x = sect.X - range; x <= sect.X + range; ++x) + { + for (var y = sect.Y - range; y <= sect.Y + range; ++y) + { + var check = GetRealSector(x, y); + if (check != InvalidSector && check.Clients.Count > 0) + { + return true; } } } - public void DeactivateSectors(int cx, int cy) + return false; + } + + public void OnClientChange(NetState oldState, NetState newState, Mobile m) + { + if (this != Internal) { - for (var x = cx - SectorActiveRange; x <= cx + SectorActiveRange; ++x) - { - for (var y = cy - SectorActiveRange; y <= cy + SectorActiveRange; ++y) - { - var sect = GetRealSector(x, y); - if (sect != InvalidSector && !PlayersInRange(sect, SectorActiveRange)) - { - sect.Deactivate(); - } - } - } + GetSector(m.Location).OnClientChange(oldState, newState); + } + } + + public void OnEnter(Mobile m) + { + if (this != Internal) + { + GetSector(m.Location).OnEnter(m); + } + } + + public void OnEnter(Item item) + { + if (this == Internal) + { + return; } - private bool PlayersInRange(Sector sect, int range) - { - for (var x = sect.X - range; x <= sect.X + range; ++x) - { - for (var y = sect.Y - range; y <= sect.Y + range; ++y) - { - var check = GetRealSector(x, y); - if (check != InvalidSector && check.Clients.Count > 0) - { - return true; - } - } - } + GetSector(item.Location).OnEnter(item); - return false; + if (item is BaseMulti m) + { + var mcl = m.Components; + + var start = GetMultiMinSector(m.Location, mcl); + var end = GetMultiMaxSector(m.Location, mcl); + + AddMulti(m, start, end); + } + } + + public void OnLeave(Mobile m) + { + if (this != Internal) + { + GetSector(m.Location).OnLeave(m); + } + } + + public void OnLeave(Item item) + { + if (this == Internal) + { + return; } - public void OnClientChange(NetState oldState, NetState newState, Mobile m) + GetSector(item.Location).OnLeave(item); + + if (item is BaseMulti m) { - if (this != Internal) - { - GetSector(m.Location).OnClientChange(oldState, newState); - } + var mcl = m.Components; + + var start = GetMultiMinSector(m.Location, mcl); + var end = GetMultiMaxSector(m.Location, mcl); + + RemoveMulti(m, start, end); + } + } + + public void RemoveMulti(BaseMulti m, Sector start, Sector end) + { + if (this == Internal) + { + return; } - public void OnEnter(Mobile m) + for (var x = start.X; x <= end.X; ++x) { - if (this != Internal) + for (var y = start.Y; y <= end.Y; ++y) { - GetSector(m.Location).OnEnter(m); + InternalGetSector(x, y).OnMultiLeave(m); } } + } - public void OnEnter(Item item) + public void AddMulti(BaseMulti m, Sector start, Sector end) + { + if (this == Internal) { - if (this == Internal) + return; + } + + for (var x = start.X; x <= end.X; ++x) + { + for (var y = start.Y; y <= end.Y; ++y) { - return; + InternalGetSector(x, y).OnMultiEnter(m); } + } + } - GetSector(item.Location).OnEnter(item); + public Sector GetMultiMinSector(Point3D loc, MultiComponentList mcl) => + GetSector(Bound(new Point2D(loc.m_X + mcl.Min.m_X, loc.m_Y + mcl.Min.m_Y))); - if (item is BaseMulti m) + public Sector GetMultiMaxSector(Point3D loc, MultiComponentList mcl) => + GetSector(Bound(new Point2D(loc.m_X + mcl.Max.m_X, loc.m_Y + mcl.Max.m_Y))); + + public void OnMove(Point3D oldLocation, Mobile m) + { + if (this == Internal) + { + return; + } + + var oldSector = GetSector(oldLocation); + var newSector = GetSector(m.Location); + + if (oldSector != newSector) + { + oldSector.OnLeave(m); + newSector.OnEnter(m); + } + } + + public void OnMove(Point3D oldLocation, Item item) + { + if (this == Internal) + { + return; + } + + var oldSector = GetSector(oldLocation); + var newSector = GetSector(item.Location); + + if (oldSector != newSector) + { + oldSector.OnLeave(item); + newSector.OnEnter(item); + } + + if (item is BaseMulti m) + { + var mcl = m.Components; + + var start = GetMultiMinSector(m.Location, mcl); + var end = GetMultiMaxSector(m.Location, mcl); + + var oldStart = GetMultiMinSector(oldLocation, mcl); + var oldEnd = GetMultiMaxSector(oldLocation, mcl); + + if (oldStart != start || oldEnd != end) { - var mcl = m.Components; - - var start = GetMultiMinSector(m.Location, mcl); - var end = GetMultiMaxSector(m.Location, mcl); - + RemoveMulti(m, oldStart, oldEnd); AddMulti(m, start, end); } } + } - public void OnLeave(Mobile m) + public void RegisterRegion(Region reg) + { + var regName = reg.Name; + + if (regName == null) { - if (this != Internal) - { - GetSector(m.Location).OnLeave(m); - } + return; } - public void OnLeave(Item item) + if (Regions.ContainsKey(regName)) { - if (this == Internal) - { - return; - } + Logger.Warning($"Duplicate region name '{regName}' for map '{Name}'"); + } + else + { + Regions[regName] = reg; + } + } - GetSector(item.Location).OnLeave(item); + public void UnregisterRegion(Region reg) + { + var regName = reg.Name; - if (item is BaseMulti m) - { - var mcl = m.Components; + if (regName != null) + { + Regions.Remove(regName); + } + } - var start = GetMultiMinSector(m.Location, mcl); - var end = GetMultiMaxSector(m.Location, mcl); + public Point3D GetPoint(object o, bool eye) + { + Point3D p; - RemoveMulti(m, start, end); - } + if (o is Mobile mobile) + { + p = mobile.Location; + p.Z += 14; // eye ? 15 : 10; + } + else if (o is Item item) + { + p = item.GetWorldLocation(); + p.Z += item.ItemData.Height / 2 + 1; + } + else if (o is Point3D point3D) + { + p = point3D; + } + else if (o is LandTarget target) + { + p = target.Location; + + GetAverageZ(p.X, p.Y, out _, out _, out var top); + + p.Z = top + 1; + } + else if (o is StaticTarget st) + { + var id = TileData.ItemTable[st.ItemID & TileData.MaxItemValue]; + + p = new Point3D(st.X, st.Y, st.Z - id.CalcHeight + id.Height / 2 + 1); + } + else if (o is IPoint3D d) + { + p = new Point3D(d.X, d.Y, d.Z); + } + else + { + Logger.Warning($"Warning: Invalid object ({o}) in line of sight"); + p = Point3D.Zero; } - public void RemoveMulti(BaseMulti m, Sector start, Sector end) - { - if (this == Internal) - { - return; - } + return p; + } - for (var x = start.X; x <= end.X; ++x) - { - for (var y = start.Y; y <= end.Y; ++y) - { - InternalGetSector(x, y).OnMultiLeave(m); - } - } + public IPooledEnumerable GetObjectsInRange(Point3D p) => GetObjectsInRange(p, Core.GlobalMaxUpdateRange); + + public IPooledEnumerable GetObjectsInRange(Point3D p, int range) => + GetObjectsInBounds(new Rectangle2D(p.m_X - range, p.m_Y - range, range * 2 + 1, range * 2 + 1)); + + public IPooledEnumerable GetObjectsInBounds(Rectangle2D bounds) => + PooledEnumeration.GetEntities(this, bounds); + + public IPooledEnumerable GetClientsInRange(Point3D p) => GetClientsInRange(p, Core.GlobalMaxUpdateRange); + + public IPooledEnumerable GetClientsInRange(Point3D p, int range) => + GetClientsInBounds(new Rectangle2D(p.m_X - range, p.m_Y - range, range * 2 + 1, range * 2 + 1)); + + public IPooledEnumerable GetClientsInBounds(Rectangle2D bounds) => + PooledEnumeration.GetClients(this, bounds); + + public IPooledEnumerable GetItemsInRange(Point3D p) => GetItemsInRange(p, Core.GlobalMaxUpdateRange); + + public IPooledEnumerable GetItemsInRange(Point3D p, int range) => GetItemsInRange(p, range); + + public IPooledEnumerable GetItemsInRange(Point3D p, int range) where T : Item => + GetItemsInBounds(new Rectangle2D(p.m_X - range, p.m_Y - range, range * 2 + 1, range * 2 + 1)); + + public IPooledEnumerable GetItemsInBounds(Rectangle2D bounds) => GetItemsInBounds(bounds); + + public IPooledEnumerable GetItemsInBounds(Rectangle2D bounds) where T : Item => + PooledEnumeration.GetItems(this, bounds); + + public IPooledEnumerable GetMobilesInRange(Point3D p) => GetMobilesInRange(p, Core.GlobalMaxUpdateRange); + + public IPooledEnumerable GetMobilesInRange(Point3D p, int range) => GetMobilesInRange(p, range); + + public IPooledEnumerable GetMobilesInRange(Point3D p, int range) where T : Mobile => + GetMobilesInBounds(new Rectangle2D(p.m_X - range, p.m_Y - range, range * 2 + 1, range * 2 + 1)); + + public IPooledEnumerable GetMobilesInBounds(Rectangle2D bounds) => GetMobilesInBounds(bounds); + + public IPooledEnumerable GetMobilesInBounds(Rectangle2D bounds) where T : Mobile => + PooledEnumeration.GetMobiles(this, bounds); + + public bool CanFit( + Point3D p, int height, bool checkBlocksFit = false, bool checkMobiles = true, + bool requireSurface = true + ) => + CanFit(p.m_X, p.m_Y, p.m_Z, height, checkBlocksFit, checkMobiles, requireSurface); + + public bool CanFit( + Point2D p, int z, int height, bool checkBlocksFit = false, bool checkMobiles = true, + bool requireSurface = true + ) => + CanFit(p.m_X, p.m_Y, z, height, checkBlocksFit, checkMobiles, requireSurface); + + public bool CanFit( + int x, int y, int z, int height, bool checkBlocksFit = false, bool checkMobiles = true, + bool requireSurface = true + ) + { + if (this == Internal) + { + return false; } - public void AddMulti(BaseMulti m, Sector start, Sector end) + if (x < 0 || y < 0 || x >= Width || y >= Height) { - if (this == Internal) - { - return; - } - - for (var x = start.X; x <= end.X; ++x) - { - for (var y = start.Y; y <= end.Y; ++y) - { - InternalGetSector(x, y).OnMultiEnter(m); - } - } + return false; } - public Sector GetMultiMinSector(Point3D loc, MultiComponentList mcl) => - GetSector(Bound(new Point2D(loc.m_X + mcl.Min.m_X, loc.m_Y + mcl.Min.m_Y))); + var hasSurface = false; - public Sector GetMultiMaxSector(Point3D loc, MultiComponentList mcl) => - GetSector(Bound(new Point2D(loc.m_X + mcl.Max.m_X, loc.m_Y + mcl.Max.m_Y))); + var lt = Tiles.GetLandTile(x, y); + GetAverageZ(x, y, out var lowZ, out var avgZ, out _); + var landFlags = TileData.LandTable[lt.ID & TileData.MaxLandValue].Flags; - public void OnMove(Point3D oldLocation, Mobile m) + if ((landFlags & TileFlag.Impassable) != 0 && avgZ > z && z + height > lowZ) { - if (this == Internal) - { - return; - } - - var oldSector = GetSector(oldLocation); - var newSector = GetSector(m.Location); - - if (oldSector != newSector) - { - oldSector.OnLeave(m); - newSector.OnEnter(m); - } + return false; } - public void OnMove(Point3D oldLocation, Item item) + if ((landFlags & TileFlag.Impassable) == 0 && z == avgZ && !lt.Ignored) { - if (this == Internal) - { - return; - } - - var oldSector = GetSector(oldLocation); - var newSector = GetSector(item.Location); - - if (oldSector != newSector) - { - oldSector.OnLeave(item); - newSector.OnEnter(item); - } - - if (item is BaseMulti m) - { - var mcl = m.Components; - - var start = GetMultiMinSector(m.Location, mcl); - var end = GetMultiMaxSector(m.Location, mcl); - - var oldStart = GetMultiMinSector(oldLocation, mcl); - var oldEnd = GetMultiMaxSector(oldLocation, mcl); - - if (oldStart != start || oldEnd != end) - { - RemoveMulti(m, oldStart, oldEnd); - AddMulti(m, start, end); - } - } + hasSurface = true; } - public void RegisterRegion(Region reg) + var staticTiles = Tiles.GetStaticTiles(x, y, true); + + bool surface, impassable; + + for (var i = 0; i < staticTiles.Length; ++i) { - var regName = reg.Name; + var id = TileData.ItemTable[staticTiles[i].ID & TileData.MaxItemValue]; + surface = id.Surface; + impassable = id.Impassable; - if (regName == null) - { - return; - } - - if (Regions.ContainsKey(regName)) - { - Logger.Warning($"Duplicate region name '{regName}' for map '{Name}'"); - } - else - { - Regions[regName] = reg; - } - } - - public void UnregisterRegion(Region reg) - { - var regName = reg.Name; - - if (regName != null) - { - Regions.Remove(regName); - } - } - - public Point3D GetPoint(object o, bool eye) - { - Point3D p; - - if (o is Mobile mobile) - { - p = mobile.Location; - p.Z += 14; // eye ? 15 : 10; - } - else if (o is Item item) - { - p = item.GetWorldLocation(); - p.Z += item.ItemData.Height / 2 + 1; - } - else if (o is Point3D point3D) - { - p = point3D; - } - else if (o is LandTarget target) - { - p = target.Location; - - GetAverageZ(p.X, p.Y, out _, out _, out var top); - - p.Z = top + 1; - } - else if (o is StaticTarget st) - { - var id = TileData.ItemTable[st.ItemID & TileData.MaxItemValue]; - - p = new Point3D(st.X, st.Y, st.Z - id.CalcHeight + id.Height / 2 + 1); - } - else if (o is IPoint3D d) - { - p = new Point3D(d.X, d.Y, d.Z); - } - else - { - Logger.Warning($"Warning: Invalid object ({o}) in line of sight"); - p = Point3D.Zero; - } - - return p; - } - - public IPooledEnumerable GetObjectsInRange(Point3D p) => GetObjectsInRange(p, Core.GlobalMaxUpdateRange); - - public IPooledEnumerable GetObjectsInRange(Point3D p, int range) => - GetObjectsInBounds(new Rectangle2D(p.m_X - range, p.m_Y - range, range * 2 + 1, range * 2 + 1)); - - public IPooledEnumerable GetObjectsInBounds(Rectangle2D bounds) => - PooledEnumeration.GetEntities(this, bounds); - - public IPooledEnumerable GetClientsInRange(Point3D p) => GetClientsInRange(p, Core.GlobalMaxUpdateRange); - - public IPooledEnumerable GetClientsInRange(Point3D p, int range) => - GetClientsInBounds(new Rectangle2D(p.m_X - range, p.m_Y - range, range * 2 + 1, range * 2 + 1)); - - public IPooledEnumerable GetClientsInBounds(Rectangle2D bounds) => - PooledEnumeration.GetClients(this, bounds); - - public IPooledEnumerable GetItemsInRange(Point3D p) => GetItemsInRange(p, Core.GlobalMaxUpdateRange); - - public IPooledEnumerable GetItemsInRange(Point3D p, int range) => GetItemsInRange(p, range); - - public IPooledEnumerable GetItemsInRange(Point3D p, int range) where T : Item => - GetItemsInBounds(new Rectangle2D(p.m_X - range, p.m_Y - range, range * 2 + 1, range * 2 + 1)); - - public IPooledEnumerable GetItemsInBounds(Rectangle2D bounds) => GetItemsInBounds(bounds); - - public IPooledEnumerable GetItemsInBounds(Rectangle2D bounds) where T : Item => - PooledEnumeration.GetItems(this, bounds); - - public IPooledEnumerable GetMobilesInRange(Point3D p) => GetMobilesInRange(p, Core.GlobalMaxUpdateRange); - - public IPooledEnumerable GetMobilesInRange(Point3D p, int range) => GetMobilesInRange(p, range); - - public IPooledEnumerable GetMobilesInRange(Point3D p, int range) where T : Mobile => - GetMobilesInBounds(new Rectangle2D(p.m_X - range, p.m_Y - range, range * 2 + 1, range * 2 + 1)); - - public IPooledEnumerable GetMobilesInBounds(Rectangle2D bounds) => GetMobilesInBounds(bounds); - - public IPooledEnumerable GetMobilesInBounds(Rectangle2D bounds) where T : Mobile => - PooledEnumeration.GetMobiles(this, bounds); - - public bool CanFit( - Point3D p, int height, bool checkBlocksFit = false, bool checkMobiles = true, - bool requireSurface = true - ) => - CanFit(p.m_X, p.m_Y, p.m_Z, height, checkBlocksFit, checkMobiles, requireSurface); - - public bool CanFit( - Point2D p, int z, int height, bool checkBlocksFit = false, bool checkMobiles = true, - bool requireSurface = true - ) => - CanFit(p.m_X, p.m_Y, z, height, checkBlocksFit, checkMobiles, requireSurface); - - public bool CanFit( - int x, int y, int z, int height, bool checkBlocksFit = false, bool checkMobiles = true, - bool requireSurface = true - ) - { - if (this == Internal) + if ((surface || impassable) && staticTiles[i].Z + id.CalcHeight > z && z + height > staticTiles[i].Z) { return false; } - if (x < 0 || y < 0 || x >= Width || y >= Height) - { - return false; - } - - var hasSurface = false; - - var lt = Tiles.GetLandTile(x, y); - GetAverageZ(x, y, out var lowZ, out var avgZ, out _); - var landFlags = TileData.LandTable[lt.ID & TileData.MaxLandValue].Flags; - - if ((landFlags & TileFlag.Impassable) != 0 && avgZ > z && z + height > lowZ) - { - return false; - } - - if ((landFlags & TileFlag.Impassable) == 0 && z == avgZ && !lt.Ignored) + if (surface && !impassable && z == staticTiles[i].Z + id.CalcHeight) { hasSurface = true; } + } - var staticTiles = Tiles.GetStaticTiles(x, y, true); + var sector = GetSector(x, y); + var items = sector.Items; + var mobs = sector.Mobiles; - bool surface, impassable; + for (var i = 0; i < items.Count; ++i) + { + var item = items[i]; - for (var i = 0; i < staticTiles.Length; ++i) + if (item is not BaseMulti && item.ItemID <= TileData.MaxItemValue && item.AtWorldPoint(x, y)) { - var id = TileData.ItemTable[staticTiles[i].ID & TileData.MaxItemValue]; + var id = item.ItemData; surface = id.Surface; impassable = id.Impassable; - if ((surface || impassable) && staticTiles[i].Z + id.CalcHeight > z && z + height > staticTiles[i].Z) + if ((surface || impassable || checkBlocksFit && item.BlocksFit) && item.Z + id.CalcHeight > z && + z + height > item.Z) { return false; } - if (surface && !impassable && z == staticTiles[i].Z + id.CalcHeight) + if (surface && !impassable && !item.Movable && z == item.Z + id.CalcHeight) { hasSurface = true; } } - - var sector = 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)) - { - var id = item.ItemData; - surface = id.Surface; - impassable = id.Impassable; - - if ((surface || impassable || checkBlocksFit && item.BlocksFit) && item.Z + id.CalcHeight > z && - z + height > item.Z) - { - return false; - } - - if (surface && !impassable && !item.Movable && z == item.Z + id.CalcHeight) - { - hasSurface = true; - } - } - } - - if (checkMobiles) - { - for (var i = 0; i < mobs.Count; ++i) - { - var m = mobs[i]; - - if (m.Location.m_X == x && m.Location.m_Y == y && (m.AccessLevel == AccessLevel.Player || !m.Hidden) && - m.Z + 16 > z && z + height > m.Z) - { - return false; - } - } - } - - return !requireSurface || hasSurface; } - public bool CanSpawnMobile(Point3D p) => CanSpawnMobile(p.m_X, p.m_Y, p.m_Z); - - public bool CanSpawnMobile(Point2D p, int z) => CanSpawnMobile(p.m_X, p.m_Y, z); - - public bool CanSpawnMobile(int x, int y, int z) => - Region.Find(new Point3D(x, y, z), this).AllowSpawn() && CanFit(x, y, z, 16); - - private class ZComparer : IComparer + if (checkMobiles) { - public static readonly ZComparer Default = new(); - - public int Compare(Item x, Item y) => x!.Z.CompareTo(y!.Z); - } - - public Sector GetSector(Point3D p) => InternalGetSector(p.m_X >> SectorShift, p.m_Y >> SectorShift); - - public Sector GetSector(Point2D p) => InternalGetSector(p.m_X >> SectorShift, p.m_Y >> SectorShift); - - // public Sector GetSector(IPoint2D p) => InternalGetSector(p.X >> SectorShift, p.Y >> SectorShift); - - public Sector GetSector(int x, int y) => InternalGetSector(x >> SectorShift, y >> SectorShift); - - public Sector GetRealSector(int x, int y) => InternalGetSector(x, y); - - private Sector InternalGetSector(int x, int y) - { - if (x >= 0 && x < m_SectorsWidth && y >= 0 && y < m_SectorsHeight) + for (var i = 0; i < mobs.Count; ++i) { - var xSectors = m_Sectors[x]; + var m = mobs[i]; - if (xSectors == null) - { - m_Sectors[x] = xSectors = new Sector[m_SectorsHeight]; - } - - var sec = xSectors[y]; - - if (sec == null) - { - xSectors[y] = sec = new Sector(x, y, this); - } - - return sec; - } - - return InvalidSector; - } - - public bool LineOfSight(Point3D org, Point3D dest) - { - if (this == Internal) - { - return false; - } - - if (!Utility.InRange(org, dest, MaxLOSDistance)) - { - return false; - } - - var end = dest; - - if (org.X > dest.X || org.X == dest.X && org.Y > dest.Y || org.X == dest.X && org.Y == dest.Y && org.Z > dest.Z) - { - (org, dest) = (dest, org); - } - - int height; - Point3D p; - var path = new Point3DList(); - TileFlag flags; - - if (org == dest) - { - return true; - } - - if (path.Count > 0) - { - path.Clear(); - } - - var xd = dest.m_X - org.m_X; - var yd = dest.m_Y - org.m_Y; - var zd = dest.m_Z - org.m_Z; - var zslp = Math.Sqrt(xd * xd + yd * yd); - var sq3d = zd != 0 ? Math.Sqrt(zslp * zslp + zd * zd) : zslp; - - var rise = yd / sq3d; - var run = xd / sq3d; - zslp = zd / sq3d; - - double y = org.m_Y; - double z = org.m_Z; - double x = org.m_X; - while (Utility.NumberBetween(x, dest.m_X, org.m_X, 0.5) && Utility.NumberBetween(y, dest.m_Y, org.m_Y, 0.5) && - Utility.NumberBetween(z, dest.m_Z, org.m_Z, 0.5)) - { - var ix = (int)Math.Round(x); - var iy = (int)Math.Round(y); - var iz = (int)Math.Round(z); - if (path.Count > 0) - { - p = path.Last; - - if (p.m_X != ix || p.m_Y != iy || p.m_Z != iz) - { - path.Add(ix, iy, iz); - } - } - else - { - path.Add(ix, iy, iz); - } - - x += run; - y += rise; - z += zslp; - } - - if (path.Count == 0) - { - return true; // <--should never happen, but to be safe. - } - - p = path.Last; - - if (p != dest) - { - path.Add(dest); - } - - Point3D pTop = org, pBottom = dest; - Utility.FixPoints(ref pTop, ref pBottom); - - var pathCount = path.Count; - var endTop = end.m_Z + 1; - - for (var i = 0; i < pathCount; ++i) - { - var point = path[i]; - var pointTop = point.m_Z + 1; - - var landTile = Tiles.GetLandTile(point.X, point.Y); - GetAverageZ(point.m_X, point.m_Y, out var landZ, out _, out var landTop); - - if (landZ <= pointTop && landTop >= point.m_Z && - (point.m_X != end.m_X || point.m_Y != end.m_Y || landZ > endTop || landTop < end.m_Z) && - !landTile.Ignored) + if (m.Location.m_X == x && m.Location.m_Y == y && (m.AccessLevel == AccessLevel.Player || !m.Hidden) && + m.Z + 16 > z && z + height > m.Z) { return false; } - - /* --Do land tiles need to be checked? There is never land between two people, always statics.-- - LandTile landTile = Tiles.GetLandTile( point.X, point.Y ); - if (landTile.Z-1 >= point.Z && landTile.Z+1 <= point.Z && (TileData.LandTable[landTile.ID & TileData.MaxLandValue].Flags & TileFlag.Impassable) != 0) - return false; - */ - - var statics = Tiles.GetStaticTiles(point.m_X, point.m_Y, true); - - var contains = false; - var ltID = landTile.ID; - - for (var j = 0; !contains && j < InvalidLandTiles.Length; ++j) - { - contains = ltID == InvalidLandTiles[j]; - } - - if (contains && statics.Length == 0) - { - var eable = GetItemsInRange(point, 0); - - foreach (Item item in eable) - { - if (item.Visible) - { - contains = false; - break; - } - } - - eable.Free(); - - if (contains) - { - return false; - } - } - - for (var j = 0; j < statics.Length; ++j) - { - var t = statics[j]; - - var id = TileData.ItemTable[t.ID & TileData.MaxItemValue]; - - flags = id.Flags; - height = id.CalcHeight; - - if (t.Z <= pointTop && t.Z + height >= point.Z && (flags & (TileFlag.Window | TileFlag.NoShoot)) != 0) - { - if (point.m_X == end.m_X && point.m_Y == end.m_Y && t.Z <= endTop && t.Z + height >= end.m_Z) - { - continue; - } - - return false; - } - } } + } - var rect = new Rectangle2D(pTop.m_X, pTop.m_Y, pBottom.m_X - pTop.m_X + 1, pBottom.m_Y - pTop.m_Y + 1); + return !requireSurface || hasSurface; + } - var area = GetItemsInBounds(rect); + public bool CanSpawnMobile(Point3D p) => CanSpawnMobile(p.m_X, p.m_Y, p.m_Z); - foreach (var i in area) + public bool CanSpawnMobile(Point2D p, int z) => CanSpawnMobile(p.m_X, p.m_Y, z); + + public bool CanSpawnMobile(int x, int y, int z) => + Region.Find(new Point3D(x, y, z), this).AllowSpawn() && CanFit(x, y, z, 16); + + private class ZComparer : IComparer + { + public static readonly ZComparer Default = new(); + + public int Compare(Item x, Item y) => x!.Z.CompareTo(y!.Z); + } + + public Sector GetSector(Point3D p) => InternalGetSector(p.m_X >> SectorShift, p.m_Y >> SectorShift); + + public Sector GetSector(Point2D p) => InternalGetSector(p.m_X >> SectorShift, p.m_Y >> SectorShift); + + // public Sector GetSector(IPoint2D p) => InternalGetSector(p.X >> SectorShift, p.Y >> SectorShift); + + public Sector GetSector(int x, int y) => InternalGetSector(x >> SectorShift, y >> SectorShift); + + public Sector GetRealSector(int x, int y) => InternalGetSector(x, y); + + private Sector InternalGetSector(int x, int y) + { + if (x >= 0 && x < m_SectorsWidth && y >= 0 && y < m_SectorsHeight) + { + var xSectors = m_Sectors[x]; + + if (xSectors == null) { - if (!i.Visible) - { - continue; - } - - if (i is BaseMulti || i.ItemID > TileData.MaxItemValue) - { - continue; - } - - var id = i.ItemData; - flags = id.Flags; - - if ((flags & (TileFlag.Window | TileFlag.NoShoot)) == 0) - { - continue; - } - - height = id.CalcHeight; - - var found = false; - - var count = path.Count; - - for (var j = 0; j < count; ++j) - { - var point = path[j]; - var pointTop = point.m_Z + 1; - var loc = i.Location; - - // if (t.Z <= point.Z && t.Z+height >= point.Z && ( height != 0 || ( t.Z == dest.Z && zd != 0 ) )) - if (loc.m_X == point.m_X && loc.m_Y == point.m_Y && loc.m_Z <= pointTop && loc.m_Z + height >= point.m_Z) - { - if (loc.m_X != end.m_X || loc.m_Y != end.m_Y || loc.m_Z > endTop || loc.m_Z + height < end.m_Z) - { - found = true; - break; - } - } - } - - if (!found) - { - continue; - } - - area.Free(); - return false; + m_Sectors[x] = xSectors = new Sector[m_SectorsHeight]; } - area.Free(); + var sec = xSectors[y]; + + if (sec == null) + { + xSectors[y] = sec = new Sector(x, y, this); + } + + return sec; + } + + return InvalidSector; + } + + public bool LineOfSight(Point3D org, Point3D dest) + { + if (this == Internal) + { + return false; + } + + if (!Utility.InRange(org, dest, MaxLOSDistance)) + { + return false; + } + + var end = dest; + + if (org.X > dest.X || org.X == dest.X && org.Y > dest.Y || org.X == dest.X && org.Y == dest.Y && org.Z > dest.Z) + { + (org, dest) = (dest, org); + } + + int height; + Point3D p; + var path = new Point3DList(); + TileFlag flags; + + if (org == dest) + { return true; } - public bool LineOfSight(object from, object dest) => - from == dest || (from as Mobile)?.AccessLevel > AccessLevel.Player || - (dest as Item)?.RootParent == from || LineOfSight(GetPoint(from, true), GetPoint(dest, false)); - - public bool LineOfSight(Mobile from, Point3D target) + if (path.Count > 0) { - if (from.AccessLevel > AccessLevel.Player) - { - return true; - } - - var eye = from.Location; - - eye.Z += 14; - - return LineOfSight(eye, target); + path.Clear(); } - public bool LineOfSight(Mobile from, Mobile to) + var xd = dest.m_X - org.m_X; + var yd = dest.m_Y - org.m_Y; + var zd = dest.m_Z - org.m_Z; + var zslp = Math.Sqrt(xd * xd + yd * yd); + var sq3d = zd != 0 ? Math.Sqrt(zslp * zslp + zd * zd) : zslp; + + var rise = yd / sq3d; + var run = xd / sq3d; + zslp = zd / sq3d; + + double y = org.m_Y; + double z = org.m_Z; + double x = org.m_X; + while (Utility.NumberBetween(x, dest.m_X, org.m_X, 0.5) && Utility.NumberBetween(y, dest.m_Y, org.m_Y, 0.5) && + Utility.NumberBetween(z, dest.m_Z, org.m_Z, 0.5)) { - if (from == to || from.AccessLevel > AccessLevel.Player) + var ix = (int)Math.Round(x); + var iy = (int)Math.Round(y); + var iz = (int)Math.Round(z); + if (path.Count > 0) { - return true; + p = path.Last; + + if (p.m_X != ix || p.m_Y != iy || p.m_Z != iz) + { + path.Add(ix, iy, iz); + } + } + else + { + path.Add(ix, iy, iz); } - var eye = from.Location; - var target = to.Location; - - eye.Z += 14; - target.Z += 14; // 10; - - return LineOfSight(eye, target); + x += run; + y += rise; + z += zslp; } - public Point3D GetRandomNearbyLocation( - Point3D loc, int maxRange = 2, int minRange = 0, int retryCount = 10, - int height = 16, bool checkBlocksFit = false, - bool checkMobiles = false + if (path.Count == 0) + { + return true; // <--should never happen, but to be safe. + } + + p = path.Last; + + if (p != dest) + { + path.Add(dest); + } + + Point3D pTop = org, pBottom = dest; + Utility.FixPoints(ref pTop, ref pBottom); + + var pathCount = path.Count; + var endTop = end.m_Z + 1; + + for (var i = 0; i < pathCount; ++i) + { + var point = path[i]; + var pointTop = point.m_Z + 1; + + var landTile = Tiles.GetLandTile(point.X, point.Y); + GetAverageZ(point.m_X, point.m_Y, out var landZ, out _, out var landTop); + + if (landZ <= pointTop && landTop >= point.m_Z && + (point.m_X != end.m_X || point.m_Y != end.m_Y || landZ > endTop || landTop < end.m_Z) && + !landTile.Ignored) + { + return false; + } + + /* --Do land tiles need to be checked? There is never land between two people, always statics.-- + LandTile landTile = Tiles.GetLandTile( point.X, point.Y ); + if (landTile.Z-1 >= point.Z && landTile.Z+1 <= point.Z && (TileData.LandTable[landTile.ID & TileData.MaxLandValue].Flags & TileFlag.Impassable) != 0) + return false; + */ + + var statics = Tiles.GetStaticTiles(point.m_X, point.m_Y, true); + + var contains = false; + var ltID = landTile.ID; + + for (var j = 0; !contains && j < InvalidLandTiles.Length; ++j) + { + contains = ltID == InvalidLandTiles[j]; + } + + if (contains && statics.Length == 0) + { + var eable = GetItemsInRange(point, 0); + + foreach (Item item in eable) + { + if (item.Visible) + { + contains = false; + break; + } + } + + eable.Free(); + + if (contains) + { + return false; + } + } + + for (var j = 0; j < statics.Length; ++j) + { + var t = statics[j]; + + var id = TileData.ItemTable[t.ID & TileData.MaxItemValue]; + + flags = id.Flags; + height = id.CalcHeight; + + if (t.Z <= pointTop && t.Z + height >= point.Z && (flags & (TileFlag.Window | TileFlag.NoShoot)) != 0) + { + if (point.m_X == end.m_X && point.m_Y == end.m_Y && t.Z <= endTop && t.Z + height >= end.m_Z) + { + continue; + } + + return false; + } + } + } + + var rect = new Rectangle2D(pTop.m_X, pTop.m_Y, pBottom.m_X - pTop.m_X + 1, pBottom.m_Y - pTop.m_Y + 1); + + var area = GetItemsInBounds(rect); + + foreach (var i in area) + { + if (!i.Visible) + { + continue; + } + + if (i is BaseMulti || i.ItemID > TileData.MaxItemValue) + { + continue; + } + + var id = i.ItemData; + flags = id.Flags; + + if ((flags & (TileFlag.Window | TileFlag.NoShoot)) == 0) + { + continue; + } + + height = id.CalcHeight; + + var found = false; + + var count = path.Count; + + for (var j = 0; j < count; ++j) + { + var point = path[j]; + var pointTop = point.m_Z + 1; + var loc = i.Location; + + // if (t.Z <= point.Z && t.Z+height >= point.Z && ( height != 0 || ( t.Z == dest.Z && zd != 0 ) )) + if (loc.m_X == point.m_X && loc.m_Y == point.m_Y && loc.m_Z <= pointTop && loc.m_Z + height >= point.m_Z) + { + if (loc.m_X != end.m_X || loc.m_Y != end.m_Y || loc.m_Z > endTop || loc.m_Z + height < end.m_Z) + { + found = true; + break; + } + } + } + + if (!found) + { + continue; + } + + area.Free(); + return false; + } + + area.Free(); + return true; + } + + public bool LineOfSight(object from, object dest) => + from == dest || (from as Mobile)?.AccessLevel > AccessLevel.Player || + (dest as Item)?.RootParent == from || LineOfSight(GetPoint(from, true), GetPoint(dest, false)); + + public bool LineOfSight(Mobile from, Point3D target) + { + if (from.AccessLevel > AccessLevel.Player) + { + return true; + } + + var eye = from.Location; + + eye.Z += 14; + + return LineOfSight(eye, target); + } + + public bool LineOfSight(Mobile from, Mobile to) + { + if (from == to || from.AccessLevel > AccessLevel.Player) + { + return true; + } + + var eye = from.Location; + var target = to.Location; + + eye.Z += 14; + target.Z += 14; // 10; + + return LineOfSight(eye, target); + } + + public Point3D GetRandomNearbyLocation( + Point3D loc, int maxRange = 2, int minRange = 0, int retryCount = 10, + int height = 16, bool checkBlocksFit = false, + bool checkMobiles = false + ) + { + var j = 0; + var range = maxRange - minRange; + var locs = range <= 10 ? new bool[range + 1, range + 1] : null; + + do + { + var xRand = Utility.Random(range); + var yRand = Utility.Random(range); + + if (locs?[xRand, yRand] != true) + { + var x = loc.X + xRand + minRange; + var y = loc.Y + yRand + minRange; + + if (CanFit(x, y, loc.Z, height, checkBlocksFit, checkMobiles)) + { + loc = new Point3D(x, y, loc.Z); + break; + } + + var z = GetAverageZ(x, y); + + if (CanFit(x, y, z, height, checkBlocksFit, checkMobiles)) + { + loc = new Point3D(x, y, z); + break; + } + + if (locs != null) + { + locs[xRand, yRand] = true; + } + } + + j++; + } while (j < retryCount); + + return loc; + } + + public class NullEnumerable : IPooledEnumerable + { + public static readonly NullEnumerable Instance = new(); + + private readonly IEnumerable m_Empty = Enumerable.Empty(); + + IEnumerator IEnumerable.GetEnumerator() => m_Empty.GetEnumerator(); + + public IEnumerator GetEnumerator() => m_Empty.GetEnumerator(); + + public void Free() + { + } + } + + public sealed class PooledEnumerable : IPooledEnumerable, IDisposable + { + private static readonly Queue> _Buffer = new(0x400); + + private bool m_IsDisposed; + + private List m_Pool = new(0x40); + + public PooledEnumerable(IEnumerable pool) + { + m_Pool.AddRange(pool); + } + + public void Dispose() + { + m_IsDisposed = true; + + m_Pool.Clear(); + m_Pool.TrimExcess(); + m_Pool = null; + } + + IEnumerator IEnumerable.GetEnumerator() => m_Pool.GetEnumerator(); + + public IEnumerator GetEnumerator() => m_Pool.GetEnumerator(); + + public void Free() + { + if (m_IsDisposed) + { + return; + } + + m_Pool.Clear(); + m_Pool.Capacity = Math.Max(m_Pool.Capacity, 0x100); + + lock (((ICollection)_Buffer).SyncRoot) + { + _Buffer.Enqueue(this); + } + } +#pragma warning disable CA1000 // Do not declare static members on generic types + public static PooledEnumerable Instantiate( + Map map, Rectangle2D bounds, PooledEnumeration.Selector selector ) { - var j = 0; - var range = maxRange - minRange; - var locs = range <= 10 ? new bool[range + 1, range + 1] : null; + PooledEnumerable e = null; - do + lock (((ICollection)_Buffer).SyncRoot) { - var xRand = Utility.Random(range); - var yRand = Utility.Random(range); - - if (locs?[xRand, yRand] != true) + if (_Buffer.Count > 0) { - var x = loc.X + xRand + minRange; - var y = loc.Y + yRand + minRange; - - if (CanFit(x, y, loc.Z, height, checkBlocksFit, checkMobiles)) - { - loc = new Point3D(x, y, loc.Z); - break; - } - - var z = GetAverageZ(x, y); - - if (CanFit(x, y, z, height, checkBlocksFit, checkMobiles)) - { - loc = new Point3D(x, y, z); - break; - } - - if (locs != null) - { - locs[xRand, yRand] = true; - } + e = _Buffer.Dequeue(); } + } - j++; - } while (j < retryCount); + var pool = PooledEnumeration.EnumerateSectors(map, bounds).SelectMany(s => selector(s, bounds)); - return loc; + if (e == null) + { + return new PooledEnumerable(pool); + } + + e.m_Pool.AddRange(pool); + return e; } - - public class NullEnumerable : IPooledEnumerable - { - public static readonly NullEnumerable Instance = new(); - - private readonly IEnumerable m_Empty = Enumerable.Empty(); - - IEnumerator IEnumerable.GetEnumerator() => m_Empty.GetEnumerator(); - - public IEnumerator GetEnumerator() => m_Empty.GetEnumerator(); - - public void Free() - { - } - } - - public sealed class PooledEnumerable : IPooledEnumerable, IDisposable - { - private static readonly Queue> _Buffer = new(0x400); - - private bool m_IsDisposed; - - private List m_Pool = new(0x40); - - public PooledEnumerable(IEnumerable pool) - { - m_Pool.AddRange(pool); - } - - public void Dispose() - { - m_IsDisposed = true; - - m_Pool.Clear(); - m_Pool.TrimExcess(); - m_Pool = null; - } - - IEnumerator IEnumerable.GetEnumerator() => m_Pool.GetEnumerator(); - - public IEnumerator GetEnumerator() => m_Pool.GetEnumerator(); - - public void Free() - { - if (m_IsDisposed) - { - return; - } - - m_Pool.Clear(); - m_Pool.Capacity = Math.Max(m_Pool.Capacity, 0x100); - - lock (((ICollection)_Buffer).SyncRoot) - { - _Buffer.Enqueue(this); - } - } -#pragma warning disable CA1000 // Do not declare static members on generic types - public static PooledEnumerable Instantiate( - Map map, Rectangle2D bounds, PooledEnumeration.Selector selector - ) - { - PooledEnumerable e = null; - - lock (((ICollection)_Buffer).SyncRoot) - { - if (_Buffer.Count > 0) - { - e = _Buffer.Dequeue(); - } - } - - var pool = PooledEnumeration.EnumerateSectors(map, bounds).SelectMany(s => selector(s, bounds)); - - if (e == null) - { - return new PooledEnumerable(pool); - } - - e.m_Pool.AddRange(pool); - return e; - } - } -#pragma warning restore CA1000 // Do not declare static members on generic types } +#pragma warning restore CA1000 // Do not declare static members on generic types } diff --git a/Projects/Server/Network/Packets/OutgoingGumpPackets.cs b/Projects/Server/Network/Packets/OutgoingGumpPackets.cs index 9460f9c8f..f8d3e9b29 100644 --- a/Projects/Server/Network/Packets/OutgoingGumpPackets.cs +++ b/Projects/Server/Network/Packets/OutgoingGumpPackets.cs @@ -1,6 +1,6 @@ /************************************************************************* * ModernUO * - * Copyright (C) 2019-2020 - ModernUO Development Team * + * Copyright 2019-2022 - ModernUO Development Team * * Email: hi@modernuo.com * * File: OutgoingGumpPackets.cs * * * @@ -18,6 +18,7 @@ using System.Buffers; using System.IO; using System.IO.Compression; using System.Runtime.CompilerServices; +using Server.Buffers; using Server.Collections; using Server.Gumps; using Server.Logging; @@ -68,7 +69,7 @@ public static class OutgoingGumpPackets if (wantLength > packBuffer.Length) { - packBuffer = rentedBuffer = ArrayPool.Shared.Rent(wantLength); + packBuffer = rentedBuffer = STArrayPool.Shared.Rent(wantLength); } var packLength = wantLength; @@ -90,7 +91,7 @@ public static class OutgoingGumpPackets if (rentedBuffer != null) { - ArrayPool.Shared.Return(rentedBuffer); + STArrayPool.Shared.Return(rentedBuffer); } } diff --git a/Projects/Server/Network/Packets/PacketContainerBuilder.cs b/Projects/Server/Network/Packets/PacketContainerBuilder.cs index 55eba01c1..4719004d6 100644 --- a/Projects/Server/Network/Packets/PacketContainerBuilder.cs +++ b/Projects/Server/Network/Packets/PacketContainerBuilder.cs @@ -1,6 +1,6 @@ /************************************************************************* * ModernUO * - * Copyright (C) 2019-2021 - ModernUO Development Team * + * Copyright 2019-2022 - ModernUO Development Team * * Email: hi@modernuo.com * * File: PacketContainerBuilder.cs * * * @@ -14,9 +14,9 @@ *************************************************************************/ using System; -using System.Buffers; using System.Buffers.Binary; using System.Runtime.CompilerServices; +using Server.Buffers; namespace Server.Network; @@ -89,7 +89,7 @@ public ref struct PacketContainerBuilder private void Grow(int additionalCapacityBeyondPos) { var newLength = Math.Max(Length + additionalCapacityBeyondPos, _bytes.Length * 2); - byte[] poolArray = ArrayPool.Shared.Rent(newLength); + byte[] poolArray = STArrayPool.Shared.Rent(newLength); _bytes[..Length].CopyTo(poolArray); @@ -97,7 +97,7 @@ public ref struct PacketContainerBuilder _bytes = _arrayToReturnToPool = poolArray; if (toReturn != null) { - ArrayPool.Shared.Return(toReturn); + STArrayPool.Shared.Return(toReturn); } } @@ -108,7 +108,7 @@ public ref struct PacketContainerBuilder this = default; // for safety, to avoid using pooled array if this instance is erroneously appended to again if (toReturn != null) { - ArrayPool.Shared.Return(toReturn); + STArrayPool.Shared.Return(toReturn); } } } diff --git a/Projects/Server/Text/StringHelpers.cs b/Projects/Server/Text/StringHelpers.cs index cf97b6a7c..ab87a90bb 100644 --- a/Projects/Server/Text/StringHelpers.cs +++ b/Projects/Server/Text/StringHelpers.cs @@ -1,6 +1,6 @@ /************************************************************************* * ModernUO * - * Copyright (C) 2019-2020 - ModernUO Development Team * + * Copyright 2019-2022 - ModernUO Development Team * * Email: hi@modernuo.com * * File: StringHelpers.cs * * * @@ -14,276 +14,275 @@ *************************************************************************/ using System; -using System.Buffers; using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using Server.Buffers; -namespace Server +namespace Server; + +public static class StringHelpers { - public static class StringHelpers + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string DefaultIfNullOrEmpty(this string value, string def) => + string.IsNullOrWhiteSpace(value) ? def : value; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Remove( + this ReadOnlySpan a, + ReadOnlySpan b, + StringComparison comparison, + Span buffer, + out int size + ) { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string DefaultIfNullOrEmpty(this string value, string def) => - string.IsNullOrWhiteSpace(value) ? def : value; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Remove( - this ReadOnlySpan a, - ReadOnlySpan b, - StringComparison comparison, - Span buffer, - out int size - ) + size = 0; + if (a == null || a.Length == 0) { - size = 0; - if (a == null || a.Length == 0) + return; + } + + var sliced = a; + + while (true) + { + var indexOf = sliced.IndexOf(b, comparison); + if (indexOf == -1) { - return; + indexOf = sliced.Length; } - var sliced = a; - - while (true) + if (size + indexOf > buffer.Length) { - var indexOf = sliced.IndexOf(b, comparison); - if (indexOf == -1) - { - indexOf = sliced.Length; - } + throw new OutOfMemoryException(nameof(buffer)); + } - if (size + indexOf > buffer.Length) - { - throw new OutOfMemoryException(nameof(buffer)); - } + sliced[..indexOf].CopyTo(buffer[size..]); + size += indexOf; - sliced[..indexOf].CopyTo(buffer[size..]); - size += indexOf; + if (indexOf == sliced.Length) + { + break; + } - if (indexOf == sliced.Length) + sliced = sliced[(indexOf + 1)..]; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string Remove(this ReadOnlySpan a, ReadOnlySpan b, StringComparison comparison) + { + if (a == null) + { + return null; + } + + if (a.Length == 0) + { + return ""; + } + + Span span = a.Length < 1024 ? stackalloc char[a.Length] : null; + char[] chrs; + if (span == null) + { + chrs = STArrayPool.Shared.Rent(a.Length); + span = chrs.AsSpan(); + } + else + { + chrs = null; + } + + a.Remove(b, comparison, span, out var size); + + var str = span[..size].ToString(); + + if (chrs != null) + { + STArrayPool.Shared.Return(chrs); + } + + return str; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string Capitalize(this string value) + { + if (string.IsNullOrEmpty(value)) + { + return value; + } + + Span span = value.Length < 1024 ? stackalloc char[value.Length] : null; + char[] chrs; + if (span == null) + { + chrs = STArrayPool.Shared.Rent(value.Length); + span = chrs.AsSpan(); + } + else + { + chrs = null; + } + + var sliced = value.AsSpan(); + // Copy over the previous span + sliced.CopyTo(span); + + var index = 0; + + while (true) + { + // Special case for titles - words that don't get capitalized + if (sliced.InsensitiveStartsWith("the ")) + { + sliced = sliced[4..]; + index += 4; + continue; + } + + var indexOf = sliced.IndexOf(' '); + span[index] = char.ToUpperInvariant(sliced[0]); + + if (indexOf == -1) + { + break; + } + + if (indexOf == sliced.Length - 1) + { + break; + } + + sliced = sliced[(indexOf + 1)..]; + index += indexOf + 1; + } + + var str = span.ToString(); + + if (chrs != null) + { + STArrayPool.Shared.Return(chrs); + } + + return str; + } + + public static string TrimMultiline(this string str, string lineSeparator = "\n") + { + var parts = str.Split(lineSeparator); + for (var i = 0; i < parts.Length; i++) + { + parts[i] = parts[i].Trim(); + } + + return string.Join(lineSeparator, parts); + } + + public static string IndentMultiline(this string str, string indent = "\t", string lineSeparator = "\n") + { + var parts = str.Split(lineSeparator); + for (var i = 0; i < parts.Length; i++) + { + parts[i] = $"{indent}{parts[i]}"; + } + + return string.Join(lineSeparator, parts); + } + + public static List Wrap(this string value, int perLine, int maxLines) + { + if ((value = value?.Trim() ?? "").Length <= 0) + { + return null; + } + + var span = value.AsSpan(); + var list = new List(maxLines); + var lineLength = 0; + + while (span.Length > 0) + { + var spaceIndex = span[lineLength..].IndexOf(' '); + if (spaceIndex == -1) + { + spaceIndex = span.Length - lineLength; // End of the string + } + + var newLineLength = lineLength + spaceIndex; + + // If the previous line is exactly perLine or not too long and we are at the end + if (newLineLength == perLine || newLineLength < perLine && newLineLength == span.Length) + { + list.Add(span[..newLineLength].ToString()); + if (list.Count == maxLines || newLineLength == span.Length) { break; } - sliced = sliced[(indexOf + 1)..]; + span = span[(newLineLength + 1)..]; + lineLength = 0; } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Remove(this ReadOnlySpan a, ReadOnlySpan b, StringComparison comparison) - { - if (a == null) + // We haven't hit perLine and are not sure if we can continue adding more words without going over + else if (newLineLength < perLine) { - return null; + lineLength = newLineLength + 1; } - - if (a.Length == 0) + // We already tried making the line longer, and it was too long, so fall back to the old line + else if (lineLength > 0 && lineLength <= perLine) { - return ""; - } + list.Add(span[..(lineLength - 1)].ToString()); + if (list.Count == maxLines) + { + break; + } - Span span = a.Length < 1024 ? stackalloc char[a.Length] : null; - char[] chrs; - if (span == null) - { - chrs = ArrayPool.Shared.Rent(a.Length); - span = chrs.AsSpan(); + span = span[lineLength..]; + lineLength = 0; } + // We have a really long single word with no spaces and have to forcibly break it up. else { - chrs = null; - } + lineLength = newLineLength; + var index = 0; - a.Remove(b, comparison, span, out var size); - - var str = span[..size].ToString(); - - if (chrs != null) - { - ArrayPool.Shared.Return(chrs); - } - - return str; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Capitalize(this string value) - { - if (string.IsNullOrEmpty(value)) - { - return value; - } - - Span span = value.Length < 1024 ? stackalloc char[value.Length] : null; - char[] chrs; - if (span == null) - { - chrs = ArrayPool.Shared.Rent(value.Length); - span = chrs.AsSpan(); - } - else - { - chrs = null; - } - - var sliced = value.AsSpan(); - // Copy over the previous span - sliced.CopyTo(span); - - var index = 0; - - while (true) - { - // Special case for titles - words that don't get capitalized - if (sliced.InsensitiveStartsWith("the ")) + while (index < lineLength) { - sliced = sliced[4..]; - index += 4; - continue; - } + lineLength -= perLine; - var indexOf = sliced.IndexOf(' '); - span[index] = char.ToUpperInvariant(sliced[0]); - - if (indexOf == -1) - { - break; - } - - if (indexOf == sliced.Length - 1) - { - break; - } - - sliced = sliced[(indexOf + 1)..]; - index += indexOf + 1; - } - - var str = span.ToString(); - - if (chrs != null) - { - ArrayPool.Shared.Return(chrs); - } - - return str; - } - - public static string TrimMultiline(this string str, string lineSeparator = "\n") - { - var parts = str.Split(lineSeparator); - for (var i = 0; i < parts.Length; i++) - { - parts[i] = parts[i].Trim(); - } - - return string.Join(lineSeparator, parts); - } - - public static string IndentMultiline(this string str, string indent = "\t", string lineSeparator = "\n") - { - var parts = str.Split(lineSeparator); - for (var i = 0; i < parts.Length; i++) - { - parts[i] = $"{indent}{parts[i]}"; - } - - return string.Join(lineSeparator, parts); - } - - public static List Wrap(this string value, int perLine, int maxLines) - { - if ((value = value?.Trim() ?? "").Length <= 0) - { - return null; - } - - var span = value.AsSpan(); - var list = new List(maxLines); - var lineLength = 0; - - while (span.Length > 0) - { - var spaceIndex = span[lineLength..].IndexOf(' '); - if (spaceIndex == -1) - { - spaceIndex = span.Length - lineLength; // End of the string - } - - var newLineLength = lineLength + spaceIndex; - - // If the previous line is exactly perLine or not too long and we are at the end - if (newLineLength == perLine || newLineLength < perLine && newLineLength == span.Length) - { - list.Add(span[..newLineLength].ToString()); - if (list.Count == maxLines || newLineLength == span.Length) - { - break; - } - - span = span[(newLineLength + 1)..]; - lineLength = 0; - } - // We haven't hit perLine and are not sure if we can continue adding more words without going over - else if (newLineLength < perLine) - { - lineLength = newLineLength + 1; - } - // We already tried making the line longer, and it was too long, so fall back to the old line - else if (lineLength > 0 && lineLength <= perLine) - { - list.Add(span[..(lineLength - 1)].ToString()); + var length = perLine - (span[index] == ' ' ? 1 : 0); + list.Add(span.Slice(index, length).ToString()); if (list.Count == maxLines) { break; } - span = span[lineLength..]; - lineLength = 0; + index += perLine; } - // We have a really long single word with no spaces and have to forcibly break it up. - else - { - lineLength = newLineLength; - var index = 0; - while (index < lineLength) - { - lineLength -= perLine; - - var length = perLine - (span[index] == ' ' ? 1 : 0); - list.Add(span.Slice(index, length).ToString()); - if (list.Count == maxLines) - { - break; - } - - index += perLine; - } - - span = span[(newLineLength - lineLength)..]; - } + span = span[(newLineLength - lineLength)..]; } - - return list; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int IndexOfTerminator(this Span buffer, int sizeT) => - sizeT switch - { - 2 => MemoryMarshal.Cast(buffer).IndexOf((char)0) * 2, - 4 => MemoryMarshal.Cast(buffer).IndexOf((uint)0) * 4, - _ => buffer.IndexOf((byte)0) - }; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int IndexOfTerminator(this ReadOnlySpan buffer, int sizeT) => - sizeT switch - { - 2 => MemoryMarshal.Cast(buffer).IndexOf((char)0) * 2, - 4 => MemoryMarshal.Cast(buffer).IndexOf((uint)0) * 4, - _ => buffer.IndexOf((byte)0) - }; + return list; } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int IndexOfTerminator(this Span buffer, int sizeT) => + sizeT switch + { + 2 => MemoryMarshal.Cast(buffer).IndexOf((char)0) * 2, + 4 => MemoryMarshal.Cast(buffer).IndexOf((uint)0) * 4, + _ => buffer.IndexOf((byte)0) + }; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int IndexOfTerminator(this ReadOnlySpan buffer, int sizeT) => + sizeT switch + { + 2 => MemoryMarshal.Cast(buffer).IndexOf((char)0) * 2, + 4 => MemoryMarshal.Cast(buffer).IndexOf((uint)0) * 4, + _ => buffer.IndexOf((byte)0) + }; } diff --git a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/BladeSpirits.cs b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/BladeSpirits.cs index 8f326bc5f..d05ffb814 100644 --- a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/BladeSpirits.cs +++ b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/BladeSpirits.cs @@ -1,118 +1,117 @@ using System; -using System.Buffers; +using Server.Buffers; using Server.Collections; -namespace Server.Mobiles +namespace Server.Mobiles; + +public class BladeSpirits : BaseCreature { - public class BladeSpirits : BaseCreature + [Constructible] + public BladeSpirits() : base(AIType.AI_Melee) { - [Constructible] - public BladeSpirits() : base(AIType.AI_Melee) + Body = 574; + + SetSpeed(0.5, 1.2); + SetStr(150); + SetDex(150); + SetInt(100); + + SetHits(Core.SE ? 160 : 80); + SetStam(250); + SetMana(0); + + SetDamage(10, 14); + + SetDamageType(ResistanceType.Physical, 60); + SetDamageType(ResistanceType.Poison, 20); + SetDamageType(ResistanceType.Energy, 20); + + SetResistance(ResistanceType.Physical, 30, 40); + SetResistance(ResistanceType.Fire, 40, 50); + SetResistance(ResistanceType.Cold, 30, 40); + SetResistance(ResistanceType.Poison, 100); + SetResistance(ResistanceType.Energy, 20, 30); + + SetSkill(SkillName.MagicResist, 70.0); + SetSkill(SkillName.Tactics, 90.0); + SetSkill(SkillName.Wrestling, 90.0); + + Fame = 0; + Karma = 0; + + VirtualArmor = 40; + ControlSlots = Core.SE ? 2 : 1; + } + + public BladeSpirits(Serial serial) : base(serial) + { + } + + public override string CorpseName => "a blade spirit corpse"; + public override bool DeleteCorpseOnDeath => Core.AOS; + public override bool IsHouseSummonable => true; + + public override double DispelDifficulty => 0.0; + public override double DispelFocus => 20.0; + + public override string DefaultName => "a blade spirit"; + + public override bool BleedImmune => true; + public override Poison PoisonImmune => Poison.Lethal; + + public override double GetFightModeRanking(Mobile m, FightMode acqType, bool bPlayerOnly) => + (m.Str + m.Skills.Tactics.Value) / Math.Max(GetDistanceToSqrt(m), 1.0); + + public override int GetAngerSound() => 0x23A; + + public override int GetAttackSound() => 0x3B8; + + public override int GetHurtSound() => 0x23A; + + public override void OnThink() + { + if (Core.SE && Summoned) { - Body = 574; - - SetSpeed(0.5, 1.2); - SetStr(150); - SetDex(150); - SetInt(100); - - SetHits(Core.SE ? 160 : 80); - SetStam(250); - SetMana(0); - - SetDamage(10, 14); - - SetDamageType(ResistanceType.Physical, 60); - SetDamageType(ResistanceType.Poison, 20); - SetDamageType(ResistanceType.Energy, 20); - - SetResistance(ResistanceType.Physical, 30, 40); - SetResistance(ResistanceType.Fire, 40, 50); - SetResistance(ResistanceType.Cold, 30, 40); - SetResistance(ResistanceType.Poison, 100); - SetResistance(ResistanceType.Energy, 20, 30); - - SetSkill(SkillName.MagicResist, 70.0); - SetSkill(SkillName.Tactics, 90.0); - SetSkill(SkillName.Wrestling, 90.0); - - Fame = 0; - Karma = 0; - - VirtualArmor = 40; - ControlSlots = Core.SE ? 2 : 1; - } - - public BladeSpirits(Serial serial) : base(serial) - { - } - - public override string CorpseName => "a blade spirit corpse"; - public override bool DeleteCorpseOnDeath => Core.AOS; - public override bool IsHouseSummonable => true; - - public override double DispelDifficulty => 0.0; - public override double DispelFocus => 20.0; - - public override string DefaultName => "a blade spirit"; - - public override bool BleedImmune => true; - public override Poison PoisonImmune => Poison.Lethal; - - public override double GetFightModeRanking(Mobile m, FightMode acqType, bool bPlayerOnly) => - (m.Str + m.Skills.Tactics.Value) / Math.Max(GetDistanceToSqrt(m), 1.0); - - public override int GetAngerSound() => 0x23A; - - public override int GetAttackSound() => 0x3B8; - - public override int GetHurtSound() => 0x23A; - - public override void OnThink() - { - if (Core.SE && Summoned) + var eable = GetMobilesInRange(5); + using var queue = PooledRefQueue.Create(); + foreach (var m in eable) { - var eable = GetMobilesInRange(5); - using var queue = PooledRefQueue.Create(); - foreach (var m in eable) + if (m is EnergyVortex or BladeSpirits && ((BaseCreature)m).Summoned) { - if (m is EnergyVortex or BladeSpirits && ((BaseCreature)m).Summoned) - { - queue.Enqueue(m); - } - } - eable.Free(); - - var amount = queue.Count - 6; - if (amount > 0) - { - var mobs = queue.ToPooledArray(); - mobs.Shuffle(); - - while (amount > 0) - { - Dispel(mobs[amount--]); - } - - ArrayPool.Shared.Return(mobs, true); + queue.Enqueue(m); } } + eable.Free(); - base.OnThink(); + var amount = queue.Count - 6; + if (amount > 0) + { + var mobs = queue.ToPooledArray(); + mobs.Shuffle(); + + while (amount > 0) + { + Dispel(mobs[amount--]); + } + + STArrayPool.Shared.Return(mobs, true); + } } - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); + base.OnThink(); + } - writer.Write(0); // version - } + public override void Serialize(IGenericWriter writer) + { + base.Serialize(writer); - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); + writer.Write(0); // version + } - var version = reader.ReadInt(); - } + public override void Deserialize(IGenericReader reader) + { + base.Deserialize(reader); + + var version = reader.ReadInt(); } } diff --git a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/EnergyVortex.cs b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/EnergyVortex.cs index 66f808bcc..ddc689b87 100644 --- a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/EnergyVortex.cs +++ b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/EnergyVortex.cs @@ -1,129 +1,128 @@ using System; -using System.Buffers; +using Server.Buffers; using Server.Collections; -namespace Server.Mobiles +namespace Server.Mobiles; + +public class EnergyVortex : BaseCreature { - public class EnergyVortex : BaseCreature + [Constructible] + public EnergyVortex() : base(AIType.AI_Melee) { - [Constructible] - public EnergyVortex() : base(AIType.AI_Melee) + if (Core.SE && Utility.Random(500) == 0) // Per OSI FoF, it's a 1/500 chance. { - if (Core.SE && Utility.RandomDouble() < 0.002) // Per OSI FoF, it's a 1/500 chance. - { - // Llama vortex! - Body = 0xDC; - Hue = 0x76; - } - else - { - Body = 164; - } - - SetStr(200); - SetDex(200); - SetInt(100); - - SetHits(Core.SE ? 140 : 70); - SetStam(250); - SetMana(0); - - SetDamage(14, 17); - - SetDamageType(ResistanceType.Physical, 0); - SetDamageType(ResistanceType.Energy, 100); - - SetResistance(ResistanceType.Physical, 60, 70); - SetResistance(ResistanceType.Fire, 40, 50); - SetResistance(ResistanceType.Cold, 40, 50); - SetResistance(ResistanceType.Poison, 40, 50); - SetResistance(ResistanceType.Energy, 90, 100); - - SetSkill(SkillName.MagicResist, 99.9); - SetSkill(SkillName.Tactics, 100.0); - SetSkill(SkillName.Wrestling, 120.0); - - Fame = 0; - Karma = 0; - - VirtualArmor = 40; - ControlSlots = Core.SE ? 2 : 1; + // Llama vortex! + Body = 0xDC; + Hue = 0x76; + } + else + { + Body = 164; } - public EnergyVortex(Serial serial) - : base(serial) + SetStr(200); + SetDex(200); + SetInt(100); + + SetHits(Core.SE ? 140 : 70); + SetStam(250); + SetMana(0); + + SetDamage(14, 17); + + SetDamageType(ResistanceType.Physical, 0); + SetDamageType(ResistanceType.Energy, 100); + + SetResistance(ResistanceType.Physical, 60, 70); + SetResistance(ResistanceType.Fire, 40, 50); + SetResistance(ResistanceType.Cold, 40, 50); + SetResistance(ResistanceType.Poison, 40, 50); + SetResistance(ResistanceType.Energy, 90, 100); + + SetSkill(SkillName.MagicResist, 99.9); + SetSkill(SkillName.Tactics, 100.0); + SetSkill(SkillName.Wrestling, 120.0); + + Fame = 0; + Karma = 0; + + VirtualArmor = 40; + ControlSlots = Core.SE ? 2 : 1; + } + + public EnergyVortex(Serial serial) + : base(serial) + { + } + + public override string CorpseName => "an energy vortex corpse"; + public override bool DeleteCorpseOnDeath => Summoned; + public override bool AlwaysMurderer => true; // Or Llama vortices will appear gray. + + public override double DispelDifficulty => 80.0; + public override double DispelFocus => 20.0; + + public override string DefaultName => "an energy vortex"; + + public override bool BleedImmune => true; + public override Poison PoisonImmune => Poison.Lethal; + + public override double GetFightModeRanking(Mobile m, FightMode acqType, bool bPlayerOnly) => + (m.Int + m.Skills.Magery.Value) / Math.Max(GetDistanceToSqrt(m), 1.0); + + public override int GetAngerSound() => 0x15; + + public override int GetAttackSound() => 0x28; + + public override void OnThink() + { + if (Core.SE && Summoned) { - } - - public override string CorpseName => "an energy vortex corpse"; - public override bool DeleteCorpseOnDeath => Summoned; - public override bool AlwaysMurderer => true; // Or Llama vortices will appear gray. - - public override double DispelDifficulty => 80.0; - public override double DispelFocus => 20.0; - - public override string DefaultName => "an energy vortex"; - - public override bool BleedImmune => true; - public override Poison PoisonImmune => Poison.Lethal; - - public override double GetFightModeRanking(Mobile m, FightMode acqType, bool bPlayerOnly) => - (m.Int + m.Skills.Magery.Value) / Math.Max(GetDistanceToSqrt(m), 1.0); - - public override int GetAngerSound() => 0x15; - - public override int GetAttackSound() => 0x28; - - public override void OnThink() - { - if (Core.SE && Summoned) + var eable = GetMobilesInRange(5); + using var queue = PooledRefQueue.Create(); + foreach (var m in eable) { - var eable = GetMobilesInRange(5); - using var queue = PooledRefQueue.Create(); - foreach (var m in eable) + if (m is EnergyVortex or BladeSpirits && ((BaseCreature)m).Summoned) { - if (m is EnergyVortex or BladeSpirits && ((BaseCreature)m).Summoned) - { - queue.Enqueue(m); - } - } - eable.Free(); - - var amount = queue.Count - 6; - if (amount > 0) - { - var mobs = queue.ToPooledArray(); - mobs.Shuffle(); - - while (amount > 0) - { - Dispel(mobs[amount--]); - } - - ArrayPool.Shared.Return(mobs, true); + queue.Enqueue(m); } } + eable.Free(); - base.OnThink(); - } - - 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(); - - if (BaseSoundID == 263) + var amount = queue.Count - 6; + if (amount > 0) { - BaseSoundID = 0; + var mobs = queue.ToPooledArray(); + mobs.Shuffle(); + + while (amount > 0) + { + Dispel(mobs[amount--]); + } + + STArrayPool.Shared.Return(mobs, true); } } + + base.OnThink(); + } + + 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(); + + if (BaseSoundID == 263) + { + BaseSoundID = 0; + } } } From c166e113b1b2823d68025d0d5b6622eef6822c97 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Tue, 22 Mar 2022 23:46:10 -0700 Subject: [PATCH 109/213] fix: Streamlines gump compilation (#969) Changes gump compilation to use string interpolation. .NET 6 uses code generation and compile time tricks to speed up string interpolation between 15 and 30% and reduce allocations dramatically. --- .../Packets/BenchmarkOutgoingGumpPacket.cs | 173 ------- .../Benchmarks/Packets/GumpPackets.cs | 315 ----------- .../Benchmarks/Packets/GumpUtilities.cs | 476 ----------------- Projects/Benchmarks/Program.cs | 2 +- .../Server.Tests/Helpers/GumpUtilities.cs | 60 +-- .../Packets/Outgoing/GumpPacketTests.cs | 6 +- Projects/Server/Gumps/Gump.cs | 488 +++++++++--------- Projects/Server/Gumps/GumpAlphaRegion.cs | 49 +- Projects/Server/Gumps/GumpBackground.cs | 55 +- Projects/Server/Gumps/GumpButton.cs | 96 ++-- Projects/Server/Gumps/GumpCheck.cs | 66 +-- Projects/Server/Gumps/GumpECHandleInput.cs | 18 +- Projects/Server/Gumps/GumpEntry.cs | 35 +- Projects/Server/Gumps/GumpGroup.cs | 33 +- Projects/Server/Gumps/GumpHtml.cs | 71 +-- Projects/Server/Gumps/GumpHtmlLocalized.cs | 217 +++----- Projects/Server/Gumps/GumpImage.cs | 73 +-- Projects/Server/Gumps/GumpImageTileButton.cs | 117 ++--- Projects/Server/Gumps/GumpImageTiled.cs | 54 +- Projects/Server/Gumps/GumpItem.cs | 56 +- Projects/Server/Gumps/GumpItemProperty.cs | 29 +- Projects/Server/Gumps/GumpLabel.cs | 49 +- Projects/Server/Gumps/GumpLabelCropped.cs | 63 +-- Projects/Server/Gumps/GumpMasterGump.cs | 27 +- Projects/Server/Gumps/GumpPage.cs | 33 +- Projects/Server/Gumps/GumpRadio.cs | 66 +-- Projects/Server/Gumps/GumpSpriteImage.cs | 65 +-- Projects/Server/Gumps/GumpTextEntry.cs | 72 +-- Projects/Server/Gumps/GumpTextEntryLimited.cs | 82 ++- Projects/Server/Gumps/GumpTooltip.cs | 45 +- .../Gumps/InvalidGumpResponseException.cs | 11 +- Projects/Server/Gumps/RelayInfo.cs | 101 ++-- .../Gumps/BaseImageTileButtonsGump.cs | 4 +- .../UOContent/Spells/Ninjitsu/AnimalForm.cs | 4 +- 34 files changed, 853 insertions(+), 2258 deletions(-) delete mode 100644 Projects/Benchmarks/Benchmarks/Packets/BenchmarkOutgoingGumpPacket.cs delete mode 100644 Projects/Benchmarks/Benchmarks/Packets/GumpPackets.cs delete mode 100644 Projects/Benchmarks/Benchmarks/Packets/GumpUtilities.cs diff --git a/Projects/Benchmarks/Benchmarks/Packets/BenchmarkOutgoingGumpPacket.cs b/Projects/Benchmarks/Benchmarks/Packets/BenchmarkOutgoingGumpPacket.cs deleted file mode 100644 index 114cac192..000000000 --- a/Projects/Benchmarks/Benchmarks/Packets/BenchmarkOutgoingGumpPacket.cs +++ /dev/null @@ -1,173 +0,0 @@ -using System; -using System.Buffers; -using System.IO; -using System.IO.Compression; -using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Jobs; -using Server.Collections; -using Server.Gumps; -using Server.Network; -using Server.Tests.Network; - -namespace Benchmarks -{ - [MemoryDiagnoser] - [SimpleJob(RuntimeMoniker.Net60)] - public class OutgoingGumpPacketBenchmarks - { - private static readonly byte[] _layoutBuffer = GC.AllocateUninitializedArray(0x20000); - private static readonly byte[] _stringsBuffer = GC.AllocateUninitializedArray(0x20000); - - public static void CreateDisplayGump(Gump gump, out int switches, out int entries) - { - switches = 0; - entries = 0; - - const bool packed = false; - - var layoutWriter = new SpanWriter(_layoutBuffer); - - if (!gump.Draggable) - { - layoutWriter.Write(Gump.NoMove); - } - - if (!gump.Closable) - { - layoutWriter.Write(Gump.NoClose); - } - - if (!gump.Disposable) - { - layoutWriter.Write(Gump.NoDispose); - } - - if (!gump.Resizable) - { - layoutWriter.Write(Gump.NoResize); - } - - var stringsList = new OrderedHashSet(32); - - foreach (var entry in gump.Entries) - { - entry.AppendTo(ref layoutWriter, stringsList, ref entries, ref switches); - } - - var stringsWriter = new SpanWriter(_stringsBuffer); - - foreach (var str in stringsList) - { - var s = str ?? ""; - stringsWriter.Write((ushort)s.Length); - stringsWriter.WriteBigUni(s); - } - - int maxLength; - if (packed) - { - var worstLayoutLength = Zlib.MaxPackSize(layoutWriter.BytesWritten); - var worstStringsLength = Zlib.MaxPackSize(stringsWriter.BytesWritten); - maxLength = 40 + worstLayoutLength + worstStringsLength; - } - else - { - maxLength = 23 + layoutWriter.BytesWritten + stringsWriter.BytesWritten; - } - - var writer = new SpanWriter(maxLength); - writer.Write((byte)(packed ? 0xDD : 0xB0)); // Packet ID - writer.Seek(2, SeekOrigin.Current); - - writer.Write(gump.Serial); - writer.Write(gump.TypeID); - writer.Write(gump.X); - writer.Write(gump.Y); - - if (packed) - { - layoutWriter.Write((byte)0); // Layout text terminator - OutgoingGumpPackets.WritePacked(layoutWriter.Span, ref writer); - - writer.Write(stringsList.Count); - OutgoingGumpPackets.WritePacked(stringsWriter.Span, ref writer); - } - else - { - writer.Write((ushort)layoutWriter.BytesWritten); - writer.Write(layoutWriter.Span); - - writer.Write((ushort)stringsList.Count); - writer.Write(stringsWriter.Span); - } - - writer.WritePacketLength(); - - layoutWriter.Dispose(); // Just in case - stringsWriter.Dispose(); // Just in case - } - - public class NameChangeDeedGump : Gump - { - public NameChangeDeedGump() : base(50, 50) - { - Closable = false; - Draggable = false; - Resizable = false; - - AddPage(0); - - AddBlackAlpha(10, 120, 250, 85); - AddHtml(10, 125, 250, 20, Color(Center("Name Change Deed"), 0xFFFFFF)); - - AddLabel(73, 15, 1152, ""); - AddLabel(20, 150, 0x480, "New Name:"); - AddTextField(100, 150, 150, 20, 0); - - AddButtonLabeled(75, 180, 1, "Submit"); - } - - public void AddBlackAlpha(int x, int y, int width, int height) - { - AddImageTiled(x, y, width, height, 2624); - AddAlphaRegion(x, y, width, height); - } - - public void AddTextField(int x, int y, int width, int height, int index) - { - AddBackground(x - 2, y - 2, width + 4, height + 4, 0x2486); - AddTextEntry(x + 2, y + 2, width - 4, height - 4, 0, index, ""); - } - - public static string Center(string text) => $"
{text}
"; - - public static string Color(string text, int color) => $"{text}"; - - public void AddButtonLabeled(int x, int y, int buttonID, string text) - { - AddButton(x, y - 1, 4005, 4007, buttonID); - AddHtml(x + 35, y, 240, 20, Color(text, 0xFFFFFF)); - } - } - - private static Gump _gump; - - [GlobalSetup] - public void Setup() - { - _gump = new NameChangeDeedGump(); - } - - [Benchmark] - public void TestNewStack() - { - CreateDisplayGump(_gump, out var _, out var _); - } - - [Benchmark] - public void TestOldStack() - { - _gump.Compile().Compile(false, out var _); - } - } -} diff --git a/Projects/Benchmarks/Benchmarks/Packets/GumpPackets.cs b/Projects/Benchmarks/Benchmarks/Packets/GumpPackets.cs deleted file mode 100644 index 74888fd37..000000000 --- a/Projects/Benchmarks/Benchmarks/Packets/GumpPackets.cs +++ /dev/null @@ -1,315 +0,0 @@ -using System.Buffers; -using System.Collections.Generic; -using System.IO; -using System.IO.Compression; -using System.Text; -using Server.Gumps; -using Server.Network; - -namespace Server.Tests -{ - public interface IGumpWriter - { - int TextEntries { get; set; } - int Switches { get; set; } - - void AppendLayout(bool val); - void AppendLayout(int val); - void AppendLayout(uint val); - void AppendLayout(Serial serial); - void AppendLayoutNS(int val); - void AppendLayout(string text); - void AppendLayoutNS(string text); - void AppendLayout(byte[] buffer); - void WriteStrings(List strings); - void Flush(); - } - - public sealed class CloseGump : Packet - { - public CloseGump(int typeID, int buttonID) : base(0xBF) - { - EnsureCapacity(13); - - Stream.Write((short)0x04); - Stream.Write(typeID); - Stream.Write(buttonID); - } - } - - public sealed class DisplayGumpPacked : Packet, IGumpWriter - { - private static readonly byte[] m_True = Gump.StringToBuffer(" 1"); - private static readonly byte[] m_False = Gump.StringToBuffer(" 0"); - - private static readonly byte[] m_BeginTextSeparator = Gump.StringToBuffer(" @"); - private static readonly byte[] m_EndTextSeparator = Gump.StringToBuffer("@"); - - private static readonly byte[] m_Buffer = new byte[48]; - - private readonly Gump m_Gump; - - private readonly PacketWriter m_Layout; - private readonly PacketWriter m_Strings; - - private int m_StringCount; - - static DisplayGumpPacked() => m_Buffer[0] = (byte)' '; - - public DisplayGumpPacked(Gump gump) - : base(0xDD) - { - m_Gump = gump; - - m_Layout = PacketWriter.CreateInstance(8192); - m_Strings = PacketWriter.CreateInstance(8192); - } - - public int TextEntries { get; set; } - - public int Switches { get; set; } - - public void AppendLayout(bool val) - { - AppendLayout(val ? m_True : m_False); - } - - public void AppendLayout(int val) - { - var toString = val.ToString(); - var bytes = Encoding.ASCII.GetBytes(toString, 0, toString.Length, m_Buffer, 1) + 1; - - m_Layout.Write(m_Buffer, 0, bytes); - } - - public void AppendLayout(uint val) - { - var toString = val.ToString(); - var bytes = Encoding.ASCII.GetBytes(toString, 0, toString.Length, m_Buffer, 1) + 1; - - m_Layout.Write(m_Buffer, 0, bytes); - } - - public void AppendLayout(Serial serial) => AppendLayout(serial.Value); - - public void AppendLayoutNS(int val) - { - var toString = val.ToString(); - var bytes = Encoding.ASCII.GetBytes(toString, 0, toString.Length, m_Buffer, 1); - - m_Layout.Write(m_Buffer, 1, bytes); - } - - public void AppendLayoutNS(string text) - { - m_Layout.WriteAsciiFixed(text, text.Length); - } - - public void AppendLayout(string text) - { - AppendLayout(m_BeginTextSeparator); - - m_Layout.WriteAsciiFixed(text, text.Length); - - AppendLayout(m_EndTextSeparator); - } - - public void AppendLayout(byte[] buffer) - { - m_Layout.Write(buffer, 0, buffer.Length); - } - - public void WriteStrings(List strings) - { - m_StringCount = strings.Count; - - for (var i = 0; i < strings.Count; ++i) - { - var v = strings[i] ?? ""; - - m_Strings.Write((ushort)v.Length); - m_Strings.WriteBigUniFixed(v, v.Length); - } - } - - public void Flush() - { - EnsureCapacity(28 + (int)m_Layout.Length + (int)m_Strings.Length); - - Stream.Write(m_Gump.Serial); - Stream.Write(m_Gump.TypeID); - Stream.Write(m_Gump.X); - Stream.Write(m_Gump.Y); - - // Note: layout MUST be null terminated (don't listen to krrios) - m_Layout.Write((byte)0); - - WritePacked(m_Layout); - - Stream.Write(m_StringCount); - - WritePacked(m_Strings); - - PacketWriter.ReleaseInstance(m_Layout); - PacketWriter.ReleaseInstance(m_Strings); - } - - private void WritePacked(PacketWriter src) - { - var buffer = src.UnderlyingStream.GetBuffer(); - var length = (int)src.Length; - - if (length == 0) - { - Stream.Write(0); - return; - } - - var wantLength = 1 + length * 1024 / 1000; - - wantLength += 4095; - wantLength &= ~4095; - - var packBuffer = ArrayPool.Shared.Rent(wantLength); - - var packLength = wantLength; - - Zlib.Pack(packBuffer, ref packLength, buffer, length, ZlibQuality.Default); - - Stream.Write(4 + packLength); - Stream.Write(length); - Stream.Write(packBuffer, 0, packLength); - - ArrayPool.Shared.Return(packBuffer); - } - } - - public sealed class DisplayGumpFast : Packet, IGumpWriter - { - private static readonly byte[] m_True = Gump.StringToBuffer(" 1"); - private static readonly byte[] m_False = Gump.StringToBuffer(" 0"); - - private static readonly byte[] m_BeginTextSeparator = Gump.StringToBuffer(" @"); - private static readonly byte[] m_EndTextSeparator = Gump.StringToBuffer("@"); - - private readonly byte[] m_Buffer = new byte[48]; - private int m_LayoutLength; - - public DisplayGumpFast(Gump g) : base(0xB0) - { - m_Buffer[0] = (byte)' '; - - EnsureCapacity(4096); - - Stream.Write(g.Serial); - Stream.Write(g.TypeID); - Stream.Write(g.X); - Stream.Write(g.Y); - Stream.Write((ushort)0xFFFF); - } - - public int TextEntries { get; set; } - - public int Switches { get; set; } - - public void AppendLayout(bool val) - { - AppendLayout(val ? m_True : m_False); - } - - public void AppendLayout(int val) - { - var toString = val.ToString(); - var bytes = Encoding.ASCII.GetBytes(toString, 0, toString.Length, m_Buffer, 1) + 1; - - Stream.Write(m_Buffer, 0, bytes); - m_LayoutLength += bytes; - } - - public void AppendLayout(uint val) - { - var toString = val.ToString(); - var bytes = Encoding.ASCII.GetBytes(toString, 0, toString.Length, m_Buffer, 1) + 1; - - Stream.Write(m_Buffer, 0, bytes); - m_LayoutLength += bytes; - } - - public void AppendLayout(Serial serial) => AppendLayout(serial.Value); - - public void AppendLayoutNS(int val) - { - var toString = val.ToString(); - var bytes = Encoding.ASCII.GetBytes(toString, 0, toString.Length, m_Buffer, 1); - - Stream.Write(m_Buffer, 1, bytes); - m_LayoutLength += bytes; - } - - public void AppendLayoutNS(string text) - { - var length = text.Length; - Stream.WriteAsciiFixed(text, length); - m_LayoutLength += length; - } - - public void AppendLayout(string text) - { - AppendLayout(m_BeginTextSeparator); - - var length = text.Length; - Stream.WriteAsciiFixed(text, length); - m_LayoutLength += length; - - AppendLayout(m_EndTextSeparator); - } - - public void AppendLayout(byte[] buffer) - { - var length = buffer.Length; - Stream.Write(buffer, 0, length); - m_LayoutLength += length; - } - - public void WriteStrings(List text) - { - Stream.Seek(19, SeekOrigin.Begin); - Stream.Write((ushort)m_LayoutLength); - Stream.Seek(0, SeekOrigin.End); - - Stream.Write((ushort)text.Count); - - for (var i = 0; i < text.Count; ++i) - { - var v = text[i] ?? ""; - - int length = (ushort)v.Length; - - Stream.Write((ushort)length); - Stream.WriteBigUniFixed(v, length); - } - } - - public void Flush() - { - } - } - - public sealed class DisplaySignGump : Packet - { - public DisplaySignGump(Serial serial, int gumpID, string unknown, string caption) : base(0x8B) - { - unknown ??= ""; - caption ??= ""; - - EnsureCapacity(15 + unknown.Length + caption.Length); - - Stream.Write(serial); - Stream.Write((short)gumpID); - Stream.Write((short)(unknown.Length + 1)); - Stream.WriteAsciiNull(unknown); - Stream.Write((short)(caption.Length + 1)); - Stream.WriteAsciiNull(caption); - } - } -} diff --git a/Projects/Benchmarks/Benchmarks/Packets/GumpUtilities.cs b/Projects/Benchmarks/Benchmarks/Packets/GumpUtilities.cs deleted file mode 100644 index 5df0a12fe..000000000 --- a/Projects/Benchmarks/Benchmarks/Packets/GumpUtilities.cs +++ /dev/null @@ -1,476 +0,0 @@ -using System.Collections.Generic; -using Server.Gumps; -using Server.Network; - -namespace Server.Tests.Network -{ - public static class GumpUtilities - { - private static readonly byte[] m_BeginLayout = Gump.StringToBuffer("{ "); - private static readonly byte[] m_EndLayout = Gump.StringToBuffer(" }"); - - public static Packet Compile(this Gump g, NetState ns = null) - { - IGumpWriter disp = new DisplayGumpFast(g); - // IGumpWriter disp = new DisplayGumpPacked(g); - - if (!g.Draggable) - { - disp.AppendLayout(Gump.NoMove); - } - - if (!g.Closable) - { - disp.AppendLayout(Gump.NoClose); - } - - if (!g.Disposable) - { - disp.AppendLayout(Gump.NoDispose); - } - - if (!g.Resizable) - { - disp.AppendLayout(Gump.NoResize); - } - - var count = g.Entries.Count; - var strings = new List(); - - for (var i = 0; i < count; ++i) - { - var e = g.Entries[i]; - - disp.AppendLayout(m_BeginLayout); - e.AppendToByType(disp, strings); - disp.AppendLayout(m_EndLayout); - } - - disp.WriteStrings(strings); - - disp.Flush(); - - return (Packet)disp; - } - - public static int Intern(this List strings, string value) - { - var indexOf = strings.IndexOf(value); - - if (indexOf >= 0) - { - return indexOf; - } - - strings.Add(value); - return strings.Count - 1; - } - - public static void AppendToByType(this GumpEntry e, IGumpWriter disp, List strings) - { - switch (e) - { - case GumpAlphaRegion g: - { - g.AppendTo(disp, strings); - break; - } - case GumpBackground g: - { - g.AppendTo(disp, strings); - break; - } - case GumpButton g: - { - g.AppendTo(disp, strings); - break; - } - case GumpCheck g: - { - g.AppendTo(disp, strings); - break; - } - case GumpGroup g: - { - g.AppendTo(disp, strings); - break; - } - case GumpECHandleInput g: - { - g.AppendTo(disp, strings); - break; - } - case GumpHtml g: - { - g.AppendTo(disp, strings); - break; - } - case GumpHtmlLocalized g: - { - g.AppendTo(disp, strings); - break; - } - case GumpImage g: - { - g.AppendTo(disp, strings); - break; - } - case GumpImageTileButton g: - { - g.AppendTo(disp, strings); - break; - } - case GumpImageTiled g: - { - g.AppendTo(disp, strings); - break; - } - case GumpItem g: - { - g.AppendTo(disp, strings); - break; - } - case GumpItemProperty g: - { - g.AppendTo(disp, strings); - break; - } - case GumpLabel g: - { - g.AppendTo(disp, strings); - break; - } - case GumpLabelCropped g: - { - g.AppendTo(disp, strings); - break; - } - case GumpMasterGump g: - { - g.AppendTo(disp, strings); - break; - } - case GumpPage g: - { - g.AppendTo(disp, strings); - break; - } - case GumpRadio g: - { - g.AppendTo(disp, strings); - break; - } - case GumpSpriteImage g: - { - g.AppendTo(disp, strings); - break; - } - case GumpTextEntry g: - { - g.AppendTo(disp, strings); - break; - } - case GumpTextEntryLimited g: - { - g.AppendTo(disp, strings); - break; - } - case GumpTooltip g: - { - g.AppendTo(disp, strings); - break; - } - } - } - - public static void AppendTo(this GumpAlphaRegion g, IGumpWriter disp, List strings) - { - disp.AppendLayout(GumpAlphaRegion.LayoutName); - disp.AppendLayout(g.X); - disp.AppendLayout(g.Y); - disp.AppendLayout(g.Width); - disp.AppendLayout(g.Height); - } - - public static void AppendTo(this GumpBackground g, IGumpWriter disp, List strings) - { - disp.AppendLayout(GumpBackground.LayoutName); - disp.AppendLayout(g.X); - disp.AppendLayout(g.Y); - disp.AppendLayout(g.GumpID); - disp.AppendLayout(g.Width); - disp.AppendLayout(g.Height); - } - - public static void AppendTo(this GumpButton g, IGumpWriter disp, List strings) - { - disp.AppendLayout(GumpButton.LayoutName); - disp.AppendLayout(g.X); - disp.AppendLayout(g.Y); - disp.AppendLayout(g.NormalID); - disp.AppendLayout(g.PressedID); - disp.AppendLayout((int)g.Type); - disp.AppendLayout(g.Param); - disp.AppendLayout(g.ButtonID); - } - - public static void AppendTo(this GumpCheck g, IGumpWriter disp, List strings) - { - disp.AppendLayout(GumpButton.LayoutName); - disp.AppendLayout(g.X); - disp.AppendLayout(g.Y); - disp.AppendLayout(g.InactiveID); - disp.AppendLayout(g.ActiveID); - disp.AppendLayout(g.InitialState); - disp.AppendLayout(g.SwitchID); - - disp.Switches++; - } - - public static void AppendTo(this GumpGroup g, IGumpWriter disp, List strings) - { - disp.AppendLayout(GumpGroup.LayoutName); - disp.AppendLayout(g.Group); - } - - public static void AppendTo(this GumpECHandleInput g, IGumpWriter disp, List strings) - { - disp.AppendLayout(GumpECHandleInput.LayoutName); - } - - public static void AppendTo(this GumpHtml g, IGumpWriter disp, List strings) - { - disp.AppendLayout(GumpHtml.LayoutName); - disp.AppendLayout(g.X); - disp.AppendLayout(g.Y); - disp.AppendLayout(g.Width); - disp.AppendLayout(g.Height); - disp.AppendLayout(strings.Intern(g.Text)); - disp.AppendLayout(g.Background); - disp.AppendLayout(g.Scrollbar); - } - - public static void AppendTo(this GumpHtmlLocalized g, IGumpWriter disp, List strings) - { - switch (g.Type) - { - case GumpHtmlLocalizedType.Plain: - { - disp.AppendLayout(GumpHtmlLocalized.LayoutNamePlain); - - disp.AppendLayout(g.X); - disp.AppendLayout(g.Y); - disp.AppendLayout(g.Width); - disp.AppendLayout(g.Height); - disp.AppendLayout(g.Number); - disp.AppendLayout(g.Background); - disp.AppendLayout(g.Scrollbar); - - break; - } - - case GumpHtmlLocalizedType.Color: - { - disp.AppendLayout(GumpHtmlLocalized.LayoutNameColor); - - disp.AppendLayout(g.X); - disp.AppendLayout(g.Y); - disp.AppendLayout(g.Width); - disp.AppendLayout(g.Height); - disp.AppendLayout(g.Number); - disp.AppendLayout(g.Background); - disp.AppendLayout(g.Scrollbar); - disp.AppendLayout(g.Color); - - break; - } - - case GumpHtmlLocalizedType.Args: - { - disp.AppendLayout(GumpHtmlLocalized.LayoutNameArgs); - - disp.AppendLayout(g.X); - disp.AppendLayout(g.Y); - disp.AppendLayout(g.Width); - disp.AppendLayout(g.Height); - disp.AppendLayout(g.Background); - disp.AppendLayout(g.Scrollbar); - disp.AppendLayout(g.Color); - disp.AppendLayout(g.Number); - disp.AppendLayout(g.Args); - - break; - } - } - } - - public static void AppendTo(this GumpImage g, IGumpWriter disp, List strings) - { - disp.AppendLayout(GumpImage.LayoutName); - disp.AppendLayout(g.X); - disp.AppendLayout(g.Y); - disp.AppendLayout(g.GumpID); - - if (g.Hue != 0) - { - disp.AppendLayout(GumpImage.HueEquals); - disp.AppendLayoutNS(g.Hue); - } - - if (!string.IsNullOrEmpty(g.Class)) - { - disp.AppendLayout(GumpImage.ClassEquals); - disp.AppendLayoutNS(g.Class); - } - } - - public static void AppendTo(this GumpImageTileButton g, IGumpWriter disp, List strings) - { - disp.AppendLayout(GumpImageTileButton.LayoutName); - disp.AppendLayout(g.X); - disp.AppendLayout(g.Y); - disp.AppendLayout(g.NormalID); - disp.AppendLayout(g.PressedID); - disp.AppendLayout((int)g.Type); - disp.AppendLayout(g.Param); - disp.AppendLayout(g.ButtonID); - - disp.AppendLayout(g.ItemID); - disp.AppendLayout(g.Hue); - disp.AppendLayout(g.Width); - disp.AppendLayout(g.Height); - - if (g.LocalizedTooltip > 0) - { - disp.AppendLayout(GumpImageTileButton.LayoutTooltip); - disp.AppendLayout(g.LocalizedTooltip); - } - } - - public static void AppendTo(this GumpImageTiled g, IGumpWriter disp, List strings) - { - disp.AppendLayout(GumpImageTiled.LayoutName); - disp.AppendLayout(g.X); - disp.AppendLayout(g.Y); - disp.AppendLayout(g.Width); - disp.AppendLayout(g.Height); - disp.AppendLayout(g.GumpID); - } - - public static void AppendTo(this GumpItem g, IGumpWriter disp, List strings) - { - disp.AppendLayout(g.Hue == 0 ? GumpItem.LayoutName : GumpItem.LayoutNameHue); - disp.AppendLayout(g.X); - disp.AppendLayout(g.Y); - disp.AppendLayout(g.ItemID); - - if (g.Hue != 0) - { - disp.AppendLayout(g.Hue); - } - } - - public static void AppendTo(this GumpItemProperty g, IGumpWriter disp, List strings) - { - disp.AppendLayout(GumpItemProperty.LayoutName); - disp.AppendLayout(g.Serial); - } - - public static void AppendTo(this GumpLabel g, IGumpWriter disp, List strings) - { - disp.AppendLayout(GumpLabel.LayoutName); - disp.AppendLayout(g.X); - disp.AppendLayout(g.Y); - disp.AppendLayout(g.Hue); - disp.AppendLayout(strings.Intern(g.Text)); - } - - public static void AppendTo(this GumpLabelCropped g, IGumpWriter disp, List strings) - { - disp.AppendLayout(GumpLabelCropped.LayoutName); - disp.AppendLayout(g.X); - disp.AppendLayout(g.Y); - disp.AppendLayout(g.Width); - disp.AppendLayout(g.Height); - disp.AppendLayout(g.Hue); - disp.AppendLayout(strings.Intern(g.Text)); - } - - public static void AppendTo(this GumpMasterGump g, IGumpWriter disp, List strings) - { - disp.AppendLayout(GumpMasterGump.LayoutName); - disp.AppendLayout(g.GumpID); - } - - public static void AppendTo(this GumpPage g, IGumpWriter disp, List strings) - { - disp.AppendLayout(GumpPage.LayoutName); - disp.AppendLayout(g.Page); - } - - public static void AppendTo(this GumpRadio g, IGumpWriter disp, List strings) - { - disp.AppendLayout(GumpRadio.LayoutName); - disp.AppendLayout(g.X); - disp.AppendLayout(g.Y); - disp.AppendLayout(g.InactiveID); - disp.AppendLayout(g.ActiveID); - disp.AppendLayout(g.InitialState); - disp.AppendLayout(g.SwitchID); - - disp.Switches++; - } - - public static void AppendTo(this GumpSpriteImage g, IGumpWriter disp, List strings) - { - disp.AppendLayout(GumpSpriteImage.LayoutName); - disp.AppendLayout(g.X); - disp.AppendLayout(g.Y); - disp.AppendLayout(g.GumpID); - disp.AppendLayout(g.Width); - disp.AppendLayout(g.Height); - disp.AppendLayout(g.SX); - disp.AppendLayout(g.SY); - } - - public static void AppendTo(this GumpTextEntry g, IGumpWriter disp, List strings) - { - disp.AppendLayout(GumpTextEntry.LayoutName); - disp.AppendLayout(g.X); - disp.AppendLayout(g.Y); - disp.AppendLayout(g.Width); - disp.AppendLayout(g.Height); - disp.AppendLayout(g.Hue); - disp.AppendLayout(g.EntryID); - disp.AppendLayout(strings.Intern(g.InitialText)); - - disp.TextEntries++; - } - - public static void AppendTo(this GumpTextEntryLimited g, IGumpWriter disp, List strings) - { - disp.AppendLayout(GumpTextEntryLimited.LayoutName); - disp.AppendLayout(g.X); - disp.AppendLayout(g.Y); - disp.AppendLayout(g.Width); - disp.AppendLayout(g.Height); - disp.AppendLayout(g.Hue); - disp.AppendLayout(g.EntryID); - disp.AppendLayout(strings.Intern(g.InitialText)); - disp.AppendLayout(g.Size); - - disp.TextEntries++; - } - - public static void AppendTo(this GumpTooltip g, IGumpWriter disp, List strings) - { - disp.AppendLayout(GumpTooltip.LayoutName); - disp.AppendLayout(g.Number); - - if (!string.IsNullOrEmpty(g.Args)) - { - disp.AppendLayout(g.Args); - } - } - } -} diff --git a/Projects/Benchmarks/Program.cs b/Projects/Benchmarks/Program.cs index 286664e06..34a5462e2 100644 --- a/Projects/Benchmarks/Program.cs +++ b/Projects/Benchmarks/Program.cs @@ -28,7 +28,7 @@ namespace Benchmarks //var mapMultiSelectors = BenchmarkRunner.Run(); // var mapItemsSelectors = BenchmarkRunner.Run(); // var stArray = BenchmarkRunner.Run(); - var pooledRefQueue = BenchmarkRunner.Run(); + // var pooledRefQueue = BenchmarkRunner.Run(); } } } diff --git a/Projects/Server.Tests/Helpers/GumpUtilities.cs b/Projects/Server.Tests/Helpers/GumpUtilities.cs index 70e7c69af..98ef15d59 100644 --- a/Projects/Server.Tests/Helpers/GumpUtilities.cs +++ b/Projects/Server.Tests/Helpers/GumpUtilities.cs @@ -193,7 +193,7 @@ namespace Server.Tests.Network public static void AppendTo(this GumpAlphaRegion g, IGumpWriter disp, List strings) { - disp.AppendLayout(GumpAlphaRegion.LayoutName); + disp.AppendLayout(Gump.StringToBuffer("checkertrans")); disp.AppendLayout(g.X); disp.AppendLayout(g.Y); disp.AppendLayout(g.Width); @@ -202,7 +202,7 @@ namespace Server.Tests.Network public static void AppendTo(this GumpBackground g, IGumpWriter disp, List strings) { - disp.AppendLayout(GumpBackground.LayoutName); + disp.AppendLayout(Gump.StringToBuffer("resizepic")); disp.AppendLayout(g.X); disp.AppendLayout(g.Y); disp.AppendLayout(g.GumpID); @@ -212,7 +212,7 @@ namespace Server.Tests.Network public static void AppendTo(this GumpButton g, IGumpWriter disp, List strings) { - disp.AppendLayout(GumpButton.LayoutName); + disp.AppendLayout(Gump.StringToBuffer("button")); disp.AppendLayout(g.X); disp.AppendLayout(g.Y); disp.AppendLayout(g.NormalID); @@ -224,7 +224,7 @@ namespace Server.Tests.Network public static void AppendTo(this GumpCheck g, IGumpWriter disp, List strings) { - disp.AppendLayout(GumpButton.LayoutName); + disp.AppendLayout(Gump.StringToBuffer("checkbox")); disp.AppendLayout(g.X); disp.AppendLayout(g.Y); disp.AppendLayout(g.InactiveID); @@ -237,18 +237,18 @@ namespace Server.Tests.Network public static void AppendTo(this GumpGroup g, IGumpWriter disp, List strings) { - disp.AppendLayout(GumpGroup.LayoutName); + disp.AppendLayout(Gump.StringToBuffer("group")); disp.AppendLayout(g.Group); } public static void AppendTo(this GumpECHandleInput g, IGumpWriter disp, List strings) { - disp.AppendLayout(GumpECHandleInput.LayoutName); + disp.AppendLayout(Gump.StringToBuffer("echandleinput")); } public static void AppendTo(this GumpHtml g, IGumpWriter disp, List strings) { - disp.AppendLayout(GumpHtml.LayoutName); + disp.AppendLayout(Gump.StringToBuffer("htmlgump")); disp.AppendLayout(g.X); disp.AppendLayout(g.Y); disp.AppendLayout(g.Width); @@ -264,7 +264,7 @@ namespace Server.Tests.Network { case GumpHtmlLocalizedType.Plain: { - disp.AppendLayout(GumpHtmlLocalized.LayoutNamePlain); + disp.AppendLayout(Gump.StringToBuffer("xmfhtmlgump")); disp.AppendLayout(g.X); disp.AppendLayout(g.Y); @@ -279,7 +279,7 @@ namespace Server.Tests.Network case GumpHtmlLocalizedType.Color: { - disp.AppendLayout(GumpHtmlLocalized.LayoutNameColor); + disp.AppendLayout(Gump.StringToBuffer("xmfhtmlgumpcolor")); disp.AppendLayout(g.X); disp.AppendLayout(g.Y); @@ -295,7 +295,7 @@ namespace Server.Tests.Network case GumpHtmlLocalizedType.Args: { - disp.AppendLayout(GumpHtmlLocalized.LayoutNameArgs); + disp.AppendLayout(Gump.StringToBuffer("xmfhtmltok")); disp.AppendLayout(g.X); disp.AppendLayout(g.Y); @@ -314,27 +314,27 @@ namespace Server.Tests.Network public static void AppendTo(this GumpImage g, IGumpWriter disp, List strings) { - disp.AppendLayout(GumpImage.LayoutName); + disp.AppendLayout(Gump.StringToBuffer("gumppic")); disp.AppendLayout(g.X); disp.AppendLayout(g.Y); disp.AppendLayout(g.GumpID); if (g.Hue != 0) { - disp.AppendLayout(GumpImage.HueEquals); + disp.AppendLayoutNS(" hue="); disp.AppendLayoutNS(g.Hue); } if (!string.IsNullOrEmpty(g.Class)) { - disp.AppendLayout(GumpImage.ClassEquals); - disp.AppendLayoutNS(g.Class); + disp.AppendLayoutNS(" class="); + disp.AppendLayout(Gump.StringToBuffer(g.Class)); } } public static void AppendTo(this GumpImageTileButton g, IGumpWriter disp, List strings) { - disp.AppendLayout(GumpImageTileButton.LayoutName); + disp.AppendLayout(Gump.StringToBuffer("buttontileart")); disp.AppendLayout(g.X); disp.AppendLayout(g.Y); disp.AppendLayout(g.NormalID); @@ -347,17 +347,11 @@ namespace Server.Tests.Network disp.AppendLayout(g.Hue); disp.AppendLayout(g.Width); disp.AppendLayout(g.Height); - - if (g.LocalizedTooltip > 0) - { - disp.AppendLayout(GumpImageTileButton.LayoutTooltip); - disp.AppendLayout(g.LocalizedTooltip); - } } public static void AppendTo(this GumpImageTiled g, IGumpWriter disp, List strings) { - disp.AppendLayout(GumpImageTiled.LayoutName); + disp.AppendLayout(Gump.StringToBuffer("gumppictiled")); disp.AppendLayout(g.X); disp.AppendLayout(g.Y); disp.AppendLayout(g.Width); @@ -367,7 +361,7 @@ namespace Server.Tests.Network public static void AppendTo(this GumpItem g, IGumpWriter disp, List strings) { - disp.AppendLayout(g.Hue == 0 ? GumpItem.LayoutName : GumpItem.LayoutNameHue); + disp.AppendLayout(Gump.StringToBuffer(g.Hue == 0 ? "tilepic" : "tilepichue")); disp.AppendLayout(g.X); disp.AppendLayout(g.Y); disp.AppendLayout(g.ItemID); @@ -380,13 +374,13 @@ namespace Server.Tests.Network public static void AppendTo(this GumpItemProperty g, IGumpWriter disp, List strings) { - disp.AppendLayout(GumpItemProperty.LayoutName); + disp.AppendLayout(Gump.StringToBuffer("itemproperty")); disp.AppendLayout(g.Serial); } public static void AppendTo(this GumpLabel g, IGumpWriter disp, List strings) { - disp.AppendLayout(GumpLabel.LayoutName); + disp.AppendLayout(Gump.StringToBuffer("text")); disp.AppendLayout(g.X); disp.AppendLayout(g.Y); disp.AppendLayout(g.Hue); @@ -395,7 +389,7 @@ namespace Server.Tests.Network public static void AppendTo(this GumpLabelCropped g, IGumpWriter disp, List strings) { - disp.AppendLayout(GumpLabelCropped.LayoutName); + disp.AppendLayout(Gump.StringToBuffer("croppedtext")); disp.AppendLayout(g.X); disp.AppendLayout(g.Y); disp.AppendLayout(g.Width); @@ -406,19 +400,19 @@ namespace Server.Tests.Network public static void AppendTo(this GumpMasterGump g, IGumpWriter disp, List strings) { - disp.AppendLayout(GumpMasterGump.LayoutName); + disp.AppendLayout(Gump.StringToBuffer("mastergump")); disp.AppendLayout(g.GumpID); } public static void AppendTo(this GumpPage g, IGumpWriter disp, List strings) { - disp.AppendLayout(GumpPage.LayoutName); + disp.AppendLayout(Gump.StringToBuffer("page")); disp.AppendLayout(g.Page); } public static void AppendTo(this GumpRadio g, IGumpWriter disp, List strings) { - disp.AppendLayout(GumpRadio.LayoutName); + disp.AppendLayout(Gump.StringToBuffer("radio")); disp.AppendLayout(g.X); disp.AppendLayout(g.Y); disp.AppendLayout(g.InactiveID); @@ -431,7 +425,7 @@ namespace Server.Tests.Network public static void AppendTo(this GumpSpriteImage g, IGumpWriter disp, List strings) { - disp.AppendLayout(GumpSpriteImage.LayoutName); + disp.AppendLayout(Gump.StringToBuffer("picinpic")); disp.AppendLayout(g.X); disp.AppendLayout(g.Y); disp.AppendLayout(g.GumpID); @@ -443,7 +437,7 @@ namespace Server.Tests.Network public static void AppendTo(this GumpTextEntry g, IGumpWriter disp, List strings) { - disp.AppendLayout(GumpTextEntry.LayoutName); + disp.AppendLayout(Gump.StringToBuffer("textentry")); disp.AppendLayout(g.X); disp.AppendLayout(g.Y); disp.AppendLayout(g.Width); @@ -457,7 +451,7 @@ namespace Server.Tests.Network public static void AppendTo(this GumpTextEntryLimited g, IGumpWriter disp, List strings) { - disp.AppendLayout(GumpTextEntryLimited.LayoutName); + disp.AppendLayout(Gump.StringToBuffer("textentrylimited")); disp.AppendLayout(g.X); disp.AppendLayout(g.Y); disp.AppendLayout(g.Width); @@ -472,7 +466,7 @@ namespace Server.Tests.Network public static void AppendTo(this GumpTooltip g, IGumpWriter disp, List strings) { - disp.AppendLayout(GumpTooltip.LayoutName); + disp.AppendLayout(Gump.StringToBuffer("tooltip")); disp.AppendLayout(g.Number); if (!string.IsNullOrEmpty(g.Args)) diff --git a/Projects/Server.Tests/Tests/Network/Packets/Outgoing/GumpPacketTests.cs b/Projects/Server.Tests/Tests/Network/Packets/Outgoing/GumpPacketTests.cs index fd8aeba6c..61332a2a0 100644 --- a/Projects/Server.Tests/Tests/Network/Packets/Outgoing/GumpPacketTests.cs +++ b/Projects/Server.Tests/Tests/Network/Packets/Outgoing/GumpPacketTests.cs @@ -24,9 +24,9 @@ namespace Server.Tests.Network public void TestDisplaySignGump() { Serial gumpSerial = (Serial)0x1000; - var gumpId = 100; - var unknownString = "This is an unknown string"; - var caption = "This is a caption"; + const int gumpId = 100; + const string unknownString = "This is an unknown string"; + const string caption = "This is a caption"; var expected = new DisplaySignGump(gumpSerial, gumpId, unknownString, caption).Compile(); diff --git a/Projects/Server/Gumps/Gump.cs b/Projects/Server/Gumps/Gump.cs index cc0940914..f3ccb13a4 100644 --- a/Projects/Server/Gumps/Gump.cs +++ b/Projects/Server/Gumps/Gump.cs @@ -3,259 +3,257 @@ using System.Collections.Generic; using Server.Network; using Server.Text; -namespace Server.Gumps +namespace Server.Gumps; + +public class Gump { - public class Gump + private static Serial _nextSerial = (Serial)1; + + public static readonly byte[] NoMove = StringToBuffer("{ nomove }"); + public static readonly byte[] NoClose = StringToBuffer("{ noclose }"); + public static readonly byte[] NoDispose = StringToBuffer("{ nodispose }"); + public static readonly byte[] NoResize = StringToBuffer("{ noresize }"); + + internal int m_TextEntries, m_Switches; + + public Gump(int x, int y) { - private static Serial _nextSerial = (Serial)1; - - public static readonly byte[] NoMove = StringToBuffer("{ nomove }"); - public static readonly byte[] NoClose = StringToBuffer("{ noclose }"); - public static readonly byte[] NoDispose = StringToBuffer("{ nodispose }"); - public static readonly byte[] NoResize = StringToBuffer("{ noresize }"); - - internal int m_TextEntries, m_Switches; - - public Gump(int x, int y) + do { - do - { - Serial = _nextSerial++; - } while (Serial == 0); // standard client apparently doesn't send a gump response packet if serial == 0 + Serial = _nextSerial++; + } while (Serial == 0); // standard client apparently doesn't send a gump response packet if serial == 0 - X = x; - Y = y; + X = x; + Y = y; - TypeID = GetTypeID(GetType()); + TypeID = GetTypeID(GetType()); - Entries = new List(); - Strings = new List(); + Entries = new List(); + Strings = new List(); + } + + public List Strings { get; } + + public int TypeID { get; } + + public List Entries { get; } + + public Serial Serial { get; set; } + + public int X { get; set; } + + public int Y { get; set; } + + public bool Disposable { get; set; } = true; + + public bool Resizable { get; set; } = true; + + public bool Draggable { get; set; } = true; + + public bool Closable { get; set; } = true; + + public static int GetTypeID(Type type) => type?.FullName?.GetHashCode(StringComparison.Ordinal) ?? -1; + + public void AddPage(int page) + { + Add(new GumpPage(page)); + } + + public void AddAlphaRegion(int x, int y, int width, int height) + { + Add(new GumpAlphaRegion(x, y, width, height)); + } + + public void AddBackground(int x, int y, int width, int height, int gumpID) + { + Add(new GumpBackground(x, y, width, height, gumpID)); + } + + public void AddButton( + int x, int y, int normalID, int pressedID, int buttonID, + GumpButtonType type = GumpButtonType.Reply, int param = 0 + ) + { + Add(new GumpButton(x, y, normalID, pressedID, buttonID, type, param)); + } + + public void AddCheck(int x, int y, int inactiveID, int activeID, bool initialState, int switchID) + { + Add(new GumpCheck(x, y, inactiveID, activeID, initialState, switchID)); + } + + public void AddGroup(int group) + { + Add(new GumpGroup(group)); + } + + public void AddTooltip(int number, string args = null) + { + Add(new GumpTooltip(number, args)); + } + + public void AddHtml( + int x, int y, int width, int height, string text, bool background = false, bool scrollbar = false + ) + { + Add(new GumpHtml(x, y, width, height, text, background, scrollbar)); + } + + public void AddHtmlLocalized( + int x, int y, int width, int height, int number, bool background = false, + bool scrollbar = false + ) + { + Add(new GumpHtmlLocalized(x, y, width, height, number, background, scrollbar)); + } + + public void AddHtmlLocalized( + int x, int y, int width, int height, int number, int color, bool background = false, + bool scrollbar = false + ) + { + Add(new GumpHtmlLocalized(x, y, width, height, number, color, background, scrollbar)); + } + + public void AddHtmlLocalized( + int x, int y, int width, int height, int number, string args, int color, + bool background = false, bool scrollbar = false + ) + { + Add(new GumpHtmlLocalized(x, y, width, height, number, args, color, background, scrollbar)); + } + + public void AddImage(int x, int y, int gumpID, int hue = 0) + { + Add(new GumpImage(x, y, gumpID, hue)); + } + + public void AddImageTiled(int x, int y, int width, int height, int gumpID) + { + Add(new GumpImageTiled(x, y, width, height, gumpID)); + } + + public void AddImageTiledButton( + int x, int y, int normalID, int pressedID, int buttonID, GumpButtonType type, + int param, int itemID, int hue, int width, int height + ) + { + Add( + new GumpImageTileButton( + x, + y, + normalID, + pressedID, + buttonID, + type, + param, + itemID, + hue, + width, + height + ) + ); + } + + public void AddItem(int x, int y, int itemID, int hue = 0) + { + Add(new GumpItem(x, y, itemID, hue)); + } + + public void AddLabel(int x, int y, int hue, string text) + { + Add(new GumpLabel(x, y, hue, text)); + } + + public void AddLabelCropped(int x, int y, int width, int height, int hue, string text) + { + Add(new GumpLabelCropped(x, y, width, height, hue, text)); + } + + public void AddRadio(int x, int y, int inactiveID, int activeID, bool initialState, int switchID) + { + Add(new GumpRadio(x, y, inactiveID, activeID, initialState, switchID)); + } + + public void AddTextEntry(int x, int y, int width, int height, int hue, int entryID, string initialText) + { + Add(new GumpTextEntry(x, y, width, height, hue, entryID, initialText)); + } + + public void AddTextEntry(int x, int y, int width, int height, int hue, int entryID, string initialText, int size) + { + Add(new GumpTextEntryLimited(x, y, width, height, hue, entryID, initialText, size)); + } + + public void AddItemProperty(Serial serial) + { + Add(new GumpItemProperty(serial)); + } + + public void AddSpriteImage(int x, int y, int gumpID, int width, int height, int sx, int sy) + { + Add(new GumpSpriteImage(x, y, gumpID, width, height, sx, sy)); + } + + public void AddECHandleInput() + { + Add(new GumpECHandleInput()); + } + + public void AddGumpIDOverride(int gumpID) + { + Add(new GumpMasterGump(gumpID)); + } + + public void Add(GumpEntry g) + { + if (g.Parent != this) + { + g.Parent = this; } - - public List Strings { get; } - - public int TypeID { get; } - - public List Entries { get; } - - public Serial Serial { get; set; } - - public int X { get; set; } - - public int Y { get; set; } - - public bool Disposable { get; set; } = true; - - public bool Resizable { get; set; } = true; - - public bool Draggable { get; set; } = true; - - public bool Closable { get; set; } = true; - - public static int GetTypeID(Type type) => type?.FullName?.GetHashCode(StringComparison.Ordinal) ?? -1; - - public void AddPage(int page) - { - Add(new GumpPage(page)); - } - - public void AddAlphaRegion(int x, int y, int width, int height) - { - Add(new GumpAlphaRegion(x, y, width, height)); - } - - public void AddBackground(int x, int y, int width, int height, int gumpID) - { - Add(new GumpBackground(x, y, width, height, gumpID)); - } - - public void AddButton( - int x, int y, int normalID, int pressedID, int buttonID, - GumpButtonType type = GumpButtonType.Reply, int param = 0 - ) - { - Add(new GumpButton(x, y, normalID, pressedID, buttonID, type, param)); - } - - public void AddCheck(int x, int y, int inactiveID, int activeID, bool initialState, int switchID) - { - Add(new GumpCheck(x, y, inactiveID, activeID, initialState, switchID)); - } - - public void AddGroup(int group) - { - Add(new GumpGroup(group)); - } - - public void AddTooltip(int number, string args = null) - { - Add(new GumpTooltip(number, args)); - } - - public void AddHtml( - int x, int y, int width, int height, string text, bool background = false, bool scrollbar = false - ) - { - Add(new GumpHtml(x, y, width, height, text, background, scrollbar)); - } - - public void AddHtmlLocalized( - int x, int y, int width, int height, int number, bool background = false, - bool scrollbar = false - ) - { - Add(new GumpHtmlLocalized(x, y, width, height, number, background, scrollbar)); - } - - public void AddHtmlLocalized( - int x, int y, int width, int height, int number, int color, bool background = false, - bool scrollbar = false - ) - { - Add(new GumpHtmlLocalized(x, y, width, height, number, color, background, scrollbar)); - } - - public void AddHtmlLocalized( - int x, int y, int width, int height, int number, string args, int color, - bool background = false, bool scrollbar = false - ) - { - Add(new GumpHtmlLocalized(x, y, width, height, number, args, color, background, scrollbar)); - } - - public void AddImage(int x, int y, int gumpID, int hue = 0) - { - Add(new GumpImage(x, y, gumpID, hue)); - } - - public void AddImageTiled(int x, int y, int width, int height, int gumpID) - { - Add(new GumpImageTiled(x, y, width, height, gumpID)); - } - - public void AddImageTiledButton( - int x, int y, int normalID, int pressedID, int buttonID, GumpButtonType type, - int param, int itemID, int hue, int width, int height, int localizedTooltip = -1 - ) - { - Add( - new GumpImageTileButton( - x, - y, - normalID, - pressedID, - buttonID, - type, - param, - itemID, - hue, - width, - height, - localizedTooltip - ) - ); - } - - public void AddItem(int x, int y, int itemID, int hue = 0) - { - Add(new GumpItem(x, y, itemID, hue)); - } - - public void AddLabel(int x, int y, int hue, string text) - { - Add(new GumpLabel(x, y, hue, text)); - } - - public void AddLabelCropped(int x, int y, int width, int height, int hue, string text) - { - Add(new GumpLabelCropped(x, y, width, height, hue, text)); - } - - public void AddRadio(int x, int y, int inactiveID, int activeID, bool initialState, int switchID) - { - Add(new GumpRadio(x, y, inactiveID, activeID, initialState, switchID)); - } - - public void AddTextEntry(int x, int y, int width, int height, int hue, int entryID, string initialText) - { - Add(new GumpTextEntry(x, y, width, height, hue, entryID, initialText)); - } - - public void AddTextEntry(int x, int y, int width, int height, int hue, int entryID, string initialText, int size) - { - Add(new GumpTextEntryLimited(x, y, width, height, hue, entryID, initialText, size)); - } - - public void AddItemProperty(Serial serial) - { - Add(new GumpItemProperty(serial)); - } - - public void AddSpriteImage(int x, int y, int gumpID, int width, int height, int sx, int sy) - { - Add(new GumpSpriteImage(x, y, gumpID, width, height, sx, sy)); - } - - public void AddECHandleInput() - { - Add(new GumpECHandleInput()); - } - - public void AddGumpIDOverride(int gumpID) - { - Add(new GumpMasterGump(gumpID)); - } - - public void Add(GumpEntry g) - { - if (g.Parent != this) - { - g.Parent = this; - } - else if (!Entries.Contains(g)) - { - Entries.Add(g); - } - } - - public void Remove(GumpEntry g) - { - if (g == null || !Entries.Contains(g)) - { - return; - } - - Entries.Remove(g); - g.Parent = null; - } - - public int Intern(string value) - { - var indexOf = Strings.IndexOf(value); - - if (indexOf >= 0) - { - return indexOf; - } - - Strings.Add(value); - return Strings.Count - 1; - } - - public void SendTo(NetState state) - { - state.AddGump(this); - state.SendDisplayGump(this, out m_Switches, out m_TextEntries); - } - - public static byte[] StringToBuffer(string str) => str.GetBytesAscii(); - - public virtual void OnResponse(NetState sender, RelayInfo info) - { - } - - public virtual void OnServerClose(NetState owner) + else if (!Entries.Contains(g)) { + Entries.Add(g); } } + + public void Remove(GumpEntry g) + { + if (g == null || !Entries.Contains(g)) + { + return; + } + + Entries.Remove(g); + g.Parent = null; + } + + public int Intern(string value) + { + var indexOf = Strings.IndexOf(value); + + if (indexOf >= 0) + { + return indexOf; + } + + Strings.Add(value); + return Strings.Count - 1; + } + + public void SendTo(NetState state) + { + state.AddGump(this); + state.SendDisplayGump(this, out m_Switches, out m_TextEntries); + } + + public static byte[] StringToBuffer(string str) => str.GetBytesAscii(); + + public virtual void OnResponse(NetState sender, RelayInfo info) + { + } + + public virtual void OnServerClose(NetState owner) + { + } } diff --git a/Projects/Server/Gumps/GumpAlphaRegion.cs b/Projects/Server/Gumps/GumpAlphaRegion.cs index f58acfcb7..376aacd0d 100644 --- a/Projects/Server/Gumps/GumpAlphaRegion.cs +++ b/Projects/Server/Gumps/GumpAlphaRegion.cs @@ -1,6 +1,6 @@ /************************************************************************* * ModernUO * - * Copyright (C) 2019-2021 - ModernUO Development Team * + * Copyright (C) 2019-2022 - ModernUO Development Team * * Email: hi@modernuo.com * * File: GumpAlphaRegion.cs * * * @@ -16,43 +16,28 @@ using System.Buffers; using Server.Collections; -namespace Server.Gumps +namespace Server.Gumps; + +public class GumpAlphaRegion : GumpEntry { - public class GumpAlphaRegion : GumpEntry + public GumpAlphaRegion(int x, int y, int width, int height) { - public static readonly byte[] LayoutName = Gump.StringToBuffer("checkertrans"); + X = x; + Y = y; + Width = width; + Height = height; + } - public GumpAlphaRegion(int x, int y, int width, int height) - { - X = x; - Y = y; - Width = width; - Height = height; - } + public int X { get; set; } - public int X { get; set; } + public int Y { get; set; } - public int Y { get; set; } + public int Width { get; set; } - public int Width { get; set; } + public int Height { get; set; } - public int Height { get; set; } - - public override string Compile(OrderedHashSet strings) => $"{{ checkertrans {X} {Y} {Width} {Height} }}"; - - public override void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches) - { - writer.Write((ushort)0x7B20); // "{ " - writer.Write(LayoutName); - writer.WriteAscii(' '); - writer.WriteAscii(X.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Y.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Width.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Height.ToString()); - writer.Write((ushort)0x207D); // " }" - } + public override void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches) + { + writer.WriteAscii($"{{ checkertrans {X} {Y} {Width} {Height} }}"); } } diff --git a/Projects/Server/Gumps/GumpBackground.cs b/Projects/Server/Gumps/GumpBackground.cs index 7232a43f2..422fe063a 100644 --- a/Projects/Server/Gumps/GumpBackground.cs +++ b/Projects/Server/Gumps/GumpBackground.cs @@ -1,6 +1,6 @@ /************************************************************************* * ModernUO * - * Copyright (C) 2019-2021 - ModernUO Development Team * + * Copyright (C) 2019-2022 - ModernUO Development Team * * Email: hi@modernuo.com * * File: GumpBackground.cs * * * @@ -16,48 +16,31 @@ using System.Buffers; using Server.Collections; -namespace Server.Gumps +namespace Server.Gumps; + +public class GumpBackground : GumpEntry { - public class GumpBackground : GumpEntry + public GumpBackground(int x, int y, int width, int height, int gumpID) { - public static readonly byte[] LayoutName = Gump.StringToBuffer("resizepic"); + X = x; + Y = y; + Width = width; + Height = height; + GumpID = gumpID; + } - public GumpBackground(int x, int y, int width, int height, int gumpID) - { - X = x; - Y = y; - Width = width; - Height = height; - GumpID = gumpID; - } + public int X { get; set; } - public int X { get; set; } + public int Y { get; set; } - public int Y { get; set; } + public int Width { get; set; } - public int Width { get; set; } + public int Height { get; set; } - public int Height { get; set; } + public int GumpID { get; set; } - public int GumpID { get; set; } - - public override string Compile(OrderedHashSet strings) => $"{{ resizepic {X} {Y} {GumpID} {Width} {Height} }}"; - - public override void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches) - { - writer.Write((ushort)0x7B20); // "{ " - writer.Write(LayoutName); - writer.WriteAscii(' '); - writer.WriteAscii(X.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Y.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(GumpID.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Width.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Height.ToString()); - writer.Write((ushort)0x207D); // " }" - } + public override void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches) + { + writer.WriteAscii($"{{ resizepic {X} {Y} {GumpID} {Width} {Height} }}"); } } diff --git a/Projects/Server/Gumps/GumpButton.cs b/Projects/Server/Gumps/GumpButton.cs index b87991762..679bffbf9 100644 --- a/Projects/Server/Gumps/GumpButton.cs +++ b/Projects/Server/Gumps/GumpButton.cs @@ -1,6 +1,6 @@ /************************************************************************* * ModernUO * - * Copyright (C) 2019-2021 - ModernUO Development Team * + * Copyright (C) 2019-2022 - ModernUO Development Team * * Email: hi@modernuo.com * * File: GumpButton.cs * * * @@ -16,68 +16,46 @@ using System.Buffers; using Server.Collections; -namespace Server.Gumps +namespace Server.Gumps; + +public enum GumpButtonType { - public enum GumpButtonType + Page = 0, + Reply = 1 +} + +public class GumpButton : GumpEntry +{ + public GumpButton( + int x, int y, int normalID, int pressedID, int buttonID, + GumpButtonType type = GumpButtonType.Reply, int param = 0 + ) { - Page = 0, - Reply = 1 + X = x; + Y = y; + NormalID = normalID; + PressedID = pressedID; + ButtonID = buttonID; + Type = type; + Param = param; } - public class GumpButton : GumpEntry + public int X { get; set; } + + public int Y { get; set; } + + public int NormalID { get; set; } + + public int PressedID { get; set; } + + public int ButtonID { get; set; } + + public GumpButtonType Type { get; set; } + + public int Param { get; set; } + + public override void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches) { - public static readonly byte[] LayoutName = Gump.StringToBuffer("button"); - - public GumpButton( - int x, int y, int normalID, int pressedID, int buttonID, - GumpButtonType type = GumpButtonType.Reply, int param = 0 - ) - { - X = x; - Y = y; - NormalID = normalID; - PressedID = pressedID; - ButtonID = buttonID; - Type = type; - Param = param; - } - - public int X { get; set; } - - public int Y { get; set; } - - public int NormalID { get; set; } - - public int PressedID { get; set; } - - public int ButtonID { get; set; } - - public GumpButtonType Type { get; set; } - - public int Param { get; set; } - - public override string Compile(OrderedHashSet strings) => - $"{{ button {X} {Y} {NormalID} {PressedID} {(int)Type} {Param} {ButtonID} }}"; - - public override void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches) - { - writer.Write((ushort)0x7B20); // "{ " - writer.Write(LayoutName); - writer.WriteAscii(' '); - writer.WriteAscii(X.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Y.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(NormalID.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(PressedID.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(((int)Type).ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Param.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(ButtonID.ToString()); - writer.Write((ushort)0x207D); // " }" - } + writer.WriteAscii($"{{ button {X} {Y} {NormalID} {PressedID} {(int)Type} {Param} {ButtonID} }}"); } } diff --git a/Projects/Server/Gumps/GumpCheck.cs b/Projects/Server/Gumps/GumpCheck.cs index 21b5e0d71..bcfa289d4 100644 --- a/Projects/Server/Gumps/GumpCheck.cs +++ b/Projects/Server/Gumps/GumpCheck.cs @@ -1,6 +1,6 @@ /************************************************************************* * ModernUO * - * Copyright (C) 2019-2021 - ModernUO Development Team * + * Copyright (C) 2019-2022 - ModernUO Development Team * * Email: hi@modernuo.com * * File: GumpCheck.cs * * * @@ -16,56 +16,36 @@ using System.Buffers; using Server.Collections; -namespace Server.Gumps +namespace Server.Gumps; + +public class GumpCheck : GumpEntry { - public class GumpCheck : GumpEntry + public GumpCheck(int x, int y, int inactiveID, int activeID, bool initialState, int switchID) { - public static readonly byte[] LayoutName = Gump.StringToBuffer("checkbox"); + X = x; + Y = y; + InactiveID = inactiveID; + ActiveID = activeID; + InitialState = initialState; + SwitchID = switchID; + } - public GumpCheck(int x, int y, int inactiveID, int activeID, bool initialState, int switchID) - { - X = x; - Y = y; - InactiveID = inactiveID; - ActiveID = activeID; - InitialState = initialState; - SwitchID = switchID; - } + public int X { get; set; } - public int X { get; set; } + public int Y { get; set; } - public int Y { get; set; } + public int InactiveID { get; set; } - public int InactiveID { get; set; } + public int ActiveID { get; set; } - public int ActiveID { get; set; } + public bool InitialState { get; set; } - public bool InitialState { get; set; } + public int SwitchID { get; set; } - public int SwitchID { get; set; } - - public override string Compile(OrderedHashSet strings) => - $"{{ checkbox {X} {Y} {InactiveID} {ActiveID} {(InitialState ? 1 : 0)} {SwitchID} }}"; - - public override void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches) - { - writer.Write((ushort)0x7B20); // "{ " - writer.Write(LayoutName); - writer.WriteAscii(' '); - writer.WriteAscii(X.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Y.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(InactiveID.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(ActiveID.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(InitialState ? '1' : '0'); - writer.WriteAscii(' '); - writer.WriteAscii(SwitchID.ToString()); - writer.Write((ushort)0x207D); // " }" - - switches++; - } + public override void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches) + { + var initialState = InitialState ? "1" : "0"; + writer.WriteAscii($"{{ checkbox {X} {Y} {InactiveID} {ActiveID} {initialState} {SwitchID} }}"); + switches++; } } diff --git a/Projects/Server/Gumps/GumpECHandleInput.cs b/Projects/Server/Gumps/GumpECHandleInput.cs index 3c3f36ea2..2bd494a8e 100644 --- a/Projects/Server/Gumps/GumpECHandleInput.cs +++ b/Projects/Server/Gumps/GumpECHandleInput.cs @@ -16,16 +16,14 @@ using System.Buffers; using Server.Collections; -namespace Server.Gumps -{ - public class GumpECHandleInput : GumpEntry - { - public static readonly byte[] LayoutName = Gump.StringToBuffer("echandleinput"); - public override string Compile(OrderedHashSet strings) => "{ echandleinput }"; +namespace Server.Gumps; - public override void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches) - { - writer.WriteAscii("{ echandleinput }"); - } +public class GumpECHandleInput : GumpEntry +{ + private static byte[] _layout = Gump.StringToBuffer("{ echandleinput }"); + + public override void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches) + { + writer.Write(_layout); } } diff --git a/Projects/Server/Gumps/GumpEntry.cs b/Projects/Server/Gumps/GumpEntry.cs index fe669f390..175f6f813 100644 --- a/Projects/Server/Gumps/GumpEntry.cs +++ b/Projects/Server/Gumps/GumpEntry.cs @@ -1,32 +1,29 @@ using System.Buffers; using Server.Collections; -namespace Server.Gumps +namespace Server.Gumps; + +public abstract class GumpEntry { - public abstract class GumpEntry + private Gump m_Parent; + + public Gump Parent { - private Gump m_Parent; - - public Gump Parent + get => m_Parent; + set { - get => m_Parent; - set + if (m_Parent != value) { - if (m_Parent != value) - { - m_Parent?.Remove(this); + m_Parent?.Remove(this); - m_Parent = value; + m_Parent = value; - m_Parent?.Add(this); - } + m_Parent?.Add(this); } } - - public abstract string Compile(OrderedHashSet strings); - - // TODO: Replace OrderedHashSet with InsertOnlyHashSet, a copy of HashSet that is ReadOnly compatible, but includes - // a public AddIfNotPresent function that returns the index of the element - public abstract void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches); } + + // TODO: Replace OrderedHashSet with InsertOnlyHashSet, a copy of HashSet that is ReadOnly compatible, but includes + // a public AddIfNotPresent function that returns the index of the element + public abstract void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches); } diff --git a/Projects/Server/Gumps/GumpGroup.cs b/Projects/Server/Gumps/GumpGroup.cs index e9d75f3f0..a24c0debc 100644 --- a/Projects/Server/Gumps/GumpGroup.cs +++ b/Projects/Server/Gumps/GumpGroup.cs @@ -1,6 +1,6 @@ /************************************************************************* * ModernUO * - * Copyright (C) 2019-2021 - ModernUO Development Team * + * Copyright (C) 2019-2022 - ModernUO Development Team * * Email: hi@modernuo.com * * File: GumpGroup.cs * * * @@ -16,24 +16,25 @@ using System.Buffers; using Server.Collections; -namespace Server.Gumps +namespace Server.Gumps; + +public class GumpGroup : GumpEntry { - public class GumpGroup : GumpEntry + private static byte[] _group1 = Gump.StringToBuffer("{ group 1 }"); + + public GumpGroup(int group) => Group = group; + + public int Group { get; set; } + + public override void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches) { - public static readonly byte[] LayoutName = Gump.StringToBuffer("group"); - - public GumpGroup(int group) => Group = group; - - public int Group { get; set; } - public override string Compile(OrderedHashSet strings) => $"{{ group {Group} }}"; - - public override void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches) + if (Group == 1) { - writer.Write((ushort)0x7B20); // "{ " - writer.Write(LayoutName); - writer.WriteAscii(' '); - writer.WriteAscii(Group.ToString()); - writer.Write((ushort)0x207D); // " }" + writer.Write(_group1); + } + else + { + writer.WriteAscii($"{{ group {Group} }}"); } } } diff --git a/Projects/Server/Gumps/GumpHtml.cs b/Projects/Server/Gumps/GumpHtml.cs index cb0759960..12b77ed05 100644 --- a/Projects/Server/Gumps/GumpHtml.cs +++ b/Projects/Server/Gumps/GumpHtml.cs @@ -1,6 +1,6 @@ /************************************************************************* * ModernUO * - * Copyright (C) 2019-2021 - ModernUO Development Team * + * Copyright (C) 2019-2022 - ModernUO Development Team * * Email: hi@modernuo.com * * File: GumpHtml.cs * * * @@ -16,59 +16,40 @@ using System.Buffers; using Server.Collections; -namespace Server.Gumps +namespace Server.Gumps; + +public class GumpHtml : GumpEntry { - public class GumpHtml : GumpEntry + public GumpHtml(int x, int y, int width, int height, string text, bool background, bool scrollbar) { - public static readonly byte[] LayoutName = Gump.StringToBuffer("htmlgump"); + X = x; + Y = y; + Width = width; + Height = height; + Text = text; + Background = background; + Scrollbar = scrollbar; + } - public GumpHtml(int x, int y, int width, int height, string text, bool background, bool scrollbar) - { - X = x; - Y = y; - Width = width; - Height = height; - Text = text; - Background = background; - Scrollbar = scrollbar; - } + public int X { get; set; } - public int X { get; set; } + public int Y { get; set; } - public int Y { get; set; } + public int Width { get; set; } - public int Width { get; set; } + public int Height { get; set; } - public int Height { get; set; } + public string Text { get; set; } - public string Text { get; set; } + public bool Background { get; set; } - public bool Background { get; set; } + public bool Scrollbar { get; set; } - public bool Scrollbar { get; set; } - - public override string Compile(OrderedHashSet strings) => - $"{{ htmlgump {X} {Y} {Width} {Height} {strings.GetOrAdd(Text ?? "")} {(Background ? 1 : 0)} {(Scrollbar ? 1 : 0)} }}"; - - public override void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches) - { - writer.Write((ushort)0x7B20); // "{ " - writer.Write(LayoutName); - writer.WriteAscii(' '); - writer.WriteAscii(X.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Y.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Width.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Height.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(strings.GetOrAdd(Text ?? "").ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Background ? '1' : '0'); - writer.WriteAscii(' '); - writer.WriteAscii(Scrollbar ? '1' : '0'); - writer.Write((ushort)0x207D); // " }" - } + public override void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches) + { + var textIndex = strings.GetOrAdd(Text ?? ""); + var background = Background ? "1" : "0"; + var scrollbar = Scrollbar ? "1" : "0"; + writer.WriteAscii($"{{ htmlgump {X} {Y} {Width} {Height} {textIndex} {background} {scrollbar} }}"); } } diff --git a/Projects/Server/Gumps/GumpHtmlLocalized.cs b/Projects/Server/Gumps/GumpHtmlLocalized.cs index 39fe020b4..71362f770 100644 --- a/Projects/Server/Gumps/GumpHtmlLocalized.cs +++ b/Projects/Server/Gumps/GumpHtmlLocalized.cs @@ -1,6 +1,6 @@ /************************************************************************* * ModernUO * - * Copyright (C) 2019-2021 - ModernUO Development Team * + * Copyright (C) 2019-2022 - ModernUO Development Team * * Email: hi@modernuo.com * * File: GumpHtmlLocalized.cs * * * @@ -16,95 +16,94 @@ using System.Buffers; using Server.Collections; -namespace Server.Gumps +namespace Server.Gumps; + +public enum GumpHtmlLocalizedType { - public enum GumpHtmlLocalizedType + Plain, + Color, + Args +} + +public class GumpHtmlLocalized : GumpEntry +{ + public GumpHtmlLocalized( + int x, int y, int width, int height, int number, + bool background = false, bool scrollbar = false + ) { - Plain, - Color, - Args + X = x; + Y = y; + Width = width; + Height = height; + Number = number; + Background = background; + Scrollbar = scrollbar; + + Type = GumpHtmlLocalizedType.Plain; } - public class GumpHtmlLocalized : GumpEntry + public GumpHtmlLocalized( + int x, int y, int width, int height, int number, int color, + bool background = false, bool scrollbar = false + ) { - public static readonly byte[] LayoutNamePlain = Gump.StringToBuffer("xmfhtmlgump"); - public static readonly byte[] LayoutNameColor = Gump.StringToBuffer("xmfhtmlgumpcolor"); - public static readonly byte[] LayoutNameArgs = Gump.StringToBuffer("xmfhtmltok"); + X = x; + Y = y; + Width = width; + Height = height; + Number = number; + Color = color; + Background = background; + Scrollbar = scrollbar; - public GumpHtmlLocalized( - int x, int y, int width, int height, int number, - bool background = false, bool scrollbar = false - ) - { - X = x; - Y = y; - Width = width; - Height = height; - Number = number; - Background = background; - Scrollbar = scrollbar; + Type = GumpHtmlLocalizedType.Color; + } - Type = GumpHtmlLocalizedType.Plain; - } + public GumpHtmlLocalized( + int x, int y, int width, int height, int number, string args, int color, + bool background = false, bool scrollbar = false + ) + { + // Are multiple arguments unsupported? And what about non ASCII arguments? - public GumpHtmlLocalized( - int x, int y, int width, int height, int number, int color, - bool background = false, bool scrollbar = false - ) - { - X = x; - Y = y; - Width = width; - Height = height; - Number = number; - Color = color; - Background = background; - Scrollbar = scrollbar; + X = x; + Y = y; + Width = width; + Height = height; + Number = number; + Args = args; + Color = color; + Background = background; + Scrollbar = scrollbar; - Type = GumpHtmlLocalizedType.Color; - } + Type = GumpHtmlLocalizedType.Args; + } - public GumpHtmlLocalized( - int x, int y, int width, int height, int number, string args, int color, - bool background = false, bool scrollbar = false - ) - { - // Are multiple arguments unsupported? And what about non ASCII arguments? + public int X { get; set; } - X = x; - Y = y; - Width = width; - Height = height; - Number = number; - Args = args; - Color = color; - Background = background; - Scrollbar = scrollbar; + public int Y { get; set; } - Type = GumpHtmlLocalizedType.Args; - } + public int Width { get; set; } - public int X { get; set; } + public int Height { get; set; } - public int Y { get; set; } + public int Number { get; set; } - public int Width { get; set; } + public string Args { get; set; } - public int Height { get; set; } + public int Color { get; set; } - public int Number { get; set; } + public bool Background { get; set; } - public string Args { get; set; } + public bool Scrollbar { get; set; } - public int Color { get; set; } + public GumpHtmlLocalizedType Type { get; set; } - public bool Background { get; set; } - public bool Scrollbar { get; set; } - - public GumpHtmlLocalizedType Type { get; set; } - - public override string Compile(OrderedHashSet strings) => + public override void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches) + { + writer.WriteAscii( Type switch { GumpHtmlLocalizedType.Plain => @@ -113,85 +112,7 @@ namespace Server.Gumps $"{{ xmfhtmlgumpcolor {X} {Y} {Width} {Height} {Number} {(Background ? 1 : 0)} {(Scrollbar ? 1 : 0)} {Color} }}", _ => $"{{ xmfhtmltok {X} {Y} {Width} {Height} {(Background ? 1 : 0)} {(Scrollbar ? 1 : 0)} {Color} {Number} @{Args}@ }}" - }; - - public override void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches) - { - writer.Write((ushort)0x7B20); // "{ " - - switch (Type) - { - case GumpHtmlLocalizedType.Plain: - { - writer.Write(LayoutNamePlain); - writer.WriteAscii(' '); - writer.WriteAscii(X.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Y.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Width.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Height.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Number.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Background ? '1' : '0'); - writer.WriteAscii(' '); - writer.WriteAscii(Scrollbar ? '1' : '0'); - - break; - } - case GumpHtmlLocalizedType.Color: - { - writer.Write(LayoutNameColor); - writer.WriteAscii(' '); - writer.WriteAscii(X.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Y.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Width.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Height.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Number.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Background ? '1' : '0'); - writer.WriteAscii(' '); - writer.WriteAscii(Scrollbar ? '1' : '0'); - writer.WriteAscii(' '); - writer.WriteAscii(Color.ToString()); - - break; - } - case GumpHtmlLocalizedType.Args: - { - writer.Write(LayoutNameArgs); - writer.WriteAscii(' '); - writer.WriteAscii(X.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Y.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Width.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Height.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Background ? '1' : '0'); - writer.WriteAscii(' '); - writer.WriteAscii(Scrollbar ? '1' : '0'); - writer.WriteAscii(' '); - writer.WriteAscii(Color.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Number.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii('@'); - writer.WriteAscii(Args ?? ""); - writer.WriteAscii('@'); - - break; - } } - - writer.Write((ushort)0x207D); // " }" - } + ); } } diff --git a/Projects/Server/Gumps/GumpImage.cs b/Projects/Server/Gumps/GumpImage.cs index 6122fecff..ba3d17969 100644 --- a/Projects/Server/Gumps/GumpImage.cs +++ b/Projects/Server/Gumps/GumpImage.cs @@ -1,6 +1,6 @@ /************************************************************************* * ModernUO * - * Copyright (C) 2019-2021 - ModernUO Development Team * + * Copyright (C) 2019-2022 - ModernUO Development Team * * Email: hi@modernuo.com * * File: GumpImage.cs * * * @@ -16,60 +16,41 @@ using System.Buffers; using Server.Collections; -namespace Server.Gumps +namespace Server.Gumps; + +public class GumpImage : GumpEntry { - public class GumpImage : GumpEntry + public GumpImage(int x, int y, int gumpID, int hue = 0, string cls = null) { - public static readonly byte[] LayoutName = Gump.StringToBuffer("gumppic"); - public static readonly byte[] HueEquals = Gump.StringToBuffer(" hue="); - public static readonly byte[] ClassEquals = Gump.StringToBuffer(" class="); + X = x; + Y = y; + GumpID = gumpID; + Hue = hue; + Class = cls; + } - public GumpImage(int x, int y, int gumpID, int hue = 0, string cls = null) - { - X = x; - Y = y; - GumpID = gumpID; - Hue = hue; - Class = cls; - } + public int X { get; set; } - public int X { get; set; } + public int Y { get; set; } - public int Y { get; set; } + public int GumpID { get; set; } - public int GumpID { get; set; } + public int Hue { get; set; } - public int Hue { get; set; } + public string Class { get; set; } - public string Class { get; set; } - - public override string Compile(OrderedHashSet strings) => - $"{{ gumppic {X} {Y} {GumpID}{(Hue == 0 ? "" : $"hue={Hue}")}{(string.IsNullOrEmpty(Class) ? "" : $"class={Class}")} }}"; - - public override void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches) - { - writer.Write((ushort)0x7B20); // "{ " - writer.Write(LayoutName); - writer.WriteAscii(' '); - writer.WriteAscii(X.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Y.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(GumpID.ToString()); - - if (Hue != 0) + public override void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches) + { + var hasHue = Hue != 0; + var hasClass = !string.IsNullOrEmpty(Class); + writer.WriteAscii( + hasHue switch { - writer.Write(HueEquals); - writer.WriteAscii(Hue.ToString()); + true when hasClass => $"{{ gumppic {X} {Y} {GumpID} hue={Hue} class={Class} }}", + true => $"{{ gumppic {X} {Y} {GumpID} hue={Hue} }}", + false when hasClass => $"{{ gumppic {X} {Y} {GumpID} class={Class} }}", + false => $"{{ gumppic {X} {Y} {GumpID} }}", } - - if (!string.IsNullOrWhiteSpace(Class)) - { - writer.Write(ClassEquals); - writer.WriteAscii(Class); - } - - writer.Write((ushort)0x207D); // " }" - } + ); } } diff --git a/Projects/Server/Gumps/GumpImageTileButton.cs b/Projects/Server/Gumps/GumpImageTileButton.cs index 383a42649..4bb862af9 100644 --- a/Projects/Server/Gumps/GumpImageTileButton.cs +++ b/Projects/Server/Gumps/GumpImageTileButton.cs @@ -1,6 +1,6 @@ /************************************************************************* * ModernUO * - * Copyright (C) 2019-2021 - ModernUO Development Team * + * Copyright (C) 2019-2022 - ModernUO Development Team * * Email: hi@modernuo.com * * File: GumpImageTileButton.cs * * * @@ -16,100 +16,55 @@ using System.Buffers; using Server.Collections; -namespace Server.Gumps +namespace Server.Gumps; + +public class GumpImageTileButton : GumpEntry { - public class GumpImageTileButton : GumpEntry + public GumpImageTileButton( + int x, int y, int normalID, int pressedID, int buttonID, GumpButtonType type, int param, + int itemID, int hue, int width, int height + ) { - public static readonly byte[] LayoutName = Gump.StringToBuffer("buttontileart"); - public static readonly byte[] LayoutTooltip = Gump.StringToBuffer(" }{ tooltip"); + X = x; + Y = y; + NormalID = normalID; + PressedID = pressedID; + ButtonID = buttonID; + Type = type; + Param = param; - // Note, on OSI, the tooltip supports ONLY clilocs as far as I can figure out, - // and the tooltip ONLY works after the buttonTileArt (as far as I can tell from testing) + ItemID = itemID; + Hue = hue; + Width = width; + Height = height; + } - public GumpImageTileButton( - int x, int y, int normalID, int pressedID, int buttonID, GumpButtonType type, int param, - int itemID, int hue, int width, int height, int localizedTooltip = -1 - ) - { - X = x; - Y = y; - NormalID = normalID; - PressedID = pressedID; - ButtonID = buttonID; - Type = type; - Param = param; + public int X { get; set; } - ItemID = itemID; - Hue = hue; - Width = width; - Height = height; + public int Y { get; set; } - LocalizedTooltip = localizedTooltip; - } + public int NormalID { get; set; } - public int X { get; set; } + public int PressedID { get; set; } - public int Y { get; set; } + public int ButtonID { get; set; } - public int NormalID { get; set; } + public GumpButtonType Type { get; set; } - public int PressedID { get; set; } + public int Param { get; set; } - public int ButtonID { get; set; } + public int ItemID { get; set; } - public GumpButtonType Type { get; set; } + public int Hue { get; set; } - public int Param { get; set; } + public int Width { get; set; } - public int ItemID { get; set; } + public int Height { get; set; } - public int Hue { get; set; } - - public int Width { get; set; } - - public int Height { get; set; } - - public int LocalizedTooltip { get; set; } - - public override string Compile(OrderedHashSet strings) => - LocalizedTooltip > 0 ? - $"{{ buttontileart {X} {Y} {NormalID} {PressedID} {(int)Type} {Param} {ButtonID} {ItemID} {Hue} {Width} {Height} }}{{ tooltip {LocalizedTooltip} }}" : - $"{{ buttontileart {X} {Y} {NormalID} {PressedID} {(int)Type} {Param} {ButtonID} {ItemID} {Hue} {Width} {Height} }}"; - - public override void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches) - { - writer.Write((ushort)0x7B20); // "{ " - writer.Write(LayoutName); - writer.WriteAscii(' '); - writer.WriteAscii(X.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Y.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(NormalID.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(PressedID.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(((int)Type).ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Param.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(ButtonID.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(ItemID.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Hue.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Width.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Height.ToString()); - - if (LocalizedTooltip > 0) - { - writer.Write(LayoutTooltip); - writer.WriteAscii(LocalizedTooltip.ToString()); - } - - writer.Write((ushort)0x207D); // " }" - } + public override void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches) + { + writer.WriteAscii( + $"{{ buttontileart {X} {Y} {NormalID} {PressedID} {(int)Type} {Param} {ButtonID} {ItemID} {Hue} {Width} {Height} }}" + ); } } diff --git a/Projects/Server/Gumps/GumpImageTiled.cs b/Projects/Server/Gumps/GumpImageTiled.cs index 30c0c7800..ab62bcc55 100644 --- a/Projects/Server/Gumps/GumpImageTiled.cs +++ b/Projects/Server/Gumps/GumpImageTiled.cs @@ -1,6 +1,6 @@ /************************************************************************* * ModernUO * - * Copyright (C) 2019-2021 - ModernUO Development Team * + * Copyright (C) 2019-2022 - ModernUO Development Team * * Email: hi@modernuo.com * * File: GumpImageTiled.cs * * * @@ -16,47 +16,31 @@ using System.Buffers; using Server.Collections; -namespace Server.Gumps +namespace Server.Gumps; + +public class GumpImageTiled : GumpEntry { - public class GumpImageTiled : GumpEntry + public GumpImageTiled(int x, int y, int width, int height, int gumpID) { - public static readonly byte[] LayoutName = Gump.StringToBuffer("gumppictiled"); + X = x; + Y = y; + Width = width; + Height = height; + GumpID = gumpID; + } - public GumpImageTiled(int x, int y, int width, int height, int gumpID) - { - X = x; - Y = y; - Width = width; - Height = height; - GumpID = gumpID; - } + public int X { get; set; } - public int X { get; set; } + public int Y { get; set; } - public int Y { get; set; } + public int Width { get; set; } - public int Width { get; set; } + public int Height { get; set; } - public int Height { get; set; } + public int GumpID { get; set; } - public int GumpID { get; set; } - public override string Compile(OrderedHashSet strings) => $"{{ gumppictiled {X} {Y} {Width} {Height} {GumpID} }}"; - - public override void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches) - { - writer.Write((ushort)0x7B20); // "{ " - writer.Write(LayoutName); - writer.WriteAscii(' '); - writer.WriteAscii(X.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Y.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Width.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Height.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(GumpID.ToString()); - writer.Write((ushort)0x207D); // " }" - } + public override void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches) + { + writer.WriteAscii($"{{ gumppictiled {X} {Y} {Width} {Height} {GumpID} }}"); } } diff --git a/Projects/Server/Gumps/GumpItem.cs b/Projects/Server/Gumps/GumpItem.cs index 4562f6e43..7ca97af42 100644 --- a/Projects/Server/Gumps/GumpItem.cs +++ b/Projects/Server/Gumps/GumpItem.cs @@ -1,6 +1,6 @@ /************************************************************************* * ModernUO * - * Copyright (C) 2019-2021 - ModernUO Development Team * + * Copyright (C) 2019-2022 - ModernUO Development Team * * Email: hi@modernuo.com * * File: GumpItem.cs * * * @@ -16,50 +16,28 @@ using System.Buffers; using Server.Collections; -namespace Server.Gumps +namespace Server.Gumps; + +public class GumpItem : GumpEntry { - public class GumpItem : GumpEntry + public GumpItem(int x, int y, int itemID, int hue = 0) { - public static readonly byte[] LayoutName = Gump.StringToBuffer("tilepic"); - public static readonly byte[] LayoutNameHue = Gump.StringToBuffer("tilepichue"); + X = x; + Y = y; + ItemID = itemID; + Hue = hue; + } - public GumpItem(int x, int y, int itemID, int hue = 0) - { - X = x; - Y = y; - ItemID = itemID; - Hue = hue; - } + public int X { get; set; } - public int X { get; set; } + public int Y { get; set; } - public int Y { get; set; } + public int ItemID { get; set; } - public int ItemID { get; set; } + public int Hue { get; set; } - public int Hue { get; set; } - - public override string Compile(OrderedHashSet strings) => - Hue == 0 ? $"{{ tilepic {X} {Y} {ItemID} }}" : $"{{ tilepichue {X} {Y} {ItemID} {Hue} }}"; - - public override void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches) - { - writer.Write((ushort)0x7B20); // "{ " - writer.Write(Hue == 0 ? LayoutName : LayoutNameHue); - writer.WriteAscii(' '); - writer.WriteAscii(X.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Y.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(ItemID.ToString()); - - if (Hue != 0) - { - writer.WriteAscii(' '); - writer.WriteAscii(Hue.ToString()); - } - - writer.Write((ushort)0x207D); // " }" - } + public override void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches) + { + writer.WriteAscii(Hue == 0 ? $"{{ tilepic {X} {Y} {ItemID} }}" : $"{{ tilepichue {X} {Y} {ItemID} {Hue} }}"); } } diff --git a/Projects/Server/Gumps/GumpItemProperty.cs b/Projects/Server/Gumps/GumpItemProperty.cs index fb248fd50..fc5c8fa94 100644 --- a/Projects/Server/Gumps/GumpItemProperty.cs +++ b/Projects/Server/Gumps/GumpItemProperty.cs @@ -1,6 +1,6 @@ /************************************************************************* * ModernUO * - * Copyright (C) 2019-2021 - ModernUO Development Team * + * Copyright (C) 2019-2022 - ModernUO Development Team * * Email: hi@modernuo.com * * File: GumpItemProperty.cs * * * @@ -16,25 +16,16 @@ using System.Buffers; using Server.Collections; -namespace Server.Gumps +namespace Server.Gumps; + +public class GumpItemProperty : GumpEntry { - public class GumpItemProperty : GumpEntry + public GumpItemProperty(Serial serial) => Serial = serial; + + public Serial Serial { get; set; } + + public override void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches) { - public static readonly byte[] LayoutName = Gump.StringToBuffer("itemproperty"); - - public GumpItemProperty(Serial serial) => Serial = serial; - - public Serial Serial { get; set; } - - public override string Compile(OrderedHashSet strings) => $"{{ itemproperty {Serial.Value} }}"; - - public override void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches) - { - writer.Write((ushort)0x7B20); // "{ " - writer.Write(LayoutName); - writer.WriteAscii(' '); - writer.WriteAscii(Serial.Value.ToString()); - writer.Write((ushort)0x207D); // " }" - } + writer.WriteAscii($"{{ itemproperty {Serial.Value} }}"); } } diff --git a/Projects/Server/Gumps/GumpLabel.cs b/Projects/Server/Gumps/GumpLabel.cs index 7f3b40e94..8299ec21b 100644 --- a/Projects/Server/Gumps/GumpLabel.cs +++ b/Projects/Server/Gumps/GumpLabel.cs @@ -1,6 +1,6 @@ /************************************************************************* * ModernUO * - * Copyright (C) 2019-2021 - ModernUO Development Team * + * Copyright (C) 2019-2022 - ModernUO Development Team * * Email: hi@modernuo.com * * File: GumpLabel.cs * * * @@ -16,42 +16,29 @@ using System.Buffers; using Server.Collections; -namespace Server.Gumps +namespace Server.Gumps; + +public class GumpLabel : GumpEntry { - public class GumpLabel : GumpEntry + public GumpLabel(int x, int y, int hue, string text) { - public static readonly byte[] LayoutName = Gump.StringToBuffer("text"); + X = x; + Y = y; + Hue = hue; + Text = text; + } - public GumpLabel(int x, int y, int hue, string text) - { - X = x; - Y = y; - Hue = hue; - Text = text; - } + public int X { get; set; } - public int X { get; set; } + public int Y { get; set; } - public int Y { get; set; } + public int Hue { get; set; } - public int Hue { get; set; } + public string Text { get; set; } - public string Text { get; set; } - public override string Compile(OrderedHashSet strings) => $"{{ text {X} {Y} {Hue} {strings.GetOrAdd(Text ?? "")} }}"; - - public override void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches) - { - writer.Write((ushort)0x7B20); // "{ " - writer.Write(LayoutName); - writer.WriteAscii(' '); - writer.WriteAscii(X.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Y.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Hue.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(strings.GetOrAdd(Text ?? "").ToString()); - writer.Write((ushort)0x207D); // " }" - } + public override void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches) + { + var textIndex = strings.GetOrAdd(Text ?? ""); + writer.WriteAscii($"{{ text {X} {Y} {Hue} {textIndex} }}"); } } diff --git a/Projects/Server/Gumps/GumpLabelCropped.cs b/Projects/Server/Gumps/GumpLabelCropped.cs index 18e7d67be..ec1961f5d 100644 --- a/Projects/Server/Gumps/GumpLabelCropped.cs +++ b/Projects/Server/Gumps/GumpLabelCropped.cs @@ -1,6 +1,6 @@ /************************************************************************* * ModernUO * - * Copyright (C) 2019-2021 - ModernUO Development Team * + * Copyright (C) 2019-2022 - ModernUO Development Team * * Email: hi@modernuo.com * * File: GumpLabelCropped.cs * * * @@ -16,54 +16,35 @@ using System.Buffers; using Server.Collections; -namespace Server.Gumps +namespace Server.Gumps; + +public class GumpLabelCropped : GumpEntry { - public class GumpLabelCropped : GumpEntry + public GumpLabelCropped(int x, int y, int width, int height, int hue, string text) { - public static readonly byte[] LayoutName = Gump.StringToBuffer("croppedtext"); + X = x; + Y = y; + Width = width; + Height = height; + Hue = hue; + Text = text; + } - public GumpLabelCropped(int x, int y, int width, int height, int hue, string text) - { - X = x; - Y = y; - Width = width; - Height = height; - Hue = hue; - Text = text; - } + public int X { get; set; } - public int X { get; set; } + public int Y { get; set; } - public int Y { get; set; } + public int Width { get; set; } - public int Width { get; set; } + public int Height { get; set; } - public int Height { get; set; } + public int Hue { get; set; } - public int Hue { get; set; } + public string Text { get; set; } - public string Text { get; set; } - - public override string Compile(OrderedHashSet strings) => - $"{{ croppedtext {X} {Y} {Width} {Height} {Hue} {strings.GetOrAdd(Text ?? "")} }}"; - - public override void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches) - { - writer.Write((ushort)0x7B20); // "{ " - writer.Write(LayoutName); - writer.WriteAscii(' '); - writer.WriteAscii(X.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Y.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Width.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Height.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Hue.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(strings.GetOrAdd(Text ?? "").ToString()); - writer.Write((ushort)0x207D); // " }" - } + public override void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches) + { + var textIndex = strings.GetOrAdd(Text ?? ""); + writer.WriteAscii($"{{ croppedtext {X} {Y} {Width} {Height} {Hue} {textIndex} }}"); } } diff --git a/Projects/Server/Gumps/GumpMasterGump.cs b/Projects/Server/Gumps/GumpMasterGump.cs index 035b1ec9b..b37ed6aa4 100644 --- a/Projects/Server/Gumps/GumpMasterGump.cs +++ b/Projects/Server/Gumps/GumpMasterGump.cs @@ -16,25 +16,16 @@ using System.Buffers; using Server.Collections; -namespace Server.Gumps +namespace Server.Gumps; + +public class GumpMasterGump : GumpEntry { - public class GumpMasterGump : GumpEntry + public GumpMasterGump(int gumpID) => GumpID = gumpID; + + public int GumpID { get; set; } + + public override void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches) { - public static readonly byte[] LayoutName = Gump.StringToBuffer("mastergump"); - - public GumpMasterGump(int gumpID) => GumpID = gumpID; - - public int GumpID { get; set; } - - public override string Compile(OrderedHashSet strings) => $"{{ mastergump {GumpID} }}"; - - public override void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches) - { - writer.Write((ushort)0x7B20); // "{ " - writer.Write(LayoutName); - writer.WriteAscii(' '); - writer.WriteAscii(GumpID.ToString()); - writer.Write((ushort)0x207D); // " }" - } + writer.WriteAscii($"{{ mastergump {GumpID} }}"); } } diff --git a/Projects/Server/Gumps/GumpPage.cs b/Projects/Server/Gumps/GumpPage.cs index 16aa448d7..1c8ae540a 100644 --- a/Projects/Server/Gumps/GumpPage.cs +++ b/Projects/Server/Gumps/GumpPage.cs @@ -1,6 +1,6 @@ /************************************************************************* * ModernUO * - * Copyright (C) 2019-2021 - ModernUO Development Team * + * Copyright (C) 2019-2022 - ModernUO Development Team * * Email: hi@modernuo.com * * File: GumpPage.cs * * * @@ -16,24 +16,25 @@ using System.Buffers; using Server.Collections; -namespace Server.Gumps +namespace Server.Gumps; + +public class GumpPage : GumpEntry { - public class GumpPage : GumpEntry + private static byte[] _page0 = Gump.StringToBuffer("{ page 0 }"); + + public GumpPage(int page) => Page = page; + + public int Page { get; set; } + + public override void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches) { - public static readonly byte[] LayoutName = Gump.StringToBuffer("page"); - - public GumpPage(int page) => Page = page; - - public int Page { get; set; } - public override string Compile(OrderedHashSet strings) => $"{{ page {Page} }}"; - - public override void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches) + if (Page == 0) { - writer.Write((ushort)0x7B20); // "{ " - writer.Write(LayoutName); - writer.WriteAscii(' '); - writer.WriteAscii(Page.ToString()); - writer.Write((ushort)0x207D); // " }" + writer.Write(_page0); + } + else + { + writer.WriteAscii($"{{ page {Page} }}"); } } } diff --git a/Projects/Server/Gumps/GumpRadio.cs b/Projects/Server/Gumps/GumpRadio.cs index ff7d6d32c..b5ad2506f 100644 --- a/Projects/Server/Gumps/GumpRadio.cs +++ b/Projects/Server/Gumps/GumpRadio.cs @@ -1,6 +1,6 @@ /************************************************************************* * ModernUO * - * Copyright (C) 2019-2021 - ModernUO Development Team * + * Copyright (C) 2019-2022 - ModernUO Development Team * * Email: hi@modernuo.com * * File: GumpRadio.cs * * * @@ -16,56 +16,36 @@ using System.Buffers; using Server.Collections; -namespace Server.Gumps +namespace Server.Gumps; + +public class GumpRadio : GumpEntry { - public class GumpRadio : GumpEntry + public GumpRadio(int x, int y, int inactiveID, int activeID, bool initialState, int switchID) { - public static readonly byte[] LayoutName = Gump.StringToBuffer("radio"); + X = x; + Y = y; + InactiveID = inactiveID; + ActiveID = activeID; + InitialState = initialState; + SwitchID = switchID; + } - public GumpRadio(int x, int y, int inactiveID, int activeID, bool initialState, int switchID) - { - X = x; - Y = y; - InactiveID = inactiveID; - ActiveID = activeID; - InitialState = initialState; - SwitchID = switchID; - } + public int X { get; set; } - public int X { get; set; } + public int Y { get; set; } - public int Y { get; set; } + public int InactiveID { get; set; } - public int InactiveID { get; set; } + public int ActiveID { get; set; } - public int ActiveID { get; set; } + public bool InitialState { get; set; } - public bool InitialState { get; set; } + public int SwitchID { get; set; } - public int SwitchID { get; set; } - - public override string Compile(OrderedHashSet strings) => - $"{{ radio {X} {Y} {InactiveID} {ActiveID} {(InitialState ? 1 : 0)} {SwitchID} }}"; - - public override void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches) - { - writer.Write((ushort)0x7B20); // "{ " - writer.Write(LayoutName); - writer.WriteAscii(' '); - writer.WriteAscii(X.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Y.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(InactiveID.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(ActiveID.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(InitialState ? '1' : '0'); - writer.WriteAscii(' '); - writer.WriteAscii(SwitchID.ToString()); - writer.Write((ushort)0x207D); // " }" - - switches++; - } + public override void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches) + { + var initialState = InitialState ? "1" : "0"; + writer.WriteAscii($"{{ radio {X} {Y} {InactiveID} {ActiveID} {initialState} {SwitchID} }}"); + switches++; } } diff --git a/Projects/Server/Gumps/GumpSpriteImage.cs b/Projects/Server/Gumps/GumpSpriteImage.cs index 59c8e8492..953e3c29f 100644 --- a/Projects/Server/Gumps/GumpSpriteImage.cs +++ b/Projects/Server/Gumps/GumpSpriteImage.cs @@ -16,58 +16,37 @@ using System.Buffers; using Server.Collections; -namespace Server.Gumps +namespace Server.Gumps; + +public class GumpSpriteImage : GumpEntry { - public class GumpSpriteImage : GumpEntry + public GumpSpriteImage(int x, int y, int gumpID, int width, int height, int sx, int sy) { - public static readonly byte[] LayoutName = Gump.StringToBuffer("picinpic"); + X = x; + Y = y; + GumpID = gumpID; + Width = width; + Height = height; + SX = sx; + SY = sy; + } - public GumpSpriteImage(int x, int y, int gumpID, int width, int height, int sx, int sy) - { - X = x; - Y = y; - GumpID = gumpID; - Width = width; - Height = height; - SX = sx; - SY = sy; - } + public int X { get; set; } - public int X { get; set; } + public int Y { get; set; } - public int Y { get; set; } + public int Width { get; set; } - public int Width { get; set; } + public int Height { get; set; } - public int Height { get; set; } + public int GumpID { get; set; } - public int GumpID { get; set; } + public int SX { get; set; } - public int SX { get; set; } + public int SY { get; set; } - public int SY { get; set; } - public override string Compile(OrderedHashSet strings) => - $"{{ picinpic {X} {Y} {GumpID} {Width} {Height} {SX} {SY} }}"; - - public override void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches) - { - writer.Write((ushort)0x7B20); // "{ " - writer.Write(LayoutName); - writer.WriteAscii(' '); - writer.WriteAscii(X.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Y.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(GumpID.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Width.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Height.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(SX.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(SY.ToString()); - writer.Write((ushort)0x207D); // " }" - } + public override void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches) + { + writer.WriteAscii($"{{ picinpic {X} {Y} {GumpID} {Width} {Height} {SX} {SY} }}"); } } diff --git a/Projects/Server/Gumps/GumpTextEntry.cs b/Projects/Server/Gumps/GumpTextEntry.cs index 1eb0aa84c..f56ef77a4 100644 --- a/Projects/Server/Gumps/GumpTextEntry.cs +++ b/Projects/Server/Gumps/GumpTextEntry.cs @@ -1,6 +1,6 @@ /************************************************************************* * ModernUO * - * Copyright (C) 2019-2021 - ModernUO Development Team * + * Copyright (C) 2019-2022 - ModernUO Development Team * * Email: hi@modernuo.com * * File: GumpTextEntry.cs * * * @@ -16,61 +16,39 @@ using System.Buffers; using Server.Collections; -namespace Server.Gumps +namespace Server.Gumps; + +public class GumpTextEntry : GumpEntry { - public class GumpTextEntry : GumpEntry + public GumpTextEntry(int x, int y, int width, int height, int hue, int entryID, string initialText) { - public static readonly byte[] LayoutName = Gump.StringToBuffer("textentry"); + X = x; + Y = y; + Width = width; + Height = height; + Hue = hue; + EntryID = entryID; + InitialText = initialText; + } - public GumpTextEntry(int x, int y, int width, int height, int hue, int entryID, string initialText) - { - X = x; - Y = y; - Width = width; - Height = height; - Hue = hue; - EntryID = entryID; - InitialText = initialText; - } + public int X { get; set; } - public int X { get; set; } + public int Y { get; set; } - public int Y { get; set; } + public int Width { get; set; } - public int Width { get; set; } + public int Height { get; set; } - public int Height { get; set; } + public int Hue { get; set; } - public int Hue { get; set; } + public int EntryID { get; set; } - public int EntryID { get; set; } + public string InitialText { get; set; } - public string InitialText { get; set; } - - public override string Compile(OrderedHashSet strings) => - $"{{ textentry {X} {Y} {Width} {Height} {Hue} {EntryID} {strings.GetOrAdd(InitialText ?? "")} }}"; - - public override void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches) - { - writer.Write((ushort)0x7B20); // "{ " - writer.Write(LayoutName); - writer.WriteAscii(' '); - writer.WriteAscii(X.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Y.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Width.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Height.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Hue.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(EntryID.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(strings.GetOrAdd(InitialText ?? "").ToString()); - writer.Write((ushort)0x207D); // " }" - - entries++; - } + public override void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches) + { + var textIndex = strings.GetOrAdd(InitialText ?? ""); + writer.WriteAscii($"{{ textentry {X} {Y} {Width} {Height} {Hue} {EntryID} {textIndex} }}"); + entries++; } } diff --git a/Projects/Server/Gumps/GumpTextEntryLimited.cs b/Projects/Server/Gumps/GumpTextEntryLimited.cs index 029a2d127..aebe6c08c 100644 --- a/Projects/Server/Gumps/GumpTextEntryLimited.cs +++ b/Projects/Server/Gumps/GumpTextEntryLimited.cs @@ -1,6 +1,6 @@ /************************************************************************* * ModernUO * - * Copyright (C) 2019-2021 - ModernUO Development Team * + * Copyright (C) 2019-2022 - ModernUO Development Team * * Email: hi@modernuo.com * * File: GumpTextEntryLimited.cs * * * @@ -16,68 +16,44 @@ using System.Buffers; using Server.Collections; -namespace Server.Gumps +namespace Server.Gumps; + +public class GumpTextEntryLimited : GumpEntry { - public class GumpTextEntryLimited : GumpEntry + public GumpTextEntryLimited( + int x, int y, int width, int height, int hue, int entryID, string initialText, int size = 0 + ) { - public static readonly byte[] LayoutName = Gump.StringToBuffer("textentrylimited"); + X = x; + Y = y; + Width = width; + Height = height; + Hue = hue; + EntryID = entryID; + InitialText = initialText; + Size = size; + } - public GumpTextEntryLimited( - int x, int y, int width, int height, int hue, int entryID, string initialText, int size = 0 - ) - { - X = x; - Y = y; - Width = width; - Height = height; - Hue = hue; - EntryID = entryID; - InitialText = initialText; - Size = size; - } + public int X { get; set; } - public int X { get; set; } + public int Y { get; set; } - public int Y { get; set; } + public int Width { get; set; } - public int Width { get; set; } + public int Height { get; set; } - public int Height { get; set; } + public int Hue { get; set; } - public int Hue { get; set; } + public int EntryID { get; set; } - public int EntryID { get; set; } + public string InitialText { get; set; } - public string InitialText { get; set; } + public int Size { get; set; } - public int Size { get; set; } - - public override string Compile(OrderedHashSet strings) => - $"{{ textentrylimited {X} {Y} {Width} {Height} {Hue} {EntryID} {strings.GetOrAdd(InitialText ?? "")} {Size} }}"; - - public override void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches) - { - writer.Write((ushort)0x7B20); // "{ " - writer.Write(LayoutName); - writer.WriteAscii(' '); - writer.WriteAscii(X.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Y.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Width.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Height.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Hue.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(EntryID.ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(strings.GetOrAdd(InitialText ?? "").ToString()); - writer.WriteAscii(' '); - writer.WriteAscii(Size.ToString()); - writer.Write((ushort)0x207D); // " }" - - entries++; - } + public override void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches) + { + var textIndex = strings.GetOrAdd(InitialText ?? ""); + writer.WriteAscii($"{{ textentrylimited {X} {Y} {Width} {Height} {Hue} {EntryID} {textIndex} {Size} }}"); + entries++; } } diff --git a/Projects/Server/Gumps/GumpTooltip.cs b/Projects/Server/Gumps/GumpTooltip.cs index 6898e2b78..4332c1d8d 100644 --- a/Projects/Server/Gumps/GumpTooltip.cs +++ b/Projects/Server/Gumps/GumpTooltip.cs @@ -16,41 +16,24 @@ using System.Buffers; using Server.Collections; -namespace Server.Gumps +namespace Server.Gumps; + +// Note, on OSI, the tooltip supports ONLY clilocs as far as I can figure out, +// and the tooltip ONLY works after the buttonTileArt (as far as I can tell from testing) +public class GumpTooltip : GumpEntry { - public class GumpTooltip : GumpEntry + public GumpTooltip(int number, string args) { - public static readonly byte[] LayoutName = Gump.StringToBuffer("tooltip"); + Number = number; + Args = args; + } - public GumpTooltip(int number, string args) - { - Number = number; - Args = args; - } + public int Number { get; set; } - public int Number { get; set; } + public string Args { get; set; } - public string Args { get; set; } - - public override string Compile(OrderedHashSet strings) => - string.IsNullOrEmpty(Args) ? $"{{ tooltip {Number} }}" : $"{{ tooltip {Number} @{Args}@ }}"; - - public override void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches) - { - writer.Write((ushort)0x7B20); // "{ " - writer.Write(LayoutName); - writer.WriteAscii(' '); - writer.WriteAscii(Number.ToString()); - - if (!string.IsNullOrEmpty(Args)) - { - writer.WriteAscii(' '); - writer.WriteAscii('@'); - writer.WriteAscii(Args); - writer.WriteAscii('@'); - } - - writer.Write((ushort)0x207D); // " }" - } + public override void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches) + { + writer.WriteAscii(string.IsNullOrEmpty(Args) ? $"{{ tooltip {Number} }}" : $"{{ tooltip {Number} @{Args}@ }}"); } } diff --git a/Projects/Server/Gumps/InvalidGumpResponseException.cs b/Projects/Server/Gumps/InvalidGumpResponseException.cs index af2c11c6c..df4b06d69 100644 --- a/Projects/Server/Gumps/InvalidGumpResponseException.cs +++ b/Projects/Server/Gumps/InvalidGumpResponseException.cs @@ -1,6 +1,6 @@ /************************************************************************* * ModernUO * - * Copyright (C) 2019-2021 - ModernUO Development Team * + * Copyright (C) 2019-2022 - ModernUO Development Team * * Email: hi@modernuo.com * * File: InvalidGumpResponseException.cs * * * @@ -15,12 +15,11 @@ using System; -namespace Server.Gumps +namespace Server.Gumps; + +public class InvalidGumpResponseException : Exception { - public class InvalidGumpResponseException : Exception + public InvalidGumpResponseException(string reason) : base(reason) { - public InvalidGumpResponseException(string reason) : base(reason) - { - } } } diff --git a/Projects/Server/Gumps/RelayInfo.cs b/Projects/Server/Gumps/RelayInfo.cs index 7831f2174..b0736e368 100644 --- a/Projects/Server/Gumps/RelayInfo.cs +++ b/Projects/Server/Gumps/RelayInfo.cs @@ -1,57 +1,56 @@ -namespace Server.Gumps +namespace Server.Gumps; + +public class TextRelay { - public class TextRelay + public TextRelay(int entryID, string text) { - public TextRelay(int entryID, string text) - { - EntryID = entryID; - Text = text; - } - - public int EntryID { get; } - - public string Text { get; } + EntryID = entryID; + Text = text; } - public class RelayInfo - { - public RelayInfo(int buttonID, int[] switches, TextRelay[] textEntries) - { - ButtonID = buttonID; - Switches = switches; - TextEntries = textEntries; - } + public int EntryID { get; } - public int ButtonID { get; } - - public int[] Switches { get; } - - public TextRelay[] TextEntries { get; } - - public bool IsSwitched(int switchID) - { - for (var i = 0; i < Switches.Length; ++i) - { - if (Switches[i] == switchID) - { - return true; - } - } - - return false; - } - - public TextRelay GetTextEntry(int entryID) - { - for (var i = 0; i < TextEntries.Length; ++i) - { - if (TextEntries[i].EntryID == entryID) - { - return TextEntries[i]; - } - } - - return null; - } - } + public string Text { get; } } + +public class RelayInfo +{ + public RelayInfo(int buttonID, int[] switches, TextRelay[] textEntries) + { + ButtonID = buttonID; + Switches = switches; + TextEntries = textEntries; + } + + public int ButtonID { get; } + + public int[] Switches { get; } + + public TextRelay[] TextEntries { get; } + + public bool IsSwitched(int switchID) + { + for (var i = 0; i < Switches.Length; ++i) + { + if (Switches[i] == switchID) + { + return true; + } + } + + return false; + } + + public TextRelay GetTextEntry(int entryID) + { + for (var i = 0; i < TextEntries.Length; ++i) + { + if (TextEntries[i].EntryID == entryID) + { + return TextEntries[i]; + } + } + + return null; + } +} \ No newline at end of file diff --git a/Projects/UOContent/Gumps/BaseImageTileButtonsGump.cs b/Projects/UOContent/Gumps/BaseImageTileButtonsGump.cs index 18602b84a..9e15cb31c 100644 --- a/Projects/UOContent/Gumps/BaseImageTileButtonsGump.cs +++ b/Projects/UOContent/Gumps/BaseImageTileButtonsGump.cs @@ -109,9 +109,9 @@ namespace Server.Gumps b.ItemID, b.Hue, 15, - 10, - b.LocalizedTooltip + 10 ); + AddTooltip(b.LocalizedTooltip); TextDefinition.AddHtmlText(this, innerX + 84, innerY, 250, 60, b.Label, false, false, 0x7FFF, 0xFFFFFF); } } diff --git a/Projects/UOContent/Spells/Ninjitsu/AnimalForm.cs b/Projects/UOContent/Spells/Ninjitsu/AnimalForm.cs index 041a10eab..1d9cc9ccd 100644 --- a/Projects/UOContent/Spells/Ninjitsu/AnimalForm.cs +++ b/Projects/UOContent/Spells/Ninjitsu/AnimalForm.cs @@ -462,9 +462,9 @@ namespace Server.Spells.Ninjitsu entries[i].ItemID, entries[i].Hue, 40 - b.Width / 2 - b.X, - 30 - b.Height / 2 - b.Y, - entries[i].Tooltip + 30 - b.Height / 2 - b.Y ); + AddTooltip(entries[i].Tooltip); AddHtmlLocalized(x + 84, y, 250, 60, entries[i].Name, 0x7FFF); current++; From 601eb4e116a3af00c60efe88f506176d7b23b89a Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Tue, 22 Mar 2022 23:51:36 -0700 Subject: [PATCH 110/213] fix: Uses variables for gump html localized (#970) --- Projects/Server/Gumps/GumpHtmlLocalized.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Projects/Server/Gumps/GumpHtmlLocalized.cs b/Projects/Server/Gumps/GumpHtmlLocalized.cs index 71362f770..a4241dfbb 100644 --- a/Projects/Server/Gumps/GumpHtmlLocalized.cs +++ b/Projects/Server/Gumps/GumpHtmlLocalized.cs @@ -103,15 +103,17 @@ public class GumpHtmlLocalized : GumpEntry public override void AppendTo(ref SpanWriter writer, OrderedHashSet strings, ref int entries, ref int switches) { + var background = Background ? "1" : "0"; + var scrollbar = Scrollbar ? "1" : "0"; writer.WriteAscii( Type switch { GumpHtmlLocalizedType.Plain => - $"{{ xmfhtmlgump {X} {Y} {Width} {Height} {Number} {(Background ? 1 : 0)} {(Scrollbar ? 1 : 0)} }}", + $"{{ xmfhtmlgump {X} {Y} {Width} {Height} {Number} {background} {scrollbar} }}", GumpHtmlLocalizedType.Color => - $"{{ xmfhtmlgumpcolor {X} {Y} {Width} {Height} {Number} {(Background ? 1 : 0)} {(Scrollbar ? 1 : 0)} {Color} }}", + $"{{ xmfhtmlgumpcolor {X} {Y} {Width} {Height} {Number} {background} {scrollbar} {Color} }}", _ => - $"{{ xmfhtmltok {X} {Y} {Width} {Height} {(Background ? 1 : 0)} {(Scrollbar ? 1 : 0)} {Color} {Number} @{Args}@ }}" + $"{{ xmfhtmltok {X} {Y} {Width} {Height} {background} {scrollbar} {Color} {Number} @{Args}@ }}" } ); } From 154f7edbdbf93e8636eac1007255166d2d2a8846 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Wed, 23 Mar 2022 00:08:01 -0700 Subject: [PATCH 111/213] fix: Updates sponsors links --- SPONSORS.md | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/SPONSORS.md b/SPONSORS.md index 769bced1f..70c0deede 100644 --- a/SPONSORS.md +++ b/SPONSORS.md @@ -3,7 +3,6 @@ Thank you to all of our generous sponsors that make ModernUO possible. **A special thank you to the following sponsors for their considerable contributions:** -* [Hephaestus Games](https://hephaestusgames.com) * [UO Outlands](https://uooutlands.com) * Prayer ([MagnUm-Opus](https://discord.gg/CzDEq3vv2N)) @@ -14,16 +13,23 @@ We greatly appreciate the support! Use one of the following platforms below: [Github Sponsors | ModernUO](https://github.com/sponsors/modernuo) #### Patreon -[Patreon | ModernUO](https://patreon.com/modernuo) +[Patreon | ModernUO](https://patreon.com/modernuo) #### Paypal -[Paypal | Sabresite](https://paypal.me/sabresite) +[Paypal | Sabresite](https://paypal.me/sabresite) #### Venmo -[Venmo | Sabresite](https://venmo.com/code?user_id=1834446441414656966) +[Venmo | Sabresite](https://venmo.com/code?user_id=1834446441414656966) -#### Bitcoin -37QmRWTCjVoNWycMpo1t5JnYVDmJTGSJ9W +#### Bitcoin (37QmRWTCjVoNWycMpo1t5JnYVDmJTGSJ9W) +Bitcoin -#### Ethereum -0x7A9D76F497d4Ee150Ada0ea0455fF3f6e8F3b6b8 + +#### Ethereum (0x7A9D76F497d4Ee150Ada0ea0455fF3f6e8F3b6b8) +Bitcoin + +#### Decentraland MANA (0xE425CF5aD90d193c4EF1eE6c5aFA8150834ABb1d) +Decrentraland + +#### Solana (AhVtRy9YXMBRf5snTRg6ybvMbGnzSryNx65BJxzg7fqa) +Solana From 474427041fb28c1023b35309b63d7d3c8ac459ff Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sat, 26 Mar 2022 11:11:22 -0700 Subject: [PATCH 112/213] feat: Adds a PooledRefList (#676) --- Projects/Server/Collections/PooledRefList.cs | 1154 +++++++++++++++++ Projects/Server/Collections/PooledRefQueue.cs | 859 ++++++------ .../ClientVersionConverterFactory.cs | 1 - .../Network/Packets/IncomingVendorPackets.cs | 1 - Projects/Server/Skills.cs | 1 - Projects/Server/TileMatrix/TileMatrixPatch.cs | 1 - 6 files changed, 1585 insertions(+), 432 deletions(-) create mode 100644 Projects/Server/Collections/PooledRefList.cs diff --git a/Projects/Server/Collections/PooledRefList.cs b/Projects/Server/Collections/PooledRefList.cs new file mode 100644 index 000000000..fccdff986 --- /dev/null +++ b/Projects/Server/Collections/PooledRefList.cs @@ -0,0 +1,1154 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Buffers; +using System.Collections.Generic; +using System.Diagnostics; +using System.Runtime.CompilerServices; +using Server.Buffers; + +namespace Server.Collections; + +// Implements a variable-size List that uses an array of objects to store the +// elements. A List has a capacity, which is the allocated length +// of the internal array. As elements are added to a List, the capacity +// of the List is automatically increased as required by reallocating the +// internal array. +// +[DebuggerDisplay("Count = {Count}")] +public ref struct PooledRefList +{ + private const int MaxLength = int.MaxValue; + private const int DefaultCapacity = 4; + + internal T[] _items; // Do not rename (binary serialization) + internal int _size; // Do not rename (binary serialization) + private int _version; // Do not rename (binary serialization) + private bool _mt; + +#pragma warning disable CA1825 // avoid the extra generic instantiation for Array.Empty() + private static readonly T[] s_emptyArray = new T[0]; +#pragma warning restore CA1825 + + private ArrayPool ArrayPool + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => _mt ? ArrayPool.Shared : STArrayPool.Shared; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static PooledRefList Create(int capacity = 32, bool mt = false) => new(capacity, mt); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static PooledRefList CreateMT(int capacity = 32) => new(capacity, true); + + // Constructs a List. The list is initially empty and has a capacity + // of zero. Upon adding the first element to the list the capacity is + // increased to DefaultCapacity, and then increased in multiples of two + // as required. + public PooledRefList(int capacity, bool mt = false) + { + _mt = mt; + _size = 0; + _version = 0; + _items = capacity switch + { + < 0 => throw new ArgumentOutOfRangeException(nameof(capacity), capacity, CollectionThrowStrings.ArgumentOutOfRange_NeedNonNegNum), + 0 => Array.Empty(), + _ => (_mt ? ArrayPool.Shared : STArrayPool.Shared).Rent(capacity) + }; + + } + + // Constructs a List, copying the contents of the given collection. The + // size and capacity of the new list will both be equal to the size of the + // given collection. + // + public PooledRefList(PooledRefList collection, bool mt = false) + { + _version = 0; + _mt = mt; + + int count = collection.Count; + if (count == 0) + { + _items = s_emptyArray; + _size = 0; + } + else + { + _items = (mt ? ArrayPool.Shared : STArrayPool.Shared).Rent(count); + collection.CopyTo(_items, 0); + _size = count; + } + } + + // Constructs a List, copying the contents of the given collection. The + // size and capacity of the new list will both be equal to the size of the + // given collection. + // + public PooledRefList(IEnumerable collection, bool mt = false) + { + if (collection == null) + { + throw new ArgumentNullException(nameof(collection)); + } + + _version = 0; + _mt = mt; + + if (collection is ICollection c) + { + int count = c.Count; + if (count == 0) + { + _items = s_emptyArray; + _size = 0; + } + else + { + _items = (mt ? ArrayPool.Shared : STArrayPool.Shared).Rent(count); + c.CopyTo(_items, 0); + _size = count; + } + } + else + { + _size = 0; + _items = s_emptyArray; + using IEnumerator en = collection!.GetEnumerator(); + while (en.MoveNext()) + { + Add(en.Current); + } + } + } + + // Gets and sets the capacity of this list. The capacity is the size of + // the internal array used to hold items. When set, the internal + // array of the list is reallocated to the given capacity. + // + public int Capacity + { + get => _items.Length; + set + { + if (value < _size) + { + throw new ArgumentOutOfRangeException(nameof(value)); + } + + if (value != _items.Length) + { + if (value > 0) + { + T[] newItems = ArrayPool.Rent(_size); + if (_size > 0) + { + Array.Copy(_items, newItems, _size); + } + + if (_items.Length > 0) + { + Clear(); + ArrayPool.Return(_items); + } + _items = newItems; + } + else + { + Clear(); + ArrayPool.Return(_items); + _items = s_emptyArray; + } + } + } + } + + // Read-only property describing how many elements are in the List. + public int Count => _size; + + // Sets or Gets the element at the given index. + public T this[int index] + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + // Following trick can reduce the range check by one + if ((uint)index >= (uint)_size) + { + throw new ArgumentOutOfRangeException(nameof(index)); + } + return _items[index]; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + set + { + if ((uint)index >= (uint)_size) + { + throw new ArgumentOutOfRangeException(nameof(index)); + } + _items[index] = value; + _version++; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static bool IsCompatibleObject(object? value) + { + // Non-null values are fine. Only accept nulls if T is a class or Nullable. + // Note that default(T) is not equal to null for value types except when T is Nullable. + return value is T || value == null && default(T) == null; + } + + // Adds the given object to the end of this list. The size of the list is + // increased by one. If required, the capacity of the list is doubled + // before adding the new element. + // + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Add(T item) + { + _version++; + T[] array = _items; + int size = _size; + if ((uint)size < (uint)array.Length) + { + _size = size + 1; + array[size] = item; + } + else + { + AddWithResize(item); + } + } + + // Non-inline from List.Add to improve its code quality as uncommon path + [MethodImpl(MethodImplOptions.NoInlining)] + private void AddWithResize(T item) + { + Debug.Assert(_size == _items.Length); + int size = _size; + Grow(size + 1); + _size = size + 1; + _items[size] = item; + } + + // Adds the elements of the given collection to the end of this list. If + // required, the capacity of the list is increased to twice the previous + // capacity or the new size, whichever is larger. + // + public void AddRange(IEnumerable collection) => InsertRange(_size, collection); + + // Searches a section of the list for a given element using a binary search + // algorithm. Elements of the list are compared to the search value using + // the given IComparer interface. If comparer is null, elements of + // the list are compared to the search value using the IComparable + // interface, which in that case must be implemented by all elements of the + // list and the given search value. This method assumes that the given + // section of the list is already sorted; if this is not the case, the + // result will be incorrect. + // + // The method returns the index of the given value in the list. If the + // list does not contain the given value, the method returns a negative + // integer. The bitwise complement operator (~) can be applied to a + // negative result to produce the index of the first element (if any) that + // is larger than the given search value. This is also the index at which + // the search value should be inserted into the list in order for the list + // to remain sorted. + // + // The method uses the Array.BinarySearch method to perform the + // search. + // + public int BinarySearch(int index, int count, T item, IComparer? comparer) + { + if (index < 0) + { + throw new ArgumentOutOfRangeException(nameof(index)); + } + + if (count < 0) + { + throw new ArgumentOutOfRangeException(nameof(count)); + } + + if (_size - index < count) + { + throw new ArgumentException("Length must be greater than zero"); + } + + return Array.BinarySearch(_items, index, count, item, comparer); + } + + public int BinarySearch(T item) => BinarySearch(0, Count, item, null); + + public int BinarySearch(T item, IComparer? comparer) => BinarySearch(0, Count, item, comparer); + + // Clears the contents of List. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Clear() + { + _version++; + if (RuntimeHelpers.IsReferenceOrContainsReferences()) + { + int size = _size; + _size = 0; + if (size > 0) + { + Array.Clear(_items, 0, size); // Clear the elements so that the gc can reclaim the references. + } + } + else + { + _size = 0; + } + } + + // Contains returns true if the specified element is in the List. + // It does a linear, O(n) search. Equality is determined by calling + // EqualityComparer.Default.Equals(). + // + public bool Contains(T item) + { + // PERF: IndexOf calls Array.IndexOf, which internally + // calls EqualityComparer.Default.IndexOf, which + // is specialized for different types. This + // boosts performance since instead of making a + // virtual method call each iteration of the loop, + // via EqualityComparer.Default.Equals, we + // only make one virtual call to EqualityComparer.IndexOf. + + return _size != 0 && IndexOf(item) != -1; + } + + public PooledRefList ConvertAll(Converter converter) + { + if (converter == null) + { + throw new ArgumentNullException(nameof(converter)); + } + + PooledRefList list = new PooledRefList(_size); + for (int i = 0; i < _size; i++) + { + list._items[i] = converter(_items[i]); + } + list._size = _size; + + return list; + } + + // Copies this List into array, which must be of a + // compatible array type. + public void CopyTo(T[] array) => CopyTo(array, 0); + + // Copies a section of this list to the given array at the given index. + // + // The method uses the Array.Copy method to copy the elements. + // + public void CopyTo(int index, T[] array, int arrayIndex, int count) + { + if (_size - index < count) + { + throw new ArgumentException("Length must be greater than zero"); + } + + // Delegate rest of error checking to Array.Copy. + Array.Copy(_items, index, array, arrayIndex, count); + } + + public void CopyTo(T[] array, int arrayIndex) + { + // Delegate rest of error checking to Array.Copy. + Array.Copy(_items, 0, array, arrayIndex, _size); + } + + /// + /// Ensures that the capacity of this list is at least the specified . + /// If the current capacity of the list is less than specified , + /// the capacity is increased by continuously twice current capacity until it is at least the specified . + /// + /// The minimum capacity to ensure. + public int EnsureCapacity(int capacity) + { + if (capacity < 0) + { + throw new ArgumentOutOfRangeException(nameof(capacity)); + } + if (_items.Length < capacity) + { + Grow(capacity); + _version++; + } + + return _items.Length; + } + + /// + /// Increase the capacity of this list to at least the specified . + /// + /// The minimum capacity to ensure. + private void Grow(int capacity) + { + Debug.Assert(_items.Length < capacity); + + int newcapacity = _items.Length == 0 ? DefaultCapacity : 2 * _items.Length; + + // Allow the list to grow to maximum possible capacity (~2G elements) before encountering overflow. + // Note that this check works even when _items.Length overflowed thanks to the (uint) cast + if ((uint)newcapacity > MaxLength) + { + newcapacity = MaxLength; + } + + // If the computed capacity is still less than specified, set to the original argument. + // Capacities exceeding Array.MaxLength will be surfaced as OutOfMemoryException by Array.Resize. + if (newcapacity < capacity) + { + newcapacity = capacity; + } + + Capacity = newcapacity; + } + + public bool Exists(Predicate match) => FindIndex(match) != -1; + + public T? Find(Predicate match) + { + if (match == null) + { + throw new ArgumentNullException(nameof(match)); + } + + for (int i = 0; i < _size; i++) + { + if (match(_items[i])) + { + return _items[i]; + } + } + return default; + } + + public PooledRefList FindAll(Predicate match) + { + if (match == null) + { + throw new ArgumentNullException(nameof(match)); + } + + PooledRefList list = new PooledRefList(); + for (int i = 0; i < _size; i++) + { + if (match(_items[i])) + { + list.Add(_items[i]); + } + } + return list; + } + + public int FindIndex(Predicate match) => FindIndex(0, _size, match); + + public int FindIndex(int startIndex, Predicate match) => FindIndex(startIndex, _size - startIndex, match); + + public int FindIndex(int startIndex, int count, Predicate match) + { + if ((uint)startIndex > (uint)_size) + { + throw new ArgumentOutOfRangeException(nameof(startIndex)); + } + + if (count < 0 || startIndex > _size - count) + { + throw new ArgumentOutOfRangeException(nameof(count)); + } + + if (match == null) + { + throw new ArgumentNullException(nameof(match)); + } + + int endIndex = startIndex + count; + for (int i = startIndex; i < endIndex; i++) + { + if (match(_items[i])) + { + return i; + } + } + return -1; + } + + public T? FindLast(Predicate match) + { + if (match == null) + { + throw new ArgumentNullException(nameof(match)); + } + + for (int i = _size - 1; i >= 0; i--) + { + if (match(_items[i])) + { + return _items[i]; + } + } + return default; + } + + public int FindLastIndex(Predicate match) => FindLastIndex(_size - 1, _size, match); + + public int FindLastIndex(int startIndex, Predicate match) => FindLastIndex(startIndex, startIndex + 1, match); + + public int FindLastIndex(int startIndex, int count, Predicate match) + { + if (match == null) + { + throw new ArgumentNullException(nameof(match)); + } + + if (_size == 0) + { + // Special case for 0 length List + if (startIndex != -1) + { + throw new ArgumentOutOfRangeException(nameof(startIndex)); + } + } + else + { + // Make sure we're not out of range + if ((uint)startIndex >= (uint)_size) + { + throw new ArgumentOutOfRangeException(nameof(startIndex)); + } + } + + // 2nd have of this also catches when startIndex == MAXINT, so MAXINT - 0 + 1 == -1, which is < 0. + if (count < 0 || startIndex - count + 1 < 0) + { + throw new ArgumentOutOfRangeException(nameof(count)); + } + + int endIndex = startIndex - count; + for (int i = startIndex; i > endIndex; i--) + { + if (match(_items[i])) + { + return i; + } + } + return -1; + } + + public void ForEach(Action action) + { + if (action == null) + { + throw new ArgumentNullException(nameof(action)); + } + + int version = _version; + + for (int i = 0; i < _size; i++) + { + if (version != _version) + { + break; + } + action(_items[i]); + } + + if (version != _version) + { + throw new InvalidOperationException(CollectionThrowStrings.InvalidOperation_EnumFailedVersion); + } + } + + // Returns an enumerator for this list with the given + // permission for removal of elements. If modifications made to the list + // while an enumeration is in progress, the MoveNext and + // GetObject methods of the enumerator will throw an exception. + // + public Enumerator GetEnumerator() => new(this); + + public PooledRefList GetRange(int index, int count) + { + if (index < 0) + { + throw new ArgumentOutOfRangeException(nameof(index)); + } + + if (count < 0) + { + throw new ArgumentOutOfRangeException(nameof(count)); + } + + if (_size - index < count) + { + throw new ArgumentException("Length must be greater than zero"); + } + + PooledRefList list = new PooledRefList(count); + Array.Copy(_items, index, list._items, 0, count); + list._size = count; + return list; + } + + // Returns the index of the first occurrence of a given value in a range of + // this list. The list is searched forwards from beginning to end. + // The elements of the list are compared to the given value using the + // Object.Equals method. + // + // This method uses the Array.IndexOf method to perform the + // search. + // + public int IndexOf(T item) => Array.IndexOf(_items, item, 0, _size); + + // Returns the index of the first occurrence of a given value in a range of + // this list. The list is searched forwards, starting at index + // index and ending at count number of elements. The + // elements of the list are compared to the given value using the + // Object.Equals method. + // + // This method uses the Array.IndexOf method to perform the + // search. + // + public int IndexOf(T item, int index) + { + if (index > _size) + { + throw new ArgumentOutOfRangeException(nameof(index)); + } + + return Array.IndexOf(_items, item, index, _size - index); + } + + // Returns the index of the first occurrence of a given value in a range of + // this list. The list is searched forwards, starting at index + // index and upto count number of elements. The + // elements of the list are compared to the given value using the + // Object.Equals method. + // + // This method uses the Array.IndexOf method to perform the + // search. + // + public int IndexOf(T item, int index, int count) + { + if (index > _size) + { + throw new ArgumentOutOfRangeException(nameof(index)); + } + + if (count < 0 || index > _size - count) + { + throw new ArgumentOutOfRangeException(nameof(count)); + } + + return Array.IndexOf(_items, item, index, count); + } + + // Inserts an element into this list at a given index. The size of the list + // is increased by one. If required, the capacity of the list is doubled + // before inserting the new element. + // + public void Insert(int index, T item) + { + // Note that insertions at the end are legal. + if ((uint)index > (uint)_size) + { + throw new ArgumentOutOfRangeException(nameof(index)); + } + if (_size == _items.Length) + { + Grow(_size + 1); + } + + if (index < _size) + { + Array.Copy(_items, index, _items, index + 1, _size - index); + } + _items[index] = item; + _size++; + _version++; + } + + // Inserts the elements of the given collection at a given index. If + // required, the capacity of the list is increased to twice the previous + // capacity or the new size, whichever is larger. Ranges may be added + // to the end of the list by setting index to the List's size. + // + public void InsertRange(int index, IEnumerable collection) + { + if (collection == null) + { + throw new ArgumentNullException(nameof(collection)); + } + + if ((uint)index > (uint)_size) + { + throw new ArgumentOutOfRangeException(nameof(index)); + } + + if (collection is ICollection c) + { + int count = c.Count; + if (count > 0) + { + if (_items.Length - _size < count) + { + Grow(_size + count); + } + if (index < _size) + { + Array.Copy(_items, index, _items, index + count, _size - index); + } + + c.CopyTo(_items, index); + _size += count; + } + } + else + { + using IEnumerator en = collection.GetEnumerator(); + while (en.MoveNext()) + { + Insert(index++, en.Current); + } + } + _version++; + } + + // Returns the index of the last occurrence of a given value in a range of + // this list. The list is searched backwards, starting at the end + // and ending at the first element in the list. The elements of the list + // are compared to the given value using the Object.Equals method. + // + // This method uses the Array.LastIndexOf method to perform the + // search. + // + public int LastIndexOf(T item) + { + if (_size == 0) + { // Special case for empty list + return -1; + } + + return LastIndexOf(item, _size - 1, _size); + } + + // Returns the index of the last occurrence of a given value in a range of + // this list. The list is searched backwards, starting at index + // index and ending at the first element in the list. The + // elements of the list are compared to the given value using the + // Object.Equals method. + // + // This method uses the Array.LastIndexOf method to perform the + // search. + // + public int LastIndexOf(T item, int index) + { + if (index >= _size) + { + throw new ArgumentOutOfRangeException(nameof(index)); + } + + return LastIndexOf(item, index, index + 1); + } + + // Returns the index of the last occurrence of a given value in a range of + // this list. The list is searched backwards, starting at index + // index and upto count elements. The elements of + // the list are compared to the given value using the Object.Equals + // method. + // + // This method uses the Array.LastIndexOf method to perform the + // search. + // + public int LastIndexOf(T item, int index, int count) + { + if (Count != 0 && index < 0) + { + throw new ArgumentOutOfRangeException(nameof(index)); + } + + if (Count != 0 && count < 0) + { + throw new ArgumentOutOfRangeException(nameof(count)); + } + + if (_size == 0) + { // Special case for empty list + return -1; + } + + if (index >= _size) + { + throw new ArgumentOutOfRangeException(nameof(index)); + } + + if (count > index + 1) + { + throw new ArgumentOutOfRangeException(nameof(count)); + } + + return Array.LastIndexOf(_items, item, index, count); + } + + // Removes the element at the given index. The size of the list is + // decreased by one. + public bool Remove(T item) + { + int index = IndexOf(item); + if (index >= 0) + { + RemoveAt(index); + return true; + } + + return false; + } + + // This method removes all items which matches the predicate. + // The complexity is O(n). + public int RemoveAll(Predicate match) + { + if (match == null) + { + throw new ArgumentNullException(nameof(match)); + } + + int freeIndex = 0; // the first free slot in items array + + // Find the first item which needs to be removed. + while (freeIndex < _size && !match(_items[freeIndex])) + { + freeIndex++; + } + + if (freeIndex >= _size) + { + return 0; + } + + int current = freeIndex + 1; + while (current < _size) + { + // Find the first item which needs to be kept. + while (current < _size && match(_items[current])) + { + current++; + } + + if (current < _size) + { + // copy item to the free slot. + _items[freeIndex++] = _items[current++]; + } + } + + if (RuntimeHelpers.IsReferenceOrContainsReferences()) + { + Array.Clear(_items, freeIndex, _size - freeIndex); // Clear the elements so that the gc can reclaim the references. + } + + int result = _size - freeIndex; + _size = freeIndex; + _version++; + return result; + } + + // Removes the element at the given index. The size of the list is + // decreased by one. + public void RemoveAt(int index) + { + if ((uint)index >= (uint)_size) + { + throw new ArgumentOutOfRangeException(nameof(index)); + } + _size--; + if (index < _size) + { + Array.Copy(_items, index + 1, _items, index, _size - index); + } + if (RuntimeHelpers.IsReferenceOrContainsReferences()) + { + _items[_size] = default!; + } + _version++; + } + + // Removes a range of elements from this list. + public void RemoveRange(int index, int count) + { + if (index < 0) + { + throw new ArgumentOutOfRangeException(nameof(index)); + } + + if (count < 0) + { + throw new ArgumentOutOfRangeException(nameof(count)); + } + + if (_size - index < count) + { + throw new ArgumentException("Length must be greater than zero"); + } + + if (count > 0) + { + _size -= count; + if (index < _size) + { + Array.Copy(_items, index + count, _items, index, _size - index); + } + + _version++; + if (RuntimeHelpers.IsReferenceOrContainsReferences()) + { + Array.Clear(_items, _size, count); + } + } + } + + // Reverses the elements in this list. + public void Reverse() => Reverse(0, Count); + + // Reverses the elements in a range of this list. Following a call to this + // method, an element in the range given by index and count + // which was previously located at index i will now be located at + // index index + (index + count - i - 1). + // + public void Reverse(int index, int count) + { + if (index < 0) + { + throw new ArgumentOutOfRangeException(nameof(index)); + } + + if (count < 0) + { + throw new ArgumentOutOfRangeException(nameof(count)); + } + + if (_size - index < count) + { + throw new ArgumentException("Length must be greater than zero"); + } + + if (count > 1) + { + Array.Reverse(_items, index, count); + } + _version++; + } + + // Sorts the elements in this list. Uses the default comparer and + // Array.Sort. + public void Sort() => Sort(0, Count, null); + + // Sorts the elements in this list. Uses Array.Sort with the + // provided comparer. + public void Sort(IComparer? comparer) => Sort(0, Count, comparer); + + // Sorts the elements in a section of this list. The sort compares the + // elements to each other using the given IComparer interface. If + // comparer is null, the elements are compared to each other using + // the IComparable interface, which in that case must be implemented by all + // elements of the list. + // + // This method uses the Array.Sort method to sort the elements. + // + public void Sort(int index, int count, IComparer? comparer) + { + if (index < 0) + { + throw new ArgumentOutOfRangeException(nameof(index)); + } + + if (count < 0) + { + throw new ArgumentOutOfRangeException(nameof(count)); + } + + if (_size - index < count) + { + throw new ArgumentException("Length must be greater than zero"); + } + + if (count > 1) + { + Array.Sort(_items, index, count, comparer); + } + _version++; + } + + public void Sort(Comparison comparison) + { + if (comparison == null) + { + throw new ArgumentNullException(nameof(comparison)); + } + + if (_size > 1) + { + Array.Sort(_items, comparison); + } + _version++; + } + + // ToArray returns an array containing the contents of the List. + // This requires copying the List, which is an O(n) operation. + public T[] ToArray() + { + if (_size == 0) + { + return s_emptyArray; + } + + T[] array = new T[_size]; + Array.Copy(_items, array, _size); + return array; + } + + public T[] ToPooledArray() + { + if (_size == 0) + { + return s_emptyArray; + } + + T[] array = ArrayPool.Rent(_size); + Array.Copy(_items, array, _size); + return array; + } + + // Sets the capacity of this list to the size of the list. This method can + // be used to minimize a list's memory overhead once it is known that no + // new elements will be added to the list. To completely clear a list and + // release all memory referenced by the list, execute the following + // statements: + // + // list.Clear(); + // list.TrimExcess(); + // + public void TrimExcess() + { + int threshold = (int)(_items.Length * 0.9); + if (_size < threshold) + { + Capacity = _size; + } + } + + public bool TrueForAll(Predicate match) + { + if (match == null) + { + throw new ArgumentNullException(nameof(match)); + } + + for (int i = 0; i < _size; i++) + { + if (!match(_items[i])) + { + return false; + } + } + return true; + } + + public ref struct Enumerator + { + private readonly PooledRefList _list; + private int _index; + private readonly int _version; + private T? _current; + + internal Enumerator(PooledRefList list) + { + _list = list; + _index = 0; + _version = list._version; + _current = default; + } + + public void Dispose() + { + _index = -2; + _current = default; + } + + public bool MoveNext() + { + PooledRefList localList = _list; + + if (_version == localList._version && (uint)_index < (uint)localList._size) + { + _current = localList._items[_index]; + _index++; + return true; + } + return MoveNextRare(); + } + + private bool MoveNextRare() + { + if (_version != _list._version) + { + throw new InvalidOperationException(CollectionThrowStrings.InvalidOperation_EnumFailedVersion); + } + + _index = _list._size + 1; + _current = default; + return false; + } + + public T Current + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + if (_index == 0 || _index == _list._size + 1) + { + ThrowEnumerationNotStartedOrEnded(); + } + return Current; + } + } + + private void ThrowEnumerationNotStartedOrEnded() + { + Debug.Assert(_index is -1 or -2); + throw new InvalidOperationException(_index == -1 ? CollectionThrowStrings.InvalidOperation_EnumNotStarted : CollectionThrowStrings.InvalidOperation_EnumEnded); + } + + public void Reset() + { + if (_version != _list._version) + { + throw new InvalidOperationException(CollectionThrowStrings.InvalidOperation_EnumFailedVersion); + } + + _index = -1; + _current = default; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Dispose() + { + var array = _items; + + if (array.Length > 0) + { + Clear(); + ArrayPool.Return(_items); + } + + this = default; + } +} diff --git a/Projects/Server/Collections/PooledRefQueue.cs b/Projects/Server/Collections/PooledRefQueue.cs index 3959f0631..00ff4b505 100644 --- a/Projects/Server/Collections/PooledRefQueue.cs +++ b/Projects/Server/Collections/PooledRefQueue.cs @@ -8,487 +8,490 @@ using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using Server.Buffers; -namespace Server.Collections +namespace Server.Collections; + +// A simple Queue of generic objects. Internally it is implemented as a +// circular buffer, so Enqueue can be O(n). Dequeue is O(1). +[DebuggerDisplay("Count = {Count}")] +public ref struct PooledRefQueue { - // A simple Queue of generic objects. Internally it is implemented as a - // circular buffer, so Enqueue can be O(n). Dequeue is O(1). - [DebuggerDisplay("Count = {Count}")] - [System.Serializable] - public ref struct PooledRefQueue + private T[] _array; + private int _head; // The index from which to dequeue if the queue isn't empty. + private int _tail; // The index at which to enqueue if the queue isn't full. + private int _size; // Number of elements. + private bool _mt; + private int _version; + +#pragma warning disable CA1825 // avoid the extra generic instantiation for Array.Empty() + private static readonly T[] s_emptyArray = new T[0]; +#pragma warning restore CA1825 + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static PooledRefQueue Create(int capacity = 32, bool mt = false) => new(capacity, mt); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static PooledRefQueue CreateMT(int capacity = 32) => new(capacity, true); + + // Creates a queue with room for capacity objects. The default grow factor + // is used. + public PooledRefQueue(int capacity, bool mt = false) { - private T[] _array; - private int _head; // The index from which to dequeue if the queue isn't empty. - private int _tail; // The index at which to enqueue if the queue isn't full. - private int _size; // Number of elements. - private bool _mt; - private int _version; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static PooledRefQueue Create(int capacity = 32, bool mt = false) => new(capacity, mt); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static PooledRefQueue CreateMT(int capacity = 32) => new(capacity, true); - - // Creates a queue with room for capacity objects. The default grow factor - // is used. - public PooledRefQueue(int capacity, bool mt = false) + _mt = mt; + _array = capacity switch { - _mt = mt; - _array = capacity switch - { - < 0 => throw new ArgumentOutOfRangeException(nameof(capacity), capacity, CollectionThrowStrings.ArgumentOutOfRange_NeedNonNegNum), - 0 => Array.Empty(), - _ => (mt ? ArrayPool.Shared : STArrayPool.Shared).Rent(capacity) - }; + < 0 => throw new ArgumentOutOfRangeException(nameof(capacity), capacity, CollectionThrowStrings.ArgumentOutOfRange_NeedNonNegNum), + 0 => s_emptyArray, + _ => (mt ? ArrayPool.Shared : STArrayPool.Shared).Rent(capacity) + }; - _head = 0; - _tail = 0; - _size = 0; - _version = 0; - } + _head = 0; + _tail = 0; + _size = 0; + _version = 0; + } - public int Count => _size; + public int Count => _size; - // Removes all Objects from the queue. - public void Clear() + // Removes all Objects from the queue. + public void Clear() + { + if (_size != 0) { - if (_size != 0) - { - if (RuntimeHelpers.IsReferenceOrContainsReferences()) - { - if (_head < _tail) - { - Array.Clear(_array, _head, _size); - } - else - { - Array.Clear(_array, _head, _array.Length - _head); - Array.Clear(_array, 0, _tail); - } - } - - _size = 0; - } - - _head = 0; - _tail = 0; - _version++; - } - - // CopyTo copies a collection into an Array, starting at a particular - // index into the array. - public void CopyTo(T[] array, int arrayIndex) - { - if (array == null) - { - throw new ArgumentNullException(nameof(array)); - } - - if (arrayIndex < 0 || arrayIndex > array.Length) - { - throw new ArgumentOutOfRangeException(nameof(arrayIndex), arrayIndex, CollectionThrowStrings.ArgumentOutOfRange_Index); - } - - if (array.Length - arrayIndex < _size) - { - throw new ArgumentException(CollectionThrowStrings.Argument_InvalidOffLen); - } - - int numToCopy = _size; - if (numToCopy == 0) - { - return; - } - - int firstPart = Math.Min(_array.Length - _head, numToCopy); - Array.Copy(_array, _head, array, arrayIndex, firstPart); - numToCopy -= firstPart; - if (numToCopy > 0) - { - Array.Copy(_array, 0, array, arrayIndex + _array.Length - _head, numToCopy); - } - } - - // Adds item to the tail of the queue. - public void Enqueue(T item) - { - if (_size == _array.Length) - { - Grow(_size + 1); - } - - _array[_tail] = item; - MoveNext(ref _tail); - _size++; - _version++; - } - - // GetEnumerator returns an IEnumerator over this Queue. This - // Enumerator will support removing. - public Enumerator GetEnumerator() => new(this); - - // Removes the object at the head of the queue and returns it. If the queue - // is empty, this method throws an - // InvalidOperationException. - public T Dequeue() - { - int head = _head; - T[] array = _array; - - if (_size == 0) - { - ThrowForEmptyQueue(); - } - - T removed = array[head]; if (RuntimeHelpers.IsReferenceOrContainsReferences()) - { - array[head] = default!; - } - MoveNext(ref _head); - _size--; - _version++; - return removed; - } - - public bool TryDequeue([MaybeNullWhen(false)] out T result) - { - int head = _head; - T[] array = _array; - - if (_size == 0) - { - result = default!; - return false; - } - - result = array[head]; - if (RuntimeHelpers.IsReferenceOrContainsReferences()) - { - array[head] = default!; - } - MoveNext(ref _head); - _size--; - _version++; - return true; - } - - // Returns the object at the head of the queue. The object remains in the - // queue. If the queue is empty, this method throws an - // InvalidOperationException. - public T Peek() - { - if (_size == 0) - { - ThrowForEmptyQueue(); - } - - return _array[_head]; - } - - public T PeekRandom() - { - if (_size == 0) - { - ThrowForEmptyQueue(); - } - - var index = _head + Utility.Random(_size); - if (index >= _array.Length) - { - index -= _array.Length; - } - - return _array[index]; - } - - public bool TryPeek([MaybeNullWhen(false)] out T result) - { - if (_size == 0) - { - result = default!; - return false; - } - - result = _array[_head]; - return true; - } - - // Returns true if the queue contains at least one object equal to item. - // Equality is determined using EqualityComparer.Default.Equals(). - public bool Contains(T item) - { - if (_size == 0) - { - return false; - } - - if (_head < _tail) - { - return Array.IndexOf(_array, item, _head, _size) >= 0; - } - - // We've wrapped around. Check both partitions, the least recently enqueued first. - return - Array.IndexOf(_array, item, _head, _array.Length - _head) >= 0 || - Array.IndexOf(_array, item, 0, _tail) >= 0; - } - - // Iterates over the objects in the queue, returning an array of the - // objects in the Queue, or an empty array if the queue is empty. - // The order of elements in the array is first in to last in, the same - // order produced by successive calls to Dequeue. - public T[] ToArray() - { - if (_size == 0) - { - return Array.Empty(); - } - - T[] arr = new T[_size]; - - if (_head < _tail) - { - Array.Copy(_array, _head, arr, 0, _size); - } - else - { - Array.Copy(_array, _head, arr, 0, _array.Length - _head); - Array.Copy(_array, 0, arr, _array.Length - _head, _tail); - } - - return arr; - } - - public T[] ToPooledArray(bool mt = false) - { - if (_size == 0) - { - return Array.Empty(); - } - - T[] arr = (mt ? ArrayPool.Shared : STArrayPool.Shared).Rent(_size); - - if (_head < _tail) - { - Array.Copy(_array, _head, arr, 0, _size); - } - else - { - Array.Copy(_array, _head, arr, 0, _array.Length - _head); - Array.Copy(_array, 0, arr, _array.Length - _head, _tail); - } - - return arr; - } - - // PRIVATE Grows or shrinks the buffer to hold capacity objects. Capacity - // must be >= _size. - private void SetCapacity(int capacity) - { - T[] newarray = (_mt ? ArrayPool.Shared : STArrayPool.Shared).Rent(capacity); - if (_size > 0) { if (_head < _tail) { - Array.Copy(_array, _head, newarray, 0, _size); + Array.Clear(_array, _head, _size); } else { - Array.Copy(_array, _head, newarray, 0, _array.Length - _head); - Array.Copy(_array, 0, newarray, _array.Length - _head, _tail); + Array.Clear(_array, _head, _array.Length - _head); + Array.Clear(_array, 0, _tail); } } - if (_array.Length > 0) - { - Clear(); - (_mt ? ArrayPool.Shared : STArrayPool.Shared).Return(_array); - } - - _array = newarray; - _head = 0; - _tail = _size == capacity ? 0 : _size; - _version++; + _size = 0; } - // Increments the index wrapping it if necessary. - private void MoveNext(ref int index) + _head = 0; + _tail = 0; + _version++; + } + + // CopyTo copies a collection into an Array, starting at a particular + // index into the array. + public void CopyTo(T[] array, int arrayIndex) + { + if (array == null) { - // It is tempting to use the remainder operator here but it is actually much slower - // than a simple comparison and a rarely taken branch. - // JIT produces better code than with ternary operator ?: - int tmp = index + 1; - if (tmp == _array.Length) - { - tmp = 0; - } - index = tmp; + throw new ArgumentNullException(nameof(array)); } - private void ThrowForEmptyQueue() + if (arrayIndex < 0 || arrayIndex > array.Length) { - Debug.Assert(_size == 0); - throw new InvalidOperationException(CollectionThrowStrings.InvalidOperation_EmptyQueue); + throw new ArgumentOutOfRangeException(nameof(arrayIndex), arrayIndex, CollectionThrowStrings.ArgumentOutOfRange_Index); } - /// - /// Ensures that the capacity of this Queue is at least the specified . - /// - /// The minimum capacity to ensure. - public int EnsureCapacity(int capacity) + if (array.Length - arrayIndex < _size) { - if (capacity < 0) - { - throw new ArgumentOutOfRangeException(nameof(capacity), capacity, CollectionThrowStrings.ArgumentOutOfRange_NeedNonNegNum); - } - - if (_array.Length < capacity) - { - Grow(capacity); - } - - return _array.Length; + throw new ArgumentException(CollectionThrowStrings.Argument_InvalidOffLen); } - private void Grow(int capacity) + int numToCopy = _size; + if (numToCopy == 0) { - const int GrowFactor = 2; - const int MinimumGrow = 4; - - int newcapacity = GrowFactor * _array.Length; - - // Allow the list to grow to maximum possible capacity (~2G elements) before encountering overflow. - // Note that this check works even when _items.Length overflowed thanks to the (uint) cast - if ((uint)newcapacity > int.MaxValue) - { - newcapacity = int.MaxValue; - } - - // Ensure minimum growth is respected. - newcapacity = Math.Max(newcapacity, _array.Length + MinimumGrow); - - // If the computed capacity is still less than specified, set to the original argument. - // Capacities exceeding Array.MaxLength will be surfaced as OutOfMemoryException by Array.Resize. - if (newcapacity < capacity) - { - newcapacity = capacity; - } - - SetCapacity(newcapacity); + return; + } + + int firstPart = Math.Min(_array.Length - _head, numToCopy); + Array.Copy(_array, _head, array, arrayIndex, firstPart); + numToCopy -= firstPart; + if (numToCopy > 0) + { + Array.Copy(_array, 0, array, arrayIndex + _array.Length - _head, numToCopy); + } + } + + // Adds item to the tail of the queue. + public void Enqueue(T item) + { + if (_size == _array.Length) + { + Grow(_size + 1); + } + + _array[_tail] = item; + MoveNext(ref _tail); + _size++; + _version++; + } + + // GetEnumerator returns an IEnumerator over this Queue. This + // Enumerator will support removing. + public Enumerator GetEnumerator() => new(this); + + // Removes the object at the head of the queue and returns it. If the queue + // is empty, this method throws an + // InvalidOperationException. + public T Dequeue() + { + int head = _head; + T[] array = _array; + + if (_size == 0) + { + ThrowForEmptyQueue(); + } + + T removed = array[head]; + if (RuntimeHelpers.IsReferenceOrContainsReferences()) + { + array[head] = default!; + } + MoveNext(ref _head); + _size--; + _version++; + return removed; + } + + public bool TryDequeue([MaybeNullWhen(false)] out T result) + { + int head = _head; + T[] array = _array; + + if (_size == 0) + { + result = default!; + return false; + } + + result = array[head]; + if (RuntimeHelpers.IsReferenceOrContainsReferences()) + { + array[head] = default!; + } + MoveNext(ref _head); + _size--; + _version++; + return true; + } + + // Returns the object at the head of the queue. The object remains in the + // queue. If the queue is empty, this method throws an + // InvalidOperationException. + public T Peek() + { + if (_size == 0) + { + ThrowForEmptyQueue(); + } + + return _array[_head]; + } + + public T PeekRandom() + { + if (_size == 0) + { + ThrowForEmptyQueue(); + } + + var index = _head + Utility.Random(_size); + if (index >= _array.Length) + { + index -= _array.Length; + } + + return _array[index]; + } + + public bool TryPeek([MaybeNullWhen(false)] out T result) + { + if (_size == 0) + { + result = default!; + return false; + } + + result = _array[_head]; + return true; + } + + // Returns true if the queue contains at least one object equal to item. + // Equality is determined using EqualityComparer.Default.Equals(). + public bool Contains(T item) + { + if (_size == 0) + { + return false; + } + + if (_head < _tail) + { + return Array.IndexOf(_array, item, _head, _size) >= 0; + } + + // We've wrapped around. Check both partitions, the least recently enqueued first. + return + Array.IndexOf(_array, item, _head, _array.Length - _head) >= 0 || + Array.IndexOf(_array, item, 0, _tail) >= 0; + } + + // Iterates over the objects in the queue, returning an array of the + // objects in the Queue, or an empty array if the queue is empty. + // The order of elements in the array is first in to last in, the same + // order produced by successive calls to Dequeue. + public T[] ToArray() + { + if (_size == 0) + { + return s_emptyArray; + } + + T[] arr = new T[_size]; + + if (_head < _tail) + { + Array.Copy(_array, _head, arr, 0, _size); + } + else + { + Array.Copy(_array, _head, arr, 0, _array.Length - _head); + Array.Copy(_array, 0, arr, _array.Length - _head, _tail); + } + + return arr; + } + + public T[] ToPooledArray(bool mt = false) + { + if (_size == 0) + { + return s_emptyArray; + } + + T[] arr = (mt ? ArrayPool.Shared : STArrayPool.Shared).Rent(_size); + + if (_head < _tail) + { + Array.Copy(_array, _head, arr, 0, _size); + } + else + { + Array.Copy(_array, _head, arr, 0, _array.Length - _head); + Array.Copy(_array, 0, arr, _array.Length - _head, _tail); + } + + return arr; + } + + // PRIVATE Grows or shrinks the buffer to hold capacity objects. Capacity + // must be >= _size. + private void SetCapacity(int capacity) + { + T[] newarray = (_mt ? ArrayPool.Shared : STArrayPool.Shared).Rent(capacity); + if (_size > 0) + { + if (_head < _tail) + { + Array.Copy(_array, _head, newarray, 0, _size); + } + else + { + Array.Copy(_array, _head, newarray, 0, _array.Length - _head); + Array.Copy(_array, 0, newarray, _array.Length - _head, _tail); + } + } + + if (_array.Length > 0) + { + Clear(); + (_mt ? ArrayPool.Shared : STArrayPool.Shared).Return(_array); + } + + _array = newarray; + _head = 0; + _tail = _size == capacity ? 0 : _size; + _version++; + } + + // Increments the index wrapping it if necessary. + private void MoveNext(ref int index) + { + // It is tempting to use the remainder operator here but it is actually much slower + // than a simple comparison and a rarely taken branch. + // JIT produces better code than with ternary operator ?: + int tmp = index + 1; + if (tmp == _array.Length) + { + tmp = 0; + } + index = tmp; + } + + private void ThrowForEmptyQueue() + { + Debug.Assert(_size == 0); + throw new InvalidOperationException(CollectionThrowStrings.InvalidOperation_EmptyQueue); + } + + /// + /// Ensures that the capacity of this Queue is at least the specified . + /// + /// The minimum capacity to ensure. + public int EnsureCapacity(int capacity) + { + if (capacity < 0) + { + throw new ArgumentOutOfRangeException(nameof(capacity), capacity, CollectionThrowStrings.ArgumentOutOfRange_NeedNonNegNum); + } + + if (_array.Length < capacity) + { + Grow(capacity); + } + + return _array.Length; + } + + private void Grow(int capacity) + { + const int GrowFactor = 2; + const int MinimumGrow = 4; + + int newcapacity = GrowFactor * _array.Length; + + // Allow the list to grow to maximum possible capacity (~2G elements) before encountering overflow. + // Note that this check works even when _items.Length overflowed thanks to the (uint) cast + if ((uint)newcapacity > int.MaxValue) + { + newcapacity = int.MaxValue; + } + + // Ensure minimum growth is respected. + newcapacity = Math.Max(newcapacity, _array.Length + MinimumGrow); + + // If the computed capacity is still less than specified, set to the original argument. + // Capacities exceeding Array.MaxLength will be surfaced as OutOfMemoryException by Array.Resize. + if (newcapacity < capacity) + { + newcapacity = capacity; + } + + SetCapacity(newcapacity); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Dispose() + { + var array = _array; + if (array.Length > 0) + { + Clear(); + (_mt ? ArrayPool.Shared : STArrayPool.Shared).Return(array); + } + + this = default; + } + + // Implements an enumerator for a Queue. The enumerator uses the + // internal version number of the list to ensure that no modifications are + // made to the list while an enumeration is in progress. + public ref struct Enumerator + { + private readonly PooledRefQueue _q; + private readonly int _version; + private int _index; // -1 = not started, -2 = ended/disposed + private T? _currentElement; + + internal Enumerator(PooledRefQueue q) + { + _q = q; + _version = q._version; + _index = -1; + _currentElement = default; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Dispose() { - var array = _array; - if (array.Length > 0) - { - Clear(); - (_mt ? ArrayPool.Shared : STArrayPool.Shared).Return(array); - } - - this = default; + _index = -2; + _currentElement = default; } - // Implements an enumerator for a Queue. The enumerator uses the - // internal version number of the list to ensure that no modifications are - // made to the list while an enumeration is in progress. - public ref struct Enumerator + public bool MoveNext() { - private readonly PooledRefQueue _q; - private readonly int _version; - private int _index; // -1 = not started, -2 = ended/disposed - private T? _currentElement; - - internal Enumerator(PooledRefQueue q) + if (_version != _q._version) { - _q = q; - _version = q._version; - _index = -1; - _currentElement = default; + throw new InvalidOperationException(CollectionThrowStrings.InvalidOperation_EnumFailedVersion); } - public void Dispose() + if (_index == -2) { + return false; + } + + _index++; + + if (_index == _q._size) + { + // We've run past the last element _index = -2; _currentElement = default; + return false; } - public bool MoveNext() + // Cache some fields in locals to decrease code size + T[] array = _q._array; + int capacity = array.Length; + + // _index represents the 0-based index into the queue, however the queue + // doesn't have to start from 0 and it may not even be stored contiguously in memory. + + int arrayIndex = _q._head + _index; // this is the actual index into the queue's backing array + if (arrayIndex >= capacity) { - if (_version != _q._version) - { - throw new InvalidOperationException(CollectionThrowStrings.InvalidOperation_EnumFailedVersion); - } + // NOTE: Originally we were using the modulo operator here, however + // on Intel processors it has a very high instruction latency which + // was slowing down the loop quite a bit. + // Replacing it with simple comparison/subtraction operations sped up + // the average foreach loop by 2x. - if (_index == -2) - { - return false; - } - - _index++; - - if (_index == _q._size) - { - // We've run past the last element - _index = -2; - _currentElement = default; - return false; - } - - // Cache some fields in locals to decrease code size - T[] array = _q._array; - int capacity = array.Length; - - // _index represents the 0-based index into the queue, however the queue - // doesn't have to start from 0 and it may not even be stored contiguously in memory. - - int arrayIndex = _q._head + _index; // this is the actual index into the queue's backing array - if (arrayIndex >= capacity) - { - // NOTE: Originally we were using the modulo operator here, however - // on Intel processors it has a very high instruction latency which - // was slowing down the loop quite a bit. - // Replacing it with simple comparison/subtraction operations sped up - // the average foreach loop by 2x. - - arrayIndex -= capacity; // wrap around if needed - } - - _currentElement = array[arrayIndex]; - return true; + arrayIndex -= capacity; // wrap around if needed } - public T Current + _currentElement = array[arrayIndex]; + return true; + } + + public T Current + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get { - get + if (_index < 0) { - if (_index < 0) - { - ThrowEnumerationNotStartedOrEnded(); - } - - return _currentElement!; - } - } - - private void ThrowEnumerationNotStartedOrEnded() - { - Debug.Assert(_index is -1 or -2); - throw new InvalidOperationException(_index == -1 ? CollectionThrowStrings.InvalidOperation_EnumNotStarted : CollectionThrowStrings.InvalidOperation_EnumEnded); - } - - public void Reset() - { - if (_version != _q._version) - { - throw new InvalidOperationException(CollectionThrowStrings.InvalidOperation_EnumFailedVersion); + ThrowEnumerationNotStartedOrEnded(); } - _index = -1; - _currentElement = default; + return _currentElement!; } } + + private void ThrowEnumerationNotStartedOrEnded() + { + Debug.Assert(_index is -1 or -2); + throw new InvalidOperationException(_index == -1 ? CollectionThrowStrings.InvalidOperation_EnumNotStarted : CollectionThrowStrings.InvalidOperation_EnumEnded); + } + + public void Reset() + { + if (_version != _q._version) + { + throw new InvalidOperationException(CollectionThrowStrings.InvalidOperation_EnumFailedVersion); + } + + _index = -1; + _currentElement = default; + } } } diff --git a/Projects/Server/Json/Converters/ClientVersionConverterFactory.cs b/Projects/Server/Json/Converters/ClientVersionConverterFactory.cs index 3e778d591..c5a5b6e00 100644 --- a/Projects/Server/Json/Converters/ClientVersionConverterFactory.cs +++ b/Projects/Server/Json/Converters/ClientVersionConverterFactory.cs @@ -14,7 +14,6 @@ *************************************************************************/ using System; -using System.Net; using System.Text.Json; using System.Text.Json.Serialization; diff --git a/Projects/Server/Network/Packets/IncomingVendorPackets.cs b/Projects/Server/Network/Packets/IncomingVendorPackets.cs index e2e12a689..7328639c7 100644 --- a/Projects/Server/Network/Packets/IncomingVendorPackets.cs +++ b/Projects/Server/Network/Packets/IncomingVendorPackets.cs @@ -14,7 +14,6 @@ *************************************************************************/ using System.Collections.Generic; -using System.IO; namespace Server.Network; diff --git a/Projects/Server/Skills.cs b/Projects/Server/Skills.cs index 75bfaf0c9..0bb156e35 100644 --- a/Projects/Server/Skills.cs +++ b/Projects/Server/Skills.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Runtime.CompilerServices; using Server.Network; diff --git a/Projects/Server/TileMatrix/TileMatrixPatch.cs b/Projects/Server/TileMatrix/TileMatrixPatch.cs index 7c55949fe..83b097558 100644 --- a/Projects/Server/TileMatrix/TileMatrixPatch.cs +++ b/Projects/Server/TileMatrix/TileMatrixPatch.cs @@ -1,7 +1,6 @@ using System; using System.IO; using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; namespace Server { From e9f986f55b34ea76fb0c2ff1084e043131fcb53c Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sat, 26 Mar 2022 13:57:42 -0700 Subject: [PATCH 113/213] fix: Adds Gen2 callback for each STArrayPool (#971) Adds. Gen2Callback for STArrayPool so it can purge the internal array stacks properly. This only happens if significant timed has passed, 2 Gen 2's have been run, and memory pressure exceeds a threshold. --- Projects/Server/Buffers/STArrayPool.cs | 8 ++ .../GarbageCollection/Gen2GcCallback.cs | 75 +++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 Projects/Server/GarbageCollection/Gen2GcCallback.cs diff --git a/Projects/Server/Buffers/STArrayPool.cs b/Projects/Server/Buffers/STArrayPool.cs index 72ddca91b..8210aa3de 100644 --- a/Projects/Server/Buffers/STArrayPool.cs +++ b/Projects/Server/Buffers/STArrayPool.cs @@ -6,6 +6,7 @@ using System.Buffers; using System.Diagnostics; using System.Numerics; using System.Runtime.CompilerServices; +using System.Threading; namespace Server.Buffers; @@ -20,6 +21,7 @@ public class STArrayPool : ArrayPool public static STArrayPool Shared => _shared; + private int _trimCallbackCreated; private static STArray[] _cacheBuckets; private STArrayStack[] _buckets = new STArrayStack[BucketCount]; @@ -172,6 +174,12 @@ public class STArrayPool : ArrayPool { Debug.Assert(_cacheBuckets is null, $"Non-null {nameof(_cacheBuckets)}"); var buckets = new STArray[BucketCount]; + + if (Interlocked.Exchange(ref _trimCallbackCreated, 1) == 0) + { + Gen2GcCallback.Register(o => ((STArrayPool)o).Trim(), this); + } + return _cacheBuckets = buckets; } diff --git a/Projects/Server/GarbageCollection/Gen2GcCallback.cs b/Projects/Server/GarbageCollection/Gen2GcCallback.cs new file mode 100644 index 000000000..fc23db8ce --- /dev/null +++ b/Projects/Server/GarbageCollection/Gen2GcCallback.cs @@ -0,0 +1,75 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics; +using System.Runtime.ConstrainedExecution; +using System.Runtime.InteropServices; + +namespace System; + +/// +/// Schedules a callback roughly every gen 2 GC (you may see a Gen 0 an Gen 1 but only once) +/// (We can fix this by capturing the Gen 2 count at startup and testing, but I mostly don't care) +/// +internal sealed class Gen2GcCallback : CriticalFinalizerObject +{ + private readonly Func _callback; + private GCHandle _weakTargetObj; + + private Gen2GcCallback(Func callback, object targetObj) + { + _callback = callback; + _weakTargetObj = GCHandle.Alloc(targetObj, GCHandleType.Weak); + } + + /// + /// Schedule 'callback' to be called in the next GC. If the callback returns true it is + /// rescheduled for the next Gen 2 GC. Otherwise the callbacks stop. + /// + /// NOTE: This callback will be kept alive until either the callback function returns false, + /// or the target object dies. + /// + public static void Register(Func callback, object targetObj) + { + // Create a unreachable object that remembers the callback function and target object. + new Gen2GcCallback(callback, targetObj); + } + + ~Gen2GcCallback() + { + if (_weakTargetObj.IsAllocated) + { + // Check to see if the target object is still alive. + object? targetObj = _weakTargetObj.Target; + if (targetObj == null) + { + // The target object is dead, so this callback object is no longer needed. + _weakTargetObj.Free(); + return; + } + + // Execute the callback method. + try + { + Debug.Assert(_callback != null); + if (_callback?.Invoke(targetObj) != true) + { + // If the callback returns false, this callback object is no longer needed. + _weakTargetObj.Free(); + return; + } + } + catch + { + // Ensure that we still get a chance to resurrect this object, even if the callback throws an exception. +#if DEBUG + // Except in DEBUG, as we really shouldn't be hitting any exceptions here. + throw; +#endif + } + } + + // Resurrect ourselves by re-registering for finalization. + GC.ReRegisterForFinalize(this); + } +} From 81cafa0753fbe3f4251d728eb593d804d5d6a502 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sat, 26 Mar 2022 21:06:46 -0700 Subject: [PATCH 114/213] fix: Fixes bank checks falling to the floor. (#972) --- Projects/UOContent/Gumps/HouseDemolishGump.cs | 2 +- Projects/UOContent/Items/Misc/BankCheck.cs | 112 +++++++----------- Projects/UOContent/Items/Misc/Gold.cs | 2 +- Projects/UOContent/Mobiles/Townfolk/Banker.cs | 6 +- 4 files changed, 46 insertions(+), 76 deletions(-) diff --git a/Projects/UOContent/Gumps/HouseDemolishGump.cs b/Projects/UOContent/Gumps/HouseDemolishGump.cs index ec667c541..eb2780c71 100644 --- a/Projects/UOContent/Gumps/HouseDemolishGump.cs +++ b/Projects/UOContent/Gumps/HouseDemolishGump.cs @@ -138,8 +138,8 @@ namespace Server.Gumps { check.Delete(); - m_Mobile.SendLocalizedMessage(1060397, worth.ToString("#,0")); // ~1_AMOUNT~ gold has been deposited into your bank box. + m_Mobile.SendLocalizedMessage(1060397, $"{worth:#,0}"); m_House.RemoveKeys(m_Mobile); m_House.Delete(); diff --git a/Projects/UOContent/Items/Misc/BankCheck.cs b/Projects/UOContent/Items/Misc/BankCheck.cs index 5683d9d5f..8cce66288 100644 --- a/Projects/UOContent/Items/Misc/BankCheck.cs +++ b/Projects/UOContent/Items/Misc/BankCheck.cs @@ -1,5 +1,4 @@ using System; -using System.Globalization; using Server.Accounting; using Server.Engines.Quests; using Server.Engines.Quests.Haven; @@ -72,19 +71,7 @@ namespace Server.Items public override void GetProperties(ObjectPropertyList list) { base.GetProperties(list); - - string worth; - - if (Core.ML) - { - worth = m_Worth.ToString("N0", CultureInfo.GetCultureInfo("en-US")); - } - else - { - worth = m_Worth.ToString(); - } - - list.Add(1060738, worth); // value: ~1_val~ + list.Add(1060738, Core.ML ? $"{m_Worth:N0}" : m_Worth.ToString()); // value: ~1_val~) } public override void OnAdded(IEntity parent) @@ -144,7 +131,7 @@ namespace Server.Items tradeInfo.VirtualCheck?.UpdateTrade(tradeInfo.Mobile); } - owner.SendLocalizedMessage(1042763, Worth.ToString("#,0")); + owner.SendLocalizedMessage(1042763, $"{m_Worth:N0}"); Delete(); @@ -159,18 +146,17 @@ namespace Server.Items MessageType.Label, 0x3B2, 3, - 1041361, + 1041361, // A bank check: "", AffixType.Append, $" {m_Worth}" - ); // A bank check: + ); } public override void OnDoubleClick(Mobile from) { // This probably isn't OSI accurate, but we can't just make the quests redundant. // Double-clicking the BankCheck in your pack will now credit your account. - var box = AccountGold.Enabled ? from.Backpack : from.FindBankNoCreate(); if (box == null || !IsChildOf(box)) @@ -180,82 +166,68 @@ namespace Server.Items return; } - Delete(); - var deposited = 0; var toAdd = m_Worth; if (AccountGold.Enabled && from.Account?.DepositGold(toAdd) == true) { deposited = toAdd; - toAdd = 0; } - if (toAdd > 0) + while (toAdd > 0) { - Gold gold; + var amount = Math.Min(toAdd, 60000); - while (toAdd > 60000) + var gold = new Gold(amount); + + if (box.TryDropItem(from, gold, false)) { - gold = new Gold(60000); - - if (box.TryDropItem(from, gold, false)) - { - toAdd -= 60000; - deposited += 60000; - } - else - { - gold.Delete(); - - from.AddToBackpack(new BankCheck(toAdd)); - toAdd = 0; - - break; - } + toAdd -= amount; + deposited += amount; } - - if (toAdd > 0) + else { - gold = new Gold(toAdd); - - if (box.TryDropItem(from, gold, false)) - { - deposited += toAdd; - } - else - { - gold.Delete(); - - from.AddToBackpack(new BankCheck(toAdd)); - } + gold.Delete(); + break; } } - // Gold was deposited in your account: - from.SendLocalizedMessage(1042672, true, deposited.ToString("#,0")); - - if (from is PlayerMobile pm) + if (deposited >= m_Worth) { - var qs = pm.Quest; + Delete(); + } + else + { + Worth -= deposited; + } - if (qs is DarkTidesQuest) + if (deposited > 0) + { + // Gold was deposited in your account: + from.SendLocalizedMessage(1042672, true, $"{deposited:N0}"); + + if (from is PlayerMobile pm) { - QuestObjective obj = qs.FindObjective(); + var qs = pm.Quest; - if (obj?.Completed == false) + if (qs is DarkTidesQuest) { - obj.Complete(); + QuestObjective obj = qs.FindObjective(); + + if (obj?.Completed == false) + { + obj.Complete(); + } } - } - if (qs is UzeraanTurmoilQuest) - { - var obj = qs.FindObjective(typeof(Engines.Quests.Haven.CashBankCheckObjective)); - - if (obj?.Completed == false) + if (qs is UzeraanTurmoilQuest) { - obj.Complete(); + var obj = qs.FindObjective(typeof(Engines.Quests.Haven.CashBankCheckObjective)); + + if (obj?.Completed == false) + { + obj.Complete(); + } } } } diff --git a/Projects/UOContent/Items/Misc/Gold.cs b/Projects/UOContent/Items/Misc/Gold.cs index faa7283d1..51e507260 100644 --- a/Projects/UOContent/Items/Misc/Gold.cs +++ b/Projects/UOContent/Items/Misc/Gold.cs @@ -102,7 +102,7 @@ namespace Server.Items tradeInfo.VirtualCheck?.UpdateTrade(tradeInfo.Mobile); } - owner.SendLocalizedMessage(1042763, Amount.ToString("#,0")); + owner.SendLocalizedMessage(1042763, $"{Amount:N0}"); Delete(); diff --git a/Projects/UOContent/Mobiles/Townfolk/Banker.cs b/Projects/UOContent/Mobiles/Townfolk/Banker.cs index 25248dd74..636867bdd 100644 --- a/Projects/UOContent/Mobiles/Townfolk/Banker.cs +++ b/Projects/UOContent/Mobiles/Townfolk/Banker.cs @@ -360,10 +360,8 @@ namespace Server.Mobiles } else { - Say( - 1042759, - GetBalance(e.Mobile).ToString("#,0") - ); // Thy current bank balance is ~1_AMOUNT~ gold. + // Thy current bank balance is ~1_AMOUNT~ gold. + Say(1042759, $"{GetBalance(e.Mobile):N0}"); } break; From 2f6a0fad3a2468dd435f62dc05fb5162e15fb7ee Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sat, 26 Mar 2022 21:15:15 -0700 Subject: [PATCH 115/213] fix: Codegens trappable containers (#973) Splits out trappable container so the logic is easier to expand. Changes trappable containers to be code genned. --- .../TrappableContainer.ExecuteTrap.cs | 146 +++++++++ .../Items/Containers/TrappableContainer.cs | 285 ++++-------------- .../Migrations/Server.Items.Talwar.v0.json | 4 - .../Server.Items.TrappableContainer.v3.json | 27 ++ 4 files changed, 234 insertions(+), 228 deletions(-) create mode 100644 Projects/UOContent/Items/Containers/TrappableContainer.ExecuteTrap.cs delete mode 100644 Projects/UOContent/Migrations/Server.Items.Talwar.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.TrappableContainer.v3.json diff --git a/Projects/UOContent/Items/Containers/TrappableContainer.ExecuteTrap.cs b/Projects/UOContent/Items/Containers/TrappableContainer.ExecuteTrap.cs new file mode 100644 index 000000000..b4fef21d9 --- /dev/null +++ b/Projects/UOContent/Items/Containers/TrappableContainer.ExecuteTrap.cs @@ -0,0 +1,146 @@ +using System; +using System.Runtime.CompilerServices; +using Server.Network; + +namespace Server.Items; + +public partial class TrappableContainer +{ + public virtual bool ExecuteTrap(Mobile from) + { + if (_trapType == TrapType.None) + { + return false; + } + + if (from.AccessLevel >= AccessLevel.GameMaster) + { + SendMessageTo(from, "That is trapped, but you open it with your godly powers.", 0x3B2); + return false; + } + + SendMessageTo(from, 502999, 0x3B2); // You set off a trap! + + var loc = GetWorldLocation(); + + switch (_trapType) + { + case TrapType.ExplosionTrap: + { + ExecuteExplosionTrap(from, loc); + break; + } + case TrapType.MagicTrap: + { + ExecuteMagicTrap(from, loc); + break; + } + case TrapType.DartTrap: + { + ExecuteDartTrap(from, loc); + break; + } + case TrapType.PoisonTrap: + { + ExecutePoisonTrap(from, loc); + break; + } + } + + TrapType = TrapType.None; + TrapPower = 0; + TrapLevel = 0; + return true; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void ExecuteExplosionTrap(Mobile from, Point3D loc) + { + var facet = Map; + if (from.InRange(loc, 3)) + { + int damage; + + if (_trapLevel > 0) + { + damage = Utility.RandomMinMax(10, 30) * _trapLevel; + } + else + { + damage = _trapPower; + } + + AOS.Damage(from, damage, 0, 100, 0, 0, 0); + + // Your skin blisters from the heat! + from.LocalOverheadMessage(MessageType.Regular, 0x2A, 503000); + } + + Effects.SendLocationEffect(loc, facet, 0x36BD, 15); + Effects.PlaySound(loc, facet, 0x307); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void ExecuteMagicTrap(Mobile from, Point3D loc) + { + var facet = Map; + if (from.InRange(loc, 1)) + { + from.Damage(_trapPower); + } + + Effects.PlaySound(loc, facet, 0x307); + + Effects.SendLocationEffect(new Point3D(loc.X - 1, loc.Y, loc.Z), facet, 0x36BD, 15); + Effects.SendLocationEffect(new Point3D(loc.X + 1, loc.Y, loc.Z), facet, 0x36BD, 15); + + Effects.SendLocationEffect(new Point3D(loc.X, loc.Y - 1, loc.Z), facet, 0x36BD, 15); + Effects.SendLocationEffect(new Point3D(loc.X, loc.Y + 1, loc.Z), facet, 0x36BD, 15); + + Effects.SendLocationEffect(new Point3D(loc.X + 1, loc.Y + 1, loc.Z + 11), facet, 0x36BD, 15); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void ExecuteDartTrap(Mobile from, Point3D loc) + { + if (from.InRange(loc, 3)) + { + var damage = _trapLevel > 0 ? Utility.RandomMinMax(5, 15) * _trapLevel : _trapPower; + + AOS.Damage(from, damage, 100, 0, 0, 0, 0); + + // A dart embeds itself in your flesh! + from.LocalOverheadMessage(MessageType.Regular, 0x62, 502998); + } + + Effects.PlaySound(loc, Map, 0x223); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void ExecutePoisonTrap(Mobile from, Point3D loc) + { + var facet = Map; + if (from.InRange(loc, 3)) + { + Poison poison; + + if (_trapLevel > 0) + { + poison = Poison.GetPoison(Math.Max(0, Math.Min(4, _trapLevel - 1))); + } + else + { + AOS.Damage(from, _trapPower, 0, 0, 0, 100, 0); + poison = Poison.Greater; + } + + from.ApplyPoison(from, poison); + + // You are enveloped in a noxious green cloud! + from.LocalOverheadMessage(MessageType.Regular, 0x44, 503004); + } + + Effects.SendLocationEffect(loc, facet, 0x113A, 10, 20); + Effects.PlaySound(loc, facet, 0x231); + } +} diff --git a/Projects/UOContent/Items/Containers/TrappableContainer.cs b/Projects/UOContent/Items/Containers/TrappableContainer.cs index ac9398ae9..f4b4f51f7 100644 --- a/Projects/UOContent/Items/Containers/TrappableContainer.cs +++ b/Projects/UOContent/Items/Containers/TrappableContainer.cs @@ -1,243 +1,80 @@ -using System; using Server.Network; -namespace Server.Items +namespace Server.Items; + +public enum TrapType { - public enum TrapType + None, + MagicTrap, + ExplosionTrap, + DartTrap, + PoisonTrap +} + +[Serializable(3, false)] +public abstract partial class TrappableContainer : BaseContainer, ITelekinesisable +{ + [SerializableField(0)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private int _trapLevel; + + [SerializableField(1)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private int _trapPower; + + [SerializableField(2)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private TrapType _trapType; + + public TrappableContainer(int itemID) : base(itemID) { - None, - MagicTrap, - ExplosionTrap, - DartTrap, - PoisonTrap } - public abstract class TrappableContainer : BaseContainer, ITelekinesisable + public virtual bool TrapOnOpen => true; + + public virtual void OnTelekinesis(Mobile from) { - public TrappableContainer(int itemID) : base(itemID) + Effects.SendLocationParticles(EffectItem.Create(Location, Map, EffectItem.DefaultDuration), 0x376A, 9, 32, 5022); + Effects.PlaySound(Location, Map, 0x1F5); + + if (TrapOnOpen) { + ExecuteTrap(from); + } + } + + private void SendMessageTo(Mobile to, int number, int hue) + { + if (Deleted || !to.CanSee(this)) + { + return; } - public TrappableContainer(Serial serial) : base(serial) + to.NetState.SendMessageLocalized(Serial, ItemID, MessageType.Regular, hue, 3, number); + } + + private void SendMessageTo(Mobile to, string text, int hue) + { + if (Deleted || !to.CanSee(this)) { + return; } - [CommandProperty(AccessLevel.GameMaster)] - public TrapType TrapType { get; set; } + to.NetState.SendMessage(Serial, ItemID, MessageType.Regular, hue, 3, false, "ENU", "", text); + } - [CommandProperty(AccessLevel.GameMaster)] - public int TrapPower { get; set; } - - [CommandProperty(AccessLevel.GameMaster)] - public int TrapLevel { get; set; } - - public virtual bool TrapOnOpen => true; - - public virtual void OnTelekinesis(Mobile from) + public override void Open(Mobile from) + { + if (!TrapOnOpen || !ExecuteTrap(from)) { - Effects.SendLocationParticles(EffectItem.Create(Location, Map, EffectItem.DefaultDuration), 0x376A, 9, 32, 5022); - Effects.PlaySound(Location, Map, 0x1F5); - - if (TrapOnOpen) - { - ExecuteTrap(from); - } + base.Open(from); } + } - private void SendMessageTo(Mobile to, int number, int hue) - { - if (Deleted || !to.CanSee(this)) - { - return; - } - - to.NetState.SendMessageLocalized(Serial, ItemID, MessageType.Regular, hue, 3, number); - } - - private void SendMessageTo(Mobile to, string text, int hue) - { - if (Deleted || !to.CanSee(this)) - { - return; - } - - to.NetState.SendMessage(Serial, ItemID, MessageType.Regular, hue, 3, false, "ENU", "", text); - } - - public virtual bool ExecuteTrap(Mobile from) - { - if (TrapType != TrapType.None) - { - var loc = GetWorldLocation(); - var facet = Map; - - if (from.AccessLevel >= AccessLevel.GameMaster) - { - SendMessageTo(from, "That is trapped, but you open it with your godly powers.", 0x3B2); - return false; - } - - switch (TrapType) - { - case TrapType.ExplosionTrap: - { - SendMessageTo(from, 502999, 0x3B2); // You set off a trap! - - if (from.InRange(loc, 3)) - { - int damage; - - if (TrapLevel > 0) - { - damage = Utility.RandomMinMax(10, 30) * TrapLevel; - } - else - { - damage = TrapPower; - } - - AOS.Damage(from, damage, 0, 100, 0, 0, 0); - - // Your skin blisters from the heat! - from.LocalOverheadMessage(MessageType.Regular, 0x2A, 503000); - } - - Effects.SendLocationEffect(loc, facet, 0x36BD, 15); - Effects.PlaySound(loc, facet, 0x307); - - break; - } - case TrapType.MagicTrap: - { - if (from.InRange(loc, 1)) - { - from.Damage(TrapPower); - } - // AOS.Damage( from, m_TrapPower, 0, 100, 0, 0, 0 ); - - Effects.PlaySound(loc, Map, 0x307); - - Effects.SendLocationEffect(new Point3D(loc.X - 1, loc.Y, loc.Z), Map, 0x36BD, 15); - Effects.SendLocationEffect(new Point3D(loc.X + 1, loc.Y, loc.Z), Map, 0x36BD, 15); - - Effects.SendLocationEffect(new Point3D(loc.X, loc.Y - 1, loc.Z), Map, 0x36BD, 15); - Effects.SendLocationEffect(new Point3D(loc.X, loc.Y + 1, loc.Z), Map, 0x36BD, 15); - - Effects.SendLocationEffect(new Point3D(loc.X + 1, loc.Y + 1, loc.Z + 11), Map, 0x36BD, 15); - - break; - } - case TrapType.DartTrap: - { - SendMessageTo(from, 502999, 0x3B2); // You set off a trap! - - if (from.InRange(loc, 3)) - { - int damage; - - if (TrapLevel > 0) - { - damage = Utility.RandomMinMax(5, 15) * TrapLevel; - } - else - { - damage = TrapPower; - } - - AOS.Damage(from, damage, 100, 0, 0, 0, 0); - - // A dart imbeds itself in your flesh! - from.LocalOverheadMessage(MessageType.Regular, 0x62, 502998); - } - - Effects.PlaySound(loc, facet, 0x223); - - break; - } - case TrapType.PoisonTrap: - { - SendMessageTo(from, 502999, 0x3B2); // You set off a trap! - - if (from.InRange(loc, 3)) - { - Poison poison; - - if (TrapLevel > 0) - { - poison = Poison.GetPoison(Math.Max(0, Math.Min(4, TrapLevel - 1))); - } - else - { - AOS.Damage(from, TrapPower, 0, 0, 0, 100, 0); - poison = Poison.Greater; - } - - from.ApplyPoison(from, poison); - - // You are enveloped in a noxious green cloud! - from.LocalOverheadMessage(MessageType.Regular, 0x44, 503004); - } - - Effects.SendLocationEffect(loc, facet, 0x113A, 10, 20); - Effects.PlaySound(loc, facet, 0x231); - - break; - } - } - - TrapType = TrapType.None; - TrapPower = 0; - TrapLevel = 0; - return true; - } - - return false; - } - - public override void Open(Mobile from) - { - if (!TrapOnOpen || !ExecuteTrap(from)) - { - base.Open(from); - } - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(2); // version - - writer.Write(TrapLevel); - - writer.Write(TrapPower); - writer.Write((int)TrapType); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - switch (version) - { - case 2: - { - TrapLevel = reader.ReadInt(); - goto case 1; - } - case 1: - { - TrapPower = reader.ReadInt(); - goto case 0; - } - case 0: - { - TrapType = (TrapType)reader.ReadInt(); - break; - } - } - } + private void Deserialize(IGenericReader reader, int version) + { + _trapLevel = reader.ReadInt(); + _trapPower = reader.ReadInt(); + _trapType = (TrapType)reader.ReadInt(); } } diff --git a/Projects/UOContent/Migrations/Server.Items.Talwar.v0.json b/Projects/UOContent/Migrations/Server.Items.Talwar.v0.json deleted file mode 100644 index d69b5f76b..000000000 --- a/Projects/UOContent/Migrations/Server.Items.Talwar.v0.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "version": 0, - "type": "Server.Items.Talwar" -} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.TrappableContainer.v3.json b/Projects/UOContent/Migrations/Server.Items.TrappableContainer.v3.json new file mode 100644 index 000000000..83ddf011a --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.TrappableContainer.v3.json @@ -0,0 +1,27 @@ +{ + "version": 3, + "type": "Server.Items.TrappableContainer", + "properties": [ + { + "name": "TrapLevel", + "type": "int", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "TrapPower", + "type": "int", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "TrapType", + "type": "Server.Items.TrapType", + "rule": "EnumMigrationRule" + } + ] +} \ No newline at end of file From ba5bb13e608808201d0ee2d3ab9210a64587ec5b Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sat, 26 Mar 2022 21:23:21 -0700 Subject: [PATCH 116/213] fix: Codegens mark containers (#974) --- .../Items/Containers/MarkContainer.cs | 461 +++++++++--------- .../Server.Items.MarkContainer.v0.json | 46 ++ 2 files changed, 264 insertions(+), 243 deletions(-) create mode 100644 Projects/UOContent/Migrations/Server.Items.MarkContainer.v0.json diff --git a/Projects/UOContent/Items/Containers/MarkContainer.cs b/Projects/UOContent/Items/Containers/MarkContainer.cs index dbdd56516..1bf5baa27 100644 --- a/Projects/UOContent/Items/Containers/MarkContainer.cs +++ b/Projects/UOContent/Items/Containers/MarkContainer.cs @@ -1,256 +1,231 @@ using System; -namespace Server.Items +namespace Server.Items; + +[Serializable(0, false)] +public partial class MarkContainer : LockableContainer { - public class MarkContainer : LockableContainer + [SerializableField(0, getter: "private", setter: "private")] + private bool _rawAutoLock; + + [TimerDrift] + [SerializableField(1, getter: "private", setter: "private")] + private InternalTimer _relockTimer; + + [DeserializeTimerField(1)] + private void DeserializeRelockTimer(TimeSpan delay) { - private bool m_AutoLock; - private InternalTimer m_RelockTimer; - - [Constructible] - public MarkContainer(bool bone = false, bool locked = false) : base(bone ? 0xECA : 0xE79) + if (!Locked && _rawAutoLock) { - Movable = false; + _relockTimer = new InternalTimer(this, delay); + } + } - if (bone) + [SerializableField(2)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private Map _targetMap; + + [SerializableField(3)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private Point3D _target; + + [SerializableField(4)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private string _description; + + [Constructible] + public MarkContainer(bool bone = false, bool locked = false) : base(bone ? 0xECA : 0xE79) + { + Movable = false; + + if (bone) + { + Hue = 1102; + } + + _rawAutoLock = locked; + Locked = locked; + + if (locked) + { + LockLevel = -255; + } + } + + [CommandProperty(AccessLevel.GameMaster)] + public bool AutoLock + { + get => _rawAutoLock; + set + { + _rawAutoLock = value; + + if (!_rawAutoLock) { - Hue = 1102; + StopTimer(); } - - m_AutoLock = locked; - Locked = locked; - - if (locked) + else if (!Locked) { - LockLevel = -255; - } - } - - public MarkContainer(Serial serial) : base(serial) - { - } - - [CommandProperty(AccessLevel.GameMaster)] - public bool AutoLock - { - get => m_AutoLock; - set - { - m_AutoLock = value; - - if (!m_AutoLock) - { - StopTimer(); - } - else if (!Locked && m_RelockTimer == null) - { - m_RelockTimer = new InternalTimer(this); - } - } - } - - [CommandProperty(AccessLevel.GameMaster)] - public Map TargetMap { get; set; } - - [CommandProperty(AccessLevel.GameMaster)] - public Point3D Target { get; set; } - - [CommandProperty(AccessLevel.GameMaster)] - public bool Bone - { - get => ItemID == 0xECA; - set - { - ItemID = value ? 0xECA : 0xE79; - Hue = value ? 1102 : 0; - } - } - - [CommandProperty(AccessLevel.GameMaster)] - public string Description { get; set; } - - public override bool IsDecoContainer => false; - - [CommandProperty(AccessLevel.GameMaster)] - public override bool Locked - { - get => base.Locked; - set - { - base.Locked = value; - - if (m_AutoLock) - { - StopTimer(); - - if (!Locked) - { - m_RelockTimer = new InternalTimer(this); - } - } - } - } - - public static void Initialize() - { - CommandSystem.Register("SecretLocGen", AccessLevel.Administrator, SecretLocGen_OnCommand); - } - - [Usage("SecretLocGen"), Description("Generates mark containers to Malas secret locations.")] - public static void SecretLocGen_OnCommand(CommandEventArgs e) - { - CreateMalasPassage(951, 546, -70, 1006, 994, -70, false, false); - CreateMalasPassage(914, 192, -79, 1019, 1062, -70, false, false); - CreateMalasPassage(1614, 143, -90, 1214, 1313, -90, false, false); - CreateMalasPassage(2176, 324, -90, 1554, 172, -90, false, false); - CreateMalasPassage(864, 812, -90, 1061, 1161, -70, false, false); - CreateMalasPassage(1051, 1434, -85, 1076, 1244, -70, false, true); - CreateMalasPassage(1326, 523, -87, 1201, 1554, -70, false, false); - CreateMalasPassage(424, 189, -1, 2333, 1501, -90, true, false); - CreateMalasPassage(1313, 1115, -85, 1183, 462, -45, false, false); - - e.Mobile.SendMessage("Secret mark containers have been created."); - } - - private static bool FindMarkContainer(Point3D p, Map map) - { - var eable = map.GetItemsInRange(p, 0); - - foreach (var item in eable) - { - if (item.Z == p.Z) - { - eable.Free(); - return true; - break; - } - } - - eable.Free(); - return false; - } - - private static void CreateMalasPassage( - int x, int y, int z, int xTarget, int yTarget, int zTarget, bool bone, - bool locked - ) - { - var location = new Point3D(x, y, z); - - if (FindMarkContainer(location, Map.Malas)) - { - return; - } - - var cont = new MarkContainer(bone, locked) - { - TargetMap = Map.Malas, - Target = new Point3D(xTarget, yTarget, zTarget), - Description = "strange location" - }; - - cont.MoveToWorld(location, Map.Malas); - } - - public void StopTimer() - { - m_RelockTimer?.Stop(); - m_RelockTimer = null; - } - - public void Mark(RecallRune rune) - { - if (TargetMap != null) - { - rune.Marked = true; - rune.TargetMap = TargetMap; - rune.Target = Target; - rune.Description = Description; - rune.House = null; - } - } - - public override bool OnDragDrop(Mobile from, Item dropped) - { - if (dropped is RecallRune rune && base.OnDragDrop(from, dropped)) - { - Mark(rune); - return true; - } - - return false; - } - - public override bool OnDragDropInto(Mobile from, Item dropped, Point3D p) - { - if (dropped is RecallRune rune && base.OnDragDropInto(from, dropped, p)) - { - Mark(rune); - return true; - } - - return false; - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); // version - - writer.Write(m_AutoLock); - - if (!Locked && m_AutoLock) - { - writer.WriteDeltaTime(m_RelockTimer.RelockTime); - } - - writer.Write(TargetMap); - writer.Write(Target); - writer.Write(Description); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - m_AutoLock = reader.ReadBool(); - - if (!Locked && m_AutoLock) - { - m_RelockTimer = new InternalTimer(this, reader.ReadDeltaTime() - Core.Now); - } - - TargetMap = reader.ReadMap(); - Target = reader.ReadPoint3D(); - Description = reader.ReadString(); - } - - private class InternalTimer : Timer - { - public InternalTimer(MarkContainer container) : this(container, TimeSpan.FromMinutes(5.0)) - { - } - - public InternalTimer(MarkContainer container, TimeSpan delay) : base(delay) - { - Container = container; - RelockTime = Core.Now + delay; - - Start(); - } - - public MarkContainer Container { get; } - - public DateTime RelockTime { get; } - - protected override void OnTick() - { - Container.Locked = true; - Container.LockLevel = -255; + _relockTimer ??= new InternalTimer(this); } } } + + [CommandProperty(AccessLevel.GameMaster)] + public bool Bone + { + get => ItemID == 0xECA; + set + { + ItemID = value ? 0xECA : 0xE79; + Hue = value ? 1102 : 0; + } + } + + public override bool IsDecoContainer => false; + + [CommandProperty(AccessLevel.GameMaster)] + public override bool Locked + { + get => base.Locked; + set + { + base.Locked = value; + + if (_rawAutoLock) + { + StopTimer(); + + if (!Locked) + { + _relockTimer = new InternalTimer(this); + } + } + } + } + + [CommandProperty(AccessLevel.GameMaster)] + public DateTime NextRelock => _relockTimer.Next; + + public static void Initialize() + { + CommandSystem.Register("SecretLocGen", AccessLevel.Administrator, SecretLocGen_OnCommand); + } + + [Usage("SecretLocGen")] + [Description("Generates mark containers to Malas secret locations.")] + public static void SecretLocGen_OnCommand(CommandEventArgs e) + { + CreateMalasPassage(951, 546, -70, 1006, 994, -70, false, false); + CreateMalasPassage(914, 192, -79, 1019, 1062, -70, false, false); + CreateMalasPassage(1614, 143, -90, 1214, 1313, -90, false, false); + CreateMalasPassage(2176, 324, -90, 1554, 172, -90, false, false); + CreateMalasPassage(864, 812, -90, 1061, 1161, -70, false, false); + CreateMalasPassage(1051, 1434, -85, 1076, 1244, -70, false, true); + CreateMalasPassage(1326, 523, -87, 1201, 1554, -70, false, false); + CreateMalasPassage(424, 189, -1, 2333, 1501, -90, true, false); + CreateMalasPassage(1313, 1115, -85, 1183, 462, -45, false, false); + + e.Mobile.SendMessage("Secret mark containers have been created."); + } + + private static bool FindMarkContainer(Point3D p, Map map) + { + var eable = map.GetItemsInRange(p, 0); + + foreach (var item in eable) + { + if (item.Z == p.Z) + { + eable.Free(); + return true; + } + } + + eable.Free(); + return false; + } + + private static void CreateMalasPassage( + int x, int y, int z, int xTarget, int yTarget, int zTarget, bool bone, bool locked + ) + { + var location = new Point3D(x, y, z); + + if (FindMarkContainer(location, Map.Malas)) + { + return; + } + + var cont = new MarkContainer(bone, locked) + { + TargetMap = Map.Malas, + Target = new Point3D(xTarget, yTarget, zTarget), + Description = "strange location" + }; + + cont.MoveToWorld(location, Map.Malas); + } + + public void StopTimer() + { + _relockTimer?.Stop(); + _relockTimer = null; + } + + public void Mark(RecallRune rune) + { + if (_targetMap != null) + { + rune.Marked = true; + rune.TargetMap = _targetMap; + rune.Target = _target; + rune.Description = _description; + rune.House = null; + } + } + + public override bool OnDragDrop(Mobile from, Item dropped) + { + if (dropped is RecallRune rune && base.OnDragDrop(from, dropped)) + { + Mark(rune); + return true; + } + + return false; + } + + public override bool OnDragDropInto(Mobile from, Item dropped, Point3D p) + { + if (dropped is RecallRune rune && base.OnDragDropInto(from, dropped, p)) + { + Mark(rune); + return true; + } + + return false; + } + + private class InternalTimer : Timer + { + public InternalTimer(MarkContainer container) : this(container, TimeSpan.FromMinutes(5.0)) + { + } + + public InternalTimer(MarkContainer container, TimeSpan delay) : base(delay) + { + Container = container; + + Start(); + } + + public MarkContainer Container { get; } + + protected override void OnTick() + { + Container.Locked = true; + Container.LockLevel = -255; + } + } } diff --git a/Projects/UOContent/Migrations/Server.Items.MarkContainer.v0.json b/Projects/UOContent/Migrations/Server.Items.MarkContainer.v0.json new file mode 100644 index 000000000..489250da4 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.MarkContainer.v0.json @@ -0,0 +1,46 @@ +{ + "version": 0, + "type": "Server.Items.MarkContainer", + "properties": [ + { + "name": "RawAutoLock", + "type": "bool", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "RelockTimer", + "type": "Server.Items.MarkContainer.InternalTimer", + "rule": "TimerMigrationRule", + "ruleArguments": [ + "@TimerDrift" + ] + }, + { + "name": "TargetMap", + "type": "Server.Map", + "rule": "PrimitiveUOTypeMigrationRule", + "ruleArguments": [ + "Map" + ] + }, + { + "name": "Target", + "type": "Server.Point3D", + "rule": "PrimitiveUOTypeMigrationRule", + "ruleArguments": [ + "Point3D" + ] + }, + { + "name": "Description", + "type": "string", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + } + ] +} \ No newline at end of file From fc0594f87cf3d7e7f592e870e267ab0c5caa92cd Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sat, 26 Mar 2022 21:33:46 -0700 Subject: [PATCH 117/213] fix: Codegens TreasureMapChest (#975) --- .../Items/Containers/TreasureMapChest.cs | 900 ++++++++---------- .../Server.Items.TreasureMapChest.v2.json | 55 ++ 2 files changed, 461 insertions(+), 494 deletions(-) create mode 100644 Projects/UOContent/Migrations/Server.Items.TreasureMapChest.v2.json diff --git a/Projects/UOContent/Items/Containers/TreasureMapChest.cs b/Projects/UOContent/Items/Containers/TreasureMapChest.cs index 1bf908694..8d07ca786 100644 --- a/Projects/UOContent/Items/Containers/TreasureMapChest.cs +++ b/Projects/UOContent/Items/Containers/TreasureMapChest.cs @@ -6,594 +6,506 @@ using Server.Gumps; using Server.Network; using Server.Utilities; -namespace Server.Items +namespace Server.Items; + +[Serializable(2, false)] +public partial class TreasureMapChest : LockableContainer { - public class TreasureMapChest : LockableContainer + [SerializableField(0, setter: "private")] + private List _guardians; + + [SerializableField(1)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private bool _temporary; + + [SerializableField(2)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private Mobile _owner; + + [SerializableField(3)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private int _level; + + [TimerDrift] + [SerializableField(4)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private Timer _expireTimer; + + [DeserializeTimerField(4)] + private void DeserializeExpireTimer(TimeSpan delay) { - private List m_Lifted = new(); - - private Timer m_Timer; - - [Constructible] - public TreasureMapChest(int level) : this(null, level) + if (!_temporary) { + _expireTimer = Timer.DelayCall(delay, Delete); } + } - public TreasureMapChest(Mobile owner, int level, bool temporary = false) : base(0xE40) + [Tidy] + [SerializableField(5, setter: "private")] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private HashSet _lifted; + + [Constructible] + public TreasureMapChest(int level) : this(null, level) + { + } + + public TreasureMapChest(Mobile owner, int level, bool temporary = false) : base(0xE40) + { + _owner = owner; + _level = level; + + _temporary = temporary; + _guardians = new List(); + + _expireTimer = Timer.DelayCall(TimeSpan.FromHours(3.0), Delete); + Fill(this, level); + } + + public override int LabelNumber => 3000541; + + public static Type[] Artifacts { get; } = + { + typeof(CandelabraOfSouls), typeof(GoldBricks), typeof(PhillipsWoodenSteed), + typeof(ArcticDeathDealer), typeof(BlazeOfDeath), typeof(BurglarsBandana), + typeof(CavortingClub), typeof(DreadPirateHat), + typeof(EnchantedTitanLegBone), typeof(GwennosHarp), typeof(IolosLute), + typeof(LunaLance), typeof(NightsKiss), typeof(NoxRangersHeavyCrossbow), + typeof(PolarBearMask), typeof(VioletCourage), typeof(HeartOfTheLion), + typeof(ColdBlood), typeof(AlchemistsBauble) + }; + + [CommandProperty(AccessLevel.GameMaster)] + public DateTime DeleteTime => _expireTimer.Next; + + public override bool IsDecoContainer => false; + + private static void GetRandomAOSStats(out int attributeCount, out int min, out int max) + { + var rnd = Utility.Random(15); + + if (Core.SE) { - Owner = owner; - Level = level; - DeleteTime = Core.Now + TimeSpan.FromHours(3.0); - - Temporary = temporary; - Guardians = new List(); - - m_Timer = new DeleteTimer(this, DeleteTime); - m_Timer.Start(); - - Fill(this, level); - } - - public TreasureMapChest(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 3000541; - - public static Type[] Artifacts { get; } = - { - typeof(CandelabraOfSouls), typeof(GoldBricks), typeof(PhillipsWoodenSteed), - typeof(ArcticDeathDealer), typeof(BlazeOfDeath), typeof(BurglarsBandana), - typeof(CavortingClub), typeof(DreadPirateHat), - typeof(EnchantedTitanLegBone), typeof(GwennosHarp), typeof(IolosLute), - typeof(LunaLance), typeof(NightsKiss), typeof(NoxRangersHeavyCrossbow), - typeof(PolarBearMask), typeof(VioletCourage), typeof(HeartOfTheLion), - typeof(ColdBlood), typeof(AlchemistsBauble) - }; - - [CommandProperty(AccessLevel.GameMaster)] - public int Level { get; set; } - - [CommandProperty(AccessLevel.GameMaster)] - public Mobile Owner { get; set; } - - [CommandProperty(AccessLevel.GameMaster)] - public DateTime DeleteTime { get; private set; } - - [CommandProperty(AccessLevel.GameMaster)] - public bool Temporary { get; set; } - - public List Guardians { get; private set; } - - public override bool IsDecoContainer => false; - - private static void GetRandomAOSStats(out int attributeCount, out int min, out int max) - { - var rnd = Utility.Random(15); - - if (Core.SE) + if (rnd < 1) { - if (rnd < 1) - { - attributeCount = Utility.RandomMinMax(3, 5); - min = 50; - max = 100; - } - else if (rnd < 3) - { - attributeCount = Utility.RandomMinMax(2, 5); - min = 40; - max = 80; - } - else if (rnd < 6) - { - attributeCount = Utility.RandomMinMax(2, 4); - min = 30; - max = 60; - } - else if (rnd < 10) - { - attributeCount = Utility.RandomMinMax(1, 3); - min = 20; - max = 40; - } - else - { - attributeCount = 1; - min = 10; - max = 20; - } + attributeCount = Utility.RandomMinMax(3, 5); + min = 50; + max = 100; + } + else if (rnd < 3) + { + attributeCount = Utility.RandomMinMax(2, 5); + min = 40; + max = 80; + } + else if (rnd < 6) + { + attributeCount = Utility.RandomMinMax(2, 4); + min = 30; + max = 60; + } + else if (rnd < 10) + { + attributeCount = Utility.RandomMinMax(1, 3); + min = 20; + max = 40; } else { - if (rnd < 1) - { - attributeCount = Utility.RandomMinMax(2, 5); - min = 20; - max = 70; - } - else if (rnd < 3) - { - attributeCount = Utility.RandomMinMax(2, 4); - min = 20; - max = 50; - } - else if (rnd < 6) - { - attributeCount = Utility.RandomMinMax(2, 3); - min = 20; - max = 40; - } - else if (rnd < 10) - { - attributeCount = Utility.RandomMinMax(1, 2); - min = 10; - max = 30; - } - else - { - attributeCount = 1; - min = 10; - max = 20; - } + attributeCount = 1; + min = 10; + max = 20; } + + return; } - public static void Fill(LockableContainer cont, int level) + if (rnd < 1) { - cont.Movable = false; - cont.Locked = true; - int numberItems; + attributeCount = Utility.RandomMinMax(2, 5); + min = 20; + max = 70; + } + else if (rnd < 3) + { + attributeCount = Utility.RandomMinMax(2, 4); + min = 20; + max = 50; + } + else if (rnd < 6) + { + attributeCount = Utility.RandomMinMax(2, 3); + min = 20; + max = 40; + } + else if (rnd < 10) + { + attributeCount = Utility.RandomMinMax(1, 2); + min = 10; + max = 30; + } + else + { + attributeCount = 1; + min = 10; + max = 20; + } + } - if (level == 0) + public static void Fill(LockableContainer cont, int level) + { + cont.Movable = false; + cont.Locked = true; + + if (level == 0) + { + cont.LockLevel = 0; + + cont.DropItem(new Gold(Utility.RandomMinMax(50, 100))); + + if (Utility.RandomDouble() < 0.75) { - cont.LockLevel = 0; // Can't be unlocked - - cont.DropItem(new Gold(Utility.RandomMinMax(50, 100))); - - if (Utility.RandomDouble() < 0.75) - { - cont.DropItem(new TreasureMap(0, Map.Trammel)); - } + cont.DropItem(new TreasureMap(0, Map.Trammel)); } - else + } + else + { + cont.TrapType = TrapType.ExplosionTrap; + cont.TrapPower = level * 25; + cont.TrapLevel = level; + + cont.RequiredSkill = level switch { - cont.TrapType = TrapType.ExplosionTrap; - cont.TrapPower = level * 25; - cont.TrapLevel = level; + 1 => 36, + 2 => 76, + 3 => 84, + 4 => 92, + 5 => 100, + _ => 100 + }; - cont.RequiredSkill = level switch + cont.LockLevel = cont.RequiredSkill - 10; + cont.MaxLockLevel = cont.RequiredSkill + 40; + + // Publish 67 gold change + // if (Core.SA) + // cont.DropItem( new Gold( level * 5000 ) ); + // else + cont.DropItem(new Gold(level * 1000)); + + for (var i = 0; i < level * 5; ++i) + { + cont.DropItem(Loot.RandomScroll(0, 63, SpellbookType.Regular)); + } + + var numberItems = Core.SE ? level switch + { + 1 => 5, + 2 => 10, + 3 => 15, + 4 => 38, + 5 => 50, + 6 => 60, + _ => 0 + } : level * 6; + + for (var i = 0; i < numberItems; ++i) + { + var item = Core.AOS + ? Loot.RandomArmorOrShieldOrWeaponOrJewelry() + : Loot.RandomArmorOrShieldOrWeapon(); + + if (item is BaseWeapon weapon) { - 1 => 36, - 2 => 76, - 3 => 84, - 4 => 92, - 5 => 100, - 6 => 100, - _ => cont.RequiredSkill - }; - - cont.LockLevel = cont.RequiredSkill - 10; - cont.MaxLockLevel = cont.RequiredSkill + 40; - - // Publish 67 gold change - // if (Core.SA) - // cont.DropItem( new Gold( level * 5000 ) ); - // else - cont.DropItem(new Gold(level * 1000)); - - for (var i = 0; i < level * 5; ++i) - { - cont.DropItem(Loot.RandomScroll(0, 63, SpellbookType.Regular)); - } - - if (Core.SE) - { - numberItems = level switch - { - 1 => 5, - 2 => 10, - 3 => 15, - 4 => 38, - 5 => 50, - 6 => 60, - _ => 0 - }; - } - else - { - numberItems = level * 6; - } - - for (var i = 0; i < numberItems; ++i) - { - Item item; - if (Core.AOS) { - item = Loot.RandomArmorOrShieldOrWeaponOrJewelry(); + GetRandomAOSStats(out var attributeCount, out var min, out var max); + BaseRunicTool.ApplyAttributesTo(weapon, attributeCount, min, max); } else { - item = Loot.RandomArmorOrShieldOrWeapon(); + weapon.DamageLevel = (WeaponDamageLevel)Utility.Random(6); + weapon.AccuracyLevel = (WeaponAccuracyLevel)Utility.Random(6); + weapon.DurabilityLevel = (WeaponDurabilityLevel)Utility.Random(6); } - if (item is BaseWeapon weapon) - { - if (Core.AOS) - { - GetRandomAOSStats(out var attributeCount, out var min, out var max); - BaseRunicTool.ApplyAttributesTo(weapon, attributeCount, min, max); - } - else - { - weapon.DamageLevel = (WeaponDamageLevel)Utility.Random(6); - weapon.AccuracyLevel = (WeaponAccuracyLevel)Utility.Random(6); - weapon.DurabilityLevel = (WeaponDurabilityLevel)Utility.Random(6); - } - - cont.DropItem(weapon); - } - else if (item is BaseArmor armor) - { - if (Core.AOS) - { - GetRandomAOSStats(out var attributeCount, out var min, out var max); - BaseRunicTool.ApplyAttributesTo(armor, attributeCount, min, max); - } - else - { - armor.ProtectionLevel = (ArmorProtectionLevel)Utility.Random(6); - armor.Durability = (ArmorDurabilityLevel)Utility.Random(6); - } - - cont.DropItem(armor); - } - else if (item is BaseHat hat) - { - if (Core.AOS) - { - GetRandomAOSStats(out var attributeCount, out var min, out var max); - BaseRunicTool.ApplyAttributesTo(hat, attributeCount, min, max); - } - - cont.DropItem(hat); - } - else if (item is BaseJewel jewel) + cont.DropItem(weapon); + } + else if (item is BaseArmor armor) + { + if (Core.AOS) { GetRandomAOSStats(out var attributeCount, out var min, out var max); - BaseRunicTool.ApplyAttributesTo(jewel, attributeCount, min, max); - - cont.DropItem(jewel); + BaseRunicTool.ApplyAttributesTo(armor, attributeCount, min, max); } - } - } - - int reagents; - if (level == 0) - { - reagents = 12; - } - else - { - reagents = level * 3; - } - - for (var i = 0; i < reagents; i++) - { - var item = Loot.RandomPossibleReagent(); - item.Amount = Utility.RandomMinMax(40, 60); - cont.DropItem(item); - } - - int gems; - if (level == 0) - { - gems = 2; - } - else - { - gems = level * 3; - } - - for (var i = 0; i < gems; i++) - { - var item = Loot.RandomGem(); - cont.DropItem(item); - } - - if (level == 6 && Core.AOS) - { - cont.DropItem(Artifacts.RandomElement().CreateInstance()); - } - } - - public override bool CheckLocked(Mobile from) - { - if (!Locked) - { - return false; - } - - if (Level == 0 && from.AccessLevel < AccessLevel.GameMaster) - { - foreach (var m in Guardians) - { - if (m.Alive) + else { - from.SendLocalizedMessage( - 1046448 - ); // You must first kill the guardians before you may open this chest. - return true; + armor.ProtectionLevel = (ArmorProtectionLevel)Utility.Random(6); + armor.Durability = (ArmorDurabilityLevel)Utility.Random(6); } + + cont.DropItem(armor); } + else if (item is BaseHat hat) + { + if (Core.AOS) + { + GetRandomAOSStats(out var attributeCount, out var min, out var max); + BaseRunicTool.ApplyAttributesTo(hat, attributeCount, min, max); + } - LockPick(from); - return false; + cont.DropItem(hat); + } + else if (item is BaseJewel jewel) + { + GetRandomAOSStats(out var attributeCount, out var min, out var max); + BaseRunicTool.ApplyAttributesTo(jewel, attributeCount, min, max); + + cont.DropItem(jewel); + } } - - return base.CheckLocked(from); } - private bool CheckLoot(Mobile m, bool criminalAction) + var reagents = level == 0 ? 12 : level * 3; + + for (var i = 0; i < reagents; i++) { - if (Temporary) - { - return false; - } + var item = Loot.RandomPossibleReagent(); + item.Amount = Utility.RandomMinMax(40, 60); + cont.DropItem(item); + } - if (m.AccessLevel >= AccessLevel.GameMaster || Owner == null || m == Owner) - { - return true; - } + var gems = level == 0 ? 2 : level * 3; - if (Party.Get(Owner)?.Contains(m) == true) - { - return true; - } + for (var i = 0; i < gems; i++) + { + var item = Loot.RandomGem(); + cont.DropItem(item); + } - var map = Map; + if (level == 6 && Core.AOS) + { + cont.DropItem(Artifacts.RandomElement().CreateInstance()); + } + } - if ((map?.Rules & MapRules.HarmfulRestrictions) == 0) - { - if (criminalAction) - { - m.CriminalAction(true); - } - else - { - m.SendLocalizedMessage(1010630); // Taking someone else's treasure is a criminal offense! - } - - return true; - } - - m.SendLocalizedMessage(1010631); // You did not discover this chest! + public override bool CheckLocked(Mobile from) + { + if (!Locked) + { return false; } - public override bool CheckItemUse(Mobile from, Item item) => - CheckLoot(from, item != this) && base.CheckItemUse(from, item); - - public override bool CheckLift(Mobile from, Item item, ref LRReason reject) => - CheckLoot(from, true) && base.CheckLift(from, item, ref reject); - - public override void OnItemLifted(Mobile from, Item item) + if (_level == 0 && from.AccessLevel < AccessLevel.GameMaster) { - var notYetLifted = !m_Lifted.Contains(item); - - from.RevealingAction(); - - if (notYetLifted) + foreach (var m in _guardians) { - m_Lifted.Add(item); - - if (Utility.RandomDouble() <= 0.1) // 10% chance to spawn a new monster + if (m.Alive) { - TreasureMap.Spawn(Level, GetWorldLocation(), Map, from, false); + // You must first kill the guardians before you may open this chest. + from.SendLocalizedMessage(1046448); + return true; } } - base.OnItemLifted(from, item); + LockPick(from); + return false; } - public override bool CheckHold(Mobile m, Item item, bool message, bool checkItems, int plusItems, int plusWeight) - { - if (m.AccessLevel < AccessLevel.GameMaster) - { - m.SendLocalizedMessage(1048122, "", 0x8A5); // The chest refuses to be filled with treasure again. - return false; - } + return base.CheckLocked(from); + } - return base.CheckHold(m, item, message, checkItems, plusItems, plusWeight); + private bool CheckLoot(Mobile m, bool criminalAction) + { + if (_temporary) + { + return false; } - public override void Serialize(IGenericWriter writer) + if (m.AccessLevel >= AccessLevel.GameMaster || _owner == null || m == _owner) { - base.Serialize(writer); - - writer.Write(2); // version - - Guardians.Tidy(); - writer.Write(Guardians); - writer.Write(Temporary); - - writer.Write(Owner); - - writer.Write(Level); - writer.WriteDeltaTime(DeleteTime); - m_Lifted.Tidy(); - writer.Write(m_Lifted); + return true; } - public override void Deserialize(IGenericReader reader) + if (Party.Get(_owner)?.Contains(m) == true) { - base.Deserialize(reader); + return true; + } - var version = reader.ReadInt(); + var map = Map; - switch (version) + if ((map?.Rules & MapRules.HarmfulRestrictions) == 0) + { + if (criminalAction) { - case 2: - { - Guardians = reader.ReadEntityList(); - Temporary = reader.ReadBool(); - - goto case 1; - } - case 1: - { - Owner = reader.ReadEntity(); - - goto case 0; - } - case 0: - { - Level = reader.ReadInt(); - DeleteTime = reader.ReadDeltaTime(); - m_Lifted = reader.ReadEntityList(); - - if (version < 2) - { - Guardians = new List(); - } - - break; - } - } - - if (!Temporary) - { - m_Timer = new DeleteTimer(this, DeleteTime); - m_Timer.Start(); + m.CriminalAction(true); } else { - Delete(); + m.SendLocalizedMessage(1010630); // Taking someone else's treasure is a criminal offense! } + + return true; } - public override void OnAfterDelete() + m.SendLocalizedMessage(1010631); // You did not discover this chest! + return false; + } + + public override bool CheckItemUse(Mobile from, Item item) => + CheckLoot(from, item != this) && base.CheckItemUse(from, item); + + public override bool CheckLift(Mobile from, Item item, ref LRReason reject) => + CheckLoot(from, true) && base.CheckLift(from, item, ref reject); + + public override void OnItemLifted(Mobile from, Item item) + { + var notYetLifted = !_lifted.Contains(item); + + from.RevealingAction(); + + if (notYetLifted) { - m_Timer?.Stop(); + _lifted.Add(item); - m_Timer = null; - - base.OnAfterDelete(); - } - - public override void GetContextMenuEntries(Mobile from, List list) - { - base.GetContextMenuEntries(from, list); - - if (from.Alive) + if (Utility.RandomDouble() <= 0.1) // 10% chance to spawn a new monster { - list.Add(new RemoveEntry(from, this)); + TreasureMap.Spawn(_level, GetWorldLocation(), Map, from, false); } } - public void BeginRemove(Mobile from) - { - if (!from.Alive) - { - return; - } + base.OnItemLifted(from, item); + } - from.CloseGump(); - from.SendGump(new RemoveGump(from, this)); + public override bool CheckHold(Mobile m, Item item, bool message, bool checkItems, int plusItems, int plusWeight) + { + if (m.AccessLevel < AccessLevel.GameMaster) + { + m.SendLocalizedMessage(1048122, "", 0x8A5); // The chest refuses to be filled with treasure again. + return false; } - public void EndRemove(Mobile from) - { - if (Deleted || from != Owner || !from.InRange(GetWorldLocation(), 3)) - { - return; - } + return base.CheckHold(m, item, message, checkItems, plusItems, plusWeight); + } - from.SendLocalizedMessage(1048124, "", 0x8A5); // The old, rusted chest crumbles when you hit it. + private void Deserialize(IGenericReader reader, int version) + { + _guardians = new List(); + + _owner = reader.ReadEntity(); + _level = reader.ReadInt(); + var expireTimerNext = reader.ReadDeltaTime(); + DeserializeExpireTimer(expireTimerNext == DateTime.MinValue ? TimeSpan.MinValue : expireTimerNext - Core.Now); + _lifted = reader.ReadEntitySet(); + } + + [AfterDeserialization(false)] + private void AfterDeserialization() + { + if (_expireTimer == null) + { Delete(); } + } - private class RemoveGump : Gump + public override void OnAfterDelete() + { + _expireTimer?.Stop(); + _expireTimer = null; + base.OnAfterDelete(); + } + + public override void GetContextMenuEntries(Mobile from, List list) + { + base.GetContextMenuEntries(from, list); + + if (from.Alive) { - private readonly TreasureMapChest m_Chest; - private readonly Mobile m_From; + list.Add(new RemoveEntry(from, this)); + } + } - public RemoveGump(Mobile from, TreasureMapChest chest) : base(15, 15) - { - m_From = from; - m_Chest = chest; - - Closable = false; - Disposable = false; - - AddPage(0); - - AddBackground(30, 0, 240, 240, 2620); - - AddHtmlLocalized( - 45, - 15, - 200, - 80, - 1048125, - 0xFFFFFF - ); // When this treasure chest is removed, any items still inside of it will be lost. - AddHtmlLocalized(45, 95, 200, 60, 1048126, 0xFFFFFF); // Are you certain you're ready to remove this chest? - - AddButton(40, 153, 4005, 4007, 1); - AddHtmlLocalized(75, 155, 180, 40, 1048127, 0xFFFFFF); // Remove the Treasure Chest - - AddButton(40, 195, 4005, 4007, 2); - AddHtmlLocalized(75, 197, 180, 35, 1006045, 0xFFFFFF); // Cancel - } - - public override void OnResponse(NetState sender, RelayInfo info) - { - if (info.ButtonID == 1) - { - m_Chest.EndRemove(m_From); - } - } + public void BeginRemove(Mobile from) + { + if (!from.Alive) + { + return; } - private class RemoveEntry : ContextMenuEntry + from.CloseGump(); + from.SendGump(new RemoveGump(from, this)); + } + + public void EndRemove(Mobile from) + { + if (Deleted || from != _owner || !from.InRange(GetWorldLocation(), 3)) { - private readonly TreasureMapChest m_Chest; - private readonly Mobile m_From; - - public RemoveEntry(Mobile from, TreasureMapChest chest) : base(6149, 3) - { - m_From = from; - m_Chest = chest; - - Enabled = from == chest.Owner; - } - - public override void OnClick() - { - if (m_Chest.Deleted || m_From != m_Chest.Owner || !m_From.CheckAlive()) - { - return; - } - - m_Chest.BeginRemove(m_From); - } + return; } - private class DeleteTimer : Timer + from.SendLocalizedMessage(1048124, "", 0x8A5); // The old, rusted chest crumbles when you hit it. + Delete(); + } + + private class RemoveGump : Gump + { + private readonly TreasureMapChest _chest; + private readonly Mobile _from; + + public RemoveGump(Mobile from, TreasureMapChest chest) : base(15, 15) { - private readonly Item m_Item; + _from = from; + _chest = chest; - public DeleteTimer(Item item, DateTime time) : base(time - Core.Now) - { - m_Item = item; - } + Closable = false; + Disposable = false; - protected override void OnTick() + AddPage(0); + + AddBackground(30, 0, 240, 240, 2620); + + // When this treasure chest is removed, any items still inside of it will be lost. + AddHtmlLocalized(45, 15, 200, 80, 1048125, 0xFFFFFF); + // Are you certain you're ready to remove this chest? + AddHtmlLocalized(45, 95, 200, 60, 1048126, 0xFFFFFF); + + AddButton(40, 153, 4005, 4007, 1); + AddHtmlLocalized(75, 155, 180, 40, 1048127, 0xFFFFFF); // Remove the Treasure Chest + + AddButton(40, 195, 4005, 4007, 2); + AddHtmlLocalized(75, 197, 180, 35, 1006045, 0xFFFFFF); // Cancel + } + + public override void OnResponse(NetState sender, RelayInfo info) + { + if (info.ButtonID == 1) { - m_Item.Delete(); + _chest.EndRemove(_from); } } } + + private class RemoveEntry : ContextMenuEntry + { + private readonly TreasureMapChest _chest; + private readonly Mobile _from; + + public RemoveEntry(Mobile from, TreasureMapChest chest) : base(6149, 3) + { + _from = from; + _chest = chest; + + Enabled = from == chest._owner; + } + + public override void OnClick() + { + if (_chest.Deleted || _from != _chest._owner || !_from.CheckAlive()) + { + return; + } + + _chest.BeginRemove(_from); + } + } } diff --git a/Projects/UOContent/Migrations/Server.Items.TreasureMapChest.v2.json b/Projects/UOContent/Migrations/Server.Items.TreasureMapChest.v2.json new file mode 100644 index 000000000..9bf36d71a --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.TreasureMapChest.v2.json @@ -0,0 +1,55 @@ +{ + "version": 2, + "type": "Server.Items.TreasureMapChest", + "properties": [ + { + "name": "Guardians", + "type": "System.Collections.Generic.List\u003CServer.Mobile\u003E", + "rule": "ListMigrationRule", + "ruleArguments": [ + "", + "Server.Mobile", + "SerializableInterfaceMigrationRule" + ] + }, + { + "name": "Temporary", + "type": "bool", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "Owner", + "type": "Server.Mobile", + "rule": "SerializableInterfaceMigrationRule" + }, + { + "name": "Level", + "type": "int", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "ExpireTimer", + "type": "Server.Timer", + "rule": "TimerMigrationRule", + "ruleArguments": [ + "@TimerDrift" + ] + }, + { + "name": "Lifted", + "type": "System.Collections.Generic.HashSet\u003CServer.Item\u003E", + "rule": "HashSetMigrationRule", + "ruleArguments": [ + "@Tidy", + "Server.Item", + "SerializableInterfaceMigrationRule" + ] + } + ] +} \ No newline at end of file From 8f922c94ae171685ee410e62f3a995134024cf0f Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sat, 26 Mar 2022 21:48:18 -0700 Subject: [PATCH 118/213] fix: Codegens lockable containers and cleans up lockpickable (#976) --- .../UOContent/Engines/Khaldun/PuzzleChest.cs | 2 +- .../Items/Containers/LockableContainer.cs | 487 +++++------- .../Items/Containers/MarkContainer.cs | 4 +- .../Items/Containers/TreasureMapChest.cs | 2 +- Projects/UOContent/Items/Misc/Key.cs | 699 +++++++++--------- .../Items/Skill Items/Thief/LockPick.cs | 266 +++---- .../Server.Items.LockableContainer.v0.json | 62 ++ Projects/UOContent/Spells/Third/MagicLock.cs | 11 +- Projects/UOContent/Spells/Third/Unlock.cs | 62 +- 9 files changed, 762 insertions(+), 833 deletions(-) create mode 100644 Projects/UOContent/Migrations/Server.Items.LockableContainer.v0.json diff --git a/Projects/UOContent/Engines/Khaldun/PuzzleChest.cs b/Projects/UOContent/Engines/Khaldun/PuzzleChest.cs index 216706930..2bc0bee22 100644 --- a/Projects/UOContent/Engines/Khaldun/PuzzleChest.cs +++ b/Projects/UOContent/Engines/Khaldun/PuzzleChest.cs @@ -267,7 +267,7 @@ namespace Server.Items protected override void SetLockLevel() { - LockLevel = 0; // Can't be unlocked + LockLevel = ILockpickable.CannotPick; // Can't be unlocked } public override bool CheckLocked(Mobile from) diff --git a/Projects/UOContent/Items/Containers/LockableContainer.cs b/Projects/UOContent/Items/Containers/LockableContainer.cs index c541abaa2..2d465001f 100644 --- a/Projects/UOContent/Items/Containers/LockableContainer.cs +++ b/Projects/UOContent/Items/Containers/LockableContainer.cs @@ -2,355 +2,234 @@ using System; using Server.Engines.Craft; using Server.Network; -namespace Server.Items +namespace Server.Items; + +[Serializable(0, false)] +public abstract partial class LockableContainer : TrappableContainer, ILockable, ILockpickable, ICraftable, IShipwreckedItem { - public abstract class LockableContainer : TrappableContainer, ILockable, ILockpickable, ICraftable, IShipwreckedItem + public LockableContainer(int itemID) : base(itemID) => MaxLockLevel = 100; + + public override bool TrapOnOpen => !_trapOnLockpick; + + public override bool DisplaysContent => !_rawLocked; + + public int OnCraft( + int quality, bool makersMark, Mobile from, CraftSystem craftSystem, Type typeRes, BaseTool tool, + CraftItem craftItem, int resHue + ) { - private bool m_Locked; - - public LockableContainer(int itemID) : base(itemID) => MaxLockLevel = 100; - - public LockableContainer(Serial serial) : base(serial) + if (from.CheckSkill(SkillName.Tinkering, -5.0, 15.0)) { + from.SendLocalizedMessage(500636); // Your tinker skill was sufficient to make the item lockable. + + var key = new Key(KeyType.Copper, Key.RandomValue()); + + _keyValue = key.KeyValue; + DropItem(key); + + var tinkering = from.Skills.Tinkering.Value; + var level = (int)(tinkering * 0.8); + + _requiredSkill = Math.Min(level - 4, 95); + _maxLockLevel = Math.Min(level + 35, 95); + + // Lock level of 0 means it is not pickable, so change it to -1 + _lockLevel = level == 14 ? -1 : Math.Min(level - 14, 95); + } + else + { + from.SendLocalizedMessage(500637); // Your tinker skill was insufficient to make the item lockable. } - public override bool TrapOnOpen => !TrapOnLockpick; + return 1; + } - [CommandProperty(AccessLevel.GameMaster)] - public bool TrapOnLockpick { get; set; } + [CommandProperty(AccessLevel.GameMaster)] + public Mobile Picker { get; set; } - public override bool DisplaysContent => !m_Locked; + [SerializableField(0)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private bool _isShipwreckedItem; - public int OnCraft( - int quality, bool makersMark, Mobile from, CraftSystem craftSystem, Type typeRes, BaseTool tool, - CraftItem craftItem, int resHue - ) + [SerializableField(1)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private bool _trapOnLockpick; + + [SerializableField(2)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private int _requiredSkill; + + [SerializableField(3)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private int _maxLockLevel; + + [SerializableField(4)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private uint _keyValue; + + [SerializableField(5)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private int _lockLevel; + + [SerializableField(6, getter: "private", setter: "private")] + private bool _rawLocked; + + [CommandProperty(AccessLevel.GameMaster)] + public virtual bool Locked + { + get => _rawLocked; + set { - if (from.CheckSkill(SkillName.Tinkering, -5.0, 15.0)) + _rawLocked = value; + + if (_rawLocked) { - from.SendLocalizedMessage(500636); // Your tinker skill was sufficient to make the item lockable. - - var key = new Key(KeyType.Copper, Key.RandomValue()); - - KeyValue = key.KeyValue; - DropItem(key); - - var tinkering = from.Skills.Tinkering.Value; - var level = (int)(tinkering * 0.8); - - RequiredSkill = level - 4; - LockLevel = level - 14; - MaxLockLevel = level + 35; - - if (LockLevel == 0) - { - LockLevel = -1; - } - else if (LockLevel > 95) - { - LockLevel = 95; - } - - if (RequiredSkill > 95) - { - RequiredSkill = 95; - } - - if (MaxLockLevel > 95) - { - MaxLockLevel = 95; - } - } - else - { - from.SendLocalizedMessage(500637); // Your tinker skill was insufficient to make the item lockable. + Picker = null; } - return 1; + InvalidateProperties(); + this.MarkDirty(); + } + } + + public virtual void LockPick(Mobile from) + { + Locked = false; + Picker = from; + + if (_trapOnLockpick && ExecuteTrap(from)) + { + _trapOnLockpick = false; + } + } + + public override bool CheckContentDisplay(Mobile from) => !_rawLocked && base.CheckContentDisplay(from); + + public override bool TryDropItem(Mobile from, Item dropped, bool sendFullMessage) + { + if (from.AccessLevel < AccessLevel.GameMaster && _rawLocked) + { + from.SendLocalizedMessage(501747); // It appears to be locked. + return false; } - [CommandProperty(AccessLevel.GameMaster)] - public virtual bool Locked + return base.TryDropItem(from, dropped, sendFullMessage); + } + + public override bool OnDragDropInto(Mobile from, Item item, Point3D p) + { + if (from.AccessLevel < AccessLevel.GameMaster && _rawLocked) { - get => m_Locked; - set - { - m_Locked = value; - - if (m_Locked) - { - Picker = null; - } - - InvalidateProperties(); - } + from.SendLocalizedMessage(501747); // It appears to be locked. + return false; } - [CommandProperty(AccessLevel.GameMaster)] - public uint KeyValue { get; set; } + return base.OnDragDropInto(from, item, p); + } - [CommandProperty(AccessLevel.GameMaster)] - public Mobile Picker { get; set; } + public override bool CheckLift(Mobile from, Item item, ref LRReason reject) => + base.CheckLift(from, item, ref reject) && + (item == this || from.AccessLevel >= AccessLevel.GameMaster || !_rawLocked); - [CommandProperty(AccessLevel.GameMaster)] - public int MaxLockLevel { get; set; } - - [CommandProperty(AccessLevel.GameMaster)] - public int LockLevel { get; set; } - - [CommandProperty(AccessLevel.GameMaster)] - public int RequiredSkill { get; set; } - - public virtual void LockPick(Mobile from) + public override bool CheckItemUse(Mobile from, Item item) + { + if (!base.CheckItemUse(from, item)) { - Locked = false; - Picker = from; - - if (TrapOnLockpick && ExecuteTrap(from)) - { - TrapOnLockpick = false; - } + return false; } - [CommandProperty(AccessLevel.GameMaster)] - public bool IsShipwreckedItem { get; set; } - - public override void Serialize(IGenericWriter writer) + if (item != this && from.AccessLevel < AccessLevel.GameMaster && _rawLocked) { - base.Serialize(writer); - - writer.Write(6); // version - - writer.Write(IsShipwreckedItem); - - writer.Write(TrapOnLockpick); - - writer.Write(RequiredSkill); - - writer.Write(MaxLockLevel); - - writer.Write(KeyValue); - writer.Write(LockLevel); - writer.Write(m_Locked); + from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that. + return false; } - public override void Deserialize(IGenericReader reader) + return true; + } + + public virtual bool CheckLocked(Mobile from) + { + if (!_rawLocked) { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - switch (version) - { - case 6: - { - IsShipwreckedItem = reader.ReadBool(); - - goto case 5; - } - case 5: - { - TrapOnLockpick = reader.ReadBool(); - - goto case 4; - } - case 4: - { - RequiredSkill = reader.ReadInt(); - - goto case 3; - } - case 3: - { - MaxLockLevel = reader.ReadInt(); - - goto case 2; - } - case 2: - { - KeyValue = reader.ReadUInt(); - - goto case 1; - } - case 1: - { - LockLevel = reader.ReadInt(); - - goto case 0; - } - case 0: - { - if (version < 3) - { - MaxLockLevel = 100; - } - - if (version < 4) - { - if (MaxLockLevel - LockLevel == 40) - { - RequiredSkill = LockLevel + 6; - LockLevel = RequiredSkill - 10; - MaxLockLevel = RequiredSkill + 39; - } - else - { - RequiredSkill = LockLevel; - } - } - - m_Locked = reader.ReadBool(); - - break; - } - } + return false; } - public override bool CheckContentDisplay(Mobile from) => !m_Locked && base.CheckContentDisplay(from); + var inaccessible = from.AccessLevel < AccessLevel.GameMaster; - public override bool TryDropItem(Mobile from, Item dropped, bool sendFullMessage) + int number = inaccessible + ? 501747 // It appears to be locked. + : 502502; // That is locked, but you open it with your godly powers. + + from.NetState.SendMessageLocalized(Serial, ItemID, MessageType.Regular, 0x3B2, 3, number); + + return inaccessible; + } + + public override void OnTelekinesis(Mobile from) + { + if (CheckLocked(from)) { - if (from.AccessLevel < AccessLevel.GameMaster && m_Locked) - { - from.SendLocalizedMessage(501747); // It appears to be locked. - return false; - } - - return base.TryDropItem(from, dropped, sendFullMessage); + Effects.SendLocationParticles( + EffectItem.Create(Location, Map, EffectItem.DefaultDuration), + 0x376A, + 9, + 32, + 5022 + ); + Effects.PlaySound(Location, Map, 0x1F5); + return; } - public override bool OnDragDropInto(Mobile from, Item item, Point3D p) - { - if (from.AccessLevel < AccessLevel.GameMaster && m_Locked) - { - from.SendLocalizedMessage(501747); // It appears to be locked. - return false; - } + base.OnTelekinesis(from); + } - return base.OnDragDropInto(from, item, p); + public override void OnDoubleClickSecureTrade(Mobile from) + { + if (CheckLocked(from)) + { + return; } - public override bool CheckLift(Mobile from, Item item, ref LRReason reject) + base.OnDoubleClickSecureTrade(from); + } + + public override void Open(Mobile from) + { + if (CheckLocked(from)) { - if (!base.CheckLift(from, item, ref reject)) - { - return false; - } - - if (item != this && from.AccessLevel < AccessLevel.GameMaster && m_Locked) - { - return false; - } - - return true; + return; } - public override bool CheckItemUse(Mobile from, Item item) + base.Open(from); + } + + public override void OnSnoop(Mobile from) + { + if (CheckLocked(from)) { - if (!base.CheckItemUse(from, item)) - { - return false; - } - - if (item != this && from.AccessLevel < AccessLevel.GameMaster && m_Locked) - { - from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that. - return false; - } - - return true; + return; } - public virtual bool CheckLocked(Mobile from) + base.OnSnoop(from); + } + + public override void AddNameProperties(ObjectPropertyList list) + { + base.AddNameProperties(list); + + if (_isShipwreckedItem) { - var inaccessible = false; - - if (m_Locked) - { - int number; - - if (from.AccessLevel >= AccessLevel.GameMaster) - { - number = 502502; // That is locked, but you open it with your godly powers. - } - else - { - number = 501747; // It appears to be locked. - inaccessible = true; - } - - from.NetState.SendMessageLocalized(Serial, ItemID, MessageType.Regular, 0x3B2, 3, number); - } - - return inaccessible; + list.Add(1041645); // recovered from a shipwreck } + } - public override void OnTelekinesis(Mobile from) + public override void OnSingleClick(Mobile from) + { + base.OnSingleClick(from); + + if (_isShipwreckedItem) { - if (CheckLocked(from)) - { - Effects.SendLocationParticles( - EffectItem.Create(Location, Map, EffectItem.DefaultDuration), - 0x376A, - 9, - 32, - 5022 - ); - Effects.PlaySound(Location, Map, 0x1F5); - return; - } - - base.OnTelekinesis(from); - } - - public override void OnDoubleClickSecureTrade(Mobile from) - { - if (CheckLocked(from)) - { - return; - } - - base.OnDoubleClickSecureTrade(from); - } - - public override void Open(Mobile from) - { - if (CheckLocked(from)) - { - return; - } - - base.Open(from); - } - - public override void OnSnoop(Mobile from) - { - if (CheckLocked(from)) - { - return; - } - - base.OnSnoop(from); - } - - public override void AddNameProperties(ObjectPropertyList list) - { - base.AddNameProperties(list); - - if (IsShipwreckedItem) - { - list.Add(1041645); // recovered from a shipwreck - } - } - - public override void OnSingleClick(Mobile from) - { - base.OnSingleClick(from); - - if (IsShipwreckedItem) - { - LabelTo(from, 1041645); // recovered from a shipwreck - } + LabelTo(from, 1041645); // recovered from a shipwreck } } } diff --git a/Projects/UOContent/Items/Containers/MarkContainer.cs b/Projects/UOContent/Items/Containers/MarkContainer.cs index 1bf5baa27..5099c7e3e 100644 --- a/Projects/UOContent/Items/Containers/MarkContainer.cs +++ b/Projects/UOContent/Items/Containers/MarkContainer.cs @@ -48,7 +48,7 @@ public partial class MarkContainer : LockableContainer if (locked) { - LockLevel = -255; + LockLevel = ILockpickable.MagicLock; } } @@ -225,7 +225,7 @@ public partial class MarkContainer : LockableContainer protected override void OnTick() { Container.Locked = true; - Container.LockLevel = -255; + Container.LockLevel = ILockpickable.MagicLock; } } } diff --git a/Projects/UOContent/Items/Containers/TreasureMapChest.cs b/Projects/UOContent/Items/Containers/TreasureMapChest.cs index 8d07ca786..bbe01747f 100644 --- a/Projects/UOContent/Items/Containers/TreasureMapChest.cs +++ b/Projects/UOContent/Items/Containers/TreasureMapChest.cs @@ -159,7 +159,7 @@ public partial class TreasureMapChest : LockableContainer if (level == 0) { - cont.LockLevel = 0; + cont.LockLevel = ILockpickable.CannotPick; cont.DropItem(new Gold(Utility.RandomMinMax(50, 100))); diff --git a/Projects/UOContent/Items/Misc/Key.cs b/Projects/UOContent/Items/Misc/Key.cs index 758f8c1ad..263a9ac03 100644 --- a/Projects/UOContent/Items/Misc/Key.cs +++ b/Projects/UOContent/Items/Misc/Key.cs @@ -2,295 +2,294 @@ using Server.Network; using Server.Prompts; using Server.Targeting; -namespace Server.Items +namespace Server.Items; + +public enum KeyType { - public enum KeyType + Copper = 0x100E, + Gold = 0x100F, + Iron = 0x1010, + Rusty = 0x1013 +} + +public interface ILockable +{ + bool Locked { get; set; } + uint KeyValue { get; set; } +} + +public class Key : Item +{ + private string m_Description; + private uint m_KeyVal; + + [Constructible] + public Key(uint val = 0) : this(KeyType.Iron, val) { - Copper = 0x100E, - Gold = 0x100F, - Iron = 0x1010, - Rusty = 0x1013 } - public interface ILockable + public Key(KeyType type, uint val = 0, Item link = null) : base((int)type) { - bool Locked { get; set; } - uint KeyValue { get; set; } + Weight = 1.0; + + MaxRange = 3; + m_KeyVal = val; + Link = link; } - public class Key : Item + public Key(Serial serial) : base(serial) { - private string m_Description; - private uint m_KeyVal; + } - [Constructible] - public Key(uint val = 0) : this(KeyType.Iron, val) + [CommandProperty(AccessLevel.GameMaster)] + public string Description + { + get => m_Description; + set { + m_Description = value; + InvalidateProperties(); + } + } + + [CommandProperty(AccessLevel.GameMaster)] + public int MaxRange { get; set; } + + [CommandProperty(AccessLevel.GameMaster)] + public uint KeyValue + { + get => m_KeyVal; + + set + { + m_KeyVal = value; + InvalidateProperties(); + } + } + + [CommandProperty(AccessLevel.GameMaster)] + public Item Link { get; set; } + + public static uint RandomValue() => (uint)(0xFFFFFFFE * Utility.RandomDouble()) + 1; + + public static void RemoveKeys(Mobile m, uint keyValue) + { + if (keyValue == 0) + { + return; } - public Key(KeyType type, uint val = 0, Item link = null) : base((int)type) - { - Weight = 1.0; + RemoveKeys(m.Backpack, keyValue); + RemoveKeys(m.BankBox, keyValue); + } - MaxRange = 3; - m_KeyVal = val; - Link = link; + public static void RemoveKeys(Container cont, uint keyValue) + { + if (cont == null || keyValue == 0) + { + return; } - public Key(Serial serial) : base(serial) - { - } + var items = cont.FindItemsByType(new[] { typeof(Key), typeof(KeyRing) }); - [CommandProperty(AccessLevel.GameMaster)] - public string Description + foreach (var item in items) { - get => m_Description; - set + if (item is Key key) { - m_Description = value; - InvalidateProperties(); - } - } - - [CommandProperty(AccessLevel.GameMaster)] - public int MaxRange { get; set; } - - [CommandProperty(AccessLevel.GameMaster)] - public uint KeyValue - { - get => m_KeyVal; - - set - { - m_KeyVal = value; - InvalidateProperties(); - } - } - - [CommandProperty(AccessLevel.GameMaster)] - public Item Link { get; set; } - - public static uint RandomValue() => (uint)(0xFFFFFFFE * Utility.RandomDouble()) + 1; - - public static void RemoveKeys(Mobile m, uint keyValue) - { - if (keyValue == 0) - { - return; - } - - RemoveKeys(m.Backpack, keyValue); - RemoveKeys(m.BankBox, keyValue); - } - - public static void RemoveKeys(Container cont, uint keyValue) - { - if (cont == null || keyValue == 0) - { - return; - } - - var items = cont.FindItemsByType(new[] { typeof(Key), typeof(KeyRing) }); - - foreach (var item in items) - { - if (item is Key key) + if (key.KeyValue == keyValue) { - if (key.KeyValue == keyValue) + key.Delete(); + } + } + else + { + var keyRing = (KeyRing)item; + + keyRing.RemoveKeys(keyValue); + } + } + } + + public static bool ContainsKey(Container cont, uint keyValue) + { + if (cont == null) + { + return false; + } + + var items = cont.FindItemsByType(new[] { typeof(Key), typeof(KeyRing) }); + + foreach (var item in items) + { + if (item is Key key) + { + if (key.KeyValue == keyValue) + { + return true; + } + } + else + { + var keyRing = (KeyRing)item; + + if (keyRing.ContainsKey(keyValue)) + { + return true; + } + } + } + + return false; + } + + public override void Serialize(IGenericWriter writer) + { + base.Serialize(writer); + + writer.Write(2); // version + + writer.Write(MaxRange); + + writer.Write(Link); + + writer.Write(m_Description); + writer.Write(m_KeyVal); + } + + public override void Deserialize(IGenericReader reader) + { + base.Deserialize(reader); + + var version = reader.ReadInt(); + + switch (version) + { + case 2: + { + MaxRange = reader.ReadInt(); + + goto case 1; + } + case 1: + { + Link = reader.ReadEntity(); + + goto case 0; + } + case 0: + { + if (version < 2 || MaxRange == 0) { - key.Delete(); + MaxRange = 3; } - } - else - { - var keyRing = (KeyRing)item; - keyRing.RemoveKeys(keyValue); + m_Description = reader.ReadString(); + + m_KeyVal = reader.ReadUInt(); + + break; } - } + } + } + + public override void OnDoubleClick(Mobile from) + { + if (!IsChildOf(from.Backpack)) + { + from.SendLocalizedMessage(501661); // That key is unreachable. + return; } - public static bool ContainsKey(Container cont, uint keyValue) + Target t; + int number; + + if (m_KeyVal != 0) { - if (cont == null) + number = 501662; // What shall I use this key on? + t = new UnlockTarget(this); + } + else + { + number = 501663; // This key is a key blank. Which key would you like to make a copy of? + t = new CopyTarget(this); + } + + from.SendLocalizedMessage(number); + from.Target = t; + } + + public override void GetProperties(ObjectPropertyList list) + { + base.GetProperties(list); + + string desc; + + if (m_KeyVal == 0) + { + desc = "(blank)"; + } + else if ((desc = m_Description) == null || (desc = desc.Trim()).Length <= 0) + { + desc = null; + } + + if (desc != null) + { + list.Add(desc); + } + } + + public override void OnSingleClick(Mobile from) + { + base.OnSingleClick(from); + + string desc; + + if (m_KeyVal == 0) + { + desc = "(blank)"; + } + else + { + desc = m_Description?.Trim() ?? ""; + } + + if (desc.Length > 0) + { + from.NetState.SendMessage(Serial, ItemID, MessageType.Regular, 0x3B2, 3, false, "ENU", "", desc); + } + } + + public bool UseOn(Mobile from, ILockable o) + { + if (o.KeyValue == KeyValue) + { + if (o is BaseDoor door && !door.UseLocks()) { return false; } - var items = cont.FindItemsByType(new[] { typeof(Key), typeof(KeyRing) }); + o.Locked = !o.Locked; - foreach (var item in items) + if (o is Item item) { - if (item is Key key) + if (o.Locked) { - if (key.KeyValue == keyValue) - { - return true; - } + item.SendLocalizedMessageTo(from, 1048000); // You lock it. } else { - var keyRing = (KeyRing)item; - - if (keyRing.ContainsKey(keyValue)) - { - return true; - } - } - } - - return false; - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(2); // version - - writer.Write(MaxRange); - - writer.Write(Link); - - writer.Write(m_Description); - writer.Write(m_KeyVal); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - switch (version) - { - case 2: - { - MaxRange = reader.ReadInt(); - - goto case 1; - } - case 1: - { - Link = reader.ReadEntity(); - - goto case 0; - } - case 0: - { - if (version < 2 || MaxRange == 0) - { - MaxRange = 3; - } - - m_Description = reader.ReadString(); - - m_KeyVal = reader.ReadUInt(); - - break; - } - } - } - - public override void OnDoubleClick(Mobile from) - { - if (!IsChildOf(from.Backpack)) - { - from.SendLocalizedMessage(501661); // That key is unreachable. - return; - } - - Target t; - int number; - - if (m_KeyVal != 0) - { - number = 501662; // What shall I use this key on? - t = new UnlockTarget(this); - } - else - { - number = 501663; // This key is a key blank. Which key would you like to make a copy of? - t = new CopyTarget(this); - } - - from.SendLocalizedMessage(number); - from.Target = t; - } - - public override void GetProperties(ObjectPropertyList list) - { - base.GetProperties(list); - - string desc; - - if (m_KeyVal == 0) - { - desc = "(blank)"; - } - else if ((desc = m_Description) == null || (desc = desc.Trim()).Length <= 0) - { - desc = null; - } - - if (desc != null) - { - list.Add(desc); - } - } - - public override void OnSingleClick(Mobile from) - { - base.OnSingleClick(from); - - string desc; - - if (m_KeyVal == 0) - { - desc = "(blank)"; - } - else - { - desc = m_Description?.Trim() ?? ""; - } - - if (desc.Length > 0) - { - from.NetState.SendMessage(Serial, ItemID, MessageType.Regular, 0x3B2, 3, false, "ENU", "", desc); - } - } - - public bool UseOn(Mobile from, ILockable o) - { - if (o.KeyValue == KeyValue) - { - if (o is BaseDoor door && !door.UseLocks()) - { - return false; + item.SendLocalizedMessageTo(from, 1048001); // You unlock it. } - o.Locked = !o.Locked; - - if (o is LockableContainer cont1) + if (item is LockableContainer cont) { - if (cont1.LockLevel == -255) + if (cont.LockLevel == ILockpickable.MagicLock) { - cont1.LockLevel = cont1.RequiredSkill - 10; - } - } - - if (o is Item item) - { - if (o.Locked) - { - item.SendLocalizedMessageTo(from, 1048000); // You lock it. - } - else - { - item.SendLocalizedMessageTo(from, 1048001); // You unlock it. + cont.LockLevel = cont.RequiredSkill - 10; } - if (item is LockableContainer cont && cont.TrapType != TrapType.None && cont.TrapOnLockpick) + if (cont.TrapType != TrapType.None && cont.TrapOnLockpick) { if (o.Locked) { @@ -298,138 +297,136 @@ namespace Server.Items } else { - cont.SendLocalizedMessageTo( - from, - 501672 - ); // You disable the trap temporarily. Lock it again to re-enable it. + // You disable the trap temporarily. Lock it again to re-enable it. + cont.SendLocalizedMessageTo(from, 501672); } } } - - return true; } - return false; + return true; } - private class RenamePrompt : Prompt + return false; + } + + private class RenamePrompt : Prompt + { + private readonly Key m_Key; + + public RenamePrompt(Key key) => m_Key = key; + + public override void OnResponse(Mobile from, string text) { - private readonly Key m_Key; - - public RenamePrompt(Key key) => m_Key = key; - - public override void OnResponse(Mobile from, string text) + if (m_Key.Deleted || !m_Key.IsChildOf(from.Backpack)) { - if (m_Key.Deleted || !m_Key.IsChildOf(from.Backpack)) - { - from.SendLocalizedMessage(501661); // That key is unreachable. - return; - } - - m_Key.Description = Utility.FixHtml(text); + from.SendLocalizedMessage(501661); // That key is unreachable. + return; } + + m_Key.Description = Utility.FixHtml(text); + } + } + + private class UnlockTarget : Target + { + private readonly Key m_Key; + + public UnlockTarget(Key key) : base(key.MaxRange, false, TargetFlags.None) + { + m_Key = key; + CheckLOS = false; } - private class UnlockTarget : Target + protected override void OnTarget(Mobile from, object targeted) { - private readonly Key m_Key; - - public UnlockTarget(Key key) : base(key.MaxRange, false, TargetFlags.None) + if (m_Key.Deleted || !m_Key.IsChildOf(from.Backpack)) { - m_Key = key; - CheckLOS = false; + from.SendLocalizedMessage(501661); // That key is unreachable. + return; } - protected override void OnTarget(Mobile from, object targeted) + int number; + + if (targeted == m_Key) { - if (m_Key.Deleted || !m_Key.IsChildOf(from.Backpack)) - { - from.SendLocalizedMessage(501661); // That key is unreachable. - return; - } + number = 501665; // Enter a description for this key. - int number; - - if (targeted == m_Key) + from.Prompt = new RenamePrompt(m_Key); + } + else if (targeted is ILockable lockable) + { + if (m_Key.UseOn(from, lockable)) { - number = 501665; // Enter a description for this key. - - from.Prompt = new RenamePrompt(m_Key); - } - else if (targeted is ILockable lockable) - { - if (m_Key.UseOn(from, lockable)) - { - number = -1; - } - else - { - number = 501668; // This key doesn't seem to unlock that. - } + number = -1; } else { - number = 501666; // You can't unlock that! - } - - if (number != -1) - { - from.SendLocalizedMessage(number); + number = 501668; // This key doesn't seem to unlock that. } } - } - - private class CopyTarget : Target - { - private readonly Key m_Key; - - public CopyTarget(Key key) : base(3, false, TargetFlags.None) => m_Key = key; - - protected override void OnTarget(Mobile from, object targeted) + else { - if (m_Key.Deleted || !m_Key.IsChildOf(from.Backpack)) - { - from.SendLocalizedMessage(501661); // That key is unreachable. - return; - } - - int number; - - if (targeted is Key k) - { - if (k.m_KeyVal == 0) - { - number = 501675; // This key is also blank. - } - else if (from.CheckTargetSkill(SkillName.Tinkering, k, 0, 75.0)) - { - number = 501676; // You make a copy of the key. - - m_Key.Description = k.Description; - m_Key.KeyValue = k.KeyValue; - m_Key.Link = k.Link; - m_Key.MaxRange = k.MaxRange; - } - else if (Utility.RandomDouble() <= 0.1) // 10% chance to destroy the key - { - from.SendLocalizedMessage(501677); // You fail to make a copy of the key. - - number = 501678; // The key was destroyed in the attempt. - - m_Key.Delete(); - } - else - { - number = 501677; // You fail to make a copy of the key. - } - } - else - { - number = 501688; // Not a key. - } + number = 501666; // You can't unlock that! + } + if (number != -1) + { from.SendLocalizedMessage(number); } } } + + private class CopyTarget : Target + { + private readonly Key m_Key; + + public CopyTarget(Key key) : base(3, false, TargetFlags.None) => m_Key = key; + + protected override void OnTarget(Mobile from, object targeted) + { + if (m_Key.Deleted || !m_Key.IsChildOf(from.Backpack)) + { + from.SendLocalizedMessage(501661); // That key is unreachable. + return; + } + + int number; + + if (targeted is Key k) + { + if (k.m_KeyVal == 0) + { + number = 501675; // This key is also blank. + } + else if (from.CheckTargetSkill(SkillName.Tinkering, k, 0, 75.0)) + { + number = 501676; // You make a copy of the key. + + m_Key.Description = k.Description; + m_Key.KeyValue = k.KeyValue; + m_Key.Link = k.Link; + m_Key.MaxRange = k.MaxRange; + } + else if (Utility.RandomDouble() <= 0.1) // 10% chance to destroy the key + { + from.SendLocalizedMessage(501677); // You fail to make a copy of the key. + + number = 501678; // The key was destroyed in the attempt. + + m_Key.Delete(); + } + else + { + number = 501677; // You fail to make a copy of the key. + } + } + else + { + number = 501688; // Not a key. + } + + from.SendLocalizedMessage(number); + } + } } diff --git a/Projects/UOContent/Items/Skill Items/Thief/LockPick.cs b/Projects/UOContent/Items/Skill Items/Thief/LockPick.cs index e94194e44..0e3ae8b03 100644 --- a/Projects/UOContent/Items/Skill Items/Thief/LockPick.cs +++ b/Projects/UOContent/Items/Skill Items/Thief/LockPick.cs @@ -1,163 +1,165 @@ using System; using Server.Targeting; -namespace Server.Items -{ - public interface ILockpickable : IPoint2D - { - int LockLevel { get; set; } - bool Locked { get; set; } - Mobile Picker { get; set; } - int MaxLockLevel { get; set; } - int RequiredSkill { get; set; } +namespace Server.Items; - void LockPick(Mobile from); +public interface ILockpickable : IPoint2D +{ + const int CannotPick = 0; + const int MagicLock = -255; + + int LockLevel { get; set; } + bool Locked { get; set; } + Mobile Picker { get; set; } + int MaxLockLevel { get; set; } + int RequiredSkill { get; set; } + + void LockPick(Mobile from); +} + +[Flippable(0x14fc, 0x14fb)] +public class Lockpick : Item +{ + [Constructible] + public Lockpick(int amount = 1) : base(0x14FC) + { + Stackable = true; + Amount = amount; } - [Flippable(0x14fc, 0x14fb)] - public class Lockpick : Item + public Lockpick(Serial serial) : base(serial) { - [Constructible] - public Lockpick(int amount = 1) : base(0x14FC) + } + + public override void Serialize(IGenericWriter writer) + { + base.Serialize(writer); + + writer.Write(1); // version + } + + public override void Deserialize(IGenericReader reader) + { + base.Deserialize(reader); + + var version = reader.ReadInt(); + + if (version == 0 && Weight == 0.1) { - Stackable = true; - Amount = amount; + Weight = -1; } + } - public Lockpick(Serial serial) : base(serial) + public override void OnDoubleClick(Mobile from) + { + from.SendLocalizedMessage(502068); // What do you want to pick? + from.Target = new InternalTarget(this); + } + + private class InternalTarget : Target + { + private readonly Lockpick m_Item; + + public InternalTarget(Lockpick item) : base(1, false, TargetFlags.None) => m_Item = item; + + protected override void OnTarget(Mobile from, object targeted) { - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(1); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - if (version == 0 && Weight == 0.1) + if (m_Item.Deleted) { - Weight = -1; + return; + } + + if (targeted is ILockpickable lockpickable) + { + var item = lockpickable as Item; + from.Direction = from.GetDirectionTo(item); + + if (lockpickable.Locked) + { + from.PlaySound(0x241); + + new InternalTimer(from, lockpickable, m_Item).Start(); + } + else + { + // The door is not locked + from.SendLocalizedMessage(502069); // This does not appear to be locked + } + } + else + { + from.SendLocalizedMessage(501666); // You can't unlock that! } } - public override void OnDoubleClick(Mobile from) + private class InternalTimer : Timer { - from.SendLocalizedMessage(502068); // What do you want to pick? - from.Target = new InternalTarget(this); - } + private readonly Mobile m_From; + private readonly ILockpickable m_Item; + private readonly Lockpick m_Lockpick; - private class InternalTarget : Target - { - private readonly Lockpick m_Item; - - public InternalTarget(Lockpick item) : base(1, false, TargetFlags.None) => m_Item = item; - - protected override void OnTarget(Mobile from, object targeted) + public InternalTimer(Mobile from, ILockpickable item, Lockpick lockpick) : base(TimeSpan.FromSeconds(3.0)) { - if (m_Item.Deleted) + m_From = from; + m_Item = item; + m_Lockpick = lockpick; + } + + protected void BrokeLockPickTest() + { + // When failed, a 25% chance to break the lockpick + if (Utility.Random(4) == 0) + { + var item = (Item)m_Item; + + // You broke the lockpick. + item.SendLocalizedMessageTo(m_From, 502074); + + m_From.PlaySound(0x3A4); + m_Lockpick.Consume(); + } + } + + protected override void OnTick() + { + var item = (Item)m_Item; + + if (!m_From.InRange(item.GetWorldLocation(), 1)) { return; } - if (targeted is ILockpickable lockpickable) + if (m_Item.LockLevel is ILockpickable.CannotPick or ILockpickable.MagicLock) { - var item = lockpickable as Item; - from.Direction = from.GetDirectionTo(item); + // LockLevel of 0 means that the door can't be picklocked + // LockLevel of -255 means it's magic locked + item.SendLocalizedMessageTo(m_From, 502073); // This lock cannot be picked by normal means + return; + } - if (lockpickable.Locked) - { - from.PlaySound(0x241); + if (m_From.Skills.Lockpicking.Value < m_Item.RequiredSkill) + { + /* + // Do some training to gain skills + m_From.CheckSkill( SkillName.Lockpicking, 0, m_Item.LockLevel );*/ - new InternalTimer(from, lockpickable, m_Item).Start(); - } - else - { - // The door is not locked - from.SendLocalizedMessage(502069); // This does not appear to be locked - } + // The LockLevel is higher thant the LockPicking of the player + item.SendLocalizedMessageTo(m_From, 502072); // You don't see how that lock can be manipulated. + return; + } + + if (m_From.CheckTargetSkill(SkillName.Lockpicking, m_Item, m_Item.LockLevel, m_Item.MaxLockLevel)) + { + // Success! Pick the lock! + item.SendLocalizedMessageTo(m_From, 502076); // The lock quickly yields to your skill. + m_From.PlaySound(0x4A); + m_Item.LockPick(m_From); } else { - from.SendLocalizedMessage(501666); // You can't unlock that! - } - } - - private class InternalTimer : Timer - { - private readonly Mobile m_From; - private readonly ILockpickable m_Item; - private readonly Lockpick m_Lockpick; - - public InternalTimer(Mobile from, ILockpickable item, Lockpick lockpick) : base(TimeSpan.FromSeconds(3.0)) - { - m_From = from; - m_Item = item; - m_Lockpick = lockpick; - } - - protected void BrokeLockPickTest() - { - // When failed, a 25% chance to break the lockpick - if (Utility.Random(4) == 0) - { - var item = (Item)m_Item; - - // You broke the lockpick. - item.SendLocalizedMessageTo(m_From, 502074); - - m_From.PlaySound(0x3A4); - m_Lockpick.Consume(); - } - } - - protected override void OnTick() - { - var item = (Item)m_Item; - - if (!m_From.InRange(item.GetWorldLocation(), 1)) - { - return; - } - - if (m_Item.LockLevel is 0 or -255) - { - // LockLevel of 0 means that the door can't be picklocked - // LockLevel of -255 means it's magic locked - item.SendLocalizedMessageTo(m_From, 502073); // This lock cannot be picked by normal means - return; - } - - if (m_From.Skills.Lockpicking.Value < m_Item.RequiredSkill) - { - /* - // Do some training to gain skills - m_From.CheckSkill( SkillName.Lockpicking, 0, m_Item.LockLevel );*/ - - // The LockLevel is higher thant the LockPicking of the player - item.SendLocalizedMessageTo(m_From, 502072); // You don't see how that lock can be manipulated. - return; - } - - if (m_From.CheckTargetSkill(SkillName.Lockpicking, m_Item, m_Item.LockLevel, m_Item.MaxLockLevel)) - { - // Success! Pick the lock! - item.SendLocalizedMessageTo(m_From, 502076); // The lock quickly yields to your skill. - m_From.PlaySound(0x4A); - m_Item.LockPick(m_From); - } - else - { - // The player failed to pick the lock - BrokeLockPickTest(); - item.SendLocalizedMessageTo(m_From, 502075); // You are unable to pick the lock. - } + // The player failed to pick the lock + BrokeLockPickTest(); + item.SendLocalizedMessageTo(m_From, 502075); // You are unable to pick the lock. } } } diff --git a/Projects/UOContent/Migrations/Server.Items.LockableContainer.v0.json b/Projects/UOContent/Migrations/Server.Items.LockableContainer.v0.json new file mode 100644 index 000000000..e9d8da768 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.LockableContainer.v0.json @@ -0,0 +1,62 @@ +{ + "version": 0, + "type": "Server.Items.LockableContainer", + "properties": [ + { + "name": "IsShipwreckedItem", + "type": "bool", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "TrapOnLockpick", + "type": "bool", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "RequiredSkill", + "type": "int", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "MaxLockLevel", + "type": "int", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "KeyValue", + "type": "uint", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "LockLevel", + "type": "int", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "RawLocked", + "type": "bool", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Spells/Third/MagicLock.cs b/Projects/UOContent/Spells/Third/MagicLock.cs index c9cfef434..2f8e23c59 100644 --- a/Projects/UOContent/Spells/Third/MagicLock.cs +++ b/Projects/UOContent/Spells/Third/MagicLock.cs @@ -30,13 +30,10 @@ namespace Server.Spells.Third } else if (BaseHouse.CheckLockedDownOrSecured(cont)) { - Caster.LocalOverheadMessage( - MessageType.Regular, - 0x22, - 501761 - ); // You cannot cast this on a locked down item. + // You cannot cast this on a locked down item. + Caster.LocalOverheadMessage(MessageType.Regular, 0x22, 501761); } - else if (cont.Locked || cont.LockLevel == 0 || cont is ParagonChest) + else if (cont.Locked || cont.LockLevel == ILockpickable.CannotPick || cont is ParagonChest) { Caster.SendLocalizedMessage(501762); // Target must be an unlocked chest. } @@ -59,7 +56,7 @@ namespace Server.Spells.Third // The chest is now locked! Caster.LocalOverheadMessage(MessageType.Regular, 0x3B2, 501763); - cont.LockLevel = -255; // signal magic lock + cont.LockLevel = ILockpickable.MagicLock; // signal magic lock cont.Locked = true; } diff --git a/Projects/UOContent/Spells/Third/Unlock.cs b/Projects/UOContent/Spells/Third/Unlock.cs index a29040d06..445b23e23 100644 --- a/Projects/UOContent/Spells/Third/Unlock.cs +++ b/Projects/UOContent/Spells/Third/Unlock.cs @@ -40,52 +40,44 @@ namespace Server.Spells.Third if (p is Mobile) { - Caster.LocalOverheadMessage(MessageType.Regular, 0x3B2, 503101); // That did not need to be unlocked. + // That did not need to be unlocked. + Caster.LocalOverheadMessage(MessageType.Regular, 0x3B2, 503101); } else if (p is not LockableContainer cont) { Caster.SendLocalizedMessage(501666); // You can't unlock that! } + else if (BaseHouse.CheckSecured(cont)) + { + Caster.SendLocalizedMessage(503098); // You cannot cast this on a secure item. + } + else if (!cont.Locked) + { + // That did not need to be unlocked. + Caster.LocalOverheadMessage(MessageType.Regular, 0x3B2, 503101); + } + else if (cont.LockLevel == ILockpickable.CannotPick) + { + Caster.SendLocalizedMessage(501666); // You can't unlock that! + } else { - if (BaseHouse.CheckSecured(cont)) + var level = (int)(Caster.Skills.Magery.Value * 0.8) - 4; + + if (level >= cont.RequiredSkill && + !(cont is TreasureMapChest chest && chest.Level > 2)) { - Caster.SendLocalizedMessage(503098); // You cannot cast this on a secure item. - } - else if (!cont.Locked) - { - Caster.LocalOverheadMessage( - MessageType.Regular, - 0x3B2, - 503101 - ); // That did not need to be unlocked. - } - else if (cont.LockLevel == 0) - { - Caster.SendLocalizedMessage(501666); // You can't unlock that! + cont.Locked = false; + + if (cont.LockLevel == ILockpickable.MagicLock) + { + cont.LockLevel = cont.RequiredSkill - 10; + } } else { - var level = (int)(Caster.Skills.Magery.Value * 0.8) - 4; - - if (level >= cont.RequiredSkill && - !(cont is TreasureMapChest chest && chest.Level > 2)) - { - cont.Locked = false; - - if (cont.LockLevel == -255) - { - cont.LockLevel = cont.RequiredSkill - 10; - } - } - else - { - Caster.LocalOverheadMessage( - MessageType.Regular, - 0x3B2, - 503099 - ); // My spell does not seem to have an effect on that lock. - } + // My spell does not seem to have an effect on that lock. + Caster.LocalOverheadMessage(MessageType.Regular, 0x3B2, 503099); } } } From fa0bf86a088d2003dfeb05c3bfd7b07f55111ac8 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 27 Mar 2022 15:02:29 -0700 Subject: [PATCH 119/213] fix: Codegens furniture containers (#977) --- .../Items/Containers/FurnitureContainer.cs | 577 ++++++------------ .../Migrations/Server.Items.Armoire.v0.json | 4 + .../Server.Items.CherryArmoire.v0.json | 4 + .../Migrations/Server.Items.Drawer.v0.json | 4 + .../Server.Items.ElegantArmoire.v0.json | 4 + .../Server.Items.EmptyBookcase.v0.json | 4 + .../Server.Items.FancyArmoire.v0.json | 4 + .../Server.Items.FancyDrawer.v0.json | 4 + .../Server.Items.FullBookcase.v0.json | 4 + .../Server.Items.MapleArmoire.v0.json | 4 + .../Server.Items.RedArmoire.v0.json | 4 + .../Server.Items.ShortCabinet.v0.json | 4 + .../Server.Items.TallCabinet.v0.json | 4 + 13 files changed, 247 insertions(+), 378 deletions(-) create mode 100644 Projects/UOContent/Migrations/Server.Items.Armoire.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.CherryArmoire.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Drawer.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.ElegantArmoire.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.EmptyBookcase.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.FancyArmoire.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.FancyDrawer.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.FullBookcase.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.MapleArmoire.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.RedArmoire.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.ShortCabinet.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.TallCabinet.v0.json diff --git a/Projects/UOContent/Items/Containers/FurnitureContainer.cs b/Projects/UOContent/Items/Containers/FurnitureContainer.cs index 07dbe1597..e718faa1e 100644 --- a/Projects/UOContent/Items/Containers/FurnitureContainer.cs +++ b/Projects/UOContent/Items/Containers/FurnitureContainer.cs @@ -1,419 +1,240 @@ using System; using System.Collections.Generic; -namespace Server.Items +namespace Server.Items; + +[Furniture] +[Flippable(0x2815, 0x2816)] +[Serializable(0, false)] +public partial class TallCabinet : BaseContainer { - [Furniture] - [Flippable(0x2815, 0x2816)] - public class TallCabinet : BaseContainer + [Constructible] + public TallCabinet() : base(0x2815) => Weight = 1.0; +} + +[Furniture] +[Flippable(0x2817, 0x2818)] +[Serializable(0, false)] +public partial class ShortCabinet : BaseContainer +{ + [Constructible] + public ShortCabinet() : base(0x2817) => Weight = 1.0; +} + +[Furniture] +[Flippable(0x2857, 0x2858)] +[Serializable(0, false)] +public partial class RedArmoire : BaseContainer +{ + [Constructible] + public RedArmoire() : base(0x2857) => Weight = 1.0; +} + +[Furniture] +[Flippable(0x285D, 0x285E)] +[Serializable(0, false)] +public partial class CherryArmoire : BaseContainer +{ + [Constructible] + public CherryArmoire() : base(0x285D) => Weight = 1.0; +} + +[Furniture] +[Flippable(0x285B, 0x285C)] +[Serializable(0, false)] +public partial class MapleArmoire : BaseContainer +{ + [Constructible] + public MapleArmoire() : base(0x285B) => Weight = 1.0; +} + +[Furniture] +[Flippable(0x2859, 0x285A)] +[Serializable(0, false)] +public partial class ElegantArmoire : BaseContainer +{ + [Constructible] + public ElegantArmoire() : base(0x2859) => Weight = 1.0; +} + +[Furniture] +[Serializable(0)] +[Flippable(0x2D07, 0x2D08)] +public partial class FancyElvenArmoire : BaseContainer +{ + [Constructible] + public FancyElvenArmoire() : base(0x2D07) => Weight = 1.0; + public override int DefaultGumpID => 0x4E; + public override int DefaultDropSound => 0x42; +} + +[Furniture] +[Serializable(0)] +[Flippable(0x2D05, 0x2D06)] +public partial class SimpleElvenArmoire : BaseContainer +{ + [Constructible] + public SimpleElvenArmoire() : base(0x2D05) => Weight = 1.0; + public override int DefaultGumpID => 0x4F; + public override int DefaultDropSound => 0x42; +} + +[Furniture] +[Flippable(0xa97, 0xa99, 0xa98, 0xa9a, 0xa9b, 0xa9c)] +[Serializable(0, false)] +public partial class FullBookcase : BaseContainer +{ + [Constructible] + public FullBookcase() : base(0xA97) => Weight = 1.0; +} + +[Furniture] +[Flippable(0xa9d, 0xa9e)] +[Serializable(0, false)] +public partial class EmptyBookcase : BaseContainer +{ + [Constructible] + public EmptyBookcase() : base(0xA9D) { - [Constructible] - public TallCabinet() : base(0x2815) => Weight = 1.0; + } +} - public TallCabinet(Serial serial) : base(serial) - { - } +[Furniture] +[Flippable(0xa2c, 0xa34)] +[Serializable(0, false)] +public partial class Drawer : BaseContainer +{ + [Constructible] + public Drawer() : base(0xA2C) => Weight = 1.0; +} - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); // version - } +[Furniture] +[Flippable(0xa30, 0xa38)] +[Serializable(0, false)] +public partial class FancyDrawer : BaseContainer +{ + [Constructible] + public FancyDrawer() : base(0xA30) => Weight = 1.0; +} - public override void Deserialize(IGenericReader reader) +[Furniture] +[Flippable(0xa4f, 0xa53)] +[Serializable(0, false)] +public partial class Armoire : BaseContainer +{ + [Constructible] + public Armoire() : base(0xA4F) => Weight = 1.0; + + public override void DisplayTo(Mobile m) + { + if (DynamicFurniture.Open(this, m)) { - base.Deserialize(reader); - var version = reader.ReadInt(); + base.DisplayTo(m); } } - [Furniture] - [Flippable(0x2817, 0x2818)] - public class ShortCabinet : BaseContainer + [AfterDeserialization] + private void AfterDeserialization() { - [Constructible] - public ShortCabinet() : base(0x2817) => Weight = 1.0; + DynamicFurniture.Close(this); + } +} - public ShortCabinet(Serial serial) : base(serial) - { - } +[Furniture] +[Flippable(0xa4d, 0xa51)] +[Serializable(0, false)] +public partial class FancyArmoire : BaseContainer +{ + [Constructible] + public FancyArmoire() : base(0xA4D) => Weight = 1.0; - public override void Serialize(IGenericWriter writer) + public override void DisplayTo(Mobile m) + { + if (DynamicFurniture.Open(this, m)) { - base.Serialize(writer); - writer.Write(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); + base.DisplayTo(m); } } - [Furniture] - [Flippable(0x2857, 0x2858)] - public class RedArmoire : BaseContainer + [AfterDeserialization] + private void AfterDeserialization() { - [Constructible] - public RedArmoire() : base(0x2857) => Weight = 1.0; - - public RedArmoire(Serial serial) : base(serial) - { - } - - 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(); - } + DynamicFurniture.Close(this); } +} - [Furniture] - [Flippable(0x285D, 0x285E)] - public class CherryArmoire : BaseContainer +public static class DynamicFurniture +{ + private static readonly Dictionary _table = new(); + + public static bool Open(Container c, Mobile m) { - [Constructible] - public CherryArmoire() : base(0x285D) => Weight = 1.0; - - public CherryArmoire(Serial serial) : base(serial) + if (_table.ContainsKey(c)) { + c.SendRemovePacket(); + Close(c); + c.Delta(ItemDelta.Update); + c.ProcessDelta(); + return false; } - public override void Serialize(IGenericWriter writer) + if (c is Armoire or FancyArmoire) { - base.Serialize(writer); - writer.Write(0); // version - } + Timer t = new FurnitureTimer(c, m); + t.Start(); + _table[c] = t; - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } - } - - [Furniture] - [Flippable(0x285B, 0x285C)] - public class MapleArmoire : BaseContainer - { - [Constructible] - public MapleArmoire() : base(0x285B) => Weight = 1.0; - - public MapleArmoire(Serial serial) : base(serial) - { - } - - 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(); - } - } - - [Furniture] - [Flippable(0x2859, 0x285A)] - public class ElegantArmoire : BaseContainer - { - [Constructible] - public ElegantArmoire() : base(0x2859) => Weight = 1.0; - - public ElegantArmoire(Serial serial) : base(serial) - { - } - - 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(); - } - } - - [Furniture] - [Serializable(0)] - [Flippable(0x2D07, 0x2D08)] - public partial class FancyElvenArmoire : BaseContainer - { - [Constructible] - public FancyElvenArmoire() : base(0x2D07) => Weight = 1.0; - public override int DefaultGumpID => 0x4E; - public override int DefaultDropSound => 0x42; - } - - [Furniture] - [Serializable(0)] - [Flippable(0x2D05, 0x2D06)] - public partial class SimpleElvenArmoire : BaseContainer - { - [Constructible] - public SimpleElvenArmoire() : base(0x2D05) => Weight = 1.0; - public override int DefaultGumpID => 0x4F; - public override int DefaultDropSound => 0x42; - } - - [Furniture] - [Flippable(0xa97, 0xa99, 0xa98, 0xa9a, 0xa9b, 0xa9c)] - public class FullBookcase : BaseContainer - { - [Constructible] - public FullBookcase() : base(0xA97) => Weight = 1.0; - - public FullBookcase(Serial serial) : base(serial) - { - } - - 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(); - } - } - - [Furniture] - [Flippable(0xa9d, 0xa9e)] - public class EmptyBookcase : BaseContainer - { - [Constructible] - public EmptyBookcase() : base(0xA9D) - { - } - - public EmptyBookcase(Serial serial) : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(1); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - - if (version == 0 && Weight == 1.0) + c.ItemID = c.ItemID switch { - Weight = -1; - } + 0xA4D => 0xA4C, + 0xA4F => 0xA4E, + 0xA51 => 0xA50, + 0xA53 => 0xA52, + _ => c.ItemID + }; } + + return true; } - [Furniture] - [Flippable(0xa2c, 0xa34)] - public class Drawer : BaseContainer + public static void Close(Container c) { - [Constructible] - public Drawer() : base(0xA2C) => Weight = 1.0; - - public Drawer(Serial serial) : base(serial) + if (_table.Remove(c, out var t)) { + t.Stop(); } - public override void Serialize(IGenericWriter writer) + if (c is Armoire or FancyArmoire) { - base.Serialize(writer); - writer.Write(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } - } - - [Furniture] - [Flippable(0xa30, 0xa38)] - public class FancyDrawer : BaseContainer - { - [Constructible] - public FancyDrawer() : base(0xA30) => Weight = 1.0; - - public FancyDrawer(Serial serial) : base(serial) - { - } - - 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(); - } - } - - [Furniture] - [Flippable(0xa4f, 0xa53)] - public class Armoire : BaseContainer - { - [Constructible] - public Armoire() : base(0xA4F) => Weight = 1.0; - - public Armoire(Serial serial) : base(serial) - { - } - - public override void DisplayTo(Mobile m) - { - if (DynamicFurniture.Open(this, m)) + c.ItemID = c.ItemID switch { - base.DisplayTo(m); - } - } - - 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(); - - DynamicFurniture.Close(this); - } - } - - [Furniture] - [Flippable(0xa4d, 0xa51)] - public class FancyArmoire : BaseContainer - { - [Constructible] - public FancyArmoire() : base(0xA4D) => Weight = 1.0; - - public FancyArmoire(Serial serial) : base(serial) - { - } - - public override void DisplayTo(Mobile m) - { - if (DynamicFurniture.Open(this, m)) - { - base.DisplayTo(m); - } - } - - 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(); - - DynamicFurniture.Close(this); - } - } - - public static class DynamicFurniture - { - private static readonly Dictionary m_Table = new(); - - public static bool Open(Container c, Mobile m) - { - if (m_Table.ContainsKey(c)) - { - c.SendRemovePacket(); - Close(c); - c.Delta(ItemDelta.Update); - c.ProcessDelta(); - return false; - } - - if (c is Armoire or FancyArmoire) - { - Timer t = new FurnitureTimer(c, m); - t.Start(); - m_Table[c] = t; - - c.ItemID = c.ItemID switch - { - 0xA4D => 0xA4C, - 0xA4F => 0xA4E, - 0xA51 => 0xA50, - 0xA53 => 0xA52, - _ => c.ItemID - }; - } - - return true; - } - - public static void Close(Container c) - { - if (m_Table.Remove(c, out var t)) - { - t.Stop(); - } - - if (c is Armoire or FancyArmoire) - { - c.ItemID = c.ItemID switch - { - 0xA4C => 0xA4D, - 0xA4E => 0xA4F, - 0xA50 => 0xA51, - 0xA52 => 0xA53, - _ => c.ItemID - }; - } - } - } - - public class FurnitureTimer : Timer - { - private readonly Container m_Container; - private readonly Mobile m_Mobile; - - public FurnitureTimer(Container c, Mobile m) : base(TimeSpan.FromSeconds(0.5), TimeSpan.FromSeconds(0.5)) - { - - m_Container = c; - m_Mobile = m; - } - - protected override void OnTick() - { - if (m_Mobile.Map != m_Container.Map || !m_Mobile.InRange(m_Container.GetWorldLocation(), 3)) - { - DynamicFurniture.Close(m_Container); - } + 0xA4C => 0xA4D, + 0xA4E => 0xA4F, + 0xA50 => 0xA51, + 0xA52 => 0xA53, + _ => c.ItemID + }; + } + } +} + +public class FurnitureTimer : Timer +{ + private readonly Container _container; + private readonly Mobile _mobile; + + public FurnitureTimer(Container c, Mobile m) : base(TimeSpan.FromSeconds(0.5), TimeSpan.FromSeconds(0.5)) + { + + _container = c; + _mobile = m; + } + + protected override void OnTick() + { + if (_mobile.Map != _container.Map || !_mobile.InRange(_container.GetWorldLocation(), 3)) + { + DynamicFurniture.Close(_container); } } } diff --git a/Projects/UOContent/Migrations/Server.Items.Armoire.v0.json b/Projects/UOContent/Migrations/Server.Items.Armoire.v0.json new file mode 100644 index 000000000..e410f3ea9 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Armoire.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Armoire" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.CherryArmoire.v0.json b/Projects/UOContent/Migrations/Server.Items.CherryArmoire.v0.json new file mode 100644 index 000000000..b554f6ad5 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.CherryArmoire.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.CherryArmoire" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Drawer.v0.json b/Projects/UOContent/Migrations/Server.Items.Drawer.v0.json new file mode 100644 index 000000000..1fcf3a71f --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Drawer.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Drawer" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.ElegantArmoire.v0.json b/Projects/UOContent/Migrations/Server.Items.ElegantArmoire.v0.json new file mode 100644 index 000000000..4f2625986 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.ElegantArmoire.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.ElegantArmoire" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.EmptyBookcase.v0.json b/Projects/UOContent/Migrations/Server.Items.EmptyBookcase.v0.json new file mode 100644 index 000000000..f5e4c51b8 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.EmptyBookcase.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.EmptyBookcase" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.FancyArmoire.v0.json b/Projects/UOContent/Migrations/Server.Items.FancyArmoire.v0.json new file mode 100644 index 000000000..b69db6c19 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.FancyArmoire.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.FancyArmoire" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.FancyDrawer.v0.json b/Projects/UOContent/Migrations/Server.Items.FancyDrawer.v0.json new file mode 100644 index 000000000..40cde68fe --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.FancyDrawer.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.FancyDrawer" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.FullBookcase.v0.json b/Projects/UOContent/Migrations/Server.Items.FullBookcase.v0.json new file mode 100644 index 000000000..c3d2eb68d --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.FullBookcase.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.FullBookcase" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.MapleArmoire.v0.json b/Projects/UOContent/Migrations/Server.Items.MapleArmoire.v0.json new file mode 100644 index 000000000..2f0d3f4fa --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.MapleArmoire.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.MapleArmoire" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.RedArmoire.v0.json b/Projects/UOContent/Migrations/Server.Items.RedArmoire.v0.json new file mode 100644 index 000000000..92d088926 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.RedArmoire.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.RedArmoire" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.ShortCabinet.v0.json b/Projects/UOContent/Migrations/Server.Items.ShortCabinet.v0.json new file mode 100644 index 000000000..04937d754 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.ShortCabinet.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.ShortCabinet" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.TallCabinet.v0.json b/Projects/UOContent/Migrations/Server.Items.TallCabinet.v0.json new file mode 100644 index 000000000..3503ffa6d --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.TallCabinet.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.TallCabinet" +} \ No newline at end of file From b61968db86e6f96574807b2ef85332af1c53f166 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 27 Mar 2022 17:56:00 -0700 Subject: [PATCH 120/213] fix: Codegens artifacts (#978) --- .../BaseDecorationArtifact.cs | 95 +- .../DoomDecorationArtifacts.cs | 878 +++----- .../SEDecorationArtifacts.cs | 1817 +++++------------ .../Server.Items.BackpackArtifact.v0.json | 4 + ...erver.Items.BaseDecorationArtifact.v0.json | 4 + ...ms.BaseDecorationContainerArtifact.v0.json | 4 + .../Server.Items.Basket1Artifact.v0.json | 4 + .../Server.Items.Basket2Artifact.v0.json | 4 + .../Server.Items.Basket3NorthArtifact.v0.json | 4 + .../Server.Items.Basket3WestArtifact.v0.json | 4 + .../Server.Items.Basket4Artifact.v0.json | 4 + .../Server.Items.Basket5NorthArtifact.v0.json | 4 + .../Server.Items.Basket5WestArtifact.v0.json | 4 + .../Server.Items.Basket6Artifact.v0.json | 4 + .../Server.Items.BloodyWaterArtifact.v0.json | 4 + ...Server.Items.BooksFaceDownArtifact.v0.json | 4 + .../Server.Items.BooksNorthArtifact.v0.json | 4 + .../Server.Items.BooksWestArtifact.v0.json | 4 + .../Server.Items.BottleArtifact.v0.json | 4 + .../Server.Items.BowlArtifact.v0.json | 4 + ...rver.Items.BowlsHorizontalArtifact.v0.json | 4 + ...Server.Items.BowlsVerticalArtifact.v0.json | 4 + .../Server.Items.BrazierArtifact.v0.json | 4 + .../Server.Items.CocoonArtifact.v0.json | 4 + .../Server.Items.CupsArtifact.v0.json | 4 + .../Server.Items.DamagedBooksArtifact.v0.json | 4 + .../Server.Items.DolphinLeftArtifact.v0.json | 4 + .../Server.Items.DolphinRightArtifact.v0.json | 4 + .../Server.Items.EggCaseArtifact.v0.json | 4 + .../Server.Items.FanNorthArtifact.v0.json | 4 + .../Server.Items.FanWestArtifact.v0.json | 4 + .../Server.Items.FlowersArtifact.v0.json | 4 + ...ver.Items.GruesomeStandardArtifact.v0.json | 4 + .../Server.Items.LampPostArtifact.v0.json | 4 + .../Server.Items.LeatherTunicArtifact.v0.json | 4 + ...ver.Items.ManStatuetteEastArtifact.v0.json | 4 + ...er.Items.ManStatuetteSouthArtifact.v0.json | 4 + ...erver.Items.Painting1NorthArtifact.v0.json | 4 + ...Server.Items.Painting1WestArtifact.v0.json | 4 + ...erver.Items.Painting2NorthArtifact.v0.json | 4 + ...Server.Items.Painting2WestArtifact.v0.json | 4 + .../Server.Items.Painting3Artifact.v0.json | 4 + ...erver.Items.Painting4NorthArtifact.v0.json | 4 + ...Server.Items.Painting4WestArtifact.v0.json | 4 + ...erver.Items.Painting5NorthArtifact.v0.json | 4 + ...Server.Items.Painting5WestArtifact.v0.json | 4 + ...erver.Items.Painting6NorthArtifact.v0.json | 4 + ...Server.Items.Painting6WestArtifact.v0.json | 4 + .../Server.Items.RockArtifact.v0.json | 4 + ...erver.Items.RuinedPaintingArtifact.v0.json | 4 + .../Server.Items.SaddleArtifact.v0.json | 4 + .../Server.Items.SakeArtifact.v0.json | 4 + .../Server.Items.Sculpture1Artifact.v0.json | 4 + .../Server.Items.Sculpture2Artifact.v0.json | 4 + .../Server.Items.SkinnedDeerArtifact.v0.json | 4 + .../Server.Items.SkinnedGoatArtifact.v0.json | 4 + .../Server.Items.SkullCandleArtifact.v0.json | 4 + ...Server.Items.StretchedHideArtifact.v0.json | 4 + ...rver.Items.StuddedLeggingsArtifact.v0.json | 4 + .../Server.Items.StuddedTunicArtifact.v0.json | 4 + ...r.Items.SwordDisplay1NorthArtifact.v0.json | 4 + ...er.Items.SwordDisplay1WestArtifact.v0.json | 4 + ...r.Items.SwordDisplay2NorthArtifact.v0.json | 4 + ...er.Items.SwordDisplay2WestArtifact.v0.json | 4 + ...er.Items.SwordDisplay3EastArtifact.v0.json | 4 + ...r.Items.SwordDisplay3SouthArtifact.v0.json | 4 + ...r.Items.SwordDisplay4NorthArtifact.v0.json | 4 + ...er.Items.SwordDisplay4WestArtifact.v0.json | 4 + ...r.Items.SwordDisplay5NorthArtifact.v0.json | 4 + ...er.Items.SwordDisplay5WestArtifact.v0.json | 4 + .../Server.Items.TarotCardsArtifact.v0.json | 4 + .../Server.Items.TeapotNorthArtifact.v0.json | 4 + .../Server.Items.TeapotWestArtifact.v0.json | 4 + .../Server.Items.TowerLanternArtifact.v0.json | 4 + ...erver.Items.TripleFanNorthArtifact.v0.json | 4 + ...Server.Items.TripleFanWestArtifact.v0.json | 4 + .../Server.Items.Urn1Artifact.v0.json | 4 + .../Server.Items.Urn2Artifact.v0.json | 4 + .../Server.Items.ZenRock1Artifact.v0.json | 4 + .../Server.Items.ZenRock2Artifact.v0.json | 4 + .../Server.Items.ZenRock3Artifact.v0.json | 4 + 81 files changed, 1040 insertions(+), 2062 deletions(-) create mode 100644 Projects/UOContent/Migrations/Server.Items.BackpackArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.BaseDecorationArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.BaseDecorationContainerArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Basket1Artifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Basket2Artifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Basket3NorthArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Basket3WestArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Basket4Artifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Basket5NorthArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Basket5WestArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Basket6Artifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.BloodyWaterArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.BooksFaceDownArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.BooksNorthArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.BooksWestArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.BottleArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.BowlArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.BowlsHorizontalArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.BowlsVerticalArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.BrazierArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.CocoonArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.CupsArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.DamagedBooksArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.DolphinLeftArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.DolphinRightArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.EggCaseArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.FanNorthArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.FanWestArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.FlowersArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.GruesomeStandardArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.LampPostArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.LeatherTunicArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.ManStatuetteEastArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.ManStatuetteSouthArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Painting1NorthArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Painting1WestArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Painting2NorthArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Painting2WestArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Painting3Artifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Painting4NorthArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Painting4WestArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Painting5NorthArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Painting5WestArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Painting6NorthArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Painting6WestArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.RockArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.RuinedPaintingArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.SaddleArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.SakeArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Sculpture1Artifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Sculpture2Artifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.SkinnedDeerArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.SkinnedGoatArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.SkullCandleArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.StretchedHideArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.StuddedLeggingsArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.StuddedTunicArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.SwordDisplay1NorthArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.SwordDisplay1WestArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.SwordDisplay2NorthArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.SwordDisplay2WestArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.SwordDisplay3EastArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.SwordDisplay3SouthArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.SwordDisplay4NorthArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.SwordDisplay4WestArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.SwordDisplay5NorthArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.SwordDisplay5WestArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.TarotCardsArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.TeapotNorthArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.TeapotWestArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.TowerLanternArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.TripleFanNorthArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.TripleFanWestArtifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Urn1Artifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Urn2Artifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.ZenRock1Artifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.ZenRock2Artifact.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.ZenRock3Artifact.v0.json diff --git a/Projects/UOContent/Items/Decoration Artifacts/BaseDecorationArtifact.cs b/Projects/UOContent/Items/Decoration Artifacts/BaseDecorationArtifact.cs index 4cdc905c8..5f6843333 100644 --- a/Projects/UOContent/Items/Decoration Artifacts/BaseDecorationArtifact.cs +++ b/Projects/UOContent/Items/Decoration Artifacts/BaseDecorationArtifact.cs @@ -1,70 +1,35 @@ -namespace Server.Items +namespace Server.Items; + +[Serializable(0)] +public abstract partial class BaseDecorationArtifact : Item { - public abstract class BaseDecorationArtifact : Item + public BaseDecorationArtifact(int itemID) : base(itemID) => Weight = 10.0; + + public abstract int ArtifactRarity { get; } + + public override bool ForceShowProperties => true; + + public override void GetProperties(ObjectPropertyList list) { - public BaseDecorationArtifact(int itemID) : base(itemID) => Weight = 10.0; + base.GetProperties(list); - public BaseDecorationArtifact(Serial serial) : base(serial) - { - } - - public abstract int ArtifactRarity { get; } - - public override bool ForceShowProperties => true; - - public override void GetProperties(ObjectPropertyList list) - { - base.GetProperties(list); - - list.Add(1061078, ArtifactRarity.ToString()); // artifact rarity ~1_val~ - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } - - public abstract class BaseDecorationContainerArtifact : BaseContainer - { - public BaseDecorationContainerArtifact(int itemID) : base(itemID) => Weight = 10.0; - - public BaseDecorationContainerArtifact(Serial serial) : base(serial) - { - } - - public abstract int ArtifactRarity { get; } - - public override bool ForceShowProperties => true; - - public override void AddNameProperties(ObjectPropertyList list) - { - base.AddNameProperties(list); - - list.Add(1061078, ArtifactRarity.ToString()); // artifact rarity ~1_val~ - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } + list.Add(1061078, ArtifactRarity.ToString()); // artifact rarity ~1_val~ + } +} + +[Serializable(0)] +public abstract partial class BaseDecorationContainerArtifact : BaseContainer +{ + public BaseDecorationContainerArtifact(int itemID) : base(itemID) => Weight = 10.0; + + public abstract int ArtifactRarity { get; } + + public override bool ForceShowProperties => true; + + public override void AddNameProperties(ObjectPropertyList list) + { + base.AddNameProperties(list); + + list.Add(1061078, ArtifactRarity.ToString()); // artifact rarity ~1_val~ } } diff --git a/Projects/UOContent/Items/Decoration Artifacts/DoomDecorationArtifacts.cs b/Projects/UOContent/Items/Decoration Artifacts/DoomDecorationArtifacts.cs index b920a1c35..70af11141 100644 --- a/Projects/UOContent/Items/Decoration Artifacts/DoomDecorationArtifacts.cs +++ b/Projects/UOContent/Items/Decoration Artifacts/DoomDecorationArtifacts.cs @@ -1,640 +1,248 @@ -namespace Server.Items +namespace Server.Items; + +[Serializable(0)] +public partial class BackpackArtifact : BaseDecorationContainerArtifact { - public class BackpackArtifact : BaseDecorationContainerArtifact + [Constructible] + public BackpackArtifact() : base(0x9B2) { - [Constructible] - public BackpackArtifact() : base(0x9B2) - { - } - - public BackpackArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 5; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class BloodyWaterArtifact : BaseDecorationArtifact - { - [Constructible] - public BloodyWaterArtifact() : base(0xE23) - { - } - - public BloodyWaterArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 5; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } - - public class BooksWestArtifact : BaseDecorationArtifact - { - [Constructible] - public BooksWestArtifact() : base(0x1E25) - { - } - - public BooksWestArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 3; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } - - public class BooksNorthArtifact : BaseDecorationArtifact - { - [Constructible] - public BooksNorthArtifact() : base(0x1E24) - { - } - - public BooksNorthArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 3; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } - - public class BooksFaceDownArtifact : BaseDecorationArtifact - { - [Constructible] - public BooksFaceDownArtifact() : base(0x1E21) - { - } - - public BooksFaceDownArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 3; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } - - public class BottleArtifact : BaseDecorationArtifact - { - [Constructible] - public BottleArtifact() : base(0xE28) - { - } - - public BottleArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 1; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } - - public class BrazierArtifact : BaseDecorationArtifact - { - [Constructible] - public BrazierArtifact() : base(0xE31) => Light = LightType.Circle150; - - public BrazierArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 2; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } - - public class CocoonArtifact : BaseDecorationArtifact - { - [Constructible] - public CocoonArtifact() : base(0x10DA) - { - } - - public CocoonArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 7; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } - - public class DamagedBooksArtifact : BaseDecorationArtifact - { - [Constructible] - public DamagedBooksArtifact() : base(0xC16) - { - } - - public DamagedBooksArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 1; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } - - public class EggCaseArtifact : BaseDecorationArtifact - { - [Constructible] - public EggCaseArtifact() : base(0x10D9) - { - } - - public EggCaseArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 5; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } - - public class GruesomeStandardArtifact : BaseDecorationArtifact - { - [Constructible] - public GruesomeStandardArtifact() : base(0x428) - { - } - - public GruesomeStandardArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 5; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } - - public class LampPostArtifact : BaseDecorationArtifact - { - [Constructible] - public LampPostArtifact() : base(0xB24) => Light = LightType.Circle300; - - public LampPostArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 3; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } - - public class LeatherTunicArtifact : BaseDecorationArtifact - { - [Constructible] - public LeatherTunicArtifact() : base(0x13CA) - { - } - - public LeatherTunicArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 9; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } - - public class RockArtifact : BaseDecorationArtifact - { - [Constructible] - public RockArtifact() : base(0x1363) - { - } - - public RockArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 1; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } - - public class RuinedPaintingArtifact : BaseDecorationArtifact - { - [Constructible] - public RuinedPaintingArtifact() : base(0xC2C) - { - } - - public RuinedPaintingArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 12; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } - - public class SaddleArtifact : BaseDecorationArtifact - { - [Constructible] - public SaddleArtifact() : base(0xF38) - { - } - - public SaddleArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 9; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } - - public class SkinnedDeerArtifact : BaseDecorationArtifact - { - [Constructible] - public SkinnedDeerArtifact() : base(0x1E91) - { - } - - public SkinnedDeerArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 8; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } - - public class SkinnedGoatArtifact : BaseDecorationArtifact - { - [Constructible] - public SkinnedGoatArtifact() : base(0x1E88) - { - } - - public SkinnedGoatArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 5; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } - - public class SkullCandleArtifact : BaseDecorationArtifact - { - [Constructible] - public SkullCandleArtifact() : base(0x1858) => Light = LightType.Circle150; - - public SkullCandleArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 1; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } - - public class StretchedHideArtifact : BaseDecorationArtifact - { - [Constructible] - public StretchedHideArtifact() : base(0x106B) - { - } - - public StretchedHideArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 2; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } - - public class StuddedLeggingsArtifact : BaseDecorationArtifact - { - [Constructible] - public StuddedLeggingsArtifact() : base(0x13D8) - { - } - - public StuddedLeggingsArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 5; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } - - public class StuddedTunicArtifact : BaseDecorationArtifact - { - [Constructible] - public StuddedTunicArtifact() : base(0x13D9) - { - } - - public StuddedTunicArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 7; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } - - public class TarotCardsArtifact : BaseDecorationArtifact - { - [Constructible] - public TarotCardsArtifact() : base(0x12A5) - { - } - - public TarotCardsArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 5; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } + public override int ArtifactRarity => 5; +} + +[Serializable(0)] +public partial class BloodyWaterArtifact : BaseDecorationArtifact +{ + [Constructible] + public BloodyWaterArtifact() : base(0xE23) + { + } + + public override int ArtifactRarity => 5; +} + +[Serializable(0)] +public partial class BooksWestArtifact : BaseDecorationArtifact +{ + [Constructible] + public BooksWestArtifact() : base(0x1E25) + { + } + + public override int ArtifactRarity => 3; +} + +[Serializable(0)] +public partial class BooksNorthArtifact : BaseDecorationArtifact +{ + [Constructible] + public BooksNorthArtifact() : base(0x1E24) + { + } + + public override int ArtifactRarity => 3; +} + +[Serializable(0)] +public partial class BooksFaceDownArtifact : BaseDecorationArtifact +{ + [Constructible] + public BooksFaceDownArtifact() : base(0x1E21) + { + } + + public override int ArtifactRarity => 3; +} + +[Serializable(0)] +public partial class BottleArtifact : BaseDecorationArtifact +{ + [Constructible] + public BottleArtifact() : base(0xE28) + { + } + + public override int ArtifactRarity => 1; +} + +[Serializable(0)] +public partial class BrazierArtifact : BaseDecorationArtifact +{ + [Constructible] + public BrazierArtifact() : base(0xE31) => Light = LightType.Circle150; + + public override int ArtifactRarity => 2; +} + +[Serializable(0)] +public partial class CocoonArtifact : BaseDecorationArtifact +{ + [Constructible] + public CocoonArtifact() : base(0x10DA) + { + } + + public override int ArtifactRarity => 7; +} + +[Serializable(0)] +public partial class DamagedBooksArtifact : BaseDecorationArtifact +{ + [Constructible] + public DamagedBooksArtifact() : base(0xC16) + { + } + + public override int ArtifactRarity => 1; +} + +[Serializable(0)] +public partial class EggCaseArtifact : BaseDecorationArtifact +{ + [Constructible] + public EggCaseArtifact() : base(0x10D9) + { + } + + public override int ArtifactRarity => 5; +} + +[Serializable(0)] +public partial class GruesomeStandardArtifact : BaseDecorationArtifact +{ + [Constructible] + public GruesomeStandardArtifact() : base(0x428) + { + } + + public override int ArtifactRarity => 5; +} + +[Serializable(0)] +public partial class LampPostArtifact : BaseDecorationArtifact +{ + [Constructible] + public LampPostArtifact() : base(0xB24) => Light = LightType.Circle300; + + public override int ArtifactRarity => 3; +} + +[Serializable(0)] +public partial class LeatherTunicArtifact : BaseDecorationArtifact +{ + [Constructible] + public LeatherTunicArtifact() : base(0x13CA) + { + } + + public override int ArtifactRarity => 9; +} + +[Serializable(0)] +public partial class RockArtifact : BaseDecorationArtifact +{ + [Constructible] + public RockArtifact() : base(0x1363) + { + } + + public override int ArtifactRarity => 1; +} + +[Serializable(0)] +public partial class RuinedPaintingArtifact : BaseDecorationArtifact +{ + [Constructible] + public RuinedPaintingArtifact() : base(0xC2C) + { + } + + public override int ArtifactRarity => 12; +} + +[Serializable(0)] +public partial class SaddleArtifact : BaseDecorationArtifact +{ + [Constructible] + public SaddleArtifact() : base(0xF38) + { + } + + public override int ArtifactRarity => 9; +} + +[Serializable(0)] +public partial class SkinnedDeerArtifact : BaseDecorationArtifact +{ + [Constructible] + public SkinnedDeerArtifact() : base(0x1E91) + { + } + + public override int ArtifactRarity => 8; +} + +[Serializable(0)] +public partial class SkinnedGoatArtifact : BaseDecorationArtifact +{ + [Constructible] + public SkinnedGoatArtifact() : base(0x1E88) + { + } + + public override int ArtifactRarity => 5; +} + +[Serializable(0)] +public partial class SkullCandleArtifact : BaseDecorationArtifact +{ + [Constructible] + public SkullCandleArtifact() : base(0x1858) => Light = LightType.Circle150; + + public override int ArtifactRarity => 1; +} + +[Serializable(0)] +public partial class StretchedHideArtifact : BaseDecorationArtifact +{ + [Constructible] + public StretchedHideArtifact() : base(0x106B) + { + } + + public override int ArtifactRarity => 2; +} + +[Serializable(0)] +public partial class StuddedLeggingsArtifact : BaseDecorationArtifact +{ + [Constructible] + public StuddedLeggingsArtifact() : base(0x13D8) + { + } + + public override int ArtifactRarity => 5; +} + +[Serializable(0)] +public partial class StuddedTunicArtifact : BaseDecorationArtifact +{ + [Constructible] + public StuddedTunicArtifact() : base(0x13D9) + { + } + + public override int ArtifactRarity => 7; +} + +[Serializable(0)] +public partial class TarotCardsArtifact : BaseDecorationArtifact +{ + [Constructible] + public TarotCardsArtifact() : base(0x12A5) + { + } + + public override int ArtifactRarity => 5; } diff --git a/Projects/UOContent/Items/Decoration Artifacts/SEDecorationArtifacts.cs b/Projects/UOContent/Items/Decoration Artifacts/SEDecorationArtifacts.cs index b9a43810b..2f1ce0be6 100644 --- a/Projects/UOContent/Items/Decoration Artifacts/SEDecorationArtifacts.cs +++ b/Projects/UOContent/Items/Decoration Artifacts/SEDecorationArtifacts.cs @@ -1,1519 +1,612 @@ using Server.Network; -namespace Server.Items +namespace Server.Items; + +[Serializable(0)] +public partial class Basket1Artifact : BaseDecorationContainerArtifact { - public class Basket1Artifact : BaseDecorationContainerArtifact + [Constructible] + public Basket1Artifact() : base(0x24DD) { - [Constructible] - public Basket1Artifact() : base(0x24DD) - { - } - - public Basket1Artifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 1; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class Basket2Artifact : BaseDecorationContainerArtifact + public override int ArtifactRarity => 1; +} + +[Serializable(0)] +public partial class Basket2Artifact : BaseDecorationContainerArtifact +{ + [Constructible] + public Basket2Artifact() : base(0x24D7) { - [Constructible] - public Basket2Artifact() : base(0x24D7) - { - } - - public Basket2Artifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 1; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class Basket3WestArtifact : BaseDecorationContainerArtifact + public override int ArtifactRarity => 1; +} + +[Serializable(0)] +public partial class Basket3WestArtifact : BaseDecorationContainerArtifact +{ + [Constructible] + public Basket3WestArtifact() : base(0x24D9) { - [Constructible] - public Basket3WestArtifact() : base(0x24D9) - { - } - - public Basket3WestArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 1; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class Basket3NorthArtifact : BaseDecorationContainerArtifact + public override int ArtifactRarity => 1; +} + +[Serializable(0)] +public partial class Basket3NorthArtifact : BaseDecorationContainerArtifact +{ + [Constructible] + public Basket3NorthArtifact() : base(0x24DA) { - [Constructible] - public Basket3NorthArtifact() : base(0x24DA) - { - } - - public Basket3NorthArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 1; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class Basket4Artifact : BaseDecorationContainerArtifact + public override int ArtifactRarity => 1; +} + +[Serializable(0)] +public partial class Basket4Artifact : BaseDecorationContainerArtifact +{ + [Constructible] + public Basket4Artifact() : base(0x24D8) { - [Constructible] - public Basket4Artifact() : base(0x24D8) - { - } - - public Basket4Artifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 2; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class Basket5WestArtifact : BaseDecorationContainerArtifact + public override int ArtifactRarity => 2; +} + +[Serializable(0)] +public partial class Basket5WestArtifact : BaseDecorationContainerArtifact +{ + [Constructible] + public Basket5WestArtifact() : base(0x24DC) { - [Constructible] - public Basket5WestArtifact() : base(0x24DC) - { - } - - public Basket5WestArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 2; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class Basket5NorthArtifact : BaseDecorationContainerArtifact + public override int ArtifactRarity => 2; +} + +[Serializable(0)] +public partial class Basket5NorthArtifact : BaseDecorationContainerArtifact +{ + [Constructible] + public Basket5NorthArtifact() : base(0x24DB) { - [Constructible] - public Basket5NorthArtifact() : base(0x24DB) - { - } - - public Basket5NorthArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 2; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class Basket6Artifact : BaseDecorationContainerArtifact + public override int ArtifactRarity => 2; +} + +[Serializable(0)] +public partial class Basket6Artifact : BaseDecorationContainerArtifact +{ + [Constructible] + public Basket6Artifact() : base(0x24D5) { - [Constructible] - public Basket6Artifact() : base(0x24D5) - { - } - - public Basket6Artifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 2; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class BowlArtifact : BaseDecorationArtifact + public override int ArtifactRarity => 2; +} + +[Serializable(0)] +public partial class BowlArtifact : BaseDecorationArtifact +{ + [Constructible] + public BowlArtifact() : base(0x24DE) { - [Constructible] - public BowlArtifact() : base(0x24DE) - { - } - - public BowlArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 4; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class BowlsVerticalArtifact : BaseDecorationArtifact + public override int ArtifactRarity => 4; +} + +[Serializable(0)] +public partial class BowlsVerticalArtifact : BaseDecorationArtifact +{ + [Constructible] + public BowlsVerticalArtifact() : base(0x24DF) { - [Constructible] - public BowlsVerticalArtifact() : base(0x24DF) - { - } - - public BowlsVerticalArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 3; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class BowlsHorizontalArtifact : BaseDecorationArtifact + public override int ArtifactRarity => 3; +} + +[Serializable(0)] +public partial class BowlsHorizontalArtifact : BaseDecorationArtifact +{ + [Constructible] + public BowlsHorizontalArtifact() : base(0x24E0) { - [Constructible] - public BowlsHorizontalArtifact() : base(0x24E0) - { - } - - public BowlsHorizontalArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 4; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class CupsArtifact : BaseDecorationArtifact + public override int ArtifactRarity => 4; +} + +[Serializable(0)] +public partial class CupsArtifact : BaseDecorationArtifact +{ + [Constructible] + public CupsArtifact() : base(0x24E1) { - [Constructible] - public CupsArtifact() : base(0x24E1) - { - } - - public CupsArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 4; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class FanWestArtifact : BaseDecorationArtifact + public override int ArtifactRarity => 4; +} + +[Serializable(0)] +public partial class FanWestArtifact : BaseDecorationArtifact +{ + [Constructible] + public FanWestArtifact() : base(0x240A) { - [Constructible] - public FanWestArtifact() : base(0x240A) - { - } - - public FanWestArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 3; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class FanNorthArtifact : BaseDecorationArtifact + public override int ArtifactRarity => 3; +} + +[Serializable(0)] +public partial class FanNorthArtifact : BaseDecorationArtifact +{ + [Constructible] + public FanNorthArtifact() : base(0x2409) { - [Constructible] - public FanNorthArtifact() : base(0x2409) - { - } - - public FanNorthArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 3; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class TripleFanWestArtifact : BaseDecorationArtifact + public override int ArtifactRarity => 3; +} + +[Serializable(0)] +public partial class TripleFanWestArtifact : BaseDecorationArtifact +{ + [Constructible] + public TripleFanWestArtifact() : base(0x240C) { - [Constructible] - public TripleFanWestArtifact() : base(0x240C) - { - } - - public TripleFanWestArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 4; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class TripleFanNorthArtifact : BaseDecorationArtifact + public override int ArtifactRarity => 4; +} + +[Serializable(0)] +public partial class TripleFanNorthArtifact : BaseDecorationArtifact +{ + [Constructible] + public TripleFanNorthArtifact() : base(0x240B) { - [Constructible] - public TripleFanNorthArtifact() : base(0x240B) - { - } - - public TripleFanNorthArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 4; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class FlowersArtifact : BaseDecorationArtifact + public override int ArtifactRarity => 4; +} + +[Serializable(0)] +public partial class FlowersArtifact : BaseDecorationArtifact +{ + [Constructible] + public FlowersArtifact() : base(0x284A) { - [Constructible] - public FlowersArtifact() : base(0x284A) - { - } - - public FlowersArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 7; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class Painting1WestArtifact : BaseDecorationArtifact + public override int ArtifactRarity => 7; +} + +[Serializable(0)] +public partial class Painting1WestArtifact : BaseDecorationArtifact +{ + [Constructible] + public Painting1WestArtifact() : base(0x240E) { - [Constructible] - public Painting1WestArtifact() : base(0x240E) - { - } - - public Painting1WestArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 4; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class Painting1NorthArtifact : BaseDecorationArtifact + public override int ArtifactRarity => 4; +} + +[Serializable(0)] +public partial class Painting1NorthArtifact : BaseDecorationArtifact +{ + [Constructible] + public Painting1NorthArtifact() : base(0x240D) { - [Constructible] - public Painting1NorthArtifact() : base(0x240D) - { - } - - public Painting1NorthArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 4; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class Painting2WestArtifact : BaseDecorationArtifact + public override int ArtifactRarity => 4; +} + +[Serializable(0)] +public partial class Painting2WestArtifact : BaseDecorationArtifact +{ + [Constructible] + public Painting2WestArtifact() : base(0x2410) { - [Constructible] - public Painting2WestArtifact() : base(0x2410) - { - } - - public Painting2WestArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 4; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class Painting2NorthArtifact : BaseDecorationArtifact + public override int ArtifactRarity => 4; +} + +[Serializable(0)] +public partial class Painting2NorthArtifact : BaseDecorationArtifact +{ + [Constructible] + public Painting2NorthArtifact() : base(0x240F) { - [Constructible] - public Painting2NorthArtifact() : base(0x240F) - { - } - - public Painting2NorthArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 4; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class Painting3Artifact : BaseDecorationArtifact + public override int ArtifactRarity => 4; +} + +[Serializable(0)] +public partial class Painting3Artifact : BaseDecorationArtifact +{ + [Constructible] + public Painting3Artifact() : base(0x2411) { - [Constructible] - public Painting3Artifact() : base(0x2411) - { - } - - public Painting3Artifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 5; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class Painting4WestArtifact : BaseDecorationArtifact + public override int ArtifactRarity => 5; +} + +[Serializable(0)] +public partial class Painting4WestArtifact : BaseDecorationArtifact +{ + [Constructible] + public Painting4WestArtifact() : base(0x2412) { - [Constructible] - public Painting4WestArtifact() : base(0x2412) - { - } - - public Painting4WestArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 6; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class Painting4NorthArtifact : BaseDecorationArtifact + public override int ArtifactRarity => 6; +} + +[Serializable(0)] +public partial class Painting4NorthArtifact : BaseDecorationArtifact +{ + [Constructible] + public Painting4NorthArtifact() : base(0x2411) { - [Constructible] - public Painting4NorthArtifact() : base(0x2411) - { - } - - public Painting4NorthArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 6; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class Painting5WestArtifact : BaseDecorationArtifact + public override int ArtifactRarity => 6; +} + +[Serializable(0)] +public partial class Painting5WestArtifact : BaseDecorationArtifact +{ + [Constructible] + public Painting5WestArtifact() : base(0x2416) { - [Constructible] - public Painting5WestArtifact() : base(0x2416) - { - } - - public Painting5WestArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 8; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class Painting5NorthArtifact : BaseDecorationArtifact + public override int ArtifactRarity => 8; +} + +[Serializable(0)] +public partial class Painting5NorthArtifact : BaseDecorationArtifact +{ + [Constructible] + public Painting5NorthArtifact() : base(0x2415) { - [Constructible] - public Painting5NorthArtifact() : base(0x2415) - { - } - - public Painting5NorthArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 8; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class Painting6WestArtifact : BaseDecorationArtifact + public override int ArtifactRarity => 8; +} + +[Serializable(0)] +public partial class Painting6WestArtifact : BaseDecorationArtifact +{ + [Constructible] + public Painting6WestArtifact() : base(0x2418) { - [Constructible] - public Painting6WestArtifact() : base(0x2418) - { - } - - public Painting6WestArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 9; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class Painting6NorthArtifact : BaseDecorationArtifact + public override int ArtifactRarity => 9; +} + +[Serializable(0)] +public partial class Painting6NorthArtifact : BaseDecorationArtifact +{ + [Constructible] + public Painting6NorthArtifact() : base(0x2417) { - [Constructible] - public Painting6NorthArtifact() : base(0x2417) - { - } - - public Painting6NorthArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 9; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class SakeArtifact : BaseDecorationArtifact + public override int ArtifactRarity => 9; +} + +[Serializable(0)] +public partial class SakeArtifact : BaseDecorationArtifact +{ + [Constructible] + public SakeArtifact() : base(0x24E2) { - [Constructible] - public SakeArtifact() : base(0x24E2) - { - } - - public SakeArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 4; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class Sculpture1Artifact : BaseDecorationArtifact + public override int ArtifactRarity => 4; +} + +[Serializable(0)] +public partial class Sculpture1Artifact : BaseDecorationArtifact +{ + [Constructible] + public Sculpture1Artifact() : base(0x2419) { - [Constructible] - public Sculpture1Artifact() : base(0x2419) - { - } - - public Sculpture1Artifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 3; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class Sculpture2Artifact : BaseDecorationArtifact + public override int ArtifactRarity => 3; +} + +[Serializable(0)] +public partial class Sculpture2Artifact : BaseDecorationArtifact +{ + [Constructible] + public Sculpture2Artifact() : base(0x241B) { - [Constructible] - public Sculpture2Artifact() : base(0x241B) - { - } - - public Sculpture2Artifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 3; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class DolphinLeftArtifact : BaseDecorationArtifact + public override int ArtifactRarity => 3; +} + +[Serializable(0)] +public partial class DolphinLeftArtifact : BaseDecorationArtifact +{ + [Constructible] + public DolphinLeftArtifact() : base(0x2846) { - [Constructible] - public DolphinLeftArtifact() : base(0x2846) - { - } - - public DolphinLeftArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 8; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class DolphinRightArtifact : BaseDecorationArtifact + public override int ArtifactRarity => 8; +} + +[Serializable(0)] +public partial class DolphinRightArtifact : BaseDecorationArtifact +{ + [Constructible] + public DolphinRightArtifact() : base(0x2847) { - [Constructible] - public DolphinRightArtifact() : base(0x2847) - { - } - - public DolphinRightArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 8; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class ManStatuetteSouthArtifact : BaseDecorationArtifact + public override int ArtifactRarity => 8; +} + +[Serializable(0)] +public partial class ManStatuetteSouthArtifact : BaseDecorationArtifact +{ + [Constructible] + public ManStatuetteSouthArtifact() : base(0x2848) { - [Constructible] - public ManStatuetteSouthArtifact() : base(0x2848) - { - } - - public ManStatuetteSouthArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 9; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class ManStatuetteEastArtifact : BaseDecorationArtifact + public override int ArtifactRarity => 9; +} + +[Serializable(0)] +public partial class ManStatuetteEastArtifact : BaseDecorationArtifact +{ + [Constructible] + public ManStatuetteEastArtifact() : base(0x2849) { - [Constructible] - public ManStatuetteEastArtifact() : base(0x2849) - { - } - - public ManStatuetteEastArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 9; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class SwordDisplay1WestArtifact : BaseDecorationArtifact + public override int ArtifactRarity => 9; +} + +[Serializable(0)] +public partial class SwordDisplay1WestArtifact : BaseDecorationArtifact +{ + [Constructible] + public SwordDisplay1WestArtifact() : base(0x2842) { - [Constructible] - public SwordDisplay1WestArtifact() : base(0x2842) - { - } - - public SwordDisplay1WestArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 5; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class SwordDisplay1NorthArtifact : BaseDecorationArtifact + public override int ArtifactRarity => 5; +} + +[Serializable(0)] +public partial class SwordDisplay1NorthArtifact : BaseDecorationArtifact +{ + [Constructible] + public SwordDisplay1NorthArtifact() : base(0x2843) { - [Constructible] - public SwordDisplay1NorthArtifact() : base(0x2843) - { - } - - public SwordDisplay1NorthArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 5; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class SwordDisplay2WestArtifact : BaseDecorationArtifact + public override int ArtifactRarity => 5; +} + +[Serializable(0)] +public partial class SwordDisplay2WestArtifact : BaseDecorationArtifact +{ + [Constructible] + public SwordDisplay2WestArtifact() : base(0x2844) { - [Constructible] - public SwordDisplay2WestArtifact() : base(0x2844) - { - } - - public SwordDisplay2WestArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 6; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class SwordDisplay2NorthArtifact : BaseDecorationArtifact + public override int ArtifactRarity => 6; +} + +[Serializable(0)] +public partial class SwordDisplay2NorthArtifact : BaseDecorationArtifact +{ + [Constructible] + public SwordDisplay2NorthArtifact() : base(0x2845) { - [Constructible] - public SwordDisplay2NorthArtifact() : base(0x2845) - { - } - - public SwordDisplay2NorthArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 6; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class SwordDisplay3SouthArtifact : BaseDecorationArtifact + public override int ArtifactRarity => 6; +} + +[Serializable(0)] +public partial class SwordDisplay3SouthArtifact : BaseDecorationArtifact +{ + [Constructible] + public SwordDisplay3SouthArtifact() : base(0x2855) { - [Constructible] - public SwordDisplay3SouthArtifact() : base(0x2855) - { - } - - public SwordDisplay3SouthArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 8; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class SwordDisplay3EastArtifact : BaseDecorationArtifact + public override int ArtifactRarity => 8; +} + +[Serializable(0)] +public partial class SwordDisplay3EastArtifact : BaseDecorationArtifact +{ + [Constructible] + public SwordDisplay3EastArtifact() : base(0x2856) { - [Constructible] - public SwordDisplay3EastArtifact() : base(0x2856) - { - } - - public SwordDisplay3EastArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 8; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class SwordDisplay4WestArtifact : BaseDecorationArtifact + public override int ArtifactRarity => 8; +} + +[Serializable(0)] +public partial class SwordDisplay4WestArtifact : BaseDecorationArtifact +{ + [Constructible] + public SwordDisplay4WestArtifact() : base(0x2853) { - [Constructible] - public SwordDisplay4WestArtifact() : base(0x2853) - { - } - - public SwordDisplay4WestArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 8; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class SwordDisplay4NorthArtifact : BaseDecorationArtifact + public override int ArtifactRarity => 8; +} + +[Serializable(0)] +public partial class SwordDisplay4NorthArtifact : BaseDecorationArtifact +{ + [Constructible] + public SwordDisplay4NorthArtifact() : base(0x2854) { - [Constructible] - public SwordDisplay4NorthArtifact() : base(0x2854) - { - } - - public SwordDisplay4NorthArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 9; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class SwordDisplay5WestArtifact : BaseDecorationArtifact + public override int ArtifactRarity => 9; +} + +[Serializable(0)] +public partial class SwordDisplay5WestArtifact : BaseDecorationArtifact +{ + [Constructible] + public SwordDisplay5WestArtifact() : base(0x2851) { - [Constructible] - public SwordDisplay5WestArtifact() : base(0x2851) - { - } - - public SwordDisplay5WestArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 9; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class SwordDisplay5NorthArtifact : BaseDecorationArtifact + public override int ArtifactRarity => 9; +} + +[Serializable(0)] +public partial class SwordDisplay5NorthArtifact : BaseDecorationArtifact +{ + [Constructible] + public SwordDisplay5NorthArtifact() : base(0x2852) { - [Constructible] - public SwordDisplay5NorthArtifact() : base(0x2852) - { - } - - public SwordDisplay5NorthArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 9; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class TeapotWestArtifact : BaseDecorationArtifact + public override int ArtifactRarity => 9; +} + +[Serializable(0)] +public partial class TeapotWestArtifact : BaseDecorationArtifact +{ + [Constructible] + public TeapotWestArtifact() : base(0x24E7) { - [Constructible] - public TeapotWestArtifact() : base(0x24E7) - { - } - - public TeapotWestArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 3; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class TeapotNorthArtifact : BaseDecorationArtifact + public override int ArtifactRarity => 3; +} + +[Serializable(0)] +public partial class TeapotNorthArtifact : BaseDecorationArtifact +{ + [Constructible] + public TeapotNorthArtifact() : base(0x24E6) { - [Constructible] - public TeapotNorthArtifact() : base(0x24E6) - { - } - - public TeapotNorthArtifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 3; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class TowerLanternArtifact : BaseDecorationArtifact + public override int ArtifactRarity => 3; +} + +[Serializable(0)] +public partial class TowerLanternArtifact : BaseDecorationArtifact +{ + [Constructible] + public TowerLanternArtifact() : base(0x24C0) => Light = LightType.Circle225; + + public override int ArtifactRarity => 3; + + [CommandProperty(AccessLevel.GameMaster)] + public bool IsOn { - [Constructible] - public TowerLanternArtifact() : base(0x24C0) => Light = LightType.Circle225; + get => ItemID == 0x24BF; + set => ItemID = value ? 0x24BF : 0x24C0; + } - public TowerLanternArtifact(Serial serial) : base(serial) + public override void OnDoubleClick(Mobile from) + { + if (from.InRange(GetWorldLocation(), 2)) { - } - - public override int ArtifactRarity => 3; - - [CommandProperty(AccessLevel.GameMaster)] - public bool IsOn - { - get => ItemID == 0x24BF; - set => ItemID = value ? 0x24BF : 0x24C0; - } - - public override void OnDoubleClick(Mobile from) - { - if (from.InRange(GetWorldLocation(), 2)) + if (IsOn) { - if (IsOn) - { - IsOn = false; - from.PlaySound(0x3BE); - } - else - { - IsOn = true; - from.PlaySound(0x47); - } + IsOn = false; + from.PlaySound(0x3BE); } else { - from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that. + IsOn = true; + from.PlaySound(0x47); } } - - public override void Serialize(IGenericWriter writer) + else { - base.Serialize(writer); - - writer.WriteEncodedInt(1); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - - if (version == 0) - { - Light = LightType.Circle225; - } - } - } - - public class Urn1Artifact : BaseDecorationArtifact - { - [Constructible] - public Urn1Artifact() : base(0x241D) - { - } - - public Urn1Artifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 3; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } - - public class Urn2Artifact : BaseDecorationArtifact - { - [Constructible] - public Urn2Artifact() : base(0x241E) - { - } - - public Urn2Artifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 3; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } - - public class ZenRock1Artifact : BaseDecorationArtifact - { - [Constructible] - public ZenRock1Artifact() : base(0x24E4) - { - } - - public ZenRock1Artifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 2; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } - - public class ZenRock2Artifact : BaseDecorationArtifact - { - [Constructible] - public ZenRock2Artifact() : base(0x24E3) - { - } - - public ZenRock2Artifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 3; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } - - public class ZenRock3Artifact : BaseDecorationArtifact - { - [Constructible] - public ZenRock3Artifact() : base(0x24E5) - { - } - - public ZenRock3Artifact(Serial serial) : base(serial) - { - } - - public override int ArtifactRarity => 3; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); + from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that. } } } + +[Serializable(0)] +public partial class Urn1Artifact : BaseDecorationArtifact +{ + [Constructible] + public Urn1Artifact() : base(0x241D) + { + } + + public override int ArtifactRarity => 3; +} + +[Serializable(0)] +public partial class Urn2Artifact : BaseDecorationArtifact +{ + [Constructible] + public Urn2Artifact() : base(0x241E) + { + } + + public override int ArtifactRarity => 3; +} + +[Serializable(0)] +public partial class ZenRock1Artifact : BaseDecorationArtifact +{ + [Constructible] + public ZenRock1Artifact() : base(0x24E4) + { + } + + public override int ArtifactRarity => 2; +} + +[Serializable(0)] +public partial class ZenRock2Artifact : BaseDecorationArtifact +{ + [Constructible] + public ZenRock2Artifact() : base(0x24E3) + { + } + + public override int ArtifactRarity => 3; +} + +[Serializable(0)] +public partial class ZenRock3Artifact : BaseDecorationArtifact +{ + [Constructible] + public ZenRock3Artifact() : base(0x24E5) + { + } + + public override int ArtifactRarity => 3; +} diff --git a/Projects/UOContent/Migrations/Server.Items.BackpackArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.BackpackArtifact.v0.json new file mode 100644 index 000000000..271e12223 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.BackpackArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.BackpackArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.BaseDecorationArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.BaseDecorationArtifact.v0.json new file mode 100644 index 000000000..3bd499052 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.BaseDecorationArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.BaseDecorationArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.BaseDecorationContainerArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.BaseDecorationContainerArtifact.v0.json new file mode 100644 index 000000000..9718a93a0 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.BaseDecorationContainerArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.BaseDecorationContainerArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Basket1Artifact.v0.json b/Projects/UOContent/Migrations/Server.Items.Basket1Artifact.v0.json new file mode 100644 index 000000000..c614628cb --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Basket1Artifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Basket1Artifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Basket2Artifact.v0.json b/Projects/UOContent/Migrations/Server.Items.Basket2Artifact.v0.json new file mode 100644 index 000000000..1a73e0f16 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Basket2Artifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Basket2Artifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Basket3NorthArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.Basket3NorthArtifact.v0.json new file mode 100644 index 000000000..6175f23bf --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Basket3NorthArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Basket3NorthArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Basket3WestArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.Basket3WestArtifact.v0.json new file mode 100644 index 000000000..052ec8b0b --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Basket3WestArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Basket3WestArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Basket4Artifact.v0.json b/Projects/UOContent/Migrations/Server.Items.Basket4Artifact.v0.json new file mode 100644 index 000000000..0d9d1f04f --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Basket4Artifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Basket4Artifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Basket5NorthArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.Basket5NorthArtifact.v0.json new file mode 100644 index 000000000..5c846cbee --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Basket5NorthArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Basket5NorthArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Basket5WestArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.Basket5WestArtifact.v0.json new file mode 100644 index 000000000..8471cfd4e --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Basket5WestArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Basket5WestArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Basket6Artifact.v0.json b/Projects/UOContent/Migrations/Server.Items.Basket6Artifact.v0.json new file mode 100644 index 000000000..7efe70742 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Basket6Artifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Basket6Artifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.BloodyWaterArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.BloodyWaterArtifact.v0.json new file mode 100644 index 000000000..62768f5c6 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.BloodyWaterArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.BloodyWaterArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.BooksFaceDownArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.BooksFaceDownArtifact.v0.json new file mode 100644 index 000000000..aeef57c93 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.BooksFaceDownArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.BooksFaceDownArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.BooksNorthArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.BooksNorthArtifact.v0.json new file mode 100644 index 000000000..75edbd1c0 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.BooksNorthArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.BooksNorthArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.BooksWestArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.BooksWestArtifact.v0.json new file mode 100644 index 000000000..1161373b9 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.BooksWestArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.BooksWestArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.BottleArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.BottleArtifact.v0.json new file mode 100644 index 000000000..4bcae0807 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.BottleArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.BottleArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.BowlArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.BowlArtifact.v0.json new file mode 100644 index 000000000..b3b120fd2 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.BowlArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.BowlArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.BowlsHorizontalArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.BowlsHorizontalArtifact.v0.json new file mode 100644 index 000000000..7f9a1bb96 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.BowlsHorizontalArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.BowlsHorizontalArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.BowlsVerticalArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.BowlsVerticalArtifact.v0.json new file mode 100644 index 000000000..cb9e76c8b --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.BowlsVerticalArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.BowlsVerticalArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.BrazierArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.BrazierArtifact.v0.json new file mode 100644 index 000000000..7601a5c28 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.BrazierArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.BrazierArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.CocoonArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.CocoonArtifact.v0.json new file mode 100644 index 000000000..493941395 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.CocoonArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.CocoonArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.CupsArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.CupsArtifact.v0.json new file mode 100644 index 000000000..c8b9779c4 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.CupsArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.CupsArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.DamagedBooksArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.DamagedBooksArtifact.v0.json new file mode 100644 index 000000000..23c93bc34 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.DamagedBooksArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.DamagedBooksArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.DolphinLeftArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.DolphinLeftArtifact.v0.json new file mode 100644 index 000000000..e9a16e0dd --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.DolphinLeftArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.DolphinLeftArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.DolphinRightArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.DolphinRightArtifact.v0.json new file mode 100644 index 000000000..65777313d --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.DolphinRightArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.DolphinRightArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.EggCaseArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.EggCaseArtifact.v0.json new file mode 100644 index 000000000..259baf617 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.EggCaseArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.EggCaseArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.FanNorthArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.FanNorthArtifact.v0.json new file mode 100644 index 000000000..2b44def64 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.FanNorthArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.FanNorthArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.FanWestArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.FanWestArtifact.v0.json new file mode 100644 index 000000000..156ece978 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.FanWestArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.FanWestArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.FlowersArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.FlowersArtifact.v0.json new file mode 100644 index 000000000..c9527ebe3 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.FlowersArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.FlowersArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.GruesomeStandardArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.GruesomeStandardArtifact.v0.json new file mode 100644 index 000000000..45dfb8bce --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.GruesomeStandardArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.GruesomeStandardArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.LampPostArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.LampPostArtifact.v0.json new file mode 100644 index 000000000..2b731c1f5 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.LampPostArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.LampPostArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.LeatherTunicArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.LeatherTunicArtifact.v0.json new file mode 100644 index 000000000..fd37349a1 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.LeatherTunicArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.LeatherTunicArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.ManStatuetteEastArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.ManStatuetteEastArtifact.v0.json new file mode 100644 index 000000000..62b7bc6ec --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.ManStatuetteEastArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.ManStatuetteEastArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.ManStatuetteSouthArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.ManStatuetteSouthArtifact.v0.json new file mode 100644 index 000000000..8d58d643a --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.ManStatuetteSouthArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.ManStatuetteSouthArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Painting1NorthArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.Painting1NorthArtifact.v0.json new file mode 100644 index 000000000..40b3e66da --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Painting1NorthArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Painting1NorthArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Painting1WestArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.Painting1WestArtifact.v0.json new file mode 100644 index 000000000..b2f21b5f5 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Painting1WestArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Painting1WestArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Painting2NorthArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.Painting2NorthArtifact.v0.json new file mode 100644 index 000000000..2031ec7bb --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Painting2NorthArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Painting2NorthArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Painting2WestArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.Painting2WestArtifact.v0.json new file mode 100644 index 000000000..e0db930f6 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Painting2WestArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Painting2WestArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Painting3Artifact.v0.json b/Projects/UOContent/Migrations/Server.Items.Painting3Artifact.v0.json new file mode 100644 index 000000000..ff244ec11 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Painting3Artifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Painting3Artifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Painting4NorthArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.Painting4NorthArtifact.v0.json new file mode 100644 index 000000000..13d2251dd --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Painting4NorthArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Painting4NorthArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Painting4WestArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.Painting4WestArtifact.v0.json new file mode 100644 index 000000000..22a8a0fe5 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Painting4WestArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Painting4WestArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Painting5NorthArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.Painting5NorthArtifact.v0.json new file mode 100644 index 000000000..a2261668d --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Painting5NorthArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Painting5NorthArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Painting5WestArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.Painting5WestArtifact.v0.json new file mode 100644 index 000000000..0870e57b3 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Painting5WestArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Painting5WestArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Painting6NorthArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.Painting6NorthArtifact.v0.json new file mode 100644 index 000000000..78b84c295 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Painting6NorthArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Painting6NorthArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Painting6WestArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.Painting6WestArtifact.v0.json new file mode 100644 index 000000000..3dff6badd --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Painting6WestArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Painting6WestArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.RockArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.RockArtifact.v0.json new file mode 100644 index 000000000..8f58e3f1b --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.RockArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.RockArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.RuinedPaintingArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.RuinedPaintingArtifact.v0.json new file mode 100644 index 000000000..0fed9ca14 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.RuinedPaintingArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.RuinedPaintingArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.SaddleArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.SaddleArtifact.v0.json new file mode 100644 index 000000000..503b174d1 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.SaddleArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.SaddleArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.SakeArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.SakeArtifact.v0.json new file mode 100644 index 000000000..9401028a8 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.SakeArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.SakeArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Sculpture1Artifact.v0.json b/Projects/UOContent/Migrations/Server.Items.Sculpture1Artifact.v0.json new file mode 100644 index 000000000..b3ba13f74 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Sculpture1Artifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Sculpture1Artifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Sculpture2Artifact.v0.json b/Projects/UOContent/Migrations/Server.Items.Sculpture2Artifact.v0.json new file mode 100644 index 000000000..110a50784 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Sculpture2Artifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Sculpture2Artifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.SkinnedDeerArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.SkinnedDeerArtifact.v0.json new file mode 100644 index 000000000..8cf6586c2 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.SkinnedDeerArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.SkinnedDeerArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.SkinnedGoatArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.SkinnedGoatArtifact.v0.json new file mode 100644 index 000000000..b110bcab3 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.SkinnedGoatArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.SkinnedGoatArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.SkullCandleArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.SkullCandleArtifact.v0.json new file mode 100644 index 000000000..440decb75 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.SkullCandleArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.SkullCandleArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.StretchedHideArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.StretchedHideArtifact.v0.json new file mode 100644 index 000000000..5864f95d2 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.StretchedHideArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.StretchedHideArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.StuddedLeggingsArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.StuddedLeggingsArtifact.v0.json new file mode 100644 index 000000000..eba0ff0e0 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.StuddedLeggingsArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.StuddedLeggingsArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.StuddedTunicArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.StuddedTunicArtifact.v0.json new file mode 100644 index 000000000..4ed9d4287 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.StuddedTunicArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.StuddedTunicArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.SwordDisplay1NorthArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.SwordDisplay1NorthArtifact.v0.json new file mode 100644 index 000000000..810db7f36 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.SwordDisplay1NorthArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.SwordDisplay1NorthArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.SwordDisplay1WestArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.SwordDisplay1WestArtifact.v0.json new file mode 100644 index 000000000..50cfbc144 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.SwordDisplay1WestArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.SwordDisplay1WestArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.SwordDisplay2NorthArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.SwordDisplay2NorthArtifact.v0.json new file mode 100644 index 000000000..33aaaad72 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.SwordDisplay2NorthArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.SwordDisplay2NorthArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.SwordDisplay2WestArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.SwordDisplay2WestArtifact.v0.json new file mode 100644 index 000000000..33df5a093 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.SwordDisplay2WestArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.SwordDisplay2WestArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.SwordDisplay3EastArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.SwordDisplay3EastArtifact.v0.json new file mode 100644 index 000000000..6adc5ea9a --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.SwordDisplay3EastArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.SwordDisplay3EastArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.SwordDisplay3SouthArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.SwordDisplay3SouthArtifact.v0.json new file mode 100644 index 000000000..0be1d44eb --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.SwordDisplay3SouthArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.SwordDisplay3SouthArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.SwordDisplay4NorthArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.SwordDisplay4NorthArtifact.v0.json new file mode 100644 index 000000000..6f18cc9f2 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.SwordDisplay4NorthArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.SwordDisplay4NorthArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.SwordDisplay4WestArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.SwordDisplay4WestArtifact.v0.json new file mode 100644 index 000000000..d87c9ae60 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.SwordDisplay4WestArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.SwordDisplay4WestArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.SwordDisplay5NorthArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.SwordDisplay5NorthArtifact.v0.json new file mode 100644 index 000000000..f7549c1c9 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.SwordDisplay5NorthArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.SwordDisplay5NorthArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.SwordDisplay5WestArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.SwordDisplay5WestArtifact.v0.json new file mode 100644 index 000000000..953b64866 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.SwordDisplay5WestArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.SwordDisplay5WestArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.TarotCardsArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.TarotCardsArtifact.v0.json new file mode 100644 index 000000000..c35d04652 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.TarotCardsArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.TarotCardsArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.TeapotNorthArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.TeapotNorthArtifact.v0.json new file mode 100644 index 000000000..0cc360e43 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.TeapotNorthArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.TeapotNorthArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.TeapotWestArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.TeapotWestArtifact.v0.json new file mode 100644 index 000000000..78e012076 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.TeapotWestArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.TeapotWestArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.TowerLanternArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.TowerLanternArtifact.v0.json new file mode 100644 index 000000000..24b052b7f --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.TowerLanternArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.TowerLanternArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.TripleFanNorthArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.TripleFanNorthArtifact.v0.json new file mode 100644 index 000000000..09d293e31 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.TripleFanNorthArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.TripleFanNorthArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.TripleFanWestArtifact.v0.json b/Projects/UOContent/Migrations/Server.Items.TripleFanWestArtifact.v0.json new file mode 100644 index 000000000..4bdca34be --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.TripleFanWestArtifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.TripleFanWestArtifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Urn1Artifact.v0.json b/Projects/UOContent/Migrations/Server.Items.Urn1Artifact.v0.json new file mode 100644 index 000000000..261d2866a --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Urn1Artifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Urn1Artifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Urn2Artifact.v0.json b/Projects/UOContent/Migrations/Server.Items.Urn2Artifact.v0.json new file mode 100644 index 000000000..723f06743 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Urn2Artifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Urn2Artifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.ZenRock1Artifact.v0.json b/Projects/UOContent/Migrations/Server.Items.ZenRock1Artifact.v0.json new file mode 100644 index 000000000..5c499202e --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.ZenRock1Artifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.ZenRock1Artifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.ZenRock2Artifact.v0.json b/Projects/UOContent/Migrations/Server.Items.ZenRock2Artifact.v0.json new file mode 100644 index 000000000..ff6522468 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.ZenRock2Artifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.ZenRock2Artifact" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.ZenRock3Artifact.v0.json b/Projects/UOContent/Migrations/Server.Items.ZenRock3Artifact.v0.json new file mode 100644 index 000000000..3f006c6a8 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.ZenRock3Artifact.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.ZenRock3Artifact" +} \ No newline at end of file From e148e1cabb9d5f798376712c3ce6a00fc4f230c4 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 27 Mar 2022 19:37:10 -0700 Subject: [PATCH 121/213] fix: Converts stealable artifacts to a system instead of a spawner. (#979) --- .../Engines/Stealables/StealableArtifacts.cs | 444 ++++++++++++++++++ .../BasePigmentsOfTokuno.cs | 3 +- .../StealableArtifactsSpawner.cs | 431 ----------------- Projects/UOContent/Skills/Stealing.cs | 9 +- 4 files changed, 450 insertions(+), 437 deletions(-) create mode 100644 Projects/UOContent/Engines/Stealables/StealableArtifacts.cs delete mode 100644 Projects/UOContent/Items/Decoration Artifacts/StealableArtifactsSpawner.cs diff --git a/Projects/UOContent/Engines/Stealables/StealableArtifacts.cs b/Projects/UOContent/Engines/Stealables/StealableArtifacts.cs new file mode 100644 index 000000000..d3e2d2219 --- /dev/null +++ b/Projects/UOContent/Engines/Stealables/StealableArtifacts.cs @@ -0,0 +1,444 @@ +using System; +using System.Collections.Generic; +using Server.Items; +using Server.Logging; +using Server.Utilities; + +namespace Server.Engines.Stealables; + +public static class StealableArtifacts +{ + private static readonly ILogger logger = LogFactory.GetLogger(typeof(StealableArtifacts)); + + private static bool _enabled; + private static Type[] _typesOfEntries; + private static StealableInstance[] _artifacts; + + private static Timer _respawnTimer; + private static Dictionary _table; + + public static void Configure() + { + GenericPersistence.Register("stealable-artifacts", Serialize, Deserialize); + } + + private static void RemoveStealableArtifacts() + { + _enabled = false; + _respawnTimer?.Stop(); + _respawnTimer = null; + + if (_artifacts?.Length > 0) + { + foreach (var si in _artifacts) + { + var item = si.Item; + if (item.Deleted == false && !item.Movable && item.Parent == null) + { + item.Delete(); + } + } + } + + _artifacts = null; + } + + private static void CreateStealableArtifacts() + { + _enabled = true; + + _artifacts = new StealableInstance[Entries.Length]; + _table ??= new Dictionary(Entries.Length); + + for (var i = 0; i < Entries.Length; i++) + { + _artifacts[i] = new StealableInstance(Entries[i]); + } + + _respawnTimer = Timer.DelayCall(TimeSpan.Zero, TimeSpan.FromMinutes(15.0), CheckRespawn); + } + + public static StealableEntry[] Entries { get; } = + { + // Doom - Artifact rarity 1 + new(Map.Malas, new Point3D(317, 56, -1), 72, 108, typeof(RockArtifact)), + new(Map.Malas, new Point3D(360, 31, 8), 72, 108, typeof(SkullCandleArtifact)), + new(Map.Malas, new Point3D(369, 372, -1), 72, 108, typeof(BottleArtifact)), + new(Map.Malas, new Point3D(378, 372, 0), 72, 108, typeof(DamagedBooksArtifact)), + // Doom - Artifact rarity 2 + new(Map.Malas, new Point3D(432, 16, -1), 144, 216, typeof(StretchedHideArtifact)), + new(Map.Malas, new Point3D(489, 9, 0), 144, 216, typeof(BrazierArtifact)), + // Doom - Artifact rarity 3 + new(Map.Malas, new Point3D(471, 96, -1), 288, 432, typeof(LampPostArtifact), GetLampPostHue()), + new(Map.Malas, new Point3D(421, 198, 2), 288, 432, typeof(BooksNorthArtifact)), + new(Map.Malas, new Point3D(431, 189, -1), 288, 432, typeof(BooksWestArtifact)), + new(Map.Malas, new Point3D(435, 196, -1), 288, 432, typeof(BooksFaceDownArtifact)), + // Doom - Artifact rarity 5 + new(Map.Malas, new Point3D(447, 9, 8), 1152, 1728, typeof(StuddedLeggingsArtifact)), + new(Map.Malas, new Point3D(423, 28, 0), 1152, 1728, typeof(EggCaseArtifact)), + new(Map.Malas, new Point3D(347, 44, 4), 1152, 1728, typeof(SkinnedGoatArtifact)), + new(Map.Malas, new Point3D(497, 57, -1), 1152, 1728, typeof(GruesomeStandardArtifact)), + new(Map.Malas, new Point3D(381, 375, 11), 1152, 1728, typeof(BloodyWaterArtifact)), + new(Map.Malas, new Point3D(489, 369, 2), 1152, 1728, typeof(TarotCardsArtifact)), + new(Map.Malas, new Point3D(497, 369, 5), 1152, 1728, typeof(BackpackArtifact)), + // Doom - Artifact rarity 7 + new(Map.Malas, new Point3D(475, 23, 4), 4608, 6912, typeof(StuddedTunicArtifact)), + new(Map.Malas, new Point3D(423, 28, 0), 4608, 6912, typeof(CocoonArtifact)), + // Doom - Artifact rarity 8 + new(Map.Malas, new Point3D(354, 36, -1), 9216, 13824, typeof(SkinnedDeerArtifact)), + // Doom - Artifact rarity 9 + new(Map.Malas, new Point3D(433, 11, -1), 18432, 27648, typeof(SaddleArtifact)), + new(Map.Malas, new Point3D(403, 31, 4), 18432, 27648, typeof(LeatherTunicArtifact)), + // Doom - Artifact rarity 10 + new(Map.Malas, new Point3D(257, 70, -2), 36864, 55296, typeof(ZyronicClaw)), + new(Map.Malas, new Point3D(354, 176, 7), 36864, 55296, typeof(TitansHammer)), + new(Map.Malas, new Point3D(369, 389, -1), 36864, 55296, typeof(BladeOfTheRighteous)), + new(Map.Malas, new Point3D(467, 92, 4), 36864, 55296, typeof(InquisitorsResolution)), + // Doom - Artifact rarity 12 + new(Map.Malas, new Point3D(487, 364, -1), 147456, 221184, typeof(RuinedPaintingArtifact)), + + // Yomotsu Mines - Artifact rarity 1 + new(Map.Malas, new Point3D(18, 110, -1), 72, 108, typeof(Basket1Artifact)), + new(Map.Malas, new Point3D(66, 114, -1), 72, 108, typeof(Basket2Artifact)), + // Yomotsu Mines - Artifact rarity 2 + new(Map.Malas, new Point3D(63, 12, 11), 144, 216, typeof(Basket4Artifact)), + new(Map.Malas, new Point3D(5, 29, -1), 144, 216, typeof(Basket5NorthArtifact)), + new(Map.Malas, new Point3D(30, 81, 3), 144, 216, typeof(Basket5WestArtifact)), + // Yomotsu Mines - Artifact rarity 3 + new(Map.Malas, new Point3D(115, 7, -1), 288, 432, typeof(Urn1Artifact)), + new(Map.Malas, new Point3D(85, 13, -1), 288, 432, typeof(Urn2Artifact)), + new(Map.Malas, new Point3D(110, 53, -1), 288, 432, typeof(Sculpture1Artifact)), + new(Map.Malas, new Point3D(108, 37, -1), 288, 432, typeof(Sculpture2Artifact)), + new(Map.Malas, new Point3D(121, 14, -1), 288, 432, typeof(TeapotNorthArtifact)), + new(Map.Malas, new Point3D(121, 115, -1), 288, 432, typeof(TeapotWestArtifact)), + new(Map.Malas, new Point3D(84, 40, -1), 288, 432, typeof(TowerLanternArtifact)), + // Yomotsu Mines - Artifact rarity 9 + new(Map.Malas, new Point3D(94, 7, -1), 18432, 27648, typeof(ManStatuetteSouthArtifact)), + + // Fan Dancer's Dojo - Artifact rarity 1 + new(Map.Malas, new Point3D(113, 640, -2), 72, 108, typeof(Basket3NorthArtifact)), + new(Map.Malas, new Point3D(102, 355, -1), 72, 108, typeof(Basket3WestArtifact)), + // Fan Dancer's Dojo - Artifact rarity 2 + new(Map.Malas, new Point3D(99, 370, -1), 144, 216, typeof(Basket6Artifact)), + new(Map.Malas, new Point3D(100, 357, -1), 144, 216, typeof(ZenRock1Artifact)), + // Fan Dancer's Dojo - Artifact rarity 3 + new(Map.Malas, new Point3D(73, 473, -1), 288, 432, typeof(FanNorthArtifact)), + new(Map.Malas, new Point3D(99, 372, -1), 288, 432, typeof(FanWestArtifact)), + new(Map.Malas, new Point3D(92, 326, -1), 288, 432, typeof(BowlsVerticalArtifact)), + new(Map.Malas, new Point3D(97, 470, -1), 288, 432, typeof(ZenRock2Artifact)), + new(Map.Malas, new Point3D(103, 691, -1), 288, 432, typeof(ZenRock3Artifact)), + // Fan Dancer's Dojo - Artifact rarity 4 + new(Map.Malas, new Point3D(103, 336, 4), 576, 864, typeof(Painting1NorthArtifact)), + new(Map.Malas, new Point3D(59, 381, 4), 576, 864, typeof(Painting1WestArtifact)), + new(Map.Malas, new Point3D(84, 401, 2), 576, 864, typeof(Painting2NorthArtifact)), + new(Map.Malas, new Point3D(59, 392, 2), 576, 864, typeof(Painting2WestArtifact)), + new(Map.Malas, new Point3D(107, 483, -1), 576, 864, typeof(TripleFanNorthArtifact)), + new(Map.Malas, new Point3D(50, 475, -1), 576, 864, typeof(TripleFanWestArtifact)), + new(Map.Malas, new Point3D(107, 460, -1), 576, 864, typeof(BowlArtifact)), + new(Map.Malas, new Point3D(90, 502, -1), 576, 864, typeof(CupsArtifact)), + new(Map.Malas, new Point3D(107, 688, -1), 576, 864, typeof(BowlsHorizontalArtifact)), + new(Map.Malas, new Point3D(112, 676, -1), 576, 864, typeof(SakeArtifact)), + // Fan Dancer's Dojo - Artifact rarity 5 + new(Map.Malas, new Point3D(135, 614, -1), 1152, 1728, typeof(SwordDisplay1NorthArtifact)), + new(Map.Malas, new Point3D(50, 482, -1), 1152, 1728, typeof(SwordDisplay1WestArtifact)), + new(Map.Malas, new Point3D(119, 672, -1), 1152, 1728, typeof(Painting3Artifact)), + // Fan Dancer's Dojo - Artifact rarity 6 + new(Map.Malas, new Point3D(90, 326, -1), 2304, 3456, typeof(Painting4NorthArtifact)), + new(Map.Malas, new Point3D(99, 354, -1), 2304, 3456, typeof(Painting4WestArtifact)), + new(Map.Malas, new Point3D(179, 652, -1), 2304, 3456, typeof(SwordDisplay2NorthArtifact)), + new(Map.Malas, new Point3D(118, 627, -1), 2304, 3456, typeof(SwordDisplay2WestArtifact)), + // Fan Dancer's Dojo - Artifact rarity 7 + new(Map.Malas, new Point3D(90, 483, -1), 4608, 6912, typeof(FlowersArtifact)), + // Fan Dancer's Dojo - Artifact rarity 8 + new(Map.Malas, new Point3D(71, 562, -1), 9216, 13824, typeof(DolphinLeftArtifact)), + new(Map.Malas, new Point3D(102, 677, -1), 9216, 13824, typeof(DolphinRightArtifact)), + new(Map.Malas, new Point3D(61, 499, 0), 9216, 13824, typeof(SwordDisplay3SouthArtifact)), + new(Map.Malas, new Point3D(182, 669, -1), 9216, 13824, typeof(SwordDisplay3EastArtifact)), + new(Map.Malas, new Point3D(162, 647, -1), 9216, 13824, typeof(SwordDisplay4WestArtifact)), + new(Map.Malas, new Point3D(124, 624, 0), 9216, 13824, typeof(Painting5NorthArtifact)), + new(Map.Malas, new Point3D(146, 649, 2), 9216, 13824, typeof(Painting5WestArtifact)), + // Fan Dancer's Dojo - Artifact rarity 9 + new(Map.Malas, new Point3D(100, 488, -1), 18432, 27648, typeof(SwordDisplay4NorthArtifact)), + new(Map.Malas, new Point3D(175, 606, 0), 18432, 27648, typeof(SwordDisplay5NorthArtifact)), + new(Map.Malas, new Point3D(157, 608, -1), 18432, 27648, typeof(SwordDisplay5WestArtifact)), + new(Map.Malas, new Point3D(187, 643, 1), 18432, 27648, typeof(Painting6NorthArtifact)), + new(Map.Malas, new Point3D(146, 623, 1), 18432, 27648, typeof(Painting6WestArtifact)), + new(Map.Malas, new Point3D(178, 629, -1), 18432, 27648, typeof(ManStatuetteEastArtifact)) + }; + + public static Type[] TypesOfEntries + { + get + { + if (_typesOfEntries == null) + { + _typesOfEntries = new Type[Entries.Length]; + + for (var i = 0; i < Entries.Length; i++) + { + _typesOfEntries[i] = Entries[i].Type; + } + } + + return _typesOfEntries; + } + } + + private static int GetLampPostHue() => + Utility.RandomDouble() < 0.9 ? 0 : Utility.RandomList(0x455, 0x47E, 0x482, 0x486, 0x48F, 0x4F2, 0x58C, 0x66C); + + public static void Initialize() + { + CommandSystem.Register("GenStealArties", AccessLevel.Administrator, GenStealArties_OnCommand); + CommandSystem.Register("RemoveStealArties", AccessLevel.Administrator, RemoveStealArties_OnCommand); + } + + [Usage("GenStealArties"), Description("Generates the stealable artifacts spawner.")] + private static void GenStealArties_OnCommand(CommandEventArgs args) + { + var from = args.Mobile; + + if (_enabled) + { + from.SendMessage("Stealable artifacts spawner already present."); + return; + } + + CreateStealableArtifacts(); + from.SendMessage("Stealable artifacts spawner generated."); + } + + [Usage("RemoveStealArties")] + [Description("Removes the stealable artifacts spawner and every not yet stolen stealable artifacts.")] + private static void RemoveStealArties_OnCommand(CommandEventArgs args) + { + var from = args.Mobile; + + if (!_enabled) + { + from.SendMessage("Stealable artifacts spawner not present."); + return; + } + + RemoveStealableArtifacts(); + from.SendMessage("Stealable artifacts spawner removed."); + } + + public static StealableInstance GetStealableInstance(Item item) + { + if (_enabled && _table.TryGetValue(item, out var value)) + { + return value; + } + + return null; + } + + public static void CheckRespawn() + { + foreach (var si in _artifacts) + { + si.CheckRespawn(); + } + } + + private static void Serialize(IGenericWriter writer) + { + writer.WriteEncodedInt(1); // version + + writer.Write(_enabled); + + if (_enabled) + { + writer.WriteEncodedInt(_artifacts.Length); + + for (var i = 0; i < _artifacts.Length; i++) + { + var si = _artifacts[i]; + + writer.Write(si.Item); + writer.WriteDeltaTime(si.NextRespawn); + } + } + } + + private static void Deserialize(IGenericReader reader) + { + var version = reader.ReadEncodedInt(); + + _enabled = version > 0 && reader.ReadBool(); + + if (_enabled) + { + _artifacts = new StealableInstance[Entries.Length]; + _table = new Dictionary(Entries.Length); + + var length = reader.ReadEncodedInt(); + + for (var i = 0; i < length; i++) + { + var item = reader.ReadEntity(); + var nextRespawn = reader.ReadDeltaTime(); + + if (i < _artifacts.Length) + { + var si = new StealableInstance(Entries[i], item, nextRespawn); + _artifacts[i] = si; + + if (si.Item != null) + { + _table[si.Item] = si; + } + } + } + + for (var i = length; i < Entries.Length; i++) + { + _artifacts[i] = new StealableInstance(Entries[i]); + } + + _enabled = _artifacts.Length > 0; + + if (_enabled) + { + _respawnTimer = Timer.DelayCall(TimeSpan.Zero, TimeSpan.FromMinutes(15.0), CheckRespawn); + } + else + { + _artifacts = null; + } + } + } + + public class StealableEntry + { + public StealableEntry(Map map, Point3D location, int minDelay, int maxDelay, Type type, int hue = 0) + { + Map = map; + Location = location; + MinDelay = minDelay; + MaxDelay = maxDelay; + Type = type; + Hue = hue; + } + + public Map Map { get; } + + public Point3D Location { get; } + + public int MinDelay { get; } + + public int MaxDelay { get; } + + public Type Type { get; } + + public int Hue { get; } + + public Item CreateInstance() + { + try + { + var item = Type.CreateInstance(); + + if (Hue > 0) + { + item.Hue = Hue; + } + + item.Movable = false; + item.MoveToWorld(Location, Map); + + return item; + } + catch (Exception e) + { + logger.Warning(e, $"Failed to construct stealable artifact: {Type.FullName}"); + return null; + } + } + } + + public class StealableInstance + { + private Item m_Item; + + public StealableInstance(StealableEntry entry) : this(entry, null, Core.Now) + { + } + + public StealableInstance(StealableEntry entry, Item item, DateTime nextRespawn) + { + m_Item = item; + NextRespawn = nextRespawn; + Entry = entry; + } + + public StealableEntry Entry { get; } + + public Item Item + { + get => m_Item; + set + { + if (m_Item != null && value == null) + { + var delay = Utility.RandomMinMax(Entry.MinDelay, Entry.MaxDelay); + NextRespawn = Core.Now + TimeSpan.FromMinutes(delay); + } + + if (_enabled) + { + if (m_Item != null) + { + _table.Remove(m_Item); + } + + if (value != null) + { + _table[value] = this; + } + } + + m_Item = value; + } + } + + public DateTime NextRespawn { get; set; } + + public void CheckRespawn() + { + if (Item != null && (Item.Deleted || Item.Movable || Item.Parent != null)) + { + Item = null; + } + + if (Item == null && Core.Now >= NextRespawn) + { + Item = Entry.CreateInstance(); + } + } + } + + [ManualDirtyChecking] + [TypeAlias("Server.Items.StealableArtifactsSpawner")] + [Obsolete("Deprecated in favor of the static system. Only used for legacy deserialization")] + public class StealableArtifactsSpawner : Item + { + private StealableArtifactsSpawner() + { + } + + public StealableArtifactsSpawner(Serial serial) : base(serial) + { + } + + public override void Deserialize(IGenericReader reader) + { + base.Deserialize(reader); + + StealableArtifacts.Deserialize(reader); + + Timer.DelayCall(Delete); + } + } +} diff --git a/Projects/UOContent/Engines/Treasures of Tokuno/BasePigmentsOfTokuno.cs b/Projects/UOContent/Engines/Treasures of Tokuno/BasePigmentsOfTokuno.cs index 2051ab96c..af63c592b 100644 --- a/Projects/UOContent/Engines/Treasures of Tokuno/BasePigmentsOfTokuno.cs +++ b/Projects/UOContent/Engines/Treasures of Tokuno/BasePigmentsOfTokuno.cs @@ -1,4 +1,5 @@ using System; +using Server.Engines.Stealables; using Server.Misc; using Server.Mobiles; using Server.Targeting; @@ -234,7 +235,7 @@ namespace Server.Items || IsInTypeList(t, DemonKnight.ArtifactRarity10) || IsInTypeList(t, DemonKnight.ArtifactRarity11) || IsInTypeList(t, MondainsLegacy.Artifacts) - || IsInTypeList(t, StealableArtifactsSpawner.TypesOfEntires) + || IsInTypeList(t, StealableArtifacts.TypesOfEntries) || IsInTypeList(t, Paragon.Artifacts) || IsInTypeList(t, Leviathan.Artifacts) || IsInTypeList(t, TreasureMapChest.Artifacts) diff --git a/Projects/UOContent/Items/Decoration Artifacts/StealableArtifactsSpawner.cs b/Projects/UOContent/Items/Decoration Artifacts/StealableArtifactsSpawner.cs deleted file mode 100644 index d7e34a96e..000000000 --- a/Projects/UOContent/Items/Decoration Artifacts/StealableArtifactsSpawner.cs +++ /dev/null @@ -1,431 +0,0 @@ -using System; -using System.Collections.Generic; -using Server.Logging; -using Server.Utilities; - -namespace Server.Items -{ - public class StealableArtifactsSpawner : Item - { - private static readonly ILogger logger = LogFactory.GetLogger(typeof(StealableArtifactsSpawner)); - - private static Type[] m_TypesOfEntries; - private StealableInstance[] m_Artifacts; - - private Timer _respawnTimer; - private Dictionary m_Table; - - private StealableArtifactsSpawner() : base(1) - { - Movable = false; - - m_Artifacts = new StealableInstance[Entries.Length]; - m_Table = new Dictionary(Entries.Length); - - for (var i = 0; i < Entries.Length; i++) - { - m_Artifacts[i] = new StealableInstance(Entries[i]); - } - - _respawnTimer = Timer.DelayCall(TimeSpan.Zero, TimeSpan.FromMinutes(15.0), CheckRespawn); - } - - public StealableArtifactsSpawner(Serial serial) : base(serial) => Instance = this; - - public static StealableEntry[] Entries { get; } = - { - // Doom - Artifact rarity 1 - new(Map.Malas, new Point3D(317, 56, -1), 72, 108, typeof(RockArtifact)), - new(Map.Malas, new Point3D(360, 31, 8), 72, 108, typeof(SkullCandleArtifact)), - new(Map.Malas, new Point3D(369, 372, -1), 72, 108, typeof(BottleArtifact)), - new(Map.Malas, new Point3D(378, 372, 0), 72, 108, typeof(DamagedBooksArtifact)), - // Doom - Artifact rarity 2 - new(Map.Malas, new Point3D(432, 16, -1), 144, 216, typeof(StretchedHideArtifact)), - new(Map.Malas, new Point3D(489, 9, 0), 144, 216, typeof(BrazierArtifact)), - // Doom - Artifact rarity 3 - new(Map.Malas, new Point3D(471, 96, -1), 288, 432, typeof(LampPostArtifact), GetLampPostHue()), - new(Map.Malas, new Point3D(421, 198, 2), 288, 432, typeof(BooksNorthArtifact)), - new(Map.Malas, new Point3D(431, 189, -1), 288, 432, typeof(BooksWestArtifact)), - new(Map.Malas, new Point3D(435, 196, -1), 288, 432, typeof(BooksFaceDownArtifact)), - // Doom - Artifact rarity 5 - new(Map.Malas, new Point3D(447, 9, 8), 1152, 1728, typeof(StuddedLeggingsArtifact)), - new(Map.Malas, new Point3D(423, 28, 0), 1152, 1728, typeof(EggCaseArtifact)), - new(Map.Malas, new Point3D(347, 44, 4), 1152, 1728, typeof(SkinnedGoatArtifact)), - new(Map.Malas, new Point3D(497, 57, -1), 1152, 1728, typeof(GruesomeStandardArtifact)), - new(Map.Malas, new Point3D(381, 375, 11), 1152, 1728, typeof(BloodyWaterArtifact)), - new(Map.Malas, new Point3D(489, 369, 2), 1152, 1728, typeof(TarotCardsArtifact)), - new(Map.Malas, new Point3D(497, 369, 5), 1152, 1728, typeof(BackpackArtifact)), - // Doom - Artifact rarity 7 - new(Map.Malas, new Point3D(475, 23, 4), 4608, 6912, typeof(StuddedTunicArtifact)), - new(Map.Malas, new Point3D(423, 28, 0), 4608, 6912, typeof(CocoonArtifact)), - // Doom - Artifact rarity 8 - new(Map.Malas, new Point3D(354, 36, -1), 9216, 13824, typeof(SkinnedDeerArtifact)), - // Doom - Artifact rarity 9 - new(Map.Malas, new Point3D(433, 11, -1), 18432, 27648, typeof(SaddleArtifact)), - new(Map.Malas, new Point3D(403, 31, 4), 18432, 27648, typeof(LeatherTunicArtifact)), - // Doom - Artifact rarity 10 - new(Map.Malas, new Point3D(257, 70, -2), 36864, 55296, typeof(ZyronicClaw)), - new(Map.Malas, new Point3D(354, 176, 7), 36864, 55296, typeof(TitansHammer)), - new(Map.Malas, new Point3D(369, 389, -1), 36864, 55296, typeof(BladeOfTheRighteous)), - new(Map.Malas, new Point3D(467, 92, 4), 36864, 55296, typeof(InquisitorsResolution)), - // Doom - Artifact rarity 12 - new(Map.Malas, new Point3D(487, 364, -1), 147456, 221184, typeof(RuinedPaintingArtifact)), - - // Yomotsu Mines - Artifact rarity 1 - new(Map.Malas, new Point3D(18, 110, -1), 72, 108, typeof(Basket1Artifact)), - new(Map.Malas, new Point3D(66, 114, -1), 72, 108, typeof(Basket2Artifact)), - // Yomotsu Mines - Artifact rarity 2 - new(Map.Malas, new Point3D(63, 12, 11), 144, 216, typeof(Basket4Artifact)), - new(Map.Malas, new Point3D(5, 29, -1), 144, 216, typeof(Basket5NorthArtifact)), - new(Map.Malas, new Point3D(30, 81, 3), 144, 216, typeof(Basket5WestArtifact)), - // Yomotsu Mines - Artifact rarity 3 - new(Map.Malas, new Point3D(115, 7, -1), 288, 432, typeof(Urn1Artifact)), - new(Map.Malas, new Point3D(85, 13, -1), 288, 432, typeof(Urn2Artifact)), - new(Map.Malas, new Point3D(110, 53, -1), 288, 432, typeof(Sculpture1Artifact)), - new(Map.Malas, new Point3D(108, 37, -1), 288, 432, typeof(Sculpture2Artifact)), - new(Map.Malas, new Point3D(121, 14, -1), 288, 432, typeof(TeapotNorthArtifact)), - new(Map.Malas, new Point3D(121, 115, -1), 288, 432, typeof(TeapotWestArtifact)), - new(Map.Malas, new Point3D(84, 40, -1), 288, 432, typeof(TowerLanternArtifact)), - // Yomotsu Mines - Artifact rarity 9 - new(Map.Malas, new Point3D(94, 7, -1), 18432, 27648, typeof(ManStatuetteSouthArtifact)), - - // Fan Dancer's Dojo - Artifact rarity 1 - new(Map.Malas, new Point3D(113, 640, -2), 72, 108, typeof(Basket3NorthArtifact)), - new(Map.Malas, new Point3D(102, 355, -1), 72, 108, typeof(Basket3WestArtifact)), - // Fan Dancer's Dojo - Artifact rarity 2 - new(Map.Malas, new Point3D(99, 370, -1), 144, 216, typeof(Basket6Artifact)), - new(Map.Malas, new Point3D(100, 357, -1), 144, 216, typeof(ZenRock1Artifact)), - // Fan Dancer's Dojo - Artifact rarity 3 - new(Map.Malas, new Point3D(73, 473, -1), 288, 432, typeof(FanNorthArtifact)), - new(Map.Malas, new Point3D(99, 372, -1), 288, 432, typeof(FanWestArtifact)), - new(Map.Malas, new Point3D(92, 326, -1), 288, 432, typeof(BowlsVerticalArtifact)), - new(Map.Malas, new Point3D(97, 470, -1), 288, 432, typeof(ZenRock2Artifact)), - new(Map.Malas, new Point3D(103, 691, -1), 288, 432, typeof(ZenRock3Artifact)), - // Fan Dancer's Dojo - Artifact rarity 4 - new(Map.Malas, new Point3D(103, 336, 4), 576, 864, typeof(Painting1NorthArtifact)), - new(Map.Malas, new Point3D(59, 381, 4), 576, 864, typeof(Painting1WestArtifact)), - new(Map.Malas, new Point3D(84, 401, 2), 576, 864, typeof(Painting2NorthArtifact)), - new(Map.Malas, new Point3D(59, 392, 2), 576, 864, typeof(Painting2WestArtifact)), - new(Map.Malas, new Point3D(107, 483, -1), 576, 864, typeof(TripleFanNorthArtifact)), - new(Map.Malas, new Point3D(50, 475, -1), 576, 864, typeof(TripleFanWestArtifact)), - new(Map.Malas, new Point3D(107, 460, -1), 576, 864, typeof(BowlArtifact)), - new(Map.Malas, new Point3D(90, 502, -1), 576, 864, typeof(CupsArtifact)), - new(Map.Malas, new Point3D(107, 688, -1), 576, 864, typeof(BowlsHorizontalArtifact)), - new(Map.Malas, new Point3D(112, 676, -1), 576, 864, typeof(SakeArtifact)), - // Fan Dancer's Dojo - Artifact rarity 5 - new(Map.Malas, new Point3D(135, 614, -1), 1152, 1728, typeof(SwordDisplay1NorthArtifact)), - new(Map.Malas, new Point3D(50, 482, -1), 1152, 1728, typeof(SwordDisplay1WestArtifact)), - new(Map.Malas, new Point3D(119, 672, -1), 1152, 1728, typeof(Painting3Artifact)), - // Fan Dancer's Dojo - Artifact rarity 6 - new(Map.Malas, new Point3D(90, 326, -1), 2304, 3456, typeof(Painting4NorthArtifact)), - new(Map.Malas, new Point3D(99, 354, -1), 2304, 3456, typeof(Painting4WestArtifact)), - new(Map.Malas, new Point3D(179, 652, -1), 2304, 3456, typeof(SwordDisplay2NorthArtifact)), - new(Map.Malas, new Point3D(118, 627, -1), 2304, 3456, typeof(SwordDisplay2WestArtifact)), - // Fan Dancer's Dojo - Artifact rarity 7 - new(Map.Malas, new Point3D(90, 483, -1), 4608, 6912, typeof(FlowersArtifact)), - // Fan Dancer's Dojo - Artifact rarity 8 - new(Map.Malas, new Point3D(71, 562, -1), 9216, 13824, typeof(DolphinLeftArtifact)), - new(Map.Malas, new Point3D(102, 677, -1), 9216, 13824, typeof(DolphinRightArtifact)), - new(Map.Malas, new Point3D(61, 499, 0), 9216, 13824, typeof(SwordDisplay3SouthArtifact)), - new(Map.Malas, new Point3D(182, 669, -1), 9216, 13824, typeof(SwordDisplay3EastArtifact)), - new(Map.Malas, new Point3D(162, 647, -1), 9216, 13824, typeof(SwordDisplay4WestArtifact)), - new(Map.Malas, new Point3D(124, 624, 0), 9216, 13824, typeof(Painting5NorthArtifact)), - new(Map.Malas, new Point3D(146, 649, 2), 9216, 13824, typeof(Painting5WestArtifact)), - // Fan Dancer's Dojo - Artifact rarity 9 - new(Map.Malas, new Point3D(100, 488, -1), 18432, 27648, typeof(SwordDisplay4NorthArtifact)), - new(Map.Malas, new Point3D(175, 606, 0), 18432, 27648, typeof(SwordDisplay5NorthArtifact)), - new(Map.Malas, new Point3D(157, 608, -1), 18432, 27648, typeof(SwordDisplay5WestArtifact)), - new(Map.Malas, new Point3D(187, 643, 1), 18432, 27648, typeof(Painting6NorthArtifact)), - new(Map.Malas, new Point3D(146, 623, 1), 18432, 27648, typeof(Painting6WestArtifact)), - new(Map.Malas, new Point3D(178, 629, -1), 18432, 27648, typeof(ManStatuetteEastArtifact)) - }; - - public static Type[] TypesOfEntires - { - get - { - if (m_TypesOfEntries == null) - { - m_TypesOfEntries = new Type[Entries.Length]; - - for (var i = 0; i < Entries.Length; i++) - { - m_TypesOfEntries[i] = Entries[i].Type; - } - } - - return m_TypesOfEntries; - } - } - - public static StealableArtifactsSpawner Instance { get; private set; } - - public override string DefaultName => "Stealable Artifacts Spawner - Internal"; - - private static int GetLampPostHue() - { - if (Utility.RandomDouble() < 0.9) - { - return 0; - } - - return Utility.RandomList(0x455, 0x47E, 0x482, 0x486, 0x48F, 0x4F2, 0x58C, 0x66C); - } - - public static void Initialize() - { - CommandSystem.Register("GenStealArties", AccessLevel.Administrator, GenStealArties_OnCommand); - CommandSystem.Register("RemoveStealArties", AccessLevel.Administrator, RemoveStealArties_OnCommand); - } - - [Usage("GenStealArties"), Description("Generates the stealable artifacts spawner.")] - private static void GenStealArties_OnCommand(CommandEventArgs args) - { - var from = args.Mobile; - - if (Create()) - { - from.SendMessage("Stealable artifacts spawner generated."); - } - else - { - from.SendMessage("Stealable artifacts spawner already present."); - } - } - - [Usage("RemoveStealArties"), - Description("Removes the stealable artifacts spawner and every not yet stolen stealable artifacts.")] - private static void RemoveStealArties_OnCommand(CommandEventArgs args) - { - var from = args.Mobile; - - if (Remove()) - { - from.SendMessage("Stealable artifacts spawner removed."); - } - else - { - from.SendMessage("Stealable artifacts spawner not present."); - } - } - - public static bool Create() - { - if (Instance?.Deleted == false) - { - return false; - } - - Instance = new StealableArtifactsSpawner(); - return true; - } - - public static bool Remove() - { - if (Instance == null) - { - return false; - } - - Instance.Delete(); - Instance = null; - return true; - } - - public static StealableInstance GetStealableInstance(Item item) - { - if (Instance == null) - { - return null; - } - - Instance.m_Table.TryGetValue(item, out var value); - return value; - } - - public override void OnDelete() - { - base.OnDelete(); - - _respawnTimer.Stop(); - _respawnTimer = null; - - foreach (var si in m_Artifacts) - { - si.Item?.Delete(); - } - - Instance = null; - } - - public void CheckRespawn() - { - foreach (var si in m_Artifacts) - { - si.CheckRespawn(); - } - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - - writer.WriteEncodedInt(m_Artifacts.Length); - - for (var i = 0; i < m_Artifacts.Length; i++) - { - var si = m_Artifacts[i]; - - writer.Write(si.Item); - writer.WriteDeltaTime(si.NextRespawn); - } - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - - m_Artifacts = new StealableInstance[Entries.Length]; - m_Table = new Dictionary(Entries.Length); - - var length = reader.ReadEncodedInt(); - - for (var i = 0; i < length; i++) - { - var item = reader.ReadEntity(); - var nextRespawn = reader.ReadDeltaTime(); - - if (i < m_Artifacts.Length) - { - var si = new StealableInstance(Entries[i], item, nextRespawn); - m_Artifacts[i] = si; - - if (si.Item != null) - { - m_Table[si.Item] = si; - } - } - } - - for (var i = length; i < Entries.Length; i++) - { - m_Artifacts[i] = new StealableInstance(Entries[i]); - } - - _respawnTimer = Timer.DelayCall(TimeSpan.Zero, TimeSpan.FromMinutes(15.0), CheckRespawn); - } - - public class StealableEntry - { - public StealableEntry(Map map, Point3D location, int minDelay, int maxDelay, Type type, int hue = 0) - { - Map = map; - Location = location; - MinDelay = minDelay; - MaxDelay = maxDelay; - Type = type; - Hue = hue; - } - - public Map Map { get; } - - public Point3D Location { get; } - - public int MinDelay { get; } - - public int MaxDelay { get; } - - public Type Type { get; } - - public int Hue { get; } - - public Item CreateInstance() - { - try - { - var item = Type.CreateInstance(); - - if (Hue > 0) - { - item.Hue = Hue; - } - - item.Movable = false; - item.MoveToWorld(Location, Map); - - return item; - } - catch (Exception e) - { - logger.Warning(e, $"Failed to construct stealable artifact: {Type.FullName}"); - return null; - } - } - } - - public class StealableInstance - { - private Item m_Item; - - public StealableInstance(StealableEntry entry) : this(entry, null, Core.Now) - { - } - - public StealableInstance(StealableEntry entry, Item item, DateTime nextRespawn) - { - m_Item = item; - NextRespawn = nextRespawn; - Entry = entry; - } - - public StealableEntry Entry { get; } - - public Item Item - { - get => m_Item; - set - { - if (m_Item != null && value == null) - { - var delay = Utility.RandomMinMax(Entry.MinDelay, Entry.MaxDelay); - NextRespawn = Core.Now + TimeSpan.FromMinutes(delay); - } - - if (Instance != null) - { - if (m_Item != null) - { - Instance.m_Table.Remove(m_Item); - } - - if (value != null) - { - Instance.m_Table[value] = this; - } - } - - m_Item = value; - } - } - - public DateTime NextRespawn { get; set; } - - public void CheckRespawn() - { - if (Item != null && (Item.Deleted || Item.Movable || Item.Parent != null)) - { - Item = null; - } - - if (Item == null && Core.Now >= NextRespawn) - { - Item = Entry.CreateInstance(); - } - } - } - } -} diff --git a/Projects/UOContent/Skills/Stealing.cs b/Projects/UOContent/Skills/Stealing.cs index 7a65b98cd..f2aa47c63 100644 --- a/Projects/UOContent/Skills/Stealing.cs +++ b/Projects/UOContent/Skills/Stealing.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using Server.Engines.ConPVP; +using Server.Engines.Stealables; using Server.Factions; using Server.Items; using Server.Mobiles; @@ -79,11 +80,9 @@ namespace Server.SkillHandlers var root = toSteal.RootParent; var mobRoot = root as Mobile; - StealableArtifactsSpawner.StealableInstance si = null; - if (toSteal.Parent == null || !toSteal.Movable) - { - si = StealableArtifactsSpawner.GetStealableInstance(toSteal); - } + StealableArtifacts.StealableInstance si = toSteal.Parent == null || !toSteal.Movable + ? StealableArtifacts.GetStealableInstance(toSteal) + : null; if (!IsEmptyHanded(m_Thief)) { From d451ed0fd390c9f8f5a0b5e23543ec10310b6f48 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Mon, 28 Mar 2022 14:36:43 -0700 Subject: [PATCH 122/213] Adds Material Theme to thank you --- README.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 957665a56..f95a27880 100644 --- a/README.md +++ b/README.md @@ -33,9 +33,10 @@ ModernUO [![Discord](https://img.shields.io/discord/751317910504603701?logo=disc #### Supported IDEs     -[Jetbrains Rider 2021.3](https://www.jetbrains.com/rider/download) +[Jetbrains Rider 2021.3](https://www.jetbrains.com/rider/download)                           -[Visual Studio 2022](https://visualstudio.microsoft.com/downloads) +[Visual Studio 2022](https://visualstudio.microsoft.com/downloads)
Rider 2021.3+             Visual Studio 2022+ ###### Note: VS Code is not currently supported. @@ -78,4 +79,6 @@ Rider 2021.3+           & Thank you for supporting us! You can find out how by visiting the [sponsors](./SPONSORS.md) page.

-

Development Tools provided with ♥ by

+

Development Tools & Plugins provided with ♥ by
JetBrains +Material Theme +

From b6d155687e4f61f076ff7302437444fa02a2e273 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Tue, 29 Mar 2022 13:29:35 -0700 Subject: [PATCH 123/213] feat: Adds account enumerator (#980) --- .../Accounting/Account.Migrations.cs | 6 +- Projects/UOContent/Accounting/Account.cs | 104 +++++++++++++----- .../Server.Accounting.Account.v4.json | 2 +- 3 files changed, 80 insertions(+), 32 deletions(-) diff --git a/Projects/UOContent/Accounting/Account.Migrations.cs b/Projects/UOContent/Accounting/Account.Migrations.cs index dd9148b01..e53d5c75f 100644 --- a/Projects/UOContent/Accounting/Account.Migrations.cs +++ b/Projects/UOContent/Accounting/Account.Migrations.cs @@ -18,7 +18,7 @@ namespace Server.Accounting _lastLogin = content.LastLogin; _totalGold = content.TotalGold; _totalPlat = content.TotalPlat; - _mobiles = content.Mobiles; + _rawMobiles = content.Mobiles; _comments = content.Comments; _tags = content.Tags; _loginIPs = content.LoginIPs; @@ -47,10 +47,10 @@ namespace Server.Accounting _totalPlat = reader.ReadInt(); var length = reader.ReadInt(); - _mobiles = new Mobile[length]; + _rawMobiles = new Mobile[length]; for (int i = 0; i < length; i++) { - _mobiles[i] = reader.ReadEntity(); + _rawMobiles[i] = reader.ReadEntity(); } length = reader.ReadInt(); diff --git a/Projects/UOContent/Accounting/Account.cs b/Projects/UOContent/Accounting/Account.cs index 81538bf8b..632597858 100644 --- a/Projects/UOContent/Accounting/Account.cs +++ b/Projects/UOContent/Accounting/Account.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Net; +using System.Runtime.CompilerServices; using System.Xml; using Server.Accounting.Security; using Server.Misc; @@ -55,7 +56,7 @@ namespace Server.Accounting public int _totalPlat; [SerializableField(8, "private", "private")] - private Mobile[] _mobiles; + private Mobile[] _rawMobiles; private List _comments; @@ -104,9 +105,9 @@ namespace Server.Accounting { get { - for (var i = 0; i < _mobiles.Length; i++) + for (var i = 0; i < _rawMobiles.Length; i++) { - if (_mobiles[i] is PlayerMobile m && m.NetState != null) + if (_rawMobiles[i] is PlayerMobile m && m.NetState != null) { return _totalGameTime + (Core.Now - m.SessionStart); } @@ -138,7 +139,7 @@ namespace Server.Accounting _lastLogin = Core.Now; _totalGameTime = TimeSpan.Zero; - _mobiles = new Mobile[7]; + _rawMobiles = new Mobile[7]; _ipRestrictions = Array.Empty(); _loginIPs = Array.Empty(); @@ -186,26 +187,26 @@ namespace Server.Accounting _totalGold = Utility.GetXMLInt32(Utility.GetText(node["totalGold"], "0"), 0); _totalPlat = Utility.GetXMLInt32(Utility.GetText(node["totalPlat"], "0"), 0); - _mobiles = LoadMobiles(node); + _rawMobiles = LoadMobiles(node); _comments = LoadComments(node); _tags = LoadTags(node); _loginIPs = LoadAddressList(node); _ipRestrictions = LoadAccessCheck(node); - for (var i = 0; i < _mobiles.Length; ++i) + for (var i = 0; i < _rawMobiles.Length; ++i) { - if (_mobiles[i] != null) + if (_rawMobiles[i] != null) { - _mobiles[i].Account = this; + _rawMobiles[i].Account = this; } } var totalGameTime = Utility.GetXMLTimeSpan(Utility.GetText(node["totalGameTime"], null), TimeSpan.Zero); if (totalGameTime == TimeSpan.Zero) { - for (var i = 0; i < _mobiles.Length; i++) + for (var i = 0; i < _rawMobiles.Length; i++) { - if (_mobiles[i] is PlayerMobile m) + if (_rawMobiles[i] is PlayerMobile m) { totalGameTime += m.GameTime; } @@ -331,19 +332,19 @@ namespace Server.Accounting _tags = null; } - for (var i = 0; i < _mobiles.Length; ++i) + for (var i = 0; i < _rawMobiles.Length; ++i) { - if (_mobiles[i] != null) + if (_rawMobiles[i] != null) { - _mobiles[i].Account = this; + _rawMobiles[i].Account = this; } } if (_totalGameTime == TimeSpan.Zero) { - for (var i = 0; i < _mobiles.Length; i++) + for (var i = 0; i < _rawMobiles.Length; i++) { - if (_mobiles[i] is PlayerMobile m) + if (_rawMobiles[i] is PlayerMobile m) { _totalGameTime += m.GameTime; } @@ -380,7 +381,7 @@ namespace Server.Accounting m.Delete(); m.Account = null; - _mobiles[i] = null; + _rawMobiles[i] = null; } if (_loginIPs.Length != 0 && AccountHandler.IPTable.ContainsKey(_loginIPs[0])) @@ -452,7 +453,7 @@ namespace Server.Accounting /// /// Gets the maximum amount of characters that this account can hold. /// - public int Length => _mobiles.Length; + public int Length => _rawMobiles.Length; /// /// Gets or sets the character at a specified index for this account. Out of bound index values are handled; null returned @@ -462,9 +463,9 @@ namespace Server.Accounting { get { - if (index >= 0 && index < _mobiles.Length) + if (index >= 0 && index < _rawMobiles.Length) { - var m = _mobiles[index]; + var m = _rawMobiles[index]; if (m?.Deleted != true) { @@ -474,7 +475,7 @@ namespace Server.Accounting // This is the only place that clears a mobile for garbage collection // outside of an entire account deletion. m.Account = null; - _mobiles[index] = null; + _rawMobiles[index] = null; this.MarkDirty(); } @@ -482,19 +483,19 @@ namespace Server.Accounting } set { - if (index >= 0 && index < _mobiles.Length) + if (index >= 0 && index < _rawMobiles.Length) { - if (_mobiles[index] != null) + if (_rawMobiles[index] != null) { - _mobiles[index].Account = null; + _rawMobiles[index].Account = null; } - _mobiles[index] = value; + _rawMobiles[index] = value; this.MarkDirty(); - if (_mobiles[index] != null) + if (_rawMobiles[index] != null) { - _mobiles[index].Account = this; + _rawMobiles[index].Account = this; } } } @@ -820,9 +821,9 @@ namespace Server.Accounting { Young = false; - for (var i = 0; i < _mobiles.Length; i++) + for (var i = 0; i < _rawMobiles.Length; i++) { - if (_mobiles[i] is PlayerMobile { Young: true } m) + if (_rawMobiles[i] is PlayerMobile { Young: true } m) { m.Young = false; @@ -1178,5 +1179,52 @@ namespace Server.Accounting m_Account.CheckYoung(); } } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Enumerator GetEnumerator() => new(_rawMobiles); + + public Enumerator Mobiles + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => GetEnumerator(); + } + + public ref struct Enumerator + { + private readonly Mobile[] _mobiles; + private int _index; + private Mobile _current; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal Enumerator(Mobile[] mobs) + { + _mobiles = mobs; + _index = 0; + _current = default; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool MoveNext() + { + Mobile[] localList = _mobiles; + + while ((uint)_index < (uint)localList.Length) + { + _current = _mobiles[_index++]; + if (_current?.Deleted == false) + { + return true; + } + } + + return false; + } + + public Mobile Current + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => _current; + } + } } } diff --git a/Projects/UOContent/Migrations/Server.Accounting.Account.v4.json b/Projects/UOContent/Migrations/Server.Accounting.Account.v4.json index 07d1336c7..887b06c08 100644 --- a/Projects/UOContent/Migrations/Server.Accounting.Account.v4.json +++ b/Projects/UOContent/Migrations/Server.Accounting.Account.v4.json @@ -61,7 +61,7 @@ ] }, { - "name": "Mobiles", + "name": "RawMobiles", "type": "Server.Mobile[]", "rule": "ArrayMigrationRule", "ruleArguments": [ From a5a54602912a0f68228a8546ef9d3d1e0691b69a Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Tue, 29 Mar 2022 15:08:23 -0700 Subject: [PATCH 124/213] fix: Fixes world save timer issue (#981) Fixes a major bug where a race condition could cause the timer wheel to have non-deterministic behavior and potentially never finish the save. --- Projects/Server/World/World.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Projects/Server/World/World.cs b/Projects/Server/World/World.cs index 1db4b3e30..119555733 100644 --- a/Projects/Server/World/World.cs +++ b/Projects/Server/World/World.cs @@ -431,7 +431,7 @@ namespace Server m_DiskWriteHandle.Set(); - Timer.StartTimer(FinishWorldSave); + Core.LoopContext.Post(FinishWorldSave); } private static void ProcessDecay() From 55a6589644cd8aa855e74ecf16eba128eefce85e Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Wed, 30 Mar 2022 13:14:29 -0700 Subject: [PATCH 125/213] fix: Fixes wrong point reference in building region (#982) --- Projects/Server/Regions/Region.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Projects/Server/Regions/Region.cs b/Projects/Server/Regions/Region.cs index 01054532d..3e9162979 100644 --- a/Projects/Server/Regions/Region.cs +++ b/Projects/Server/Regions/Region.cs @@ -331,7 +331,7 @@ namespace Server var rect = Area[i]; var start = Map.Bound(new Point2D(rect.Start.X, rect.Start.Y)); - var end = Map.Bound(new Point2D(rect.End.X, rect.Start.Y)); + var end = Map.Bound(new Point2D(rect.End.X, rect.End.Y)); var startSector = Map.GetSector(start); var endSector = Map.GetSector(end); From 9baa6f58e7f6c2eb9de7d272753ae2758c80138c Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Wed, 30 Mar 2022 19:42:38 -0700 Subject: [PATCH 126/213] fix: Codegens deeds (#983) --- .../Items/Armor/BaseArmor.Migrations.cs | 6 +- Projects/UOContent/Items/Armor/BaseArmor.cs | 4 +- .../Items/Clothing/BaseClothing.Migrations.cs | 6 +- .../UOContent/Items/Deeds/BarkeepContract.cs | 114 +++--- .../Items/Deeds/ClothingBlessDeed.cs | 139 +++---- .../UOContent/Items/Deeds/CommodityDeed.cs | 386 ++++++++---------- .../Items/Deeds/DragonBardingDeed.cs | 294 ++++++------- .../Items/Deeds/HairRestylingDeed.cs | 249 ++++++----- .../UOContent/Items/Deeds/HolidayTreeDeed.cs | 260 ++++++------ .../UOContent/Items/Deeds/NameChangeDeed.cs | 190 ++++----- .../UOContent/Items/Deeds/NewPlayerTicket.cs | 297 ++++++-------- .../Server.Items.BarkeepContract.v0.json | 4 + .../Server.Items.ClothingBlessDeed.v0.json | 4 + .../Server.Items.CommodityDeed.v1.json | 11 + .../Server.Items.DragonBardingDeed.v2.json | 27 ++ .../Server.Items.HairRestylingDeed.v0.json | 4 + .../Server.Items.HolidayTreeDeed.v0.json | 4 + .../Server.Items.NameChangeDeed.v0.json | 4 + .../Server.Items.NewPlayerTicket.v0.json | 11 + .../Mobiles/Animals/Mounts/SwampDragon.cs | 29 +- 20 files changed, 967 insertions(+), 1076 deletions(-) create mode 100644 Projects/UOContent/Migrations/Server.Items.BarkeepContract.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.ClothingBlessDeed.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.CommodityDeed.v1.json create mode 100644 Projects/UOContent/Migrations/Server.Items.DragonBardingDeed.v2.json create mode 100644 Projects/UOContent/Migrations/Server.Items.HairRestylingDeed.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.HolidayTreeDeed.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.NameChangeDeed.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.NewPlayerTicket.v0.json diff --git a/Projects/UOContent/Items/Armor/BaseArmor.Migrations.cs b/Projects/UOContent/Items/Armor/BaseArmor.Migrations.cs index 2e4906f52..de8904f0c 100644 --- a/Projects/UOContent/Items/Armor/BaseArmor.Migrations.cs +++ b/Projects/UOContent/Items/Armor/BaseArmor.Migrations.cs @@ -16,7 +16,8 @@ public partial class BaseArmor _identified = content.Identified; _maxHitPoints = content.MaxHitPoints ?? 0; _hitPoints = content.HitPoints ?? 0; - _crafter = content.Crafter?.RawName; // Convert from Mobile -> String via RawName + var crafter = content.Crafter; + Timer.StartTimer(() => _crafter = crafter?.RawName); _quality = content.Quality ?? ArmorQuality.Regular; _durability = content.Durability ?? ArmorDurabilityLevel.Regular; _rawResource = content.RawResource ?? DefaultResource; @@ -90,7 +91,8 @@ public partial class BaseArmor if (GetSaveFlag(flags, OldSaveFlag.Crafter)) { - _crafter = reader.ReadEntity()?.RawName; + var crafter = reader.ReadEntity(); + Timer.StartTimer(() => _crafter = crafter?.RawName); } if (GetSaveFlag(flags, OldSaveFlag.Quality)) diff --git a/Projects/UOContent/Items/Armor/BaseArmor.cs b/Projects/UOContent/Items/Armor/BaseArmor.cs index faba5062c..c306494b3 100644 --- a/Projects/UOContent/Items/Armor/BaseArmor.cs +++ b/Projects/UOContent/Items/Armor/BaseArmor.cs @@ -589,8 +589,8 @@ namespace Server.Items if (Quality == ArmorQuality.Exceptional) { - if (!(Core.ML && this is BaseShield) - ) // Guessed Core.ML removed exceptional resist bonuses from crafted shields + // Guessed Core.ML removed exceptional resist bonuses from crafted shields + if (!(Core.ML && this is BaseShield)) { DistributeBonuses( tool is BaseRunicTool ? 6 : diff --git a/Projects/UOContent/Items/Clothing/BaseClothing.Migrations.cs b/Projects/UOContent/Items/Clothing/BaseClothing.Migrations.cs index 1278b0db2..fe0902747 100644 --- a/Projects/UOContent/Items/Clothing/BaseClothing.Migrations.cs +++ b/Projects/UOContent/Items/Clothing/BaseClothing.Migrations.cs @@ -11,7 +11,8 @@ public partial class BaseClothing _resistances = content.Resistances ?? ResistancesDefaultValue(); _maxHitPoints = content.MaxHitPoints ?? 0; _playerConstructed = content.PlayerConstructed; - _crafter = content.Crafter?.RawName; // Convert from Mobile -> String via RawName + var crafter = content.Crafter; + Timer.StartTimer(() => _crafter = crafter?.RawName); _quality = content.Quality ?? ClothingQuality.Regular; _strReq = content.StrRequirement ?? -1; } @@ -70,7 +71,8 @@ public partial class BaseClothing if (GetSaveFlag(flags, OldSaveFlag.Crafter)) { - _crafter = reader.ReadEntity()?.RawName; + var crafter = reader.ReadEntity(); + Timer.StartTimer(() => _crafter = crafter?.RawName); } if (GetSaveFlag(flags, OldSaveFlag.Quality)) diff --git a/Projects/UOContent/Items/Deeds/BarkeepContract.cs b/Projects/UOContent/Items/Deeds/BarkeepContract.cs index 086088722..c1fa4b22c 100644 --- a/Projects/UOContent/Items/Deeds/BarkeepContract.cs +++ b/Projects/UOContent/Items/Deeds/BarkeepContract.cs @@ -2,96 +2,78 @@ using Server.Mobiles; using Server.Multis; using Server.Network; -namespace Server.Items +namespace Server.Items; + +[Serializable(0, false)] +public partial class BarkeepContract : Item { - public class BarkeepContract : Item + [Constructible] + public BarkeepContract() : base(0x14F0) { - [Constructible] - public BarkeepContract() : base(0x14F0) + Weight = 1.0; + LootType = LootType.Blessed; + } + + public override string DefaultName => "a barkeep contract"; + + public override void OnDoubleClick(Mobile from) + { + if (!IsChildOf(from.Backpack)) { - Weight = 1.0; - LootType = LootType.Blessed; + from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it. } - - public BarkeepContract(Serial serial) : base(serial) + else if (from.AccessLevel >= AccessLevel.GameMaster) { + from.SendLocalizedMessage(503248); // Your godly powers allow you to place this vendor whereever you wish. + + Mobile v = new PlayerBarkeeper(from, BaseHouse.FindHouseAt(from)); + + v.Direction = from.Direction & Direction.Mask; + v.MoveToWorld(from.Location, from.Map); + + Delete(); } - - public override string DefaultName => "a barkeep contract"; - - public override void Serialize(IGenericWriter writer) + else { - base.Serialize(writer); + var house = BaseHouse.FindHouseAt(from); - writer.Write(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - - public override void OnDoubleClick(Mobile from) - { - if (!IsChildOf(from.Backpack)) + if (house?.IsOwner(from) != true) { - from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it. + from.LocalOverheadMessage( + MessageType.Regular, + 0x3B2, + false, + "You are not the full owner of this house." + ); } - else if (from.AccessLevel >= AccessLevel.GameMaster) + else if (!house.CanPlaceNewBarkeep()) { - from.SendLocalizedMessage(503248); // Your godly powers allow you to place this vendor whereever you wish. - - Mobile v = new PlayerBarkeeper(from, BaseHouse.FindHouseAt(from)); - - v.Direction = from.Direction & Direction.Mask; - v.MoveToWorld(from.Location, from.Map); - - Delete(); + from.SendLocalizedMessage( + 1062490 + ); // That action would exceed the maximum number of barkeeps for this house. } else { - var house = BaseHouse.FindHouseAt(from); + BaseHouse.IsThereVendor(from.Location, from.Map, out var vendor, out var contract); - if (house?.IsOwner(from) != true) + if (vendor) { - from.LocalOverheadMessage( - MessageType.Regular, - 0x3B2, - false, - "You are not the full owner of this house." - ); + from.SendLocalizedMessage(1062677); // You cannot place a vendor or barkeep at this location. } - else if (!house.CanPlaceNewBarkeep()) + else if (contract) { from.SendLocalizedMessage( - 1062490 - ); // That action would exceed the maximum number of barkeeps for this house. + 1062678 + ); // You cannot place a vendor or barkeep on top of a rental contract! } else { - BaseHouse.IsThereVendor(from.Location, from.Map, out var vendor, out var contract); + Mobile v = new PlayerBarkeeper(from, house); - if (vendor) - { - from.SendLocalizedMessage(1062677); // You cannot place a vendor or barkeep at this location. - } - else if (contract) - { - from.SendLocalizedMessage( - 1062678 - ); // You cannot place a vendor or barkeep on top of a rental contract! - } - else - { - Mobile v = new PlayerBarkeeper(from, house); + v.Direction = from.Direction & Direction.Mask; + v.MoveToWorld(from.Location, from.Map); - v.Direction = from.Direction & Direction.Mask; - v.MoveToWorld(from.Location, from.Map); - - Delete(); - } + Delete(); } } } diff --git a/Projects/UOContent/Items/Deeds/ClothingBlessDeed.cs b/Projects/UOContent/Items/Deeds/ClothingBlessDeed.cs index 598c17bab..cb6186600 100644 --- a/Projects/UOContent/Items/Deeds/ClothingBlessDeed.cs +++ b/Projects/UOContent/Items/Deeds/ClothingBlessDeed.cs @@ -1,99 +1,80 @@ using Server.Targeting; -namespace Server.Items +namespace Server.Items; + +public class ClothingBlessTarget : Target // Create our targeting class (which we derive from the base target class) { - public class ClothingBlessTarget : Target // Create our targeting class (which we derive from the base target class) + private readonly ClothingBlessDeed m_Deed; + + public ClothingBlessTarget(ClothingBlessDeed deed) : base(1, false, TargetFlags.None) => m_Deed = deed; + + protected override void OnTarget(Mobile from, object target) // Override the protected OnTarget() for our feature { - private readonly ClothingBlessDeed m_Deed; - - public ClothingBlessTarget(ClothingBlessDeed deed) : base(1, false, TargetFlags.None) => m_Deed = deed; - - protected override void OnTarget(Mobile from, object target) // Override the protected OnTarget() for our feature + if (m_Deed.Deleted || m_Deed.RootParent != from) { - if (m_Deed.Deleted || m_Deed.RootParent != from) + return; + } + + if (target is BaseClothing item) + { + if ((item as IArcaneEquip)?.IsArcane == true) { + from.SendLocalizedMessage(1005019); // This bless deed is for Clothes only. return; } - if (target is BaseClothing item) + // Check if its already newbied (blessed) + if (item.LootType == LootType.Blessed || item.BlessedFor == from || Mobile.InsuranceEnabled && item.Insured) { - if ((item as IArcaneEquip)?.IsArcane == true) - { - from.SendLocalizedMessage(1005019); // This bless deed is for Clothes only. - return; - } - - if (item.LootType == LootType.Blessed || item.BlessedFor == from || Mobile.InsuranceEnabled && item.Insured - ) // Check if its already newbied (blessed) - { - from.SendLocalizedMessage(1045113); // That item is already blessed - } - else if (item.LootType != LootType.Regular) - { - from.SendLocalizedMessage(1045114); // You can not bless that item - } - else if (!item.CanBeBlessed || item.RootParent != from) - { - from.SendLocalizedMessage(500509); // You cannot bless that object - } - else - { - item.LootType = LootType.Blessed; - from.SendLocalizedMessage(1010026); // You bless the item.... - - m_Deed.Delete(); // Delete the bless deed - } + from.SendLocalizedMessage(1045113); // That item is already blessed } - else + else if (item.LootType != LootType.Regular) + { + from.SendLocalizedMessage(1045114); // You can not bless that item + } + else if (!item.CanBeBlessed || item.RootParent != from) { from.SendLocalizedMessage(500509); // You cannot bless that object } - } - } - - public class ClothingBlessDeed : Item // Create the item class which is derived from the base item class - { - [Constructible] - public ClothingBlessDeed() : base(0x14F0) - { - Weight = 1.0; - LootType = LootType.Blessed; - } - - public ClothingBlessDeed(Serial serial) : base(serial) - { - } - - public override string DefaultName => "a clothing bless deed"; - - public override bool DisplayLootType => false; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - LootType = LootType.Blessed; - - var version = reader.ReadInt(); - } - - public override void OnDoubleClick(Mobile from) // Override double click of the deed to call our target - { - if (!IsChildOf(from.Backpack)) // Make sure its in their pack - { - from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it. - } else { - from.SendLocalizedMessage(1005018); // What would you like to bless? (Clothes Only) - from.Target = new ClothingBlessTarget(this); // Call our target + item.LootType = LootType.Blessed; + from.SendLocalizedMessage(1010026); // You bless the item.... + + m_Deed.Delete(); // Delete the bless deed } } + else + { + from.SendLocalizedMessage(500509); // You cannot bless that object + } + } +} + +[Serializable(0, false)] +public partial class ClothingBlessDeed : Item // Create the item class which is derived from the base item class +{ + [Constructible] + public ClothingBlessDeed() : base(0x14F0) + { + Weight = 1.0; + LootType = LootType.Blessed; + } + + public override string DefaultName => "a clothing bless deed"; + + public override bool DisplayLootType => false; + + public override void OnDoubleClick(Mobile from) // Override double click of the deed to call our target + { + if (!IsChildOf(from.Backpack)) // Make sure its in their pack + { + from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it. + } + else + { + from.SendLocalizedMessage(1005018); // What would you like to bless? (Clothes Only) + from.Target = new ClothingBlessTarget(this); // Call our target + } } } diff --git a/Projects/UOContent/Items/Deeds/CommodityDeed.cs b/Projects/UOContent/Items/Deeds/CommodityDeed.cs index 5133f2b3c..3aa141533 100644 --- a/Projects/UOContent/Items/Deeds/CommodityDeed.cs +++ b/Projects/UOContent/Items/Deeds/CommodityDeed.cs @@ -1,183 +1,209 @@ using Server.Targeting; -namespace Server.Items +namespace Server.Items; + +public interface ICommodity /* added IsDeedable prop so expansion-based deedables can determine true/false */ { - public interface ICommodity /* added IsDeedable prop so expansion-based deedables can determine true/false */ + int DescriptionNumber { get; } + bool IsDeedable { get; } +} + +[Serializable(1, false)] +public partial class CommodityDeed : Item +{ + [SerializableField(0, setter: "private")] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + public Item _commodity; + + [Constructible] + public CommodityDeed(Item commodity = null) : base(0x14F0) { - int DescriptionNumber { get; } - bool IsDeedable { get; } + Weight = 1.0; + Hue = 0x47; + + Commodity = commodity; + + LootType = LootType.Blessed; } - public class CommodityDeed : Item + public override int LabelNumber => Commodity == null ? 1047016 : 1047017; + + public bool SetCommodity(Item item) { - [Constructible] - public CommodityDeed(Item commodity = null) : base(0x14F0) - { - Weight = 1.0; - Hue = 0x47; - - Commodity = commodity; - - LootType = LootType.Blessed; - } - - public CommodityDeed(Serial serial) : base(serial) - { - } - - [CommandProperty(AccessLevel.GameMaster)] - public Item Commodity { get; private set; } - - public override int LabelNumber => Commodity == null ? 1047016 : 1047017; - - public bool SetCommodity(Item item) + InvalidateProperties(); + + if (Commodity == null && (item as ICommodity)?.IsDeedable == true) { + Commodity = item; + Commodity.Internalize(); InvalidateProperties(); - if (Commodity == null && (item as ICommodity)?.IsDeedable == true) - { - Commodity = item; - Commodity.Internalize(); - InvalidateProperties(); + return true; + } - return true; + return false; + } + + private void Deserialize(IGenericReader reader, int version) + { + Commodity = reader.ReadEntity(); + + if (Commodity != null) + { + Hue = 0x592; + } + } + + public override void OnDelete() + { + Commodity?.Delete(); + + base.OnDelete(); + } + + public override void GetProperties(ObjectPropertyList list) + { + base.GetProperties(list); + + if (Commodity != null) + { + var args = Commodity.Name == null + ? $"#{(Commodity as ICommodity)?.DescriptionNumber ?? Commodity.LabelNumber}\t{Commodity.Amount}" + : $"{Commodity.Name}\t{Commodity.Amount}"; + + list.Add(1060658, args); // ~1_val~: ~2_val~ + } + else + { + list.Add(1060748); // unfilled + } + } + + public override void OnSingleClick(Mobile from) + { + base.OnSingleClick(from); + + if (Commodity != null) + { + var args = Commodity.Name == null + ? $"#{(Commodity as ICommodity)?.DescriptionNumber ?? Commodity.LabelNumber}\t{Commodity.Amount}" + : $"{Commodity.Name}\t{Commodity.Amount}"; + + LabelTo(from, 1060658, args); // ~1_val~: ~2_val~ + } + } + + public override void OnDoubleClick(Mobile from) + { + int number; + + var box = from.FindBankNoCreate(); + var cox = CommodityDeedBox.Find(this); + + // Veteran Rewards mods + if (Commodity != null) + { + if (box != null && IsChildOf(box)) + { + number = 1047031; // The commodity has been redeemed. + + box.DropItem(Commodity); + + Commodity = null; + Delete(); } - - return false; - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(1); // version - - writer.Write(Commodity); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - Commodity = reader.ReadEntity(); - - switch (version) + else if (cox != null) { - case 0: - { - if (Commodity != null) - { - Hue = 0x592; - } - - break; - } - } - } - - public override void OnDelete() - { - Commodity?.Delete(); - - base.OnDelete(); - } - - public override void GetProperties(ObjectPropertyList list) - { - base.GetProperties(list); - - if (Commodity != null) - { - var args = Commodity.Name == null - ? $"#{(Commodity is ICommodity commodity ? commodity.DescriptionNumber : Commodity.LabelNumber)}\t{Commodity.Amount}" - : $"{Commodity.Name}\t{Commodity.Amount}"; - - list.Add(1060658, args); // ~1_val~: ~2_val~ - } - else - { - list.Add(1060748); // unfilled - } - } - - public override void OnSingleClick(Mobile from) - { - base.OnSingleClick(from); - - if (Commodity != null) - { - string args; - - if (Commodity.Name == null) - { - args = - $"#{(Commodity is ICommodity commodity ? commodity.DescriptionNumber : Commodity.LabelNumber)}\t{Commodity.Amount}"; - } - else - { - args = $"{Commodity.Name}\t{Commodity.Amount}"; - } - - LabelTo(from, 1060658, args); // ~1_val~: ~2_val~ - } - } - - public override void OnDoubleClick(Mobile from) - { - int number; - - var box = from.FindBankNoCreate(); - var cox = CommodityDeedBox.Find(this); - - // Veteran Rewards mods - if (Commodity != null) - { - if (box != null && IsChildOf(box)) + if (cox.IsSecure) { number = 1047031; // The commodity has been redeemed. - box.DropItem(Commodity); + cox.DropItem(Commodity); Commodity = null; Delete(); } - else if (cox != null) + else { - if (cox.IsSecure) - { - number = 1047031; // The commodity has been redeemed. - - cox.DropItem(Commodity); - - Commodity = null; - Delete(); - } - else - { - number = 1080525; // The commodity deed box must be secured before you can use it. - } + number = 1080525; // The commodity deed box must be secured before you can use it. + } + } + else + { + if (Core.ML) + { + number = 1080526; // That must be in your bank box or commodity deed box to use it. } else { - if (Core.ML) + number = 1047024; // To claim the resources .... + } + } + } + else if (cox?.IsSecure == false) + { + number = 1080525; // The commodity deed box must be secured before you can use it. + } + else if ((box == null || !IsChildOf(box)) && cox == null) + { + if (Core.ML) + { + number = 1080526; // That must be in your bank box or commodity deed box to use it. + } + else + { + number = 1047026; // That must be in your bank box to use it. + } + } + else + { + number = 1047029; // Target the commodity to fill this deed with. + + from.Target = new InternalTarget(this); + } + + from.SendLocalizedMessage(number); + } + + private class InternalTarget : Target + { + private readonly CommodityDeed m_Deed; + + public InternalTarget(CommodityDeed deed) : base(3, false, TargetFlags.None) => m_Deed = deed; + + protected override void OnTarget(Mobile from, object targeted) + { + if (m_Deed.Deleted) + { + return; + } + + int number; + + if (m_Deed.Commodity != null) + { + number = 1047028; // The commodity deed has already been filled. + } + else if (targeted is Item item) + { + var box = from.FindBankNoCreate(); + var cox = CommodityDeedBox.Find(m_Deed); + + // Veteran Rewards mods + if (box != null && m_Deed.IsChildOf(box) && item.IsChildOf(box) || + cox?.IsSecure != true && item.IsChildOf(cox)) + { + if (m_Deed.SetCommodity(item)) { - number = 1080526; // That must be in your bank box or commodity deed box to use it. + m_Deed.Hue = 0x592; + number = 1047030; // The commodity deed has been filled. } else { - number = 1047024; // To claim the resources .... + number = 1047027; // That is not a commodity the bankers will fill a commodity deed with. } } - } - else if (cox?.IsSecure == false) - { - number = 1080525; // The commodity deed box must be secured before you can use it. - } - else if ((box == null || !IsChildOf(box)) && cox == null) - { - if (Core.ML) + else if (Core.ML) { number = 1080526; // That must be in your bank box or commodity deed box to use it. } @@ -188,68 +214,10 @@ namespace Server.Items } else { - number = 1047029; // Target the commodity to fill this deed with. - - from.Target = new InternalTarget(this); + number = 1047027; // That is not a commodity the bankers will fill a commodity deed with. } from.SendLocalizedMessage(number); } - - private class InternalTarget : Target - { - private readonly CommodityDeed m_Deed; - - public InternalTarget(CommodityDeed deed) : base(3, false, TargetFlags.None) => m_Deed = deed; - - protected override void OnTarget(Mobile from, object targeted) - { - if (m_Deed.Deleted) - { - return; - } - - int number; - - if (m_Deed.Commodity != null) - { - number = 1047028; // The commodity deed has already been filled. - } - else if (targeted is Item item) - { - var box = from.FindBankNoCreate(); - var cox = CommodityDeedBox.Find(m_Deed); - - // Veteran Rewards mods - if (box != null && m_Deed.IsChildOf(box) && item.IsChildOf(box) || - cox?.IsSecure != true && item.IsChildOf(cox)) - { - if (m_Deed.SetCommodity(item)) - { - m_Deed.Hue = 0x592; - number = 1047030; // The commodity deed has been filled. - } - else - { - number = 1047027; // That is not a commodity the bankers will fill a commodity deed with. - } - } - else if (Core.ML) - { - number = 1080526; // That must be in your bank box or commodity deed box to use it. - } - else - { - number = 1047026; // That must be in your bank box to use it. - } - } - else - { - number = 1047027; // That is not a commodity the bankers will fill a commodity deed with. - } - - from.SendLocalizedMessage(number); - } - } } } diff --git a/Projects/UOContent/Items/Deeds/DragonBardingDeed.cs b/Projects/UOContent/Items/Deeds/DragonBardingDeed.cs index cf3e814a4..75840190b 100644 --- a/Projects/UOContent/Items/Deeds/DragonBardingDeed.cs +++ b/Projects/UOContent/Items/Deeds/DragonBardingDeed.cs @@ -3,176 +3,136 @@ using Server.Engines.Craft; using Server.Mobiles; using Server.Targeting; -namespace Server.Items +namespace Server.Items; + +[TypeAlias("Server.Items.DragonBarding")] +[Serializable(2, false)] +public partial class DragonBardingDeed : Item, ICraftable { - [TypeAlias("Server.Items.DragonBarding")] - public class DragonBardingDeed : Item, ICraftable + [InvalidateProperties] + [SerializableField(0)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private string _craftedBy; + + [InvalidateProperties] + [SerializableField(1)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private bool _exceptional; + + [SerializableField(2, "private", "private")] + private CraftResource _rawResource; + + public DragonBardingDeed() : base(0x14F0) => Weight = 1.0; + + public override int LabelNumber => _exceptional ? 1053181 : 1053012; // dragon barding deed + + [CommandProperty(AccessLevel.GameMaster)] + public CraftResource Resource { - private Mobile m_Crafter; - private bool m_Exceptional; - private CraftResource m_Resource; - - public DragonBardingDeed() : base(0x14F0) => Weight = 1.0; - - public DragonBardingDeed(Serial serial) : base(serial) + get => _rawResource; + set { - } - - public override int LabelNumber => m_Exceptional ? 1053181 : 1053012; // dragon barding deed - - [CommandProperty(AccessLevel.GameMaster)] - public Mobile Crafter - { - get => m_Crafter; - set - { - m_Crafter = value; - InvalidateProperties(); - } - } - - [CommandProperty(AccessLevel.GameMaster)] - public bool Exceptional - { - get => m_Exceptional; - set - { - m_Exceptional = value; - InvalidateProperties(); - } - } - - [CommandProperty(AccessLevel.GameMaster)] - public CraftResource Resource - { - get => m_Resource; - set - { - m_Resource = value; - Hue = CraftResources.GetHue(value); - InvalidateProperties(); - } - } - - public int OnCraft( - int quality, bool makersMark, Mobile from, CraftSystem craftSystem, Type typeRes, BaseTool tool, - CraftItem craftItem, int resHue - ) - { - Exceptional = quality >= 2; - - if (makersMark) - { - Crafter = from; - } - - var resourceType = typeRes ?? craftItem.Resources[0].ItemType; - - Resource = CraftResources.GetFromType(resourceType); - - var context = craftSystem.GetContext(from); - - if (context?.DoNotColor == true) - { - Hue = 0; - } - - return quality; - } - - public override void GetProperties(ObjectPropertyList list) - { - base.GetProperties(list); - - if (m_Exceptional && m_Crafter != null) - { - list.Add(1050043, m_Crafter.Name); // crafted by ~1_NAME~ - } - } - - public override void OnDoubleClick(Mobile from) - { - if (IsChildOf(from.Backpack)) - { - from.BeginTarget(6, false, TargetFlags.None, OnTarget); - from.SendLocalizedMessage(1053024); // Select the swamp dragon you wish to place the barding on. - } - else - { - from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it. - } - } - - public virtual void OnTarget(Mobile from, object obj) - { - if (Deleted) - { - return; - } - - if (obj is not SwampDragon pet || pet.HasBarding) - { - from.SendLocalizedMessage(1053025); // That is not an unarmored swamp dragon. - } - else if (!pet.Controlled || pet.ControlMaster != from) - { - from.SendLocalizedMessage(1053026); // You can only put barding on a tamed swamp dragon that you own. - } - else if (!IsChildOf(from.Backpack)) - { - from.SendLocalizedMessage(1060640); // The item must be in your backpack to use it. - } - else - { - pet.BardingExceptional = Exceptional; - pet.BardingCrafter = Crafter; - pet.BardingHP = pet.BardingMaxHP; - pet.BardingResource = Resource; - pet.HasBarding = true; - pet.Hue = Hue; - - Delete(); - - from.SendLocalizedMessage( - 1053027 - ); // You place the barding on your swamp dragon. Use a bladed item on your dragon to remove the armor. - } - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(1); // version - - writer.Write(m_Exceptional); - writer.Write(m_Crafter); - writer.Write((int)m_Resource); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - switch (version) - { - case 1: - case 0: - { - m_Exceptional = reader.ReadBool(); - m_Crafter = reader.ReadEntity(); - - if (version < 1) - { - reader.ReadInt(); - } - - m_Resource = (CraftResource)reader.ReadInt(); - break; - } - } + _rawResource = value; + Hue = CraftResources.GetHue(value); + InvalidateProperties(); } } + + public int OnCraft( + int quality, bool makersMark, Mobile from, CraftSystem craftSystem, Type typeRes, BaseTool tool, + CraftItem craftItem, int resHue + ) + { + Exceptional = quality >= 2; + + if (makersMark) + { + CraftedBy = from?.RawName; + } + + var resourceType = typeRes ?? craftItem.Resources[0].ItemType; + + Resource = CraftResources.GetFromType(resourceType); + + var context = craftSystem.GetContext(from); + + if (context?.DoNotColor == true) + { + Hue = 0; + } + + return quality; + } + + public override void GetProperties(ObjectPropertyList list) + { + base.GetProperties(list); + + if (_exceptional && _craftedBy != null) + { + list.Add(1050043, _craftedBy); // crafted by ~1_NAME~ + } + } + + public override void OnDoubleClick(Mobile from) + { + if (IsChildOf(from.Backpack)) + { + from.BeginTarget(6, false, TargetFlags.None, OnTarget); + from.SendLocalizedMessage(1053024); // Select the swamp dragon you wish to place the barding on. + } + else + { + from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it. + } + } + + public virtual void OnTarget(Mobile from, object obj) + { + if (Deleted) + { + return; + } + + if (obj is not SwampDragon pet || pet.HasBarding) + { + from.SendLocalizedMessage(1053025); // That is not an unarmored swamp dragon. + } + else if (!pet.Controlled || pet.ControlMaster != from) + { + from.SendLocalizedMessage(1053026); // You can only put barding on a tamed swamp dragon that you own. + } + else if (!IsChildOf(from.Backpack)) + { + from.SendLocalizedMessage(1060640); // The item must be in your backpack to use it. + } + else + { + pet.BardingExceptional = Exceptional; + pet.BardingCraftedBy = _craftedBy; + pet.BardingHP = pet.BardingMaxHP; + pet.BardingResource = Resource; + pet.HasBarding = true; + pet.Hue = Hue; + + Delete(); + + // You place the barding on your swamp dragon. Use a bladed item on your dragon to remove the armor. + from.SendLocalizedMessage(1053027); + } + } + + private void Deserialize(IGenericReader reader, int version) + { + _exceptional = reader.ReadBool(); + var crafter = reader.ReadEntity(); + Timer.StartTimer(() => _craftedBy = crafter?.RawName); + + if (version < 1) + { + reader.ReadInt(); + } + + _rawResource = (CraftResource)reader.ReadInt(); + } } diff --git a/Projects/UOContent/Items/Deeds/HairRestylingDeed.cs b/Projects/UOContent/Items/Deeds/HairRestylingDeed.cs index 847536294..e87eb7d1d 100644 --- a/Projects/UOContent/Items/Deeds/HairRestylingDeed.cs +++ b/Projects/UOContent/Items/Deeds/HairRestylingDeed.cs @@ -2,163 +2,146 @@ using Server.Gumps; using Server.Mobiles; using Server.Network; -namespace Server.Items +namespace Server.Items; + +[Serializable(0, false)] +public partial class HairRestylingDeed : Item { - public class HairRestylingDeed : Item + [Constructible] + public HairRestylingDeed() : base(0x14F0) { - [Constructible] - public HairRestylingDeed() : base(0x14F0) + Weight = 1.0; + LootType = LootType.Blessed; + } + + public override int LabelNumber => 1041061; // a coupon for a free hair restyling + + public override void OnDoubleClick(Mobile from) + { + if (!IsChildOf(from.Backpack)) { - Weight = 1.0; - LootType = LootType.Blessed; + from.SendLocalizedMessage(1042001); // That must be in your pack... } - - public HairRestylingDeed(Serial serial) : base(serial) + else { + from.SendGump(new InternalGump(from, this)); } + } - public override int LabelNumber => 1041061; // a coupon for a free hair restyling - - public override void Serialize(IGenericWriter writer) + private class InternalGump : Gump + { + private static readonly int[][] ElvenArray = { - base.Serialize(writer); + new[] { 0 }, + new[] { 1011064, 1011064, 0, 0, 0, 0 }, // bald + new[] { 1074386, 1074386, 0x2fc0, 0x2fc0, 0xedf5, 0xc6e5 }, // long feather + new[] { 1074387, 1074387, 0x2fc1, 0x2fc1, 0xedf6, 0xc6e6 }, // short + new[] { 1074388, 1074388, 0x2fc2, 0x2fc2, 0xedf7, 0xc6e7 }, // mullet + new[] { 1074391, 1074391, 0x2fce, 0x2fce, 0xeddc, 0xc6cc }, // knob + new[] { 1074392, 1074392, 0x2fcf, 0x2fcf, 0xeddd, 0xc6cd }, // braided + new[] { 1074394, 1074394, 0x2fd1, 0x2fd1, 0xeddf, 0xc6cf }, // spiked + new[] { 1074389, 1074385, 0x2fcc, 0x2fbf, 0xedda, 0xc6e4 }, // flower, mid-long + new[] { 1074393, 1074390, 0x2fd0, 0x2fcd, 0xedde, 0xc6cb } // buns, long + }; - writer.Write(0); // version - } - - public override void Deserialize(IGenericReader reader) + /* + racial arrays are: cliloc_F, cliloc_M, ItemID_F, ItemID_M, gump_img_F, gump_img_M + */ + private static readonly int[][] HumanArray = /* why on earth cant these utilities be consistent with hex/dec */ { - base.Deserialize(reader); - var version = reader.ReadInt(); - } + new[] { 0 }, + new[] { 1011064, 1011064, 0, 0, 0, 0 }, // bald + new[] { 1011052, 1011052, 0x203B, 0x203B, 0xed1c, 0xC60C }, // Short + new[] { 1011053, 1011053, 0x203C, 0x203C, 0xed1d, 0xc60d }, // Long + new[] { 1011054, 1011054, 0x203D, 0x203D, 0xed1e, 0xc60e }, // Ponytail + new[] { 1011055, 1011055, 0x2044, 0x2044, 0xed27, 0xC60F }, // Mohawk + new[] { 1011047, 1011047, 0x2045, 0x2045, 0xED26, 0xED26 }, // Pageboy + new[] { 1074393, 1011048, 0x2046, 0x2048, 0xed28, 0xEDE5 }, // Buns, Receding + new[] { 1011049, 1011049, 0x2049, 0x2049, 0xede6, 0xede6 }, // 2-tails + new[] { 1011050, 1011050, 0x204A, 0x204A, 0xED29, 0xED29 }, // Topknot + new[] { 1011396, 1011396, 0x2047, 0x2047, 0xed25, 0xc618 } // Curly + }; - public override void OnDoubleClick(Mobile from) + /* + gump data: bgX, bgY, htmlX, htmlY, imgX, imgY, butX, butY + */ + private static readonly int[][] LayoutArray = { - if (!IsChildOf(from.Backpack)) + new[] { 0 }, /* padding: its more efficient than code to ++ the index/buttonid */ + new[] { 425, 280, 342, 295, 000, 000, 310, 292 }, + new[] { 235, 060, 150, 075, 168, 020, 118, 073 }, + new[] { 235, 115, 150, 130, 168, 070, 118, 128 }, + new[] { 235, 170, 150, 185, 168, 130, 118, 183 }, + new[] { 235, 225, 150, 240, 168, 185, 118, 238 }, + new[] { 425, 060, 342, 075, 358, 018, 310, 073 }, + new[] { 425, 115, 342, 130, 358, 075, 310, 128 }, + new[] { 425, 170, 342, 185, 358, 125, 310, 183 }, + new[] { 425, 225, 342, 240, 358, 185, 310, 238 }, + new[] { 235, 280, 150, 295, 168, 245, 118, 292 } // slot 10, Curly - N/A for elfs. + }; + + private readonly HairRestylingDeed m_Deed; + private readonly Mobile m_From; + + public InternalGump(Mobile from, HairRestylingDeed deed) : base(50, 50) + { + m_From = from; + m_Deed = deed; + + from.CloseGump(); + + AddBackground(100, 10, 400, 385, 0xA28); + + AddHtmlLocalized(100, 25, 400, 35, 1013008); + AddButton(175, 340, 0xFA5, 0xFA7, 0x0); // CANCEL + + AddHtmlLocalized(210, 342, 90, 35, 1011012); //
HAIRSTYLE SELECTION MENU
+ + var RacialData = from.Race == Race.Human ? HumanArray : ElvenArray; + + for (var i = 1; i < RacialData.Length; i++) { - from.SendLocalizedMessage(1042001); // That must be in your pack... - } - else - { - from.SendGump(new InternalGump(from, this)); + AddHtmlLocalized( + LayoutArray[i][2], + LayoutArray[i][3], + i == 1 ? 125 : 80, + i == 1 ? 70 : 35, + m_From.Female ? RacialData[i][0] : RacialData[i][1] + ); + if (LayoutArray[i][4] != 0) + { + AddBackground(LayoutArray[i][0], LayoutArray[i][1], 50, 50, 0xA3C); + AddImage(LayoutArray[i][4], LayoutArray[i][5], m_From.Female ? RacialData[i][4] : RacialData[i][5]); + } + + AddButton(LayoutArray[i][6], LayoutArray[i][7], 0xFA5, 0xFA7, i); } } - private class InternalGump : Gump + public override void OnResponse(NetState sender, RelayInfo info) { - private static readonly int[][] ElvenArray = + if (m_From?.Alive != true) { - new[] { 0 }, - new[] { 1011064, 1011064, 0, 0, 0, 0 }, // bald - new[] { 1074386, 1074386, 0x2fc0, 0x2fc0, 0xedf5, 0xc6e5 }, // long feather - new[] { 1074387, 1074387, 0x2fc1, 0x2fc1, 0xedf6, 0xc6e6 }, // short - new[] { 1074388, 1074388, 0x2fc2, 0x2fc2, 0xedf7, 0xc6e7 }, // mullet - new[] { 1074391, 1074391, 0x2fce, 0x2fce, 0xeddc, 0xc6cc }, // knob - new[] { 1074392, 1074392, 0x2fcf, 0x2fcf, 0xeddd, 0xc6cd }, // braided - new[] { 1074394, 1074394, 0x2fd1, 0x2fd1, 0xeddf, 0xc6cf }, // spiked - new[] { 1074389, 1074385, 0x2fcc, 0x2fbf, 0xedda, 0xc6e4 }, // flower, mid-long - new[] { 1074393, 1074390, 0x2fd0, 0x2fcd, 0xedde, 0xc6cb } // buns, long - }; - - /* - racial arrays are: cliloc_F, cliloc_M, ItemID_F, ItemID_M, gump_img_F, gump_img_M - */ - private static readonly int[][] HumanArray = /* why on earth cant these utilities be consistent with hex/dec */ - { - new[] { 0 }, - new[] { 1011064, 1011064, 0, 0, 0, 0 }, // bald - new[] { 1011052, 1011052, 0x203B, 0x203B, 0xed1c, 0xC60C }, // Short - new[] { 1011053, 1011053, 0x203C, 0x203C, 0xed1d, 0xc60d }, // Long - new[] { 1011054, 1011054, 0x203D, 0x203D, 0xed1e, 0xc60e }, // Ponytail - new[] { 1011055, 1011055, 0x2044, 0x2044, 0xed27, 0xC60F }, // Mohawk - new[] { 1011047, 1011047, 0x2045, 0x2045, 0xED26, 0xED26 }, // Pageboy - new[] { 1074393, 1011048, 0x2046, 0x2048, 0xed28, 0xEDE5 }, // Buns, Receding - new[] { 1011049, 1011049, 0x2049, 0x2049, 0xede6, 0xede6 }, // 2-tails - new[] { 1011050, 1011050, 0x204A, 0x204A, 0xED29, 0xED29 }, // Topknot - new[] { 1011396, 1011396, 0x2047, 0x2047, 0xed25, 0xc618 } // Curly - }; - - /* - gump data: bgX, bgY, htmlX, htmlY, imgX, imgY, butX, butY - */ - private static readonly int[][] LayoutArray = - { - new[] { 0 }, /* padding: its more efficient than code to ++ the index/buttonid */ - new[] { 425, 280, 342, 295, 000, 000, 310, 292 }, - new[] { 235, 060, 150, 075, 168, 020, 118, 073 }, - new[] { 235, 115, 150, 130, 168, 070, 118, 128 }, - new[] { 235, 170, 150, 185, 168, 130, 118, 183 }, - new[] { 235, 225, 150, 240, 168, 185, 118, 238 }, - new[] { 425, 060, 342, 075, 358, 018, 310, 073 }, - new[] { 425, 115, 342, 130, 358, 075, 310, 128 }, - new[] { 425, 170, 342, 185, 358, 125, 310, 183 }, - new[] { 425, 225, 342, 240, 358, 185, 310, 238 }, - new[] { 235, 280, 150, 295, 168, 245, 118, 292 } // slot 10, Curly - N/A for elfs. - }; - - private readonly HairRestylingDeed m_Deed; - private readonly Mobile m_From; - - public InternalGump(Mobile from, HairRestylingDeed deed) : base(50, 50) - { - m_From = from; - m_Deed = deed; - - from.CloseGump(); - - AddBackground(100, 10, 400, 385, 0xA28); - - AddHtmlLocalized(100, 25, 400, 35, 1013008); - AddButton(175, 340, 0xFA5, 0xFA7, 0x0); // CANCEL - - AddHtmlLocalized(210, 342, 90, 35, 1011012); //
HAIRSTYLE SELECTION MENU
- - var RacialData = from.Race == Race.Human ? HumanArray : ElvenArray; - - for (var i = 1; i < RacialData.Length; i++) - { - AddHtmlLocalized( - LayoutArray[i][2], - LayoutArray[i][3], - i == 1 ? 125 : 80, - i == 1 ? 70 : 35, - m_From.Female ? RacialData[i][0] : RacialData[i][1] - ); - if (LayoutArray[i][4] != 0) - { - AddBackground(LayoutArray[i][0], LayoutArray[i][1], 50, 50, 0xA3C); - AddImage(LayoutArray[i][4], LayoutArray[i][5], m_From.Female ? RacialData[i][4] : RacialData[i][5]); - } - - AddButton(LayoutArray[i][6], LayoutArray[i][7], 0xFA5, 0xFA7, i); - } + return; } - public override void OnResponse(NetState sender, RelayInfo info) + if (m_Deed.Deleted) { - if (m_From?.Alive != true) - { - return; - } + return; + } - if (m_Deed.Deleted) - { - return; - } + if (info.ButtonID is < 1 or > 10) + { + return; + } - if (info.ButtonID is < 1 or > 10) - { - return; - } + var RacialData = m_From.Race == Race.Human ? HumanArray : ElvenArray; - var RacialData = m_From.Race == Race.Human ? HumanArray : ElvenArray; - - if (m_From is PlayerMobile pm) - { - pm.SetHairMods(-1, -1); // clear any hairmods (disguise kit, incognito) - pm.HairItemID = pm.Female ? RacialData[info.ButtonID][2] : RacialData[info.ButtonID][3]; - m_Deed.Delete(); - } + if (m_From is PlayerMobile pm) + { + pm.SetHairMods(-1, -1); // clear any hairmods (disguise kit, incognito) + pm.HairItemID = pm.Female ? RacialData[info.ButtonID][2] : RacialData[info.ButtonID][3]; + m_Deed.Delete(); } } } diff --git a/Projects/UOContent/Items/Deeds/HolidayTreeDeed.cs b/Projects/UOContent/Items/Deeds/HolidayTreeDeed.cs index 9f3eb7962..da5ca4a71 100644 --- a/Projects/UOContent/Items/Deeds/HolidayTreeDeed.cs +++ b/Projects/UOContent/Items/Deeds/HolidayTreeDeed.cs @@ -3,171 +3,151 @@ using Server.Multis; using Server.Network; using Server.Targeting; -namespace Server.Items +namespace Server.Items; + +[Serializable(0, false)] +public partial class HolidayTreeDeed : Item { - public class HolidayTreeDeed : Item + [Constructible] + public HolidayTreeDeed() : base(0x14F0) { - [Constructible] - public HolidayTreeDeed() : base(0x14F0) + Hue = 0x488; + Weight = 1.0; + LootType = LootType.Blessed; + } + + public override int LabelNumber => 1041116; // a deed for a holiday tree + + public bool ValidatePlacement(Mobile from, Point3D loc) + { + if (from.AccessLevel >= AccessLevel.GameMaster) { - Hue = 0x488; - Weight = 1.0; - LootType = LootType.Blessed; - } - - public HolidayTreeDeed(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1041116; // a deed for a holiday tree - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - LootType = LootType.Blessed; - } - - public bool ValidatePlacement(Mobile from, Point3D loc) - { - if (from.AccessLevel >= AccessLevel.GameMaster) - { - return true; - } - - if (!from.InRange(GetWorldLocation(), 1)) - { - from.SendLocalizedMessage(500446); // That is too far away. - return false; - } - - if (Core.Now.Month != 12) - { - from.SendLocalizedMessage( - 1005700 - ); // You will have to wait till next December to put your tree back up for display. - return false; - } - - var map = from.Map; - - if (map == null) - { - return false; - } - - var house = BaseHouse.FindHouseAt(loc, map, 20); - - if (house?.IsFriend(from) != true) - { - from.SendLocalizedMessage(1005701); // The holiday tree can only be placed in your house. - return false; - } - - if (!map.CanFit(loc, 20)) - { - from.SendLocalizedMessage(500269); // You cannot build that there. - return false; - } - return true; } - public void BeginPlace(Mobile from, HolidayTreeType type) + if (!from.InRange(GetWorldLocation(), 1)) { - from.BeginTarget(-1, true, TargetFlags.None, Placement_OnTarget, type); + from.SendLocalizedMessage(500446); // That is too far away. + return false; } - public void Placement_OnTarget(Mobile from, object targeted, HolidayTreeType type) + if (Core.Now.Month != 12) { - if (targeted is not IPoint3D p) - { - return; - } - - var loc = new Point3D(p); - - if (p is StaticTarget target) - /* NOTE: OSI does not properly normalize Z positioning here. - * A side affect is that you can only place on floors (due to the CanFit call). - * That functionality may be desired. And so, it's included in this script. - */ - { - loc.Z -= TileData.ItemTable[target.ItemID] - .CalcHeight; - } - - if (ValidatePlacement(from, loc)) - { - EndPlace(from, type, loc); - } + from.SendLocalizedMessage( + 1005700 + ); // You will have to wait till next December to put your tree back up for display. + return false; } - public void EndPlace(Mobile from, HolidayTreeType type, Point3D loc) + var map = from.Map; + + if (map == null) { - Delete(); - var tree = new HolidayTree(from, type, loc); - BaseHouse.FindHouseAt(tree)?.Addons.Add(tree); + return false; } - public override void OnDoubleClick(Mobile from) + var house = BaseHouse.FindHouseAt(loc, map, 20); + + if (house?.IsFriend(from) != true) { - from.CloseGump(); - from.SendGump(new HolidayTreeChoiceGump(from, this)); + from.SendLocalizedMessage(1005701); // The holiday tree can only be placed in your house. + return false; + } + + if (!map.CanFit(loc, 20)) + { + from.SendLocalizedMessage(500269); // You cannot build that there. + return false; + } + + return true; + } + + public void BeginPlace(Mobile from, HolidayTreeType type) + { + from.BeginTarget(-1, true, TargetFlags.None, Placement_OnTarget, type); + } + + public void Placement_OnTarget(Mobile from, object targeted, HolidayTreeType type) + { + if (targeted is not IPoint3D p) + { + return; + } + + var loc = new Point3D(p); + + if (p is StaticTarget target) + /* NOTE: OSI does not properly normalize Z positioning here. + * A side affect is that you can only place on floors (due to the CanFit call). + * That functionality may be desired. And so, it's included in this script. + */ + { + loc.Z -= TileData.ItemTable[target.ItemID] + .CalcHeight; + } + + if (ValidatePlacement(from, loc)) + { + EndPlace(from, type, loc); } } - public class HolidayTreeChoiceGump : Gump + public void EndPlace(Mobile from, HolidayTreeType type, Point3D loc) { - private readonly HolidayTreeDeed m_Deed; - private readonly Mobile m_From; + Delete(); + var tree = new HolidayTree(from, type, loc); + BaseHouse.FindHouseAt(tree)?.Addons.Add(tree); + } - public HolidayTreeChoiceGump(Mobile from, HolidayTreeDeed deed) : base(200, 200) + public override void OnDoubleClick(Mobile from) + { + from.CloseGump(); + from.SendGump(new HolidayTreeChoiceGump(from, this)); + } +} + +public class HolidayTreeChoiceGump : Gump +{ + private readonly HolidayTreeDeed m_Deed; + private readonly Mobile m_From; + + public HolidayTreeChoiceGump(Mobile from, HolidayTreeDeed deed) : base(200, 200) + { + m_From = from; + m_Deed = deed; + + AddPage(0); + + AddBackground(0, 0, 220, 120, 5054); + AddBackground(10, 10, 200, 100, 3000); + + AddButton(20, 35, 4005, 4007, 1); + AddHtmlLocalized(55, 35, 145, 25, 1018322); // Classic + + AddButton(20, 65, 4005, 4007, 2); + AddHtmlLocalized(55, 65, 145, 25, 1018321); // Modern + } + + public override void OnResponse(NetState sender, RelayInfo info) + { + if (m_Deed.Deleted) { - m_From = from; - m_Deed = deed; - - AddPage(0); - - AddBackground(0, 0, 220, 120, 5054); - AddBackground(10, 10, 200, 100, 3000); - - AddButton(20, 35, 4005, 4007, 1); - AddHtmlLocalized(55, 35, 145, 25, 1018322); // Classic - - AddButton(20, 65, 4005, 4007, 2); - AddHtmlLocalized(55, 65, 145, 25, 1018321); // Modern + return; } - public override void OnResponse(NetState sender, RelayInfo info) + switch (info.ButtonID) { - if (m_Deed.Deleted) - { - return; - } - - switch (info.ButtonID) - { - case 1: - { - m_Deed.BeginPlace(m_From, HolidayTreeType.Classic); - break; - } - case 2: - { - m_Deed.BeginPlace(m_From, HolidayTreeType.Modern); - break; - } - } + case 1: + { + m_Deed.BeginPlace(m_From, HolidayTreeType.Classic); + break; + } + case 2: + { + m_Deed.BeginPlace(m_From, HolidayTreeType.Modern); + break; + } } } } diff --git a/Projects/UOContent/Items/Deeds/NameChangeDeed.cs b/Projects/UOContent/Items/Deeds/NameChangeDeed.cs index 05a7d3628..45fd6e080 100644 --- a/Projects/UOContent/Items/Deeds/NameChangeDeed.cs +++ b/Projects/UOContent/Items/Deeds/NameChangeDeed.cs @@ -2,115 +2,97 @@ using Server.Gumps; using Server.Misc; using Server.Network; -namespace Server.Items +namespace Server.Items; + +[Serializable(0, false)] +public partial class NameChangeDeed : Item { - public class NameChangeDeed : Item + [Constructible] + public NameChangeDeed() : base(0x14F0) => LootType = LootType.Blessed; + + public override string DefaultName => "a name change deed"; + + public override void OnDoubleClick(Mobile from) { - [Constructible] - public NameChangeDeed() : base(0x14F0) => LootType = LootType.Blessed; - - public NameChangeDeed(Serial serial) : base(serial) + if (RootParent == from) { + from.CloseGump(); + from.SendGump(new NameChangeDeedGump(this)); } - - public override string DefaultName => "a name change deed"; - - public override void Serialize(IGenericWriter writer) + else { - base.Serialize(writer); - - writer.Write(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - - public override void OnDoubleClick(Mobile from) - { - if (RootParent == from) - { - from.CloseGump(); - from.SendGump(new NameChangeDeedGump(this)); - } - else - { - from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it. - } - } - } - - public class NameChangeDeedGump : Gump - { - private readonly Item m_Sender; - - public NameChangeDeedGump(Item sender) : base(50, 50) - { - m_Sender = sender; - - Closable = true; - Draggable = true; - Resizable = false; - - AddPage(0); - - AddBlackAlpha(10, 120, 250, 85); - AddHtml(10, 125, 250, 20, Color(Center("Name Change Deed"), 0xFFFFFF)); - - AddLabel(73, 15, 1152, ""); - AddLabel(20, 150, 0x480, "New Name:"); - AddTextField(100, 150, 150, 20, 0); - - AddButtonLabeled(75, 180, 1, "Submit"); - } - - public void AddBlackAlpha(int x, int y, int width, int height) - { - AddImageTiled(x, y, width, height, 2624); - AddAlphaRegion(x, y, width, height); - } - - public void AddTextField(int x, int y, int width, int height, int index) - { - AddBackground(x - 2, y - 2, width + 4, height + 4, 0x2486); - AddTextEntry(x + 2, y + 2, width - 4, height - 4, 0, index, ""); - } - - public string Center(string text) => $"
{text}
"; - - public string Color(string text, int color) => $"{text}"; - - public void AddButtonLabeled(int x, int y, int buttonID, string text) - { - AddButton(x, y - 1, 4005, 4007, buttonID); - AddHtml(x + 35, y, 240, 20, Color(text, 0xFFFFFF)); - } - - public override void OnResponse(NetState sender, RelayInfo info) - { - if (m_Sender?.Deleted != false || info.ButtonID != 1 || m_Sender.RootParent != sender.Mobile) - { - return; - } - - var m = sender.Mobile; - var nameEntry = info.GetTextEntry(0); - - var newName = nameEntry?.Text.Trim(); - - if (!NameVerification.Validate(newName, 2, 16, true, false, true, 1, NameVerification.SpaceDashPeriodQuote)) - { - m.SendMessage("That name is unacceptable."); - return; - } - - m.RawName = newName; - m.SendMessage("Your name has been changed!"); - m.SendMessage($"You are now known as {newName}"); - m_Sender.Delete(); + from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it. } } } + +public class NameChangeDeedGump : Gump +{ + private readonly Item m_Sender; + + public NameChangeDeedGump(Item sender) : base(50, 50) + { + m_Sender = sender; + + Closable = true; + Draggable = true; + Resizable = false; + + AddPage(0); + + AddBlackAlpha(10, 120, 250, 85); + AddHtml(10, 125, 250, 20, Color(Center("Name Change Deed"), 0xFFFFFF)); + + AddLabel(73, 15, 1152, ""); + AddLabel(20, 150, 0x480, "New Name:"); + AddTextField(100, 150, 150, 20, 0); + + AddButtonLabeled(75, 180, 1, "Submit"); + } + + public void AddBlackAlpha(int x, int y, int width, int height) + { + AddImageTiled(x, y, width, height, 2624); + AddAlphaRegion(x, y, width, height); + } + + public void AddTextField(int x, int y, int width, int height, int index) + { + AddBackground(x - 2, y - 2, width + 4, height + 4, 0x2486); + AddTextEntry(x + 2, y + 2, width - 4, height - 4, 0, index, ""); + } + + public string Center(string text) => $"
{text}
"; + + public string Color(string text, int color) => $"{text}"; + + public void AddButtonLabeled(int x, int y, int buttonID, string text) + { + AddButton(x, y - 1, 4005, 4007, buttonID); + AddHtml(x + 35, y, 240, 20, Color(text, 0xFFFFFF)); + } + + public override void OnResponse(NetState sender, RelayInfo info) + { + if (m_Sender?.Deleted != false || info.ButtonID != 1 || m_Sender.RootParent != sender.Mobile) + { + return; + } + + var m = sender.Mobile; + var nameEntry = info.GetTextEntry(0); + + var newName = nameEntry?.Text.Trim(); + + if (!NameVerification.Validate(newName, 2, 16, true, false, true, 1, NameVerification.SpaceDashPeriodQuote)) + { + m.SendMessage("That name is unacceptable."); + return; + } + + m.RawName = newName; + m.SendMessage("Your name has been changed!"); + m.SendMessage($"You are now known as {newName}"); + m_Sender.Delete(); + } +} diff --git a/Projects/UOContent/Items/Deeds/NewPlayerTicket.cs b/Projects/UOContent/Items/Deeds/NewPlayerTicket.cs index 5db09f6ef..1b75e9eaf 100644 --- a/Projects/UOContent/Items/Deeds/NewPlayerTicket.cs +++ b/Projects/UOContent/Items/Deeds/NewPlayerTicket.cs @@ -2,217 +2,188 @@ using Server.Gumps; using Server.Network; using Server.Targeting; -namespace Server.Items +namespace Server.Items; + +[Serializable(0, false)] +public partial class NewPlayerTicket : Item { - public class NewPlayerTicket : Item + [SerializableField(0)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.Owner)]")] + private Mobile _owner; + + [Constructible] + public NewPlayerTicket() : base(0x14EF) { - [Constructible] - public NewPlayerTicket() : base(0x14EF) + Weight = 1.0; + LootType = LootType.Blessed; + } + + public override int LabelNumber => 1062094; // a young player ticket + + public override bool DisplayLootType => false; + + public override void GetProperties(ObjectPropertyList list) + { + base.GetProperties(list); + + // This is half a prize ticket! Double-click this ticket and target any other ticket marked NEW PLAYER and get a prize! This ticket will only work for YOU, so don't give it away! + list.Add(1041492); + } + + public override void OnDoubleClick(Mobile from) + { + if (from != Owner) { - Weight = 1.0; - LootType = LootType.Blessed; + from.SendLocalizedMessage(501926); // This isn't your ticket! Shame on you! You have to use YOUR ticket. } - - public NewPlayerTicket(Serial serial) : base(serial) + else if (!IsChildOf(from.Backpack)) { + from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it. } - - [CommandProperty(AccessLevel.GameMaster)] - public Mobile Owner { get; set; } - - public override int LabelNumber => 1062094; // a young player ticket - - public override bool DisplayLootType => false; - - public override void GetProperties(ObjectPropertyList list) + else { - base.GetProperties(list); - - list.Add( - 1041492 - ); // This is half a prize ticket! Double-click this ticket and target any other ticket marked NEW PLAYER and get a prize! This ticket will only work for YOU, so don't give it away! + from.SendLocalizedMessage(501927); // Target any other ticket marked NEW PLAYER to win a prize. + from.Target = new InternalTarget(this); } + } - public override void Serialize(IGenericWriter writer) + private class InternalTarget : Target + { + private readonly NewPlayerTicket m_Ticket; + + public InternalTarget(NewPlayerTicket ticket) : base(2, false, TargetFlags.None) => m_Ticket = ticket; + + protected override void OnTarget(Mobile from, object targeted) { - base.Serialize(writer); - - writer.Write(0); // version - - writer.Write(Owner); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - switch (version) + if (targeted == m_Ticket) { - case 0: - { - Owner = reader.ReadEntity(); - break; - } + from.SendLocalizedMessage(501928); // You can't target the same ticket! } - - if (Name == "a young player ticket") + else if (targeted is NewPlayerTicket theirTicket) { - Name = null; - } - } + var them = theirTicket.Owner; - public override void OnDoubleClick(Mobile from) - { - if (from != Owner) - { - from.SendLocalizedMessage(501926); // This isn't your ticket! Shame on you! You have to use YOUR ticket. - } - else if (!IsChildOf(from.Backpack)) - { - from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it. - } - else - { - from.SendLocalizedMessage(501927); // Target any other ticket marked NEW PLAYER to win a prize. - from.Target = new InternalTarget(this); - } - } - - private class InternalTarget : Target - { - private readonly NewPlayerTicket m_Ticket; - - public InternalTarget(NewPlayerTicket ticket) : base(2, false, TargetFlags.None) => m_Ticket = ticket; - - protected override void OnTarget(Mobile from, object targeted) - { - if (targeted == m_Ticket) + if (them?.Deleted != false) { - from.SendLocalizedMessage(501928); // You can't target the same ticket! - } - else if (targeted is NewPlayerTicket theirTicket) - { - var them = theirTicket.Owner; - - if (them?.Deleted != false) - { - from.SendLocalizedMessage(501930); // That is not a valid ticket. - } - else - { - from.SendGump(new InternalGump(from, m_Ticket)); - them.SendGump(new InternalGump(them, theirTicket)); - } - } - else if ((targeted as Item)?.ItemID == 0x14F0) - { - from.SendLocalizedMessage(501931); // You need to find another ticket marked NEW PLAYER. + from.SendLocalizedMessage(501930); // That is not a valid ticket. } else { - from.SendLocalizedMessage(501929); // You will need to select a ticket. + from.SendGump(new InternalGump(from, m_Ticket)); + them.SendGump(new InternalGump(them, theirTicket)); } } + else if ((targeted as Item)?.ItemID == 0x14F0) + { + from.SendLocalizedMessage(501931); // You need to find another ticket marked NEW PLAYER. + } + else + { + from.SendLocalizedMessage(501929); // You will need to select a ticket. + } } + } - private class InternalGump : Gump + private class InternalGump : Gump + { + private readonly Mobile m_From; + private readonly NewPlayerTicket m_Ticket; + + public InternalGump(Mobile from, NewPlayerTicket ticket) : base(50, 50) { - private readonly Mobile m_From; - private readonly NewPlayerTicket m_Ticket; + m_From = from; + m_Ticket = ticket; - public InternalGump(Mobile from, NewPlayerTicket ticket) : base(50, 50) + AddBackground(0, 0, 400, 385, 0xA28); + + // Choose the gift you prefer. WARNING: if you cancel, and your partner does not, you will need to find another matching ticket! + AddHtmlLocalized(30, 45, 340, 70, 1013011, true, true); + + AddButton(46, 128, 0xFA5, 0xFA7, 1); + AddHtmlLocalized(80, 130, 320, 35, 1013012); // A sextant + + AddButton(46, 163, 0xFA5, 0xFA7, 2); + AddHtmlLocalized(80, 165, 320, 35, 1013013); // A coupon for a single hair restyling + + AddButton(46, 198, 0xFA5, 0xFA7, 3); + AddHtmlLocalized(80, 200, 320, 35, 1013014); // A spellbook with all 1st - 4th spells. + + AddButton(46, 233, 0xFA5, 0xFA7, 4); + AddHtmlLocalized(80, 235, 320, 35, 1013015); // A wand of fireworks + + AddButton(46, 268, 0xFA5, 0xFA7, 5); + AddHtmlLocalized(80, 270, 320, 35, 1013016); // A spyglass + + AddButton(46, 303, 0xFA5, 0xFA7, 6); + AddHtmlLocalized(80, 305, 320, 35, 1013017); // Dyes and a dye tub + + AddButton(120, 340, 0xFA5, 0xFA7, 0); + AddHtmlLocalized(154, 342, 100, 35, 1011012); // CANCEL + } + + public override void OnResponse(NetState sender, RelayInfo info) + { + if (m_Ticket.Deleted) { - m_From = from; - m_Ticket = ticket; - - AddBackground(0, 0, 400, 385, 0xA28); - - AddHtmlLocalized( - 30, - 45, - 340, - 70, - 1013011, - true, - true - ); // Choose the gift you prefer. WARNING: if you cancel, and your partner does not, you will need to find another matching ticket! - - AddButton(46, 128, 0xFA5, 0xFA7, 1); - AddHtmlLocalized(80, 130, 320, 35, 1013012); // A sextant - - AddButton(46, 163, 0xFA5, 0xFA7, 2); - AddHtmlLocalized(80, 165, 320, 35, 1013013); // A coupon for a single hair restyling - - AddButton(46, 198, 0xFA5, 0xFA7, 3); - AddHtmlLocalized(80, 200, 320, 35, 1013014); // A spellbook with all 1st - 4th spells. - - AddButton(46, 233, 0xFA5, 0xFA7, 4); - AddHtmlLocalized(80, 235, 320, 35, 1013015); // A wand of fireworks - - AddButton(46, 268, 0xFA5, 0xFA7, 5); - AddHtmlLocalized(80, 270, 320, 35, 1013016); // A spyglass - - AddButton(46, 303, 0xFA5, 0xFA7, 6); - AddHtmlLocalized(80, 305, 320, 35, 1013017); // Dyes and a dye tub - - AddButton(120, 340, 0xFA5, 0xFA7, 0); - AddHtmlLocalized(154, 342, 100, 35, 1011012); // CANCEL + return; } - public override void OnResponse(NetState sender, RelayInfo info) + var number = 0; + + Item item = null; + Item item2 = null; + + switch (info.ButtonID) { - if (m_Ticket.Deleted) - { - return; - } - - var number = 0; - - Item item = null; - Item item2 = null; - - switch (info.ButtonID) - { - case 1: + case 1: + { item = new Sextant(); number = 1010494; break; // A sextant has been placed in your backpack. - case 2: + } + case 2: + { item = new HairRestylingDeed(); number = 501933; break; // A coupon for a free hair restyling has been placed in your backpack. - case 3: + } + case 3: + { item = new Spellbook(0xFFFFFFFF); number = 1010495; break; // A spellbook with all 1st to 4th circle spells has been placed in your backpack. - case 4: + } + case 4: + { item = new FireworksWand(); number = 501935; break; // A wand of fireworks has been placed in your backpack. - case 5: + } + case 5: + { item = new Spyglass(); number = 501936; break; // A spyglass has been placed in your backpack. - case 6: + } + case 6: + { item = new DyeTub(); item2 = new Dyes(); number = 501937; break; // The dyes and dye tub have been placed in your backpack. - } - - if (item != null) - { - m_Ticket.Delete(); - - m_From.SendLocalizedMessage(number); - m_From.AddToBackpack(item); - - if (item2 != null) - { - m_From.AddToBackpack(item2); } + } + + if (item != null) + { + m_Ticket.Delete(); + + m_From.SendLocalizedMessage(number); + m_From.AddToBackpack(item); + + if (item2 != null) + { + m_From.AddToBackpack(item2); } } } diff --git a/Projects/UOContent/Migrations/Server.Items.BarkeepContract.v0.json b/Projects/UOContent/Migrations/Server.Items.BarkeepContract.v0.json new file mode 100644 index 000000000..76a2853cc --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.BarkeepContract.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.BarkeepContract" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.ClothingBlessDeed.v0.json b/Projects/UOContent/Migrations/Server.Items.ClothingBlessDeed.v0.json new file mode 100644 index 000000000..4e081598a --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.ClothingBlessDeed.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.ClothingBlessDeed" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.CommodityDeed.v1.json b/Projects/UOContent/Migrations/Server.Items.CommodityDeed.v1.json new file mode 100644 index 000000000..57487eb5d --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.CommodityDeed.v1.json @@ -0,0 +1,11 @@ +{ + "version": 1, + "type": "Server.Items.CommodityDeed", + "properties": [ + { + "name": "Commodity", + "type": "Server.Item", + "rule": "SerializableInterfaceMigrationRule" + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.DragonBardingDeed.v2.json b/Projects/UOContent/Migrations/Server.Items.DragonBardingDeed.v2.json new file mode 100644 index 000000000..a6a26d015 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.DragonBardingDeed.v2.json @@ -0,0 +1,27 @@ +{ + "version": 2, + "type": "Server.Items.DragonBardingDeed", + "properties": [ + { + "name": "CraftedBy", + "type": "string", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "Exceptional", + "type": "bool", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "RawResource", + "type": "Server.Items.CraftResource", + "rule": "EnumMigrationRule" + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.HairRestylingDeed.v0.json b/Projects/UOContent/Migrations/Server.Items.HairRestylingDeed.v0.json new file mode 100644 index 000000000..8db04fb3d --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.HairRestylingDeed.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.HairRestylingDeed" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.HolidayTreeDeed.v0.json b/Projects/UOContent/Migrations/Server.Items.HolidayTreeDeed.v0.json new file mode 100644 index 000000000..8263aa14e --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.HolidayTreeDeed.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.HolidayTreeDeed" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.NameChangeDeed.v0.json b/Projects/UOContent/Migrations/Server.Items.NameChangeDeed.v0.json new file mode 100644 index 000000000..265569945 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.NameChangeDeed.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.NameChangeDeed" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.NewPlayerTicket.v0.json b/Projects/UOContent/Migrations/Server.Items.NewPlayerTicket.v0.json new file mode 100644 index 000000000..b73d06bb7 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.NewPlayerTicket.v0.json @@ -0,0 +1,11 @@ +{ + "version": 0, + "type": "Server.Items.NewPlayerTicket", + "properties": [ + { + "name": "Owner", + "type": "Server.Mobile", + "rule": "SerializableInterfaceMigrationRule" + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/SwampDragon.cs b/Projects/UOContent/Mobiles/Animals/Mounts/SwampDragon.cs index 3e08164d1..64671c8d5 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/SwampDragon.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/SwampDragon.cs @@ -4,7 +4,7 @@ namespace Server.Mobiles { public class SwampDragon : BaseMount { - private Mobile m_BardingCrafter; + private string _bardingCraftedBy; private bool m_BardingExceptional; private int m_BardingHP; private CraftResource m_BardingResource; @@ -54,12 +54,12 @@ namespace Server.Mobiles public override string CorpseName => "a swamp dragon corpse"; [CommandProperty(AccessLevel.GameMaster)] - public Mobile BardingCrafter + public string BardingCraftedBy { - get => m_BardingCrafter; + get => _bardingCraftedBy; set { - m_BardingCrafter = value; + _bardingCraftedBy = value; InvalidateProperties(); } } @@ -156,9 +156,9 @@ namespace Server.Mobiles { base.GetProperties(list); - if (m_HasBarding && m_BardingExceptional && m_BardingCrafter != null) + if (m_HasBarding && m_BardingExceptional && _bardingCraftedBy != null) { - list.Add(1060853, m_BardingCrafter.Name); // armor exceptionally crafted by ~1_val~ + list.Add(1060853, _bardingCraftedBy); // armor exceptionally crafted by ~1_val~ } } @@ -166,10 +166,10 @@ namespace Server.Mobiles { base.Serialize(writer); - writer.Write(1); // version + writer.Write(2); // version writer.Write(m_BardingExceptional); - writer.Write(m_BardingCrafter); + writer.Write(_bardingCraftedBy); writer.Write(m_HasBarding); writer.Write(m_BardingHP); writer.Write((int)m_BardingResource); @@ -183,10 +183,21 @@ namespace Server.Mobiles switch (version) { + case 2: + { + m_BardingExceptional = reader.ReadBool(); + _bardingCraftedBy = reader.ReadString(); + m_HasBarding = reader.ReadBool(); + m_BardingHP = reader.ReadInt(); + m_BardingResource = (CraftResource)reader.ReadInt(); + break; + } case 1: { m_BardingExceptional = reader.ReadBool(); - m_BardingCrafter = reader.ReadEntity(); + var crafter = reader.ReadEntity(); + // Name might not be set during this deserialization + Timer.StartTimer(() => _bardingCraftedBy = crafter?.RawName); m_HasBarding = reader.ReadBool(); m_BardingHP = reader.ReadInt(); m_BardingResource = (CraftResource)reader.ReadInt(); From fdcd6c80a8a82e08fff3f5d718ecf986550c798f Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Thu, 31 Mar 2022 00:16:45 -0700 Subject: [PATCH 127/213] chore: Adds benchmarks for RunUO vs ModernUO Timers (#984) --- .../Timers/BenchmarkTimerExecutions.cs | 96 ++++ .../Timers/BenchmarkTimerInserts.cs | 60 +++ .../Benchmarks/Benchmarks/Timers/RUOTimer.cs | 495 ++++++++++++++++++ Projects/Benchmarks/Program.cs | 4 + Projects/Server/Timer/Timer.TimerWheel.cs | 5 + 5 files changed, 660 insertions(+) create mode 100644 Projects/Benchmarks/Benchmarks/Timers/BenchmarkTimerExecutions.cs create mode 100644 Projects/Benchmarks/Benchmarks/Timers/BenchmarkTimerInserts.cs create mode 100644 Projects/Benchmarks/Benchmarks/Timers/RUOTimer.cs diff --git a/Projects/Benchmarks/Benchmarks/Timers/BenchmarkTimerExecutions.cs b/Projects/Benchmarks/Benchmarks/Timers/BenchmarkTimerExecutions.cs new file mode 100644 index 000000000..5d71ce8ea --- /dev/null +++ b/Projects/Benchmarks/Benchmarks/Timers/BenchmarkTimerExecutions.cs @@ -0,0 +1,96 @@ +using System; +using System.Threading; +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Jobs; + +namespace Server +{ + [MemoryDiagnoser] + [SimpleJob(RuntimeMoniker.Net60, warmupCount: 20, targetCount: 20)] + public class BenchmarkTimerExecutions + { + private const int timerCount = 1000; + private CancellationTokenSource _cancellationTokenSource; + private static SemaphoreSlim _slim; + + [GlobalSetup] + public void Setup() + { + Core.Profiling = false; + Timer.Init(0); + + RUOTimer.TimerThread ttObj = new RUOTimer.TimerThread(); + _cancellationTokenSource = new CancellationTokenSource(); + var timerThread = new Thread(() => ttObj.TimerMain(_cancellationTokenSource.Token)) + { + Name = "Timer Thread" + }; + + timerThread.Start(); + } + + [GlobalCleanup] + public void Cleanup() + { + RUOTimer.TimerThread.Set(); + _cancellationTokenSource.Cancel(); + RUOTimer.TimerThread.CleanupForTesting(); + Timer.ClearAllTimers(0); + GC.Collect(); + } + + [Benchmark] + public void RUOTimerExecutions() + { + _slim = new SemaphoreSlim(1); + + for (var i = 0; i < timerCount; i++) + { + new TestRUOTimer(TimeSpan.FromMilliseconds(1), i).Start(); + } + + RUOTimer.TimerThread.m_TickCount += 8; + RUOTimer.TimerThread.Set(); + _slim.Wait(); + } + + [Benchmark] + public void MUOTimerExecutions() + { + for (var i = 0; i < timerCount; i++) + { + new TestMUOTimer(TimeSpan.FromMilliseconds(1), i).Start(); + } + + Timer.Slice(8); + } + + public class TestRUOTimer : RUOTimer + { + private int _amount; + + public TestRUOTimer(TimeSpan delay, int amount) : base(delay) => _amount = amount; + + protected override void OnTick() + { + var b = 6 * _amount; + if (_amount == timerCount - 1) + { + _slim.Release(); + } + } + } + + public class TestMUOTimer : Timer + { + private int _amount; + + public TestMUOTimer(TimeSpan delay, int amount) : base(delay) => _amount = amount; + + protected override void OnTick() + { + var b = 6 * _amount; + } + } + } +} diff --git a/Projects/Benchmarks/Benchmarks/Timers/BenchmarkTimerInserts.cs b/Projects/Benchmarks/Benchmarks/Timers/BenchmarkTimerInserts.cs new file mode 100644 index 000000000..a2918943c --- /dev/null +++ b/Projects/Benchmarks/Benchmarks/Timers/BenchmarkTimerInserts.cs @@ -0,0 +1,60 @@ +using System; +using System.Threading; +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Jobs; + +namespace Server +{ + [MemoryDiagnoser] + [SimpleJob(RuntimeMoniker.Net60, warmupCount: 20, targetCount: 20)] + public class BenchmarkTimerInserts + { + private const int timerCount = 1000; + private CancellationTokenSource _cancellationTokenSource; + + [GlobalSetup] + public void Setup() + { + Core.Profiling = false; + Timer.Init(0); + + RUOTimer.TimerThread ttObj = new RUOTimer.TimerThread(); + _cancellationTokenSource = new CancellationTokenSource(); + var timerThread = new Thread(() => ttObj.TimerMain(_cancellationTokenSource.Token)) + { + Name = "Timer Thread" + }; + + timerThread.Start(); + } + + [GlobalCleanup] + public void Cleanup() + { + _cancellationTokenSource.Cancel(); + RUOTimer.TimerThread.Set(); + RUOTimer.TimerThread.CleanupForTesting(); + Timer.ClearAllTimers(0); + GC.Collect(); + } + + [Benchmark] + public void RUOTimerInserts() + { + for (var i = 0; i < timerCount; i++) + { + new RUOTimer(TimeSpan.Zero).Start(); + } + RUOTimer.TimerThread.Set(); + } + + [Benchmark] + public void MUOTimerInserts() + { + for (var i = 0; i < timerCount; i++) + { + new Timer(TimeSpan.Zero).Start(); + } + } + } +} diff --git a/Projects/Benchmarks/Benchmarks/Timers/RUOTimer.cs b/Projects/Benchmarks/Benchmarks/Timers/RUOTimer.cs new file mode 100644 index 000000000..bdba69fe9 --- /dev/null +++ b/Projects/Benchmarks/Benchmarks/Timers/RUOTimer.cs @@ -0,0 +1,495 @@ +/*************************************************************************** + * Timer.cs + * ------------------- + * begin : May 1, 2002 + * copyright : (C) The RunUO Software Team + * email : info@runuo.com + * + * $Id$ + * + ***************************************************************************/ + +/*************************************************************************** + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + ***************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Threading; +using Server.Diagnostics; + +namespace Server +{ + public enum TimerPriority + { + EveryTick, + TenMS, + TwentyFiveMS, + FiftyMS, + TwoFiftyMS, + OneSecond, + FiveSeconds, + OneMinute + } + + public class RUOTimer + { + private long m_Next; + private long m_Delay; + private long m_Interval; + private bool m_Running; + private int m_Index, m_Count; + private TimerPriority m_Priority; + private List m_List; + private bool m_PrioritySet; + + private static string FormatDelegate( Delegate callback ) + { + if ( callback == null ) + { + return "null"; + } + + return String.Format( "{0}.{1}", callback.Method.DeclaringType.FullName, callback.Method.Name ); + } + + public TimerPriority Priority + { + get + { + return m_Priority; + } + set + { + if ( !m_PrioritySet ) + { + m_PrioritySet = true; + } + + if ( m_Priority != value ) + { + m_Priority = value; + + if ( m_Running ) + { + TimerThread.PriorityChange( this, (int)m_Priority ); + } + } + } + } + + public DateTime Next + { + // Obnoxious + get { return DateTime.UtcNow + TimeSpan.FromMilliseconds(m_Next-TimerThread.m_TickCount); } + } + + public TimeSpan Delay + { + get { return TimeSpan.FromMilliseconds(m_Delay); } + set { m_Delay = (long)value.TotalMilliseconds; } + } + + public TimeSpan Interval + { + get { return TimeSpan.FromMilliseconds(m_Interval); } + set { m_Interval = (long)value.TotalMilliseconds; } + } + + public bool Running + { + get { return m_Running; } + set { + if ( value ) { + Start(); + } else { + Stop(); + } + } + } + + public TimerProfile GetProfile() + { + if ( !Core.Profiling ) { + return null; + } + + string name = ToString(); + + if ( name == null ) { + name = "null"; + } + + return TimerProfile.Acquire( name ); + } + + public class TimerThread + { + public static long m_TickCount; // Mimics core tick count for testing + + private static Dictionary m_Changed = new Dictionary(); + + private static long[] m_NextPriorities = new long[8]; + private static long[] m_PriorityDelays = new long[8] + { + 0, + 10, + 25, + 50, + 250, + 1000, + 5000, + 60000 + }; + + private static List[] m_Timers = new List[8] + { + new List(), + new List(), + new List(), + new List(), + new List(), + new List(), + new List(), + new List(), + }; + + private class TimerChangeEntry + { + public RUOTimer MRuoTimer; + public int m_NewIndex; + public bool m_IsAdd; + + private TimerChangeEntry( RUOTimer t, int newIndex, bool isAdd ) + { + MRuoTimer = t; + m_NewIndex = newIndex; + m_IsAdd = isAdd; + } + + public void Free() + { + lock (m_InstancePool) { + if (m_InstancePool.Count < 200) // Arbitrary + { + m_InstancePool.Enqueue( this ); + } + } + } + + private static Queue m_InstancePool = new Queue(); + + public static TimerChangeEntry GetInstance( RUOTimer t, int newIndex, bool isAdd ) + { + TimerChangeEntry e = null; + + lock (m_InstancePool) { + if ( m_InstancePool.Count > 0 ) { + e = m_InstancePool.Dequeue(); + } + } + + if (e != null) { + e.MRuoTimer = t; + e.m_NewIndex = newIndex; + e.m_IsAdd = isAdd; + } else { + e = new TimerChangeEntry( t, newIndex, isAdd ); + } + + return e; + } + } + + public TimerThread() + { + } + + public static void Change( RUOTimer t, int newIndex, bool isAdd ) + { + lock (m_Changed) + { + m_Changed[t] = TimerChangeEntry.GetInstance(t, newIndex, isAdd); + } + + m_Signal.Set(); + } + + public static void AddTimer( RUOTimer t ) + { + Change( t, (int)t.Priority, true ); + } + + public static void PriorityChange( RUOTimer t, int newPrio ) + { + Change( t, newPrio, false ); + } + + public static void RemoveTimer( RUOTimer t ) + { + Change( t, -1, false ); + } + + private static void ProcessChanged() + { + lock (m_Changed) { + long curTicks = m_TickCount; + + foreach (TimerChangeEntry tce in m_Changed.Values) { + RUOTimer ruoTimer = tce.MRuoTimer; + int newIndex = tce.m_NewIndex; + + if (ruoTimer.m_List != null) + { + ruoTimer.m_List.Remove(ruoTimer); + } + + if (tce.m_IsAdd) { + ruoTimer.m_Next = curTicks + ruoTimer.m_Delay; + ruoTimer.m_Index = 0; + } + + if (newIndex >= 0) { + ruoTimer.m_List = m_Timers[newIndex]; + ruoTimer.m_List.Add(ruoTimer); + } else { + ruoTimer.m_List = null; + } + + tce.Free(); + } + + m_Changed.Clear(); + } + } + + public static void CleanupForTesting() + { + lock (m_Changed) + { + m_Changed.Clear(); + } + } + + private static AutoResetEvent m_Signal = new AutoResetEvent( false ); + public static void Set() { m_Signal.Set(); } + + public void TimerMain(CancellationToken cancellationToken) + { + long now; + int i, j; + bool loaded; + + while ( !cancellationToken.IsCancellationRequested ) + { + ProcessChanged(); + + loaded = false; + + for ( i = 0; i < m_Timers.Length; i++) + { + now = m_TickCount; + if ( now < m_NextPriorities[i] ) + { + break; + } + + m_NextPriorities[i] = now + m_PriorityDelays[i]; + + for ( j = 0; j < m_Timers[i].Count; j++) + { + RUOTimer t = m_Timers[i][j]; + + if ( !t.m_Queued && now > t.m_Next ) + { + t.m_Queued = true; + + lock ( m_Queue ) + { + m_Queue.Enqueue( t ); + } + + loaded = true; + + if ( t.m_Count != 0 && (++t.m_Index >= t.m_Count) ) + { + t.Stop(); + } + else + { + t.m_Next = now + t.m_Interval; + } + } + } + } + + if ( loaded ) + { + // Core.Set(); + } + + m_Signal.WaitOne(-1, false); + } + } + } + + private static Queue m_Queue = new Queue(); + private static int m_BreakCount = 20000; + + public static int BreakCount{ get{ return m_BreakCount; } set{ m_BreakCount = value; } } + + private static int m_QueueCountAtSlice; + + private bool m_Queued; + + public static void Slice() + { + lock ( m_Queue ) + { + m_QueueCountAtSlice = m_Queue.Count; + + int index = 0; + + while ( index < m_BreakCount && m_Queue.Count != 0 ) + { + RUOTimer t = m_Queue.Dequeue(); + TimerProfile prof = t.GetProfile(); + + if ( prof != null ) { + prof.Start(); + } + + t.OnTick(); + t.m_Queued = false; + ++index; + + if ( prof != null ) { + prof.Finish(); + } + } + } + } + + public RUOTimer( TimeSpan delay ) : this( delay, TimeSpan.Zero, 1 ) + { + } + + public RUOTimer( TimeSpan delay, TimeSpan interval ) : this( delay, interval, 0 ) + { + } + + public virtual bool DefRegCreation + { + get{ return true; } + } + + public void RegCreation() + { + TimerProfile prof = GetProfile(); + + if ( prof != null ) { + prof.Created++; + } + } + + public RUOTimer( TimeSpan delay, TimeSpan interval, int count ) + { + m_Delay = (long)delay.TotalMilliseconds; + m_Interval = (long)interval.TotalMilliseconds; + m_Count = count; + + if ( !m_PrioritySet ) { + if ( count == 1 ) { + m_Priority = ComputePriority( delay ); + } else { + m_Priority = ComputePriority( interval ); + } + m_PrioritySet = true; + } + + if ( DefRegCreation ) + { + RegCreation(); + } + } + + public override string ToString() + { + return GetType().FullName; + } + + public static TimerPriority ComputePriority( TimeSpan ts ) + { + if ( ts >= TimeSpan.FromMinutes( 1.0 ) ) + { + return TimerPriority.FiveSeconds; + } + + if ( ts >= TimeSpan.FromSeconds( 10.0 ) ) + { + return TimerPriority.OneSecond; + } + + if ( ts >= TimeSpan.FromSeconds( 5.0 ) ) + { + return TimerPriority.TwoFiftyMS; + } + + if ( ts >= TimeSpan.FromSeconds( 2.5 ) ) + { + return TimerPriority.FiftyMS; + } + + if ( ts >= TimeSpan.FromSeconds( 1.0 ) ) + { + return TimerPriority.TwentyFiveMS; + } + + if ( ts >= TimeSpan.FromSeconds( 0.5 ) ) + { + return TimerPriority.TenMS; + } + + return TimerPriority.EveryTick; + } + + public void Start() + { + if ( !m_Running ) + { + m_Running = true; + TimerThread.AddTimer( this ); + + TimerProfile prof = GetProfile(); + + if ( prof != null ) { + prof.Started++; + } + } + } + + public void Stop() + { + if ( m_Running ) + { + m_Running = false; + TimerThread.RemoveTimer( this ); + + TimerProfile prof = GetProfile(); + + if ( prof != null ) { + prof.Stopped++; + } + } + } + + protected virtual void OnTick() + { + } + } +} diff --git a/Projects/Benchmarks/Program.cs b/Projects/Benchmarks/Program.cs index 34a5462e2..ef1033575 100644 --- a/Projects/Benchmarks/Program.cs +++ b/Projects/Benchmarks/Program.cs @@ -4,6 +4,7 @@ using Benchmarks.ItemSelectors; using Benchmarks.MobileSelectors; using Benchmarks.MultiSelectors; using Benchmarks.MultiTilesSelectors; +using Server; namespace Benchmarks { @@ -29,6 +30,9 @@ namespace Benchmarks // var mapItemsSelectors = BenchmarkRunner.Run(); // var stArray = BenchmarkRunner.Run(); // var pooledRefQueue = BenchmarkRunner.Run(); + + var timerInsertionTest = BenchmarkRunner.Run(); + // var timerExecutionTest = BenchmarkRunner.Run(); } } } diff --git a/Projects/Server/Timer/Timer.TimerWheel.cs b/Projects/Server/Timer/Timer.TimerWheel.cs index 5e9d66334..02b54f12a 100644 --- a/Projects/Server/Timer/Timer.TimerWheel.cs +++ b/Projects/Server/Timer/Timer.TimerWheel.cs @@ -260,6 +260,11 @@ namespace Server foreach (var t in _rings) { + if (t == null) + { + continue; + } + for (var i = 0; i < _ringSize; i++) { var node = t[i]; From 4d1ee2156863257dcb770d2f76d88c517ae5a92f Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Thu, 31 Mar 2022 10:37:33 -0700 Subject: [PATCH 128/213] chore: Removes benchmarks. (#985) --- ModernUO.sln | 8 - Projects/Benchmarks/Benchmarks.csproj | 18 - .../Collections/BenchmarkOrderedHashSet.cs | 130 ----- .../Collections/BenchmarkPooledRefQueue.cs | 95 --- .../Collections/BenchmarkSTArray.cs | 92 --- .../Logging/BenchmarkConsoleLogging.cs | 63 -- .../Benchmarks/Map/MapEntitiesSelectors.cs | 545 ------------------ .../Benchmarks/Map/MapItemSelectors.cs | 403 ------------- .../Benchmarks/Map/MapMobileSelectors.cs | 254 -------- .../Benchmarks/Map/MapMultiSelectors.cs | 310 ---------- .../Benchmarks/Map/MapMultiTilesSelectors.cs | 350 ----------- .../Packets/BenchmarkPacketBroadcast.cs | 174 ------ .../Benchmarks/Benchmarks/Packets/Packet.cs | 265 --------- .../Benchmarks/Packets/PacketTestUtilities.cs | 31 - .../Benchmarks/Packets/PacketWriter.cs | 354 ------------ .../Benchmarks/Rng/BenchmarkDoubleVsFixed.cs | 28 - .../Benchmarks/Rng/BenchmarkXoshiro.cs | 46 -- .../Benchmarks/Text/BenchmarkTextEncoding.cs | 32 - .../Timers/BenchmarkTimerExecutions.cs | 96 --- .../Timers/BenchmarkTimerInserts.cs | 60 -- .../Benchmarks/Benchmarks/Timers/RUOTimer.cs | 495 ---------------- .../Utilities/BenchmarkStringHelpers.cs | 87 --- Projects/Benchmarks/Directory.Build.props | 3 - Projects/Benchmarks/Program.cs | 38 -- 24 files changed, 3977 deletions(-) delete mode 100644 Projects/Benchmarks/Benchmarks.csproj delete mode 100644 Projects/Benchmarks/Benchmarks/Collections/BenchmarkOrderedHashSet.cs delete mode 100644 Projects/Benchmarks/Benchmarks/Collections/BenchmarkPooledRefQueue.cs delete mode 100644 Projects/Benchmarks/Benchmarks/Collections/BenchmarkSTArray.cs delete mode 100644 Projects/Benchmarks/Benchmarks/Logging/BenchmarkConsoleLogging.cs delete mode 100644 Projects/Benchmarks/Benchmarks/Map/MapEntitiesSelectors.cs delete mode 100644 Projects/Benchmarks/Benchmarks/Map/MapItemSelectors.cs delete mode 100644 Projects/Benchmarks/Benchmarks/Map/MapMobileSelectors.cs delete mode 100644 Projects/Benchmarks/Benchmarks/Map/MapMultiSelectors.cs delete mode 100644 Projects/Benchmarks/Benchmarks/Map/MapMultiTilesSelectors.cs delete mode 100644 Projects/Benchmarks/Benchmarks/Packets/BenchmarkPacketBroadcast.cs delete mode 100644 Projects/Benchmarks/Benchmarks/Packets/Packet.cs delete mode 100644 Projects/Benchmarks/Benchmarks/Packets/PacketTestUtilities.cs delete mode 100644 Projects/Benchmarks/Benchmarks/Packets/PacketWriter.cs delete mode 100644 Projects/Benchmarks/Benchmarks/Rng/BenchmarkDoubleVsFixed.cs delete mode 100644 Projects/Benchmarks/Benchmarks/Rng/BenchmarkXoshiro.cs delete mode 100644 Projects/Benchmarks/Benchmarks/Text/BenchmarkTextEncoding.cs delete mode 100644 Projects/Benchmarks/Benchmarks/Timers/BenchmarkTimerExecutions.cs delete mode 100644 Projects/Benchmarks/Benchmarks/Timers/BenchmarkTimerInserts.cs delete mode 100644 Projects/Benchmarks/Benchmarks/Timers/RUOTimer.cs delete mode 100644 Projects/Benchmarks/Benchmarks/Utilities/BenchmarkStringHelpers.cs delete mode 100644 Projects/Benchmarks/Directory.Build.props delete mode 100644 Projects/Benchmarks/Program.cs diff --git a/ModernUO.sln b/ModernUO.sln index f42d55f2e..92647cca4 100644 --- a/ModernUO.sln +++ b/ModernUO.sln @@ -10,8 +10,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Server.Tests", "Projects\Se EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UOContent.Tests", "Projects\UOContent.Tests\UOContent.Tests.csproj", "{3C4797F9-603E-44EF-8E8C-9275CC9EA74B}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Benchmarks", "Projects\Benchmarks\Benchmarks.csproj", "{38B7E4A1-FDDD-486C-98EE-BA7B13712528}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Analyze|x64 = Analyze|x64 @@ -43,12 +41,6 @@ Global {3C4797F9-603E-44EF-8E8C-9275CC9EA74B}.Debug|x64.Build.0 = Debug|x64 {3C4797F9-603E-44EF-8E8C-9275CC9EA74B}.Release|x64.ActiveCfg = Release|x64 {3C4797F9-603E-44EF-8E8C-9275CC9EA74B}.Release|x64.Build.0 = Release|x64 - {38B7E4A1-FDDD-486C-98EE-BA7B13712528}.Analyze|x64.ActiveCfg = Release|x64 - {38B7E4A1-FDDD-486C-98EE-BA7B13712528}.Analyze|x64.Build.0 = Release|x64 - {38B7E4A1-FDDD-486C-98EE-BA7B13712528}.Debug|x64.ActiveCfg = Debug|x64 - {38B7E4A1-FDDD-486C-98EE-BA7B13712528}.Debug|x64.Build.0 = Debug|x64 - {38B7E4A1-FDDD-486C-98EE-BA7B13712528}.Release|x64.ActiveCfg = Release|x64 - {38B7E4A1-FDDD-486C-98EE-BA7B13712528}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Projects/Benchmarks/Benchmarks.csproj b/Projects/Benchmarks/Benchmarks.csproj deleted file mode 100644 index 2720cb6da..000000000 --- a/Projects/Benchmarks/Benchmarks.csproj +++ /dev/null @@ -1,18 +0,0 @@ - - - Exe - net6.0 - x64 - x64 - 9 - true - true - - - - - - - - - diff --git a/Projects/Benchmarks/Benchmarks/Collections/BenchmarkOrderedHashSet.cs b/Projects/Benchmarks/Benchmarks/Collections/BenchmarkOrderedHashSet.cs deleted file mode 100644 index b9ec3d676..000000000 --- a/Projects/Benchmarks/Benchmarks/Collections/BenchmarkOrderedHashSet.cs +++ /dev/null @@ -1,130 +0,0 @@ -using System.Collections.Generic; -using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Jobs; -using Server.Collections; - -namespace Benchmarks -{ - [MemoryDiagnoser] - [SimpleJob(RuntimeMoniker.Net60)] - public class BenchmarkOrderedHashSet - { - private readonly string[] _iterations = new string[16]; - - [IterationSetup] - public void IterationSetup() - { - for (var i = 0; i < _iterations.Length; i++) - { - _iterations[i] = i.ToString(); - } - } - - [Benchmark] - public int UsingList() - { - var list = new List(); - for (int i = 0; i < _iterations.Length / 2; i++) - { - AddIfNotPresent(list, _iterations[i]); - } - - for (int i = 0; i < _iterations.Length; i++) - { - AddIfNotPresent(list, _iterations[i]); - } - - for (int i = 0; i < list.Count; i++) - { - list[i].ToString(); - } - - return list.Count; - } - - private static int AddIfNotPresent(List list, T item) - { - var index = list.IndexOf(item); - if (index > -1) - { - return index; - } - - list.Add(item); - return list.Count - 1; - } - - [Benchmark] - public int UsingOrderedHashSet() - { - var ordered = new OrderedHashSet(); - for (int i = 0; i < _iterations.Length / 2; i++) - { - ordered.GetOrAdd(_iterations[i]).ToString(); - } - - for (int i = 0; i < _iterations.Length; i++) - { - ordered.GetOrAdd(_iterations[i]).ToString(); - } - - foreach (var str in ordered) - { - str.ToString(); - } - - return ordered.Count; - } - - [Benchmark] - public int UsingPooledOrderedHashSet() - { - var ordered = new PooledOrderedHashSet(); - for (int i = 0; i < _iterations.Length / 2; i++) - { - ordered.GetOrAdd(_iterations[i]).ToString(); - } - - for (int i = 0; i < _iterations.Length; i++) - { - ordered.GetOrAdd(_iterations[i]).ToString(); - } - - foreach (var str in ordered) - { - str.ToString(); - } - - return ordered.Count; - } - - [Benchmark] - public int UsingHashSet() - { - var hashSet = new HashSet<(string, int)>(new OrderedStringComparer()); - for (int i = 0; i < _iterations.Length / 2; i++) - { - hashSet.Add((_iterations[i], i)); - } - - for (int i = 0; i < _iterations.Length; i++) - { - hashSet.Add((_iterations[i], i)); - } - - foreach (var str in hashSet) - { - str.ToString(); - } - - return hashSet.Count; - } - - private class OrderedStringComparer : EqualityComparer<(string, int)> - { - public override bool Equals((string, int) x, (string, int) y) => x.Item1.Equals(y.Item1, System.StringComparison.Ordinal); - - public override int GetHashCode((string, int) obj) => obj.Item1.GetHashCode(); - } - } -} diff --git a/Projects/Benchmarks/Benchmarks/Collections/BenchmarkPooledRefQueue.cs b/Projects/Benchmarks/Benchmarks/Collections/BenchmarkPooledRefQueue.cs deleted file mode 100644 index f72dcd7af..000000000 --- a/Projects/Benchmarks/Benchmarks/Collections/BenchmarkPooledRefQueue.cs +++ /dev/null @@ -1,95 +0,0 @@ -using System.Buffers; -using System.Collections.Generic; -using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Jobs; -using Server.Buffers; -using Server.Collections; - -namespace Benchmarks -{ - [MemoryDiagnoser] - [SimpleJob(RuntimeMoniker.Net60)] - public class BenchmarkPooledRefQueue - { - [GlobalSetup] - public void Setup() - { - // Allocate - var arrays = new long[16][]; - for (var i = 0; i < 16; i++) - { - arrays[i] = ArrayPool.Shared.Rent(64); - } - - var stArrays = new long[16][]; - for (var i = 0; i < 16; i++) - { - stArrays[i] = STArrayPool.Shared.Rent(64); - } - - for (var i = 0; i < 16; i++) - { - ArrayPool.Shared.Return(arrays[i]); - } - - for (var i = 0; i < 16; i++) - { - STArrayPool.Shared.Return(stArrays[i]); - } - } - - [Benchmark] - public void UseQueue() - { - for (var i = 0; i < 8; i++) - { - var queue = new Queue(); - for (var j = 0; j < 32; j++) - { - queue.Enqueue(j); - } - - for (var j = 0; j < 32; j++) - { - var num = queue.Dequeue(); - } - } - } - - [Benchmark] - public void UsePooledRefQueue() - { - for (var i = 0; i < 8; i++) - { - using var queue = PooledRefQueue.Create(); - for (var j = 0; j < 32; j++) - { - queue.Enqueue(j); - } - - for (var j = 0; j < 32; j++) - { - var num = queue.Dequeue(); - } - } - } - - [Benchmark] - public void UsePooledRefQueueMT() - { - for (var i = 0; i < 8; i++) - { - using var queue = PooledRefQueue.CreateMT(); - for (var j = 0; j < 32; j++) - { - queue.Enqueue(j); - } - - for (var j = 0; j < 32; j++) - { - var num = queue.Dequeue(); - } - } - } - } -} diff --git a/Projects/Benchmarks/Benchmarks/Collections/BenchmarkSTArray.cs b/Projects/Benchmarks/Benchmarks/Collections/BenchmarkSTArray.cs deleted file mode 100644 index 78be46dd9..000000000 --- a/Projects/Benchmarks/Benchmarks/Collections/BenchmarkSTArray.cs +++ /dev/null @@ -1,92 +0,0 @@ -using System.Buffers; -using System.Collections.Generic; -using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Jobs; -using Server.Buffers; - -namespace Benchmarks -{ - [MemoryDiagnoser] - [SimpleJob(RuntimeMoniker.Net60)] - public class BenchmarkSTArray - { - private static long[][] arrays = new long[16][]; - private static long[][] stArrays = new long[16][]; - private static long[][] newArrays = new long[16][]; - private static Queue[] newQueue = new Queue[16]; - - [GlobalSetup] - public void Setup() - { - // Allocate - arrays = new long[16][]; - for (var i = 0; i < 16; i++) - { - arrays[i] = ArrayPool.Shared.Rent(64); - } - - stArrays = new long[16][]; - for (var i = 0; i < 16; i++) - { - stArrays[i] = STArrayPool.Shared.Rent(64); - } - - for (var i = 0; i < 16; i++) - { - ArrayPool.Shared.Return(arrays[i]); - } - - for (var i = 0; i < 16; i++) - { - STArrayPool.Shared.Return(stArrays[i]); - } - } - - [Benchmark] - public void ArrayPool() - { - for (var i = 0; i < 8; i++) - { - arrays[i] = ArrayPool.Shared.Rent(64); - } - - for (var i = 0; i < 8; i++) - { - ArrayPool.Shared.Return(arrays[i], true); - } - } - - [Benchmark] - public void STArrayPool() - { - for (var i = 0; i < 8; i++) - { - arrays[i] = STArrayPool.Shared.Rent(64); - } - - for (var i = 0; i < 8; i++) - { - STArrayPool.Shared.Return(arrays[i], true); - } - } - - [Benchmark] - public void NewArray() - { - for (var i = 0; i < 8; i++) - { - newArrays[i] = new long[64]; - } - } - - [Benchmark] - public void NewQueue() - { - for (var i = 0; i < 8; i++) - { - newQueue[i] = new Queue(); - newQueue[i].EnsureCapacity(64); - } - } - } -} diff --git a/Projects/Benchmarks/Benchmarks/Logging/BenchmarkConsoleLogging.cs b/Projects/Benchmarks/Benchmarks/Logging/BenchmarkConsoleLogging.cs deleted file mode 100644 index f794d64b4..000000000 --- a/Projects/Benchmarks/Benchmarks/Logging/BenchmarkConsoleLogging.cs +++ /dev/null @@ -1,63 +0,0 @@ -using System; -using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Jobs; -using Serilog; -using Serilog.Core; - -namespace Benchmarks -{ - [SimpleJob(RuntimeMoniker.Net60)] - public class BenchmarkConsoleLogging - { - private const string text = "Sample message"; - - private Logger logger; - private Logger asyncLogger; - - [GlobalSetup] - public void GlobalSetup() - { - logger = new LoggerConfiguration() - .WriteTo.Console() - .CreateLogger(); - - asyncLogger = new LoggerConfiguration() - .WriteTo.Async(a => a.Console()) - .CreateLogger(); - } - - [GlobalCleanup] - public void GlobalCleanup() - { - logger = null; - asyncLogger = null; - } - - [Benchmark] - public void TestConsoleWriteLine() - { - for (int i = 0; i < 10000; i++) - { - Console.WriteLine(text); - } - } - - [Benchmark] - public void TestSerilogConsoleSink() - { - for (int i = 0; i < 10000; i++) - { - logger.Information(text); - } - } - - [Benchmark] - public void TestSerilogAsyncConsoleSink() - { - for (int i = 0; i < 10000; i++) - { - asyncLogger.Information(text); - } - } - } -} diff --git a/Projects/Benchmarks/Benchmarks/Map/MapEntitiesSelectors.cs b/Projects/Benchmarks/Benchmarks/Map/MapEntitiesSelectors.cs deleted file mode 100644 index 7c70d3056..000000000 --- a/Projects/Benchmarks/Benchmarks/Map/MapEntitiesSelectors.cs +++ /dev/null @@ -1,545 +0,0 @@ -using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Jobs; -using NetFabric.Hyperlinq; -using Server; -using System; -using System.Collections.Generic; -using System.Linq; -using static NetFabric.Hyperlinq.ArrayExtensions; - -namespace Benchmarks.EntitiesSelectors -{ - [SimpleJob(RuntimeMoniker.Net60)] - [MemoryDiagnoser] - public class MapEntitiesSelectors - { - private static readonly Sector sector = new(); - private static readonly Point3D[] locations = { new Point3D(0, 0, 0), new Point3D(50, 50, 0) }; - - public static Rectangle2D[] BoundsArray() => new[] - { - new Rectangle2D(70, 70, 100, 100), - new Rectangle2D(30, 30, 100, 100), - new Rectangle2D(0, 0, 100, 100), - }; - - [GlobalSetup] - public static void Init() - { - for (int j = 0; j < locations.Length; j++) - { - Point3D loc = locations[j]; - - for (int i = 0; i < 500; ++i) - { - sector.BItems.Add(new BItem(loc)); - } - - for (int i = 0; i < 25; ++i) - { - sector.Mobiles.Add(new Mobile(loc)); - } - } - } - - [ParamsSource(nameof(BoundsArray))] - public Rectangle2D bounds; - - [Benchmark(Baseline = true)] - public IEntity SelectEntitiesFor() - { - IEntity toRet = null; - for (int i = sector.Mobiles.Count - 1; i >= 0; --i) - { - Mobile mob = sector.Mobiles[i]; - if (mob is { Deleted: false } tMob && bounds.Contains(mob.Location)) - { - toRet = tMob; - } - } - - for (int i = sector.BItems.Count - 1; i >= 0; --i) - { - BItem item = sector.BItems[i]; - if (item is { Deleted: false, Parent: null } tItem && bounds.Contains(item.Location)) - { - toRet = tItem; - } - } - - return toRet; - } - - [Benchmark] - public IEntity SelectEntitiesNew() - { - IEntity toRet = null; - foreach (IEntity e in SelectEntitiesNew(sector, bounds)) - { - toRet = e; - } - - return toRet; - } - - [Benchmark] - public IEntity SelectEntitiesLinq() - { - IEntity toRet = null; - foreach (IEntity e in SelectEntitiesLinq(sector, bounds)) - { - toRet = e; - } - - return toRet; - } - - [Benchmark] - public IEntity SelectMobilesHyperLinq() - { - IEntity toRet = null; - foreach (IEntity e in SelectEntitiesHyperlinq(sector, bounds)) - { - toRet = e; - } - - return toRet; - } - - - public IEnumerable SelectEntitiesLinq(Sector s, Rectangle2D bounds) - { - return Enumerable.Empty() - .Union(s.Mobiles.Where(o => o is { Deleted: false } && bounds.Contains(o.Location))) - .Union(s.BItems.Where(o => o is { Deleted: false, Parent: null } && bounds.Contains(o.Location))); - } - - private readonly List entities = new(10); - - public IEnumerable SelectEntitiesNew(Sector s, Rectangle2D bounds) - { - entities.Clear(); - entities.EnsureCapacity(s.Mobiles.Count + s.BItems.Count); - - for (int i = s.Mobiles.Count - 1, j = s.BItems.Count - 1; i >= 0 || j >= 0; --i, --j) - { - if (j >= 0) - { - BItem BItem = s.BItems[j]; - if (BItem is { Deleted: false, Parent: null } && bounds.Contains(BItem.Location)) - { - entities.Add(BItem); - } - } - if (i >= 0) - { - Mobile mob = s.Mobiles[i]; - if (mob is { Deleted: false } && bounds.Contains(mob.Location)) - { - entities.Add(mob); - } - } - } - return entities; - } - - public IEnumerable SelectEntitiesHyperlinq(Sector s, Rectangle2D bounds) - { - ArraySegmentWhereSelectEnumerable> mobiles = - s.Mobiles.AsValueEnumerable().Where(new MobileWhereHyper(bounds)).Select>(); - - ArraySegmentWhereSelectEnumerable> items = - s.BItems.AsValueEnumerable().Where(new BItemWhereHyper(bounds)).Select>(); - - return mobiles.Concat(items); - } - } - - public class BItem : IPoint3D, IEntity - { - public object Parent { get; set; } = null; - - public bool Deleted { get; set; } = false; - - public int Z { get; set; } = 1; - - public int X { get; set; } = 1; - - public int Y { get; set; } = 1; - - public Serial Serial => throw new NotImplementedException(); - - public Point3D Location { get; } - public Map Map { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - public Region Region => throw new NotImplementedException(); - - public string Name { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - public int Hue { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - public Direction Direction { get => throw new System.NotImplementedException(); set => throw new NotImplementedException(); } - public DateTime Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - public int TypeRef => throw new NotImplementedException(); - - Point3D IEntity.Location => Location; - - Map IEntity.Map => throw new NotImplementedException(); - - int IPoint3D.Z => throw new NotImplementedException(); - - int IPoint2D.X => throw new NotImplementedException(); - - int IPoint2D.Y => throw new NotImplementedException(); - - DateTime ISerializable.Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - DateTime ISerializable.LastSerialized { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - long ISerializable.SavePosition { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - BufferWriter ISerializable.SaveBuffer { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - int ISerializable.TypeRef => throw new NotImplementedException(); - - Serial ISerializable.Serial => throw new NotImplementedException(); - - bool ISerializable.Deleted => throw new NotImplementedException(); - - public BItem(Point3D location) - { - Location = location; - } - - public void Delete() - { - throw new NotImplementedException(); - } - - public void ProcessDelta() - { - throw new NotImplementedException(); - } - - public void OnStatsQuery(Server.Mobile m) - { - throw new NotImplementedException(); - } - - public void InvalidateProperties() - { - throw new NotImplementedException(); - } - - public int CompareTo(object obj) - { - throw new NotImplementedException(); - } - - public int CompareTo(IEntity other) - { - throw new NotImplementedException(); - } - - public void MoveToWorld(Point3D location, Map map) - { - throw new NotImplementedException(); - } - - public bool InRange(Point2D p, int range) - { - throw new NotImplementedException(); - } - - public bool InRange(Point3D p, int range) - { - throw new NotImplementedException(); - } - - public void RemoveBItem(BItem BItem) - { - throw new NotImplementedException(); - } - - public void BeforeSerialize() - { - throw new NotImplementedException(); - } - - public void Deserialize(IGenericReader reader) - { - throw new NotImplementedException(); - } - - public void Serialize(IGenericWriter writer) - { - throw new NotImplementedException(); - } - - public void SetTypeRef(Type type) - { - throw new NotImplementedException(); - } - - void IEntity.MoveToWorld(Point3D location, Map map) - { - throw new NotImplementedException(); - } - - void IEntity.ProcessDelta() - { - throw new NotImplementedException(); - } - - bool IEntity.InRange(Point2D p, int range) - { - throw new NotImplementedException(); - } - - bool IEntity.InRange(Point3D p, int range) - { - throw new NotImplementedException(); - } - - void ISerializable.BeforeSerialize() - { - throw new NotImplementedException(); - } - - void ISerializable.Deserialize(IGenericReader reader) - { - throw new NotImplementedException(); - } - - void ISerializable.Serialize(IGenericWriter writer) - { - throw new NotImplementedException(); - } - - void ISerializable.Delete() - { - throw new NotImplementedException(); - } - - void ISerializable.SetTypeRef(Type type) - { - throw new NotImplementedException(); - } - - public void RemoveItem(Item item) - { - throw new NotImplementedException(); - } - } - - public class Mobile : IPoint3D, IEntity - { - public bool Deleted { get; set; } = false; - - public int Z { get; set; } = 1; - - public int X { get; set; } = 1; - - public int Y { get; set; } = 1; - - public Serial Serial => throw new NotImplementedException(); - - public Point3D Location { get; } - public Map Map { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - public Region Region => throw new NotImplementedException(); - - public string Name { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - public int Hue { get => throw new System.NotImplementedException(); set => throw new NotImplementedException(); } - public Direction Direction { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - public DateTime Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - public int TypeRef => throw new NotImplementedException(); - - Point3D IEntity.Location => Location; - - Map IEntity.Map => throw new NotImplementedException(); - - int IPoint3D.Z => throw new NotImplementedException(); - - int IPoint2D.X => throw new NotImplementedException(); - - int IPoint2D.Y => throw new NotImplementedException(); - - DateTime ISerializable.Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - DateTime ISerializable.LastSerialized { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - long ISerializable.SavePosition { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - BufferWriter ISerializable.SaveBuffer { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - int ISerializable.TypeRef => throw new NotImplementedException(); - - Serial ISerializable.Serial => throw new NotImplementedException(); - - bool ISerializable.Deleted => throw new NotImplementedException(); - - public Mobile(Point3D location) - { - Location = location; - } - - public void Delete() - { - throw new NotImplementedException(); - } - - public void ProcessDelta() - { - throw new NotImplementedException(); - } - - public void OnStatsQuery(Server.Mobile m) - { - throw new NotImplementedException(); - } - - public void InvalidateProperties() - { - throw new NotImplementedException(); - } - - public int CompareTo(object obj) - { - throw new NotImplementedException(); - } - - public int CompareTo(IEntity other) - { - throw new NotImplementedException(); - } - - public void MoveToWorld(Point3D location, Map map) - { - throw new NotImplementedException(); - } - - public bool InRange(Point2D p, int range) - { - throw new NotImplementedException(); - } - - public bool InRange(Point3D p, int range) - { - throw new NotImplementedException(); - } - - public void RemoveBItem(BItem BItem) - { - throw new NotImplementedException(); - } - - public void BeforeSerialize() - { - throw new NotImplementedException(); - } - - public void Deserialize(IGenericReader reader) - { - throw new NotImplementedException(); - } - - public void Serialize(IGenericWriter writer) - { - throw new NotImplementedException(); - } - - public void SetTypeRef(Type type) - { - throw new NotImplementedException(); - } - - void IEntity.MoveToWorld(Point3D location, Map map) - { - throw new NotImplementedException(); - } - - void IEntity.ProcessDelta() - { - throw new NotImplementedException(); - } - - bool IEntity.InRange(Point2D p, int range) - { - throw new NotImplementedException(); - } - - bool IEntity.InRange(Point3D p, int range) - { - throw new NotImplementedException(); - } - - void ISerializable.BeforeSerialize() - { - throw new NotImplementedException(); - } - - void ISerializable.Deserialize(IGenericReader reader) - { - throw new NotImplementedException(); - } - - void ISerializable.Serialize(IGenericWriter writer) - { - throw new NotImplementedException(); - } - - void ISerializable.Delete() - { - throw new NotImplementedException(); - } - - void ISerializable.SetTypeRef(Type type) - { - throw new NotImplementedException(); - } - - public void RemoveItem(Item item) - { - throw new NotImplementedException(); - } - } - - public class Sector - { - public List BItems { get; set; } = new(); - public List Mobiles { get; set; } = new(); - } - - public struct BItemWhereHyper : NetFabric.Hyperlinq.IFunction - { - private readonly Rectangle2D bounds; - - public BItemWhereHyper(Rectangle2D bounds) - { - this.bounds = bounds; - } - - public bool Invoke(BItem element) - { - return element is { Deleted: false, Parent: null } && bounds.Contains(element.Location); - } - } - - public struct MobileWhereHyper : NetFabric.Hyperlinq.IFunction - { - private readonly Rectangle2D bounds; - - public MobileWhereHyper(Rectangle2D bounds) - { - this.bounds = bounds; - } - - public bool Invoke(Mobile element) - { - return element is { Deleted: false } && bounds.Contains(element.Location); - } - } - - public struct SelectHyper : NetFabric.Hyperlinq.IFunction where TSource : TDest - { - public TDest Invoke(TSource arg) - { - return arg; - } - } -} diff --git a/Projects/Benchmarks/Benchmarks/Map/MapItemSelectors.cs b/Projects/Benchmarks/Benchmarks/Map/MapItemSelectors.cs deleted file mode 100644 index 43f5179c0..000000000 --- a/Projects/Benchmarks/Benchmarks/Map/MapItemSelectors.cs +++ /dev/null @@ -1,403 +0,0 @@ -using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Jobs; -using NetFabric.Hyperlinq; -using Server; -using StructLinq; -using StructLinq.Array; -using StructLinq.List; -using StructLinq.Select; -using StructLinq.Where; -using System; -using System.Buffers; -using System.Collections.Generic; -using System.Linq; -using static NetFabric.Hyperlinq.ArrayExtensions; - -namespace Benchmarks.ItemSelectors -{ - [SimpleJob(RuntimeMoniker.Net60)] - [MemoryDiagnoser] - public class MapItemSelectors - { - private static readonly Sector sector = new(); - private static readonly Point3D[] locations = { new Point3D(0, 0, 0), new Point3D(50, 50, 0) }; - - public static Rectangle2D[] BoundsArray() => new[] - { - new Rectangle2D(70, 70, 100, 100), - new Rectangle2D(30, 30, 100, 100), - new Rectangle2D(0, 0, 100, 100), - }; - - [GlobalSetup] - public static void Init() - { - for (int j = 0; j < locations.Length; j++) - { - Point3D loc = locations[j]; - - for (int i = 0; i < 500; ++i) - { - sector.BItems.Add(new BItemDerived(loc)); - } - } - } - - [ParamsSource(nameof(BoundsArray))] - public Rectangle2D bounds; - - [Benchmark(Baseline = true)] - public BItemDerived SelectBItemsFor() - { - BItemDerived toRet = null; - for (int i = sector.BItems.Count - 1; i >= 0; --i) - { - BItem BItem = sector.BItems[i]; - if (BItem is BItemDerived { Deleted: false, Parent: null } tItem && bounds.Contains(BItem.Location)) - { - toRet = tItem; - } - } - - return toRet; - } - - [Benchmark] - public BItemDerived SelectBItemsNew() - { - BItemDerived toRet = null; - foreach (BItemDerived i in SelectBItems(sector, bounds)) - { - toRet = i; - } - - return toRet; - } - - [Benchmark] - public BItemDerived SelectBItemsLinq() - { - BItemDerived toRet = null; - foreach (BItemDerived i in SelectBItemsLinq(sector, bounds)) - { - toRet = i; - } - - return toRet; - } - - [Benchmark] - public BItemDerived SelectBItemsLinqStruct() - { - BItemDerived toRet = null; - foreach (BItemDerived i in SelectBItemsLinqStruct(sector, bounds)) - { - toRet = i; - } - - return toRet; - } - - [Benchmark] - public BItemDerived SelectBItemsLinqStructInterface() - { - BItemDerived toRet = null; - IEnumerable enumerable = SelectBItemsLinqStruct(sector, bounds).ToEnumerable(); - - foreach (BItemDerived i in enumerable) - { - toRet = i; - } - - return toRet; - } - - [Benchmark] - public BItemDerived SelectBItemsHyperLinq() - { - BItemDerived toRet = null; - foreach (BItemDerived i in SelectBItemsHyperlinq(sector, bounds)) - { - toRet = i; - } - - return toRet; - } - - [Benchmark] - public BItemDerived SelectBItemsHyperLinqInterface() - { - BItemDerived toRet = null; - IEnumerable enumerable = SelectBItemsHyperlinq(sector, bounds); - - foreach (BItemDerived i in enumerable) - { - toRet = i; - } - - return toRet; - } - - [Benchmark] - public BItemDerived SelectBItemsHyperLinqArrayPool() - { - BItemDerived toRet = null; - using Lease lease = SelectBItemsHyperlinq(sector, bounds).ToArray(ArrayPool.Shared); - - foreach (BItemDerived i in lease) - { - toRet = i; - } - - return toRet; - } - - public IEnumerable SelectBItemsLinq(Sector s, Rectangle2D bounds) where T : BItem - { - return s.BItems.OfType().Where(o => o is { Deleted: false, Parent: null } && bounds.Contains(o.Location)); - } - - public IEnumerable SelectBItems(Sector s, Rectangle2D bounds) where T : BItem - { - List items = s.BItems; - List entities = new(items.Count); - - for (int i = items.Count - 1; i >= 0; --i) - { - if (items[i] is T { Deleted: false, Parent: null } tItem && bounds.Contains(tItem.Location)) - { - entities.Add(tItem); - } - } - return entities; - } - - public SelectEnumerable, ArrayStructEnumerator, BItemWhere>, - WhereEnumerator, BItemWhere>, BItemSelect> - SelectBItemsLinqStruct(Sector s, Rectangle2D bounds) where T : BItem - { - BItemWhere bitemWhere = new(bounds); - BItemSelect bitemSelect = new(); - - return s.BItems.ToStructEnumerable() - .Where(ref bitemWhere, x => x) - .Select(ref bitemSelect, x => x, x => x); - } - - public ArraySegmentWhereSelectEnumerable, SelectHyper> - SelectBItemsHyperlinq(Sector s, Rectangle2D bounds) where T : BItem - { - return s.BItems.AsValueEnumerable() - .Where(new BItemWhereHyper(bounds)) - .Select>(); - } - } - - public class BItem : IPoint3D, IEntity - { - public object Parent { get; set; } = null; - - public bool Deleted { get; set; } = false; - - public int Z { get; set; } = 1; - - public int X { get; set; } = 1; - - public int Y { get; set; } = 1; - - public Serial Serial => throw new NotImplementedException(); - - public Point3D Location { get; } - - public Map Map { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - public Region Region => throw new NotImplementedException(); - - public string Name { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - public int Hue { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - public Direction Direction { get => throw new System.NotImplementedException(); set => throw new NotImplementedException(); } - public DateTime Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - public int TypeRef => throw new NotImplementedException(); - - Point3D IEntity.Location => Location; - - int IPoint3D.Z => throw new NotImplementedException(); - - int IPoint2D.X => throw new NotImplementedException(); - - int IPoint2D.Y => throw new NotImplementedException(); - - DateTime ISerializable.Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - DateTime ISerializable.LastSerialized { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - long ISerializable.SavePosition { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - BufferWriter ISerializable.SaveBuffer { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - int ISerializable.TypeRef => throw new NotImplementedException(); - - Serial ISerializable.Serial => throw new NotImplementedException(); - - bool ISerializable.Deleted => throw new NotImplementedException(); - - public BItem(Point3D location) - { - Location = location; - } - - public void Delete() - { - throw new NotImplementedException(); - } - - public void ProcessDelta() - { - throw new NotImplementedException(); - } - - public void OnStatsQuery(Server.Mobile m) - { - throw new NotImplementedException(); - } - - public void InvalidateProperties() - { - throw new NotImplementedException(); - } - - public int CompareTo(object obj) - { - throw new NotImplementedException(); - } - - public int CompareTo(IEntity other) - { - throw new NotImplementedException(); - } - - public void MoveToWorld(Point3D location, Map map) - { - throw new NotImplementedException(); - } - - public bool InRange(Point2D p, int range) - { - throw new NotImplementedException(); - } - - public bool InRange(Point3D p, int range) - { - throw new NotImplementedException(); - } - - public void RemoveBItem(BItem BItem) - { - throw new NotImplementedException(); - } - - public void BeforeSerialize() - { - throw new NotImplementedException(); - } - - public void Deserialize(IGenericReader reader) - { - throw new NotImplementedException(); - } - - public void Serialize(IGenericWriter writer) - { - throw new NotImplementedException(); - } - - public void SetTypeRef(Type type) - { - throw new NotImplementedException(); - } - - void ISerializable.BeforeSerialize() - { - throw new NotImplementedException(); - } - - void ISerializable.Deserialize(IGenericReader reader) - { - throw new NotImplementedException(); - } - - void ISerializable.Serialize(IGenericWriter writer) - { - throw new NotImplementedException(); - } - - void ISerializable.Delete() - { - throw new NotImplementedException(); - } - - void ISerializable.SetTypeRef(Type type) - { - throw new NotImplementedException(); - } - - public void RemoveItem(Item item) - { - throw new NotImplementedException(); - } - } - - public class BItemDerived : BItem - { - public BItemDerived(Point3D location) : base(location) { } - } - - public class Sector - { - public List BItems { get; set; } = new(); - } - - public struct BItemWhere : StructLinq.IFunction where T : BItem - { - private readonly Rectangle2D bounds; - - public BItemWhere(Rectangle2D bounds) - { - this.bounds = bounds; - } - - public bool Eval(BItem element) - { - return element is T { Deleted: false, Parent: null } && bounds.Contains(element.Location); - } - } - - public struct BItemSelect : StructLinq.IFunction where T : BItem - { - public T Eval(BItem element) - { - return (T)element; - } - } - - public struct BItemWhereHyper : NetFabric.Hyperlinq.IFunction where T : BItem - { - private readonly Rectangle2D bounds; - - public BItemWhereHyper(Rectangle2D bounds) - { - this.bounds = bounds; - } - - public bool Invoke(BItem element) - { - return element is T { Deleted: false, Parent: null } && bounds.Contains(element.Location); - } - } - - public struct SelectHyper : NetFabric.Hyperlinq.IFunction where TDest : TSource - { - public TDest Invoke(TSource arg) - { - return (TDest)arg; - } - } -} diff --git a/Projects/Benchmarks/Benchmarks/Map/MapMobileSelectors.cs b/Projects/Benchmarks/Benchmarks/Map/MapMobileSelectors.cs deleted file mode 100644 index a259981f0..000000000 --- a/Projects/Benchmarks/Benchmarks/Map/MapMobileSelectors.cs +++ /dev/null @@ -1,254 +0,0 @@ -using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Jobs; -using NetFabric.Hyperlinq; -using Server; -using System; -using System.Collections.Generic; -using System.Linq; -using static NetFabric.Hyperlinq.ArrayExtensions; - -namespace Benchmarks.MobileSelectors -{ - [SimpleJob(RuntimeMoniker.Net60)] - [MemoryDiagnoser] - public class MapMobileSelectors - { - private static readonly Sector sector = new(); - private static readonly Point3D[] locations = { new Point3D(0, 0, 0), new Point3D(50, 50, 0) }; - - public static Rectangle2D[] BoundsArray() => new[] - { - new Rectangle2D(70, 70, 100, 100), - new Rectangle2D(30, 30, 100, 100), - new Rectangle2D(0, 0, 100, 100), - }; - - [GlobalSetup] - public static void Init() - { - for (int j = 0; j < locations.Length; j++) - { - Point3D loc = locations[j]; - - for (int i = 0; i < 500; ++i) - { - sector.Mobiles.Add(new MobileDerived(loc)); - } - } - } - - [ParamsSource(nameof(BoundsArray))] - public Rectangle2D bounds; - - [Benchmark(Baseline = true)] - public MobileDerived SelectMobilesFor() - { - MobileDerived toRet = null; - for (int i = sector.Mobiles.Count - 1; i >= 0; --i) - { - Mobile mob = sector.Mobiles[i]; - if (mob is MobileDerived { Deleted: false } tMob && bounds.Contains(mob.Location)) - { - toRet = tMob; - } - } - - return toRet; - } - - [Benchmark] - public MobileDerived SelectMobilesNew() - { - MobileDerived toRet = null; - foreach (MobileDerived m in SelectMobiles(sector, bounds)) - { - toRet = m; - } - - return toRet; - } - - [Benchmark] - public MobileDerived SelectMobilesLinq() - { - MobileDerived toRet = null; - foreach (MobileDerived m in SelectMobilesLinq(sector, bounds)) - { - toRet = m; - } - - return toRet; - } - - [Benchmark] - public MobileDerived SelectMobilesHyperLinq() - { - MobileDerived toRet = null; - foreach (MobileDerived m in SelectMobilesHyperlinq(sector, bounds)) - { - toRet = m; - } - - return toRet; - } - - public IEnumerable SelectMobilesLinq(Sector s, Rectangle2D bounds) where T : Mobile - { - return s.Mobiles.OfType().Where(o => o is { Deleted: false } && bounds.Contains(o.Location)); - } - - public IEnumerable SelectMobiles(Sector s, Rectangle2D bounds) where T : Mobile - { - List mobiles = s.Mobiles; - List entities = new(mobiles.Count); - - for (int i = mobiles.Count - 1; i >= 0; --i) - { - if (mobiles[i] is T { Deleted: false } tMob && bounds.Contains(tMob.Location)) - { - entities.Add(tMob); - } - } - return entities; - } - - public ArraySegmentWhereSelectEnumerable, SelectHyper> - SelectMobilesHyperlinq(Sector s, Rectangle2D bounds) where T : Mobile - { - return s.Mobiles.AsValueEnumerable() - .Where(new MobileWhereHyper(bounds)) - .Select>(); - } - } - - public class Mobile : IPoint3D, IEntity - { - public bool Deleted { get; set; } = false; - - public int Z { get; set; } = 1; - - public int X { get; set; } = 1; - - public int Y { get; set; } = 1; - - public Serial Serial => throw new NotImplementedException(); - - public Point3D Location { get; } - - public Map Map { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - public Region Region => throw new NotImplementedException(); - - public string Name { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - public int Hue { get => throw new System.NotImplementedException(); set => throw new NotImplementedException(); } - public Direction Direction { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - public DateTime Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - public int TypeRef => throw new NotImplementedException(); - - int IPoint3D.Z => throw new NotImplementedException(); - - int IPoint2D.X => throw new NotImplementedException(); - - int IPoint2D.Y => throw new NotImplementedException(); - - DateTime ISerializable.Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - DateTime ISerializable.LastSerialized { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - long ISerializable.SavePosition { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - BufferWriter ISerializable.SaveBuffer { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - int ISerializable.TypeRef => throw new NotImplementedException(); - - Serial ISerializable.Serial => throw new NotImplementedException(); - - bool ISerializable.Deleted => throw new NotImplementedException(); - - public Mobile(Point3D location) - { - Location = location; - } - - public void MoveToWorld(Point3D location, Map map) - { - throw new NotImplementedException(); - } - - public void ProcessDelta() - { - throw new NotImplementedException(); - } - - public bool InRange(Point2D p, int range) - { - throw new NotImplementedException(); - } - - public bool InRange(Point3D p, int range) - { - throw new NotImplementedException(); - } - - public void RemoveItem(Item item) - { - throw new NotImplementedException(); - } - - public void BeforeSerialize() - { - throw new NotImplementedException(); - } - - public void Deserialize(IGenericReader reader) - { - throw new NotImplementedException(); - } - - public void Serialize(IGenericWriter writer) - { - throw new NotImplementedException(); - } - - public void Delete() - { - throw new NotImplementedException(); - } - - public void SetTypeRef(Type type) - { - throw new NotImplementedException(); - } - } - - public class MobileDerived : Mobile - { - public MobileDerived(Point3D location) : base(location) { } - } - - public class Sector - { - public List Mobiles { get; set; } = new(); - } - - public struct MobileWhereHyper : NetFabric.Hyperlinq.IFunction where T : Mobile - { - private readonly Rectangle2D bounds; - - public MobileWhereHyper(Rectangle2D bounds) - { - this.bounds = bounds; - } - - public bool Invoke(Mobile element) - { - return element is T { Deleted: false } && bounds.Contains(element.Location); - } - } - - public struct SelectHyper : NetFabric.Hyperlinq.IFunction where TDest : TSource - { - public TDest Invoke(TSource arg) - { - return (TDest)arg; - } - } -} diff --git a/Projects/Benchmarks/Benchmarks/Map/MapMultiSelectors.cs b/Projects/Benchmarks/Benchmarks/Map/MapMultiSelectors.cs deleted file mode 100644 index 233d6b5e4..000000000 --- a/Projects/Benchmarks/Benchmarks/Map/MapMultiSelectors.cs +++ /dev/null @@ -1,310 +0,0 @@ -using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Jobs; -using NetFabric.Hyperlinq; -using Server; -using System; -using System.Collections.Generic; -using System.Linq; -using static NetFabric.Hyperlinq.ArrayExtensions; - -namespace Benchmarks.MultiSelectors -{ - [SimpleJob(RuntimeMoniker.Net60)] - [MemoryDiagnoser] - public class MapMultiSelectors - { - private static readonly Sector sector = new(); - private static readonly Point3D[] locations = { new Point3D(0, 0, 0), new Point3D(50, 50, 0) }; - - public static Rectangle2D[] BoundsArray() => new[] - { - new Rectangle2D(70, 70, 100, 100), - new Rectangle2D(30, 30, 100, 100), - new Rectangle2D(0, 0, 100, 100), - }; - - [GlobalSetup] - public static void Init() - { - for (int j = 0; j < locations.Length; j++) - { - Point3D loc = locations[j]; - - for (int i = 0; i < 25; ++i) - { - sector.Multis.Add(new BaseMulti(loc)); - } - } - } - - [ParamsSource(nameof(BoundsArray))] - public Rectangle2D bounds; - - [Benchmark(Baseline = true)] - public BaseMulti SelectMultiFor() - { - BaseMulti toRet = null; - for (int i = sector.Multis.Count - 1; i >= 0; --i) - { - BaseMulti multi = sector.Multis[i]; - if (multi is { Deleted: false } tMulti && bounds.Contains(multi.Location)) - { - toRet = tMulti; - } - } - - return toRet; - } - - [Benchmark] - public BaseMulti SelectMultiNew() - { - BaseMulti toRet = null; - foreach (BaseMulti m in SelectMultiNew(sector, bounds)) - { - toRet = m; - } - - return toRet; - } - - [Benchmark] - public BaseMulti SelectMultiLinq() - { - BaseMulti toRet = null; - foreach (BaseMulti m in SelectMultiLinq(sector, bounds)) - { - toRet = m; - } - - return toRet; - } - - [Benchmark] - public BaseMulti SelectMultiHyperLinq() - { - BaseMulti toRet = null; - foreach (BaseMulti m in SelectMultiHyperlinq(sector, bounds)) - { - toRet = m; - } - - return toRet; - } - - public IEnumerable SelectMultiLinq(Sector s, Rectangle2D bounds) - { - return s.Multis.Where(o => o is { Deleted: false } && bounds.Contains(o.Location)); - } - - public IEnumerable SelectMultiNew(Sector s, Rectangle2D bounds) - { - List entities = new(s.Multis.Count); - - for (int i = s.Multis.Count - 1; i >= 0; --i) - { - BaseMulti multiItem = s.Multis[i]; - if (multiItem is { Deleted: false } && bounds.Contains(multiItem.Location)) - { - entities.Add(multiItem); - } - } - return entities; - } - - public ArraySegmentWhereEnumerable - SelectMultiHyperlinq(Sector s, Rectangle2D bounds) - { - return s.Multis.AsValueEnumerable().Where(new MultiWhereHyper(bounds)); - } - } - - public class BItem : IPoint3D, IEntity - { - public object Parent { get; set; } = null; - - public bool Deleted { get; set; } = false; - - public int Z { get; set; } = 1; - - public int X { get; set; } = 1; - - public int Y { get; set; } = 1; - - public Serial Serial => throw new NotImplementedException(); - - public Point3D Location { get; } - - public Map Map { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - public Region Region => throw new NotImplementedException(); - - public string Name { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - public int Hue { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - public Direction Direction { get => throw new System.NotImplementedException(); set => throw new NotImplementedException(); } - public DateTime Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - public int TypeRef => throw new NotImplementedException(); - - int IPoint3D.Z => throw new NotImplementedException(); - - int IPoint2D.X => throw new NotImplementedException(); - - int IPoint2D.Y => throw new NotImplementedException(); - - DateTime ISerializable.Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - DateTime ISerializable.LastSerialized { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - long ISerializable.SavePosition { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - BufferWriter ISerializable.SaveBuffer { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - int ISerializable.TypeRef => throw new NotImplementedException(); - - Serial ISerializable.Serial => throw new NotImplementedException(); - - bool ISerializable.Deleted => throw new NotImplementedException(); - - public BItem(Point3D location) - { - Location = location; - } - - public void Delete() - { - throw new NotImplementedException(); - } - - public void ProcessDelta() - { - throw new NotImplementedException(); - } - - public void OnStatsQuery(Server.Mobile m) - { - throw new NotImplementedException(); - } - - public void InvalidateProperties() - { - throw new NotImplementedException(); - } - - public int CompareTo(object obj) - { - throw new NotImplementedException(); - } - - public int CompareTo(IEntity other) - { - throw new NotImplementedException(); - } - - public void MoveToWorld(Point3D location, Map map) - { - throw new NotImplementedException(); - } - - public bool InRange(Point2D p, int range) - { - throw new NotImplementedException(); - } - - public bool InRange(Point3D p, int range) - { - throw new NotImplementedException(); - } - - public void RemoveBItem(BItem BItem) - { - throw new NotImplementedException(); - } - - public void BeforeSerialize() - { - throw new NotImplementedException(); - } - - public void Deserialize(IGenericReader reader) - { - throw new NotImplementedException(); - } - - public void Serialize(IGenericWriter writer) - { - throw new NotImplementedException(); - } - - public void SetTypeRef(Type type) - { - throw new NotImplementedException(); - } - - void ISerializable.BeforeSerialize() - { - throw new NotImplementedException(); - } - - void ISerializable.Deserialize(IGenericReader reader) - { - throw new NotImplementedException(); - } - - void ISerializable.Serialize(IGenericWriter writer) - { - throw new NotImplementedException(); - } - - void ISerializable.Delete() - { - throw new NotImplementedException(); - } - - void ISerializable.SetTypeRef(Type type) - { - throw new NotImplementedException(); - } - - public void RemoveItem(Item item) - { - throw new NotImplementedException(); - } - } - - public class BaseMulti : BItem - { - public MultiComponentList Components = MultiComponentList.Empty; - - public BaseMulti(Point3D location) : base(location) - { - for (int i = 0; i < 20; ++i) - { - for (int j = 0; j < 20; ++j) - { - for (int z = 0; z < 20; ++z) - { - Components.Add(123, i, j, z); - } - } - } - } - } - - public class Sector - { - public List Multis { get; set; } = new(); - } - - public struct MultiWhereHyper : IFunction - { - private readonly Rectangle2D bounds; - - public MultiWhereHyper(Rectangle2D bounds) - { - this.bounds = bounds; - } - - public bool Invoke(BaseMulti element) - { - return element is { Deleted: false } && bounds.Contains(element.Location); - } - } -} diff --git a/Projects/Benchmarks/Benchmarks/Map/MapMultiTilesSelectors.cs b/Projects/Benchmarks/Benchmarks/Map/MapMultiTilesSelectors.cs deleted file mode 100644 index 8f77aee25..000000000 --- a/Projects/Benchmarks/Benchmarks/Map/MapMultiTilesSelectors.cs +++ /dev/null @@ -1,350 +0,0 @@ -using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Jobs; -using Server; -using System; -using System.Collections.Generic; -using System.Linq; - -namespace Benchmarks.MultiTilesSelectors -{ - [SimpleJob(RuntimeMoniker.Net60)] - [MemoryDiagnoser] - public class MapMultiTilesSelectors - { - private static readonly Sector sector = new(); - private static readonly Point3D[] locations = { new Point3D(0, 0, 0), new Point3D(50, 50, 0) }; - - public static Rectangle2D[] BoundsArray() => new[] - { - new Rectangle2D(70, 70, 100, 100), - new Rectangle2D(30, 30, 100, 100), - new Rectangle2D(0, 0, 100, 100), - }; - - [GlobalSetup] - public static void Init() - { - for (int j = 0; j < locations.Length; j++) - { - Point3D loc = locations[j]; - - for (int i = 0; i < 25; ++i) - { - sector.Multis.Add(new BaseMulti(loc)); - } - } - } - - [ParamsSource(nameof(BoundsArray))] - public Rectangle2D bounds; - - [Benchmark] - public int SelectMultiTilesNew() - { - int toRet = 0; - - foreach (StaticTile[] tiles in SelectMultiTilesNew(sector, bounds)) - { - for (int i = 0; i < tiles.Length; ++i) - { - toRet = tiles[i].ID; - } - } - - return toRet; - } - - [Benchmark(Baseline = true)] - public int SelectMultiTilesLinq() - { - int toRet = 0; - - foreach (StaticTile[] tiles in SelectMultiTilesLinq(sector, bounds)) - { - for (int i = 0; i < tiles.Length; ++i) - { - toRet = tiles[i].ID; - } - } - - return toRet; - } - - public IEnumerable SelectMultiTilesLinq(Sector s, Rectangle2D bounds) - { - foreach (var o in s.Multis.Where(o => o != null && !o.Deleted)) - { - var c = o.Components; - - int x, y, xo, yo; - StaticTile[] t, r; - - for (x = bounds.Start.X; x < bounds.End.X; x++) - { - xo = x - (o.X + c.Min.X); - - if (xo < 0 || xo >= c.Width) - { - continue; - } - - for (y = bounds.Start.Y; y < bounds.End.Y; y++) - { - yo = y - (o.Y + c.Min.Y); - - if (yo < 0 || yo >= c.Height) - { - continue; - } - - t = c.Tiles[xo][yo]; - - if (t.Length <= 0) - { - continue; - } - - r = new StaticTile[t.Length]; - - for (var i = 0; i < t.Length; i++) - { - r[i] = t[i]; - r[i].Z += o.Z; - } - - yield return r; - } - } - } - } - - public IEnumerable SelectMultiTilesNew(Sector s, Rectangle2D bounds) - { - List multis = s.Multis; - - for (int l = multis.Count - 1; l >= 0; --l) - { - if (multis[l] is not { Deleted: false } o) - { - continue; - } - - MultiComponentList c = o.Components; - - int x, y, xo, yo; - StaticTile[] t, r; - - for (x = bounds.Start.X; x < bounds.End.X; x++) - { - xo = x - (o.X + c.Min.X); - - if (xo < 0 || xo >= c.Width) - { - continue; - } - - for (y = bounds.Start.Y; y < bounds.End.Y; y++) - { - yo = y - (o.Y + c.Min.Y); - - if (yo < 0 || yo >= c.Height) - { - continue; - } - - t = c.Tiles[xo][yo]; - - if (t.Length <= 0) - { - continue; - } - - r = new StaticTile[t.Length]; - - for (var i = 0; i < t.Length; i++) - { - r[i] = t[i]; - r[i].Z += o.Z; - } - - yield return r; - } - } - } - } - } - - public class BItem : IPoint3D, IEntity - { - public object Parent { get; set; } = null; - - public bool Deleted { get; set; } = false; - - public int Z { get; set; } = 1; - - public int X { get; set; } = 1; - - public int Y { get; set; } = 1; - - public Serial Serial => throw new NotImplementedException(); - - public Point3D Location { get; } - - public Map Map { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - public Region Region => throw new NotImplementedException(); - - public string Name { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - public int Hue { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - public Direction Direction { get => throw new System.NotImplementedException(); set => throw new NotImplementedException(); } - public DateTime Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - public int TypeRef => throw new NotImplementedException(); - - int IPoint3D.Z => throw new NotImplementedException(); - - int IPoint2D.X => throw new NotImplementedException(); - - int IPoint2D.Y => throw new NotImplementedException(); - - DateTime ISerializable.Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - DateTime ISerializable.LastSerialized { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - long ISerializable.SavePosition { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - BufferWriter ISerializable.SaveBuffer { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - int ISerializable.TypeRef => throw new NotImplementedException(); - - Serial ISerializable.Serial => throw new NotImplementedException(); - - bool ISerializable.Deleted => throw new NotImplementedException(); - - public BItem(Point3D location) - { - Location = location; - } - - public void Delete() - { - throw new NotImplementedException(); - } - - public void ProcessDelta() - { - throw new NotImplementedException(); - } - - public void OnStatsQuery(Server.Mobile m) - { - throw new NotImplementedException(); - } - - public void InvalidateProperties() - { - throw new NotImplementedException(); - } - - public int CompareTo(object obj) - { - throw new NotImplementedException(); - } - - public int CompareTo(IEntity other) - { - throw new NotImplementedException(); - } - - public void MoveToWorld(Point3D location, Map map) - { - throw new NotImplementedException(); - } - - public bool InRange(Point2D p, int range) - { - throw new NotImplementedException(); - } - - public bool InRange(Point3D p, int range) - { - throw new NotImplementedException(); - } - - public void RemoveBItem(BItem BItem) - { - throw new NotImplementedException(); - } - - public void BeforeSerialize() - { - throw new NotImplementedException(); - } - - public void Deserialize(IGenericReader reader) - { - throw new NotImplementedException(); - } - - public void Serialize(IGenericWriter writer) - { - throw new NotImplementedException(); - } - - public void SetTypeRef(Type type) - { - throw new NotImplementedException(); - } - - void ISerializable.BeforeSerialize() - { - throw new NotImplementedException(); - } - - void ISerializable.Deserialize(IGenericReader reader) - { - throw new NotImplementedException(); - } - - void ISerializable.Serialize(IGenericWriter writer) - { - throw new NotImplementedException(); - } - - void ISerializable.Delete() - { - throw new NotImplementedException(); - } - - void ISerializable.SetTypeRef(Type type) - { - throw new NotImplementedException(); - } - - public void RemoveItem(Item item) - { - throw new NotImplementedException(); - } - } - - public class BaseMulti : BItem - { - public MultiComponentList Components = MultiComponentList.Empty; - - public BaseMulti(Point3D location) : base(location) - { - for (int i = 0; i < 20; ++i) - { - for (int j = 0; j < 20; ++j) - { - for (int z = 0; z < 20; ++z) - { - Components.Add(123, i, j, z); - } - } - } - } - } - - public class Sector - { - public List Multis { get; set; } = new(); - } -} diff --git a/Projects/Benchmarks/Benchmarks/Packets/BenchmarkPacketBroadcast.cs b/Projects/Benchmarks/Benchmarks/Packets/BenchmarkPacketBroadcast.cs deleted file mode 100644 index 4db59d432..000000000 --- a/Projects/Benchmarks/Benchmarks/Packets/BenchmarkPacketBroadcast.cs +++ /dev/null @@ -1,174 +0,0 @@ -using System; -using System.Buffers; -using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Jobs; -using Server; -using Server.Network; - -namespace Benchmarks -{ - [SimpleJob(RuntimeMoniker.Net60)] - public class BenchmarkPacketBroadcast - { - public static int SendUnicodeMessage( - ArraySegment[] buffer, - Serial serial, int graphic, MessageType type, int hue, int font, string lang, string name, string text - ) - { - name = name?.Trim() ?? ""; - text = text?.Trim() ?? ""; - lang = lang?.Trim() ?? "ENU"; - - if (hue == 0) - { - hue = 0x3B2; - } - - var writer = new CircularBufferWriter(buffer); - writer.Write((byte)0xAE); - writer.Write((ushort)(50 + text.Length * 2)); - writer.Write(serial.Value); - writer.Write((short)graphic); - writer.Write((byte)type); - writer.Write((short)hue); - writer.Write((short)font); - writer.WriteAscii(lang, 4); - writer.WriteAscii(name, 30); - writer.WriteBigUniNull(text); - - return writer.Position; - } - - public static int CreateUnicodeMessage( - Span buffer, - Serial serial, int graphic, MessageType type, int hue, int font, string lang, string name, string text - ) - { - name = name?.Trim() ?? ""; - text = text?.Trim() ?? ""; - lang = lang?.Trim() ?? "ENU"; - - if (hue == 0) - { - hue = 0x3B2; - } - - var writer = new SpanWriter(buffer); - writer.Write((byte)0xAE); - writer.Write((ushort)(50 + text.Length * 2)); - writer.Write(serial); - writer.Write((short)graphic); - writer.Write((byte)type); - writer.Write((short)hue); - writer.Write((short)font); - writer.WriteAscii(lang, 4); - writer.WriteAscii(name, 30); - writer.WriteBigUniNull(text); - - return writer.Position; - } - - private Pipe[] _pipes = new Pipe[25000]; - - [IterationSetup] - public void SetUp() - { - for (var i = 0; i < _pipes.Length; i++) - { - _pipes[i] = new Pipe(new byte[4096]); - } - } - - [IterationCleanup] - public void CleanUp() - { - for (var i = 0; i < _pipes.Length; i++) - { - _pipes[i] = null; - } - } - - [Benchmark] - public int TestCircularBuffer() - { - var text = "This is some really long text that we want to handle. It should take a little bit to encode this."; - foreach (var pipe in _pipes) - { - var result = pipe.Writer.TryGetMemory(); - var length = SendUnicodeMessage( - result.Buffer, - Serial.MinusOne, -1, MessageType.Regular, 0x3B2, 3, "ENU", "System", text - ); - pipe.Writer.Advance((uint)length); - } - - return _pipes.Length; - } - - [Benchmark] - public int TestSpanWriterFromBuffer() - { - var text = "This is some really long text that we want to handle. It should take a little bit to encode this."; - foreach (var pipe in _pipes) - { - var result = pipe.Writer.TryGetMemory(); - - Span buffer = result.Buffer[0]; - - var length = CreateUnicodeMessage( - buffer, Serial.MinusOne, -1, MessageType.Regular, 0x3B2, 3, "ENU", "System", text - ); - pipe.Writer.Advance((uint)length); - } - - return _pipes.Length; - } - - [Benchmark] - public int TestSpanWriter() - { - var text = "This is some really long text that we want to handle. It should take a little bit to encode this."; - Span buffer = stackalloc byte[OutgoingMessagePackets.GetMaxMessageLength(text)]; - var length = CreateUnicodeMessage( - buffer, Serial.MinusOne, -1, MessageType.Regular, 0x3B2, 3, "ENU", "System", text - ); - - buffer = buffer[..length]; - - foreach (var pipe in _pipes) - { - var result = pipe.Writer.TryGetMemory(); - result.CopyFrom(buffer); - pipe.Writer.Advance((uint)buffer.Length); - } - - return _pipes.Length; - } - - private static void SendUnicodeMessageWithSpan(Pipe pipe, string text) - { - Span buffer = stackalloc byte[OutgoingMessagePackets.GetMaxMessageLength(text)]; - var length = CreateUnicodeMessage( - buffer, Serial.MinusOne, -1, MessageType.Regular, 0x3B2, 3, "ENU", "System", text - ); - - buffer = buffer[..length]; - var result = pipe.Writer.TryGetMemory(); - result.CopyFrom(buffer); - pipe.Writer.Advance((uint)buffer.Length); - } - - [Benchmark] - public int TestSpanWriterLooped() - { - var text = "This is some really long text that we want to handle. It should take a little bit to encode this."; - - foreach (var pipe in _pipes) - { - SendUnicodeMessageWithSpan(pipe, text); - } - - return _pipes.Length; - } - } -} diff --git a/Projects/Benchmarks/Benchmarks/Packets/Packet.cs b/Projects/Benchmarks/Benchmarks/Packets/Packet.cs deleted file mode 100644 index 7b634fcce..000000000 --- a/Projects/Benchmarks/Benchmarks/Packets/Packet.cs +++ /dev/null @@ -1,265 +0,0 @@ -using System; -using System.Buffers; -using System.Diagnostics; -using System.IO; -using Server.Diagnostics; - -namespace Server.Network -{ - public abstract class Packet - { - private const int CompressorBufferSize = 0x10000; - - private readonly int m_Length; - - private byte[] m_CompiledBuffer; - private int m_CompiledLength; - private State m_State; - - protected Packet(int packetID) - { - PacketID = packetID; - - if (Core.Profiling) - { - var prof = PacketSendProfile.Acquire(PacketID); - prof.Increment(); - } - } - - protected Packet(int packetID, int length) - { - PacketID = packetID; - m_Length = length; - - Stream = PacketWriter.CreateInstance(length); // new PacketWriter( length ); - Stream.Write((byte)packetID); - - if (Core.Profiling) - { - var prof = PacketSendProfile.Acquire(PacketID); - prof.Increment(); - } - } - - public int PacketID { get; } - - public PacketWriter Stream { get; protected set; } - - public void EnsureCapacity(int length) - { - Stream = PacketWriter.CreateInstance(length); // new PacketWriter( length ); - Stream.Write((byte)PacketID); - Stream.Write((short)0); - } - - public static Packet SetStatic(Packet p) - { - p.SetStatic(); - return p; - } - - public static Packet Acquire(Packet p) - { - p.Acquire(); - return p; - } - - public static void Release(ref Packet p) - { - p?.Release(); - p = null; - } - - public static void Release(Packet p) - { - p?.Release(); - } - - public void SetStatic() - { - m_State |= State.Static | State.Acquired; - } - - public void Acquire() - { - m_State |= State.Acquired; - } - - public void OnSend() - { - if ((m_State & (State.Acquired | State.Static)) == 0) - { - Free(); - } - } - - private void Free() - { - if (m_CompiledBuffer == null) - { - return; - } - - if ((m_State & State.Buffered) != 0) - { - ArrayPool.Shared.Return(m_CompiledBuffer); - } - - m_State &= ~(State.Static | State.Acquired | State.Buffered); - - m_CompiledBuffer = null; - } - - public void Release() - { - if ((m_State & State.Acquired) != 0) - { - Free(); - } - } - - private readonly object _object = new(); - - public byte[] Compile(bool compress, out int length) - { - lock (_object) - { - if (m_CompiledBuffer == null) - { - if ((m_State & State.Accessed) == 0) - { - m_State |= State.Accessed; - } - else - { - if ((m_State & State.Warned) == 0) - { - m_State |= State.Warned; - - try - { - using var op = new StreamWriter("net_opt.log", true); - op.WriteLine("Redundant compile for packet {0}, use Acquire() and Release()", GetType()); - op.WriteLine(new StackTrace()); - } - catch - { - // ignored - } - } - - m_CompiledBuffer = Array.Empty(); - m_CompiledLength = 0; - - length = m_CompiledLength; - return m_CompiledBuffer; - } - - InternalCompile(compress); - } - - length = m_CompiledLength; - return m_CompiledBuffer; - } - } - - private void InternalCompile(bool compress) - { - if (m_Length == 0) - { - var streamLen = Stream.Length; - - Stream.Seek(1, SeekOrigin.Begin); - Stream.Write((ushort)streamLen); - } - else if (Stream.Length != m_Length) - { - var diff = (int)Stream.Length - m_Length; - - Console.WriteLine( - "Packet: 0x{0:X2}: Bad packet length! ({1}{2} bytes)", - PacketID, - diff >= 0 ? "+" : "", - diff - ); - } - - var ms = Stream.UnderlyingStream; - - m_CompiledBuffer = ms.GetBuffer(); - var length = (int)ms.Length; - - if (compress) - { - var compressorBuffer = new byte[CompressorBufferSize]; - var compressedLength = NetworkCompression.Compress(m_CompiledBuffer.AsSpan(0, length), compressorBuffer); - - if (length <= 0) - { - Console.WriteLine( - "Warning: Compression buffer overflowed on packet 0x{0:X2} ('{1}') (length={2})", - PacketID, - GetType().Name, - length - ); - using var op = new StreamWriter("compression_overflow.log", true); - op.WriteLine( - "{0} Warning: Compression buffer overflowed on packet 0x{1:X2} ('{2}') (length={3})", - Core.Now, - PacketID, - GetType().Name, - length - ); - op.WriteLine(new StackTrace()); - } - else - { - m_CompiledBuffer = compressorBuffer; - m_CompiledLength = compressedLength; - } - } - else - { - m_CompiledLength = length; - } - - if (m_CompiledLength > 0) - { - var old = m_CompiledBuffer; - - if ((m_State & State.Static) != 0) - { - m_CompiledBuffer = new byte[m_CompiledLength]; - } - else - { - // Release it later using Release() - m_CompiledBuffer = ArrayPool.Shared.Rent(m_CompiledLength); - m_State |= State.Buffered; - } - - Buffer.BlockCopy(old, 0, m_CompiledBuffer, 0, m_CompiledLength); - - if (compress) - { - ArrayPool.Shared.Return(old); - } - } - - PacketWriter.ReleaseInstance(Stream); - Stream = null; - } - - [Flags] - private enum State - { - Inactive = 0x00, - Static = 0x01, - Acquired = 0x02, - Accessed = 0x04, - Buffered = 0x08, - Warned = 0x10 - } - } -} diff --git a/Projects/Benchmarks/Benchmarks/Packets/PacketTestUtilities.cs b/Projects/Benchmarks/Benchmarks/Packets/PacketTestUtilities.cs deleted file mode 100644 index e7a01619f..000000000 --- a/Projects/Benchmarks/Benchmarks/Packets/PacketTestUtilities.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using System.Buffers.Binary; -using System.Runtime.CompilerServices; -using Server; -using Server.Network; - -namespace Benchmarks -{ - public static class PacketTestUtilities - { - public static Span Compile(this Packet p) => - p.Compile(false, out var length).AsSpan(0, length); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Write(this Span data, ref int pos, Serial serial) - { - BinaryPrimitives.WriteUInt32BigEndian(data.Slice(pos, 4), serial.Value); - pos += 4; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Write(this Span data, ref int pos, ushort value) - { - BinaryPrimitives.WriteUInt16BigEndian(data.Slice(pos, 2), value); - pos += 2; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Write(this Span data, ref int pos, byte value) => data[pos++] = value; - } -} diff --git a/Projects/Benchmarks/Benchmarks/Packets/PacketWriter.cs b/Projects/Benchmarks/Benchmarks/Packets/PacketWriter.cs deleted file mode 100644 index 696dbc7e8..000000000 --- a/Projects/Benchmarks/Benchmarks/Packets/PacketWriter.cs +++ /dev/null @@ -1,354 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.IO; -using System.Text; - -namespace Server.Network -{ - /// - /// Provides functionality for writing primitive binary data. - /// - public class PacketWriter - { - private static readonly ConcurrentQueue m_Pool = new(); - - /// - /// Internal format buffer. - /// - private readonly byte[] m_Buffer = new byte[4]; - - private int m_Capacity; - - /// - /// Instantiates a new PacketWriter instance with a given capacity. - /// - /// Initial capacity for the internal stream. - public PacketWriter(int capacity = 32) - { - UnderlyingStream = new MemoryStream(capacity); - m_Capacity = capacity; - } - - /// - /// Gets the total stream length. - /// - public long Length => UnderlyingStream.Length; - - /// - /// Gets or sets the current stream position. - /// - public long Position - { - get => UnderlyingStream.Position; - set => UnderlyingStream.Position = value; - } - - /// - /// The internal stream used by this PacketWriter instance. - /// - public MemoryStream UnderlyingStream { get; } - - public static PacketWriter CreateInstance(int capacity = 32) - { - if (m_Pool.TryDequeue(out var pw)) - { - pw.m_Capacity = capacity; - pw.UnderlyingStream.SetLength(0); - return pw; - } - - return new PacketWriter(capacity); - } - - public static void ReleaseInstance(PacketWriter pw) - { - m_Pool.Enqueue(pw); - } - - /// - /// Writes a 1-byte boolean value to the underlying stream. False is represented by 0, true by 1. - /// - public void Write(bool value) - { - UnderlyingStream.WriteByte((byte)(value ? 1 : 0)); - } - - /// - /// Writes a 1-byte unsigned integer value to the underlying stream. - /// - public void Write(byte value) - { - UnderlyingStream.WriteByte(value); - } - - /// - /// Writes a 1-byte signed integer value to the underlying stream. - /// - public void Write(sbyte value) - { - UnderlyingStream.WriteByte((byte)value); - } - - /// - /// Writes a 2-byte signed integer value to the underlying stream. - /// - public void Write(short value) - { - m_Buffer[0] = (byte)(value >> 8); - m_Buffer[1] = (byte)value; - - UnderlyingStream.Write(m_Buffer, 0, 2); - } - - /// - /// Writes a 2-byte unsigned integer value to the underlying stream. - /// - public void Write(ushort value) - { - m_Buffer[0] = (byte)(value >> 8); - m_Buffer[1] = (byte)value; - - UnderlyingStream.Write(m_Buffer, 0, 2); - } - - public void Write(Serial serial) => Write(serial.Value); - - /// - /// Writes a 4-byte signed integer value to the underlying stream. - /// - public void Write(int value) - { - m_Buffer[0] = (byte)(value >> 24); - m_Buffer[1] = (byte)(value >> 16); - m_Buffer[2] = (byte)(value >> 8); - m_Buffer[3] = (byte)value; - - UnderlyingStream.Write(m_Buffer, 0, 4); - } - - /// - /// Writes a 4-byte unsigned integer value to the underlying stream. - /// - public void Write(uint value) - { - m_Buffer[0] = (byte)(value >> 24); - m_Buffer[1] = (byte)(value >> 16); - m_Buffer[2] = (byte)(value >> 8); - m_Buffer[3] = (byte)value; - - UnderlyingStream.Write(m_Buffer, 0, 4); - } - - /// - /// Writes a sequence of bytes to the underlying stream - /// - public void Write(byte[] buffer, int offset, int size) - { - UnderlyingStream.Write(buffer, offset, size); - } - - /// - /// Writes a fixed-length ASCII-encoded string value to the underlying stream. To fit (size), the string content is either - /// truncated or padded with null characters. - /// - public void WriteAsciiFixed(string value, int size) - { - if (value == null) - { - Console.WriteLine("Network: Attempted to WriteAsciiFixed() with null value"); - value = string.Empty; - } - - var length = value.Length; - - UnderlyingStream.SetLength(UnderlyingStream.Length + size); - - if (length >= size) - { - UnderlyingStream.Position += - Encoding.ASCII.GetBytes(value, 0, size, UnderlyingStream.GetBuffer(), (int)UnderlyingStream.Position); - } - else - { - Encoding.ASCII.GetBytes(value, 0, length, UnderlyingStream.GetBuffer(), (int)UnderlyingStream.Position); - UnderlyingStream.Position += size; - } - } - - /// - /// Writes a dynamic-length ASCII-encoded string value to the underlying stream, followed by a 1-byte null character. - /// - public void WriteAsciiNull(string value) - { - if (value == null) - { - Console.WriteLine("Network: Attempted to WriteAsciiNull() with null value"); - value = string.Empty; - } - - var length = value.Length; - - UnderlyingStream.SetLength(UnderlyingStream.Length + length + 1); - - Encoding.ASCII.GetBytes(value, 0, length, UnderlyingStream.GetBuffer(), (int)UnderlyingStream.Position); - UnderlyingStream.Position += length + 1; - } - - /// - /// Writes a dynamic-length little-endian unicode string value to the underlying stream, followed by a 2-byte null - /// character. - /// - public void WriteLittleUniNull(string value) - { - if (value == null) - { - Console.WriteLine("Network: Attempted to WriteLittleUniNull() with null value"); - value = string.Empty; - } - - var length = value.Length; - - UnderlyingStream.SetLength(UnderlyingStream.Length + (length + 1) * 2); - - UnderlyingStream.Position += - Encoding.Unicode.GetBytes(value, 0, length, UnderlyingStream.GetBuffer(), (int)UnderlyingStream.Position); - UnderlyingStream.Position += 2; - } - - /// - /// Writes a fixed-length little-endian unicode string value to the underlying stream. To fit (size), the string content is - /// either truncated or padded with null characters. - /// - public void WriteLittleUniFixed(string value, int size) - { - if (value == null) - { - Console.WriteLine("Network: Attempted to WriteLittleUniFixed() with null value"); - value = string.Empty; - } - - var length = value.Length; - size *= 2; - - UnderlyingStream.SetLength(UnderlyingStream.Length + size); - - if (length * 2 >= size) - { - UnderlyingStream.Position += - Encoding.Unicode.GetBytes( - value, - 0, - size / 2, - UnderlyingStream.GetBuffer(), - (int)UnderlyingStream.Position - ); - } - else - { - Encoding.Unicode.GetBytes(value, 0, length, UnderlyingStream.GetBuffer(), (int)UnderlyingStream.Position); - UnderlyingStream.Position += size; - } - } - - /// - /// Writes a dynamic-length big-endian unicode string value to the underlying stream, followed by a 2-byte null character. - /// - public void WriteBigUniNull(string value) - { - if (value == null) - { - Console.WriteLine("Network: Attempted to WriteBigUniNull() with null value"); - value = string.Empty; - } - - var length = value.Length; - - UnderlyingStream.SetLength(UnderlyingStream.Length + (length + 1) * 2); - - UnderlyingStream.Position += - Encoding.BigEndianUnicode.GetBytes( - value, - 0, - length, - UnderlyingStream.GetBuffer(), - (int)UnderlyingStream.Position - ); - UnderlyingStream.Position += 2; - } - - /// - /// Writes a fixed-length big-endian unicode string value to the underlying stream. To fit (size), the string content is - /// either truncated or padded with null characters. - /// - public void WriteBigUniFixed(string value, int size) - { - if (value == null) - { - Console.WriteLine("Network: Attempted to WriteBigUniFixed() with null value"); - value = string.Empty; - } - - var length = value.Length; - size *= 2; - - UnderlyingStream.SetLength(UnderlyingStream.Length + size); - - if (length * 2 >= size) - { - UnderlyingStream.Position += - Encoding.BigEndianUnicode.GetBytes( - value, - 0, - size / 2, - UnderlyingStream.GetBuffer(), - (int)UnderlyingStream.Position - ); - } - else - { - Encoding.BigEndianUnicode.GetBytes( - value, - 0, - length, - UnderlyingStream.GetBuffer(), - (int)UnderlyingStream.Position - ); - UnderlyingStream.Position += size; - } - } - - /// - /// Fills the stream from the current position up to (capacity) with 0x00's - /// - public void Fill() - { - Fill(m_Capacity - UnderlyingStream.Length); - } - - /// - /// Writes a number of 0x00 byte values to the underlying stream. - /// - public void Fill(long length) - { - if (UnderlyingStream.Position == UnderlyingStream.Length) - { - UnderlyingStream.SetLength(UnderlyingStream.Length + length); - UnderlyingStream.Seek(0, SeekOrigin.End); - } - else - { - UnderlyingStream.Write(new byte[length], 0, (int)length); - } - } - - /// - /// Offsets the current position from an origin. - /// - public long Seek(long offset, SeekOrigin origin) => UnderlyingStream.Seek(offset, origin); - - /// - /// Gets the entire stream content as a byte array. - /// - public byte[] ToArray() => UnderlyingStream.ToArray(); - } -} diff --git a/Projects/Benchmarks/Benchmarks/Rng/BenchmarkDoubleVsFixed.cs b/Projects/Benchmarks/Benchmarks/Rng/BenchmarkDoubleVsFixed.cs deleted file mode 100644 index 53b079cb5..000000000 --- a/Projects/Benchmarks/Benchmarks/Rng/BenchmarkDoubleVsFixed.cs +++ /dev/null @@ -1,28 +0,0 @@ -using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Jobs; -using Server.Random; - -namespace Benchmarks.Benchmarks.Rng -{ - [MemoryDiagnoser] - [SimpleJob(RuntimeMoniker.Net60)] - public class BenchmarkDoubleVsFixed - { - private Xoshiro256PlusPlus _xoshiro256PlusPlus; - - [GlobalSetup] - public void Setup() - { - _xoshiro256PlusPlus = new Xoshiro256PlusPlus(); - } - - [Benchmark] - public bool NextDouble() => 50.1 < _xoshiro256PlusPlus.NextDouble() * 100; - - [Benchmark] - public bool NextFixedInt() => 501 < _xoshiro256PlusPlus.Next(1000); - - [Benchmark] - public bool NextHighResDouble() => 50.1 < _xoshiro256PlusPlus.NextDoubleHighRes() * 100; - } -} diff --git a/Projects/Benchmarks/Benchmarks/Rng/BenchmarkXoshiro.cs b/Projects/Benchmarks/Benchmarks/Rng/BenchmarkXoshiro.cs deleted file mode 100644 index caced76b3..000000000 --- a/Projects/Benchmarks/Benchmarks/Rng/BenchmarkXoshiro.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System; -using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Jobs; -using Server.Random; - -namespace Benchmarks.Benchmarks.Rng -{ - [MemoryDiagnoser] - [SimpleJob(RuntimeMoniker.Net60)] - public class BenchmarkXoshiro - { - private Random _random; - private Xoshiro256PlusPlus _xoshiro256PlusPlus; - - [GlobalSetup] - public void Setup() - { - _xoshiro256PlusPlus = new Xoshiro256PlusPlus(); - _random = new Random(); - } - - [Benchmark] - public int SystemRandomULong() => _random.Next(10000); - - [Benchmark] - public int XoshiroRandomULong() => _xoshiro256PlusPlus.Next(10000); - - [Benchmark] - public double SystemRandomDouble() => _random.NextDouble(); - - [Benchmark] - public double XoshiroRandomDouble() => _xoshiro256PlusPlus.NextDouble(); - - [Benchmark] - public int SystemRandomMinMax() => _random.Next(5000, 85000); - - [Benchmark] - public int XoshiroRandomMinMax() - { - const int min = 5000; - const int max = 85000; - - return min + (int)_xoshiro256PlusPlus.Next((uint)(max - min + 1)); - } - } -} diff --git a/Projects/Benchmarks/Benchmarks/Text/BenchmarkTextEncoding.cs b/Projects/Benchmarks/Benchmarks/Text/BenchmarkTextEncoding.cs deleted file mode 100644 index b2f716861..000000000 --- a/Projects/Benchmarks/Benchmarks/Text/BenchmarkTextEncoding.cs +++ /dev/null @@ -1,32 +0,0 @@ -using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Jobs; -using Server.Text; - -namespace Benchmarks.BenchmarkText -{ - [MemoryDiagnoser] - [SimpleJob(RuntimeMoniker.Net60)] - public class BenchmarkTextEncoding - { - private const string text = - "This is supposed to be a really long text Ƞă¼ÖƄŭȘú😅¥♓ǵDƤĂ😋ġǁ⚕😐'ƿī😪_l" + - "This is supposed to be a really long text Ƞă¼ÖƄŭȘú😅¥♓ǵDƤĂ😋ġǁ⚕😐'ƿī😪_l" + - "This is supposed to be a really long text Ƞă¼ÖƄŭȘú😅¥♓ǵDƤĂ😋ġǁ⚕😐'ƿī😪_l" + - "This is supposed to be a really long text Ƞă¼ÖƄŭȘú😅¥♓ǵDƤĂ😋ġǁ⚕😐'ƿī😪_l" + - "This is supposed to be a really long text Ƞă¼ÖƄŭȘú😅¥♓ǵDƤĂ😋ġǁ⚕😐'ƿī😪_l"; - - [Benchmark] - public byte[] TestEncodingOldReturnBytes() - { - var bytes = TextEncoding.UTF8.GetBytes(text); - return bytes; - } - - [Benchmark] - public byte[] TestEncodingNewReturnBytes() - { - var bytes = text.GetBytesUtf8(); - return bytes; - } - } -} diff --git a/Projects/Benchmarks/Benchmarks/Timers/BenchmarkTimerExecutions.cs b/Projects/Benchmarks/Benchmarks/Timers/BenchmarkTimerExecutions.cs deleted file mode 100644 index 5d71ce8ea..000000000 --- a/Projects/Benchmarks/Benchmarks/Timers/BenchmarkTimerExecutions.cs +++ /dev/null @@ -1,96 +0,0 @@ -using System; -using System.Threading; -using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Jobs; - -namespace Server -{ - [MemoryDiagnoser] - [SimpleJob(RuntimeMoniker.Net60, warmupCount: 20, targetCount: 20)] - public class BenchmarkTimerExecutions - { - private const int timerCount = 1000; - private CancellationTokenSource _cancellationTokenSource; - private static SemaphoreSlim _slim; - - [GlobalSetup] - public void Setup() - { - Core.Profiling = false; - Timer.Init(0); - - RUOTimer.TimerThread ttObj = new RUOTimer.TimerThread(); - _cancellationTokenSource = new CancellationTokenSource(); - var timerThread = new Thread(() => ttObj.TimerMain(_cancellationTokenSource.Token)) - { - Name = "Timer Thread" - }; - - timerThread.Start(); - } - - [GlobalCleanup] - public void Cleanup() - { - RUOTimer.TimerThread.Set(); - _cancellationTokenSource.Cancel(); - RUOTimer.TimerThread.CleanupForTesting(); - Timer.ClearAllTimers(0); - GC.Collect(); - } - - [Benchmark] - public void RUOTimerExecutions() - { - _slim = new SemaphoreSlim(1); - - for (var i = 0; i < timerCount; i++) - { - new TestRUOTimer(TimeSpan.FromMilliseconds(1), i).Start(); - } - - RUOTimer.TimerThread.m_TickCount += 8; - RUOTimer.TimerThread.Set(); - _slim.Wait(); - } - - [Benchmark] - public void MUOTimerExecutions() - { - for (var i = 0; i < timerCount; i++) - { - new TestMUOTimer(TimeSpan.FromMilliseconds(1), i).Start(); - } - - Timer.Slice(8); - } - - public class TestRUOTimer : RUOTimer - { - private int _amount; - - public TestRUOTimer(TimeSpan delay, int amount) : base(delay) => _amount = amount; - - protected override void OnTick() - { - var b = 6 * _amount; - if (_amount == timerCount - 1) - { - _slim.Release(); - } - } - } - - public class TestMUOTimer : Timer - { - private int _amount; - - public TestMUOTimer(TimeSpan delay, int amount) : base(delay) => _amount = amount; - - protected override void OnTick() - { - var b = 6 * _amount; - } - } - } -} diff --git a/Projects/Benchmarks/Benchmarks/Timers/BenchmarkTimerInserts.cs b/Projects/Benchmarks/Benchmarks/Timers/BenchmarkTimerInserts.cs deleted file mode 100644 index a2918943c..000000000 --- a/Projects/Benchmarks/Benchmarks/Timers/BenchmarkTimerInserts.cs +++ /dev/null @@ -1,60 +0,0 @@ -using System; -using System.Threading; -using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Jobs; - -namespace Server -{ - [MemoryDiagnoser] - [SimpleJob(RuntimeMoniker.Net60, warmupCount: 20, targetCount: 20)] - public class BenchmarkTimerInserts - { - private const int timerCount = 1000; - private CancellationTokenSource _cancellationTokenSource; - - [GlobalSetup] - public void Setup() - { - Core.Profiling = false; - Timer.Init(0); - - RUOTimer.TimerThread ttObj = new RUOTimer.TimerThread(); - _cancellationTokenSource = new CancellationTokenSource(); - var timerThread = new Thread(() => ttObj.TimerMain(_cancellationTokenSource.Token)) - { - Name = "Timer Thread" - }; - - timerThread.Start(); - } - - [GlobalCleanup] - public void Cleanup() - { - _cancellationTokenSource.Cancel(); - RUOTimer.TimerThread.Set(); - RUOTimer.TimerThread.CleanupForTesting(); - Timer.ClearAllTimers(0); - GC.Collect(); - } - - [Benchmark] - public void RUOTimerInserts() - { - for (var i = 0; i < timerCount; i++) - { - new RUOTimer(TimeSpan.Zero).Start(); - } - RUOTimer.TimerThread.Set(); - } - - [Benchmark] - public void MUOTimerInserts() - { - for (var i = 0; i < timerCount; i++) - { - new Timer(TimeSpan.Zero).Start(); - } - } - } -} diff --git a/Projects/Benchmarks/Benchmarks/Timers/RUOTimer.cs b/Projects/Benchmarks/Benchmarks/Timers/RUOTimer.cs deleted file mode 100644 index bdba69fe9..000000000 --- a/Projects/Benchmarks/Benchmarks/Timers/RUOTimer.cs +++ /dev/null @@ -1,495 +0,0 @@ -/*************************************************************************** - * Timer.cs - * ------------------- - * begin : May 1, 2002 - * copyright : (C) The RunUO Software Team - * email : info@runuo.com - * - * $Id$ - * - ***************************************************************************/ - -/*************************************************************************** - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - ***************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Threading; -using Server.Diagnostics; - -namespace Server -{ - public enum TimerPriority - { - EveryTick, - TenMS, - TwentyFiveMS, - FiftyMS, - TwoFiftyMS, - OneSecond, - FiveSeconds, - OneMinute - } - - public class RUOTimer - { - private long m_Next; - private long m_Delay; - private long m_Interval; - private bool m_Running; - private int m_Index, m_Count; - private TimerPriority m_Priority; - private List m_List; - private bool m_PrioritySet; - - private static string FormatDelegate( Delegate callback ) - { - if ( callback == null ) - { - return "null"; - } - - return String.Format( "{0}.{1}", callback.Method.DeclaringType.FullName, callback.Method.Name ); - } - - public TimerPriority Priority - { - get - { - return m_Priority; - } - set - { - if ( !m_PrioritySet ) - { - m_PrioritySet = true; - } - - if ( m_Priority != value ) - { - m_Priority = value; - - if ( m_Running ) - { - TimerThread.PriorityChange( this, (int)m_Priority ); - } - } - } - } - - public DateTime Next - { - // Obnoxious - get { return DateTime.UtcNow + TimeSpan.FromMilliseconds(m_Next-TimerThread.m_TickCount); } - } - - public TimeSpan Delay - { - get { return TimeSpan.FromMilliseconds(m_Delay); } - set { m_Delay = (long)value.TotalMilliseconds; } - } - - public TimeSpan Interval - { - get { return TimeSpan.FromMilliseconds(m_Interval); } - set { m_Interval = (long)value.TotalMilliseconds; } - } - - public bool Running - { - get { return m_Running; } - set { - if ( value ) { - Start(); - } else { - Stop(); - } - } - } - - public TimerProfile GetProfile() - { - if ( !Core.Profiling ) { - return null; - } - - string name = ToString(); - - if ( name == null ) { - name = "null"; - } - - return TimerProfile.Acquire( name ); - } - - public class TimerThread - { - public static long m_TickCount; // Mimics core tick count for testing - - private static Dictionary m_Changed = new Dictionary(); - - private static long[] m_NextPriorities = new long[8]; - private static long[] m_PriorityDelays = new long[8] - { - 0, - 10, - 25, - 50, - 250, - 1000, - 5000, - 60000 - }; - - private static List[] m_Timers = new List[8] - { - new List(), - new List(), - new List(), - new List(), - new List(), - new List(), - new List(), - new List(), - }; - - private class TimerChangeEntry - { - public RUOTimer MRuoTimer; - public int m_NewIndex; - public bool m_IsAdd; - - private TimerChangeEntry( RUOTimer t, int newIndex, bool isAdd ) - { - MRuoTimer = t; - m_NewIndex = newIndex; - m_IsAdd = isAdd; - } - - public void Free() - { - lock (m_InstancePool) { - if (m_InstancePool.Count < 200) // Arbitrary - { - m_InstancePool.Enqueue( this ); - } - } - } - - private static Queue m_InstancePool = new Queue(); - - public static TimerChangeEntry GetInstance( RUOTimer t, int newIndex, bool isAdd ) - { - TimerChangeEntry e = null; - - lock (m_InstancePool) { - if ( m_InstancePool.Count > 0 ) { - e = m_InstancePool.Dequeue(); - } - } - - if (e != null) { - e.MRuoTimer = t; - e.m_NewIndex = newIndex; - e.m_IsAdd = isAdd; - } else { - e = new TimerChangeEntry( t, newIndex, isAdd ); - } - - return e; - } - } - - public TimerThread() - { - } - - public static void Change( RUOTimer t, int newIndex, bool isAdd ) - { - lock (m_Changed) - { - m_Changed[t] = TimerChangeEntry.GetInstance(t, newIndex, isAdd); - } - - m_Signal.Set(); - } - - public static void AddTimer( RUOTimer t ) - { - Change( t, (int)t.Priority, true ); - } - - public static void PriorityChange( RUOTimer t, int newPrio ) - { - Change( t, newPrio, false ); - } - - public static void RemoveTimer( RUOTimer t ) - { - Change( t, -1, false ); - } - - private static void ProcessChanged() - { - lock (m_Changed) { - long curTicks = m_TickCount; - - foreach (TimerChangeEntry tce in m_Changed.Values) { - RUOTimer ruoTimer = tce.MRuoTimer; - int newIndex = tce.m_NewIndex; - - if (ruoTimer.m_List != null) - { - ruoTimer.m_List.Remove(ruoTimer); - } - - if (tce.m_IsAdd) { - ruoTimer.m_Next = curTicks + ruoTimer.m_Delay; - ruoTimer.m_Index = 0; - } - - if (newIndex >= 0) { - ruoTimer.m_List = m_Timers[newIndex]; - ruoTimer.m_List.Add(ruoTimer); - } else { - ruoTimer.m_List = null; - } - - tce.Free(); - } - - m_Changed.Clear(); - } - } - - public static void CleanupForTesting() - { - lock (m_Changed) - { - m_Changed.Clear(); - } - } - - private static AutoResetEvent m_Signal = new AutoResetEvent( false ); - public static void Set() { m_Signal.Set(); } - - public void TimerMain(CancellationToken cancellationToken) - { - long now; - int i, j; - bool loaded; - - while ( !cancellationToken.IsCancellationRequested ) - { - ProcessChanged(); - - loaded = false; - - for ( i = 0; i < m_Timers.Length; i++) - { - now = m_TickCount; - if ( now < m_NextPriorities[i] ) - { - break; - } - - m_NextPriorities[i] = now + m_PriorityDelays[i]; - - for ( j = 0; j < m_Timers[i].Count; j++) - { - RUOTimer t = m_Timers[i][j]; - - if ( !t.m_Queued && now > t.m_Next ) - { - t.m_Queued = true; - - lock ( m_Queue ) - { - m_Queue.Enqueue( t ); - } - - loaded = true; - - if ( t.m_Count != 0 && (++t.m_Index >= t.m_Count) ) - { - t.Stop(); - } - else - { - t.m_Next = now + t.m_Interval; - } - } - } - } - - if ( loaded ) - { - // Core.Set(); - } - - m_Signal.WaitOne(-1, false); - } - } - } - - private static Queue m_Queue = new Queue(); - private static int m_BreakCount = 20000; - - public static int BreakCount{ get{ return m_BreakCount; } set{ m_BreakCount = value; } } - - private static int m_QueueCountAtSlice; - - private bool m_Queued; - - public static void Slice() - { - lock ( m_Queue ) - { - m_QueueCountAtSlice = m_Queue.Count; - - int index = 0; - - while ( index < m_BreakCount && m_Queue.Count != 0 ) - { - RUOTimer t = m_Queue.Dequeue(); - TimerProfile prof = t.GetProfile(); - - if ( prof != null ) { - prof.Start(); - } - - t.OnTick(); - t.m_Queued = false; - ++index; - - if ( prof != null ) { - prof.Finish(); - } - } - } - } - - public RUOTimer( TimeSpan delay ) : this( delay, TimeSpan.Zero, 1 ) - { - } - - public RUOTimer( TimeSpan delay, TimeSpan interval ) : this( delay, interval, 0 ) - { - } - - public virtual bool DefRegCreation - { - get{ return true; } - } - - public void RegCreation() - { - TimerProfile prof = GetProfile(); - - if ( prof != null ) { - prof.Created++; - } - } - - public RUOTimer( TimeSpan delay, TimeSpan interval, int count ) - { - m_Delay = (long)delay.TotalMilliseconds; - m_Interval = (long)interval.TotalMilliseconds; - m_Count = count; - - if ( !m_PrioritySet ) { - if ( count == 1 ) { - m_Priority = ComputePriority( delay ); - } else { - m_Priority = ComputePriority( interval ); - } - m_PrioritySet = true; - } - - if ( DefRegCreation ) - { - RegCreation(); - } - } - - public override string ToString() - { - return GetType().FullName; - } - - public static TimerPriority ComputePriority( TimeSpan ts ) - { - if ( ts >= TimeSpan.FromMinutes( 1.0 ) ) - { - return TimerPriority.FiveSeconds; - } - - if ( ts >= TimeSpan.FromSeconds( 10.0 ) ) - { - return TimerPriority.OneSecond; - } - - if ( ts >= TimeSpan.FromSeconds( 5.0 ) ) - { - return TimerPriority.TwoFiftyMS; - } - - if ( ts >= TimeSpan.FromSeconds( 2.5 ) ) - { - return TimerPriority.FiftyMS; - } - - if ( ts >= TimeSpan.FromSeconds( 1.0 ) ) - { - return TimerPriority.TwentyFiveMS; - } - - if ( ts >= TimeSpan.FromSeconds( 0.5 ) ) - { - return TimerPriority.TenMS; - } - - return TimerPriority.EveryTick; - } - - public void Start() - { - if ( !m_Running ) - { - m_Running = true; - TimerThread.AddTimer( this ); - - TimerProfile prof = GetProfile(); - - if ( prof != null ) { - prof.Started++; - } - } - } - - public void Stop() - { - if ( m_Running ) - { - m_Running = false; - TimerThread.RemoveTimer( this ); - - TimerProfile prof = GetProfile(); - - if ( prof != null ) { - prof.Stopped++; - } - } - } - - protected virtual void OnTick() - { - } - } -} diff --git a/Projects/Benchmarks/Benchmarks/Utilities/BenchmarkStringHelpers.cs b/Projects/Benchmarks/Benchmarks/Utilities/BenchmarkStringHelpers.cs deleted file mode 100644 index 55e4fd289..000000000 --- a/Projects/Benchmarks/Benchmarks/Utilities/BenchmarkStringHelpers.cs +++ /dev/null @@ -1,87 +0,0 @@ -using System.Buffers; -using System.Text; -using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Jobs; -using Server.Buffers; - -namespace Benchmarks.BenchmarkUtilities -{ - [MemoryDiagnoser] - [SimpleJob(RuntimeMoniker.Net60)] - public class BenchmarkStringHelpers - { - private readonly string[] names = - { - "Kamron", "Owyn", "Luthius", "Jaedan", "Vorspire", "other people", - "Kamron-2", "Owyn-2", "Luthius-2", "Jaedan-2", "Vorspire-2", "other people too" - }; - - private int length; - - [GlobalSetup] - public void Setup() - { - var chrs = ArrayPool.Shared.Rent(65535); - ArrayPool.Shared.Return(chrs); - length = 0; - - for (int i = 0; i < names.Length; i++) - { - length += names.Length; - } - - length += 2 * (names.Length - 1) + 3; - } - - [Benchmark] - public string BenchmarkStringBuilder() - { - var sb = new StringBuilder(); - for (var i = 0; i < names.Length; i++) - { - if (i > 0) - { - sb.Append(i == names.Length - 1 ? ", and" : ", "); - } - - sb.Append(names[i]); - } - - return sb.ToString(); - } - - [Benchmark] - public string BenchmarkValueStringBuilderWithStack() - { - using var sb = new ValueStringBuilder(stackalloc char[length]); - for (var i = 0; i < names.Length; i++) - { - if (i > 0) - { - sb.Append(i == names.Length - 1 ? ", and" : ", "); - } - - sb.Append(names[i]); - } - - return sb.ToString(); - } - - [Benchmark] - public string BenchmarkValueStringBuilderWithRentedBuffer() - { - using var sb = new ValueStringBuilder(stackalloc char[32]); - for (var i = 0; i < names.Length; i++) - { - if (i > 0) - { - sb.Append(i == names.Length - 1 ? ", and" : ", "); - } - - sb.Append(names[i]); - } - - return sb.ToString(); - } - } -} diff --git a/Projects/Benchmarks/Directory.Build.props b/Projects/Benchmarks/Directory.Build.props deleted file mode 100644 index b9b7c8ad8..000000000 --- a/Projects/Benchmarks/Directory.Build.props +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/Projects/Benchmarks/Program.cs b/Projects/Benchmarks/Program.cs deleted file mode 100644 index ef1033575..000000000 --- a/Projects/Benchmarks/Program.cs +++ /dev/null @@ -1,38 +0,0 @@ -using BenchmarkDotNet.Running; -using Benchmarks.EntitiesSelectors; -using Benchmarks.ItemSelectors; -using Benchmarks.MobileSelectors; -using Benchmarks.MultiSelectors; -using Benchmarks.MultiTilesSelectors; -using Server; - -namespace Benchmarks -{ - public static class Program - { - private static void Main(string[] args) - { - // var featureFlags = BenchmarkRunner.Run(); - // var packetConstruction = BenchmarkRunner.Run(); - // var broadcast = BenchmarkRunner.Run(); - // var stringHelpers = BenchmarkRunner.Run(); - // var indexList = BenchmarkRunner.Run(); - // var textEncoding = BenchmarkRunner.Run(); - // var logging = BenchmarkRunner.Run(); - // var gumpPacket = BenchmarkRunner.Run(); - // var rngTest = BenchmarkRunner.Run(); - //var doubleRngText = BenchmarkRunner.Run(); - - //var mapEntitiesSelectors = BenchmarkRunner.Run(); - //var mapMobilesSelectors = BenchmarkRunner.Run(); - //var mapMultiTilesSelectors = BenchmarkRunner.Run(); - //var mapMultiSelectors = BenchmarkRunner.Run(); - // var mapItemsSelectors = BenchmarkRunner.Run(); - // var stArray = BenchmarkRunner.Run(); - // var pooledRefQueue = BenchmarkRunner.Run(); - - var timerInsertionTest = BenchmarkRunner.Run(); - // var timerExecutionTest = BenchmarkRunner.Run(); - } - } -} From b2b4c809f816e618d67ad99f04e0359d4172e1cd Mon Sep 17 00:00:00 2001 From: jkachhad Date: Sun, 3 Apr 2022 00:00:01 -0700 Subject: [PATCH 129/213] fix: Properly count timers for DumpInfo (#986) --- Projects/Server/Timer/Timer.TimerWheel.cs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/Projects/Server/Timer/Timer.TimerWheel.cs b/Projects/Server/Timer/Timer.TimerWheel.cs index 02b54f12a..e3dc9ae6c 100644 --- a/Projects/Server/Timer/Timer.TimerWheel.cs +++ b/Projects/Server/Timer/Timer.TimerWheel.cs @@ -221,12 +221,17 @@ namespace Server continue; } - var name = t.ToString(); - - hash.TryGetValue(name, out var count); - hash[name] = count + 1; - - total++; + while (t != null) + { + var name = t.ToString(); + + hash.TryGetValue(name, out var count); + hash[name] = count + 1; + + total++; + + t = t?._nextTimer; + } } } From 8112602b88b92bdcdd0a02ee2abf7a687a661d9c Mon Sep 17 00:00:00 2001 From: IAmDanielDinner <38978615+SpeedyDevil@users.noreply.github.com> Date: Mon, 4 Apr 2022 22:39:16 +0200 Subject: [PATCH 130/213] docs: Documentation update (#941) --- docs/scripting-guide/serialization.md | 163 ++++++++++++++++++++++++++ docs/scripting-guide/timers.md | 8 ++ mkdocs.yml | 5 +- 3 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 docs/scripting-guide/serialization.md create mode 100644 docs/scripting-guide/timers.md diff --git a/docs/scripting-guide/serialization.md b/docs/scripting-guide/serialization.md new file mode 100644 index 000000000..095930751 --- /dev/null +++ b/docs/scripting-guide/serialization.md @@ -0,0 +1,163 @@ +--- +title: Serialization +--- + +# Serialization / Savings + +=== "Generic persistence" + ```Persistence.Serialize``` and ```Persistence.Deserialize``` is replaced with GenericPersistence class + + Example of how to persist a custom system. + + ```cs + namespace Server.ExampleSystem + { + public static class ExampleSerialization + { + public static void Configure() + { + GenericPersistence.Register("ExampleSystem", Serialize, Deserialize); + } + + public static void Serialize(IGenericWriter writer) + { + // Do serialization here + writer.WriteEncodedInt(0); // version + } + + public static void Deserialize(IGenericReader reader) + { + // Do deserialization here + var version = reader.ReadEncodedInt(); + } + } + } + ``` + +=== "Codegen" + ### Basic info + ModernUO can programatically generate migrations. This feature is based on internal C# Source generators [More info](https://devblogs.microsoft.com/dotnet/introducing-c-source-generators/) + + Old way of serializing objects: + ```cs + public class ExampleItem : Item + { + public string ExampleText { get; set; } + + [Constructible] + public ExampleItem() : base(0) + { + + } + public ExampleItem(Serial serial) : base(serial) + { + } + + public override void Serialize(IGenericWriter writer) + { + base.Serialize(writer); + + writer.WriteEncodedInt(0); //Version + writer.Write(ExampleText); + } + + public override void Deserialize(IGenericReader reader) + { + base.Deserialize(reader); + + var version = reader.ReadEncodedInt(); + ExampleText = reader.ReadString(); + } + } + ``` + + Same class serialized with codegen + ```cs + [Serializable(0)] + public partial class ExampleItem : Item + { + [SerializableField(0)] + public string ExampleText { get; set; } + + [Constructible] + public ExampleItem() : base(0) + { + + } + } + ``` + + ### Step by step + 1. Add ```SerializableAttribute(versionNumber)``` to your class and make it ```partial``` + ```cs + [Serializable(0)] + public partial class ExampleItem : Item + ``` + 1. Delete constructors with ```Serial serial```, ```Serialize``` and ```Deserialize``` methods. + 1. Add ```SerializableField(fieldOrder)``` attribute to all field you want to serialize. + ```cs + [SerializableField(0)] + public string ExampleText { get; set; } + ``` + 1. Build project "Run Schema Migrations". ModernUO will create migration files for you. In this case "Server.Items.ExampleItem.v0.json" and "Server.Items.ExampleItem.Serialization.cs" + These files contains all information and classes needed for MUO to serialize/deserialize your objects. + + ### Migrations + When new field is added to serialization, you need to increment versionNumber and make migration files. Here is little example. + + New class code will look like this: + ```cs + [Serializable(1)] + public partial class ExampleItem : Item + { + [SerializableField(0)] + public string ExampleText { get; set; } + + [SerializableField(1)] + public string AddedExampleTest { get; set; } + + [Constructible] + public ExampleItem() : base(0) + { + } + } + ``` + + After building "Run Schema Migrations" project, MUO will generate V0Content in serialization class. + + This Content contains all fields from V0. + Now create MigrateFrom for each version you make, in this case V0. + + !!! Tip + When you have more versions, create standalone file for migrations only. For example "ExampleItem.Migrations.cs" + + ```cs + private void MigrateFrom(V0Content content) + { + ExampleText = content.ExampleText; + } + ``` + + Your migration is now completed. + + ### Migrating from pre-codegen + For migration from pre-codegen code, use method + ```cs + private void Deserialize(IGenericReader reader, int version) + ``` + + this method is called when codegen doesnt have VXContent for deserialized object or version of Content is lower than deserialized. + In this method you can make old fashioned deserialization as before codegen. + + ### After deserialization + For some code changes after world load, you can use AfterDeserializationAttribute. + ```cs + [AfterDeserialization] + private void AfterDeserialization() + { + // Some code here + } + ``` + + ### Embedded serialization + Sometimes you need to serialize object inside object. For this you should use "EmbeddedSerializableAttribute". Nice example to understand it is ["AquariumState"](https://github.com/modernuo/ModernUO/blob/main/Projects/UOContent/Items/Aquarium/AquariumState.cs) diff --git a/docs/scripting-guide/timers.md b/docs/scripting-guide/timers.md new file mode 100644 index 000000000..443291e14 --- /dev/null +++ b/docs/scripting-guide/timers.md @@ -0,0 +1,8 @@ +--- +title: Timers +--- + +# Timers + +ModernUO completely changed the timer system to use an optimized data structure called a timer wheel. This will allow shards to add thousands of timers without slowing down the server. Traditionally the timer system used a thread and locked to add/remove/process timers. All of this is gone. +With the new timer system there is no TimerPriority. This can be deleted entirely from your scripts. diff --git a/mkdocs.yml b/mkdocs.yml index dcb2d826d..9ab434a9c 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -9,7 +9,7 @@ edit_uri: edit/main/docs/ repo_name: modernuo/modernuo repo_url: https://github.com/modernuo/modernuo site_description: The Ultima Online Server Emulator for the modern era! -copyright: Copyright 2019-2020 ModernUO Development Team +copyright: Copyright 2019-2022 ModernUO Development Team theme: name: material favicon: branding/favicon.png @@ -72,3 +72,6 @@ nav: - 'Get Started': - 'installation.md' - 'building-server.md' + - 'Scripting guide': + - 'scripting-guide/timers.md' + - 'scripting-guide/serialization.md' From 943b2eca3661679bc2f6f973ad18c10c7097816f Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Wed, 6 Apr 2022 15:34:47 -0700 Subject: [PATCH 131/213] feat: Adds Combine for arrays (#988) --- Projects/Server/Utilities/Utility.cs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/Projects/Server/Utilities/Utility.cs b/Projects/Server/Utilities/Utility.cs index 30f25b577..6881fb03d 100644 --- a/Projects/Server/Utilities/Utility.cs +++ b/Projects/Server/Utilities/Utility.cs @@ -1554,5 +1554,32 @@ namespace Server min = date.Minute; sec = date.Second; } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static T[] Combine(this IList source, bool pooled = false, params IList[] arrays) + { + var totalLength = source.Count; + foreach (var arr in arrays) + { + totalLength += arr.Count; + } + + if (totalLength == 0) + { + return Array.Empty(); + } + + var combined = pooled ? STArrayPool.Shared.Rent(totalLength) : new T[totalLength]; + + source.CopyTo(combined, 0); + var position = source.Count; + foreach (var arr in arrays) + { + arr.CopyTo(combined, position); + position += arr.Count; + } + + return combined; + } } } From 0d9259e4cd3ad7c094cd7bc53010b1f38b2738f6 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Wed, 6 Apr 2022 15:51:03 -0700 Subject: [PATCH 132/213] fix: Adds Combine overloads (#989) --- Projects/Server/Utilities/Utility.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Projects/Server/Utilities/Utility.cs b/Projects/Server/Utilities/Utility.cs index 6881fb03d..ba4877fc9 100644 --- a/Projects/Server/Utilities/Utility.cs +++ b/Projects/Server/Utilities/Utility.cs @@ -1556,7 +1556,15 @@ namespace Server } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static T[] Combine(this IList source, bool pooled = false, params IList[] arrays) + public static T[] Combine(this IList source, params IList[] arrays) => + source.Combine(false, arrays); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static T[] CombinePooled(this IList source, params IList[] arrays) => + source.Combine(true, arrays); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static T[] Combine(this IList source, bool pooled, params IList[] arrays) { var totalLength = source.Count; foreach (var arr in arrays) From f91ebe81835eea0c3e82d6b913614580bbea1a4e Mon Sep 17 00:00:00 2001 From: Mink80 <46659983+Mink80@users.noreply.github.com> Date: Fri, 8 Apr 2022 19:37:42 +0200 Subject: [PATCH 133/213] fix: Fixes food stacking for poisoned food. (#987) --- Projects/UOContent/Items/Food/Food.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Projects/UOContent/Items/Food/Food.cs b/Projects/UOContent/Items/Food/Food.cs index 8110b24d4..7049c0a22 100644 --- a/Projects/UOContent/Items/Food/Food.cs +++ b/Projects/UOContent/Items/Food/Food.cs @@ -48,6 +48,19 @@ namespace Server.Items } } + public override bool CanStackWith(Item dropped) + { + if (dropped is Food food) + { + if (Poison != food.Poison || Poisoner != food.Poisoner) + { + return false; + } + } + return base.CanStackWith(dropped); + } + + public virtual bool Eat(Mobile from) { // Fill the Mobile with FillFactor From de0bf03f4656a355d582058b429fa99c4de283ba Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Tue, 12 Apr 2022 20:52:53 -0700 Subject: [PATCH 134/213] fix: Simplifies expansion checks (#994) --- Distribution/Data/expansion.json | 42 +++++++++---------- Projects/Server/ExpansionInfo.cs | 9 ++-- .../Network/Packets/OutgoingAccountPackets.cs | 1 - 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/Distribution/Data/expansion.json b/Distribution/Data/expansion.json index e0b036f61..50ce99c51 100644 --- a/Distribution/Data/expansion.json +++ b/Distribution/Data/expansion.json @@ -335,9 +335,9 @@ "ClientFlags": "Malas", "FeatureFlags": { "None": false, - "T2A": true, - "UOR": true, - "UOTD": true, + "T2A": false, + "UOR": false, + "UOTD": false, "LBR": true, "AOS": true, "SixthCharacterSlot": false, @@ -401,9 +401,9 @@ "ClientFlags": "Tokuno", "FeatureFlags": { "None": false, - "T2A": true, - "UOR": true, - "UOTD": true, + "T2A": false, + "UOR": false, + "UOTD": false, "LBR": true, "AOS": true, "SixthCharacterSlot": false, @@ -467,9 +467,9 @@ "ClientFlags": null, "FeatureFlags": { "None": false, - "T2A": true, - "UOR": true, - "UOTD": true, + "T2A": false, + "UOR": false, + "UOTD": false, "LBR": true, "AOS": true, "SixthCharacterSlot": false, @@ -533,9 +533,9 @@ "ClientFlags": "TerMur", "FeatureFlags": { "None": false, - "T2A": true, - "UOR": true, - "UOTD": true, + "T2A": false, + "UOR": false, + "UOTD": false, "LBR": true, "AOS": true, "SixthCharacterSlot": false, @@ -599,9 +599,9 @@ "ClientFlags": null, "FeatureFlags": { "None": false, - "T2A": true, - "UOR": true, - "UOTD": true, + "T2A": false, + "UOR": false, + "UOTD": false, "LBR": true, "AOS": true, "SixthCharacterSlot": false, @@ -665,9 +665,9 @@ "ClientFlags": null, "FeatureFlags": { "None": false, - "T2A": true, - "UOR": true, - "UOTD": true, + "T2A": false, + "UOR": false, + "UOTD": false, "LBR": true, "AOS": true, "SixthCharacterSlot": false, @@ -731,9 +731,9 @@ "ClientFlags": null, "FeatureFlags": { "None": false, - "T2A": true, - "UOR": true, - "UOTD": true, + "T2A": false, + "UOR": false, + "UOTD": false, "LBR": true, "AOS": true, "SixthCharacterSlot": false, diff --git a/Projects/Server/ExpansionInfo.cs b/Projects/Server/ExpansionInfo.cs index 18407c052..fbbbdd2bb 100644 --- a/Projects/Server/ExpansionInfo.cs +++ b/Projects/Server/ExpansionInfo.cs @@ -57,7 +57,7 @@ namespace Server { None = 0x00000000, T2A = 0x00000001, - UOR = 0x00000002, + UOR = 0x00000002, // In later clients, the T2A/UOR flags are negative feature flags to disable body replacement of Pre-AOS graphics. UOTD = 0x00000004, LBR = 0x00000008, AOS = 0x00000010, @@ -65,9 +65,9 @@ namespace Server SE = 0x00000040, ML = 0x00000080, EigthAge = 0x00000100, - NinthAge = 0x00000200, /* Crystal/Shadow Custom House Tiles */ + NinthAge = 0x00000200, // Crystal/Shadow Custom House Tiles TenthAge = 0x00000400, - IncreasedStorage = 0x00000800, /* Increased Housing/Bank Storage */ + IncreasedStorage = 0x00000800, // Increased Housing/Bank Storage SeventhCharacterSlot = 0x00001000, RoleplayFaces = 0x00002000, TrialAccount = 0x00004000, @@ -86,7 +86,8 @@ namespace Server ExpansionUOR = ExpansionT2A | UOR, ExpansionUOTD = ExpansionUOR | UOTD, ExpansionLBR = ExpansionUOTD | LBR, - ExpansionAOS = ExpansionLBR | AOS | LiveAccount, + // In later clients, the AOS+ expansions include the Publish 16 LBR flag, but not the previous expansions. + ExpansionAOS = LBR | AOS | LiveAccount, ExpansionSE = ExpansionAOS | SE, ExpansionML = ExpansionSE | ML | NinthAge, ExpansionSA = ExpansionML | SA | Gothic | Rustic, diff --git a/Projects/Server/Network/Packets/OutgoingAccountPackets.cs b/Projects/Server/Network/Packets/OutgoingAccountPackets.cs index d29a8cbe4..8e6e56d32 100644 --- a/Projects/Server/Network/Packets/OutgoingAccountPackets.cs +++ b/Projects/Server/Network/Packets/OutgoingAccountPackets.cs @@ -149,7 +149,6 @@ public static class OutgoingAccountPackets if (ns.Account.Limit >= 6) { flags |= FeatureFlags.LiveAccount; - flags &= ~FeatureFlags.UOTD; if (ns.Account.Limit > 6) { From 6c22bb2b972af06151a31112817c56a5ab93d082 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Tue, 12 Apr 2022 21:00:30 -0700 Subject: [PATCH 135/213] fix: Fixes spelling of 8th age (#995) --- Distribution/Data/expansion.json | 24 ++++++++++++------------ Projects/Server/ExpansionInfo.cs | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Distribution/Data/expansion.json b/Distribution/Data/expansion.json index 50ce99c51..90be17229 100644 --- a/Distribution/Data/expansion.json +++ b/Distribution/Data/expansion.json @@ -13,7 +13,7 @@ "SixthCharacterSlot": false, "SE": false, "ML": false, - "EigthAge": false, + "EighthAge": false, "NinthAge": false, "TenthAge": false, "IncreasedStorage": false, @@ -79,7 +79,7 @@ "SixthCharacterSlot": false, "SE": false, "ML": false, - "EigthAge": false, + "EighthAge": false, "NinthAge": false, "TenthAge": false, "IncreasedStorage": false, @@ -145,7 +145,7 @@ "SixthCharacterSlot": false, "SE": false, "ML": false, - "EigthAge": false, + "EighthAge": false, "NinthAge": false, "TenthAge": false, "IncreasedStorage": false, @@ -211,7 +211,7 @@ "SixthCharacterSlot": false, "SE": false, "ML": false, - "EigthAge": false, + "EighthAge": false, "NinthAge": false, "TenthAge": false, "IncreasedStorage": false, @@ -277,7 +277,7 @@ "SixthCharacterSlot": false, "SE": false, "ML": false, - "EigthAge": false, + "EighthAge": false, "NinthAge": false, "TenthAge": false, "IncreasedStorage": false, @@ -343,7 +343,7 @@ "SixthCharacterSlot": false, "SE": false, "ML": false, - "EigthAge": false, + "EighthAge": false, "NinthAge": false, "TenthAge": false, "IncreasedStorage": false, @@ -409,7 +409,7 @@ "SixthCharacterSlot": false, "SE": true, "ML": false, - "EigthAge": false, + "EighthAge": false, "NinthAge": false, "TenthAge": false, "IncreasedStorage": false, @@ -475,7 +475,7 @@ "SixthCharacterSlot": false, "SE": true, "ML": true, - "EigthAge": false, + "EighthAge": false, "NinthAge": true, "TenthAge": false, "IncreasedStorage": false, @@ -541,7 +541,7 @@ "SixthCharacterSlot": false, "SE": true, "ML": true, - "EigthAge": false, + "EighthAge": false, "NinthAge": true, "TenthAge": false, "IncreasedStorage": false, @@ -607,7 +607,7 @@ "SixthCharacterSlot": false, "SE": true, "ML": true, - "EigthAge": false, + "EighthAge": false, "NinthAge": true, "TenthAge": false, "IncreasedStorage": false, @@ -673,7 +673,7 @@ "SixthCharacterSlot": false, "SE": true, "ML": true, - "EigthAge": false, + "EighthAge": false, "NinthAge": true, "TenthAge": false, "IncreasedStorage": false, @@ -739,7 +739,7 @@ "SixthCharacterSlot": false, "SE": true, "ML": true, - "EigthAge": false, + "EighthAge": false, "NinthAge": true, "TenthAge": false, "IncreasedStorage": false, diff --git a/Projects/Server/ExpansionInfo.cs b/Projects/Server/ExpansionInfo.cs index fbbbdd2bb..3d9ca5cd5 100644 --- a/Projects/Server/ExpansionInfo.cs +++ b/Projects/Server/ExpansionInfo.cs @@ -64,7 +64,7 @@ namespace Server SixthCharacterSlot = 0x00000020, SE = 0x00000040, ML = 0x00000080, - EigthAge = 0x00000100, + EighthAge = 0x00000100, NinthAge = 0x00000200, // Crystal/Shadow Custom House Tiles TenthAge = 0x00000400, IncreasedStorage = 0x00000800, // Increased Housing/Bank Storage From 910549db849b7644d3e53edff994ae7fb1d3be08 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Thu, 14 Apr 2022 16:52:45 -0700 Subject: [PATCH 136/213] fix: Fixes loading multi when client is missing (#996) * Changes reading multi.mul/multi.idx so it is loaded entirely during bootup. * Fixes finding files in Linux. * Fixes handling HS format. * Removes verdata support. ModernUO will still have issues if there is a multi.mul that is pre-HS loaded when it detects a client that is 7.0.9+. --- Projects/Server/Main.cs | 4 +- Projects/Server/MultiData.cs | 1807 +++++++++++++++++----------------- 2 files changed, 881 insertions(+), 930 deletions(-) diff --git a/Projects/Server/Main.cs b/Projects/Server/Main.cs index 1eac5d8e8..d7af5d17c 100644 --- a/Projects/Server/Main.cs +++ b/Projects/Server/Main.cs @@ -249,15 +249,13 @@ namespace Server { fullPath = Path.Combine(p, path); - if (IsLinux) + if (IsLinux && !File.Exists(fullPath)) { var fi = new FileInfo(fullPath); fullPath = fi.Directory!.EnumerateFiles( fi.Name, new EnumerationOptions { MatchCasing = MatchCasing.CaseInsensitive } ).FirstOrDefault()?.FullName; - - break; } if (File.Exists(fullPath)) diff --git a/Projects/Server/MultiData.cs b/Projects/Server/MultiData.cs index ead7417af..b815ab0c9 100644 --- a/Projects/Server/MultiData.cs +++ b/Projects/Server/MultiData.cs @@ -4,990 +4,943 @@ using System.Collections.Generic; using System.IO; using System.IO.Compression; -namespace Server +namespace Server; + +public static class MultiData { - public static class MultiData + public static void Configure() { - private static readonly BinaryReader m_IndexReader; - private static readonly BinaryReader m_StreamReader; + var multiUOPPath = Core.FindDataFile("MultiCollection.uop", false); - public static readonly bool PostHSMulFormat; - public static readonly bool UsingUOPFormat; - - static MultiData() + if (File.Exists(multiUOPPath)) { - var multiUOPPath = Core.FindDataFile("MultiCollection.uop", false); - - if (File.Exists(multiUOPPath)) - { - LoadUOP(multiUOPPath); - UsingUOPFormat = true; - PostHSMulFormat = false; - return; - } - - // Client version 7.0.9.0+ - PostHSMulFormat = UOClient.ServerClientVersion >= ClientVersion.Version7090; - - var idxPath = Core.FindDataFile("multi.idx"); - var mulPath = Core.FindDataFile("multi.mul"); - - var idx = new FileStream(idxPath, FileMode.Open, FileAccess.Read, FileShare.Read); - m_IndexReader = new BinaryReader(idx); - - var stream = new FileStream(mulPath, FileMode.Open, FileAccess.Read, FileShare.Read); - m_StreamReader = new BinaryReader(stream); - - var vdPath = Core.FindDataFile("verdata.mul", false); - - if (!File.Exists(vdPath)) - { - return; - } - - using var fs = new FileStream(vdPath, FileMode.Open, FileAccess.Read, FileShare.Read); - var bin = new BinaryReader(fs); - - var count = bin.ReadInt32(); - - for (var i = 0; i < count; ++i) - { - var file = bin.ReadInt32(); - var index = bin.ReadInt32(); - var lookup = bin.ReadInt32(); - var length = bin.ReadInt32(); - bin.ReadInt32(); // extra - - if (file == 14 && index >= 0 && lookup >= 0 && length > 0) - { - bin.BaseStream.Seek(lookup, SeekOrigin.Begin); - - Components[index] = new MultiComponentList(bin, length / 12); - - bin.BaseStream.Seek(24 + i * 20, SeekOrigin.Begin); - } - } - - bin.Close(); + LoadUOP(multiUOPPath); + return; } - public static Dictionary Components { get; } = new(); + // OSI Client 7.0.9.0+ uses 64bit tiledata flags + var postHSMulFormat = ServerConfiguration.GetSetting( + "maps.enablePostHSMultiComponentFormat", + UOClient.ServerClientVersion >= ClientVersion.Version7090 + ); - public static MultiComponentList GetComponents(int multiID) - { - MultiComponentList mcl; - - multiID &= 0x3FFF; - - if (Components.ContainsKey(multiID)) - { - mcl = Components[multiID]; - } - else if (!UsingUOPFormat) - { - Components[multiID] = mcl = Load(multiID); - } - else - { - mcl = MultiComponentList.Empty; - } - - return mcl; - } - - public static void LoadUOP(string path) - { - var stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read); - var streamReader = new BinaryReader(stream); - - // Head Information Start - if (streamReader.ReadInt32() != 0x0050594D) // Not a UOP Files - { - return; - } - - if (streamReader.ReadInt32() > 5) // Bad Version - { - return; - } - - // Multi ID List Array Start - UOPHash.BuildChunkIDs(out var chunkIds); - // Multi ID List Array End - - streamReader.ReadUInt32(); // format timestamp? 0xFD23EC43 - var startAddress = streamReader.ReadInt64(); - - streamReader.ReadInt32(); - streamReader.ReadInt32(); - - stream.Seek(startAddress, SeekOrigin.Begin); // Head Information End - - long nextBlock; - - do - { - var blockFileCount = streamReader.ReadInt32(); - nextBlock = streamReader.ReadInt64(); - - var index = 0; - - do - { - var offset = streamReader.ReadInt64(); - - var headerSize = streamReader.ReadInt32(); // header length - var compressedSize = streamReader.ReadInt32(); // compressed size - var decompressedSize = streamReader.ReadInt32(); // decompressed size - - var filehash = streamReader.ReadUInt64(); // filename hash (HashLittle2) - streamReader.ReadUInt32(); - var compressionMethod = streamReader.ReadInt16(); // compression method (0 = none, 1 = zlib) - - index++; - - if (offset == 0 || decompressedSize == 0 || filehash == 0x126D1E99DDEDEE0A) // Exclude housing.bin - { - continue; - } - - chunkIds.TryGetValue(filehash, out var chunkID); - - var position = stream.Position; // save current position - - stream.Seek(offset + headerSize, SeekOrigin.Begin); - - Span sourceData = GC.AllocateUninitializedArray(compressedSize); - - if (stream.Read(sourceData) != compressedSize) - { - continue; - } - - Span data; - - if (compressionMethod == 1) - { - data = GC.AllocateUninitializedArray(decompressedSize); - Zlib.Unpack(data, ref decompressedSize, sourceData, compressedSize); - } - else - { - data = sourceData; - } - - var tileList = new List(); - - var reader = new SpanReader(data); - reader.Seek(4, SeekOrigin.Begin); - var count = reader.ReadUInt32LE(); - - for (uint i = 0; i < count; i++) - { - var itemId = reader.ReadUInt16LE(); - var x = reader.ReadInt16LE(); - var y = reader.ReadInt16LE(); - var z = reader.ReadInt16LE(); - var flagValue = reader.ReadUInt16LE(); - - var tileFlag = flagValue switch - { - 1 => TileFlag.None, - 257 => TileFlag.Generic, - _ => TileFlag.Background // 0 - }; - - var clilocsCount = reader.ReadUInt32LE(); - var skip = (int)Math.Min(clilocsCount, int.MaxValue) * 4; // bypass binary block - reader.Seek(skip, SeekOrigin.Current); - - tileList.Add(new MultiTileEntry(itemId, x, y, z, tileFlag)); - } - - Components[chunkID] = new MultiComponentList(tileList); - - stream.Seek(position, SeekOrigin.Begin); // back to position - } while (index < blockFileCount); - } while (stream.Seek(nextBlock, SeekOrigin.Begin) != 0); - } - - // TODO: Change this to read the file all during load time - public static MultiComponentList Load(int multiID) - { - try - { - m_IndexReader.BaseStream.Seek(multiID * 12, SeekOrigin.Begin); - - var lookup = m_IndexReader.ReadInt32(); - var length = m_IndexReader.ReadInt32(); - - if (lookup < 0 || length <= 0) - { - return MultiComponentList.Empty; - } - - m_StreamReader.BaseStream.Seek(lookup, SeekOrigin.Begin); - - return new MultiComponentList(m_StreamReader, length / (PostHSMulFormat ? 16 : 12)); - } - catch - { - return MultiComponentList.Empty; - } - } + LoadMul(postHSMulFormat); } - public struct MultiTileEntry + private static Dictionary _components = new(); + + public static MultiComponentList GetComponents(int multiID) => + _components.TryGetValue(multiID & 0x3FFF, out var mcl) ? mcl : MultiComponentList.Empty; + + private static void LoadUOP(string path) { - public ushort ItemId { get; set; } - public short OffsetX { get; set; } - public short OffsetY { get; set; } - public short OffsetZ { get; set; } - public TileFlag Flags { get; set; } + using var stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read); + var streamReader = new BinaryReader(stream); - public MultiTileEntry(ushort itemID, short xOffset, short yOffset, short zOffset, TileFlag flags) + // Head Information Start + if (streamReader.ReadInt32() != 0x0050594D) // Not a UOP File { - ItemId = itemID; - OffsetX = xOffset; - OffsetY = yOffset; - OffsetZ = zOffset; - Flags = flags; - } - } - - public sealed class MultiComponentList - { - public static readonly MultiComponentList Empty = new(); - - private Point2D m_Min, m_Max; - - public MultiComponentList(MultiComponentList toCopy) - { - m_Min = toCopy.m_Min; - m_Max = toCopy.m_Max; - - Center = toCopy.Center; - - Width = toCopy.Width; - Height = toCopy.Height; - - Tiles = new StaticTile[Width][][]; - - for (var x = 0; x < Width; ++x) - { - Tiles[x] = new StaticTile[Height][]; - - for (var y = 0; y < Height; ++y) - { - Tiles[x][y] = new StaticTile[toCopy.Tiles[x][y].Length]; - - for (var i = 0; i < Tiles[x][y].Length; ++i) - { - Tiles[x][y][i] = toCopy.Tiles[x][y][i]; - } - } - } - - List = new MultiTileEntry[toCopy.List.Length]; - - for (var i = 0; i < List.Length; ++i) - { - List[i] = toCopy.List[i]; - } + return; } - public MultiComponentList(IGenericReader reader) + if (streamReader.ReadInt32() > 5) // Bad Version { - var version = reader.ReadInt(); - - m_Min = reader.ReadPoint2D(); - m_Max = reader.ReadPoint2D(); - Center = reader.ReadPoint2D(); - Width = reader.ReadInt(); - Height = reader.ReadInt(); - - var length = reader.ReadInt(); - - var allTiles = List = new MultiTileEntry[length]; - - if (version == 0) - { - for (var i = 0; i < length; ++i) - { - int id = reader.ReadShort(); - if (id >= 0x4000) - { - id -= 0x4000; - } - - allTiles[i].ItemId = (ushort)id; - allTiles[i].OffsetX = reader.ReadShort(); - allTiles[i].OffsetY = reader.ReadShort(); - allTiles[i].OffsetZ = reader.ReadShort(); - allTiles[i].Flags = (TileFlag)reader.ReadInt(); - } - } - else - { - for (var i = 0; i < length; ++i) - { - allTiles[i].ItemId = reader.ReadUShort(); - allTiles[i].OffsetX = reader.ReadShort(); - allTiles[i].OffsetY = reader.ReadShort(); - allTiles[i].OffsetZ = reader.ReadShort(); - allTiles[i].Flags = (TileFlag)reader.ReadInt(); - } - } - - var tiles = new TileList[Width][]; - Tiles = new StaticTile[Width][][]; - - for (var x = 0; x < Width; ++x) - { - tiles[x] = new TileList[Height]; - Tiles[x] = new StaticTile[Height][]; - - for (var y = 0; y < Height; ++y) - { - tiles[x][y] = new TileList(); - } - } - - for (var i = 0; i < allTiles.Length; ++i) - { - if (i == 0 || allTiles[i].Flags != 0) - { - var xOffset = allTiles[i].OffsetX + Center.m_X; - var yOffset = allTiles[i].OffsetY + Center.m_Y; - - tiles[xOffset][yOffset].Add(allTiles[i].ItemId, (sbyte)allTiles[i].OffsetZ); - } - } - - for (var x = 0; x < Width; ++x) - { - for (var y = 0; y < Height; ++y) - { - Tiles[x][y] = tiles[x][y].ToArray(); - } - } + return; } - public MultiComponentList(BinaryReader reader, int count) + UOPHash.BuildChunkIDs(out var chunkIds); + + streamReader.ReadUInt32(); // format timestamp? 0xFD23EC43 + var startAddress = streamReader.ReadInt64(); + + stream.Seek(startAddress, SeekOrigin.Begin); // End of head block + + long nextBlock; + + do { - var allTiles = List = new MultiTileEntry[count]; - - for (var i = 0; i < count; ++i) - { - allTiles[i].ItemId = reader.ReadUInt16(); - allTiles[i].OffsetX = reader.ReadInt16(); - allTiles[i].OffsetY = reader.ReadInt16(); - allTiles[i].OffsetZ = reader.ReadInt16(); - allTiles[i].Flags = MultiData.PostHSMulFormat - ? (TileFlag)reader.ReadUInt64() - : (TileFlag)reader.ReadUInt32(); - - var e = allTiles[i]; - - if (i == 0 || e.Flags != 0) - { - if (e.OffsetX < m_Min.m_X) - { - m_Min.m_X = e.OffsetX; - } - - if (e.OffsetY < m_Min.m_Y) - { - m_Min.m_Y = e.OffsetY; - } - - if (e.OffsetX > m_Max.m_X) - { - m_Max.m_X = e.OffsetX; - } - - if (e.OffsetY > m_Max.m_Y) - { - m_Max.m_Y = e.OffsetY; - } - } - } - - Center = new Point2D(-m_Min.m_X, -m_Min.m_Y); - Width = m_Max.m_X - m_Min.m_X + 1; - Height = m_Max.m_Y - m_Min.m_Y + 1; - - var tiles = new TileList[Width][]; - Tiles = new StaticTile[Width][][]; - - for (var x = 0; x < Width; ++x) - { - tiles[x] = new TileList[Height]; - Tiles[x] = new StaticTile[Height][]; - - for (var y = 0; y < Height; ++y) - { - tiles[x][y] = new TileList(); - } - } - - for (var i = 0; i < allTiles.Length; ++i) - { - if (i == 0 || allTiles[i].Flags != 0) - { - var xOffset = allTiles[i].OffsetX + Center.m_X; - var yOffset = allTiles[i].OffsetY + Center.m_Y; - - tiles[xOffset][yOffset].Add(allTiles[i].ItemId, (sbyte)allTiles[i].OffsetZ); - } - } - - for (var x = 0; x < Width; ++x) - { - for (var y = 0; y < Height; ++y) - { - Tiles[x][y] = tiles[x][y].ToArray(); - } - } - } - - public MultiComponentList(List list) - { - var allTiles = List = new MultiTileEntry[list.Count]; - - for (var i = 0; i < list.Count; ++i) - { - allTiles[i].ItemId = list[i].ItemId; - allTiles[i].OffsetX = list[i].OffsetX; - allTiles[i].OffsetY = list[i].OffsetY; - allTiles[i].OffsetZ = list[i].OffsetZ; - - allTiles[i].Flags = list[i].Flags; - - var e = allTiles[i]; - - if (i == 0 || e.Flags != 0) - { - if (e.OffsetX < m_Min.m_X) - { - m_Min.m_X = e.OffsetX; - } - - if (e.OffsetY < m_Min.m_Y) - { - m_Min.m_Y = e.OffsetY; - } - - if (e.OffsetX > m_Max.m_X) - { - m_Max.m_X = e.OffsetX; - } - - if (e.OffsetY > m_Max.m_Y) - { - m_Max.m_Y = e.OffsetY; - } - } - } - - Center = new Point2D(-m_Min.m_X, -m_Min.m_Y); - Width = m_Max.m_X - m_Min.m_X + 1; - Height = m_Max.m_Y - m_Min.m_Y + 1; - - var tiles = new TileList[Width][]; - Tiles = new StaticTile[Width][][]; - - for (var x = 0; x < Width; ++x) - { - tiles[x] = new TileList[Height]; - Tiles[x] = new StaticTile[Height][]; - - for (var y = 0; y < Height; ++y) - { - tiles[x][y] = new TileList(); - } - } - - for (var i = 0; i < allTiles.Length; ++i) - { - if (i == 0 || allTiles[i].Flags != 0) - { - var xOffset = allTiles[i].OffsetX + Center.m_X; - var yOffset = allTiles[i].OffsetY + Center.m_Y; - var itemID = (allTiles[i].ItemId & TileData.MaxItemValue) | 0x10000; - - tiles[xOffset][yOffset].Add((ushort)itemID, (sbyte)allTiles[i].OffsetZ); - } - } - - for (var x = 0; x < Width; ++x) - { - for (var y = 0; y < Height; ++y) - { - Tiles[x][y] = tiles[x][y].ToArray(); - } - } - } - - private MultiComponentList() - { - Tiles = Array.Empty(); - List = Array.Empty(); - } - - public static void Configure() - { - // OSI Client Patch 7.0.9.0 - PostHSFormat = ServerConfiguration.GetSetting("maps.enablePostHSMultiComponentFormat", true); - } - - public static bool PostHSFormat { get; set; } - - public Point2D Min => m_Min; - public Point2D Max => m_Max; - - public Point2D Center { get; } - - public int Width { get; private set; } - - public int Height { get; private set; } - - public StaticTile[][][] Tiles { get; private set; } - - public MultiTileEntry[] List { get; private set; } - - public void Add(int itemID, int x, int y, int z) - { - var vx = x + Center.m_X; - var vy = y + Center.m_Y; - - if (vx >= 0 && vx < Width && vy >= 0 && vy < Height) - { - var oldTiles = Tiles[vx][vy]; - - for (var i = oldTiles.Length - 1; i >= 0; --i) - { - var data = TileData.ItemTable[itemID & TileData.MaxItemValue]; - - if (oldTiles[i].Z == z && oldTiles[i].Height > 0 == data.Height > 0) - { - var newIsRoof = (data.Flags & TileFlag.Roof) != 0; - var oldIsRoof = - (TileData.ItemTable[oldTiles[i].ID & TileData.MaxItemValue].Flags & TileFlag.Roof) != 0; - - if (newIsRoof == oldIsRoof) - { - Remove(oldTiles[i].ID, x, y, z); - } - } - } - - oldTiles = Tiles[vx][vy]; - - var newTiles = new StaticTile[oldTiles.Length + 1]; - - for (var i = 0; i < oldTiles.Length; ++i) - { - newTiles[i] = oldTiles[i]; - } - - newTiles[oldTiles.Length] = new StaticTile((ushort)itemID, (sbyte)z); - - Tiles[vx][vy] = newTiles; - - var oldList = List; - var newList = new MultiTileEntry[oldList.Length + 1]; - - for (var i = 0; i < oldList.Length; ++i) - { - newList[i] = oldList[i]; - } - - newList[oldList.Length] = new MultiTileEntry( - (ushort)itemID, - (short)x, - (short)y, - (short)z, - TileFlag.Background - ); - - List = newList; - - if (x < m_Min.m_X) - { - m_Min.m_X = x; - } - - if (y < m_Min.m_Y) - { - m_Min.m_Y = y; - } - - if (x > m_Max.m_X) - { - m_Max.m_X = x; - } - - if (y > m_Max.m_Y) - { - m_Max.m_Y = y; - } - } - } - - public void RemoveXYZH(int x, int y, int z, int minHeight) - { - var vx = x + Center.m_X; - var vy = y + Center.m_Y; - - if (vx >= 0 && vx < Width && vy >= 0 && vy < Height) - { - var oldTiles = Tiles[vx][vy]; - - for (var i = 0; i < oldTiles.Length; ++i) - { - var tile = oldTiles[i]; - - if (tile.Z == z && tile.Height >= minHeight) - { - var newTiles = new StaticTile[oldTiles.Length - 1]; - - for (var j = 0; j < i; ++j) - { - newTiles[j] = oldTiles[j]; - } - - for (var j = i + 1; j < oldTiles.Length; ++j) - { - newTiles[j - 1] = oldTiles[j]; - } - - Tiles[vx][vy] = newTiles; - - break; - } - } - - var oldList = List; - - for (var i = 0; i < oldList.Length; ++i) - { - var tile = oldList[i]; - - if (tile.OffsetX == (short)x && tile.OffsetY == (short)y && tile.OffsetZ == (short)z && - TileData.ItemTable[tile.ItemId & TileData.MaxItemValue].Height >= minHeight) - { - var newList = new MultiTileEntry[oldList.Length - 1]; - - for (var j = 0; j < i; ++j) - { - newList[j] = oldList[j]; - } - - for (var j = i + 1; j < oldList.Length; ++j) - { - newList[j - 1] = oldList[j]; - } - - List = newList; - - break; - } - } - } - } - - public void Remove(int itemID, int x, int y, int z) - { - var vx = x + Center.m_X; - var vy = y + Center.m_Y; - - if (vx >= 0 && vx < Width && vy >= 0 && vy < Height) - { - var oldTiles = Tiles[vx][vy]; - - for (var i = 0; i < oldTiles.Length; ++i) - { - var tile = oldTiles[i]; - - if (tile.ID == itemID && tile.Z == z) - { - var newTiles = new StaticTile[oldTiles.Length - 1]; - - for (var j = 0; j < i; ++j) - { - newTiles[j] = oldTiles[j]; - } - - for (var j = i + 1; j < oldTiles.Length; ++j) - { - newTiles[j - 1] = oldTiles[j]; - } - - Tiles[vx][vy] = newTiles; - - break; - } - } - - var oldList = List; - - for (var i = 0; i < oldList.Length; ++i) - { - var tile = oldList[i]; - - if (tile.ItemId == itemID && tile.OffsetX == (short)x && tile.OffsetY == (short)y && - tile.OffsetZ == (short)z) - { - var newList = new MultiTileEntry[oldList.Length - 1]; - - for (var j = 0; j < i; ++j) - { - newList[j] = oldList[j]; - } - - for (var j = i + 1; j < oldList.Length; ++j) - { - newList[j - 1] = oldList[j]; - } - - List = newList; - - break; - } - } - } - } - - public void Resize(int newWidth, int newHeight) - { - int oldWidth = Width, oldHeight = Height; - var oldTiles = Tiles; - - var totalLength = 0; - - var newTiles = new StaticTile[newWidth][][]; - - for (var x = 0; x < newWidth; ++x) - { - newTiles[x] = new StaticTile[newHeight][]; - - for (var y = 0; y < newHeight; ++y) - { - if (x < oldWidth && y < oldHeight) - { - newTiles[x][y] = oldTiles[x][y]; - } - else - { - newTiles[x][y] = Array.Empty(); - } - - totalLength += newTiles[x][y].Length; - } - } - - Tiles = newTiles; - List = new MultiTileEntry[totalLength]; - Width = newWidth; - Height = newHeight; - - m_Min = Point2D.Zero; - m_Max = Point2D.Zero; + var blockFileCount = streamReader.ReadInt32(); + nextBlock = streamReader.ReadInt64(); var index = 0; - for (var x = 0; x < newWidth; ++x) + do { - for (var y = 0; y < newHeight; ++y) + var offset = streamReader.ReadInt64(); + + var headerSize = streamReader.ReadInt32(); // header length + var compressedSize = streamReader.ReadInt32(); // compressed size + var decompressedSize = streamReader.ReadInt32(); // decompressed size + + var filehash = streamReader.ReadUInt64(); // filename hash (HashLittle2) + streamReader.ReadUInt32(); + var compressionMethod = streamReader.ReadInt16(); // compression method (0 = none, 1 = zlib) + + index++; + + if (offset == 0 || decompressedSize == 0 || filehash == 0x126D1E99DDEDEE0A) // Exclude housing.bin { - var tiles = newTiles[x][y]; + continue; + } - for (var i = 0; i < tiles.Length; ++i) + chunkIds.TryGetValue(filehash, out var chunkID); + + var position = stream.Position; // save current position + + stream.Seek(offset + headerSize, SeekOrigin.Begin); + + Span sourceData = GC.AllocateUninitializedArray(compressedSize); + + if (stream.Read(sourceData) != compressedSize) + { + continue; + } + + Span data; + + if (compressionMethod == 1) + { + data = GC.AllocateUninitializedArray(decompressedSize); + Zlib.Unpack(data, ref decompressedSize, sourceData, compressedSize); + } + else + { + data = sourceData; + } + + var tileList = new List(); + + var reader = new SpanReader(data); + reader.Seek(4, SeekOrigin.Begin); + var count = reader.ReadUInt32LE(); + + for (uint i = 0; i < count; i++) + { + var itemId = reader.ReadUInt16LE(); + var x = reader.ReadInt16LE(); + var y = reader.ReadInt16LE(); + var z = reader.ReadInt16LE(); + var flagValue = reader.ReadUInt16LE(); + + var tileFlag = flagValue switch { - var tile = tiles[i]; + 1 => TileFlag.None, + 257 => TileFlag.Generic, + _ => TileFlag.Background // 0 + }; - var vx = x - Center.X; - var vy = y - Center.Y; + var clilocsCount = reader.ReadUInt32LE(); + var skip = (int)Math.Min(clilocsCount, int.MaxValue) * 4; // bypass binary block + reader.Seek(skip, SeekOrigin.Current); - if (vx < m_Min.m_X) - { - m_Min.m_X = vx; - } + tileList.Add(new MultiTileEntry(itemId, x, y, z, tileFlag)); + } - if (vy < m_Min.m_Y) - { - m_Min.m_Y = vy; - } + _components[chunkID] = new MultiComponentList(tileList); - if (vx > m_Max.m_X) - { - m_Max.m_X = vx; - } + stream.Seek(position, SeekOrigin.Begin); // back to position + } while (index < blockFileCount); + } while (stream.Seek(nextBlock, SeekOrigin.Begin) != 0); - if (vy > m_Max.m_Y) - { - m_Max.m_Y = vy; - } + streamReader.Close(); + } - List[index++] = new MultiTileEntry( - (ushort)tile.ID, - (short)vx, - (short)vy, - (short)tile.Z, - TileFlag.Background - ); + private static void LoadMul(bool postHSMulFormat) + { + var idxPath = Core.FindDataFile("multi.idx"); + var mulPath = Core.FindDataFile("multi.mul"); + + using var idx = new FileStream(idxPath, FileMode.Open, FileAccess.Read, FileShare.Read); + var idxReader = new BinaryReader(idx); + + using var stream = new FileStream(mulPath, FileMode.Open, FileAccess.Read, FileShare.Read); + var bin = new BinaryReader(stream); + + var count = (int)(idx.Length / 12); + for (var i = 0; i < count; i++) + { + var lookup = idxReader.ReadInt32(); + var length = idxReader.ReadInt32(); + idx.Seek(4, SeekOrigin.Current); // Extra + + if (lookup < 0 || length <= 0) + { + continue; + } + + bin.BaseStream.Seek(lookup, SeekOrigin.Begin); + _components[i] = new MultiComponentList(bin, length, postHSMulFormat); + } + + idxReader.Close(); + } +} + +public struct MultiTileEntry +{ + public ushort ItemId { get; set; } + public short OffsetX { get; set; } + public short OffsetY { get; set; } + public short OffsetZ { get; set; } + public TileFlag Flags { get; set; } + + public MultiTileEntry(ushort itemID, short xOffset, short yOffset, short zOffset, TileFlag flags) + { + ItemId = itemID; + OffsetX = xOffset; + OffsetY = yOffset; + OffsetZ = zOffset; + Flags = flags; + } +} + +public sealed class MultiComponentList +{ + public static readonly MultiComponentList Empty = new(); + + private Point2D m_Min, m_Max; + + public MultiComponentList(MultiComponentList toCopy) + { + m_Min = toCopy.m_Min; + m_Max = toCopy.m_Max; + + Center = toCopy.Center; + + Width = toCopy.Width; + Height = toCopy.Height; + + Tiles = new StaticTile[Width][][]; + + for (var x = 0; x < Width; ++x) + { + Tiles[x] = new StaticTile[Height][]; + + for (var y = 0; y < Height; ++y) + { + Tiles[x][y] = new StaticTile[toCopy.Tiles[x][y].Length]; + + for (var i = 0; i < Tiles[x][y].Length; ++i) + { + Tiles[x][y][i] = toCopy.Tiles[x][y][i]; + } + } + } + + List = new MultiTileEntry[toCopy.List.Length]; + + for (var i = 0; i < List.Length; ++i) + { + List[i] = toCopy.List[i]; + } + } + + public MultiComponentList(IGenericReader reader) + { + var version = reader.ReadInt(); + + m_Min = reader.ReadPoint2D(); + m_Max = reader.ReadPoint2D(); + Center = reader.ReadPoint2D(); + Width = reader.ReadInt(); + Height = reader.ReadInt(); + + var length = reader.ReadInt(); + + var allTiles = List = new MultiTileEntry[length]; + + if (version == 0) + { + for (var i = 0; i < length; ++i) + { + int id = reader.ReadShort(); + if (id >= 0x4000) + { + id -= 0x4000; + } + + allTiles[i].ItemId = (ushort)id; + allTiles[i].OffsetX = reader.ReadShort(); + allTiles[i].OffsetY = reader.ReadShort(); + allTiles[i].OffsetZ = reader.ReadShort(); + allTiles[i].Flags = (TileFlag)reader.ReadInt(); + } + } + else + { + for (var i = 0; i < length; ++i) + { + allTiles[i].ItemId = reader.ReadUShort(); + allTiles[i].OffsetX = reader.ReadShort(); + allTiles[i].OffsetY = reader.ReadShort(); + allTiles[i].OffsetZ = reader.ReadShort(); + allTiles[i].Flags = (TileFlag)reader.ReadInt(); + } + } + + var tiles = new TileList[Width][]; + Tiles = new StaticTile[Width][][]; + + for (var x = 0; x < Width; ++x) + { + tiles[x] = new TileList[Height]; + Tiles[x] = new StaticTile[Height][]; + + for (var y = 0; y < Height; ++y) + { + tiles[x][y] = new TileList(); + } + } + + for (var i = 0; i < allTiles.Length; ++i) + { + if (i == 0 || allTiles[i].Flags != 0) + { + var xOffset = allTiles[i].OffsetX + Center.m_X; + var yOffset = allTiles[i].OffsetY + Center.m_Y; + + tiles[xOffset][yOffset].Add(allTiles[i].ItemId, (sbyte)allTiles[i].OffsetZ); + } + } + + for (var x = 0; x < Width; ++x) + { + for (var y = 0; y < Height; ++y) + { + Tiles[x][y] = tiles[x][y].ToArray(); + } + } + } + + public MultiComponentList(BinaryReader reader, int length, bool postHSFormat) + { + var count = length / (postHSFormat ? 16 : 12); + var allTiles = List = new MultiTileEntry[count]; + + for (var i = 0; i < count; ++i) + { + allTiles[i].ItemId = reader.ReadUInt16(); + allTiles[i].OffsetX = reader.ReadInt16(); + allTiles[i].OffsetY = reader.ReadInt16(); + allTiles[i].OffsetZ = reader.ReadInt16(); + allTiles[i].Flags = postHSFormat ? (TileFlag)reader.ReadUInt64() : (TileFlag)reader.ReadUInt32(); + + var e = allTiles[i]; + + if (i == 0 || e.Flags != 0) + { + if (e.OffsetX < m_Min.m_X) + { + m_Min.m_X = e.OffsetX; + } + + if (e.OffsetY < m_Min.m_Y) + { + m_Min.m_Y = e.OffsetY; + } + + if (e.OffsetX > m_Max.m_X) + { + m_Max.m_X = e.OffsetX; + } + + if (e.OffsetY > m_Max.m_Y) + { + m_Max.m_Y = e.OffsetY; + } + } + } + + Center = new Point2D(-m_Min.m_X, -m_Min.m_Y); + Width = m_Max.m_X - m_Min.m_X + 1; + Height = m_Max.m_Y - m_Min.m_Y + 1; + + var tiles = new TileList[Width][]; + Tiles = new StaticTile[Width][][]; + + for (var x = 0; x < Width; ++x) + { + tiles[x] = new TileList[Height]; + Tiles[x] = new StaticTile[Height][]; + + for (var y = 0; y < Height; ++y) + { + tiles[x][y] = new TileList(); + } + } + + for (var i = 0; i < allTiles.Length; ++i) + { + if (i == 0 || allTiles[i].Flags != 0) + { + var xOffset = allTiles[i].OffsetX + Center.m_X; + var yOffset = allTiles[i].OffsetY + Center.m_Y; + + tiles[xOffset][yOffset].Add(allTiles[i].ItemId, (sbyte)allTiles[i].OffsetZ); + } + } + + for (var x = 0; x < Width; ++x) + { + for (var y = 0; y < Height; ++y) + { + Tiles[x][y] = tiles[x][y].ToArray(); + } + } + } + + public MultiComponentList(List list) + { + var allTiles = List = new MultiTileEntry[list.Count]; + + for (var i = 0; i < list.Count; ++i) + { + allTiles[i].ItemId = list[i].ItemId; + allTiles[i].OffsetX = list[i].OffsetX; + allTiles[i].OffsetY = list[i].OffsetY; + allTiles[i].OffsetZ = list[i].OffsetZ; + + allTiles[i].Flags = list[i].Flags; + + var e = allTiles[i]; + + if (i == 0 || e.Flags != 0) + { + if (e.OffsetX < m_Min.m_X) + { + m_Min.m_X = e.OffsetX; + } + + if (e.OffsetY < m_Min.m_Y) + { + m_Min.m_Y = e.OffsetY; + } + + if (e.OffsetX > m_Max.m_X) + { + m_Max.m_X = e.OffsetX; + } + + if (e.OffsetY > m_Max.m_Y) + { + m_Max.m_Y = e.OffsetY; + } + } + } + + Center = new Point2D(-m_Min.m_X, -m_Min.m_Y); + Width = m_Max.m_X - m_Min.m_X + 1; + Height = m_Max.m_Y - m_Min.m_Y + 1; + + var tiles = new TileList[Width][]; + Tiles = new StaticTile[Width][][]; + + for (var x = 0; x < Width; ++x) + { + tiles[x] = new TileList[Height]; + Tiles[x] = new StaticTile[Height][]; + + for (var y = 0; y < Height; ++y) + { + tiles[x][y] = new TileList(); + } + } + + for (var i = 0; i < allTiles.Length; ++i) + { + if (i == 0 || allTiles[i].Flags != 0) + { + var xOffset = allTiles[i].OffsetX + Center.m_X; + var yOffset = allTiles[i].OffsetY + Center.m_Y; + var itemID = (allTiles[i].ItemId & TileData.MaxItemValue) | 0x10000; + + tiles[xOffset][yOffset].Add((ushort)itemID, (sbyte)allTiles[i].OffsetZ); + } + } + + for (var x = 0; x < Width; ++x) + { + for (var y = 0; y < Height; ++y) + { + Tiles[x][y] = tiles[x][y].ToArray(); + } + } + } + + private MultiComponentList() + { + Tiles = Array.Empty(); + List = Array.Empty(); + } + + public Point2D Min => m_Min; + public Point2D Max => m_Max; + + public Point2D Center { get; } + + public int Width { get; private set; } + + public int Height { get; private set; } + + public StaticTile[][][] Tiles { get; private set; } + + public MultiTileEntry[] List { get; private set; } + + public void Add(int itemID, int x, int y, int z) + { + var vx = x + Center.m_X; + var vy = y + Center.m_Y; + + if (vx >= 0 && vx < Width && vy >= 0 && vy < Height) + { + var oldTiles = Tiles[vx][vy]; + + for (var i = oldTiles.Length - 1; i >= 0; --i) + { + var data = TileData.ItemTable[itemID & TileData.MaxItemValue]; + + if (oldTiles[i].Z == z && oldTiles[i].Height > 0 == data.Height > 0) + { + var newIsRoof = (data.Flags & TileFlag.Roof) != 0; + var oldIsRoof = + (TileData.ItemTable[oldTiles[i].ID & TileData.MaxItemValue].Flags & TileFlag.Roof) != 0; + + if (newIsRoof == oldIsRoof) + { + Remove(oldTiles[i].ID, x, y, z); } } } - } - public void Serialize(IGenericWriter writer) - { - writer.Write(1); // version; + oldTiles = Tiles[vx][vy]; - writer.Write(m_Min); - writer.Write(m_Max); - writer.Write(Center); + var newTiles = new StaticTile[oldTiles.Length + 1]; - writer.Write(Width); - writer.Write(Height); - - writer.Write(List.Length); - - for (var i = 0; i < List.Length; ++i) + for (var i = 0; i < oldTiles.Length; ++i) { - var ent = List[i]; + newTiles[i] = oldTiles[i]; + } - writer.Write(ent.ItemId); - writer.Write(ent.OffsetX); - writer.Write(ent.OffsetY); - writer.Write(ent.OffsetZ); - writer.Write((int)ent.Flags); + newTiles[oldTiles.Length] = new StaticTile((ushort)itemID, (sbyte)z); + + Tiles[vx][vy] = newTiles; + + var oldList = List; + var newList = new MultiTileEntry[oldList.Length + 1]; + + for (var i = 0; i < oldList.Length; ++i) + { + newList[i] = oldList[i]; + } + + newList[oldList.Length] = new MultiTileEntry( + (ushort)itemID, + (short)x, + (short)y, + (short)z, + TileFlag.Background + ); + + List = newList; + + if (x < m_Min.m_X) + { + m_Min.m_X = x; + } + + if (y < m_Min.m_Y) + { + m_Min.m_Y = y; + } + + if (x > m_Max.m_X) + { + m_Max.m_X = x; + } + + if (y > m_Max.m_Y) + { + m_Max.m_Y = y; } } } - public static class UOPHash + public void RemoveXYZH(int x, int y, int z, int minHeight) { - public static void BuildChunkIDs(out Dictionary chunkIds) + var vx = x + Center.m_X; + var vy = y + Center.m_Y; + + if (vx >= 0 && vx < Width && vy >= 0 && vy < Height) { - const int maxId = 0x10000; + var oldTiles = Tiles[vx][vy]; - chunkIds = new Dictionary(); - - for (var i = 0; i < maxId; ++i) + for (var i = 0; i < oldTiles.Length; ++i) { - chunkIds[HashLittle2($"build/multicollection/{i:000000}.bin")] = i; + var tile = oldTiles[i]; + + if (tile.Z == z && tile.Height >= minHeight) + { + var newTiles = new StaticTile[oldTiles.Length - 1]; + + for (var j = 0; j < i; ++j) + { + newTiles[j] = oldTiles[j]; + } + + for (var j = i + 1; j < oldTiles.Length; ++j) + { + newTiles[j - 1] = oldTiles[j]; + } + + Tiles[vx][vy] = newTiles; + + break; + } + } + + var oldList = List; + + for (var i = 0; i < oldList.Length; ++i) + { + var tile = oldList[i]; + + if (tile.OffsetX == (short)x && tile.OffsetY == (short)y && tile.OffsetZ == (short)z && + TileData.ItemTable[tile.ItemId & TileData.MaxItemValue].Height >= minHeight) + { + var newList = new MultiTileEntry[oldList.Length - 1]; + + for (var j = 0; j < i; ++j) + { + newList[j] = oldList[j]; + } + + for (var j = i + 1; j < oldList.Length; ++j) + { + newList[j - 1] = oldList[j]; + } + + List = newList; + + break; + } + } + } + } + + public void Remove(int itemID, int x, int y, int z) + { + var vx = x + Center.m_X; + var vy = y + Center.m_Y; + + if (vx >= 0 && vx < Width && vy >= 0 && vy < Height) + { + var oldTiles = Tiles[vx][vy]; + + for (var i = 0; i < oldTiles.Length; ++i) + { + var tile = oldTiles[i]; + + if (tile.ID == itemID && tile.Z == z) + { + var newTiles = new StaticTile[oldTiles.Length - 1]; + + for (var j = 0; j < i; ++j) + { + newTiles[j] = oldTiles[j]; + } + + for (var j = i + 1; j < oldTiles.Length; ++j) + { + newTiles[j - 1] = oldTiles[j]; + } + + Tiles[vx][vy] = newTiles; + + break; + } + } + + var oldList = List; + + for (var i = 0; i < oldList.Length; ++i) + { + var tile = oldList[i]; + + if (tile.ItemId == itemID && tile.OffsetX == (short)x && tile.OffsetY == (short)y && + tile.OffsetZ == (short)z) + { + var newList = new MultiTileEntry[oldList.Length - 1]; + + for (var j = 0; j < i; ++j) + { + newList[j] = oldList[j]; + } + + for (var j = i + 1; j < oldList.Length; ++j) + { + newList[j - 1] = oldList[j]; + } + + List = newList; + + break; + } + } + } + } + + public void Resize(int newWidth, int newHeight) + { + int oldWidth = Width, oldHeight = Height; + var oldTiles = Tiles; + + var totalLength = 0; + + var newTiles = new StaticTile[newWidth][][]; + + for (var x = 0; x < newWidth; ++x) + { + newTiles[x] = new StaticTile[newHeight][]; + + for (var y = 0; y < newHeight; ++y) + { + if (x < oldWidth && y < oldHeight) + { + newTiles[x][y] = oldTiles[x][y]; + } + else + { + newTiles[x][y] = Array.Empty(); + } + + totalLength += newTiles[x][y].Length; } } - private static ulong HashLittle2(string s) + Tiles = newTiles; + List = new MultiTileEntry[totalLength]; + Width = newWidth; + Height = newHeight; + + m_Min = Point2D.Zero; + m_Max = Point2D.Zero; + + var index = 0; + + for (var x = 0; x < newWidth; ++x) { - var length = s.Length; - - uint b, c; - var a = b = c = 0xDEADBEEF + (uint)length; - - var k = 0; - - while (length > 12) + for (var y = 0; y < newHeight; ++y) { - a += s[k]; - a += (uint)s[k + 1] << 8; - a += (uint)s[k + 2] << 16; - a += (uint)s[k + 3] << 24; - b += s[k + 4]; - b += (uint)s[k + 5] << 8; - b += (uint)s[k + 6] << 16; - b += (uint)s[k + 7] << 24; - c += s[k + 8]; - c += (uint)s[k + 9] << 8; - c += (uint)s[k + 10] << 16; - c += (uint)s[k + 11] << 24; + var tiles = newTiles[x][y]; - a -= c; - a ^= (c << 4) | (c >> 28); - c += b; - b -= a; - b ^= (a << 6) | (a >> 26); - a += c; - c -= b; - c ^= (b << 8) | (b >> 24); - b += a; - a -= c; - a ^= (c << 16) | (c >> 16); - c += b; - b -= a; - b ^= (a << 19) | (a >> 13); - a += c; - c -= b; - c ^= (b << 4) | (b >> 28); - b += a; - - length -= 12; - k += 12; - } - - if (length != 0) - { - switch (length) + for (var i = 0; i < tiles.Length; ++i) { - case 12: - c += (uint)s[k + 11] << 24; - goto case 11; - case 11: - c += (uint)s[k + 10] << 16; - goto case 10; - case 10: - c += (uint)s[k + 9] << 8; - goto case 9; - case 9: - c += s[k + 8]; - goto case 8; - case 8: - b += (uint)s[k + 7] << 24; - goto case 7; - case 7: - b += (uint)s[k + 6] << 16; - goto case 6; - case 6: - b += (uint)s[k + 5] << 8; - goto case 5; - case 5: - b += s[k + 4]; - goto case 4; - case 4: - a += (uint)s[k + 3] << 24; - goto case 3; - case 3: - a += (uint)s[k + 2] << 16; - goto case 2; - case 2: - a += (uint)s[k + 1] << 8; - goto case 1; - case 1: - a += s[k]; - break; + var tile = tiles[i]; + + var vx = x - Center.X; + var vy = y - Center.Y; + + if (vx < m_Min.m_X) + { + m_Min.m_X = vx; + } + + if (vy < m_Min.m_Y) + { + m_Min.m_Y = vy; + } + + if (vx > m_Max.m_X) + { + m_Max.m_X = vx; + } + + if (vy > m_Max.m_Y) + { + m_Max.m_Y = vy; + } + + List[index++] = new MultiTileEntry( + (ushort)tile.ID, + (short)vx, + (short)vy, + (short)tile.Z, + TileFlag.Background + ); } - - c ^= b; - c -= (b << 14) | (b >> 18); - a ^= c; - a -= (c << 11) | (c >> 21); - b ^= a; - b -= (a << 25) | (a >> 7); - c ^= b; - c -= (b << 16) | (b >> 16); - a ^= c; - a -= (c << 4) | (c >> 28); - b ^= a; - b -= (a << 14) | (a >> 18); - c ^= b; - c -= (b << 24) | (b >> 8); } + } + } - return ((ulong)b << 32) | c; + public void Serialize(IGenericWriter writer) + { + writer.Write(1); // version; + + writer.Write(m_Min); + writer.Write(m_Max); + writer.Write(Center); + + writer.Write(Width); + writer.Write(Height); + + writer.Write(List.Length); + + for (var i = 0; i < List.Length; ++i) + { + var ent = List[i]; + + writer.Write(ent.ItemId); + writer.Write(ent.OffsetX); + writer.Write(ent.OffsetY); + writer.Write(ent.OffsetZ); + writer.Write((int)ent.Flags); } } } + +public static class UOPHash +{ + public static void BuildChunkIDs(out Dictionary chunkIds) + { + const int maxId = 0x10000; + + chunkIds = new Dictionary(); + + for (var i = 0; i < maxId; ++i) + { + chunkIds[HashLittle2($"build/multicollection/{i:000000}.bin")] = i; + } + } + + public static ulong HashLittle2(ReadOnlySpan s) + { + var length = s.Length; + + uint b, c; + var a = b = c = 0xDEADBEEF + (uint)length; + + var k = 0; + + while (length > 12) + { + a += s[k]; + a += (uint)s[k + 1] << 8; + a += (uint)s[k + 2] << 16; + a += (uint)s[k + 3] << 24; + b += s[k + 4]; + b += (uint)s[k + 5] << 8; + b += (uint)s[k + 6] << 16; + b += (uint)s[k + 7] << 24; + c += s[k + 8]; + c += (uint)s[k + 9] << 8; + c += (uint)s[k + 10] << 16; + c += (uint)s[k + 11] << 24; + + a -= c; + a ^= (c << 4) | (c >> 28); + c += b; + b -= a; + b ^= (a << 6) | (a >> 26); + a += c; + c -= b; + c ^= (b << 8) | (b >> 24); + b += a; + a -= c; + a ^= (c << 16) | (c >> 16); + c += b; + b -= a; + b ^= (a << 19) | (a >> 13); + a += c; + c -= b; + c ^= (b << 4) | (b >> 28); + b += a; + + length -= 12; + k += 12; + } + + if (length != 0) + { + switch (length) + { + case 12: + { + c += (uint)s[k + 11] << 24; + goto case 11; + } + case 11: + { + c += (uint)s[k + 10] << 16; + goto case 10; + } + case 10: + { + c += (uint)s[k + 9] << 8; + goto case 9; + } + case 9: + { + c += s[k + 8]; + goto case 8; + } + case 8: + { + b += (uint)s[k + 7] << 24; + goto case 7; + } + case 7: + { + b += (uint)s[k + 6] << 16; + goto case 6; + } + case 6: + { + b += (uint)s[k + 5] << 8; + goto case 5; + } + case 5: + { + b += s[k + 4]; + goto case 4; + } + case 4: + { + a += (uint)s[k + 3] << 24; + goto case 3; + } + case 3: + { + a += (uint)s[k + 2] << 16; + goto case 2; + } + case 2: + { + a += (uint)s[k + 1] << 8; + goto case 1; + } + case 1: + { + a += s[k]; + break; + } + } + + c ^= b; + c -= (b << 14) | (b >> 18); + a ^= c; + a -= (c << 11) | (c >> 21); + b ^= a; + b -= (a << 25) | (a >> 7); + c ^= b; + c -= (b << 16) | (b >> 16); + a ^= c; + a -= (c << 4) | (c >> 28); + b ^= a; + b -= (a << 14) | (a >> 18); + c ^= b; + c -= (b << 24) | (b >> 8); + } + + return ((ulong)b << 32) | c; + } +} From f28f29791faec40c9e9f2ec3952897b2cebaee78 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Thu, 14 Apr 2022 17:39:57 -0700 Subject: [PATCH 137/213] fix: Fixes detecting linux distro during build (#997) --- publish.cmd | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/publish.cmd b/publish.cmd index 15daf9977..6ce7daf6e 100755 --- a/publish.cmd +++ b/publish.cmd @@ -12,8 +12,7 @@ elif [[ $(uname) = "Darwin" ]]; then os="-r osx-x64" elif [[ -f /etc/os-release ]]; then . /etc/os-release - NAME="$(tr '[:upper:]' '[:lower:]' <<< $NAME | tr -d [:blank:])" - os="-r $NAME.$VERSION_ID-x64" + os="-r $(tr '[:upper:]' '[:lower:]' <<< $ID).$VERSION_ID-x64" fi if [[ $config ]]; then From 5d972caa9ce1b7337a19a71b75b7b84655fec277 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Fri, 15 Apr 2022 00:47:03 -0700 Subject: [PATCH 138/213] fix: Changes Fedora to use new icon and color --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f95a27880..3f4af0244 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ ModernUO [![Discord](https://img.shields.io/discord/751317910504603701?logo=disc [![Ubuntu 16/18/20 LTS](https://img.shields.io/badge/-20LTS-E95420?logo=ubuntu&logoColor=white)](https://ubuntu.com/download/server) [![Linux Mint 17/18/19/20](https://img.shields.io/badge/-20-87CF3E?logo=linux%20mint&logoColor=white)](https://linuxmint.com/download.php) [![CentOS 7/8](https://img.shields.io/badge/-8.5-262577?logo=centos&logoColor=white)](https://www.centos.org/download/) -[![Fedora 32/33/34](https://img.shields.io/badge/-fedora%2034-0B57A4)](https://getfedora.org/en/server/download/) +[![Fedora 32/33/34](https://img.shields.io/badge/-34-51a2da?logo=fedora&logoColor=white)](https://getfedora.org/en/server/download/) [![RedHat 7/8](https://img.shields.io/badge/-8-BE0000?logo=red%20hat&logoColor=white)](https://access.redhat.com/downloads) #### Running the server From 54d728a322f1c6529108acd4f99a3c0319ca3082 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 17 Apr 2022 08:02:15 -0700 Subject: [PATCH 139/213] fix: Updates serialization to use v2.0 (#998) - [X] Deletes serialization annotations - [X] Updates to ModernUO.Serialization.Annotations nuget - [X] Updates serializer to v2.0 - [X] Changes all `Serializable()` to `SerializationGenerator()` - [X] Updates to schema generator v2.0 --- .config/dotnet-tools.json | 2 +- Projects/Server/Collections/BitArray.cs | 2 +- Projects/Server/Main.cs | 2 +- .../AfterDeserializationAttribute.cs | 38 ------- .../Attributes/DeltaDateTimeAttribute.cs | 27 ----- .../DeserializeTimerFieldAttribute.cs | 34 ------ .../EmbeddedSerializableAttribute.cs | 32 ------ .../Attributes/EncodedIntAttribute.cs | 27 ----- .../Attributes/InternStringAttribute.cs | 27 ----- .../InvalidatePropertiesAttribute.cs | 28 ----- .../Attributes/SerializableAttribute.cs | 32 ------ .../Attributes/SerializableFieldAttribute.cs | 46 -------- .../SerializableFieldAttributeAttribute.cs | 46 -------- .../SerializableFieldDefaultAttribute.cs | 35 ------ .../SerializableFieldSaveFlagAttribute.cs | 30 ----- .../Attributes/SerializableParentAttribute.cs | 30 ----- .../Serialization/Attributes/TidyAttribute.cs | 27 ----- .../Attributes/TimerDriftAttribute.cs | 28 ----- Projects/Server/Server.csproj | 3 +- .../Security/PasswordProtectionTest.cs | 1 - Projects/UOContent/Accounting/Account.cs | 3 +- .../UOContent/Engines/Bulk Orders/BaseBOD.cs | 3 +- .../UOContent/Engines/Bulk Orders/LargeBOD.cs | 3 +- .../Engines/Bulk Orders/LargeSmithBOD.cs | 4 +- .../Engines/Bulk Orders/LargeTailorBOD.cs | 4 +- .../Engines/Bulk Orders/SmallSmithBOD.cs | 3 +- .../Engines/Bulk Orders/SmallTailorBOD.cs | 3 +- .../Christmas/2010/Addons/FireFliesDeed.cs | 5 +- .../Christmas/2010/Items/AngelDecoration.cs | 6 +- .../Christmas/2010/Items/RockingHorse.cs | 6 +- .../Easter/2011/Items/DragonEasterEgg.cs | 6 +- .../Halloween/2006/Engines/TrickOrTreat.cs | 3 +- .../Halloween/2006/Items/HalloweenPumpkin.cs | 5 +- .../Halloween/2006/Items/PumpkinScarecrow.cs | 6 +- .../Halloween/2006/Items/RuinedTapestry.cs | 6 +- .../Halloween/2006/Items/TwilightLantern.cs | 6 +- .../Halloween/2009/Foods/CreepyCake.cs | 6 +- .../Halloween/2009/Foods/HarvestWine.cs | 6 +- .../Halloween/2009/Foods/MrPlainsCookies.cs | 6 +- .../Halloween/2009/Foods/MurkyMilk.cs | 6 +- .../Halloween/2009/Foods/PumpkinPizza.cs | 6 +- .../Halloween/2009/Items/GrimWarning.cs | 6 +- .../Halloween/2009/Items/SkullsOnPike.cs | 6 +- .../2010/Items/ChairInAGhostCostume.cs | 4 +- .../Halloween/2010/Items/ColoredSmallWebs.cs | 4 +- .../2010/Items/ExcellentIronMaiden.cs | 4 +- .../2010/Items/HalloweenGuillotine.cs | 4 +- .../Halloween/2011/Items/BasePaintedMask.cs | 6 +- .../Halloween/2011/Items/ClownMask.cs | 6 +- .../Halloween/2011/Items/DaemonMask.cs | 6 +- .../Halloween/2011/Items/PlagueMask.cs | 6 +- .../Halloween/2011/Mobiles/PumpkinHead.cs | 3 +- .../Halloween/2012/Engines/PlayerZombies.cs | 5 +- .../Halloween/2012/Items/EvilJesterMask.cs | 6 +- .../Halloween/2012/Items/PorcelainMask.cs | 6 +- .../Halloween/Treats/Jellybeans.cs | 6 +- .../Halloween/Treats/Lollipops.cs | 6 +- .../Halloween/Treats/NougatSwirl.cs | 6 +- .../Holiday Stuff/Halloween/Treats/Taffy.cs | 6 +- .../Halloween/Treats/WrappedCandy.cs | 6 +- .../2010/Items/AnimatedHeartShapedBox.cs | 4 +- .../Valentine/2011/Items/StValentinesBears.cs | 7 +- .../Valentine/2012/Items/CupidStatue.cs | 4 +- .../Valentine/2012/Items/CupidsArrow.cs | 3 +- .../Valentine/2012/Items/HeartShapedBox.cs | 4 +- .../UOContent/Items/Addons/AbbatoirAddon.cs | 6 +- .../UOContent/Items/Addons/AddonComponent.cs | 9 +- .../Items/Addons/AddonContainerComponent.cs | 5 +- .../Items/Addons/AlchemistTableEastAddon.cs | 6 +- .../Items/Addons/AlchemistTableSouthAddon.cs | 6 +- .../UOContent/Items/Addons/AnvilEastAddon.cs | 6 +- .../UOContent/Items/Addons/AnvilSouthAddon.cs | 6 +- .../Items/Addons/ArcaneBookshelfEastAddon.cs | 6 +- .../Items/Addons/ArcaneBookshelfSouthAddon.cs | 6 +- .../Items/Addons/ArcaneCircleAddon.cs | 6 +- .../Items/Addons/ArcanistStatueEastAddon.cs | 6 +- .../Items/Addons/ArcanistStatueSouthAddon.cs | 6 +- .../Items/Addons/ArcheryButteAddon.cs | 7 +- Projects/UOContent/Items/Addons/BallotBox.cs | 7 +- Projects/UOContent/Items/Addons/BaseAddon.cs | 3 +- .../Items/Addons/BaseAddonContainer.cs | 3 +- .../UOContent/Items/Addons/BaseAddonDeed.cs | 3 +- Projects/UOContent/Items/Addons/BearRugs.cs | 18 +-- .../UOContent/Items/Addons/BloodPentagram.cs | 4 +- Projects/UOContent/Items/Addons/DartBoard.cs | 11 +- .../Items/Addons/ElvenBedEastAddon.cs | 6 +- .../Items/Addons/ElvenBedSouthAddon.cs | 6 +- .../Items/Addons/ElvenDresserEastAddon.cs | 6 +- .../Items/Addons/ElvenDresserSouthAddon.cs | 6 +- .../UOContent/Items/Addons/ElvenForgeAddon.cs | 6 +- .../Items/Addons/ElvenLoveseatEastAddon.cs | 6 +- .../Items/Addons/ElvenLoveseatSouthAddon.cs | 6 +- .../Addons/ElvenSpinningWheelEastAddon.cs | 5 +- .../Addons/ElvenSpinningwheelSouthAddon.cs | 5 +- .../Items/Addons/ElvenStoveEastAddon.cs | 6 +- .../Items/Addons/ElvenStoveSouthAddon.cs | 6 +- .../Items/Addons/ElvenWashbasinEastAddon.cs | 6 +- .../Items/Addons/ElvenWashbasinSouthAddon.cs | 6 +- .../Items/Addons/FancyElvenTableEastAddon.cs | 6 +- .../Items/Addons/FancyElvenTableSouthAddon.cs | 6 +- .../UOContent/Items/Addons/FireColumnAddon.cs | 4 +- .../Items/Addons/FlourMillEastAddon.cs | 5 +- .../Items/Addons/FlourMillSouthAddon.cs | 5 +- .../Items/Addons/FlowerTapestries.cs | 18 +-- Projects/UOContent/Items/Addons/GiantWebs.cs | 14 ++- Projects/UOContent/Items/Addons/GozaMats.cs | 34 +++--- .../Addons/GrayBrickFireplaceEastAddon.cs | 6 +- .../Addons/GrayBrickFireplaceSouthAddon.cs | 6 +- .../UOContent/Items/Addons/JackOLantern.cs | 4 +- .../Items/Addons/LargeBedEastAddon.cs | 4 +- .../Items/Addons/LargeBedSouthAddon.cs | 6 +- .../Items/Addons/LargeForgeEastAddon.cs | 6 +- .../Items/Addons/LargeForgeSouthAddon.cs | 6 +- .../Items/Addons/LargeStoneTableEastAddon.cs | 6 +- .../Items/Addons/LargeStoneTableSouthAddon.cs | 6 +- .../UOContent/Items/Addons/LoomEastAddon.cs | 6 +- .../UOContent/Items/Addons/LoomSouthAddon.cs | 6 +- .../Items/Addons/MediumStoneTableEastAddon.cs | 6 +- .../Addons/MediumStoneTableSouthAddon.cs | 6 +- .../Items/Addons/OrnateElvenChestEastAddon.cs | 6 +- .../Addons/OrnateElvenChestSouthAddon.cs | 6 +- .../Items/Addons/OrnateElvenTableEastAddon.cs | 6 +- .../Addons/OrnateElvenTableSouthAddon.cs | 6 +- .../Items/Addons/ParrotPerchAddon.cs | 6 +- .../UOContent/Items/Addons/PentagramAddon.cs | 6 +- .../UOContent/Items/Addons/PickpocketDips.cs | 11 +- .../UOContent/Items/Addons/PyramidAddon.cs | 4 +- .../Items/Addons/RejuvinationAnkhs.cs | 9 +- .../UOContent/Items/Addons/SHTeleporter.cs | 5 +- .../Addons/SandstoneFireplaceEastAddon.cs | 6 +- .../Addons/SandstoneFireplaceSouthAddon.cs | 6 +- .../Items/Addons/SandstoneFountainAddon.cs | 4 +- .../Items/Addons/SerpentPillarAddon.cs | 4 +- .../Items/Addons/ShrineOfWisdomAddon.cs | 5 +- .../UOContent/Items/Addons/SkullPileAddon.cs | 4 +- .../Items/Addons/SmallBedEastAddon.cs | 6 +- .../Items/Addons/SmallBedSouthAddon.cs | 6 +- .../UOContent/Items/Addons/SmallForgeAddon.cs | 6 +- .../UOContent/Items/Addons/SolenAntHole.cs | 5 +- .../Items/Addons/SpinningwheelEastAddon.cs | 5 +- .../Items/Addons/SpinningwheelSouthAddon.cs | 5 +- .../Items/Addons/SquirrelStatueEastAddon.cs | 6 +- .../Items/Addons/SquirrelStatueSouthAddon.cs | 6 +- .../Items/Addons/StoneFireplaceEastAddon.cs | 6 +- .../Items/Addons/StoneFireplaceSouthAddon.cs | 6 +- .../Items/Addons/StoneFountainAddon.cs | 4 +- .../Items/Addons/StoneOvenEastAddon.cs | 6 +- .../Items/Addons/StoneOvenSouthAddon.cs | 6 +- .../UOContent/Items/Addons/StretchedHides.cs | 18 +-- .../Items/Addons/TallElvenBedEastAddon.cs | 6 +- .../Items/Addons/TallElvenBedSouthAddon.cs | 6 +- Projects/UOContent/Items/Addons/Telescope.cs | 4 +- .../UOContent/Items/Addons/TrainingDummies.cs | 11 +- .../Items/Addons/WarriorStatueEastAddon.cs | 6 +- .../Items/Addons/WarriorStatueSouthAddon.cs | 6 +- .../Items/Addons/WaterTroughEastAddon.cs | 6 +- .../Items/Addons/WaterTroughSouthAddon.cs | 6 +- Projects/UOContent/Items/Addons/WaterVat.cs | 6 +- Projects/UOContent/Items/Aquarium/Aquarium.cs | 7 +- .../Items/Aquarium/AquariumFishingNet.cs | 4 +- .../UOContent/Items/Aquarium/AquariumFood.cs | 4 +- .../UOContent/Items/Aquarium/AquariumState.cs | 7 +- Projects/UOContent/Items/Aquarium/BaseFish.cs | 3 +- .../Aquarium/Fish/AlbinoCourtesanFish.cs | 4 +- .../Items/Aquarium/Fish/AlbinoFrog.cs | 4 +- .../Items/Aquarium/Fish/BritainCrownFish.cs | 4 +- .../Items/Aquarium/Fish/FandancerFish.cs | 4 +- .../Items/Aquarium/Fish/GoldenBroadtail.cs | 4 +- .../Items/Aquarium/Fish/Jellyfish.cs | 4 +- .../Items/Aquarium/Fish/KillerFrog.cs | 4 +- .../Items/Aquarium/Fish/LongClawCrab.cs | 4 +- .../Aquarium/Fish/MakotoCourtesanFish.cs | 4 +- .../Items/Aquarium/Fish/MinocBlueFish.cs | 4 +- .../Items/Aquarium/Fish/NujelmHoneyFish.cs | 4 +- .../Items/Aquarium/Fish/PurpleFrog.cs | 4 +- .../Items/Aquarium/Fish/RedDartFish.cs | 4 +- .../UOContent/Items/Aquarium/Fish/Shrimp.cs | 4 +- .../Aquarium/Fish/SmallMouthSuckerFin.cs | 4 +- .../Items/Aquarium/Fish/SpeckledCrab.cs | 4 +- .../Aquarium/Fish/SpinedScratcherFish.cs | 4 +- .../Items/Aquarium/Fish/SpottedBuccaneer.cs | 4 +- .../Items/Aquarium/Fish/VesperReefTiger.cs | 4 +- .../Items/Aquarium/Fish/YellowFinBluebelly.cs | 4 +- Projects/UOContent/Items/Aquarium/FishBowl.cs | 3 +- .../Items/Aquarium/Reward Fish/BrineShrimp.cs | 4 +- .../Items/Aquarium/Reward Fish/Coral.cs | 4 +- .../Aquarium/Reward Fish/FullMoonFish.cs | 4 +- .../Items/Aquarium/Reward Fish/SeaHorse.cs | 4 +- .../Aquarium/Reward Fish/StrippedFlakeFish.cs | 4 +- .../Reward Fish/StrippedSosarianSwill.cs | 4 +- .../Items/Aquarium/Rewards/AquariumMessage.cs | 4 +- .../Rewards/CaptainBlackheartsFishingPole.cs | 4 +- .../Aquarium/Rewards/CraftysFishingHat.cs | 4 +- .../Items/Aquarium/Rewards/FishBones.cs | 4 +- .../Items/Aquarium/Rewards/IslandStatue.cs | 4 +- .../UOContent/Items/Aquarium/Rewards/Shell.cs | 4 +- .../Items/Aquarium/Rewards/ToyBoat.cs | 4 +- .../Aquarium/Rewards/WaterloggedBoots.cs | 4 +- .../UOContent/Items/Aquarium/VacationWafer.cs | 4 +- .../Items/Armor/Artifacts/ArmorOfFortune.cs | 4 +- .../Armor/Artifacts/Craftable/BrambleCoat.cs | 4 +- .../Artifacts/Craftable/IronwoodCrown.cs | 4 +- .../Artifacts/Craftable/SongWovenMantle.cs | 4 +- .../Artifacts/Craftable/SpellWovenBritches.cs | 4 +- .../Artifacts/Craftable/StitchersMittens.cs | 4 +- .../Armor/Artifacts/GauntletsOfNobility.cs | 4 +- .../Items/Armor/Artifacts/HelmOfInsight.cs | 4 +- .../Armor/Artifacts/HolyKnightsBreastplate.cs | 4 +- .../Armor/Artifacts/InquisitorsResolution.cs | 4 +- .../Items/Armor/Artifacts/JackalsCollar.cs | 4 +- .../Items/Armor/Artifacts/LeggingsOfBane.cs | 4 +- .../Items/Armor/Artifacts/MidnightBracers.cs | 4 +- .../Artifacts/OrnateCrownOfTheHarrower.cs | 4 +- .../Armor/Artifacts/ShadowDancerLeggings.cs | 4 +- .../Items/Armor/Artifacts/TunicOfFire.cs | 4 +- .../Armor/Artifacts/VoiceOfTheFallenKing.cs | 4 +- Projects/UOContent/Items/Armor/BaseArmor.cs | 3 +- .../UOContent/Items/Armor/Bone/BoneArms.cs | 4 +- .../UOContent/Items/Armor/Bone/BoneChest.cs | 4 +- .../UOContent/Items/Armor/Bone/BoneGloves.cs | 4 +- .../UOContent/Items/Armor/Bone/BoneLegs.cs | 4 +- .../UOContent/Items/Armor/Chain/ChainChest.cs | 4 +- .../Items/Armor/Chain/ChainHatsuburi.cs | 4 +- .../UOContent/Items/Armor/Chain/ChainLegs.cs | 4 +- .../Armor/Cloth/GargishClothArmsType1.cs | 4 +- .../Armor/Cloth/GargishClothArmsType2.cs | 4 +- .../Armor/Cloth/GargishClothChestType1.cs | 4 +- .../Armor/Cloth/GargishClothChestType2.cs | 4 +- .../Armor/Cloth/GargishClothKiltType1.cs | 4 +- .../Armor/Cloth/GargishClothKiltType2.cs | 4 +- .../Armor/Cloth/GargishClothLegsType1.cs | 4 +- .../Armor/Cloth/GargishClothLegsType2.cs | 4 +- .../Items/Armor/DaemonBone/DaemonArms.cs | 4 +- .../Items/Armor/DaemonBone/DaemonChest.cs | 4 +- .../Items/Armor/DaemonBone/DaemonGloves.cs | 4 +- .../Items/Armor/DaemonBone/DaemonLegs.cs | 4 +- .../Items/Armor/Dragon/DragonArms.cs | 4 +- .../Items/Armor/Dragon/DragonChest.cs | 4 +- .../Items/Armor/Dragon/DragonGloves.cs | 4 +- .../Items/Armor/Dragon/DragonHelm.cs | 4 +- .../Items/Armor/Dragon/DragonLegs.cs | 4 +- .../Armor/Glasses/AnthropomorphistGlasses.cs | 4 +- .../Items/Armor/Glasses/ArtsGlasses.cs | 4 +- .../Items/Armor/Glasses/ElvenGlasses.cs | 4 +- .../Items/Armor/Glasses/FoldedSteelGlasses.cs | 4 +- .../Items/Armor/Glasses/LightOfWayGlasses.cs | 4 +- .../Items/Armor/Glasses/LyricalGlasses.cs | 4 +- .../Items/Armor/Glasses/MaceShieldGlasses.cs | 4 +- .../Items/Armor/Glasses/MaritimeGlasses.cs | 4 +- .../Items/Armor/Glasses/NecromanticGlasses.cs | 4 +- .../Items/Armor/Glasses/PoisonedGlasses.cs | 4 +- .../Items/Armor/Glasses/TradeGlasses.cs | 4 +- .../Armor/Glasses/TreasureTrinketGlasses.cs | 4 +- .../Items/Armor/Glasses/WizardsGlasses.cs | 4 +- .../UOContent/Items/Armor/Helmets/Bascinet.cs | 4 +- .../UOContent/Items/Armor/Helmets/BoneHelm.cs | 4 +- .../Items/Armor/Helmets/ChainCoif.cs | 4 +- .../UOContent/Items/Armor/Helmets/Circlet.cs | 4 +- .../Items/Armor/Helmets/CloseHelm.cs | 4 +- .../Items/Armor/Helmets/DaemonHelm.cs | 4 +- .../Items/Armor/Helmets/GemmedCirclet.cs | 4 +- .../UOContent/Items/Armor/Helmets/Helmet.cs | 4 +- .../Items/Armor/Helmets/LeatherCap.cs | 4 +- .../Items/Armor/Helmets/NorseHelm.cs | 4 +- .../UOContent/Items/Armor/Helmets/OrcHelm.cs | 4 +- .../Items/Armor/Helmets/PlateHelm.cs | 4 +- .../Items/Armor/Helmets/RavenHelm.cs | 4 +- .../Items/Armor/Helmets/RoyalCirclet.cs | 4 +- .../Items/Armor/Helmets/VultureHelm.cs | 4 +- .../Items/Armor/Helmets/WingedHelm.cs | 4 +- .../Items/Armor/Leather/FemaleLeafChest.cs | 4 +- .../Items/Armor/Leather/FemaleLeatherChest.cs | 4 +- .../Armor/Leather/GargishLeatherArmsType1.cs | 4 +- .../Armor/Leather/GargishLeatherArmsType2.cs | 4 +- .../Armor/Leather/GargishLeatherChestType1.cs | 4 +- .../Armor/Leather/GargishLeatherChestType2.cs | 4 +- .../Armor/Leather/GargishLeatherKiltType1.cs | 4 +- .../Armor/Leather/GargishLeatherKiltType2.cs | 4 +- .../Armor/Leather/GargishLeatherLegsType1.cs | 4 +- .../Armor/Leather/GargishLeatherLegsType2.cs | 4 +- .../Armor/Leather/GargishLeatherWingArmor.cs | 4 +- .../UOContent/Items/Armor/Leather/LeafArms.cs | 4 +- .../Items/Armor/Leather/LeafChest.cs | 4 +- .../Items/Armor/Leather/LeafGloves.cs | 4 +- .../Items/Armor/Leather/LeafGorget.cs | 4 +- .../UOContent/Items/Armor/Leather/LeafLegs.cs | 4 +- .../Items/Armor/Leather/LeafTonlet.cs | 4 +- .../Items/Armor/Leather/LeatherArms.cs | 4 +- .../Items/Armor/Leather/LeatherBustierArms.cs | 4 +- .../Items/Armor/Leather/LeatherChest.cs | 4 +- .../Items/Armor/Leather/LeatherDo.cs | 4 +- .../Items/Armor/Leather/LeatherGloves.cs | 4 +- .../Items/Armor/Leather/LeatherGorget.cs | 4 +- .../Items/Armor/Leather/LeatherHaidate.cs | 4 +- .../Items/Armor/Leather/LeatherHiroSode.cs | 4 +- .../Items/Armor/Leather/LeatherJingasa.cs | 4 +- .../Items/Armor/Leather/LeatherLegs.cs | 4 +- .../Items/Armor/Leather/LeatherMempo.cs | 4 +- .../Items/Armor/Leather/LeatherNinjaHood.cs | 4 +- .../Items/Armor/Leather/LeatherNinjaJacket.cs | 4 +- .../Items/Armor/Leather/LeatherNinjaMitts.cs | 4 +- .../Items/Armor/Leather/LeatherNinjaPants.cs | 4 +- .../Items/Armor/Leather/LeatherShorts.cs | 4 +- .../Items/Armor/Leather/LeatherSkirt.cs | 4 +- .../Items/Armor/Leather/LeatherSuneate.cs | 4 +- .../Armor/Plate/DecorativePlateKabuto.cs | 4 +- .../Items/Armor/Plate/FemalePlateChest.cs | 4 +- .../Items/Armor/Plate/FemaleWoodlandChest.cs | 4 +- .../Items/Armor/Plate/HeavyPlateJingasa.cs | 4 +- .../Items/Armor/Plate/LightPlateJingasa.cs | 4 +- .../UOContent/Items/Armor/Plate/PlateArms.cs | 4 +- .../Items/Armor/Plate/PlateBattleKabuto.cs | 4 +- .../UOContent/Items/Armor/Plate/PlateChest.cs | 4 +- .../UOContent/Items/Armor/Plate/PlateDo.cs | 4 +- .../Items/Armor/Plate/PlateGloves.cs | 4 +- .../Items/Armor/Plate/PlateGorget.cs | 4 +- .../Items/Armor/Plate/PlateHaidate.cs | 4 +- .../Items/Armor/Plate/PlateHatsuburi.cs | 4 +- .../Items/Armor/Plate/PlateHiroSode.cs | 4 +- .../UOContent/Items/Armor/Plate/PlateLegs.cs | 4 +- .../UOContent/Items/Armor/Plate/PlateMempo.cs | 4 +- .../Items/Armor/Plate/PlateSuneate.cs | 4 +- .../Items/Armor/Plate/SmallPlateJingasa.cs | 4 +- .../Items/Armor/Plate/StandardPlateKabuto.cs | 4 +- .../Items/Armor/Plate/WoodlandArms.cs | 4 +- .../Items/Armor/Plate/WoodlandChest.cs | 4 +- .../Items/Armor/Plate/WoodlandGloves.cs | 4 +- .../Items/Armor/Plate/WoodlandGorget.cs | 4 +- .../Items/Armor/Plate/WoodlandLegs.cs | 4 +- .../Items/Armor/Ranger/RangerArms.cs | 4 +- .../Items/Armor/Ranger/RangerChest.cs | 4 +- .../Items/Armor/Ranger/RangerGloves.cs | 4 +- .../Items/Armor/Ranger/RangerGorget.cs | 4 +- .../Items/Armor/Ranger/RangerLegs.cs | 4 +- .../Items/Armor/Ring/RingmailArms.cs | 4 +- .../Items/Armor/Ring/RingmailChest.cs | 4 +- .../Items/Armor/Ring/RingmailGloves.cs | 4 +- .../Items/Armor/Ring/RingmailLegs.cs | 4 +- .../Armor/Stone/GargishStoneArmsType1.cs | 4 +- .../Armor/Stone/GargishStoneArmsType2.cs | 4 +- .../Armor/Stone/GargishStoneChestType1.cs | 4 +- .../Armor/Stone/GargishStoneChestType2.cs | 4 +- .../Armor/Stone/GargishStoneKiltType1.cs | 4 +- .../Armor/Stone/GargishStoneKiltType2.cs | 4 +- .../Armor/Stone/GargishStoneLegsType1.cs | 4 +- .../Armor/Stone/GargishStoneLegsType2.cs | 4 +- .../Items/Armor/Studded/FemaleStuddedChest.cs | 4 +- .../Armor/Studded/GargishStuddedArmsType1.cs | 4 +- .../Armor/Studded/GargishStuddedArmsType2.cs | 4 +- .../Armor/Studded/GargishStuddedChestType1.cs | 4 +- .../Armor/Studded/GargishStuddedChestType2.cs | 4 +- .../Armor/Studded/GargishStuddedKiltType1.cs | 4 +- .../Armor/Studded/GargishStuddedKiltType2.cs | 4 +- .../Armor/Studded/GargishStuddedLegsType1.cs | 4 +- .../Armor/Studded/GargishStuddedLegsType2.cs | 4 +- .../Items/Armor/Studded/HideChest.cs | 4 +- .../Items/Armor/Studded/HideFemaleChest.cs | 4 +- .../Items/Armor/Studded/HideGloves.cs | 4 +- .../Items/Armor/Studded/HideGorget.cs | 4 +- .../Items/Armor/Studded/HidePants.cs | 4 +- .../Items/Armor/Studded/HidePauldrons.cs | 4 +- .../Items/Armor/Studded/StuddedArms.cs | 4 +- .../Items/Armor/Studded/StuddedBustierArms.cs | 4 +- .../Items/Armor/Studded/StuddedChest.cs | 4 +- .../Items/Armor/Studded/StuddedDo.cs | 4 +- .../Items/Armor/Studded/StuddedGloves.cs | 4 +- .../Items/Armor/Studded/StuddedGorget.cs | 4 +- .../Items/Armor/Studded/StuddedHaidate.cs | 4 +- .../Items/Armor/Studded/StuddedHiroSode.cs | 4 +- .../Items/Armor/Studded/StuddedLegs.cs | 4 +- .../Items/Armor/Studded/StuddedMempo.cs | 4 +- .../Items/Armor/Studded/StuddedSuneate.cs | 4 +- .../UOContent/Items/Body Parts/BonePile.cs | 4 +- Projects/UOContent/Items/Body Parts/Head.cs | 4 +- .../UOContent/Items/Body Parts/LeftArm.cs | 4 +- .../UOContent/Items/Body Parts/LeftLeg.cs | 4 +- .../UOContent/Items/Body Parts/RibCage.cs | 4 +- .../UOContent/Items/Body Parts/RightArm.cs | 4 +- .../UOContent/Items/Body Parts/RightLeg.cs | 4 +- Projects/UOContent/Items/Body Parts/Torso.cs | 4 +- Projects/UOContent/Items/Books/BaseBook.cs | 3 +- Projects/UOContent/Items/Books/BlueBook.cs | 4 +- Projects/UOContent/Items/Books/BrownBook.cs | 4 +- .../Books/Defined/BlackthornWelcomeBook.cs | 4 +- .../Items/Books/Defined/DrakovsJournal.cs | 4 +- .../Items/Books/Defined/FropozJournal.cs | 4 +- .../Items/Books/Defined/KaburJournal.cs | 4 +- .../Items/Books/Defined/LibraryBooks.cs | 58 +++++----- .../Items/Books/Defined/NewAquariumBook.cs | 4 +- .../Defined/TranslatedGargoyleJournal.cs | 4 +- Projects/UOContent/Items/Books/RedBook.cs | 4 +- Projects/UOContent/Items/Books/TanBook.cs | 4 +- .../Items/Bulletin Boards/BulletinBoard.cs | 5 +- .../Items/Bulletin Boards/BulletinMessage.cs | 3 +- .../Decorative/ArtifactLargeVase.cs | 4 +- .../Decorative/ArtifactVase.cs | 4 +- .../Decorative/DemonSkull.cs | 4 +- .../Decorative/DirtPatch.cs | 4 +- .../Decorative/EvilIdolSkull.cs | 4 +- .../Champion Artifacts/Decorative/Futon.cs | 4 +- .../Champion Artifacts/Decorative/LavaTile.cs | 4 +- .../Champion Artifacts/Decorative/Pier.cs | 4 +- .../Decorative/SkullPole.cs | 4 +- .../Decorative/SwampTile.cs | 4 +- .../TatteredAncientMummyWrapping.cs | 4 +- .../Decorative/WallBlood.cs | 4 +- .../Decorative/WaterTile.cs | 4 +- .../Champion Artifacts/Decorative/Web.cs | 4 +- .../Decorative/WindSpirit.cs | 4 +- .../Shared/ANecromancerShroud.cs | 4 +- .../Shared/BraveKnightOfTheBritannia.cs | 4 +- .../Shared/CaptainJohnsHat.cs | 4 +- .../Shared/DetectiveBoots.cs | 3 +- .../Champion Artifacts/Shared/DjinnisRing.cs | 4 +- .../Shared/EmbroideredOakLeafCloak.cs | 4 +- .../Shared/GauntletsOfAnger.cs | 4 +- .../LieutenantOfTheBritannianRoyalGuard.cs | 4 +- .../Shared/OblivionsNeedle.cs | 4 +- .../Shared/RoyalGuardSurvivalKnife.cs | 4 +- .../Shared/SamaritanRobe.cs | 4 +- .../Shared/TheMostKnowledgePerson.cs | 4 +- .../Shared/TheRobeOfBritanniaAri.cs | 4 +- .../Unique/AcidProofRobe.cs | 4 +- .../Items/Champion Artifacts/Unique/Calm.cs | 4 +- .../Unique/CrownOfTalKeesh.cs | 4 +- .../Champion Artifacts/Unique/FangOfRactus.cs | 4 +- .../Unique/GladiatorsCollar.cs | 4 +- .../Unique/OrcChieftainHelm.cs | 4 +- .../Items/Champion Artifacts/Unique/Pacify.cs | 4 +- .../Items/Champion Artifacts/Unique/Quell.cs | 4 +- .../Unique/ShroudOfDeceit.cs | 4 +- .../Items/Champion Artifacts/Unique/Subdue.cs | 4 +- .../Clothing/Artifacts/CrimsonCincture.cs | 4 +- .../Clothing/Artifacts/DivineCountenance.cs | 4 +- .../Items/Clothing/Artifacts/HatOfTheMagi.cs | 4 +- .../Clothing/Artifacts/HuntersHeaddress.cs | 4 +- .../Clothing/Artifacts/SpiritOfTheTotem.cs | 4 +- .../UOContent/Items/Clothing/BaseClothing.cs | 3 +- Projects/UOContent/Items/Clothing/Cloaks.cs | 9 +- Projects/UOContent/Items/Clothing/Hats.cs | 47 ++++---- .../UOContent/Items/Clothing/MiddleTorso.cs | 20 ++-- .../UOContent/Items/Clothing/OuterLegs.cs | 12 +- .../UOContent/Items/Clothing/OuterTorso.cs | 31 ++--- Projects/UOContent/Items/Clothing/Pants.cs | 12 +- Projects/UOContent/Items/Clothing/Shirts.cs | 14 ++- Projects/UOContent/Items/Clothing/Shoes.cs | 22 ++-- Projects/UOContent/Items/Clothing/Waist.cs | 10 +- .../UOContent/Items/Construction/Ankhs.cs | 9 +- .../Items/Construction/Chairs/Benchs.cs | 4 +- .../Items/Construction/Chairs/Chairs.cs | 18 +-- .../Items/Construction/Chairs/Stools.cs | 6 +- .../Items/Construction/Chairs/Thrones.cs | 6 +- .../Decorative/DecorativeShield.cs | 32 +++--- .../Decorative/DecorativeWeapon.cs | 26 +++-- .../Decorative/GiantReplicaAcorn.cs | 4 +- .../Decorative/MountedDreadHorn.cs | 4 +- .../Decorative/PaintingPortraits.cs | 16 +-- .../Items/Construction/Decorative/Tapestry.cs | 46 ++++---- .../Items/Construction/Tables/ElvenPodium.cs | 4 +- .../Items/Construction/Tables/Tables.cs | 12 +- .../Items/Construction/Tables/WritingTable.cs | 4 +- .../Items/Construction/Walls/BaseWall.cs | 4 +- .../Items/Construction/Walls/DarkWoodWall.cs | 4 +- .../Construction/Walls/ThickGrayStoneWall.cs | 4 +- .../Items/Construction/Walls/ThinBrickWall.cs | 4 +- .../Items/Construction/Walls/ThinStoneWall.cs | 4 +- .../Construction/Walls/WhiteStoneWall.cs | 4 +- .../Items/Containers/BaseTreasureChest.cs | 3 +- .../UOContent/Items/Containers/Container.cs | 55 ++++----- .../Items/Containers/FurnitureContainer.cs | 29 ++--- .../Items/Containers/LockableContainer.cs | 3 +- .../Items/Containers/MarkContainer.cs | 3 +- .../Items/Containers/ParagonChest.cs | 4 +- .../UOContent/Items/Containers/SalvageBag.cs | 3 +- .../UOContent/Items/Containers/Strongbox.cs | 3 +- .../Items/Containers/TrappableContainer.cs | 3 +- .../Items/Containers/TreasureChest.cs | 8 +- .../Items/Containers/TreasureMapChest.cs | 3 +- .../AcademicBooksArtifacts.cs | 4 +- .../BaseDecorationArtifact.cs | 6 +- .../DoomDecorationArtifacts.cs | 48 ++++---- .../SEDecorationArtifacts.cs | 107 +++++++++--------- .../UOContent/Items/Deeds/BarkeepContract.cs | 3 +- .../Items/Deeds/ClothingBlessDeed.cs | 3 +- .../UOContent/Items/Deeds/CommodityDeed.cs | 3 +- .../Items/Deeds/DragonBardingDeed.cs | 3 +- .../Items/Deeds/HairRestylingDeed.cs | 3 +- .../UOContent/Items/Deeds/HolidayTreeDeed.cs | 3 +- .../UOContent/Items/Deeds/NameChangeDeed.cs | 3 +- .../UOContent/Items/Deeds/NewPlayerTicket.cs | 3 +- .../Items/Resources/Blacksmithing/Ingots.cs | 22 ++-- .../Items/Resources/Blacksmithing/Ore.cs | 21 ++-- .../Items/Resources/Fishing/BigFish.cs | 3 +- .../UOContent/Items/Resources/Fishing/Fish.cs | 4 +- .../Items/Resources/Fishing/MagicFish.cs | 11 +- .../Items/Resources/MiscMLResources.cs | 52 +++++---- .../Items/Resources/Reagents/BaseReagent.cs | 4 +- .../Items/Resources/Reagents/BatWing.cs | 4 +- .../Items/Resources/Reagents/BlackPearl.cs | 4 +- .../Items/Resources/Reagents/Bloodmoss.cs | 4 +- .../Items/Resources/Reagents/DaemonBlood.cs | 4 +- .../Items/Resources/Reagents/DaemonBone.cs | 4 +- .../Items/Resources/Reagents/DeadWood.cs | 4 +- .../Items/Resources/Reagents/DragonsBlood.cs | 6 +- .../Items/Resources/Reagents/Garlic.cs | 4 +- .../Items/Resources/Reagents/Ginseng.cs | 4 +- .../Items/Resources/Reagents/GraveDust.cs | 4 +- .../Items/Resources/Reagents/MandrakeRoot.cs | 4 +- .../Items/Resources/Reagents/Nightshade.cs | 4 +- .../Items/Resources/Reagents/NoxCrystal.cs | 4 +- .../Items/Resources/Reagents/PigIron.cs | 4 +- .../Items/Resources/Reagents/SpidersSilk.cs | 4 +- .../Items/Resources/Reagents/SulfurousAsh.cs | 4 +- .../Items/Resources/Tailor/BoltOfCloth.cs | 3 +- .../UOContent/Items/Resources/Tailor/Bone.cs | 4 +- .../UOContent/Items/Resources/Tailor/Cloth.cs | 3 +- .../Items/Resources/Tailor/Cotton.cs | 3 +- .../UOContent/Items/Resources/Tailor/Flax.cs | 3 +- .../UOContent/Items/Resources/Tailor/Hides.cs | 12 +- .../Items/Resources/Tailor/Leathers.cs | 12 +- .../Items/Resources/Tailor/UncutCloth.cs | 3 +- .../UOContent/Items/Resources/Tailor/Wool.cs | 5 +- .../Items/Resources/Tailor/YarnsAndThreads.cs | 11 +- .../Items/Shields/GargishWoodenShield.cs | 4 +- .../Items/Skill Items/Lumberjack/Log.cs | 16 +-- .../Tailor Items/Dyetubs/BlackDyeTub.cs | 4 +- .../Tailor Items/Dyetubs/BlazeDyeTub.cs | 4 +- .../Tailor Items/Dyetubs/DyeTub.cs | 3 +- .../Tailor Items/Dyetubs/FurnitureDyeTub.cs | 3 +- .../Tailor Items/Dyetubs/LeatherDyeTub.cs | 3 +- .../Dyetubs/MetallicClothDyetub.cs | 4 +- .../Dyetubs/MetallicLeatherDyeTub.cs | 4 +- .../Tailor Items/Dyetubs/RewardBlackDyeTub.cs | 3 +- .../Tailor Items/Dyetubs/RunebookDyeTub.cs | 3 +- .../Tailor Items/Dyetubs/SpecialDyeTub.cs | 3 +- .../Tailor Items/Dyetubs/StatuetteDyeTub.cs | 3 +- .../Tailor Items/Dyetubs/WhiteClothDyeTub.cs | 4 +- .../Dyetubs/WhiteLeatherDyeTub.cs | 4 +- .../Items/Skill Items/Tools/TinkerTools.cs | 5 +- Projects/UOContent/Items/Special/SoulStone.cs | 1 - .../TreasureChests/TreasureChestLevel1.cs | 3 +- .../TreasureChests/TreasureChestLevel2.cs | 3 +- .../TreasureChests/TreasureChestLevel3.cs | 3 +- .../TreasureChests/TreasureChestLevel4.cs | 3 +- Projects/UOContent/Items/Wands/BaseWand.cs | 3 +- Projects/UOContent/Items/Wands/ClumsyWand.cs | 3 +- Projects/UOContent/Items/Wands/FeebleWand.cs | 3 +- .../UOContent/Items/Wands/FireballWand.cs | 3 +- .../UOContent/Items/Wands/GreaterHealWand.cs | 3 +- Projects/UOContent/Items/Wands/HarmWand.cs | 3 +- Projects/UOContent/Items/Wands/HealWand.cs | 3 +- Projects/UOContent/Items/Wands/IDWand.cs | 3 +- .../UOContent/Items/Wands/LightningWand.cs | 3 +- .../UOContent/Items/Wands/MagicArrowWand.cs | 3 +- .../UOContent/Items/Wands/ManaDrainWand.cs | 3 +- .../UOContent/Items/Wands/WeaknessWand.cs | 3 +- .../Weapons/Artifacts/AxeOfTheHeavens.cs | 4 +- .../Weapons/Artifacts/BladeOfInsanity.cs | 4 +- .../Weapons/Artifacts/BladeOfTheRighteous.cs | 4 +- .../Items/Weapons/Artifacts/BoneCrusher.cs | 4 +- .../Weapons/Artifacts/BreathOfTheDead.cs | 4 +- .../Items/Weapons/Artifacts/Frostbringer.cs | 4 +- .../Weapons/Artifacts/LegacyOfTheDreadLord.cs | 4 +- .../Items/Weapons/Artifacts/SerpentsFang.cs | 4 +- .../Items/Weapons/Artifacts/StaffOfTheMagi.cs | 4 +- .../Weapons/Artifacts/TheBeserkersMaul.cs | 4 +- .../Weapons/Artifacts/TheDragonSlayer.cs | 4 +- .../Items/Weapons/Artifacts/TheDryadBow.cs | 4 +- .../Items/Weapons/Artifacts/TheTaskmaster.cs | 4 +- .../Items/Weapons/Artifacts/TitansHammer.cs | 4 +- .../Items/Weapons/Artifacts/ZyronicClaw.cs | 4 +- Projects/UOContent/Items/Weapons/Axes/Axe.cs | 4 +- .../UOContent/Items/Weapons/Axes/BaseAxe.cs | 3 +- .../UOContent/Items/Weapons/Axes/BattleAxe.cs | 4 +- .../UOContent/Items/Weapons/Axes/DoubleAxe.cs | 4 +- .../Items/Weapons/Axes/DualShortAxes.cs | 4 +- .../Items/Weapons/Axes/ExecutionersAxe.cs | 4 +- .../Items/Weapons/Axes/GuardianAxe.cs | 4 +- .../UOContent/Items/Weapons/Axes/Hatchet.cs | 4 +- .../Items/Weapons/Axes/HeavyOrnateAxe.cs | 4 +- .../Items/Weapons/Axes/LargeBattleAxe.cs | 4 +- .../UOContent/Items/Weapons/Axes/Pickaxe.cs | 3 +- .../Items/Weapons/Axes/SingingAxe.cs | 4 +- .../Items/Weapons/Axes/ThunderingAxe.cs | 4 +- .../Items/Weapons/Axes/TwoHandedAxe.cs | 4 +- .../UOContent/Items/Weapons/Axes/WarAxe.cs | 3 +- Projects/UOContent/Items/Weapons/Fists.cs | 3 +- .../Items/Weapons/Knives/BaseKnife.cs | 3 +- .../Items/Weapons/Knives/ButcherKnife.cs | 4 +- .../UOContent/Items/Weapons/Knives/Cleaver.cs | 4 +- .../UOContent/Items/Weapons/Knives/Dagger.cs | 4 +- .../Items/Weapons/Knives/SkinningKnife.cs | 4 +- .../Items/Weapons/Knives/ThrowingDagger.cs | 3 +- .../Artifacts/BlightGrippedLongbow.cs | 4 +- .../ML Weapons/Artifacts/ColdForgedBlade.cs | 4 +- .../ML Weapons/Artifacts/FaerieFire.cs | 4 +- .../ML Weapons/Artifacts/LuminousRuneBlade.cs | 4 +- .../ML Weapons/Artifacts/MischiefMaker.cs | 4 +- .../Artifacts/OverseerSunderedBlade.cs | 4 +- .../ML Weapons/Artifacts/PhantomStaff.cs | 4 +- .../ML Weapons/Artifacts/RuneCarvingKnife.cs | 4 +- .../ML Weapons/Artifacts/ShardTrasher.cs | 4 +- .../Artifacts/SilvanisFeywoodBow.cs | 4 +- .../ML Weapons/Artifacts/TheNightReaper.cs | 4 +- .../Items/Weapons/ML Weapons/AssassinSpike.cs | 4 +- .../Weapons/ML Weapons/ButchersWarCleaver.cs | 4 +- .../Items/Weapons/ML Weapons/DiamondMace.cs | 4 +- .../ML Weapons/ElvenCompositeLongbow.cs | 3 +- .../Items/Weapons/ML Weapons/ElvenMachete.cs | 4 +- .../Weapons/ML Weapons/ElvenSpellblade.cs | 4 +- .../Items/Weapons/ML Weapons/Leafblade.cs | 4 +- .../Weapons/ML Weapons/MagicalShortbow.cs | 3 +- .../Items/Weapons/ML Weapons/OrnateAxe.cs | 4 +- .../Weapons/ML Weapons/RadiantScimitar.cs | 4 +- .../Items/Weapons/ML Weapons/RuneBlade.cs | 4 +- .../Items/Weapons/ML Weapons/WarCleaver.cs | 4 +- .../Items/Weapons/ML Weapons/WildStaff.cs | 4 +- .../Items/Weapons/Maces/BaseBashing.cs | 3 +- .../UOContent/Items/Weapons/Maces/Club.cs | 4 +- .../UOContent/Items/Weapons/Maces/DiscMace.cs | 4 +- .../Items/Weapons/Maces/EmeraldMace.cs | 4 +- .../Items/Weapons/Maces/FireworksWand.cs | 3 +- .../Items/Weapons/Maces/HammerPick.cs | 4 +- .../UOContent/Items/Weapons/Maces/Mace.cs | 4 +- .../Items/Weapons/Maces/MagicWand.cs | 4 +- .../UOContent/Items/Weapons/Maces/Maul.cs | 4 +- .../UOContent/Items/Weapons/Maces/RubyMace.cs | 4 +- .../Items/Weapons/Maces/SapphireMace.cs | 4 +- .../UOContent/Items/Weapons/Maces/Scepter.cs | 4 +- .../Items/Weapons/Maces/SilverEtchedMace.cs | 4 +- .../Items/Weapons/Maces/WarHammer.cs | 4 +- .../UOContent/Items/Weapons/Maces/WarMace.cs | 4 +- .../Items/Weapons/PoleArms/Bardiche.cs | 4 +- .../Items/Weapons/PoleArms/BasePoleArm.cs | 3 +- .../Items/Weapons/PoleArms/Halberd.cs | 4 +- .../Items/Weapons/PoleArms/Scythe.cs | 3 +- .../Items/Weapons/Ranged/AssassinsShortbow.cs | 4 +- .../Items/Weapons/Ranged/BarbedLongbow.cs | 4 +- .../Items/Weapons/Ranged/BaseRanged.cs | 3 +- .../UOContent/Items/Weapons/Ranged/Bow.cs | 3 +- .../Items/Weapons/Ranged/CompositeBow.cs | 3 +- .../Items/Weapons/Ranged/Crossbow.cs | 3 +- .../Items/Weapons/Ranged/FrozenLongbow.cs | 4 +- .../Items/Weapons/Ranged/HeavyCrossbow.cs | 3 +- .../UOContent/Items/Weapons/Ranged/JukaBow.cs | 3 +- .../Weapons/Ranged/LightweightShortbow.cs | 4 +- .../Items/Weapons/Ranged/LongbowOfMight.cs | 4 +- .../Items/Weapons/Ranged/MysticalShortbow.cs | 4 +- .../Items/Weapons/Ranged/RangersShortbow.cs | 4 +- .../Items/Weapons/Ranged/RepeatingCrossbow.cs | 3 +- .../Items/Weapons/Ranged/SlayerLongbow.cs | 4 +- .../Items/Weapons/SE Weapons/Bokuto.cs | 4 +- .../Items/Weapons/SE Weapons/Daisho.cs | 4 +- .../Items/Weapons/SE Weapons/Kama.cs | 4 +- .../Items/Weapons/SE Weapons/Lajatang.cs | 4 +- .../Items/Weapons/SE Weapons/NoDachi.cs | 4 +- .../Items/Weapons/SE Weapons/Nunchaku.cs | 4 +- .../UOContent/Items/Weapons/SE Weapons/Sai.cs | 4 +- .../Items/Weapons/SE Weapons/Tekagi.cs | 4 +- .../Items/Weapons/SE Weapons/Tessen.cs | 4 +- .../Items/Weapons/SE Weapons/Tetsubo.cs | 4 +- .../Items/Weapons/SE Weapons/Wakizashi.cs | 4 +- .../Items/Weapons/SE Weapons/Yumi.cs | 3 +- .../Items/Weapons/SpearsAndForks/BaseSpear.cs | 3 +- .../Weapons/SpearsAndForks/BladedStaff.cs | 4 +- .../SpearsAndForks/DoubleBladedStaff.cs | 4 +- .../SpearsAndForks/DualPointedSpear.cs | 4 +- .../Items/Weapons/SpearsAndForks/Pike.cs | 4 +- .../Items/Weapons/SpearsAndForks/Pitchfork.cs | 4 +- .../Weapons/SpearsAndForks/ShortSpear.cs | 4 +- .../Items/Weapons/SpearsAndForks/Spear.cs | 4 +- .../Weapons/SpearsAndForks/TribalSpear.cs | 4 +- .../Items/Weapons/SpearsAndForks/WarFork.cs | 4 +- .../Items/Weapons/Staves/BaseStaff.cs | 4 +- .../Items/Weapons/Staves/BlackStaff.cs | 4 +- .../Items/Weapons/Staves/GlacialStaff.cs | 4 +- .../Items/Weapons/Staves/GlassStaff.cs | 4 +- .../Items/Weapons/Staves/GnarledStaff.cs | 4 +- .../Items/Weapons/Staves/QuarterStaff.cs | 4 +- .../Items/Weapons/Staves/SerpentstoneStaff.cs | 4 +- .../Items/Weapons/Staves/ShepherdsCrook.cs | 3 +- .../Weapons/Swords/AdventurersMachete.cs | 4 +- .../Items/Weapons/Swords/BaseSword.cs | 3 +- .../Items/Weapons/Swords/BloodBlade.cs | 4 +- .../Items/Weapons/Swords/BoneHarvester.cs | 4 +- .../Items/Weapons/Swords/BoneMachete.cs | 3 +- .../Items/Weapons/Swords/Broadsword.cs | 4 +- .../Weapons/Swords/ChargedAssassinSpike.cs | 4 +- .../Weapons/Swords/CorruptedRuneBlade.cs | 4 +- .../Items/Weapons/Swords/CrescentBlade.cs | 4 +- .../UOContent/Items/Weapons/Swords/Cutlass.cs | 4 +- .../Items/Weapons/Swords/DarkglowScimitar.cs | 4 +- .../Items/Weapons/Swords/DiseasedMachete.cs | 4 +- .../Items/Weapons/Swords/DreadSword.cs | 4 +- .../Items/Weapons/Swords/FierySpellblade.cs | 4 +- .../Items/Weapons/Swords/GargishTalwar.cs | 4 +- .../Items/Weapons/Swords/GlassSword.cs | 4 +- .../Items/Weapons/Swords/IcyScimitar.cs | 4 +- .../Items/Weapons/Swords/IcySpellblade.cs | 4 +- .../UOContent/Items/Weapons/Swords/Katana.cs | 4 +- .../Items/Weapons/Swords/KnightsWarCleaver.cs | 4 +- .../UOContent/Items/Weapons/Swords/Kryss.cs | 4 +- .../UOContent/Items/Weapons/Swords/Lance.cs | 4 +- .../Items/Weapons/Swords/LeafbladeOfEase.cs | 4 +- .../Items/Weapons/Swords/Longsword.cs | 4 +- .../Items/Weapons/Swords/Luckblade.cs | 4 +- .../Items/Weapons/Swords/MacheteOfDefense.cs | 4 +- .../Weapons/Swords/MagekillerAssassinSpike.cs | 4 +- .../Weapons/Swords/MagekillerLeafblade.cs | 4 +- .../Items/Weapons/Swords/MagesRuneBlade.cs | 4 +- .../Items/Weapons/Swords/OrcishMachete.cs | 4 +- .../Weapons/Swords/RuneBladeOfKnowledge.cs | 4 +- .../Items/Weapons/Swords/Runesabre.cs | 4 +- .../Items/Weapons/Swords/Scimitar.cs | 4 +- .../Weapons/Swords/SerratedWarCleaver.cs | 4 +- .../Weapons/Swords/SpellbladeOfDefense.cs | 4 +- .../Items/Weapons/Swords/ThinLongsword.cs | 4 +- .../Items/Weapons/Swords/TrueAssassinSpike.cs | 4 +- .../Items/Weapons/Swords/TrueLeafblade.cs | 4 +- .../Weapons/Swords/TrueRadiantScimitar.cs | 4 +- .../Items/Weapons/Swords/TrueSpellblade.cs | 4 +- .../Items/Weapons/Swords/TrueWarCleaver.cs | 4 +- .../Items/Weapons/Swords/TwinklingScimitar.cs | 4 +- .../Items/Weapons/Swords/VikingSword.cs | 4 +- .../Weapons/Swords/WoundingAssassinSpike.cs | 4 +- .../Items/Weapons/Wooden/AncientWildStaff.cs | 4 +- .../Weapons/Wooden/ArcanistsWildStaff.cs | 4 +- .../Items/Weapons/Wooden/HardenedWildStaff.cs | 4 +- .../Items/Weapons/Wooden/ThornedWildStaff.cs | 4 +- .../Migrations/Server.Items.Aquarium.v4.json | 4 +- .../Migrations/Server.Items.BaseArmor.v8.json | 8 +- .../Migrations/Server.Items.BaseArmor.v9.json | 6 +- .../Server.Items.BaseClothing.v6.json | 10 +- .../Server.Items.BaseClothing.v7.json | 8 +- .../Server.Items.ElvenGlasses.v0.json | 2 +- Projects/UOContent/Misc/AOS.cs | 7 +- .../Monsters/Humanoid/Magic/EvilMage.cs | 3 +- .../Monsters/Humanoid/Magic/EvilMageLord.cs | 3 +- .../Spells/Bushido/MomentumStrike.cs | 1 - Projects/UOContent/UOContent.csproj | 5 +- 740 files changed, 2552 insertions(+), 1743 deletions(-) delete mode 100644 Projects/Server/Serialization/Attributes/AfterDeserializationAttribute.cs delete mode 100644 Projects/Server/Serialization/Attributes/DeltaDateTimeAttribute.cs delete mode 100644 Projects/Server/Serialization/Attributes/DeserializeTimerFieldAttribute.cs delete mode 100755 Projects/Server/Serialization/Attributes/EmbeddedSerializableAttribute.cs delete mode 100644 Projects/Server/Serialization/Attributes/EncodedIntAttribute.cs delete mode 100644 Projects/Server/Serialization/Attributes/InternStringAttribute.cs delete mode 100644 Projects/Server/Serialization/Attributes/InvalidatePropertiesAttribute.cs delete mode 100755 Projects/Server/Serialization/Attributes/SerializableAttribute.cs delete mode 100755 Projects/Server/Serialization/Attributes/SerializableFieldAttribute.cs delete mode 100644 Projects/Server/Serialization/Attributes/SerializableFieldAttributeAttribute.cs delete mode 100644 Projects/Server/Serialization/Attributes/SerializableFieldDefaultAttribute.cs delete mode 100644 Projects/Server/Serialization/Attributes/SerializableFieldSaveFlagAttribute.cs delete mode 100644 Projects/Server/Serialization/Attributes/SerializableParentAttribute.cs delete mode 100644 Projects/Server/Serialization/Attributes/TidyAttribute.cs delete mode 100644 Projects/Server/Serialization/Attributes/TimerDriftAttribute.cs diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index e0dbc85fc..524152c71 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "modernuoschemagenerator": { - "version": "1.0.2", + "version": "2.0.3", "commands": [ "ModernUOSchemaGenerator" ] diff --git a/Projects/Server/Collections/BitArray.cs b/Projects/Server/Collections/BitArray.cs index 9df8f5441..10f87459d 100644 --- a/Projects/Server/Collections/BitArray.cs +++ b/Projects/Server/Collections/BitArray.cs @@ -15,7 +15,7 @@ namespace Server.Collections; // A vector of bits. Use this to store bits efficiently, without having to do bit // shifting yourself. -[System.Serializable] +[Serializable] public sealed class BitArray : ICollection, ICloneable { private int[] m_array; // Do not rename (binary serialization) diff --git a/Projects/Server/Main.cs b/Projects/Server/Main.cs index d7af5d17c..f9ab272b7 100644 --- a/Projects/Server/Main.cs +++ b/Projects/Server/Main.cs @@ -599,7 +599,7 @@ namespace Server if (World.DirtyTrackingEnabled) { var manualDirtyCheckingAttribute = type.GetCustomAttribute(false); - var codeGennedAttribute = type.GetCustomAttribute(false); + var codeGennedAttribute = type.GetCustomAttribute(false); if (manualDirtyCheckingAttribute == null && codeGennedAttribute == null) { diff --git a/Projects/Server/Serialization/Attributes/AfterDeserializationAttribute.cs b/Projects/Server/Serialization/Attributes/AfterDeserializationAttribute.cs deleted file mode 100644 index 97386a53d..000000000 --- a/Projects/Server/Serialization/Attributes/AfterDeserializationAttribute.cs +++ /dev/null @@ -1,38 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: AfterDeserializationAttribute.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System; - -namespace Server -{ - /// - /// Hints to the source generator that this method should be executed after deserializing the object. - /// Method must have no parameters and return void. - /// - [AttributeUsage(AttributeTargets.Method)] - public class AfterDeserializationAttribute : Attribute - { - /// - /// Indicates whether the source generator should execute the method this is attached to immediately, or when - /// this is set to false, execute it using a Timer Delay. - /// - /// Note: Use false when the after deserialization involves deleting objects. This is to prevent corrupted - /// deserialization by removing an object before it has finished deserializing. - /// - public bool Synchronous { get; set; } - - public AfterDeserializationAttribute(bool synchronous = true) => Synchronous = true; - } -} diff --git a/Projects/Server/Serialization/Attributes/DeltaDateTimeAttribute.cs b/Projects/Server/Serialization/Attributes/DeltaDateTimeAttribute.cs deleted file mode 100644 index aa77bdacb..000000000 --- a/Projects/Server/Serialization/Attributes/DeltaDateTimeAttribute.cs +++ /dev/null @@ -1,27 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: DeltaDateTimeAttribute.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System; - -namespace Server -{ - /// - /// Hints to the source generator that a serializable DateTime field or property is for delta time (duration) - /// - [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] - public class DeltaDateTimeAttribute : Attribute - { - } -} diff --git a/Projects/Server/Serialization/Attributes/DeserializeTimerFieldAttribute.cs b/Projects/Server/Serialization/Attributes/DeserializeTimerFieldAttribute.cs deleted file mode 100644 index fb33ce62b..000000000 --- a/Projects/Server/Serialization/Attributes/DeserializeTimerFieldAttribute.cs +++ /dev/null @@ -1,34 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: DeserializeTimerFieldAttribute.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System; - -namespace Server -{ - /// - /// Hints to the source generator that the specified serializable field, which must be a timer, - /// can be deserialized by this method. The method signature should look like this: - /// - /// [DeserializeTimerField(0)] - /// private void DeserializeTimer(TimeSpan delay) - /// - [AttributeUsage(AttributeTargets.Method)] - public sealed class DeserializeTimerFieldAttribute : Attribute - { - public int Order { get; } - - public DeserializeTimerFieldAttribute(int order) => Order = order; - } -} diff --git a/Projects/Server/Serialization/Attributes/EmbeddedSerializableAttribute.cs b/Projects/Server/Serialization/Attributes/EmbeddedSerializableAttribute.cs deleted file mode 100755 index 8513097ef..000000000 --- a/Projects/Server/Serialization/Attributes/EmbeddedSerializableAttribute.cs +++ /dev/null @@ -1,32 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: EmbeddedSerializableAttribute.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System; - -namespace Server -{ - [AttributeUsage(AttributeTargets.Class)] - public sealed class EmbeddedSerializableAttribute : Attribute - { - public int Version { get; } - public bool EncodedVersion { get; } - - public EmbeddedSerializableAttribute(int version, bool encodedVersion = true) - { - Version = version; - EncodedVersion = encodedVersion; - } - } -} diff --git a/Projects/Server/Serialization/Attributes/EncodedIntAttribute.cs b/Projects/Server/Serialization/Attributes/EncodedIntAttribute.cs deleted file mode 100644 index 3cfd5dbaa..000000000 --- a/Projects/Server/Serialization/Attributes/EncodedIntAttribute.cs +++ /dev/null @@ -1,27 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: EncodedIntAttribute.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System; - -namespace Server -{ - /// - /// Hints to the source generator that a serializable int field or property should be encoded - /// - [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] - public class EncodedIntAttribute : Attribute - { - } -} diff --git a/Projects/Server/Serialization/Attributes/InternStringAttribute.cs b/Projects/Server/Serialization/Attributes/InternStringAttribute.cs deleted file mode 100644 index 968b0dd39..000000000 --- a/Projects/Server/Serialization/Attributes/InternStringAttribute.cs +++ /dev/null @@ -1,27 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: InternalizeString.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System; - -namespace Server -{ - /// - /// Hints to the source generator that a serializable string field or property should be internalized on deserialization - /// - [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] - public class InternStringAttribute : Attribute - { - } -} diff --git a/Projects/Server/Serialization/Attributes/InvalidatePropertiesAttribute.cs b/Projects/Server/Serialization/Attributes/InvalidatePropertiesAttribute.cs deleted file mode 100644 index b6f20f41e..000000000 --- a/Projects/Server/Serialization/Attributes/InvalidatePropertiesAttribute.cs +++ /dev/null @@ -1,28 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: InvalidatePropertiesAttribute.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System; - -namespace Server -{ - /// - /// Hints to the source generator that this field will execute an InvalidateProperties when the value is set - /// and the value is different from the current value. - /// - [AttributeUsage(AttributeTargets.Field)] - public class InvalidatePropertiesAttribute : Attribute - { - } -} diff --git a/Projects/Server/Serialization/Attributes/SerializableAttribute.cs b/Projects/Server/Serialization/Attributes/SerializableAttribute.cs deleted file mode 100755 index 052d81d11..000000000 --- a/Projects/Server/Serialization/Attributes/SerializableAttribute.cs +++ /dev/null @@ -1,32 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright (C) 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SerializableEntityAttribute.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System; - -namespace Server -{ - [AttributeUsage(AttributeTargets.Class)] - public sealed class SerializableAttribute : Attribute - { - public int Version { get; } - public bool EncodedVersion { get; } - - public SerializableAttribute(int version, bool encodedVersion = true) - { - Version = version; - EncodedVersion = encodedVersion; - } - } -} diff --git a/Projects/Server/Serialization/Attributes/SerializableFieldAttribute.cs b/Projects/Server/Serialization/Attributes/SerializableFieldAttribute.cs deleted file mode 100755 index 52a3dc097..000000000 --- a/Projects/Server/Serialization/Attributes/SerializableFieldAttribute.cs +++ /dev/null @@ -1,46 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright (C) 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SerializableFieldAttribute.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System; - -namespace Server -{ - /// - /// Hints to the source generator that this field or property should be serialized. - /// When used on a field, the source generator will generate the property entirely. - /// When used on a property, the user must call this.MarkDirty() after reassigning the value or modifying the value internally. - /// - [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] - public sealed class SerializableFieldAttribute : Attribute - { - public int Order { get; } - public string PropertyGetter { get; } - public string? PropertySetter { get; } - public bool IsVirtual { get; } - - public SerializableFieldAttribute( - int order, - string getter = "public", - string setter = "public", - bool isVirtual = false - ) - { - Order = order; - PropertyGetter = getter; - PropertySetter = setter; - IsVirtual = isVirtual; - } - } -} diff --git a/Projects/Server/Serialization/Attributes/SerializableFieldAttributeAttribute.cs b/Projects/Server/Serialization/Attributes/SerializableFieldAttributeAttribute.cs deleted file mode 100644 index 1cf8d6bb5..000000000 --- a/Projects/Server/Serialization/Attributes/SerializableFieldAttributeAttribute.cs +++ /dev/null @@ -1,46 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SerializableFieldAttributeAttribute.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System; - -namespace Server -{ - /// - /// Hints to the source generator that this field will need this attribute on the generated property - /// [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] - /// -or- - /// [SerializableFieldAttr(typeof(CommandPropertyAttribute), AccessLevel.GameMaster)] - /// - [AttributeUsage(AttributeTargets.Field, AllowMultiple = true)] - public sealed class SerializableFieldAttrAttribute : Attribute - { - public string AttributeString { get; } - public Type AttributeType { get; } - public object[] Arguments { get; } - - public SerializableFieldAttrAttribute(string attrString) => AttributeString = attrString; - - public SerializableFieldAttrAttribute(Type type, params object[] args) - { - if (typeof(Attribute).IsAssignableFrom(type)) - { - throw new ArgumentException($"Argument {nameof(type)} must be an attribute."); - } - - AttributeType = type; - Arguments = args; - } - } -} diff --git a/Projects/Server/Serialization/Attributes/SerializableFieldDefaultAttribute.cs b/Projects/Server/Serialization/Attributes/SerializableFieldDefaultAttribute.cs deleted file mode 100644 index 35ba44256..000000000 --- a/Projects/Server/Serialization/Attributes/SerializableFieldDefaultAttribute.cs +++ /dev/null @@ -1,35 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SerializableFieldDefaultAttribute.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System; - -namespace Server -{ - /// - /// Hints to the source generator that the field with the same order should use this default value - /// while deserializing. The default is used when the save flag indicates that we don't need to serialize the value - /// because this default can be used instead. - /// - /// Note: This is only used for the current version, not previous versions. Previous versions will always use a default - /// value for that type if it is not deserialized. - /// - [AttributeUsage(AttributeTargets.Method)] - public sealed class SerializableFieldDefaultAttribute : Attribute - { - public int Order { get; } - - public SerializableFieldDefaultAttribute(int order) => Order = order; - } -} diff --git a/Projects/Server/Serialization/Attributes/SerializableFieldSaveFlagAttribute.cs b/Projects/Server/Serialization/Attributes/SerializableFieldSaveFlagAttribute.cs deleted file mode 100644 index fb9c16184..000000000 --- a/Projects/Server/Serialization/Attributes/SerializableFieldSaveFlagAttribute.cs +++ /dev/null @@ -1,30 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SerializableFieldSaveFlagAttribute.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System; - -namespace Server -{ - /// - /// Hints to the source generator that the field with the same order value should use a save flag. - /// - [AttributeUsage(AttributeTargets.Method)] - public sealed class SerializableFieldSaveFlagAttribute : Attribute - { - public int Order { get; } - - public SerializableFieldSaveFlagAttribute(int order) => Order = order; - } -} diff --git a/Projects/Server/Serialization/Attributes/SerializableParentAttribute.cs b/Projects/Server/Serialization/Attributes/SerializableParentAttribute.cs deleted file mode 100644 index 12526d7f3..000000000 --- a/Projects/Server/Serialization/Attributes/SerializableParentAttribute.cs +++ /dev/null @@ -1,30 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SerializableParentAttribute.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System; - -namespace Server -{ - /// - /// Hints to the source generator that this field or property indicates the ISerializable parent of this class. - /// - [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] - public sealed class SerializableParentAttribute : Attribute - { - public SerializableParentAttribute() - { - } - } -} diff --git a/Projects/Server/Serialization/Attributes/TidyAttribute.cs b/Projects/Server/Serialization/Attributes/TidyAttribute.cs deleted file mode 100644 index 0e2ba92d9..000000000 --- a/Projects/Server/Serialization/Attributes/TidyAttribute.cs +++ /dev/null @@ -1,27 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: TidyAttribute.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System; - -namespace Server -{ - /// - /// Hints to the source generator that a serializable list should be tidied up - /// - [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] - public class TidyAttribute : Attribute - { - } -} diff --git a/Projects/Server/Serialization/Attributes/TimerDriftAttribute.cs b/Projects/Server/Serialization/Attributes/TimerDriftAttribute.cs deleted file mode 100644 index 87bb7174d..000000000 --- a/Projects/Server/Serialization/Attributes/TimerDriftAttribute.cs +++ /dev/null @@ -1,28 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: TimerDriftAttribute.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System; - -namespace Server -{ - /// - /// Hints to the source generator that this serializable timer field or property will drift - /// during deserialization. - /// - [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] - public class TimerDriftAttribute : Attribute - { - } -} diff --git a/Projects/Server/Server.csproj b/Projects/Server/Server.csproj index 5f4e998c5..68191b6ec 100755 --- a/Projects/Server/Server.csproj +++ b/Projects/Server/Server.csproj @@ -38,7 +38,8 @@ - + + diff --git a/Projects/UOContent.Tests/Tests/Accounting/Security/PasswordProtectionTest.cs b/Projects/UOContent.Tests/Tests/Accounting/Security/PasswordProtectionTest.cs index 380ab8954..1719f5295 100644 --- a/Projects/UOContent.Tests/Tests/Accounting/Security/PasswordProtectionTest.cs +++ b/Projects/UOContent.Tests/Tests/Accounting/Security/PasswordProtectionTest.cs @@ -1,5 +1,4 @@ using System; -using System.Security.Cryptography; using Server.Accounting; using Server.Accounting.Security; using Xunit; diff --git a/Projects/UOContent/Accounting/Account.cs b/Projects/UOContent/Accounting/Account.cs index 632597858..61b9dae64 100644 --- a/Projects/UOContent/Accounting/Account.cs +++ b/Projects/UOContent/Accounting/Account.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Net; using System.Runtime.CompilerServices; using System.Xml; +using ModernUO.Serialization; using Server.Accounting.Security; using Server.Misc; using Server.Mobiles; @@ -11,7 +12,7 @@ using Server.Network; namespace Server.Accounting { - [Serializable(4)] + [SerializationGenerator(4)] public partial class Account : IAccount, IComparable, ISerializable { public static readonly TimeSpan YoungDuration = TimeSpan.FromHours(40.0); diff --git a/Projects/UOContent/Engines/Bulk Orders/BaseBOD.cs b/Projects/UOContent/Engines/Bulk Orders/BaseBOD.cs index 2103ff656..42777a342 100644 --- a/Projects/UOContent/Engines/Bulk Orders/BaseBOD.cs +++ b/Projects/UOContent/Engines/Bulk Orders/BaseBOD.cs @@ -1,8 +1,9 @@ using System.Collections.Generic; +using ModernUO.Serialization; namespace Server.Engines.BulkOrders { - [Serializable(1)] + [SerializationGenerator(1)] public abstract partial class BaseBOD : Item { public BaseBOD(int hue, int amountMax, bool requireExeptional, BulkMaterialType material) : this() diff --git a/Projects/UOContent/Engines/Bulk Orders/LargeBOD.cs b/Projects/UOContent/Engines/Bulk Orders/LargeBOD.cs index b6b8c77b8..c20ec4e86 100644 --- a/Projects/UOContent/Engines/Bulk Orders/LargeBOD.cs +++ b/Projects/UOContent/Engines/Bulk Orders/LargeBOD.cs @@ -1,8 +1,9 @@ +using ModernUO.Serialization; using Server.Mobiles; namespace Server.Engines.BulkOrders { - [Serializable(1)] + [SerializationGenerator(1)] public abstract partial class LargeBOD : BaseBOD { [InvalidateProperties] diff --git a/Projects/UOContent/Engines/Bulk Orders/LargeSmithBOD.cs b/Projects/UOContent/Engines/Bulk Orders/LargeSmithBOD.cs index e2aace6c6..07fc832dd 100644 --- a/Projects/UOContent/Engines/Bulk Orders/LargeSmithBOD.cs +++ b/Projects/UOContent/Engines/Bulk Orders/LargeSmithBOD.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Engines.BulkOrders { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LargeSmithBOD : LargeBOD { public static double[] m_BlacksmithMaterialChances = diff --git a/Projects/UOContent/Engines/Bulk Orders/LargeTailorBOD.cs b/Projects/UOContent/Engines/Bulk Orders/LargeTailorBOD.cs index 39d79e8e3..f8579e289 100644 --- a/Projects/UOContent/Engines/Bulk Orders/LargeTailorBOD.cs +++ b/Projects/UOContent/Engines/Bulk Orders/LargeTailorBOD.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Engines.BulkOrders { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LargeTailorBOD : LargeBOD { public static double[] m_TailoringMaterialChances = diff --git a/Projects/UOContent/Engines/Bulk Orders/SmallSmithBOD.cs b/Projects/UOContent/Engines/Bulk Orders/SmallSmithBOD.cs index dc5b06095..d91f2a84e 100644 --- a/Projects/UOContent/Engines/Bulk Orders/SmallSmithBOD.cs +++ b/Projects/UOContent/Engines/Bulk Orders/SmallSmithBOD.cs @@ -1,10 +1,11 @@ using System; using System.Collections.Generic; +using ModernUO.Serialization; using Server.Engines.Craft; namespace Server.Engines.BulkOrders { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class SmallSmithBOD : SmallBOD { public static double[] m_BlacksmithMaterialChances = diff --git a/Projects/UOContent/Engines/Bulk Orders/SmallTailorBOD.cs b/Projects/UOContent/Engines/Bulk Orders/SmallTailorBOD.cs index 598779cbd..9a0c6ed13 100644 --- a/Projects/UOContent/Engines/Bulk Orders/SmallTailorBOD.cs +++ b/Projects/UOContent/Engines/Bulk Orders/SmallTailorBOD.cs @@ -1,10 +1,11 @@ using System; using System.Collections.Generic; +using ModernUO.Serialization; using Server.Engines.Craft; namespace Server.Engines.BulkOrders { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class SmallTailorBOD : SmallBOD { public static double[] m_TailoringMaterialChances = diff --git a/Projects/UOContent/Holiday Stuff/Christmas/2010/Addons/FireFliesDeed.cs b/Projects/UOContent/Holiday Stuff/Christmas/2010/Addons/FireFliesDeed.cs index dce038cf1..2e88a0a9b 100644 --- a/Projects/UOContent/Holiday Stuff/Christmas/2010/Addons/FireFliesDeed.cs +++ b/Projects/UOContent/Holiday Stuff/Christmas/2010/Addons/FireFliesDeed.cs @@ -1,3 +1,4 @@ +using ModernUO.Serialization; using Server.Gumps; using Server.Multis; using Server.Network; @@ -5,7 +6,7 @@ using Server.Targeting; namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class Fireflies : Item, IAddon { [Constructible] @@ -59,7 +60,7 @@ namespace Server.Items } } - [Serializable(0)] + [SerializationGenerator(0)] public partial class FirefliesDeed : Item { [Constructible] diff --git a/Projects/UOContent/Holiday Stuff/Christmas/2010/Items/AngelDecoration.cs b/Projects/UOContent/Holiday Stuff/Christmas/2010/Items/AngelDecoration.cs index 2242706da..4b6d4969c 100644 --- a/Projects/UOContent/Holiday Stuff/Christmas/2010/Items/AngelDecoration.cs +++ b/Projects/UOContent/Holiday Stuff/Christmas/2010/Items/AngelDecoration.cs @@ -1,6 +1,8 @@ -namespace Server.Items.Holiday +using ModernUO.Serialization; + +namespace Server.Items.Holiday { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [TypeAlias("Server.Items.AngelDecoration"), Flippable(0x46FA, 0x46FB)] public partial class AngelDecoration : Item { diff --git a/Projects/UOContent/Holiday Stuff/Christmas/2010/Items/RockingHorse.cs b/Projects/UOContent/Holiday Stuff/Christmas/2010/Items/RockingHorse.cs index a33fbf70a..f2588cf46 100644 --- a/Projects/UOContent/Holiday Stuff/Christmas/2010/Items/RockingHorse.cs +++ b/Projects/UOContent/Holiday Stuff/Christmas/2010/Items/RockingHorse.cs @@ -1,6 +1,8 @@ -namespace Server.Items.Holiday +using ModernUO.Serialization; + +namespace Server.Items.Holiday { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [TypeAlias("Server.Items.RockingHorse"), Flippable(0x4214, 0x4215)] public partial class RockingHorse : Item { diff --git a/Projects/UOContent/Holiday Stuff/Easter/2011/Items/DragonEasterEgg.cs b/Projects/UOContent/Holiday Stuff/Easter/2011/Items/DragonEasterEgg.cs index 5d936e8ca..bd0212152 100644 --- a/Projects/UOContent/Holiday Stuff/Easter/2011/Items/DragonEasterEgg.cs +++ b/Projects/UOContent/Holiday Stuff/Easter/2011/Items/DragonEasterEgg.cs @@ -1,6 +1,8 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class DragonEasterEgg : Item, IDyable { [Constructible] diff --git a/Projects/UOContent/Holiday Stuff/Halloween/2006/Engines/TrickOrTreat.cs b/Projects/UOContent/Holiday Stuff/Halloween/2006/Engines/TrickOrTreat.cs index c66f1ccf2..9eda894b9 100644 --- a/Projects/UOContent/Holiday Stuff/Halloween/2006/Engines/TrickOrTreat.cs +++ b/Projects/UOContent/Holiday Stuff/Halloween/2006/Engines/TrickOrTreat.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Runtime.CompilerServices; +using ModernUO.Serialization; using Server.Events.Halloween; using Server.Items; using Server.Mobiles; @@ -232,7 +233,7 @@ namespace Server.Engines.Events } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class NaughtyTwin : BaseCreature { private static readonly Point3D[] Felucca_Locations = diff --git a/Projects/UOContent/Holiday Stuff/Halloween/2006/Items/HalloweenPumpkin.cs b/Projects/UOContent/Holiday Stuff/Halloween/2006/Items/HalloweenPumpkin.cs index 7197c531e..896af55d9 100644 --- a/Projects/UOContent/Holiday Stuff/Halloween/2006/Items/HalloweenPumpkin.cs +++ b/Projects/UOContent/Holiday Stuff/Halloween/2006/Items/HalloweenPumpkin.cs @@ -1,8 +1,9 @@ -using Server.Mobiles; +using ModernUO.Serialization; +using Server.Mobiles; namespace Server.Items { - [Serializable(1, false)] + [SerializationGenerator(1, false)] public partial class HalloweenPumpkin : Item { private static readonly string[] m_Staff = diff --git a/Projects/UOContent/Holiday Stuff/Halloween/2006/Items/PumpkinScarecrow.cs b/Projects/UOContent/Holiday Stuff/Halloween/2006/Items/PumpkinScarecrow.cs index 2d27e9e53..b6983203c 100644 --- a/Projects/UOContent/Holiday Stuff/Halloween/2006/Items/PumpkinScarecrow.cs +++ b/Projects/UOContent/Holiday Stuff/Halloween/2006/Items/PumpkinScarecrow.cs @@ -1,6 +1,8 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class PumpkinScarecrow : Item { [Constructible] diff --git a/Projects/UOContent/Holiday Stuff/Halloween/2006/Items/RuinedTapestry.cs b/Projects/UOContent/Holiday Stuff/Halloween/2006/Items/RuinedTapestry.cs index af265221c..db86b8f0a 100644 --- a/Projects/UOContent/Holiday Stuff/Halloween/2006/Items/RuinedTapestry.cs +++ b/Projects/UOContent/Holiday Stuff/Halloween/2006/Items/RuinedTapestry.cs @@ -1,6 +1,8 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class RuinedTapestry : Item { [Constructible] diff --git a/Projects/UOContent/Holiday Stuff/Halloween/2006/Items/TwilightLantern.cs b/Projects/UOContent/Holiday Stuff/Halloween/2006/Items/TwilightLantern.cs index 456804a67..5152901d2 100644 --- a/Projects/UOContent/Holiday Stuff/Halloween/2006/Items/TwilightLantern.cs +++ b/Projects/UOContent/Holiday Stuff/Halloween/2006/Items/TwilightLantern.cs @@ -1,6 +1,8 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class TwilightLantern : Lantern { [Constructible] diff --git a/Projects/UOContent/Holiday Stuff/Halloween/2009/Foods/CreepyCake.cs b/Projects/UOContent/Holiday Stuff/Halloween/2009/Foods/CreepyCake.cs index 605b1446c..268c25ae0 100644 --- a/Projects/UOContent/Holiday Stuff/Halloween/2009/Foods/CreepyCake.cs +++ b/Projects/UOContent/Holiday Stuff/Halloween/2009/Foods/CreepyCake.cs @@ -1,10 +1,12 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items { /* first seen halloween 2009. subsequently in 2010, 2011 and 2012. GM Beggar-only Semi-Rare Treats */ - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class CreepyCake : Food { [Constructible] diff --git a/Projects/UOContent/Holiday Stuff/Halloween/2009/Foods/HarvestWine.cs b/Projects/UOContent/Holiday Stuff/Halloween/2009/Foods/HarvestWine.cs index d657d6dcb..ca0513ac4 100644 --- a/Projects/UOContent/Holiday Stuff/Halloween/2009/Foods/HarvestWine.cs +++ b/Projects/UOContent/Holiday Stuff/Halloween/2009/Foods/HarvestWine.cs @@ -1,10 +1,12 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items { /* first seen halloween 2009. subsequently in 2010, 2011 and 2012. GM Beggar-only Semi-Rare Treats */ - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class HarvestWine : BeverageBottle { [Constructible] diff --git a/Projects/UOContent/Holiday Stuff/Halloween/2009/Foods/MrPlainsCookies.cs b/Projects/UOContent/Holiday Stuff/Halloween/2009/Foods/MrPlainsCookies.cs index 7b70e3a31..9e2c2b670 100644 --- a/Projects/UOContent/Holiday Stuff/Halloween/2009/Foods/MrPlainsCookies.cs +++ b/Projects/UOContent/Holiday Stuff/Halloween/2009/Foods/MrPlainsCookies.cs @@ -1,6 +1,8 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class MrPlainsCookies : Food { [Constructible] diff --git a/Projects/UOContent/Holiday Stuff/Halloween/2009/Foods/MurkyMilk.cs b/Projects/UOContent/Holiday Stuff/Halloween/2009/Foods/MurkyMilk.cs index 1a93b89fb..eb5ab5b87 100644 --- a/Projects/UOContent/Holiday Stuff/Halloween/2009/Foods/MurkyMilk.cs +++ b/Projects/UOContent/Holiday Stuff/Halloween/2009/Foods/MurkyMilk.cs @@ -1,10 +1,12 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items { /* first seen halloween 2009. subsequently in 2010, 2011 and 2012. GM Beggar-only Semi-Rare Treats */ - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class MurkyMilk : Pitcher { [Constructible] diff --git a/Projects/UOContent/Holiday Stuff/Halloween/2009/Foods/PumpkinPizza.cs b/Projects/UOContent/Holiday Stuff/Halloween/2009/Foods/PumpkinPizza.cs index 29c02dcbc..ef277242f 100644 --- a/Projects/UOContent/Holiday Stuff/Halloween/2009/Foods/PumpkinPizza.cs +++ b/Projects/UOContent/Holiday Stuff/Halloween/2009/Foods/PumpkinPizza.cs @@ -1,10 +1,12 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items { /* first seen halloween 2009. subsequently in 2010, 2011 and 2012. GM Beggar-only Semi-Rare Treats */ - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class PumpkinPizza : CheesePizza { [Constructible] diff --git a/Projects/UOContent/Holiday Stuff/Halloween/2009/Items/GrimWarning.cs b/Projects/UOContent/Holiday Stuff/Halloween/2009/Items/GrimWarning.cs index 9376063eb..3a5eef292 100644 --- a/Projects/UOContent/Holiday Stuff/Halloween/2009/Items/GrimWarning.cs +++ b/Projects/UOContent/Holiday Stuff/Halloween/2009/Items/GrimWarning.cs @@ -1,10 +1,12 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items { /* first seen halloween 2009. subsequently in 2010, 2011 and 2012. GM Beggar-only Semi-Rare Treats */ - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class GrimWarning : Item { [Constructible] diff --git a/Projects/UOContent/Holiday Stuff/Halloween/2009/Items/SkullsOnPike.cs b/Projects/UOContent/Holiday Stuff/Halloween/2009/Items/SkullsOnPike.cs index e391394fc..76d7bf978 100644 --- a/Projects/UOContent/Holiday Stuff/Halloween/2009/Items/SkullsOnPike.cs +++ b/Projects/UOContent/Holiday Stuff/Halloween/2009/Items/SkullsOnPike.cs @@ -1,10 +1,12 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items { /* first seen halloween 2009. subsequently in 2010, 2011 and 2012. GM Beggar-only Semi-Rare Treats */ - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class SkullsOnPike : Item { [Constructible] diff --git a/Projects/UOContent/Holiday Stuff/Halloween/2010/Items/ChairInAGhostCostume.cs b/Projects/UOContent/Holiday Stuff/Halloween/2010/Items/ChairInAGhostCostume.cs index 73a5981b1..7b981aa3d 100644 --- a/Projects/UOContent/Holiday Stuff/Halloween/2010/Items/ChairInAGhostCostume.cs +++ b/Projects/UOContent/Holiday Stuff/Halloween/2010/Items/ChairInAGhostCostume.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class ChairInAGhostCostume : Item { [Constructible] diff --git a/Projects/UOContent/Holiday Stuff/Halloween/2010/Items/ColoredSmallWebs.cs b/Projects/UOContent/Holiday Stuff/Halloween/2010/Items/ColoredSmallWebs.cs index d4dec3a11..33f5c0891 100644 --- a/Projects/UOContent/Holiday Stuff/Halloween/2010/Items/ColoredSmallWebs.cs +++ b/Projects/UOContent/Holiday Stuff/Halloween/2010/Items/ColoredSmallWebs.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class ColoredSmallWebs : Item { [Constructible] diff --git a/Projects/UOContent/Holiday Stuff/Halloween/2010/Items/ExcellentIronMaiden.cs b/Projects/UOContent/Holiday Stuff/Halloween/2010/Items/ExcellentIronMaiden.cs index 502eb1755..5213054b3 100644 --- a/Projects/UOContent/Holiday Stuff/Halloween/2010/Items/ExcellentIronMaiden.cs +++ b/Projects/UOContent/Holiday Stuff/Halloween/2010/Items/ExcellentIronMaiden.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class ExcellentIronMaiden : Item { [Constructible] diff --git a/Projects/UOContent/Holiday Stuff/Halloween/2010/Items/HalloweenGuillotine.cs b/Projects/UOContent/Holiday Stuff/Halloween/2010/Items/HalloweenGuillotine.cs index 6effbfe54..8eb576c92 100644 --- a/Projects/UOContent/Holiday Stuff/Halloween/2010/Items/HalloweenGuillotine.cs +++ b/Projects/UOContent/Holiday Stuff/Halloween/2010/Items/HalloweenGuillotine.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class HalloweenGuillotine : Item { [Constructible] diff --git a/Projects/UOContent/Holiday Stuff/Halloween/2011/Items/BasePaintedMask.cs b/Projects/UOContent/Holiday Stuff/Halloween/2011/Items/BasePaintedMask.cs index 4ea4e1800..8fc991ddc 100644 --- a/Projects/UOContent/Holiday Stuff/Halloween/2011/Items/BasePaintedMask.cs +++ b/Projects/UOContent/Holiday Stuff/Halloween/2011/Items/BasePaintedMask.cs @@ -1,6 +1,8 @@ -namespace Server.Items.Holiday +using ModernUO.Serialization; + +namespace Server.Items.Holiday { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [TypeAlias("Server.Items.ClownMask", "Server.Items.DaemonMask", "Server.Items.PlagueMask")] public partial class BasePaintedMask : Item { diff --git a/Projects/UOContent/Holiday Stuff/Halloween/2011/Items/ClownMask.cs b/Projects/UOContent/Holiday Stuff/Halloween/2011/Items/ClownMask.cs index 6d3819aea..735285b54 100644 --- a/Projects/UOContent/Holiday Stuff/Halloween/2011/Items/ClownMask.cs +++ b/Projects/UOContent/Holiday Stuff/Halloween/2011/Items/ClownMask.cs @@ -1,6 +1,8 @@ -namespace Server.Items.Holiday +using ModernUO.Serialization; + +namespace Server.Items.Holiday { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class PaintedEvilClownMask : BasePaintedMask { [Constructible] diff --git a/Projects/UOContent/Holiday Stuff/Halloween/2011/Items/DaemonMask.cs b/Projects/UOContent/Holiday Stuff/Halloween/2011/Items/DaemonMask.cs index e94e9b598..9d38be46d 100644 --- a/Projects/UOContent/Holiday Stuff/Halloween/2011/Items/DaemonMask.cs +++ b/Projects/UOContent/Holiday Stuff/Halloween/2011/Items/DaemonMask.cs @@ -1,6 +1,8 @@ -namespace Server.Items.Holiday +using ModernUO.Serialization; + +namespace Server.Items.Holiday { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class PaintedDaemonMask : BasePaintedMask { [Constructible] diff --git a/Projects/UOContent/Holiday Stuff/Halloween/2011/Items/PlagueMask.cs b/Projects/UOContent/Holiday Stuff/Halloween/2011/Items/PlagueMask.cs index ff03d1bcb..320ac732d 100644 --- a/Projects/UOContent/Holiday Stuff/Halloween/2011/Items/PlagueMask.cs +++ b/Projects/UOContent/Holiday Stuff/Halloween/2011/Items/PlagueMask.cs @@ -1,6 +1,8 @@ -namespace Server.Items.Holiday +using ModernUO.Serialization; + +namespace Server.Items.Holiday { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class PaintedPlagueMask : BasePaintedMask { [Constructible] diff --git a/Projects/UOContent/Holiday Stuff/Halloween/2011/Mobiles/PumpkinHead.cs b/Projects/UOContent/Holiday Stuff/Halloween/2011/Mobiles/PumpkinHead.cs index 8f1a35d21..954bd991d 100644 --- a/Projects/UOContent/Holiday Stuff/Halloween/2011/Mobiles/PumpkinHead.cs +++ b/Projects/UOContent/Holiday Stuff/Halloween/2011/Mobiles/PumpkinHead.cs @@ -1,10 +1,11 @@ using System; +using ModernUO.Serialization; using Server.Items; using Server.Items.Holiday; namespace Server.Mobiles { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class PumpkinHead : BaseCreature { [Constructible] diff --git a/Projects/UOContent/Holiday Stuff/Halloween/2012/Engines/PlayerZombies.cs b/Projects/UOContent/Holiday Stuff/Halloween/2012/Engines/PlayerZombies.cs index 20fd8e5ea..efb2cf1e0 100644 --- a/Projects/UOContent/Holiday Stuff/Halloween/2012/Engines/PlayerZombies.cs +++ b/Projects/UOContent/Holiday Stuff/Halloween/2012/Engines/PlayerZombies.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using ModernUO.Serialization; using Server.Events.Halloween; using Server.Items; using Server.Mobiles; @@ -132,7 +133,7 @@ namespace Server.Engines.Events } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class PlayerBones : BaseContainer { [Constructible] @@ -150,7 +151,7 @@ namespace Server.Engines.Events } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class ZombieSkeleton : BaseCreature { [SerializableField(0, "private", "private")] diff --git a/Projects/UOContent/Holiday Stuff/Halloween/2012/Items/EvilJesterMask.cs b/Projects/UOContent/Holiday Stuff/Halloween/2012/Items/EvilJesterMask.cs index ac7e9d8ea..7cd77753d 100644 --- a/Projects/UOContent/Holiday Stuff/Halloween/2012/Items/EvilJesterMask.cs +++ b/Projects/UOContent/Holiday Stuff/Halloween/2012/Items/EvilJesterMask.cs @@ -1,6 +1,8 @@ -namespace Server.Items.Holiday +using ModernUO.Serialization; + +namespace Server.Items.Holiday { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class PaintedEvilJesterMask : BasePaintedMask { [Constructible] diff --git a/Projects/UOContent/Holiday Stuff/Halloween/2012/Items/PorcelainMask.cs b/Projects/UOContent/Holiday Stuff/Halloween/2012/Items/PorcelainMask.cs index 630fa6aba..8a194e968 100644 --- a/Projects/UOContent/Holiday Stuff/Halloween/2012/Items/PorcelainMask.cs +++ b/Projects/UOContent/Holiday Stuff/Halloween/2012/Items/PorcelainMask.cs @@ -1,6 +1,8 @@ -namespace Server.Items.Holiday +using ModernUO.Serialization; + +namespace Server.Items.Holiday { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class PaintedPorcelainMask : BasePaintedMask { [Constructible] diff --git a/Projects/UOContent/Holiday Stuff/Halloween/Treats/Jellybeans.cs b/Projects/UOContent/Holiday Stuff/Halloween/Treats/Jellybeans.cs index 5e6d763c8..5b7279389 100644 --- a/Projects/UOContent/Holiday Stuff/Halloween/Treats/Jellybeans.cs +++ b/Projects/UOContent/Holiday Stuff/Halloween/Treats/Jellybeans.cs @@ -1,6 +1,8 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class JellyBeans : CandyCane { [Constructible] diff --git a/Projects/UOContent/Holiday Stuff/Halloween/Treats/Lollipops.cs b/Projects/UOContent/Holiday Stuff/Halloween/Treats/Lollipops.cs index a768fff99..280be39c6 100644 --- a/Projects/UOContent/Holiday Stuff/Halloween/Treats/Lollipops.cs +++ b/Projects/UOContent/Holiday Stuff/Halloween/Treats/Lollipops.cs @@ -1,7 +1,9 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items { [TypeAlias("Server.Items.Lollipop")] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Lollipops : CandyCane { [Constructible] diff --git a/Projects/UOContent/Holiday Stuff/Halloween/Treats/NougatSwirl.cs b/Projects/UOContent/Holiday Stuff/Halloween/Treats/NougatSwirl.cs index eb9942868..750239324 100644 --- a/Projects/UOContent/Holiday Stuff/Halloween/Treats/NougatSwirl.cs +++ b/Projects/UOContent/Holiday Stuff/Halloween/Treats/NougatSwirl.cs @@ -1,6 +1,8 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class NougatSwirl : CandyCane { [Constructible] diff --git a/Projects/UOContent/Holiday Stuff/Halloween/Treats/Taffy.cs b/Projects/UOContent/Holiday Stuff/Halloween/Treats/Taffy.cs index 2b2571604..814e4a822 100644 --- a/Projects/UOContent/Holiday Stuff/Halloween/Treats/Taffy.cs +++ b/Projects/UOContent/Holiday Stuff/Halloween/Treats/Taffy.cs @@ -1,6 +1,8 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Taffy : CandyCane { [Constructible] diff --git a/Projects/UOContent/Holiday Stuff/Halloween/Treats/WrappedCandy.cs b/Projects/UOContent/Holiday Stuff/Halloween/Treats/WrappedCandy.cs index eb86ac43d..8df86c688 100644 --- a/Projects/UOContent/Holiday Stuff/Halloween/Treats/WrappedCandy.cs +++ b/Projects/UOContent/Holiday Stuff/Halloween/Treats/WrappedCandy.cs @@ -1,6 +1,8 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class WrappedCandy : CandyCane { [Constructible] diff --git a/Projects/UOContent/Holiday Stuff/Valentine/2010/Items/AnimatedHeartShapedBox.cs b/Projects/UOContent/Holiday Stuff/Valentine/2010/Items/AnimatedHeartShapedBox.cs index e9e320e0c..3429c0af4 100644 --- a/Projects/UOContent/Holiday Stuff/Valentine/2010/Items/AnimatedHeartShapedBox.cs +++ b/Projects/UOContent/Holiday Stuff/Valentine/2010/Items/AnimatedHeartShapedBox.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x49CC, 0x49D0)] public partial class AnimatedHeartShapedBox : HeartShapedBox { diff --git a/Projects/UOContent/Holiday Stuff/Valentine/2011/Items/StValentinesBears.cs b/Projects/UOContent/Holiday Stuff/Valentine/2011/Items/StValentinesBears.cs index 119b167fa..700080df4 100644 --- a/Projects/UOContent/Holiday Stuff/Valentine/2011/Items/StValentinesBears.cs +++ b/Projects/UOContent/Holiday Stuff/Valentine/2011/Items/StValentinesBears.cs @@ -1,10 +1,11 @@ using System; +using ModernUO.Serialization; using Server.Gumps; using Server.Network; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public abstract partial class StValentinesBear : Item { [InternString] @@ -190,7 +191,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x48E0, 0x48E1)] public partial class StValentinesPanda : StValentinesBear { @@ -200,7 +201,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x48E2, 0x48E3)] public partial class StValentinesPolarBear : StValentinesBear { diff --git a/Projects/UOContent/Holiday Stuff/Valentine/2012/Items/CupidStatue.cs b/Projects/UOContent/Holiday Stuff/Valentine/2012/Items/CupidStatue.cs index a86ba5a56..20a11413a 100644 --- a/Projects/UOContent/Holiday Stuff/Valentine/2012/Items/CupidStatue.cs +++ b/Projects/UOContent/Holiday Stuff/Valentine/2012/Items/CupidStatue.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x4F7C, 0x4F7D)] public partial class CupidStatue : Item { diff --git a/Projects/UOContent/Holiday Stuff/Valentine/2012/Items/CupidsArrow.cs b/Projects/UOContent/Holiday Stuff/Valentine/2012/Items/CupidsArrow.cs index 184c9cec5..7b302e836 100644 --- a/Projects/UOContent/Holiday Stuff/Valentine/2012/Items/CupidsArrow.cs +++ b/Projects/UOContent/Holiday Stuff/Valentine/2012/Items/CupidsArrow.cs @@ -1,8 +1,9 @@ +using ModernUO.Serialization; using Server.Targeting; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class CupidsArrow : Item { [InternString] diff --git a/Projects/UOContent/Holiday Stuff/Valentine/2012/Items/HeartShapedBox.cs b/Projects/UOContent/Holiday Stuff/Valentine/2012/Items/HeartShapedBox.cs index 5f749777f..5882a3780 100644 --- a/Projects/UOContent/Holiday Stuff/Valentine/2012/Items/HeartShapedBox.cs +++ b/Projects/UOContent/Holiday Stuff/Valentine/2012/Items/HeartShapedBox.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x49CA, 0x49CB)] public partial class HeartShapedBox : BaseContainer { diff --git a/Projects/UOContent/Items/Addons/AbbatoirAddon.cs b/Projects/UOContent/Items/Addons/AbbatoirAddon.cs index 19db8af81..a3c1979ac 100644 --- a/Projects/UOContent/Items/Addons/AbbatoirAddon.cs +++ b/Projects/UOContent/Items/Addons/AbbatoirAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class AbbatoirAddon : BaseAddon { [Constructible] @@ -20,7 +22,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new AbbatoirDeed(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class AbbatoirDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/AddonComponent.cs b/Projects/UOContent/Items/Addons/AddonComponent.cs index 90d74dbc0..3cf10fc20 100644 --- a/Projects/UOContent/Items/Addons/AddonComponent.cs +++ b/Projects/UOContent/Items/Addons/AddonComponent.cs @@ -1,9 +1,10 @@ +using ModernUO.Serialization; using Server.Engines.Craft; namespace Server.Items { [Anvil] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class AnvilComponent : AddonComponent { [Constructible] @@ -13,7 +14,7 @@ namespace Server.Items } [Forge] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class ForgeComponent : AddonComponent { [Constructible] @@ -22,7 +23,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LocalizedAddonComponent : AddonComponent { [InvalidateProperties] @@ -36,7 +37,7 @@ namespace Server.Items public override int LabelNumber => _number; } - [Serializable(1, false)] + [SerializationGenerator(1, false)] public partial class AddonComponent : Item, IChoppable { private static readonly LightEntry[] m_Entries = diff --git a/Projects/UOContent/Items/Addons/AddonContainerComponent.cs b/Projects/UOContent/Items/Addons/AddonContainerComponent.cs index 509d430ea..7c612fd03 100644 --- a/Projects/UOContent/Items/Addons/AddonContainerComponent.cs +++ b/Projects/UOContent/Items/Addons/AddonContainerComponent.cs @@ -1,12 +1,13 @@ using System; using System.Buffers.Binary; using System.Collections.Generic; +using ModernUO.Serialization; using Server.ContextMenus; using Server.Network; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class AddonContainerComponent : Item, IChoppable { [Constructible] @@ -107,7 +108,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LocalizedContainerComponent : AddonContainerComponent { [SerializableField(0, setter: "private")] diff --git a/Projects/UOContent/Items/Addons/AlchemistTableEastAddon.cs b/Projects/UOContent/Items/Addons/AlchemistTableEastAddon.cs index a530b0d33..30492ddae 100644 --- a/Projects/UOContent/Items/Addons/AlchemistTableEastAddon.cs +++ b/Projects/UOContent/Items/Addons/AlchemistTableEastAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class AlchemistTableEastAddon : BaseAddon { [Constructible] @@ -12,7 +14,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new AlchemistTableEastDeed(); } - [Serializable(0)] + [SerializationGenerator(0)] public partial class AlchemistTableEastDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/AlchemistTableSouthAddon.cs b/Projects/UOContent/Items/Addons/AlchemistTableSouthAddon.cs index 8dabc4335..4f667d664 100644 --- a/Projects/UOContent/Items/Addons/AlchemistTableSouthAddon.cs +++ b/Projects/UOContent/Items/Addons/AlchemistTableSouthAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class AlchemistTableSouthAddon : BaseAddon { [Constructible] @@ -12,7 +14,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new AlchemistTableSouthDeed(); } - [Serializable(0)] + [SerializationGenerator(0)] public partial class AlchemistTableSouthDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/AnvilEastAddon.cs b/Projects/UOContent/Items/Addons/AnvilEastAddon.cs index 22d9cd232..bad7b1e1f 100644 --- a/Projects/UOContent/Items/Addons/AnvilEastAddon.cs +++ b/Projects/UOContent/Items/Addons/AnvilEastAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class AnvilEastAddon : BaseAddon { [Constructible] @@ -12,7 +14,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new AnvilEastDeed(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class AnvilEastDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/AnvilSouthAddon.cs b/Projects/UOContent/Items/Addons/AnvilSouthAddon.cs index fd5383a7c..a1495d3f5 100644 --- a/Projects/UOContent/Items/Addons/AnvilSouthAddon.cs +++ b/Projects/UOContent/Items/Addons/AnvilSouthAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class AnvilSouthAddon : BaseAddon { [Constructible] @@ -12,7 +14,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new AnvilSouthDeed(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class AnvilSouthDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/ArcaneBookshelfEastAddon.cs b/Projects/UOContent/Items/Addons/ArcaneBookshelfEastAddon.cs index ba197ed84..224d919d5 100644 --- a/Projects/UOContent/Items/Addons/ArcaneBookshelfEastAddon.cs +++ b/Projects/UOContent/Items/Addons/ArcaneBookshelfEastAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class ArcaneBookshelfEastAddon : BaseAddonContainer { [Constructible] @@ -15,7 +17,7 @@ namespace Server.Items public override int DefaultDropSound => 0x42; } - [Serializable(0)] + [SerializationGenerator(0)] public partial class ArcaneBookshelfEastDeed : BaseAddonContainerDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/ArcaneBookshelfSouthAddon.cs b/Projects/UOContent/Items/Addons/ArcaneBookshelfSouthAddon.cs index 4a9569f0d..c034d992d 100644 --- a/Projects/UOContent/Items/Addons/ArcaneBookshelfSouthAddon.cs +++ b/Projects/UOContent/Items/Addons/ArcaneBookshelfSouthAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class ArcaneBookshelfSouthAddon : BaseAddonContainer { [Constructible] @@ -16,7 +18,7 @@ namespace Server.Items public override int LabelNumber => 1032420; // arcane bookshelf } - [Serializable(0)] + [SerializationGenerator(0)] public partial class ArcaneBookshelfSouthDeed : BaseAddonContainerDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/ArcaneCircleAddon.cs b/Projects/UOContent/Items/Addons/ArcaneCircleAddon.cs index dd5b27f0b..931b506ae 100644 --- a/Projects/UOContent/Items/Addons/ArcaneCircleAddon.cs +++ b/Projects/UOContent/Items/Addons/ArcaneCircleAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(1)] + [SerializationGenerator(1)] public partial class ArcaneCircleAddon : BaseAddon { [Constructible] @@ -40,7 +42,7 @@ namespace Server.Items } } - [Serializable(0)] + [SerializationGenerator(0)] public partial class ArcaneCircleDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/ArcanistStatueEastAddon.cs b/Projects/UOContent/Items/Addons/ArcanistStatueEastAddon.cs index a41083159..8c8c3c0f9 100644 --- a/Projects/UOContent/Items/Addons/ArcanistStatueEastAddon.cs +++ b/Projects/UOContent/Items/Addons/ArcanistStatueEastAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class ArcanistStatueEastAddon : BaseAddon { [Constructible] @@ -12,7 +14,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new ArcanistStatueEastDeed(); } - [Serializable(0)] + [SerializationGenerator(0)] public partial class ArcanistStatueEastDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/ArcanistStatueSouthAddon.cs b/Projects/UOContent/Items/Addons/ArcanistStatueSouthAddon.cs index 27e19a4e2..1cfa9f277 100644 --- a/Projects/UOContent/Items/Addons/ArcanistStatueSouthAddon.cs +++ b/Projects/UOContent/Items/Addons/ArcanistStatueSouthAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class ArcanistStatueSouthAddon : BaseAddon { [Constructible] @@ -12,7 +14,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new ArcanistStatueSouthDeed(); } - [Serializable(0)] + [SerializationGenerator(0)] public partial class ArcanistStatueSouthDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/ArcheryButteAddon.cs b/Projects/UOContent/Items/Addons/ArcheryButteAddon.cs index 6f417235e..fc9f7eceb 100644 --- a/Projects/UOContent/Items/Addons/ArcheryButteAddon.cs +++ b/Projects/UOContent/Items/Addons/ArcheryButteAddon.cs @@ -1,10 +1,11 @@ using System; using System.Collections.Generic; +using ModernUO.Serialization; using Server.Network; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [FlippableAttribute(0x100A /*East*/, 0x100B /*South*/)] public partial class ArcheryButte : AddonComponent { @@ -293,7 +294,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class ArcheryButteAddon : BaseAddon { [Constructible] @@ -305,7 +306,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new ArcheryButteDeed(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class ArcheryButteDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/BallotBox.cs b/Projects/UOContent/Items/Addons/BallotBox.cs index a952c0dfe..cc9a6b99d 100644 --- a/Projects/UOContent/Items/Addons/BallotBox.cs +++ b/Projects/UOContent/Items/Addons/BallotBox.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using ModernUO.Serialization; using Server.Gumps; using Server.Multis; using Server.Network; @@ -7,7 +8,7 @@ using Server.Prompts; namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class BallotBox : AddonComponent { public static readonly int MaxTopicLines = 6; @@ -312,7 +313,7 @@ namespace Server.Items } } - [Serializable(0)] + [SerializationGenerator(0)] public partial class BallotBoxAddon : BaseAddon { public BallotBoxAddon() @@ -321,7 +322,7 @@ namespace Server.Items } } - [Serializable(0)] + [SerializationGenerator(0)] public partial class BallotBoxDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/BaseAddon.cs b/Projects/UOContent/Items/Addons/BaseAddon.cs index a0507e8cb..f7fbd61c7 100644 --- a/Projects/UOContent/Items/Addons/BaseAddon.cs +++ b/Projects/UOContent/Items/Addons/BaseAddon.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using ModernUO.Serialization; using Server.Multis; namespace Server.Items @@ -20,7 +21,7 @@ namespace Server.Items bool CouldFit(IPoint3D p, Map map); } - [Serializable(3, false)] + [SerializationGenerator(3, false)] public abstract partial class BaseAddon : Item, IChoppable, IAddon { [SerializableField(1, "private", "private")] diff --git a/Projects/UOContent/Items/Addons/BaseAddonContainer.cs b/Projects/UOContent/Items/Addons/BaseAddonContainer.cs index 976a6fc00..547c4900c 100644 --- a/Projects/UOContent/Items/Addons/BaseAddonContainer.cs +++ b/Projects/UOContent/Items/Addons/BaseAddonContainer.cs @@ -1,9 +1,10 @@ using System.Collections.Generic; +using ModernUO.Serialization; using Server.Multis; namespace Server.Items { - [Serializable(2, false)] + [SerializationGenerator(2, false)] public abstract partial class BaseAddonContainer : BaseContainer, IChoppable, IAddon { [SerializableField(0, setter: "private")] diff --git a/Projects/UOContent/Items/Addons/BaseAddonDeed.cs b/Projects/UOContent/Items/Addons/BaseAddonDeed.cs index 3313140fa..49977289b 100644 --- a/Projects/UOContent/Items/Addons/BaseAddonDeed.cs +++ b/Projects/UOContent/Items/Addons/BaseAddonDeed.cs @@ -1,10 +1,11 @@ +using ModernUO.Serialization; using Server.Multis; using Server.Spells; using Server.Targeting; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x14F0, 0x14EF)] public abstract partial class BaseAddonDeed : Item { diff --git a/Projects/UOContent/Items/Addons/BearRugs.cs b/Projects/UOContent/Items/Addons/BearRugs.cs index 20adc3297..d259305cd 100644 --- a/Projects/UOContent/Items/Addons/BearRugs.cs +++ b/Projects/UOContent/Items/Addons/BearRugs.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class BrownBearRugEastAddon : BaseAddon { [Constructible] @@ -20,7 +22,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new BrownBearRugEastDeed(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class BrownBearRugEastDeed : BaseAddonDeed { [Constructible] @@ -32,7 +34,7 @@ namespace Server.Items public override int LabelNumber => 1049397; // a brown bear rug deed facing east } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class BrownBearRugSouthAddon : BaseAddon { [Constructible] @@ -52,7 +54,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new BrownBearRugSouthDeed(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class BrownBearRugSouthDeed : BaseAddonDeed { [Constructible] @@ -64,7 +66,7 @@ namespace Server.Items public override int LabelNumber => 1049398; // a brown bear rug deed facing south } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class PolarBearRugEastAddon : BaseAddon { [Constructible] @@ -84,7 +86,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new PolarBearRugEastDeed(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class PolarBearRugEastDeed : BaseAddonDeed { [Constructible] @@ -96,7 +98,7 @@ namespace Server.Items public override int LabelNumber => 1049399; // a polar bear rug deed facing east } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class PolarBearRugSouthAddon : BaseAddon { [Constructible] @@ -116,7 +118,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new PolarBearRugSouthDeed(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class PolarBearRugSouthDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/BloodPentagram.cs b/Projects/UOContent/Items/Addons/BloodPentagram.cs index cbe6f1857..e6e6d2f04 100644 --- a/Projects/UOContent/Items/Addons/BloodPentagram.cs +++ b/Projects/UOContent/Items/Addons/BloodPentagram.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class BloodPentagram : BaseAddon { [Constructible] diff --git a/Projects/UOContent/Items/Addons/DartBoard.cs b/Projects/UOContent/Items/Addons/DartBoard.cs index 18333c337..71f973ae6 100644 --- a/Projects/UOContent/Items/Addons/DartBoard.cs +++ b/Projects/UOContent/Items/Addons/DartBoard.cs @@ -1,8 +1,9 @@ +using ModernUO.Serialization; using Server.Network; namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class DartBoard : AddonComponent { [Constructible] @@ -86,7 +87,7 @@ namespace Server.Items } } - [Serializable(0)] + [SerializationGenerator(0)] public partial class DartBoardEastAddon : BaseAddon { public DartBoardEastAddon() @@ -97,7 +98,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new DartBoardEastDeed(); } - [Serializable(0)] + [SerializationGenerator(0)] public partial class DartBoardEastDeed : BaseAddonDeed { [Constructible] @@ -110,7 +111,7 @@ namespace Server.Items public override int LabelNumber => 1044326; // dartboard (east) } - [Serializable(0)] + [SerializationGenerator(0)] public partial class DartBoardSouthAddon : BaseAddon { public DartBoardSouthAddon() @@ -121,7 +122,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new DartBoardSouthDeed(); } - [Serializable(0)] + [SerializationGenerator(0)] public partial class DartBoardSouthDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/ElvenBedEastAddon.cs b/Projects/UOContent/Items/Addons/ElvenBedEastAddon.cs index 69dd2c529..507282b2c 100644 --- a/Projects/UOContent/Items/Addons/ElvenBedEastAddon.cs +++ b/Projects/UOContent/Items/Addons/ElvenBedEastAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class ElvenBedEastAddon : BaseAddon { [Constructible] @@ -13,7 +15,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new ElvenBedEastDeed(); } - [Serializable(0)] + [SerializationGenerator(0)] public partial class ElvenBedEastDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/ElvenBedSouthAddon.cs b/Projects/UOContent/Items/Addons/ElvenBedSouthAddon.cs index 96dc0d99d..5f53debec 100644 --- a/Projects/UOContent/Items/Addons/ElvenBedSouthAddon.cs +++ b/Projects/UOContent/Items/Addons/ElvenBedSouthAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class ElvenBedSouthAddon : BaseAddon { [Constructible] @@ -13,7 +15,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new ElvenBedSouthDeed(); } - [Serializable(0)] + [SerializationGenerator(0)] public partial class ElvenBedSouthDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/ElvenDresserEastAddon.cs b/Projects/UOContent/Items/Addons/ElvenDresserEastAddon.cs index 1bf3bebd2..642021c39 100644 --- a/Projects/UOContent/Items/Addons/ElvenDresserEastAddon.cs +++ b/Projects/UOContent/Items/Addons/ElvenDresserEastAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class ElvenDresserEastAddon : BaseAddonContainer { [Constructible] @@ -15,7 +17,7 @@ namespace Server.Items public override int DefaultDropSound => 0x42; } - [Serializable(0)] + [SerializationGenerator(0)] public partial class ElvenDresserEastDeed : BaseAddonContainerDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/ElvenDresserSouthAddon.cs b/Projects/UOContent/Items/Addons/ElvenDresserSouthAddon.cs index c49be3673..9820186c7 100644 --- a/Projects/UOContent/Items/Addons/ElvenDresserSouthAddon.cs +++ b/Projects/UOContent/Items/Addons/ElvenDresserSouthAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class ElvenDresserSouthAddon : BaseAddonContainer { [Constructible] @@ -15,7 +17,7 @@ namespace Server.Items public override int DefaultDropSound => 0x42; } - [Serializable(0)] + [SerializationGenerator(0)] public partial class ElvenDresserSouthDeed : BaseAddonContainerDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/ElvenForgeAddon.cs b/Projects/UOContent/Items/Addons/ElvenForgeAddon.cs index 52dd5add9..a3ffc8be5 100644 --- a/Projects/UOContent/Items/Addons/ElvenForgeAddon.cs +++ b/Projects/UOContent/Items/Addons/ElvenForgeAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class ElvenForgeAddon : BaseAddon { [Constructible] @@ -13,7 +15,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new ElvenForgeDeed(); } - [Serializable(0)] + [SerializationGenerator(0)] public partial class ElvenForgeDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/ElvenLoveseatEastAddon.cs b/Projects/UOContent/Items/Addons/ElvenLoveseatEastAddon.cs index cbd01379c..04c6695dc 100644 --- a/Projects/UOContent/Items/Addons/ElvenLoveseatEastAddon.cs +++ b/Projects/UOContent/Items/Addons/ElvenLoveseatEastAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class ElvenLoveseatEastAddon : BaseAddon { [Constructible] @@ -13,7 +15,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new ElvenLoveseatEastDeed(); } - [Serializable(0)] + [SerializationGenerator(0)] public partial class ElvenLoveseatEastDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/ElvenLoveseatSouthAddon.cs b/Projects/UOContent/Items/Addons/ElvenLoveseatSouthAddon.cs index 879ca82ce..29b9056da 100644 --- a/Projects/UOContent/Items/Addons/ElvenLoveseatSouthAddon.cs +++ b/Projects/UOContent/Items/Addons/ElvenLoveseatSouthAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class ElvenLoveseatSouthAddon : BaseAddon { [Constructible] @@ -13,7 +15,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new ElvenLoveseatSouthDeed(); } - [Serializable(0)] + [SerializationGenerator(0)] public partial class ElvenLoveseatSouthDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/ElvenSpinningWheelEastAddon.cs b/Projects/UOContent/Items/Addons/ElvenSpinningWheelEastAddon.cs index fe27635e8..e6958aed2 100644 --- a/Projects/UOContent/Items/Addons/ElvenSpinningWheelEastAddon.cs +++ b/Projects/UOContent/Items/Addons/ElvenSpinningWheelEastAddon.cs @@ -1,4 +1,5 @@ using System; +using ModernUO.Serialization; namespace Server.Items { @@ -10,7 +11,7 @@ namespace Server.Items void BeginSpin(SpinCallback callback, Mobile from, int hue); } - [Serializable(0)] + [SerializationGenerator(0)] [TypeAlias("Server.Items.ElvenSpinningwheelEastAddon")] public partial class ElvenSpinningWheelEastAddon : BaseAddon, ISpinningWheel { @@ -99,7 +100,7 @@ namespace Server.Items } } - [Serializable(0)] + [SerializationGenerator(0)] [TypeAlias("Server.Items.ElvenSpinningwheelEastDeed")] public partial class ElvenSpinningWheelEastDeed : BaseAddonDeed { diff --git a/Projects/UOContent/Items/Addons/ElvenSpinningwheelSouthAddon.cs b/Projects/UOContent/Items/Addons/ElvenSpinningwheelSouthAddon.cs index e737c3d0f..8d99ba515 100644 --- a/Projects/UOContent/Items/Addons/ElvenSpinningwheelSouthAddon.cs +++ b/Projects/UOContent/Items/Addons/ElvenSpinningwheelSouthAddon.cs @@ -1,8 +1,9 @@ using System; +using ModernUO.Serialization; namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] [TypeAlias("Server.Items.ElvenSpinningwheelSouthAddon")] public partial class ElvenSpinningWheelSouthAddon : BaseAddon, ISpinningWheel { @@ -90,7 +91,7 @@ namespace Server.Items } } - [Serializable(0)] + [SerializationGenerator(0)] [TypeAlias("Server.Items.ElvenSpinningwheelSouthDeed")] public partial class ElvenSpinningWheelSouthDeed : BaseAddonDeed { diff --git a/Projects/UOContent/Items/Addons/ElvenStoveEastAddon.cs b/Projects/UOContent/Items/Addons/ElvenStoveEastAddon.cs index 687989ffa..cdd58cf90 100644 --- a/Projects/UOContent/Items/Addons/ElvenStoveEastAddon.cs +++ b/Projects/UOContent/Items/Addons/ElvenStoveEastAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class ElvenStoveEastAddon : BaseAddon { [Constructible] @@ -12,7 +14,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new ElvenStoveEastDeed(); } - [Serializable(0)] + [SerializationGenerator(0)] public partial class ElvenStoveEastDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/ElvenStoveSouthAddon.cs b/Projects/UOContent/Items/Addons/ElvenStoveSouthAddon.cs index d63db83fe..aa71d591b 100644 --- a/Projects/UOContent/Items/Addons/ElvenStoveSouthAddon.cs +++ b/Projects/UOContent/Items/Addons/ElvenStoveSouthAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class ElvenStoveSouthAddon : BaseAddon { [Constructible] @@ -12,7 +14,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new ElvenStoveSouthDeed(); } - [Serializable(0)] + [SerializationGenerator(0)] public partial class ElvenStoveSouthDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/ElvenWashbasinEastAddon.cs b/Projects/UOContent/Items/Addons/ElvenWashbasinEastAddon.cs index a47e6dbbb..986a19a3b 100644 --- a/Projects/UOContent/Items/Addons/ElvenWashbasinEastAddon.cs +++ b/Projects/UOContent/Items/Addons/ElvenWashbasinEastAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class ElvenWashBasinEastAddon : BaseAddonContainer { [Constructible] @@ -15,7 +17,7 @@ namespace Server.Items public override int DefaultDropSound => 0x0042; } - [Serializable(0)] + [SerializationGenerator(0)] public partial class ElvenWashBasinEastDeed : BaseAddonContainerDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/ElvenWashbasinSouthAddon.cs b/Projects/UOContent/Items/Addons/ElvenWashbasinSouthAddon.cs index a46b37fcc..1358fea17 100644 --- a/Projects/UOContent/Items/Addons/ElvenWashbasinSouthAddon.cs +++ b/Projects/UOContent/Items/Addons/ElvenWashbasinSouthAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class ElvenWashBasinSouthAddon : BaseAddonContainer { [Constructible] @@ -15,7 +17,7 @@ namespace Server.Items public override int DefaultDropSound => 0x0042; } - [Serializable(0)] + [SerializationGenerator(0)] public partial class ElvenWashBasinSouthDeed : BaseAddonContainerDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/FancyElvenTableEastAddon.cs b/Projects/UOContent/Items/Addons/FancyElvenTableEastAddon.cs index e31e67f22..6528ea581 100644 --- a/Projects/UOContent/Items/Addons/FancyElvenTableEastAddon.cs +++ b/Projects/UOContent/Items/Addons/FancyElvenTableEastAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class FancyElvenTableEastAddon : BaseAddon { [Constructible] @@ -14,7 +16,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new FancyElvenTableEastDeed(); } - [Serializable(0)] + [SerializationGenerator(0)] public partial class FancyElvenTableEastDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/FancyElvenTableSouthAddon.cs b/Projects/UOContent/Items/Addons/FancyElvenTableSouthAddon.cs index 7bed9dcf7..72886fcca 100644 --- a/Projects/UOContent/Items/Addons/FancyElvenTableSouthAddon.cs +++ b/Projects/UOContent/Items/Addons/FancyElvenTableSouthAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class FancyElvenTableSouthAddon : BaseAddon { [Constructible] @@ -14,7 +16,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new FancyElvenTableSouthDeed(); } - [Serializable(0)] + [SerializationGenerator(0)] public partial class FancyElvenTableSouthDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/FireColumnAddon.cs b/Projects/UOContent/Items/Addons/FireColumnAddon.cs index c3672ea98..e312066ca 100644 --- a/Projects/UOContent/Items/Addons/FireColumnAddon.cs +++ b/Projects/UOContent/Items/Addons/FireColumnAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class FireColumnAddon : BaseAddon { [Constructible] diff --git a/Projects/UOContent/Items/Addons/FlourMillEastAddon.cs b/Projects/UOContent/Items/Addons/FlourMillEastAddon.cs index b729fd392..1fd8c3072 100644 --- a/Projects/UOContent/Items/Addons/FlourMillEastAddon.cs +++ b/Projects/UOContent/Items/Addons/FlourMillEastAddon.cs @@ -1,4 +1,5 @@ using System; +using ModernUO.Serialization; using Server.Network; namespace Server.Items @@ -16,7 +17,7 @@ namespace Server.Items Working } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class FlourMillEastAddon : BaseAddon, IFlourMill { private static readonly int[][] m_StageTable = @@ -171,7 +172,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class FlourMillEastDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/FlourMillSouthAddon.cs b/Projects/UOContent/Items/Addons/FlourMillSouthAddon.cs index f5bb4ab63..cfd7c7c72 100644 --- a/Projects/UOContent/Items/Addons/FlourMillSouthAddon.cs +++ b/Projects/UOContent/Items/Addons/FlourMillSouthAddon.cs @@ -1,9 +1,10 @@ using System; +using ModernUO.Serialization; using Server.Network; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class FlourMillSouthAddon : BaseAddon, IFlourMill { private static readonly int[][] m_StageTable = @@ -159,7 +160,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class FlourMillSouthDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/FlowerTapestries.cs b/Projects/UOContent/Items/Addons/FlowerTapestries.cs index 29b655295..a67b8ea15 100644 --- a/Projects/UOContent/Items/Addons/FlowerTapestries.cs +++ b/Projects/UOContent/Items/Addons/FlowerTapestries.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LightFlowerTapestryEastAddon : BaseAddon { [Constructible] @@ -13,7 +15,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new LightFlowerTapestryEastDeed(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LightFlowerTapestryEastDeed : BaseAddonDeed { [Constructible] @@ -25,7 +27,7 @@ namespace Server.Items public override int LabelNumber => 1049393; // a flower tapestry deed facing east } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LightFlowerTapestrySouthAddon : BaseAddon { [Constructible] @@ -38,7 +40,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new LightFlowerTapestrySouthDeed(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LightFlowerTapestrySouthDeed : BaseAddonDeed { [Constructible] @@ -50,7 +52,7 @@ namespace Server.Items public override int LabelNumber => 1049394; // a flower tapestry deed facing south } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class DarkFlowerTapestryEastAddon : BaseAddon { [Constructible] @@ -63,7 +65,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new DarkFlowerTapestryEastDeed(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class DarkFlowerTapestryEastDeed : BaseAddonDeed { [Constructible] @@ -75,7 +77,7 @@ namespace Server.Items public override int LabelNumber => 1049395; // a dark flower tapestry deed facing east } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class DarkFlowerTapestrySouthAddon : BaseAddon { [Constructible] @@ -88,7 +90,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new DarkFlowerTapestrySouthDeed(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class DarkFlowerTapestrySouthDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/GiantWebs.cs b/Projects/UOContent/Items/Addons/GiantWebs.cs index bf0160eb8..d766c51e6 100644 --- a/Projects/UOContent/Items/Addons/GiantWebs.cs +++ b/Projects/UOContent/Items/Addons/GiantWebs.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class GiantWeb1 : BaseAddon { [Constructible] @@ -21,7 +23,7 @@ namespace Server.Items } } - [Serializable(0)] + [SerializationGenerator(0)] public partial class GiantWeb2 : BaseAddon { [Constructible] @@ -42,7 +44,7 @@ namespace Server.Items } } - [Serializable(0)] + [SerializationGenerator(0)] public partial class GiantWeb3 : BaseAddon { [Constructible] @@ -63,7 +65,7 @@ namespace Server.Items } } - [Serializable(0)] + [SerializationGenerator(0)] public partial class GiantWeb4 : BaseAddon { [Constructible] @@ -84,7 +86,7 @@ namespace Server.Items } } - [Serializable(0)] + [SerializationGenerator(0)] public partial class GiantWeb5 : BaseAddon { [Constructible] @@ -105,7 +107,7 @@ namespace Server.Items } } - [Serializable(0)] + [SerializationGenerator(0)] public partial class GiantWeb6 : BaseAddon { [Constructible] diff --git a/Projects/UOContent/Items/Addons/GozaMats.cs b/Projects/UOContent/Items/Addons/GozaMats.cs index 3127f367a..6d199c110 100644 --- a/Projects/UOContent/Items/Addons/GozaMats.cs +++ b/Projects/UOContent/Items/Addons/GozaMats.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class GozaMatEastAddon : BaseAddon { [Constructible] @@ -16,7 +18,7 @@ namespace Server.Items public override bool RetainDeedHue => true; } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class GozaMatEastDeed : BaseAddonDeed { [Constructible] @@ -28,7 +30,7 @@ namespace Server.Items public override int LabelNumber => 1030404; // goza (east) } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class GozaMatSouthAddon : BaseAddon { [Constructible] @@ -44,7 +46,7 @@ namespace Server.Items public override bool RetainDeedHue => true; } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class GozaMatSouthDeed : BaseAddonDeed { [Constructible] @@ -56,7 +58,7 @@ namespace Server.Items public override int LabelNumber => 1030405; // goza (south) } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class SquareGozaMatEastAddon : BaseAddon { [Constructible] @@ -72,7 +74,7 @@ namespace Server.Items public override bool RetainDeedHue => true; } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class SquareGozaMatEastDeed : BaseAddonDeed { [Constructible] @@ -84,7 +86,7 @@ namespace Server.Items public override int LabelNumber => 1030407; // square goza (east) } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class SquareGozaMatSouthAddon : BaseAddon { [Constructible] @@ -99,7 +101,7 @@ namespace Server.Items public override bool RetainDeedHue => true; } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class SquareGozaMatSouthDeed : BaseAddonDeed { [Constructible] @@ -111,7 +113,7 @@ namespace Server.Items public override int LabelNumber => 1030406; // square goza (south) } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class BrocadeGozaMatEastAddon : BaseAddon { [Constructible] @@ -127,7 +129,7 @@ namespace Server.Items public override bool RetainDeedHue => true; } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class BrocadeGozaMatEastDeed : BaseAddonDeed { [Constructible] @@ -139,7 +141,7 @@ namespace Server.Items public override int LabelNumber => 1030408; // brocade goza (east) } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class BrocadeGozaMatSouthAddon : BaseAddon { [Constructible] @@ -155,7 +157,7 @@ namespace Server.Items public override bool RetainDeedHue => true; } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class BrocadeGozaMatSouthDeed : BaseAddonDeed { [Constructible] @@ -167,7 +169,7 @@ namespace Server.Items public override int LabelNumber => 1030409; // brocade goza (south) } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class BrocadeSquareGozaMatEastAddon : BaseAddon { [Constructible] @@ -182,7 +184,7 @@ namespace Server.Items public override bool RetainDeedHue => true; } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class BrocadeSquareGozaMatEastDeed : BaseAddonDeed { [Constructible] @@ -194,7 +196,7 @@ namespace Server.Items public override int LabelNumber => 1030411; // brocade square goza (east) } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class BrocadeSquareGozaMatSouthAddon : BaseAddon { [Constructible] @@ -209,7 +211,7 @@ namespace Server.Items public override bool RetainDeedHue => true; } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class BrocadeSquareGozaMatSouthDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/GrayBrickFireplaceEastAddon.cs b/Projects/UOContent/Items/Addons/GrayBrickFireplaceEastAddon.cs index 2567bccc4..f8500eabf 100644 --- a/Projects/UOContent/Items/Addons/GrayBrickFireplaceEastAddon.cs +++ b/Projects/UOContent/Items/Addons/GrayBrickFireplaceEastAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class GrayBrickFireplaceEastAddon : BaseAddon { [Constructible] @@ -13,7 +15,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new GrayBrickFireplaceEastDeed(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class GrayBrickFireplaceEastDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/GrayBrickFireplaceSouthAddon.cs b/Projects/UOContent/Items/Addons/GrayBrickFireplaceSouthAddon.cs index 50fdee87e..792f50cb0 100644 --- a/Projects/UOContent/Items/Addons/GrayBrickFireplaceSouthAddon.cs +++ b/Projects/UOContent/Items/Addons/GrayBrickFireplaceSouthAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class GrayBrickFireplaceSouthAddon : BaseAddon { [Constructible] @@ -13,7 +15,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new GrayBrickFireplaceSouthDeed(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class GrayBrickFireplaceSouthDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/JackOLantern.cs b/Projects/UOContent/Items/Addons/JackOLantern.cs index 0ff84fb93..c2f13b753 100644 --- a/Projects/UOContent/Items/Addons/JackOLantern.cs +++ b/Projects/UOContent/Items/Addons/JackOLantern.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class JackOLantern : BaseAddon { [Constructible] diff --git a/Projects/UOContent/Items/Addons/LargeBedEastAddon.cs b/Projects/UOContent/Items/Addons/LargeBedEastAddon.cs index e77a27d52..4fc2b7ad3 100644 --- a/Projects/UOContent/Items/Addons/LargeBedEastAddon.cs +++ b/Projects/UOContent/Items/Addons/LargeBedEastAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LargeBedEastAddon : BaseAddon { [Constructible] diff --git a/Projects/UOContent/Items/Addons/LargeBedSouthAddon.cs b/Projects/UOContent/Items/Addons/LargeBedSouthAddon.cs index 328702270..b7c48baf5 100644 --- a/Projects/UOContent/Items/Addons/LargeBedSouthAddon.cs +++ b/Projects/UOContent/Items/Addons/LargeBedSouthAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LargeBedSouthAddon : BaseAddon { [Constructible] @@ -15,7 +17,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new LargeBedSouthDeed(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LargeBedSouthDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/LargeForgeEastAddon.cs b/Projects/UOContent/Items/Addons/LargeForgeEastAddon.cs index 197002acc..c3ebe12a6 100644 --- a/Projects/UOContent/Items/Addons/LargeForgeEastAddon.cs +++ b/Projects/UOContent/Items/Addons/LargeForgeEastAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LargeForgeEastAddon : BaseAddon { [Constructible] @@ -15,7 +17,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new LargeForgeEastDeed(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LargeForgeEastDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/LargeForgeSouthAddon.cs b/Projects/UOContent/Items/Addons/LargeForgeSouthAddon.cs index 1c9885c56..761c804dd 100644 --- a/Projects/UOContent/Items/Addons/LargeForgeSouthAddon.cs +++ b/Projects/UOContent/Items/Addons/LargeForgeSouthAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LargeForgeSouthAddon : BaseAddon { [Constructible] @@ -15,7 +17,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new LargeForgeSouthDeed(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LargeForgeSouthDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/LargeStoneTableEastAddon.cs b/Projects/UOContent/Items/Addons/LargeStoneTableEastAddon.cs index 20f652234..67568d247 100644 --- a/Projects/UOContent/Items/Addons/LargeStoneTableEastAddon.cs +++ b/Projects/UOContent/Items/Addons/LargeStoneTableEastAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LargeStoneTableEastAddon : BaseAddon { [Constructible] @@ -16,7 +18,7 @@ namespace Server.Items public override bool RetainDeedHue => true; } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LargeStoneTableEastDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/LargeStoneTableSouthAddon.cs b/Projects/UOContent/Items/Addons/LargeStoneTableSouthAddon.cs index 79ae3fc18..78e5f0e91 100644 --- a/Projects/UOContent/Items/Addons/LargeStoneTableSouthAddon.cs +++ b/Projects/UOContent/Items/Addons/LargeStoneTableSouthAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LargeStoneTableSouthAddon : BaseAddon { [Constructible] @@ -17,7 +19,7 @@ namespace Server.Items public override bool RetainDeedHue => true; } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LargeStoneTableSouthDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/LoomEastAddon.cs b/Projects/UOContent/Items/Addons/LoomEastAddon.cs index 034cdbf1c..db3af2a52 100644 --- a/Projects/UOContent/Items/Addons/LoomEastAddon.cs +++ b/Projects/UOContent/Items/Addons/LoomEastAddon.cs @@ -1,3 +1,5 @@ +using ModernUO.Serialization; + namespace Server.Items { public interface ILoom @@ -5,7 +7,7 @@ namespace Server.Items int Phase { get; set; } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LoomEastAddon : BaseAddon, ILoom { [SerializableField(0)] @@ -21,7 +23,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new LoomEastDeed(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LoomEastDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/LoomSouthAddon.cs b/Projects/UOContent/Items/Addons/LoomSouthAddon.cs index 596ff2170..9ec8f5595 100644 --- a/Projects/UOContent/Items/Addons/LoomSouthAddon.cs +++ b/Projects/UOContent/Items/Addons/LoomSouthAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LoomSouthAddon : BaseAddon, ILoom { [SerializableField(0)] @@ -16,7 +18,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new LoomSouthDeed(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LoomSouthDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/MediumStoneTableEastAddon.cs b/Projects/UOContent/Items/Addons/MediumStoneTableEastAddon.cs index 91f1807f9..dd20cdde4 100644 --- a/Projects/UOContent/Items/Addons/MediumStoneTableEastAddon.cs +++ b/Projects/UOContent/Items/Addons/MediumStoneTableEastAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class MediumStoneTableEastAddon : BaseAddon { [Constructible] @@ -16,7 +18,7 @@ namespace Server.Items public override bool RetainDeedHue => true; } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class MediumStoneTableEastDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/MediumStoneTableSouthAddon.cs b/Projects/UOContent/Items/Addons/MediumStoneTableSouthAddon.cs index 4eb79450b..09e4f4518 100644 --- a/Projects/UOContent/Items/Addons/MediumStoneTableSouthAddon.cs +++ b/Projects/UOContent/Items/Addons/MediumStoneTableSouthAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class MediumStoneTableSouthAddon : BaseAddon { [Constructible] @@ -16,7 +18,7 @@ namespace Server.Items public override bool RetainDeedHue => true; } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class MediumStoneTableSouthDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/OrnateElvenChestEastAddon.cs b/Projects/UOContent/Items/Addons/OrnateElvenChestEastAddon.cs index f936d0da7..066ca2870 100644 --- a/Projects/UOContent/Items/Addons/OrnateElvenChestEastAddon.cs +++ b/Projects/UOContent/Items/Addons/OrnateElvenChestEastAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class OrnateElvenChestEastAddon : BaseAddonContainer { [Constructible] @@ -15,7 +17,7 @@ namespace Server.Items public override int DefaultDropSound => 0x42; } - [Serializable(0)] + [SerializationGenerator(0)] public partial class OrnateElvenChestEastDeed : BaseAddonContainerDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/OrnateElvenChestSouthAddon.cs b/Projects/UOContent/Items/Addons/OrnateElvenChestSouthAddon.cs index 109433111..cc0dc3f85 100644 --- a/Projects/UOContent/Items/Addons/OrnateElvenChestSouthAddon.cs +++ b/Projects/UOContent/Items/Addons/OrnateElvenChestSouthAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class OrnateElvenChestSouthAddon : BaseAddonContainer { [Constructible] @@ -15,7 +17,7 @@ namespace Server.Items public override int DefaultDropSound => 0x42; } - [Serializable(0)] + [SerializationGenerator(0)] public partial class OrnateElvenChestSouthDeed : BaseAddonContainerDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/OrnateElvenTableEastAddon.cs b/Projects/UOContent/Items/Addons/OrnateElvenTableEastAddon.cs index 8328eb52f..0401e04bd 100644 --- a/Projects/UOContent/Items/Addons/OrnateElvenTableEastAddon.cs +++ b/Projects/UOContent/Items/Addons/OrnateElvenTableEastAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class OrnateElvenTableEastAddon : BaseAddon { [Constructible] @@ -14,7 +16,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new OrnateElvenTableEastDeed(); } - [Serializable(0)] + [SerializationGenerator(0)] public partial class OrnateElvenTableEastDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/OrnateElvenTableSouthAddon.cs b/Projects/UOContent/Items/Addons/OrnateElvenTableSouthAddon.cs index 04f3553a4..14f65f529 100644 --- a/Projects/UOContent/Items/Addons/OrnateElvenTableSouthAddon.cs +++ b/Projects/UOContent/Items/Addons/OrnateElvenTableSouthAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class OrnateElvenTableSouthAddon : BaseAddon { [Constructible] @@ -14,7 +16,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new OrnateElvenTableSouthDeed(); } - [Serializable(0)] + [SerializationGenerator(0)] public partial class OrnateElvenTableSouthDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/ParrotPerchAddon.cs b/Projects/UOContent/Items/Addons/ParrotPerchAddon.cs index 94278a0a8..5629d8c36 100644 --- a/Projects/UOContent/Items/Addons/ParrotPerchAddon.cs +++ b/Projects/UOContent/Items/Addons/ParrotPerchAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class ParrotPerchAddon : BaseAddon { [Constructible] @@ -12,7 +14,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new ParrotPerchDeed(); } - [Serializable(0)] + [SerializationGenerator(0)] public partial class ParrotPerchDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/PentagramAddon.cs b/Projects/UOContent/Items/Addons/PentagramAddon.cs index 7190bb289..99777409d 100644 --- a/Projects/UOContent/Items/Addons/PentagramAddon.cs +++ b/Projects/UOContent/Items/Addons/PentagramAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class PentagramAddon : BaseAddon { [Constructible] @@ -20,7 +22,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new PentagramDeed(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class PentagramDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/PickpocketDips.cs b/Projects/UOContent/Items/Addons/PickpocketDips.cs index aa20d1ef6..c990ff7d4 100644 --- a/Projects/UOContent/Items/Addons/PickpocketDips.cs +++ b/Projects/UOContent/Items/Addons/PickpocketDips.cs @@ -1,8 +1,9 @@ using System; +using ModernUO.Serialization; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1EC0, 0x1EC3)] public partial class PickpocketDip : AddonComponent { @@ -118,7 +119,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class PickpocketDipEastAddon : BaseAddon { [Constructible] @@ -128,7 +129,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class PickpocketDipEastDeed : BaseAddonDeed { [Constructible] @@ -140,7 +141,7 @@ namespace Server.Items public override int LabelNumber => 1044337; // pickpocket dip (east) } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class PickpocketDipSouthAddon : BaseAddon { [Constructible] @@ -152,7 +153,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new PickpocketDipSouthDeed(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class PickpocketDipSouthDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/PyramidAddon.cs b/Projects/UOContent/Items/Addons/PyramidAddon.cs index 4133f9c86..f717d576d 100644 --- a/Projects/UOContent/Items/Addons/PyramidAddon.cs +++ b/Projects/UOContent/Items/Addons/PyramidAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class PyramidAddon : BaseAddon { [Constructible] diff --git a/Projects/UOContent/Items/Addons/RejuvinationAnkhs.cs b/Projects/UOContent/Items/Addons/RejuvinationAnkhs.cs index e8e059cf1..fa6b00c95 100644 --- a/Projects/UOContent/Items/Addons/RejuvinationAnkhs.cs +++ b/Projects/UOContent/Items/Addons/RejuvinationAnkhs.cs @@ -1,8 +1,9 @@ using System; +using ModernUO.Serialization; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class RejuvinationAddonComponent : AddonComponent { public RejuvinationAddonComponent(int itemID) : base(itemID) @@ -51,7 +52,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public abstract partial class BaseRejuvinationAnkh : BaseAddon { private DateTime m_NextMessage; @@ -79,7 +80,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class RejuvinationAnkhWest : BaseRejuvinationAnkh { [Constructible] @@ -90,7 +91,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class RejuvinationAnkhNorth : BaseRejuvinationAnkh { [Constructible] diff --git a/Projects/UOContent/Items/Addons/SHTeleporter.cs b/Projects/UOContent/Items/Addons/SHTeleporter.cs index cdca627cc..7c56698dd 100644 --- a/Projects/UOContent/Items/Addons/SHTeleporter.cs +++ b/Projects/UOContent/Items/Addons/SHTeleporter.cs @@ -1,9 +1,10 @@ using System.Linq; +using ModernUO.Serialization; using Server.Mobiles; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class SHTeleComponent : AddonComponent { private bool _active; @@ -105,7 +106,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class SHTeleporter : BaseAddon { private bool m_Changing; diff --git a/Projects/UOContent/Items/Addons/SandstoneFireplaceEastAddon.cs b/Projects/UOContent/Items/Addons/SandstoneFireplaceEastAddon.cs index 0c692b860..cdd44ad82 100644 --- a/Projects/UOContent/Items/Addons/SandstoneFireplaceEastAddon.cs +++ b/Projects/UOContent/Items/Addons/SandstoneFireplaceEastAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class SandstoneFireplaceEastAddon : BaseAddon { [Constructible] @@ -13,7 +15,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new SandstoneFireplaceEastDeed(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class SandstoneFireplaceEastDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/SandstoneFireplaceSouthAddon.cs b/Projects/UOContent/Items/Addons/SandstoneFireplaceSouthAddon.cs index 72cc30e26..888b7baa6 100644 --- a/Projects/UOContent/Items/Addons/SandstoneFireplaceSouthAddon.cs +++ b/Projects/UOContent/Items/Addons/SandstoneFireplaceSouthAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class SandstoneFireplaceSouthAddon : BaseAddon { [Constructible] @@ -13,7 +15,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new SandstoneFireplaceSouthDeed(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class SandstoneFireplaceSouthDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/SandstoneFountainAddon.cs b/Projects/UOContent/Items/Addons/SandstoneFountainAddon.cs index 34b764788..38189257d 100644 --- a/Projects/UOContent/Items/Addons/SandstoneFountainAddon.cs +++ b/Projects/UOContent/Items/Addons/SandstoneFountainAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class SandstoneFountainAddon : BaseAddon { [Constructible] diff --git a/Projects/UOContent/Items/Addons/SerpentPillarAddon.cs b/Projects/UOContent/Items/Addons/SerpentPillarAddon.cs index 7170a56e3..da1c4f065 100644 --- a/Projects/UOContent/Items/Addons/SerpentPillarAddon.cs +++ b/Projects/UOContent/Items/Addons/SerpentPillarAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class SerpentPillarAddon : BaseAddon { [Constructible] diff --git a/Projects/UOContent/Items/Addons/ShrineOfWisdomAddon.cs b/Projects/UOContent/Items/Addons/ShrineOfWisdomAddon.cs index 81703f6de..5f68ef9bd 100644 --- a/Projects/UOContent/Items/Addons/ShrineOfWisdomAddon.cs +++ b/Projects/UOContent/Items/Addons/ShrineOfWisdomAddon.cs @@ -1,8 +1,9 @@ +using ModernUO.Serialization; using Server.Engines.Craft; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class ShrineOfWisdomAddon : BaseAddon { [Constructible] @@ -17,7 +18,7 @@ namespace Server.Items } [Forge] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class ShrineOfWisdomComponent : AddonComponent { [Constructible] diff --git a/Projects/UOContent/Items/Addons/SkullPileAddon.cs b/Projects/UOContent/Items/Addons/SkullPileAddon.cs index aa07f9fb2..732a01ffa 100644 --- a/Projects/UOContent/Items/Addons/SkullPileAddon.cs +++ b/Projects/UOContent/Items/Addons/SkullPileAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class SkullPileAddon : BaseAddon { [Constructible] diff --git a/Projects/UOContent/Items/Addons/SmallBedEastAddon.cs b/Projects/UOContent/Items/Addons/SmallBedEastAddon.cs index c0adb5eaf..0474f0684 100644 --- a/Projects/UOContent/Items/Addons/SmallBedEastAddon.cs +++ b/Projects/UOContent/Items/Addons/SmallBedEastAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class SmallBedEastAddon : BaseAddon { [Constructible] @@ -13,7 +15,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new SmallBedEastDeed(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class SmallBedEastDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/SmallBedSouthAddon.cs b/Projects/UOContent/Items/Addons/SmallBedSouthAddon.cs index c133bfbb1..b53288984 100644 --- a/Projects/UOContent/Items/Addons/SmallBedSouthAddon.cs +++ b/Projects/UOContent/Items/Addons/SmallBedSouthAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class SmallBedSouthAddon : BaseAddon { [Constructible] @@ -13,7 +15,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new SmallBedSouthDeed(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class SmallBedSouthDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/SmallForgeAddon.cs b/Projects/UOContent/Items/Addons/SmallForgeAddon.cs index ebf4ae75a..ad9aedd6a 100644 --- a/Projects/UOContent/Items/Addons/SmallForgeAddon.cs +++ b/Projects/UOContent/Items/Addons/SmallForgeAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class SmallForgeAddon : BaseAddon { [Constructible] @@ -12,7 +14,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new SmallForgeDeed(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class SmallForgeDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/SolenAntHole.cs b/Projects/UOContent/Items/Addons/SolenAntHole.cs index 00209f6bc..9cd1a469f 100644 --- a/Projects/UOContent/Items/Addons/SolenAntHole.cs +++ b/Projects/UOContent/Items/Addons/SolenAntHole.cs @@ -1,11 +1,12 @@ using System.Collections.Generic; +using ModernUO.Serialization; using Server.Mobiles; using Server.Network; using Server.Spells; namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class SolenAntHoleComponent : AddonComponent { public SolenAntHoleComponent(int itemID) : base(itemID) @@ -36,7 +37,7 @@ namespace Server.Items } } - [Serializable(1)] + [SerializationGenerator(1)] public partial class SolenAntHole : BaseAddon { [SerializableField(0, getter: "private", setter: "private")] diff --git a/Projects/UOContent/Items/Addons/SpinningwheelEastAddon.cs b/Projects/UOContent/Items/Addons/SpinningwheelEastAddon.cs index 7f3803ae1..9cdb98041 100644 --- a/Projects/UOContent/Items/Addons/SpinningwheelEastAddon.cs +++ b/Projects/UOContent/Items/Addons/SpinningwheelEastAddon.cs @@ -1,8 +1,9 @@ using System; +using ModernUO.Serialization; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [TypeAlias("Server.Items.SpinningwheelEastAddon")] public partial class SpinningWheelEastAddon : BaseAddon, ISpinningWheel { @@ -97,7 +98,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] [TypeAlias("Server.Items.SpinningwheelEastDeed")] public partial class SpinningWheelEastDeed : BaseAddonDeed { diff --git a/Projects/UOContent/Items/Addons/SpinningwheelSouthAddon.cs b/Projects/UOContent/Items/Addons/SpinningwheelSouthAddon.cs index 062e7eccf..6ee83298e 100644 --- a/Projects/UOContent/Items/Addons/SpinningwheelSouthAddon.cs +++ b/Projects/UOContent/Items/Addons/SpinningwheelSouthAddon.cs @@ -1,8 +1,9 @@ using System; +using ModernUO.Serialization; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [TypeAlias("Server.Items.SpinningwheelSouthAddon")] public partial class SpinningWheelSouthAddon : BaseAddon, ISpinningWheel { @@ -97,7 +98,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] [TypeAlias("Server.Items.SpinningwheelSouthDeed")] public partial class SpinningWheelSouthDeed : BaseAddonDeed { diff --git a/Projects/UOContent/Items/Addons/SquirrelStatueEastAddon.cs b/Projects/UOContent/Items/Addons/SquirrelStatueEastAddon.cs index f81c70973..19f958d99 100644 --- a/Projects/UOContent/Items/Addons/SquirrelStatueEastAddon.cs +++ b/Projects/UOContent/Items/Addons/SquirrelStatueEastAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class SquirrelStatueEastAddon : BaseAddon { [Constructible] @@ -12,7 +14,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new SquirrelStatueEastDeed(); } - [Serializable(0)] + [SerializationGenerator(0)] public partial class SquirrelStatueEastDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/SquirrelStatueSouthAddon.cs b/Projects/UOContent/Items/Addons/SquirrelStatueSouthAddon.cs index 3429b1404..cacef3870 100644 --- a/Projects/UOContent/Items/Addons/SquirrelStatueSouthAddon.cs +++ b/Projects/UOContent/Items/Addons/SquirrelStatueSouthAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class SquirrelStatueSouthAddon : BaseAddon { [Constructible] @@ -12,7 +14,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new SquirrelStatueSouthDeed(); } - [Serializable(0)] + [SerializationGenerator(0)] public partial class SquirrelStatueSouthDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/StoneFireplaceEastAddon.cs b/Projects/UOContent/Items/Addons/StoneFireplaceEastAddon.cs index e4b7284ee..363227d55 100644 --- a/Projects/UOContent/Items/Addons/StoneFireplaceEastAddon.cs +++ b/Projects/UOContent/Items/Addons/StoneFireplaceEastAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class StoneFireplaceEastAddon : BaseAddon { [Constructible] @@ -13,7 +15,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new StoneFireplaceEastDeed(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class StoneFireplaceEastDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/StoneFireplaceSouthAddon.cs b/Projects/UOContent/Items/Addons/StoneFireplaceSouthAddon.cs index 7b10c6972..1116ac86b 100644 --- a/Projects/UOContent/Items/Addons/StoneFireplaceSouthAddon.cs +++ b/Projects/UOContent/Items/Addons/StoneFireplaceSouthAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class StoneFireplaceSouthAddon : BaseAddon { [Constructible] @@ -13,7 +15,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new StoneFireplaceSouthDeed(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class StoneFireplaceSouthDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/StoneFountainAddon.cs b/Projects/UOContent/Items/Addons/StoneFountainAddon.cs index f4307c4c7..31189f654 100644 --- a/Projects/UOContent/Items/Addons/StoneFountainAddon.cs +++ b/Projects/UOContent/Items/Addons/StoneFountainAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class StoneFountainAddon : BaseAddon { [Constructible] diff --git a/Projects/UOContent/Items/Addons/StoneOvenEastAddon.cs b/Projects/UOContent/Items/Addons/StoneOvenEastAddon.cs index b160916da..06378063a 100644 --- a/Projects/UOContent/Items/Addons/StoneOvenEastAddon.cs +++ b/Projects/UOContent/Items/Addons/StoneOvenEastAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class StoneOvenEastAddon : BaseAddon { [Constructible] @@ -13,7 +15,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new StoneOvenEastDeed(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class StoneOvenEastDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/StoneOvenSouthAddon.cs b/Projects/UOContent/Items/Addons/StoneOvenSouthAddon.cs index 5f54e0f1e..afe43d098 100644 --- a/Projects/UOContent/Items/Addons/StoneOvenSouthAddon.cs +++ b/Projects/UOContent/Items/Addons/StoneOvenSouthAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class StoneOvenSouthAddon : BaseAddon { [Constructible] @@ -13,7 +15,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new StoneOvenSouthDeed(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class StoneOvenSouthDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/StretchedHides.cs b/Projects/UOContent/Items/Addons/StretchedHides.cs index e6a8f9aff..6911e1324 100644 --- a/Projects/UOContent/Items/Addons/StretchedHides.cs +++ b/Projects/UOContent/Items/Addons/StretchedHides.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class SmallStretchedHideEastAddon : BaseAddon { [Constructible] @@ -12,7 +14,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new SmallStretchedHideEastDeed(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class SmallStretchedHideEastDeed : BaseAddonDeed { [Constructible] @@ -24,7 +26,7 @@ namespace Server.Items public override int LabelNumber => 1049401; // a small stretched hide deed facing east } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class SmallStretchedHideSouthAddon : BaseAddon { [Constructible] @@ -36,7 +38,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new SmallStretchedHideSouthDeed(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class SmallStretchedHideSouthDeed : BaseAddonDeed { [Constructible] @@ -48,7 +50,7 @@ namespace Server.Items public override int LabelNumber => 1049402; // a small stretched hide deed facing south } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class MediumStretchedHideEastAddon : BaseAddon { [Constructible] @@ -60,7 +62,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new MediumStretchedHideEastDeed(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class MediumStretchedHideEastDeed : BaseAddonDeed { [Constructible] @@ -72,7 +74,7 @@ namespace Server.Items public override int LabelNumber => 1049403; // a medium stretched hide deed facing east } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class MediumStretchedHideSouthAddon : BaseAddon { [Constructible] @@ -84,7 +86,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new MediumStretchedHideSouthDeed(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class MediumStretchedHideSouthDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/TallElvenBedEastAddon.cs b/Projects/UOContent/Items/Addons/TallElvenBedEastAddon.cs index c4a26ad76..74cb13a78 100644 --- a/Projects/UOContent/Items/Addons/TallElvenBedEastAddon.cs +++ b/Projects/UOContent/Items/Addons/TallElvenBedEastAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class TallElvenBedEastAddon : BaseAddon { [Constructible] @@ -15,7 +17,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new TallElvenBedEastDeed(); } - [Serializable(0)] + [SerializationGenerator(0)] public partial class TallElvenBedEastDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/TallElvenBedSouthAddon.cs b/Projects/UOContent/Items/Addons/TallElvenBedSouthAddon.cs index 9b319957c..85cf51b48 100644 --- a/Projects/UOContent/Items/Addons/TallElvenBedSouthAddon.cs +++ b/Projects/UOContent/Items/Addons/TallElvenBedSouthAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class TallElvenBedSouthAddon : BaseAddon { [Constructible] @@ -15,7 +17,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new TallElvenBedSouthDeed(); } - [Serializable(0)] + [SerializationGenerator(0)] public partial class TallElvenBedSouthDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/Telescope.cs b/Projects/UOContent/Items/Addons/Telescope.cs index 0fe081fca..ec5c0711b 100644 --- a/Projects/UOContent/Items/Addons/Telescope.cs +++ b/Projects/UOContent/Items/Addons/Telescope.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Telescope : BaseAddon { [Constructible] diff --git a/Projects/UOContent/Items/Addons/TrainingDummies.cs b/Projects/UOContent/Items/Addons/TrainingDummies.cs index 760b1a8a5..61f81dc1a 100644 --- a/Projects/UOContent/Items/Addons/TrainingDummies.cs +++ b/Projects/UOContent/Items/Addons/TrainingDummies.cs @@ -1,8 +1,9 @@ using System; +using ModernUO.Serialization; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1070, 0x1074)] public partial class TrainingDummy : AddonComponent { @@ -131,7 +132,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class TrainingDummyEastAddon : BaseAddon { [Constructible] @@ -143,7 +144,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new TrainingDummyEastDeed(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class TrainingDummyEastDeed : BaseAddonDeed { [Constructible] @@ -155,7 +156,7 @@ namespace Server.Items public override int LabelNumber => 1044335; // training dummy (east) } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class TrainingDummySouthAddon : BaseAddon { [Constructible] @@ -167,7 +168,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new TrainingDummySouthDeed(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class TrainingDummySouthDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/WarriorStatueEastAddon.cs b/Projects/UOContent/Items/Addons/WarriorStatueEastAddon.cs index a33b062ed..24d178904 100644 --- a/Projects/UOContent/Items/Addons/WarriorStatueEastAddon.cs +++ b/Projects/UOContent/Items/Addons/WarriorStatueEastAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class WarriorStatueEastAddon : BaseAddon { [Constructible] @@ -12,7 +14,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new WarriorStatueEastDeed(); } - [Serializable(0)] + [SerializationGenerator(0)] public partial class WarriorStatueEastDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/WarriorStatueSouthAddon.cs b/Projects/UOContent/Items/Addons/WarriorStatueSouthAddon.cs index 8c24908c7..d89ea386b 100644 --- a/Projects/UOContent/Items/Addons/WarriorStatueSouthAddon.cs +++ b/Projects/UOContent/Items/Addons/WarriorStatueSouthAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class WarriorStatueSouthAddon : BaseAddon { [Constructible] @@ -12,7 +14,7 @@ namespace Server.Items public override BaseAddonDeed Deed => new WarriorStatueSouthDeed(); } - [Serializable(0)] + [SerializationGenerator(0)] public partial class WarriorStatueSouthDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/WaterTroughEastAddon.cs b/Projects/UOContent/Items/Addons/WaterTroughEastAddon.cs index 6253a849b..fe55a496f 100644 --- a/Projects/UOContent/Items/Addons/WaterTroughEastAddon.cs +++ b/Projects/UOContent/Items/Addons/WaterTroughEastAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class WaterTroughEastAddon : BaseAddon, IWaterSource { [Constructible] @@ -19,7 +21,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class WaterTroughEastDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/WaterTroughSouthAddon.cs b/Projects/UOContent/Items/Addons/WaterTroughSouthAddon.cs index 6e17e71b5..f51fe665c 100644 --- a/Projects/UOContent/Items/Addons/WaterTroughSouthAddon.cs +++ b/Projects/UOContent/Items/Addons/WaterTroughSouthAddon.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class WaterTroughSouthAddon : BaseAddon, IWaterSource { [Constructible] @@ -19,7 +21,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class WaterTroughSouthDeed : BaseAddonDeed { [Constructible] diff --git a/Projects/UOContent/Items/Addons/WaterVat.cs b/Projects/UOContent/Items/Addons/WaterVat.cs index 0ecdc51f1..43b58dc0d 100644 --- a/Projects/UOContent/Items/Addons/WaterVat.cs +++ b/Projects/UOContent/Items/Addons/WaterVat.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class WaterVatEast : BaseAddon { [Constructible] @@ -24,7 +26,7 @@ namespace Server.Items } } - [Serializable(0)] + [SerializationGenerator(0)] public partial class WaterVatSouth : BaseAddon { [Constructible] diff --git a/Projects/UOContent/Items/Aquarium/Aquarium.cs b/Projects/UOContent/Items/Aquarium/Aquarium.cs index c228b2779..d69041f5d 100644 --- a/Projects/UOContent/Items/Aquarium/Aquarium.cs +++ b/Projects/UOContent/Items/Aquarium/Aquarium.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using ModernUO.Serialization; using Server.ContextMenus; using Server.Multis; using Server.Network; @@ -7,7 +8,7 @@ using Server.Utilities; namespace Server.Items { - [Serializable(4, false)] + [SerializationGenerator(4, false)] public partial class Aquarium : BaseAddonContainer { public static readonly TimeSpan EvaluationInterval = TimeSpan.FromDays(1); @@ -1130,7 +1131,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class AquariumEastDeed : BaseAddonContainerDeed { [Constructible] @@ -1142,7 +1143,7 @@ namespace Server.Items public override int LabelNumber => 1074501; // Large Aquarium (east) } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class AquariumNorthDeed : BaseAddonContainerDeed { [Constructible] diff --git a/Projects/UOContent/Items/Aquarium/AquariumFishingNet.cs b/Projects/UOContent/Items/Aquarium/AquariumFishingNet.cs index 474abcde4..363351a13 100644 --- a/Projects/UOContent/Items/Aquarium/AquariumFishingNet.cs +++ b/Projects/UOContent/Items/Aquarium/AquariumFishingNet.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class AquariumFishNet : SpecialFishingNet { [Constructible] diff --git a/Projects/UOContent/Items/Aquarium/AquariumFood.cs b/Projects/UOContent/Items/Aquarium/AquariumFood.cs index db2cc1bc9..e8dd8162c 100644 --- a/Projects/UOContent/Items/Aquarium/AquariumFood.cs +++ b/Projects/UOContent/Items/Aquarium/AquariumFood.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class AquariumFood : Item { [Constructible] diff --git a/Projects/UOContent/Items/Aquarium/AquariumState.cs b/Projects/UOContent/Items/Aquarium/AquariumState.cs index 2692d3521..ed38e98f7 100644 --- a/Projects/UOContent/Items/Aquarium/AquariumState.cs +++ b/Projects/UOContent/Items/Aquarium/AquariumState.cs @@ -1,4 +1,5 @@ using System; +using ModernUO.Serialization; namespace Server.Items { @@ -21,10 +22,10 @@ namespace Server.Items } [PropertyObject] - [EmbeddedSerializable(0, false)] + [SerializationGenerator(0, false)] public partial class AquariumState { - [SerializableParent] + [DirtyTrackingEntity] private Aquarium _aquarium; private int _state; @@ -41,7 +42,7 @@ namespace Server.Items if (_state != value) { _state = Math.Clamp(value, 0, 4); - _aquarium.MarkDirty(); + this.MarkDirty(); } } } diff --git a/Projects/UOContent/Items/Aquarium/BaseFish.cs b/Projects/UOContent/Items/Aquarium/BaseFish.cs index 9611a5429..a3bfdc2aa 100644 --- a/Projects/UOContent/Items/Aquarium/BaseFish.cs +++ b/Projects/UOContent/Items/Aquarium/BaseFish.cs @@ -1,8 +1,9 @@ using System; +using ModernUO.Serialization; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public abstract partial class BaseFish : Item { private static readonly TimeSpan DeathDelay = TimeSpan.FromMinutes(5); diff --git a/Projects/UOContent/Items/Aquarium/Fish/AlbinoCourtesanFish.cs b/Projects/UOContent/Items/Aquarium/Fish/AlbinoCourtesanFish.cs index b916c715d..b542864b6 100644 --- a/Projects/UOContent/Items/Aquarium/Fish/AlbinoCourtesanFish.cs +++ b/Projects/UOContent/Items/Aquarium/Fish/AlbinoCourtesanFish.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class AlbinoCourtesanFish : BaseFish { [Constructible] diff --git a/Projects/UOContent/Items/Aquarium/Fish/AlbinoFrog.cs b/Projects/UOContent/Items/Aquarium/Fish/AlbinoFrog.cs index 58db24162..2e95417dc 100644 --- a/Projects/UOContent/Items/Aquarium/Fish/AlbinoFrog.cs +++ b/Projects/UOContent/Items/Aquarium/Fish/AlbinoFrog.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class AlbinoFrog : BaseFish { [Constructible] diff --git a/Projects/UOContent/Items/Aquarium/Fish/BritainCrownFish.cs b/Projects/UOContent/Items/Aquarium/Fish/BritainCrownFish.cs index 35c649ad5..a4ee40404 100644 --- a/Projects/UOContent/Items/Aquarium/Fish/BritainCrownFish.cs +++ b/Projects/UOContent/Items/Aquarium/Fish/BritainCrownFish.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class BritainCrownFish : BaseFish { [Constructible] diff --git a/Projects/UOContent/Items/Aquarium/Fish/FandancerFish.cs b/Projects/UOContent/Items/Aquarium/Fish/FandancerFish.cs index b27074e5b..c65e9ac6c 100644 --- a/Projects/UOContent/Items/Aquarium/Fish/FandancerFish.cs +++ b/Projects/UOContent/Items/Aquarium/Fish/FandancerFish.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class FandancerFish : BaseFish { [Constructible] diff --git a/Projects/UOContent/Items/Aquarium/Fish/GoldenBroadtail.cs b/Projects/UOContent/Items/Aquarium/Fish/GoldenBroadtail.cs index 984178f1e..b01f38c2b 100644 --- a/Projects/UOContent/Items/Aquarium/Fish/GoldenBroadtail.cs +++ b/Projects/UOContent/Items/Aquarium/Fish/GoldenBroadtail.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class GoldenBroadtail : BaseFish { [Constructible] diff --git a/Projects/UOContent/Items/Aquarium/Fish/Jellyfish.cs b/Projects/UOContent/Items/Aquarium/Fish/Jellyfish.cs index 05820fa3c..5751c35d8 100644 --- a/Projects/UOContent/Items/Aquarium/Fish/Jellyfish.cs +++ b/Projects/UOContent/Items/Aquarium/Fish/Jellyfish.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Jellyfish : BaseFish { [Constructible] diff --git a/Projects/UOContent/Items/Aquarium/Fish/KillerFrog.cs b/Projects/UOContent/Items/Aquarium/Fish/KillerFrog.cs index 0fa0d33d1..239545245 100644 --- a/Projects/UOContent/Items/Aquarium/Fish/KillerFrog.cs +++ b/Projects/UOContent/Items/Aquarium/Fish/KillerFrog.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class KillerFrog : BaseFish { [Constructible] diff --git a/Projects/UOContent/Items/Aquarium/Fish/LongClawCrab.cs b/Projects/UOContent/Items/Aquarium/Fish/LongClawCrab.cs index 5e4e8f920..4bbcfccb7 100644 --- a/Projects/UOContent/Items/Aquarium/Fish/LongClawCrab.cs +++ b/Projects/UOContent/Items/Aquarium/Fish/LongClawCrab.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LongClawCrab : BaseFish { [Constructible] diff --git a/Projects/UOContent/Items/Aquarium/Fish/MakotoCourtesanFish.cs b/Projects/UOContent/Items/Aquarium/Fish/MakotoCourtesanFish.cs index 2e597a684..b2729ec10 100644 --- a/Projects/UOContent/Items/Aquarium/Fish/MakotoCourtesanFish.cs +++ b/Projects/UOContent/Items/Aquarium/Fish/MakotoCourtesanFish.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class MakotoCourtesanFish : BaseFish { [Constructible] diff --git a/Projects/UOContent/Items/Aquarium/Fish/MinocBlueFish.cs b/Projects/UOContent/Items/Aquarium/Fish/MinocBlueFish.cs index cc98591dc..0b0924c2b 100644 --- a/Projects/UOContent/Items/Aquarium/Fish/MinocBlueFish.cs +++ b/Projects/UOContent/Items/Aquarium/Fish/MinocBlueFish.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class MinocBlueFish : BaseFish { [Constructible] diff --git a/Projects/UOContent/Items/Aquarium/Fish/NujelmHoneyFish.cs b/Projects/UOContent/Items/Aquarium/Fish/NujelmHoneyFish.cs index 1264e7f3d..f80d24923 100644 --- a/Projects/UOContent/Items/Aquarium/Fish/NujelmHoneyFish.cs +++ b/Projects/UOContent/Items/Aquarium/Fish/NujelmHoneyFish.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class NujelmHoneyFish : BaseFish { [Constructible] diff --git a/Projects/UOContent/Items/Aquarium/Fish/PurpleFrog.cs b/Projects/UOContent/Items/Aquarium/Fish/PurpleFrog.cs index 44b131e95..fb32ce954 100644 --- a/Projects/UOContent/Items/Aquarium/Fish/PurpleFrog.cs +++ b/Projects/UOContent/Items/Aquarium/Fish/PurpleFrog.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class PurpleFrog : BaseFish { [Constructible] diff --git a/Projects/UOContent/Items/Aquarium/Fish/RedDartFish.cs b/Projects/UOContent/Items/Aquarium/Fish/RedDartFish.cs index 5593ef753..d75f46245 100644 --- a/Projects/UOContent/Items/Aquarium/Fish/RedDartFish.cs +++ b/Projects/UOContent/Items/Aquarium/Fish/RedDartFish.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class RedDartFish : BaseFish { [Constructible] diff --git a/Projects/UOContent/Items/Aquarium/Fish/Shrimp.cs b/Projects/UOContent/Items/Aquarium/Fish/Shrimp.cs index a431db254..ae66c1b3a 100644 --- a/Projects/UOContent/Items/Aquarium/Fish/Shrimp.cs +++ b/Projects/UOContent/Items/Aquarium/Fish/Shrimp.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Shrimp : BaseFish { [Constructible] diff --git a/Projects/UOContent/Items/Aquarium/Fish/SmallMouthSuckerFin.cs b/Projects/UOContent/Items/Aquarium/Fish/SmallMouthSuckerFin.cs index 748e7f8cd..65e0d4f3b 100644 --- a/Projects/UOContent/Items/Aquarium/Fish/SmallMouthSuckerFin.cs +++ b/Projects/UOContent/Items/Aquarium/Fish/SmallMouthSuckerFin.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class SmallMouthSuckerFin : BaseFish { [Constructible] diff --git a/Projects/UOContent/Items/Aquarium/Fish/SpeckledCrab.cs b/Projects/UOContent/Items/Aquarium/Fish/SpeckledCrab.cs index 044618b18..0c5e82c60 100644 --- a/Projects/UOContent/Items/Aquarium/Fish/SpeckledCrab.cs +++ b/Projects/UOContent/Items/Aquarium/Fish/SpeckledCrab.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class SpeckledCrab : BaseFish { [Constructible] diff --git a/Projects/UOContent/Items/Aquarium/Fish/SpinedScratcherFish.cs b/Projects/UOContent/Items/Aquarium/Fish/SpinedScratcherFish.cs index 7490419cc..c9e91b504 100644 --- a/Projects/UOContent/Items/Aquarium/Fish/SpinedScratcherFish.cs +++ b/Projects/UOContent/Items/Aquarium/Fish/SpinedScratcherFish.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class SpinedScratcherFish : BaseFish { [Constructible] diff --git a/Projects/UOContent/Items/Aquarium/Fish/SpottedBuccaneer.cs b/Projects/UOContent/Items/Aquarium/Fish/SpottedBuccaneer.cs index 54b4b284d..979afc170 100644 --- a/Projects/UOContent/Items/Aquarium/Fish/SpottedBuccaneer.cs +++ b/Projects/UOContent/Items/Aquarium/Fish/SpottedBuccaneer.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class SpottedBuccaneer : BaseFish { [Constructible] diff --git a/Projects/UOContent/Items/Aquarium/Fish/VesperReefTiger.cs b/Projects/UOContent/Items/Aquarium/Fish/VesperReefTiger.cs index 7d7ac4fde..46d575d08 100644 --- a/Projects/UOContent/Items/Aquarium/Fish/VesperReefTiger.cs +++ b/Projects/UOContent/Items/Aquarium/Fish/VesperReefTiger.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class VesperReefTiger : BaseFish { [Constructible] diff --git a/Projects/UOContent/Items/Aquarium/Fish/YellowFinBluebelly.cs b/Projects/UOContent/Items/Aquarium/Fish/YellowFinBluebelly.cs index 5a707f132..e2e6f152d 100644 --- a/Projects/UOContent/Items/Aquarium/Fish/YellowFinBluebelly.cs +++ b/Projects/UOContent/Items/Aquarium/Fish/YellowFinBluebelly.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class YellowFinBluebelly : BaseFish { [Constructible] diff --git a/Projects/UOContent/Items/Aquarium/FishBowl.cs b/Projects/UOContent/Items/Aquarium/FishBowl.cs index 71d364305..d180b85fb 100644 --- a/Projects/UOContent/Items/Aquarium/FishBowl.cs +++ b/Projects/UOContent/Items/Aquarium/FishBowl.cs @@ -1,10 +1,11 @@ using System.Collections.Generic; +using ModernUO.Serialization; using Server.ContextMenus; using Server.Network; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class FishBowl : BaseContainer { [Constructible] diff --git a/Projects/UOContent/Items/Aquarium/Reward Fish/BrineShrimp.cs b/Projects/UOContent/Items/Aquarium/Reward Fish/BrineShrimp.cs index ac95c67b6..fe53aa46b 100644 --- a/Projects/UOContent/Items/Aquarium/Reward Fish/BrineShrimp.cs +++ b/Projects/UOContent/Items/Aquarium/Reward Fish/BrineShrimp.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class BrineShrimp : BaseFish { [Constructible] diff --git a/Projects/UOContent/Items/Aquarium/Reward Fish/Coral.cs b/Projects/UOContent/Items/Aquarium/Reward Fish/Coral.cs index 9d50f152e..d5308177d 100644 --- a/Projects/UOContent/Items/Aquarium/Reward Fish/Coral.cs +++ b/Projects/UOContent/Items/Aquarium/Reward Fish/Coral.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Coral : BaseFish { [Constructible] diff --git a/Projects/UOContent/Items/Aquarium/Reward Fish/FullMoonFish.cs b/Projects/UOContent/Items/Aquarium/Reward Fish/FullMoonFish.cs index aa048fe97..0136ad42e 100644 --- a/Projects/UOContent/Items/Aquarium/Reward Fish/FullMoonFish.cs +++ b/Projects/UOContent/Items/Aquarium/Reward Fish/FullMoonFish.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class FullMoonFish : BaseFish { [Constructible] diff --git a/Projects/UOContent/Items/Aquarium/Reward Fish/SeaHorse.cs b/Projects/UOContent/Items/Aquarium/Reward Fish/SeaHorse.cs index 2bbb36e37..f7d07eb71 100644 --- a/Projects/UOContent/Items/Aquarium/Reward Fish/SeaHorse.cs +++ b/Projects/UOContent/Items/Aquarium/Reward Fish/SeaHorse.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class SeaHorseFish : BaseFish { [Constructible] diff --git a/Projects/UOContent/Items/Aquarium/Reward Fish/StrippedFlakeFish.cs b/Projects/UOContent/Items/Aquarium/Reward Fish/StrippedFlakeFish.cs index 6da23490b..665405180 100644 --- a/Projects/UOContent/Items/Aquarium/Reward Fish/StrippedFlakeFish.cs +++ b/Projects/UOContent/Items/Aquarium/Reward Fish/StrippedFlakeFish.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class StrippedFlakeFish : BaseFish { [Constructible] diff --git a/Projects/UOContent/Items/Aquarium/Reward Fish/StrippedSosarianSwill.cs b/Projects/UOContent/Items/Aquarium/Reward Fish/StrippedSosarianSwill.cs index 024593418..2d00c8122 100644 --- a/Projects/UOContent/Items/Aquarium/Reward Fish/StrippedSosarianSwill.cs +++ b/Projects/UOContent/Items/Aquarium/Reward Fish/StrippedSosarianSwill.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class StrippedSosarianSwill : BaseFish { [Constructible] diff --git a/Projects/UOContent/Items/Aquarium/Rewards/AquariumMessage.cs b/Projects/UOContent/Items/Aquarium/Rewards/AquariumMessage.cs index d8f1ec031..86d5dadb8 100644 --- a/Projects/UOContent/Items/Aquarium/Rewards/AquariumMessage.cs +++ b/Projects/UOContent/Items/Aquarium/Rewards/AquariumMessage.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class AquariumMessage : MessageInABottle { [Constructible] diff --git a/Projects/UOContent/Items/Aquarium/Rewards/CaptainBlackheartsFishingPole.cs b/Projects/UOContent/Items/Aquarium/Rewards/CaptainBlackheartsFishingPole.cs index 6432239cb..ede935971 100644 --- a/Projects/UOContent/Items/Aquarium/Rewards/CaptainBlackheartsFishingPole.cs +++ b/Projects/UOContent/Items/Aquarium/Rewards/CaptainBlackheartsFishingPole.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class CaptainBlackheartsFishingPole : FishingPole { [Constructible] diff --git a/Projects/UOContent/Items/Aquarium/Rewards/CraftysFishingHat.cs b/Projects/UOContent/Items/Aquarium/Rewards/CraftysFishingHat.cs index d7fbbdc46..01dd1366f 100644 --- a/Projects/UOContent/Items/Aquarium/Rewards/CraftysFishingHat.cs +++ b/Projects/UOContent/Items/Aquarium/Rewards/CraftysFishingHat.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class CraftysFishingHat : BaseHat { [Constructible] diff --git a/Projects/UOContent/Items/Aquarium/Rewards/FishBones.cs b/Projects/UOContent/Items/Aquarium/Rewards/FishBones.cs index 2a3183355..d87e24503 100644 --- a/Projects/UOContent/Items/Aquarium/Rewards/FishBones.cs +++ b/Projects/UOContent/Items/Aquarium/Rewards/FishBones.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class FishBones : Item { [Constructible] diff --git a/Projects/UOContent/Items/Aquarium/Rewards/IslandStatue.cs b/Projects/UOContent/Items/Aquarium/Rewards/IslandStatue.cs index e8e57e963..c78a92cb5 100644 --- a/Projects/UOContent/Items/Aquarium/Rewards/IslandStatue.cs +++ b/Projects/UOContent/Items/Aquarium/Rewards/IslandStatue.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class IslandStatue : Item { [Constructible] diff --git a/Projects/UOContent/Items/Aquarium/Rewards/Shell.cs b/Projects/UOContent/Items/Aquarium/Rewards/Shell.cs index ce3bc4060..c5ffeb1bb 100644 --- a/Projects/UOContent/Items/Aquarium/Rewards/Shell.cs +++ b/Projects/UOContent/Items/Aquarium/Rewards/Shell.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Shell : Item { [Constructible] diff --git a/Projects/UOContent/Items/Aquarium/Rewards/ToyBoat.cs b/Projects/UOContent/Items/Aquarium/Rewards/ToyBoat.cs index 06e470d5a..fa28f994f 100644 --- a/Projects/UOContent/Items/Aquarium/Rewards/ToyBoat.cs +++ b/Projects/UOContent/Items/Aquarium/Rewards/ToyBoat.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x14F3, 0x14F4)] public partial class ToyBoat : Item { diff --git a/Projects/UOContent/Items/Aquarium/Rewards/WaterloggedBoots.cs b/Projects/UOContent/Items/Aquarium/Rewards/WaterloggedBoots.cs index ea3a6efd5..973207bc2 100644 --- a/Projects/UOContent/Items/Aquarium/Rewards/WaterloggedBoots.cs +++ b/Projects/UOContent/Items/Aquarium/Rewards/WaterloggedBoots.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class WaterloggedBoots : BaseShoes { [Constructible] diff --git a/Projects/UOContent/Items/Aquarium/VacationWafer.cs b/Projects/UOContent/Items/Aquarium/VacationWafer.cs index 1021afc37..9f4f5707a 100644 --- a/Projects/UOContent/Items/Aquarium/VacationWafer.cs +++ b/Projects/UOContent/Items/Aquarium/VacationWafer.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class VacationWafer : Item { public const int VacationDays = 7; diff --git a/Projects/UOContent/Items/Armor/Artifacts/ArmorOfFortune.cs b/Projects/UOContent/Items/Armor/Artifacts/ArmorOfFortune.cs index 624692b54..6379b8463 100644 --- a/Projects/UOContent/Items/Armor/Artifacts/ArmorOfFortune.cs +++ b/Projects/UOContent/Items/Armor/Artifacts/ArmorOfFortune.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class ArmorOfFortune : StuddedChest { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Artifacts/Craftable/BrambleCoat.cs b/Projects/UOContent/Items/Armor/Artifacts/Craftable/BrambleCoat.cs index 7327a9b52..6f694b926 100644 --- a/Projects/UOContent/Items/Armor/Artifacts/Craftable/BrambleCoat.cs +++ b/Projects/UOContent/Items/Armor/Artifacts/Craftable/BrambleCoat.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class BrambleCoat : WoodlandChest { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Artifacts/Craftable/IronwoodCrown.cs b/Projects/UOContent/Items/Armor/Artifacts/Craftable/IronwoodCrown.cs index dd00c0838..10c01388e 100644 --- a/Projects/UOContent/Items/Armor/Artifacts/Craftable/IronwoodCrown.cs +++ b/Projects/UOContent/Items/Armor/Artifacts/Craftable/IronwoodCrown.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class IronwoodCrown : RavenHelm { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Artifacts/Craftable/SongWovenMantle.cs b/Projects/UOContent/Items/Armor/Artifacts/Craftable/SongWovenMantle.cs index 007bf2165..db318d0e2 100644 --- a/Projects/UOContent/Items/Armor/Artifacts/Craftable/SongWovenMantle.cs +++ b/Projects/UOContent/Items/Armor/Artifacts/Craftable/SongWovenMantle.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class SongWovenMantle : LeafArms { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Artifacts/Craftable/SpellWovenBritches.cs b/Projects/UOContent/Items/Armor/Artifacts/Craftable/SpellWovenBritches.cs index 1ad94ff66..219625192 100644 --- a/Projects/UOContent/Items/Armor/Artifacts/Craftable/SpellWovenBritches.cs +++ b/Projects/UOContent/Items/Armor/Artifacts/Craftable/SpellWovenBritches.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class SpellWovenBritches : LeafLegs { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Artifacts/Craftable/StitchersMittens.cs b/Projects/UOContent/Items/Armor/Artifacts/Craftable/StitchersMittens.cs index c2b0e0a13..e60595ae6 100644 --- a/Projects/UOContent/Items/Armor/Artifacts/Craftable/StitchersMittens.cs +++ b/Projects/UOContent/Items/Armor/Artifacts/Craftable/StitchersMittens.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class StitchersMittens : LeafGloves { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Artifacts/GauntletsOfNobility.cs b/Projects/UOContent/Items/Armor/Artifacts/GauntletsOfNobility.cs index 872851cd6..c182d7fb4 100644 --- a/Projects/UOContent/Items/Armor/Artifacts/GauntletsOfNobility.cs +++ b/Projects/UOContent/Items/Armor/Artifacts/GauntletsOfNobility.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class GauntletsOfNobility : RingmailGloves { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Artifacts/HelmOfInsight.cs b/Projects/UOContent/Items/Armor/Artifacts/HelmOfInsight.cs index c19866380..c913ccefa 100644 --- a/Projects/UOContent/Items/Armor/Artifacts/HelmOfInsight.cs +++ b/Projects/UOContent/Items/Armor/Artifacts/HelmOfInsight.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class HelmOfInsight : PlateHelm { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Artifacts/HolyKnightsBreastplate.cs b/Projects/UOContent/Items/Armor/Artifacts/HolyKnightsBreastplate.cs index 2f7b0951c..20043d69c 100644 --- a/Projects/UOContent/Items/Armor/Artifacts/HolyKnightsBreastplate.cs +++ b/Projects/UOContent/Items/Armor/Artifacts/HolyKnightsBreastplate.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class HolyKnightsBreastplate : PlateChest { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Artifacts/InquisitorsResolution.cs b/Projects/UOContent/Items/Armor/Artifacts/InquisitorsResolution.cs index 3aee07ed6..17b535ec8 100644 --- a/Projects/UOContent/Items/Armor/Artifacts/InquisitorsResolution.cs +++ b/Projects/UOContent/Items/Armor/Artifacts/InquisitorsResolution.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class InquisitorsResolution : PlateGloves { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Artifacts/JackalsCollar.cs b/Projects/UOContent/Items/Armor/Artifacts/JackalsCollar.cs index 32114470e..c24a4b668 100644 --- a/Projects/UOContent/Items/Armor/Artifacts/JackalsCollar.cs +++ b/Projects/UOContent/Items/Armor/Artifacts/JackalsCollar.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class JackalsCollar : PlateGorget { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Artifacts/LeggingsOfBane.cs b/Projects/UOContent/Items/Armor/Artifacts/LeggingsOfBane.cs index 6a7fa1da7..1d8c7de2d 100644 --- a/Projects/UOContent/Items/Armor/Artifacts/LeggingsOfBane.cs +++ b/Projects/UOContent/Items/Armor/Artifacts/LeggingsOfBane.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LeggingsOfBane : ChainLegs { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Artifacts/MidnightBracers.cs b/Projects/UOContent/Items/Armor/Artifacts/MidnightBracers.cs index 57d6d661d..6379b05cb 100644 --- a/Projects/UOContent/Items/Armor/Artifacts/MidnightBracers.cs +++ b/Projects/UOContent/Items/Armor/Artifacts/MidnightBracers.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class MidnightBracers : BoneArms { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Artifacts/OrnateCrownOfTheHarrower.cs b/Projects/UOContent/Items/Armor/Artifacts/OrnateCrownOfTheHarrower.cs index c94054d0d..7ae2a0ee3 100644 --- a/Projects/UOContent/Items/Armor/Artifacts/OrnateCrownOfTheHarrower.cs +++ b/Projects/UOContent/Items/Armor/Artifacts/OrnateCrownOfTheHarrower.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class OrnateCrownOfTheHarrower : BoneHelm { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Artifacts/ShadowDancerLeggings.cs b/Projects/UOContent/Items/Armor/Artifacts/ShadowDancerLeggings.cs index 188c50b2b..1395a55b6 100644 --- a/Projects/UOContent/Items/Armor/Artifacts/ShadowDancerLeggings.cs +++ b/Projects/UOContent/Items/Armor/Artifacts/ShadowDancerLeggings.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class ShadowDancerLeggings : LeatherLegs { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Artifacts/TunicOfFire.cs b/Projects/UOContent/Items/Armor/Artifacts/TunicOfFire.cs index 9b83136fd..41a3be68a 100644 --- a/Projects/UOContent/Items/Armor/Artifacts/TunicOfFire.cs +++ b/Projects/UOContent/Items/Armor/Artifacts/TunicOfFire.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class TunicOfFire : ChainChest { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Artifacts/VoiceOfTheFallenKing.cs b/Projects/UOContent/Items/Armor/Artifacts/VoiceOfTheFallenKing.cs index e4db5af05..62e57d825 100644 --- a/Projects/UOContent/Items/Armor/Artifacts/VoiceOfTheFallenKing.cs +++ b/Projects/UOContent/Items/Armor/Artifacts/VoiceOfTheFallenKing.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class VoiceOfTheFallenKing : LeatherGorget { [Constructible] diff --git a/Projects/UOContent/Items/Armor/BaseArmor.cs b/Projects/UOContent/Items/Armor/BaseArmor.cs index c306494b3..ae821b7ee 100644 --- a/Projects/UOContent/Items/Armor/BaseArmor.cs +++ b/Projects/UOContent/Items/Armor/BaseArmor.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using ModernUO.Serialization; using Server.Engines.Craft; using Server.Ethics; using Server.Factions; @@ -10,7 +11,7 @@ using AMT = Server.Items.ArmorMaterialType; namespace Server.Items { - [Serializable(9, false)] + [SerializationGenerator(9, false)] public abstract partial class BaseArmor : Item, IScissorable, IFactionItem, ICraftable, IWearableDurability { [SerializableField(0, setter: "private")] diff --git a/Projects/UOContent/Items/Armor/Bone/BoneArms.cs b/Projects/UOContent/Items/Armor/Bone/BoneArms.cs index 886bff8a1..a5a41d647 100644 --- a/Projects/UOContent/Items/Armor/Bone/BoneArms.cs +++ b/Projects/UOContent/Items/Armor/Bone/BoneArms.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x144e, 0x1453)] public partial class BoneArms : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Bone/BoneChest.cs b/Projects/UOContent/Items/Armor/Bone/BoneChest.cs index 6431abd75..edbb82f10 100644 --- a/Projects/UOContent/Items/Armor/Bone/BoneChest.cs +++ b/Projects/UOContent/Items/Armor/Bone/BoneChest.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x144f, 0x1454)] public partial class BoneChest : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Bone/BoneGloves.cs b/Projects/UOContent/Items/Armor/Bone/BoneGloves.cs index 795fe85f4..5958198ad 100644 --- a/Projects/UOContent/Items/Armor/Bone/BoneGloves.cs +++ b/Projects/UOContent/Items/Armor/Bone/BoneGloves.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1450, 0x1455)] public partial class BoneGloves : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Bone/BoneLegs.cs b/Projects/UOContent/Items/Armor/Bone/BoneLegs.cs index ed0357a12..67c3f9653 100644 --- a/Projects/UOContent/Items/Armor/Bone/BoneLegs.cs +++ b/Projects/UOContent/Items/Armor/Bone/BoneLegs.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1452, 0x1457)] public partial class BoneLegs : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Chain/ChainChest.cs b/Projects/UOContent/Items/Armor/Chain/ChainChest.cs index 57df216de..9d4536d80 100644 --- a/Projects/UOContent/Items/Armor/Chain/ChainChest.cs +++ b/Projects/UOContent/Items/Armor/Chain/ChainChest.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x13bf, 0x13c4)] public partial class ChainChest : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Chain/ChainHatsuburi.cs b/Projects/UOContent/Items/Armor/Chain/ChainHatsuburi.cs index 4f537f4b1..b5fd1431f 100644 --- a/Projects/UOContent/Items/Armor/Chain/ChainHatsuburi.cs +++ b/Projects/UOContent/Items/Armor/Chain/ChainHatsuburi.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class ChainHatsuburi : BaseArmor { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Chain/ChainLegs.cs b/Projects/UOContent/Items/Armor/Chain/ChainLegs.cs index 2e40231f7..edfbea1e5 100644 --- a/Projects/UOContent/Items/Armor/Chain/ChainLegs.cs +++ b/Projects/UOContent/Items/Armor/Chain/ChainLegs.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x13be, 0x13c3)] public partial class ChainLegs : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Cloth/GargishClothArmsType1.cs b/Projects/UOContent/Items/Armor/Cloth/GargishClothArmsType1.cs index 819d4e44e..0d124f8f4 100644 --- a/Projects/UOContent/Items/Armor/Cloth/GargishClothArmsType1.cs +++ b/Projects/UOContent/Items/Armor/Cloth/GargishClothArmsType1.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] [TypeAlias("Server.Items.GargishClothArms", "Server.Items.GargishClothArmsArmor")] public partial class GargishClothArmsType1 : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Cloth/GargishClothArmsType2.cs b/Projects/UOContent/Items/Armor/Cloth/GargishClothArmsType2.cs index c46c5ebf0..96027ec54 100644 --- a/Projects/UOContent/Items/Armor/Cloth/GargishClothArmsType2.cs +++ b/Projects/UOContent/Items/Armor/Cloth/GargishClothArmsType2.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] [TypeAlias("Server.Items.FemaleGargishClothArms", "Server.Items.FemaleGargishClothArmsArmor")] public partial class GargishClothArmsType2 : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Cloth/GargishClothChestType1.cs b/Projects/UOContent/Items/Armor/Cloth/GargishClothChestType1.cs index 4785b91bb..76f8ac65c 100644 --- a/Projects/UOContent/Items/Armor/Cloth/GargishClothChestType1.cs +++ b/Projects/UOContent/Items/Armor/Cloth/GargishClothChestType1.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] [TypeAlias("Server.Items.GargishClothChest", "Server.Items.GargishClothChestArmor")] public partial class GargishClothChestType1 : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Cloth/GargishClothChestType2.cs b/Projects/UOContent/Items/Armor/Cloth/GargishClothChestType2.cs index a1ba296a2..0867ec5c7 100644 --- a/Projects/UOContent/Items/Armor/Cloth/GargishClothChestType2.cs +++ b/Projects/UOContent/Items/Armor/Cloth/GargishClothChestType2.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] [TypeAlias("Server.Items.FemaleGargishClothChest", "Server.Items.FemaleGargishClothChestArmor")] public partial class GargishClothChestType2 : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Cloth/GargishClothKiltType1.cs b/Projects/UOContent/Items/Armor/Cloth/GargishClothKiltType1.cs index b3b8c1093..3200848bc 100644 --- a/Projects/UOContent/Items/Armor/Cloth/GargishClothKiltType1.cs +++ b/Projects/UOContent/Items/Armor/Cloth/GargishClothKiltType1.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] [TypeAlias("Server.Items.GargishClothKilt", "Server.Items.GargishClothKiltArmor")] public partial class GargishClothKiltType1 : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Cloth/GargishClothKiltType2.cs b/Projects/UOContent/Items/Armor/Cloth/GargishClothKiltType2.cs index e18718dc1..45c836fb4 100644 --- a/Projects/UOContent/Items/Armor/Cloth/GargishClothKiltType2.cs +++ b/Projects/UOContent/Items/Armor/Cloth/GargishClothKiltType2.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] [TypeAlias("Server.Items.GargishClothKilt", "Server.Items.GargishClothKiltArmor")] public partial class GargishClothKiltType2 : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Cloth/GargishClothLegsType1.cs b/Projects/UOContent/Items/Armor/Cloth/GargishClothLegsType1.cs index 45084fbc3..53e724d47 100644 --- a/Projects/UOContent/Items/Armor/Cloth/GargishClothLegsType1.cs +++ b/Projects/UOContent/Items/Armor/Cloth/GargishClothLegsType1.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] [TypeAlias("Server.Items.GargishClothLegs", "Server.Items.GargishClothLegsArmor")] public partial class GargishClothLegsType1 : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Cloth/GargishClothLegsType2.cs b/Projects/UOContent/Items/Armor/Cloth/GargishClothLegsType2.cs index bad26d399..0016b886f 100644 --- a/Projects/UOContent/Items/Armor/Cloth/GargishClothLegsType2.cs +++ b/Projects/UOContent/Items/Armor/Cloth/GargishClothLegsType2.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] [TypeAlias("Server.Items.FemaleGargishClothLegs", "Server.Items.FemaleGargishClothLegsArmor")] public partial class GargishClothLegsType2 : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/DaemonBone/DaemonArms.cs b/Projects/UOContent/Items/Armor/DaemonBone/DaemonArms.cs index fd997f57f..8c22af849 100644 --- a/Projects/UOContent/Items/Armor/DaemonBone/DaemonArms.cs +++ b/Projects/UOContent/Items/Armor/DaemonBone/DaemonArms.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x144e, 0x1453)] public partial class DaemonArms : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/DaemonBone/DaemonChest.cs b/Projects/UOContent/Items/Armor/DaemonBone/DaemonChest.cs index 5c591a497..e2a0ec586 100644 --- a/Projects/UOContent/Items/Armor/DaemonBone/DaemonChest.cs +++ b/Projects/UOContent/Items/Armor/DaemonBone/DaemonChest.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x144f, 0x1454)] public partial class DaemonChest : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/DaemonBone/DaemonGloves.cs b/Projects/UOContent/Items/Armor/DaemonBone/DaemonGloves.cs index 070102ebe..e7d0793cd 100644 --- a/Projects/UOContent/Items/Armor/DaemonBone/DaemonGloves.cs +++ b/Projects/UOContent/Items/Armor/DaemonBone/DaemonGloves.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1450, 0x1455)] public partial class DaemonGloves : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/DaemonBone/DaemonLegs.cs b/Projects/UOContent/Items/Armor/DaemonBone/DaemonLegs.cs index f74377813..f07aeeae6 100644 --- a/Projects/UOContent/Items/Armor/DaemonBone/DaemonLegs.cs +++ b/Projects/UOContent/Items/Armor/DaemonBone/DaemonLegs.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1452, 0x1457)] public partial class DaemonLegs : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Dragon/DragonArms.cs b/Projects/UOContent/Items/Armor/Dragon/DragonArms.cs index 1412755c8..970be0af2 100644 --- a/Projects/UOContent/Items/Armor/Dragon/DragonArms.cs +++ b/Projects/UOContent/Items/Armor/Dragon/DragonArms.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x2657, 0x2658)] public partial class DragonArms : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Dragon/DragonChest.cs b/Projects/UOContent/Items/Armor/Dragon/DragonChest.cs index 796a76329..7e012296e 100644 --- a/Projects/UOContent/Items/Armor/Dragon/DragonChest.cs +++ b/Projects/UOContent/Items/Armor/Dragon/DragonChest.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x2641, 0x2642)] public partial class DragonChest : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Dragon/DragonGloves.cs b/Projects/UOContent/Items/Armor/Dragon/DragonGloves.cs index a327b29d9..4d2ec9c8d 100644 --- a/Projects/UOContent/Items/Armor/Dragon/DragonGloves.cs +++ b/Projects/UOContent/Items/Armor/Dragon/DragonGloves.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x2643, 0x2644)] public partial class DragonGloves : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Dragon/DragonHelm.cs b/Projects/UOContent/Items/Armor/Dragon/DragonHelm.cs index 900a9db5b..79190e074 100644 --- a/Projects/UOContent/Items/Armor/Dragon/DragonHelm.cs +++ b/Projects/UOContent/Items/Armor/Dragon/DragonHelm.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x2645, 0x2646)] public partial class DragonHelm : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Dragon/DragonLegs.cs b/Projects/UOContent/Items/Armor/Dragon/DragonLegs.cs index d708fa77c..2f02eea46 100644 --- a/Projects/UOContent/Items/Armor/Dragon/DragonLegs.cs +++ b/Projects/UOContent/Items/Armor/Dragon/DragonLegs.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x2647, 0x2648)] public partial class DragonLegs : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Glasses/AnthropomorphistGlasses.cs b/Projects/UOContent/Items/Armor/Glasses/AnthropomorphistGlasses.cs index d367588bc..059d8274c 100644 --- a/Projects/UOContent/Items/Armor/Glasses/AnthropomorphistGlasses.cs +++ b/Projects/UOContent/Items/Armor/Glasses/AnthropomorphistGlasses.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class AnthropomorphistGlasses : ElvenGlasses { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Glasses/ArtsGlasses.cs b/Projects/UOContent/Items/Armor/Glasses/ArtsGlasses.cs index 5982541ad..e1d502342 100644 --- a/Projects/UOContent/Items/Armor/Glasses/ArtsGlasses.cs +++ b/Projects/UOContent/Items/Armor/Glasses/ArtsGlasses.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class ArtsGlasses : ElvenGlasses { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Glasses/ElvenGlasses.cs b/Projects/UOContent/Items/Armor/Glasses/ElvenGlasses.cs index 1b4bbd3e3..c9140977a 100644 --- a/Projects/UOContent/Items/Armor/Glasses/ElvenGlasses.cs +++ b/Projects/UOContent/Items/Armor/Glasses/ElvenGlasses.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class ElvenGlasses : BaseArmor { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Glasses/FoldedSteelGlasses.cs b/Projects/UOContent/Items/Armor/Glasses/FoldedSteelGlasses.cs index 52ad9a712..a28392ff9 100644 --- a/Projects/UOContent/Items/Armor/Glasses/FoldedSteelGlasses.cs +++ b/Projects/UOContent/Items/Armor/Glasses/FoldedSteelGlasses.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class FoldedSteelGlasses : ElvenGlasses { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Glasses/LightOfWayGlasses.cs b/Projects/UOContent/Items/Armor/Glasses/LightOfWayGlasses.cs index bc41b7a3f..fdc40425a 100644 --- a/Projects/UOContent/Items/Armor/Glasses/LightOfWayGlasses.cs +++ b/Projects/UOContent/Items/Armor/Glasses/LightOfWayGlasses.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LightOfWayGlasses : ElvenGlasses { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Glasses/LyricalGlasses.cs b/Projects/UOContent/Items/Armor/Glasses/LyricalGlasses.cs index 4a83f3d33..cf453cb1e 100644 --- a/Projects/UOContent/Items/Armor/Glasses/LyricalGlasses.cs +++ b/Projects/UOContent/Items/Armor/Glasses/LyricalGlasses.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LyricalGlasses : ElvenGlasses { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Glasses/MaceShieldGlasses.cs b/Projects/UOContent/Items/Armor/Glasses/MaceShieldGlasses.cs index 2a71e599f..dc7ca8b8b 100644 --- a/Projects/UOContent/Items/Armor/Glasses/MaceShieldGlasses.cs +++ b/Projects/UOContent/Items/Armor/Glasses/MaceShieldGlasses.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class MaceShieldGlasses : ElvenGlasses { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Glasses/MaritimeGlasses.cs b/Projects/UOContent/Items/Armor/Glasses/MaritimeGlasses.cs index 7afdc60d6..0f892737e 100644 --- a/Projects/UOContent/Items/Armor/Glasses/MaritimeGlasses.cs +++ b/Projects/UOContent/Items/Armor/Glasses/MaritimeGlasses.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class MaritimeGlasses : ElvenGlasses { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Glasses/NecromanticGlasses.cs b/Projects/UOContent/Items/Armor/Glasses/NecromanticGlasses.cs index 334cb7469..cbf3b455f 100644 --- a/Projects/UOContent/Items/Armor/Glasses/NecromanticGlasses.cs +++ b/Projects/UOContent/Items/Armor/Glasses/NecromanticGlasses.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class NecromanticGlasses : ElvenGlasses { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Glasses/PoisonedGlasses.cs b/Projects/UOContent/Items/Armor/Glasses/PoisonedGlasses.cs index e96c2e41c..706d33f3a 100644 --- a/Projects/UOContent/Items/Armor/Glasses/PoisonedGlasses.cs +++ b/Projects/UOContent/Items/Armor/Glasses/PoisonedGlasses.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class PoisonedGlasses : ElvenGlasses { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Glasses/TradeGlasses.cs b/Projects/UOContent/Items/Armor/Glasses/TradeGlasses.cs index 7bfd740a9..224a83870 100644 --- a/Projects/UOContent/Items/Armor/Glasses/TradeGlasses.cs +++ b/Projects/UOContent/Items/Armor/Glasses/TradeGlasses.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class TradeGlasses : ElvenGlasses { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Glasses/TreasureTrinketGlasses.cs b/Projects/UOContent/Items/Armor/Glasses/TreasureTrinketGlasses.cs index a4e4df3be..f355f166c 100644 --- a/Projects/UOContent/Items/Armor/Glasses/TreasureTrinketGlasses.cs +++ b/Projects/UOContent/Items/Armor/Glasses/TreasureTrinketGlasses.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class TreasureTrinketGlasses : ElvenGlasses { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Glasses/WizardsGlasses.cs b/Projects/UOContent/Items/Armor/Glasses/WizardsGlasses.cs index 1f9f93573..628dcfd0e 100644 --- a/Projects/UOContent/Items/Armor/Glasses/WizardsGlasses.cs +++ b/Projects/UOContent/Items/Armor/Glasses/WizardsGlasses.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class WizardsGlasses : ElvenGlasses { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Helmets/Bascinet.cs b/Projects/UOContent/Items/Armor/Helmets/Bascinet.cs index a4f7b9f23..3885e397a 100644 --- a/Projects/UOContent/Items/Armor/Helmets/Bascinet.cs +++ b/Projects/UOContent/Items/Armor/Helmets/Bascinet.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Bascinet : BaseArmor { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Helmets/BoneHelm.cs b/Projects/UOContent/Items/Armor/Helmets/BoneHelm.cs index e6d891e3d..f863f6d7a 100644 --- a/Projects/UOContent/Items/Armor/Helmets/BoneHelm.cs +++ b/Projects/UOContent/Items/Armor/Helmets/BoneHelm.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1451, 0x1456)] public partial class BoneHelm : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Helmets/ChainCoif.cs b/Projects/UOContent/Items/Armor/Helmets/ChainCoif.cs index 6db814674..d1277dd77 100644 --- a/Projects/UOContent/Items/Armor/Helmets/ChainCoif.cs +++ b/Projects/UOContent/Items/Armor/Helmets/ChainCoif.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x13BB, 0x13C0)] public partial class ChainCoif : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Helmets/Circlet.cs b/Projects/UOContent/Items/Armor/Helmets/Circlet.cs index 7d504bfa2..7544eb134 100644 --- a/Projects/UOContent/Items/Armor/Helmets/Circlet.cs +++ b/Projects/UOContent/Items/Armor/Helmets/Circlet.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] [Flippable(0x2B6E, 0x3165)] public partial class Circlet : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Helmets/CloseHelm.cs b/Projects/UOContent/Items/Armor/Helmets/CloseHelm.cs index 0de794c6b..b7a5197a4 100644 --- a/Projects/UOContent/Items/Armor/Helmets/CloseHelm.cs +++ b/Projects/UOContent/Items/Armor/Helmets/CloseHelm.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class CloseHelm : BaseArmor { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Helmets/DaemonHelm.cs b/Projects/UOContent/Items/Armor/Helmets/DaemonHelm.cs index 81fb497da..80f2de0b5 100644 --- a/Projects/UOContent/Items/Armor/Helmets/DaemonHelm.cs +++ b/Projects/UOContent/Items/Armor/Helmets/DaemonHelm.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1451, 0x1456)] public partial class DaemonHelm : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Helmets/GemmedCirclet.cs b/Projects/UOContent/Items/Armor/Helmets/GemmedCirclet.cs index 26c0d373d..3df8b821a 100644 --- a/Projects/UOContent/Items/Armor/Helmets/GemmedCirclet.cs +++ b/Projects/UOContent/Items/Armor/Helmets/GemmedCirclet.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x2B70, 0x3167)] - [Serializable(0)] + [SerializationGenerator(0)] public partial class GemmedCirclet : BaseArmor { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Helmets/Helmet.cs b/Projects/UOContent/Items/Armor/Helmets/Helmet.cs index 9dd8a7a15..01b138abb 100644 --- a/Projects/UOContent/Items/Armor/Helmets/Helmet.cs +++ b/Projects/UOContent/Items/Armor/Helmets/Helmet.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Helmet : BaseArmor { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Helmets/LeatherCap.cs b/Projects/UOContent/Items/Armor/Helmets/LeatherCap.cs index 455bc4550..dfeafd35b 100644 --- a/Projects/UOContent/Items/Armor/Helmets/LeatherCap.cs +++ b/Projects/UOContent/Items/Armor/Helmets/LeatherCap.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x1db9, 0x1dba)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LeatherCap : BaseArmor { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Helmets/NorseHelm.cs b/Projects/UOContent/Items/Armor/Helmets/NorseHelm.cs index 5278c1437..84926b157 100644 --- a/Projects/UOContent/Items/Armor/Helmets/NorseHelm.cs +++ b/Projects/UOContent/Items/Armor/Helmets/NorseHelm.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class NorseHelm : BaseArmor { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Helmets/OrcHelm.cs b/Projects/UOContent/Items/Armor/Helmets/OrcHelm.cs index 263922d7b..e7e34a718 100644 --- a/Projects/UOContent/Items/Armor/Helmets/OrcHelm.cs +++ b/Projects/UOContent/Items/Armor/Helmets/OrcHelm.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class OrcHelm : BaseArmor { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Helmets/PlateHelm.cs b/Projects/UOContent/Items/Armor/Helmets/PlateHelm.cs index a9401e970..c4e2060cf 100644 --- a/Projects/UOContent/Items/Armor/Helmets/PlateHelm.cs +++ b/Projects/UOContent/Items/Armor/Helmets/PlateHelm.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class PlateHelm : BaseArmor { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Helmets/RavenHelm.cs b/Projects/UOContent/Items/Armor/Helmets/RavenHelm.cs index ce38ba388..5cd85bb25 100644 --- a/Projects/UOContent/Items/Armor/Helmets/RavenHelm.cs +++ b/Projects/UOContent/Items/Armor/Helmets/RavenHelm.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x2B71, 0x3168)] - [Serializable(0)] + [SerializationGenerator(0)] public partial class RavenHelm : BaseArmor { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Helmets/RoyalCirclet.cs b/Projects/UOContent/Items/Armor/Helmets/RoyalCirclet.cs index 673eb2e12..ed2b78800 100644 --- a/Projects/UOContent/Items/Armor/Helmets/RoyalCirclet.cs +++ b/Projects/UOContent/Items/Armor/Helmets/RoyalCirclet.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x2B6F, 0x3166)] - [Serializable(0)] + [SerializationGenerator(0)] public partial class RoyalCirclet : BaseArmor { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Helmets/VultureHelm.cs b/Projects/UOContent/Items/Armor/Helmets/VultureHelm.cs index 59f169fc4..8d5e89a25 100644 --- a/Projects/UOContent/Items/Armor/Helmets/VultureHelm.cs +++ b/Projects/UOContent/Items/Armor/Helmets/VultureHelm.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x2B72, 0x3169)] - [Serializable(0)] + [SerializationGenerator(0)] public partial class VultureHelm : BaseArmor { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Helmets/WingedHelm.cs b/Projects/UOContent/Items/Armor/Helmets/WingedHelm.cs index f8609a28c..91c2f3b59 100644 --- a/Projects/UOContent/Items/Armor/Helmets/WingedHelm.cs +++ b/Projects/UOContent/Items/Armor/Helmets/WingedHelm.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x2B73, 0x316A)] - [Serializable(0)] + [SerializationGenerator(0)] public partial class WingedHelm : BaseArmor { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Leather/FemaleLeafChest.cs b/Projects/UOContent/Items/Armor/Leather/FemaleLeafChest.cs index e46b414b6..83b7bb84c 100644 --- a/Projects/UOContent/Items/Armor/Leather/FemaleLeafChest.cs +++ b/Projects/UOContent/Items/Armor/Leather/FemaleLeafChest.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] [Flippable(0x2FCB, 0x3181)] public partial class FemaleLeafChest : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Leather/FemaleLeatherChest.cs b/Projects/UOContent/Items/Armor/Leather/FemaleLeatherChest.cs index 30e3edd50..0a6433ff9 100644 --- a/Projects/UOContent/Items/Armor/Leather/FemaleLeatherChest.cs +++ b/Projects/UOContent/Items/Armor/Leather/FemaleLeatherChest.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1c06, 0x1c07)] public partial class FemaleLeatherChest : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Leather/GargishLeatherArmsType1.cs b/Projects/UOContent/Items/Armor/Leather/GargishLeatherArmsType1.cs index 950141073..007d64209 100644 --- a/Projects/UOContent/Items/Armor/Leather/GargishLeatherArmsType1.cs +++ b/Projects/UOContent/Items/Armor/Leather/GargishLeatherArmsType1.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [TypeAlias("Server.Items.GargishLeatherArms")] public partial class GargishLeatherArmsType1 : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Leather/GargishLeatherArmsType2.cs b/Projects/UOContent/Items/Armor/Leather/GargishLeatherArmsType2.cs index 8c973c861..5167c8e15 100644 --- a/Projects/UOContent/Items/Armor/Leather/GargishLeatherArmsType2.cs +++ b/Projects/UOContent/Items/Armor/Leather/GargishLeatherArmsType2.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [TypeAlias("Server.Items.FemaleGargishLeatherArms")] public partial class GargishLeatherArmsType2 : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Leather/GargishLeatherChestType1.cs b/Projects/UOContent/Items/Armor/Leather/GargishLeatherChestType1.cs index 1af594db3..21a38d83c 100644 --- a/Projects/UOContent/Items/Armor/Leather/GargishLeatherChestType1.cs +++ b/Projects/UOContent/Items/Armor/Leather/GargishLeatherChestType1.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [TypeAlias("Server.Items.GargishLeatherChest")] public partial class GargishLeatherChestType1 : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Leather/GargishLeatherChestType2.cs b/Projects/UOContent/Items/Armor/Leather/GargishLeatherChestType2.cs index 5e0278116..5e91ef3a0 100644 --- a/Projects/UOContent/Items/Armor/Leather/GargishLeatherChestType2.cs +++ b/Projects/UOContent/Items/Armor/Leather/GargishLeatherChestType2.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [TypeAlias("Server.Items.FemaleGargishLeatherChest")] public partial class GargishLeatherChestType2 : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Leather/GargishLeatherKiltType1.cs b/Projects/UOContent/Items/Armor/Leather/GargishLeatherKiltType1.cs index e84097924..98d468165 100644 --- a/Projects/UOContent/Items/Armor/Leather/GargishLeatherKiltType1.cs +++ b/Projects/UOContent/Items/Armor/Leather/GargishLeatherKiltType1.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [TypeAlias("Server.Items.GargishLeatherKilt")] public partial class GargishLeatherKiltType1 : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Leather/GargishLeatherKiltType2.cs b/Projects/UOContent/Items/Armor/Leather/GargishLeatherKiltType2.cs index 89438bfb9..ef7e3491c 100644 --- a/Projects/UOContent/Items/Armor/Leather/GargishLeatherKiltType2.cs +++ b/Projects/UOContent/Items/Armor/Leather/GargishLeatherKiltType2.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [TypeAlias("Server.Items.FemaleGargishLeatherKilt")] public partial class GargishLeatherKiltType2 : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Leather/GargishLeatherLegsType1.cs b/Projects/UOContent/Items/Armor/Leather/GargishLeatherLegsType1.cs index 22bb593c9..6decd20a6 100644 --- a/Projects/UOContent/Items/Armor/Leather/GargishLeatherLegsType1.cs +++ b/Projects/UOContent/Items/Armor/Leather/GargishLeatherLegsType1.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [TypeAlias("Server.Items.GargishLeatherLegs")] public partial class GargishLeatherLegsType1 : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Leather/GargishLeatherLegsType2.cs b/Projects/UOContent/Items/Armor/Leather/GargishLeatherLegsType2.cs index 5aa010f10..be0e8b395 100644 --- a/Projects/UOContent/Items/Armor/Leather/GargishLeatherLegsType2.cs +++ b/Projects/UOContent/Items/Armor/Leather/GargishLeatherLegsType2.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [TypeAlias("Server.Items.FemaleGargishLeatherLegs")] public partial class GargishLeatherLegsType2 : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Leather/GargishLeatherWingArmor.cs b/Projects/UOContent/Items/Armor/Leather/GargishLeatherWingArmor.cs index 3773586de..52505040e 100644 --- a/Projects/UOContent/Items/Armor/Leather/GargishLeatherWingArmor.cs +++ b/Projects/UOContent/Items/Armor/Leather/GargishLeatherWingArmor.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x457E, 0x457F)] public partial class GargishLeatherWingArmor : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Leather/LeafArms.cs b/Projects/UOContent/Items/Armor/Leather/LeafArms.cs index cafacb422..2eb21fbfd 100644 --- a/Projects/UOContent/Items/Armor/Leather/LeafArms.cs +++ b/Projects/UOContent/Items/Armor/Leather/LeafArms.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] [Flippable(0x2FC8, 0x317E)] public partial class LeafArms : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Leather/LeafChest.cs b/Projects/UOContent/Items/Armor/Leather/LeafChest.cs index 5a1919187..853aad33d 100644 --- a/Projects/UOContent/Items/Armor/Leather/LeafChest.cs +++ b/Projects/UOContent/Items/Armor/Leather/LeafChest.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] [Flippable(0x2FC5, 0x317B)] public partial class LeafChest : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Leather/LeafGloves.cs b/Projects/UOContent/Items/Armor/Leather/LeafGloves.cs index 611e5952f..5698e6cd9 100644 --- a/Projects/UOContent/Items/Armor/Leather/LeafGloves.cs +++ b/Projects/UOContent/Items/Armor/Leather/LeafGloves.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable] - [Serializable(1)] + [SerializationGenerator(1)] public partial class LeafGloves : BaseArmor, IArcaneEquip { private int _maxArcaneCharges; diff --git a/Projects/UOContent/Items/Armor/Leather/LeafGorget.cs b/Projects/UOContent/Items/Armor/Leather/LeafGorget.cs index 0e024ef06..7361479ce 100644 --- a/Projects/UOContent/Items/Armor/Leather/LeafGorget.cs +++ b/Projects/UOContent/Items/Armor/Leather/LeafGorget.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class LeafGorget : BaseArmor { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Leather/LeafLegs.cs b/Projects/UOContent/Items/Armor/Leather/LeafLegs.cs index 1867289e3..6ba3d3593 100644 --- a/Projects/UOContent/Items/Armor/Leather/LeafLegs.cs +++ b/Projects/UOContent/Items/Armor/Leather/LeafLegs.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] [Flippable(0x2FC9, 0x317F)] public partial class LeafLegs : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Leather/LeafTonlet.cs b/Projects/UOContent/Items/Armor/Leather/LeafTonlet.cs index 2aa652ddf..b627757e7 100644 --- a/Projects/UOContent/Items/Armor/Leather/LeafTonlet.cs +++ b/Projects/UOContent/Items/Armor/Leather/LeafTonlet.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] [Flippable(0x2FCA, 0x3180)] public partial class LeafTonlet : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Leather/LeatherArms.cs b/Projects/UOContent/Items/Armor/Leather/LeatherArms.cs index d2b399f33..f092fb371 100644 --- a/Projects/UOContent/Items/Armor/Leather/LeatherArms.cs +++ b/Projects/UOContent/Items/Armor/Leather/LeatherArms.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x13cd, 0x13c5)] public partial class LeatherArms : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Leather/LeatherBustierArms.cs b/Projects/UOContent/Items/Armor/Leather/LeatherBustierArms.cs index e480f1753..5e7bd8e9a 100644 --- a/Projects/UOContent/Items/Armor/Leather/LeatherBustierArms.cs +++ b/Projects/UOContent/Items/Armor/Leather/LeatherBustierArms.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1c0a, 0x1c0b)] public partial class LeatherBustierArms : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Leather/LeatherChest.cs b/Projects/UOContent/Items/Armor/Leather/LeatherChest.cs index 7bf28c097..e66f20ef1 100644 --- a/Projects/UOContent/Items/Armor/Leather/LeatherChest.cs +++ b/Projects/UOContent/Items/Armor/Leather/LeatherChest.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x13cc, 0x13d3)] public partial class LeatherChest : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Leather/LeatherDo.cs b/Projects/UOContent/Items/Armor/Leather/LeatherDo.cs index 0b389285c..a0450165e 100644 --- a/Projects/UOContent/Items/Armor/Leather/LeatherDo.cs +++ b/Projects/UOContent/Items/Armor/Leather/LeatherDo.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LeatherDo : BaseArmor { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Leather/LeatherGloves.cs b/Projects/UOContent/Items/Armor/Leather/LeatherGloves.cs index 7a79e95fe..7b0a8a2c0 100644 --- a/Projects/UOContent/Items/Armor/Leather/LeatherGloves.cs +++ b/Projects/UOContent/Items/Armor/Leather/LeatherGloves.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable] - [Serializable(2, false)] + [SerializationGenerator(2, false)] public partial class LeatherGloves : BaseArmor, IArcaneEquip { private int _maxArcaneCharges; diff --git a/Projects/UOContent/Items/Armor/Leather/LeatherGorget.cs b/Projects/UOContent/Items/Armor/Leather/LeatherGorget.cs index 07b8baf08..42eb16daf 100644 --- a/Projects/UOContent/Items/Armor/Leather/LeatherGorget.cs +++ b/Projects/UOContent/Items/Armor/Leather/LeatherGorget.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LeatherGorget : BaseArmor { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Leather/LeatherHaidate.cs b/Projects/UOContent/Items/Armor/Leather/LeatherHaidate.cs index 5a267ff4d..a4509020d 100644 --- a/Projects/UOContent/Items/Armor/Leather/LeatherHaidate.cs +++ b/Projects/UOContent/Items/Armor/Leather/LeatherHaidate.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LeatherHaidate : BaseArmor { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Leather/LeatherHiroSode.cs b/Projects/UOContent/Items/Armor/Leather/LeatherHiroSode.cs index 107940e01..6b54d1695 100644 --- a/Projects/UOContent/Items/Armor/Leather/LeatherHiroSode.cs +++ b/Projects/UOContent/Items/Armor/Leather/LeatherHiroSode.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LeatherHiroSode : BaseArmor { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Leather/LeatherJingasa.cs b/Projects/UOContent/Items/Armor/Leather/LeatherJingasa.cs index d26cd8793..a37ed89c0 100644 --- a/Projects/UOContent/Items/Armor/Leather/LeatherJingasa.cs +++ b/Projects/UOContent/Items/Armor/Leather/LeatherJingasa.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LeatherJingasa : BaseArmor { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Leather/LeatherLegs.cs b/Projects/UOContent/Items/Armor/Leather/LeatherLegs.cs index 9c3d88b98..2d83b9148 100644 --- a/Projects/UOContent/Items/Armor/Leather/LeatherLegs.cs +++ b/Projects/UOContent/Items/Armor/Leather/LeatherLegs.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x13cb, 0x13d2)] public partial class LeatherLegs : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Leather/LeatherMempo.cs b/Projects/UOContent/Items/Armor/Leather/LeatherMempo.cs index 4fda47995..5887692ab 100644 --- a/Projects/UOContent/Items/Armor/Leather/LeatherMempo.cs +++ b/Projects/UOContent/Items/Armor/Leather/LeatherMempo.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LeatherMempo : BaseArmor { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Leather/LeatherNinjaHood.cs b/Projects/UOContent/Items/Armor/Leather/LeatherNinjaHood.cs index b0c09710b..19d7cd049 100644 --- a/Projects/UOContent/Items/Armor/Leather/LeatherNinjaHood.cs +++ b/Projects/UOContent/Items/Armor/Leather/LeatherNinjaHood.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LeatherNinjaHood : BaseArmor { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Leather/LeatherNinjaJacket.cs b/Projects/UOContent/Items/Armor/Leather/LeatherNinjaJacket.cs index 05c5ab220..c27194003 100644 --- a/Projects/UOContent/Items/Armor/Leather/LeatherNinjaJacket.cs +++ b/Projects/UOContent/Items/Armor/Leather/LeatherNinjaJacket.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LeatherNinjaJacket : BaseArmor { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Leather/LeatherNinjaMitts.cs b/Projects/UOContent/Items/Armor/Leather/LeatherNinjaMitts.cs index 3e3586bfc..0112fafa3 100644 --- a/Projects/UOContent/Items/Armor/Leather/LeatherNinjaMitts.cs +++ b/Projects/UOContent/Items/Armor/Leather/LeatherNinjaMitts.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LeatherNinjaMitts : BaseArmor { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Leather/LeatherNinjaPants.cs b/Projects/UOContent/Items/Armor/Leather/LeatherNinjaPants.cs index c7fbd22e6..b21807d32 100644 --- a/Projects/UOContent/Items/Armor/Leather/LeatherNinjaPants.cs +++ b/Projects/UOContent/Items/Armor/Leather/LeatherNinjaPants.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LeatherNinjaPants : BaseArmor { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Leather/LeatherShorts.cs b/Projects/UOContent/Items/Armor/Leather/LeatherShorts.cs index 08cadaf62..b18307d99 100644 --- a/Projects/UOContent/Items/Armor/Leather/LeatherShorts.cs +++ b/Projects/UOContent/Items/Armor/Leather/LeatherShorts.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1c00, 0x1c01)] public partial class LeatherShorts : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Leather/LeatherSkirt.cs b/Projects/UOContent/Items/Armor/Leather/LeatherSkirt.cs index 6c351757c..acaaa09fb 100644 --- a/Projects/UOContent/Items/Armor/Leather/LeatherSkirt.cs +++ b/Projects/UOContent/Items/Armor/Leather/LeatherSkirt.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1c08, 0x1c09)] public partial class LeatherSkirt : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Leather/LeatherSuneate.cs b/Projects/UOContent/Items/Armor/Leather/LeatherSuneate.cs index 6262a83dc..31df6ddeb 100644 --- a/Projects/UOContent/Items/Armor/Leather/LeatherSuneate.cs +++ b/Projects/UOContent/Items/Armor/Leather/LeatherSuneate.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LeatherSuneate : BaseArmor { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Plate/DecorativePlateKabuto.cs b/Projects/UOContent/Items/Armor/Plate/DecorativePlateKabuto.cs index f24620620..e8d99a675 100644 --- a/Projects/UOContent/Items/Armor/Plate/DecorativePlateKabuto.cs +++ b/Projects/UOContent/Items/Armor/Plate/DecorativePlateKabuto.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class DecorativePlateKabuto : BaseArmor { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Plate/FemalePlateChest.cs b/Projects/UOContent/Items/Armor/Plate/FemalePlateChest.cs index 5298e68f9..76bd975b4 100644 --- a/Projects/UOContent/Items/Armor/Plate/FemalePlateChest.cs +++ b/Projects/UOContent/Items/Armor/Plate/FemalePlateChest.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1c04, 0x1c05)] public partial class FemalePlateChest : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Plate/FemaleWoodlandChest.cs b/Projects/UOContent/Items/Armor/Plate/FemaleWoodlandChest.cs index 2dcfce8a1..5ac5a42ab 100644 --- a/Projects/UOContent/Items/Armor/Plate/FemaleWoodlandChest.cs +++ b/Projects/UOContent/Items/Armor/Plate/FemaleWoodlandChest.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] [Flippable(0x2B6D, 0x3164)] public partial class FemaleElvenPlateChest : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Plate/HeavyPlateJingasa.cs b/Projects/UOContent/Items/Armor/Plate/HeavyPlateJingasa.cs index f98e3c58b..b35003750 100644 --- a/Projects/UOContent/Items/Armor/Plate/HeavyPlateJingasa.cs +++ b/Projects/UOContent/Items/Armor/Plate/HeavyPlateJingasa.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class HeavyPlateJingasa : BaseArmor { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Plate/LightPlateJingasa.cs b/Projects/UOContent/Items/Armor/Plate/LightPlateJingasa.cs index a8024d88f..1f35c50ae 100644 --- a/Projects/UOContent/Items/Armor/Plate/LightPlateJingasa.cs +++ b/Projects/UOContent/Items/Armor/Plate/LightPlateJingasa.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LightPlateJingasa : BaseArmor { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Plate/PlateArms.cs b/Projects/UOContent/Items/Armor/Plate/PlateArms.cs index 2269150fa..1e4505195 100644 --- a/Projects/UOContent/Items/Armor/Plate/PlateArms.cs +++ b/Projects/UOContent/Items/Armor/Plate/PlateArms.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1410, 0x1417)] public partial class PlateArms : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Plate/PlateBattleKabuto.cs b/Projects/UOContent/Items/Armor/Plate/PlateBattleKabuto.cs index 8a6aa5289..cc882ec5b 100644 --- a/Projects/UOContent/Items/Armor/Plate/PlateBattleKabuto.cs +++ b/Projects/UOContent/Items/Armor/Plate/PlateBattleKabuto.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class PlateBattleKabuto : BaseArmor { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Plate/PlateChest.cs b/Projects/UOContent/Items/Armor/Plate/PlateChest.cs index 4a00f339d..60375189a 100644 --- a/Projects/UOContent/Items/Armor/Plate/PlateChest.cs +++ b/Projects/UOContent/Items/Armor/Plate/PlateChest.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1415, 0x1416)] public partial class PlateChest : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Plate/PlateDo.cs b/Projects/UOContent/Items/Armor/Plate/PlateDo.cs index 44fdf73f2..de8ecd5f1 100644 --- a/Projects/UOContent/Items/Armor/Plate/PlateDo.cs +++ b/Projects/UOContent/Items/Armor/Plate/PlateDo.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class PlateDo : BaseArmor { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Plate/PlateGloves.cs b/Projects/UOContent/Items/Armor/Plate/PlateGloves.cs index bf10b5751..2303f2a83 100644 --- a/Projects/UOContent/Items/Armor/Plate/PlateGloves.cs +++ b/Projects/UOContent/Items/Armor/Plate/PlateGloves.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1414, 0x1418)] public partial class PlateGloves : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Plate/PlateGorget.cs b/Projects/UOContent/Items/Armor/Plate/PlateGorget.cs index 10880dad2..27ea17e0f 100644 --- a/Projects/UOContent/Items/Armor/Plate/PlateGorget.cs +++ b/Projects/UOContent/Items/Armor/Plate/PlateGorget.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class PlateGorget : BaseArmor { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Plate/PlateHaidate.cs b/Projects/UOContent/Items/Armor/Plate/PlateHaidate.cs index 04e192ce2..ae238cf3b 100644 --- a/Projects/UOContent/Items/Armor/Plate/PlateHaidate.cs +++ b/Projects/UOContent/Items/Armor/Plate/PlateHaidate.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class PlateHaidate : BaseArmor { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Plate/PlateHatsuburi.cs b/Projects/UOContent/Items/Armor/Plate/PlateHatsuburi.cs index 7d0e43054..cb629b4ce 100644 --- a/Projects/UOContent/Items/Armor/Plate/PlateHatsuburi.cs +++ b/Projects/UOContent/Items/Armor/Plate/PlateHatsuburi.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class PlateHatsuburi : BaseArmor { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Plate/PlateHiroSode.cs b/Projects/UOContent/Items/Armor/Plate/PlateHiroSode.cs index e565693f6..2f272a4a7 100644 --- a/Projects/UOContent/Items/Armor/Plate/PlateHiroSode.cs +++ b/Projects/UOContent/Items/Armor/Plate/PlateHiroSode.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class PlateHiroSode : BaseArmor { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Plate/PlateLegs.cs b/Projects/UOContent/Items/Armor/Plate/PlateLegs.cs index c633ca873..cc69bfce6 100644 --- a/Projects/UOContent/Items/Armor/Plate/PlateLegs.cs +++ b/Projects/UOContent/Items/Armor/Plate/PlateLegs.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1411, 0x141a)] public partial class PlateLegs : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Plate/PlateMempo.cs b/Projects/UOContent/Items/Armor/Plate/PlateMempo.cs index c42e3c84b..257dcce97 100644 --- a/Projects/UOContent/Items/Armor/Plate/PlateMempo.cs +++ b/Projects/UOContent/Items/Armor/Plate/PlateMempo.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class PlateMempo : BaseArmor { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Plate/PlateSuneate.cs b/Projects/UOContent/Items/Armor/Plate/PlateSuneate.cs index ae8298b63..dce3c24fa 100644 --- a/Projects/UOContent/Items/Armor/Plate/PlateSuneate.cs +++ b/Projects/UOContent/Items/Armor/Plate/PlateSuneate.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class PlateSuneate : BaseArmor { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Plate/SmallPlateJingasa.cs b/Projects/UOContent/Items/Armor/Plate/SmallPlateJingasa.cs index 592cc447c..3d3112286 100644 --- a/Projects/UOContent/Items/Armor/Plate/SmallPlateJingasa.cs +++ b/Projects/UOContent/Items/Armor/Plate/SmallPlateJingasa.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class SmallPlateJingasa : BaseArmor { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Plate/StandardPlateKabuto.cs b/Projects/UOContent/Items/Armor/Plate/StandardPlateKabuto.cs index cf23240c3..be98d3a65 100644 --- a/Projects/UOContent/Items/Armor/Plate/StandardPlateKabuto.cs +++ b/Projects/UOContent/Items/Armor/Plate/StandardPlateKabuto.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class StandardPlateKabuto : BaseArmor { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Plate/WoodlandArms.cs b/Projects/UOContent/Items/Armor/Plate/WoodlandArms.cs index 8517da829..582bfed08 100644 --- a/Projects/UOContent/Items/Armor/Plate/WoodlandArms.cs +++ b/Projects/UOContent/Items/Armor/Plate/WoodlandArms.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] [Flippable(0x2B6C, 0x3163)] public partial class WoodlandArms : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Plate/WoodlandChest.cs b/Projects/UOContent/Items/Armor/Plate/WoodlandChest.cs index c90b21fce..9fb9e6567 100644 --- a/Projects/UOContent/Items/Armor/Plate/WoodlandChest.cs +++ b/Projects/UOContent/Items/Armor/Plate/WoodlandChest.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] [Flippable(0x2B67, 0x315E)] public partial class WoodlandChest : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Plate/WoodlandGloves.cs b/Projects/UOContent/Items/Armor/Plate/WoodlandGloves.cs index 7ea514016..40455c089 100644 --- a/Projects/UOContent/Items/Armor/Plate/WoodlandGloves.cs +++ b/Projects/UOContent/Items/Armor/Plate/WoodlandGloves.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] [Flippable(0x2B6A, 0x3161)] public partial class WoodlandGloves : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Plate/WoodlandGorget.cs b/Projects/UOContent/Items/Armor/Plate/WoodlandGorget.cs index 492d1216e..1554576fe 100644 --- a/Projects/UOContent/Items/Armor/Plate/WoodlandGorget.cs +++ b/Projects/UOContent/Items/Armor/Plate/WoodlandGorget.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] [Flippable(0x2B69, 0x3160)] public partial class WoodlandGorget : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Plate/WoodlandLegs.cs b/Projects/UOContent/Items/Armor/Plate/WoodlandLegs.cs index ee10d8f65..ec16588aa 100644 --- a/Projects/UOContent/Items/Armor/Plate/WoodlandLegs.cs +++ b/Projects/UOContent/Items/Armor/Plate/WoodlandLegs.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] [Flippable(0x2B6B, 0x3162)] public partial class WoodlandLegs : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Ranger/RangerArms.cs b/Projects/UOContent/Items/Armor/Ranger/RangerArms.cs index 5745de85a..6eb5864db 100644 --- a/Projects/UOContent/Items/Armor/Ranger/RangerArms.cs +++ b/Projects/UOContent/Items/Armor/Ranger/RangerArms.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x13dc, 0x13d4)] public partial class RangerArms : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Ranger/RangerChest.cs b/Projects/UOContent/Items/Armor/Ranger/RangerChest.cs index 2b573a11a..e2a6054f5 100644 --- a/Projects/UOContent/Items/Armor/Ranger/RangerChest.cs +++ b/Projects/UOContent/Items/Armor/Ranger/RangerChest.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x13db, 0x13e2)] public partial class RangerChest : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Ranger/RangerGloves.cs b/Projects/UOContent/Items/Armor/Ranger/RangerGloves.cs index 2a42a14d3..b51b766e6 100644 --- a/Projects/UOContent/Items/Armor/Ranger/RangerGloves.cs +++ b/Projects/UOContent/Items/Armor/Ranger/RangerGloves.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x13d5, 0x13dd)] public partial class RangerGloves : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Ranger/RangerGorget.cs b/Projects/UOContent/Items/Armor/Ranger/RangerGorget.cs index 13c751303..e9a4a6949 100644 --- a/Projects/UOContent/Items/Armor/Ranger/RangerGorget.cs +++ b/Projects/UOContent/Items/Armor/Ranger/RangerGorget.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class RangerGorget : BaseArmor { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Ranger/RangerLegs.cs b/Projects/UOContent/Items/Armor/Ranger/RangerLegs.cs index 39549df6e..7fae0424a 100644 --- a/Projects/UOContent/Items/Armor/Ranger/RangerLegs.cs +++ b/Projects/UOContent/Items/Armor/Ranger/RangerLegs.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x13da, 0x13e1)] public partial class RangerLegs : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Ring/RingmailArms.cs b/Projects/UOContent/Items/Armor/Ring/RingmailArms.cs index b22ac9ca0..c9d1061e0 100644 --- a/Projects/UOContent/Items/Armor/Ring/RingmailArms.cs +++ b/Projects/UOContent/Items/Armor/Ring/RingmailArms.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x13ee, 0x13ef)] public partial class RingmailArms : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Ring/RingmailChest.cs b/Projects/UOContent/Items/Armor/Ring/RingmailChest.cs index 3c43daf7d..e01dd908e 100644 --- a/Projects/UOContent/Items/Armor/Ring/RingmailChest.cs +++ b/Projects/UOContent/Items/Armor/Ring/RingmailChest.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x13ec, 0x13ed)] public partial class RingmailChest : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Ring/RingmailGloves.cs b/Projects/UOContent/Items/Armor/Ring/RingmailGloves.cs index 15f3ab0d2..b57887f80 100644 --- a/Projects/UOContent/Items/Armor/Ring/RingmailGloves.cs +++ b/Projects/UOContent/Items/Armor/Ring/RingmailGloves.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x13eb, 0x13f2)] public partial class RingmailGloves : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Ring/RingmailLegs.cs b/Projects/UOContent/Items/Armor/Ring/RingmailLegs.cs index 1704cbf71..189a8597d 100644 --- a/Projects/UOContent/Items/Armor/Ring/RingmailLegs.cs +++ b/Projects/UOContent/Items/Armor/Ring/RingmailLegs.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x13f0, 0x13f1)] public partial class RingmailLegs : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Stone/GargishStoneArmsType1.cs b/Projects/UOContent/Items/Armor/Stone/GargishStoneArmsType1.cs index e9223b58f..8e28498d0 100644 --- a/Projects/UOContent/Items/Armor/Stone/GargishStoneArmsType1.cs +++ b/Projects/UOContent/Items/Armor/Stone/GargishStoneArmsType1.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [TypeAlias("Server.Items.GargishStoneArms")] public partial class GargishStoneArmsType1 : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Stone/GargishStoneArmsType2.cs b/Projects/UOContent/Items/Armor/Stone/GargishStoneArmsType2.cs index ec9a5cefc..9198bf879 100644 --- a/Projects/UOContent/Items/Armor/Stone/GargishStoneArmsType2.cs +++ b/Projects/UOContent/Items/Armor/Stone/GargishStoneArmsType2.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [TypeAlias("Server.Items.FemaleGargishStoneArms")] public partial class GargishStoneArmsType2 : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Stone/GargishStoneChestType1.cs b/Projects/UOContent/Items/Armor/Stone/GargishStoneChestType1.cs index 8aafab468..25b39d0eb 100644 --- a/Projects/UOContent/Items/Armor/Stone/GargishStoneChestType1.cs +++ b/Projects/UOContent/Items/Armor/Stone/GargishStoneChestType1.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [TypeAlias("Server.Items.GargishStoneChest")] public partial class GargishStoneChestType1 : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Stone/GargishStoneChestType2.cs b/Projects/UOContent/Items/Armor/Stone/GargishStoneChestType2.cs index 78fa08650..81bb3b928 100644 --- a/Projects/UOContent/Items/Armor/Stone/GargishStoneChestType2.cs +++ b/Projects/UOContent/Items/Armor/Stone/GargishStoneChestType2.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [TypeAlias("Server.Items.FemaleGargishStoneChest")] public partial class GargishStoneChestType2 : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Stone/GargishStoneKiltType1.cs b/Projects/UOContent/Items/Armor/Stone/GargishStoneKiltType1.cs index cf826661f..501a9cbf2 100644 --- a/Projects/UOContent/Items/Armor/Stone/GargishStoneKiltType1.cs +++ b/Projects/UOContent/Items/Armor/Stone/GargishStoneKiltType1.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [TypeAlias("Server.Items.GargishStoneKilt")] public partial class GargishStoneKiltType1 : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Stone/GargishStoneKiltType2.cs b/Projects/UOContent/Items/Armor/Stone/GargishStoneKiltType2.cs index 7ca6f2363..43103cd72 100644 --- a/Projects/UOContent/Items/Armor/Stone/GargishStoneKiltType2.cs +++ b/Projects/UOContent/Items/Armor/Stone/GargishStoneKiltType2.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [TypeAlias("Server.Items.FemaleGargishStoneKilt")] public partial class GargishStoneKiltType2 : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Stone/GargishStoneLegsType1.cs b/Projects/UOContent/Items/Armor/Stone/GargishStoneLegsType1.cs index 3974d969a..c8a683f91 100644 --- a/Projects/UOContent/Items/Armor/Stone/GargishStoneLegsType1.cs +++ b/Projects/UOContent/Items/Armor/Stone/GargishStoneLegsType1.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [TypeAlias("Server.Items.GargishStoneLegs")] public partial class GargishStoneLegsType1 : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Stone/GargishStoneLegsType2.cs b/Projects/UOContent/Items/Armor/Stone/GargishStoneLegsType2.cs index 90707fc02..f5ab12bbf 100644 --- a/Projects/UOContent/Items/Armor/Stone/GargishStoneLegsType2.cs +++ b/Projects/UOContent/Items/Armor/Stone/GargishStoneLegsType2.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [TypeAlias("Server.Items.FemaleGargishStoneLegs")] public partial class GargishStoneLegsType2 : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Studded/FemaleStuddedChest.cs b/Projects/UOContent/Items/Armor/Studded/FemaleStuddedChest.cs index 5a378aeed..9034f797a 100644 --- a/Projects/UOContent/Items/Armor/Studded/FemaleStuddedChest.cs +++ b/Projects/UOContent/Items/Armor/Studded/FemaleStuddedChest.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1c02, 0x1c03)] public partial class FemaleStuddedChest : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Studded/GargishStuddedArmsType1.cs b/Projects/UOContent/Items/Armor/Studded/GargishStuddedArmsType1.cs index 6cd2fcb02..9d3279ae2 100644 --- a/Projects/UOContent/Items/Armor/Studded/GargishStuddedArmsType1.cs +++ b/Projects/UOContent/Items/Armor/Studded/GargishStuddedArmsType1.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [TypeAlias("Server.Items.GargishStuddedArms")] public partial class GargishStuddedArmsType1 : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Studded/GargishStuddedArmsType2.cs b/Projects/UOContent/Items/Armor/Studded/GargishStuddedArmsType2.cs index 35d76fbe2..c30396f45 100644 --- a/Projects/UOContent/Items/Armor/Studded/GargishStuddedArmsType2.cs +++ b/Projects/UOContent/Items/Armor/Studded/GargishStuddedArmsType2.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [TypeAlias("Server.Items.FemaleGargishStuddedArms")] public partial class GargishStuddedArmsType2 : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Studded/GargishStuddedChestType1.cs b/Projects/UOContent/Items/Armor/Studded/GargishStuddedChestType1.cs index 4245fbd33..6d3305544 100644 --- a/Projects/UOContent/Items/Armor/Studded/GargishStuddedChestType1.cs +++ b/Projects/UOContent/Items/Armor/Studded/GargishStuddedChestType1.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [TypeAlias("Server.Items.GargishStuddedChest")] public partial class GargishStuddedChestType1 : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Studded/GargishStuddedChestType2.cs b/Projects/UOContent/Items/Armor/Studded/GargishStuddedChestType2.cs index 1c5a78f59..ef80c6847 100644 --- a/Projects/UOContent/Items/Armor/Studded/GargishStuddedChestType2.cs +++ b/Projects/UOContent/Items/Armor/Studded/GargishStuddedChestType2.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [TypeAlias("Server.Items.FemaleGargishStuddedChest")] public partial class GargishStuddedChestType2 : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Studded/GargishStuddedKiltType1.cs b/Projects/UOContent/Items/Armor/Studded/GargishStuddedKiltType1.cs index fda72ba8d..2b61adb4d 100644 --- a/Projects/UOContent/Items/Armor/Studded/GargishStuddedKiltType1.cs +++ b/Projects/UOContent/Items/Armor/Studded/GargishStuddedKiltType1.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [TypeAlias("Server.Items.GargishStuddedKilt")] public partial class GargishStuddedKiltType1 : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Studded/GargishStuddedKiltType2.cs b/Projects/UOContent/Items/Armor/Studded/GargishStuddedKiltType2.cs index 9ea5e74c9..a5d60040f 100644 --- a/Projects/UOContent/Items/Armor/Studded/GargishStuddedKiltType2.cs +++ b/Projects/UOContent/Items/Armor/Studded/GargishStuddedKiltType2.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [TypeAlias("Server.Items.FemaleGargishStuddedKilt")] public partial class GargishStuddedKiltType2 : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Studded/GargishStuddedLegsType1.cs b/Projects/UOContent/Items/Armor/Studded/GargishStuddedLegsType1.cs index 81cb4bb1d..8b98f861b 100644 --- a/Projects/UOContent/Items/Armor/Studded/GargishStuddedLegsType1.cs +++ b/Projects/UOContent/Items/Armor/Studded/GargishStuddedLegsType1.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [TypeAlias("Server.Items.GargishStuddedLegs")] public partial class GargishStuddedLegsType1 : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Studded/GargishStuddedLegsType2.cs b/Projects/UOContent/Items/Armor/Studded/GargishStuddedLegsType2.cs index aa2496357..3984ad6eb 100644 --- a/Projects/UOContent/Items/Armor/Studded/GargishStuddedLegsType2.cs +++ b/Projects/UOContent/Items/Armor/Studded/GargishStuddedLegsType2.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [TypeAlias("Server.Items.FemaleGargishStuddedLegs")] public partial class GargishStuddedLegsType2 : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Studded/HideChest.cs b/Projects/UOContent/Items/Armor/Studded/HideChest.cs index d7c2ab30d..b853279ba 100644 --- a/Projects/UOContent/Items/Armor/Studded/HideChest.cs +++ b/Projects/UOContent/Items/Armor/Studded/HideChest.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] [Flippable(0x2B74, 0x316B)] public partial class HideChest : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Studded/HideFemaleChest.cs b/Projects/UOContent/Items/Armor/Studded/HideFemaleChest.cs index cd7529b4b..acafa6b7f 100644 --- a/Projects/UOContent/Items/Armor/Studded/HideFemaleChest.cs +++ b/Projects/UOContent/Items/Armor/Studded/HideFemaleChest.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] [Flippable(0x2B79, 0x3170)] public partial class HideFemaleChest : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Studded/HideGloves.cs b/Projects/UOContent/Items/Armor/Studded/HideGloves.cs index c3a6a915c..cc9bde92a 100644 --- a/Projects/UOContent/Items/Armor/Studded/HideGloves.cs +++ b/Projects/UOContent/Items/Armor/Studded/HideGloves.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] [Flippable(0x2B75, 0x316C)] public partial class HideGloves : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Studded/HideGorget.cs b/Projects/UOContent/Items/Armor/Studded/HideGorget.cs index 9473afc3d..831c816da 100644 --- a/Projects/UOContent/Items/Armor/Studded/HideGorget.cs +++ b/Projects/UOContent/Items/Armor/Studded/HideGorget.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x2B76, 0x316D)] public partial class HideGorget : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Studded/HidePants.cs b/Projects/UOContent/Items/Armor/Studded/HidePants.cs index 200861c35..3b952d3bc 100644 --- a/Projects/UOContent/Items/Armor/Studded/HidePants.cs +++ b/Projects/UOContent/Items/Armor/Studded/HidePants.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] [Flippable(0x2B78, 0x316F)] public partial class HidePants : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Studded/HidePauldrons.cs b/Projects/UOContent/Items/Armor/Studded/HidePauldrons.cs index a91c1cb1a..0eb6b8b3d 100644 --- a/Projects/UOContent/Items/Armor/Studded/HidePauldrons.cs +++ b/Projects/UOContent/Items/Armor/Studded/HidePauldrons.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] [Flippable(0x2B77, 0x316E)] public partial class HidePauldrons : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Studded/StuddedArms.cs b/Projects/UOContent/Items/Armor/Studded/StuddedArms.cs index 3d16400d2..4fa9de780 100644 --- a/Projects/UOContent/Items/Armor/Studded/StuddedArms.cs +++ b/Projects/UOContent/Items/Armor/Studded/StuddedArms.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x13dc, 0x13d4)] public partial class StuddedArms : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Studded/StuddedBustierArms.cs b/Projects/UOContent/Items/Armor/Studded/StuddedBustierArms.cs index 5f55712ff..3dd466c49 100644 --- a/Projects/UOContent/Items/Armor/Studded/StuddedBustierArms.cs +++ b/Projects/UOContent/Items/Armor/Studded/StuddedBustierArms.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1c0c, 0x1c0d)] public partial class StuddedBustierArms : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Studded/StuddedChest.cs b/Projects/UOContent/Items/Armor/Studded/StuddedChest.cs index 99d1ac8b8..2698f5b09 100644 --- a/Projects/UOContent/Items/Armor/Studded/StuddedChest.cs +++ b/Projects/UOContent/Items/Armor/Studded/StuddedChest.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x13db, 0x13e2)] public partial class StuddedChest : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Studded/StuddedDo.cs b/Projects/UOContent/Items/Armor/Studded/StuddedDo.cs index adf62707a..692076af7 100644 --- a/Projects/UOContent/Items/Armor/Studded/StuddedDo.cs +++ b/Projects/UOContent/Items/Armor/Studded/StuddedDo.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class StuddedDo : BaseArmor { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Studded/StuddedGloves.cs b/Projects/UOContent/Items/Armor/Studded/StuddedGloves.cs index c6977efb1..aa2d585ea 100644 --- a/Projects/UOContent/Items/Armor/Studded/StuddedGloves.cs +++ b/Projects/UOContent/Items/Armor/Studded/StuddedGloves.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x13d5, 0x13dd)] public partial class StuddedGloves : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Studded/StuddedGorget.cs b/Projects/UOContent/Items/Armor/Studded/StuddedGorget.cs index d72ba4199..079d99e3a 100644 --- a/Projects/UOContent/Items/Armor/Studded/StuddedGorget.cs +++ b/Projects/UOContent/Items/Armor/Studded/StuddedGorget.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class StuddedGorget : BaseArmor { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Studded/StuddedHaidate.cs b/Projects/UOContent/Items/Armor/Studded/StuddedHaidate.cs index b719c1fe9..26b41dd45 100644 --- a/Projects/UOContent/Items/Armor/Studded/StuddedHaidate.cs +++ b/Projects/UOContent/Items/Armor/Studded/StuddedHaidate.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class StuddedHaidate : BaseArmor { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Studded/StuddedHiroSode.cs b/Projects/UOContent/Items/Armor/Studded/StuddedHiroSode.cs index 145e1c7cb..0b0afd5bd 100644 --- a/Projects/UOContent/Items/Armor/Studded/StuddedHiroSode.cs +++ b/Projects/UOContent/Items/Armor/Studded/StuddedHiroSode.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class StuddedHiroSode : BaseArmor { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Studded/StuddedLegs.cs b/Projects/UOContent/Items/Armor/Studded/StuddedLegs.cs index 24a77c890..85863125b 100644 --- a/Projects/UOContent/Items/Armor/Studded/StuddedLegs.cs +++ b/Projects/UOContent/Items/Armor/Studded/StuddedLegs.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x13da, 0x13e1)] public partial class StuddedLegs : BaseArmor { diff --git a/Projects/UOContent/Items/Armor/Studded/StuddedMempo.cs b/Projects/UOContent/Items/Armor/Studded/StuddedMempo.cs index 252c836e7..31b0b9a82 100644 --- a/Projects/UOContent/Items/Armor/Studded/StuddedMempo.cs +++ b/Projects/UOContent/Items/Armor/Studded/StuddedMempo.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class StuddedMempo : BaseArmor { [Constructible] diff --git a/Projects/UOContent/Items/Armor/Studded/StuddedSuneate.cs b/Projects/UOContent/Items/Armor/Studded/StuddedSuneate.cs index 55b77c2a5..f57939ea1 100644 --- a/Projects/UOContent/Items/Armor/Studded/StuddedSuneate.cs +++ b/Projects/UOContent/Items/Armor/Studded/StuddedSuneate.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class StuddedSuneate : BaseArmor { [Constructible] diff --git a/Projects/UOContent/Items/Body Parts/BonePile.cs b/Projects/UOContent/Items/Body Parts/BonePile.cs index 64e3e90d0..04fcadcda 100644 --- a/Projects/UOContent/Items/Body Parts/BonePile.cs +++ b/Projects/UOContent/Items/Body Parts/BonePile.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1B09, 0x1B10)] public partial class BonePile : Item, IScissorable { diff --git a/Projects/UOContent/Items/Body Parts/Head.cs b/Projects/UOContent/Items/Body Parts/Head.cs index 39f4078f7..c5c67ed6a 100644 --- a/Projects/UOContent/Items/Body Parts/Head.cs +++ b/Projects/UOContent/Items/Body Parts/Head.cs @@ -1,3 +1,5 @@ +using ModernUO.Serialization; + namespace Server.Items { public enum HeadType @@ -7,7 +9,7 @@ namespace Server.Items Tournament } - [Serializable(1, false)] + [SerializationGenerator(1, false)] public partial class Head : Item { [SerializableField(0)] diff --git a/Projects/UOContent/Items/Body Parts/LeftArm.cs b/Projects/UOContent/Items/Body Parts/LeftArm.cs index 6e514fc52..1ff09dea0 100644 --- a/Projects/UOContent/Items/Body Parts/LeftArm.cs +++ b/Projects/UOContent/Items/Body Parts/LeftArm.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LeftArm : Item { [Constructible] diff --git a/Projects/UOContent/Items/Body Parts/LeftLeg.cs b/Projects/UOContent/Items/Body Parts/LeftLeg.cs index 620e169f9..2495b97d6 100644 --- a/Projects/UOContent/Items/Body Parts/LeftLeg.cs +++ b/Projects/UOContent/Items/Body Parts/LeftLeg.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LeftLeg : Item { [Constructible] diff --git a/Projects/UOContent/Items/Body Parts/RibCage.cs b/Projects/UOContent/Items/Body Parts/RibCage.cs index 0267b8165..0b02dfce0 100644 --- a/Projects/UOContent/Items/Body Parts/RibCage.cs +++ b/Projects/UOContent/Items/Body Parts/RibCage.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1B17, 0x1B18)] public partial class RibCage : Item, IScissorable { diff --git a/Projects/UOContent/Items/Body Parts/RightArm.cs b/Projects/UOContent/Items/Body Parts/RightArm.cs index 4adc9ca5a..2360cc447 100644 --- a/Projects/UOContent/Items/Body Parts/RightArm.cs +++ b/Projects/UOContent/Items/Body Parts/RightArm.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class RightArm : Item { [Constructible] diff --git a/Projects/UOContent/Items/Body Parts/RightLeg.cs b/Projects/UOContent/Items/Body Parts/RightLeg.cs index b9fcd60fb..c7eff68e7 100644 --- a/Projects/UOContent/Items/Body Parts/RightLeg.cs +++ b/Projects/UOContent/Items/Body Parts/RightLeg.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class RightLeg : Item { [Constructible] diff --git a/Projects/UOContent/Items/Body Parts/Torso.cs b/Projects/UOContent/Items/Body Parts/Torso.cs index 68a1add55..8a26dbecf 100644 --- a/Projects/UOContent/Items/Body Parts/Torso.cs +++ b/Projects/UOContent/Items/Body Parts/Torso.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Torso : Item { [Constructible] diff --git a/Projects/UOContent/Items/Books/BaseBook.cs b/Projects/UOContent/Items/Books/BaseBook.cs index 52a703f82..85f62eee1 100644 --- a/Projects/UOContent/Items/Books/BaseBook.cs +++ b/Projects/UOContent/Items/Books/BaseBook.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using ModernUO.Serialization; using Server.Buffers; using Server.ContextMenus; using Server.Gumps; @@ -7,7 +8,7 @@ using Server.Multis; namespace Server.Items { - [Serializable(5, false)] + [SerializationGenerator(5, false)] public partial class BaseBook : Item, ISecurable { [SerializableField(0)] diff --git a/Projects/UOContent/Items/Books/BlueBook.cs b/Projects/UOContent/Items/Books/BlueBook.cs index f8e1ef965..2a47dd817 100644 --- a/Projects/UOContent/Items/Books/BlueBook.cs +++ b/Projects/UOContent/Items/Books/BlueBook.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class BlueBook : BaseBook { [Constructible] diff --git a/Projects/UOContent/Items/Books/BrownBook.cs b/Projects/UOContent/Items/Books/BrownBook.cs index e0083a744..f845a8875 100644 --- a/Projects/UOContent/Items/Books/BrownBook.cs +++ b/Projects/UOContent/Items/Books/BrownBook.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class BrownBook : BaseBook { [Constructible] diff --git a/Projects/UOContent/Items/Books/Defined/BlackthornWelcomeBook.cs b/Projects/UOContent/Items/Books/Defined/BlackthornWelcomeBook.cs index 78e0ffffd..2f103ccec 100644 --- a/Projects/UOContent/Items/Books/Defined/BlackthornWelcomeBook.cs +++ b/Projects/UOContent/Items/Books/Defined/BlackthornWelcomeBook.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class BlackthornWelcomeBook : RedBook { public static readonly BookContent Content = new( diff --git a/Projects/UOContent/Items/Books/Defined/DrakovsJournal.cs b/Projects/UOContent/Items/Books/Defined/DrakovsJournal.cs index 09b8c4bf6..eab1cc2e5 100644 --- a/Projects/UOContent/Items/Books/Defined/DrakovsJournal.cs +++ b/Projects/UOContent/Items/Books/Defined/DrakovsJournal.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class DrakovsJournal : BlueBook { public static readonly BookContent Content = new( diff --git a/Projects/UOContent/Items/Books/Defined/FropozJournal.cs b/Projects/UOContent/Items/Books/Defined/FropozJournal.cs index a2d361ea6..9051e678a 100644 --- a/Projects/UOContent/Items/Books/Defined/FropozJournal.cs +++ b/Projects/UOContent/Items/Books/Defined/FropozJournal.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class FropozJournal : RedBook { public static readonly BookContent Content = new( diff --git a/Projects/UOContent/Items/Books/Defined/KaburJournal.cs b/Projects/UOContent/Items/Books/Defined/KaburJournal.cs index 69da71ca6..fbbad7317 100644 --- a/Projects/UOContent/Items/Books/Defined/KaburJournal.cs +++ b/Projects/UOContent/Items/Books/Defined/KaburJournal.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class KaburJournal : RedBook { public static readonly BookContent Content = new( diff --git a/Projects/UOContent/Items/Books/Defined/LibraryBooks.cs b/Projects/UOContent/Items/Books/Defined/LibraryBooks.cs index 6bdf73831..615bb756b 100644 --- a/Projects/UOContent/Items/Books/Defined/LibraryBooks.cs +++ b/Projects/UOContent/Items/Books/Defined/LibraryBooks.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class GrammarOfOrcish : BaseBook { public static readonly BookContent Content = new( @@ -246,7 +248,7 @@ namespace Server.Items public override BookContent DefaultContent => Content; } - [Serializable(0)] + [SerializationGenerator(0)] public partial class CallToAnarchy : BaseBook { public static readonly BookContent Content = new( @@ -407,7 +409,7 @@ namespace Server.Items public override BookContent DefaultContent => Content; } - [Serializable(0)] + [SerializationGenerator(0)] public partial class ArmsAndWeaponsPrimer : BaseBook { public static readonly BookContent Content = new( @@ -578,7 +580,7 @@ namespace Server.Items public override BookContent DefaultContent => Content; } - [Serializable(0)] + [SerializationGenerator(0)] public partial class SongOfSamlethe : BaseBook { public static readonly BookContent Content = new( @@ -647,7 +649,7 @@ namespace Server.Items public override BookContent DefaultContent => Content; } - [Serializable(0)] + [SerializationGenerator(0)] public partial class TaleOfThreeTribes : BaseBook { public static readonly BookContent Content = new( @@ -759,7 +761,7 @@ namespace Server.Items public override BookContent DefaultContent => Content; } - [Serializable(0)] + [SerializationGenerator(0)] public partial class GuideToGuilds : BaseBook { public static readonly BookContent Content = new( @@ -947,7 +949,7 @@ namespace Server.Items public override BookContent DefaultContent => Content; } - [Serializable(0)] + [SerializationGenerator(0)] public partial class BirdsOfBritannia : BaseBook { public static readonly BookContent Content = new( @@ -1237,7 +1239,7 @@ namespace Server.Items public override BookContent DefaultContent => Content; } - [Serializable(0)] + [SerializationGenerator(0)] public partial class BritannianFlora : BaseBook { public static readonly BookContent Content = new( @@ -1432,7 +1434,7 @@ namespace Server.Items public override BookContent DefaultContent => Content; } - [Serializable(0)] + [SerializationGenerator(0)] public partial class ChildrenTalesVol2 : BaseBook { public static readonly BookContent Content = new( @@ -1539,7 +1541,7 @@ namespace Server.Items public override BookContent DefaultContent => Content; } - [Serializable(0)] + [SerializationGenerator(0)] public partial class TalesOfVesperVol1 : BaseBook { public static readonly BookContent Content = new( @@ -1760,7 +1762,7 @@ namespace Server.Items public override BookContent DefaultContent => Content; } - [Serializable(0)] + [SerializationGenerator(0)] public partial class DeceitDungeonOfHorror : BaseBook { public static readonly BookContent Content = new( @@ -1892,7 +1894,7 @@ namespace Server.Items public override BookContent DefaultContent => Content; } - [Serializable(0)] + [SerializationGenerator(0)] public partial class DimensionalTravel : BaseBook { public static readonly BookContent Content = new( @@ -2088,7 +2090,7 @@ namespace Server.Items public override BookContent DefaultContent => Content; } - [Serializable(0)] + [SerializationGenerator(0)] public partial class EthicalHedonism : BaseBook { public static readonly BookContent Content = new( @@ -2349,7 +2351,7 @@ namespace Server.Items public override BookContent DefaultContent => Content; } - [Serializable(0)] + [SerializationGenerator(0)] public partial class MyStory : BaseBook { public static readonly BookContent Content = new( @@ -2851,7 +2853,7 @@ namespace Server.Items public override BookContent DefaultContent => Content; } - [Serializable(0)] + [SerializationGenerator(0)] public partial class DiversityOfOurLand : BaseBook { public static readonly BookContent Content = new( @@ -3014,7 +3016,7 @@ namespace Server.Items public override BookContent DefaultContent => Content; } - [Serializable(0)] + [SerializationGenerator(0)] public partial class QuestOfVirtues : BaseBook { public static readonly BookContent Content = new( @@ -3407,7 +3409,7 @@ namespace Server.Items public override BookContent DefaultContent => Content; } - [Serializable(0)] + [SerializationGenerator(0)] public partial class RegardingLlamas : BaseBook { public static readonly BookContent Content = new( @@ -3461,7 +3463,7 @@ namespace Server.Items public override BookContent DefaultContent => Content; } - [Serializable(0)] + [SerializationGenerator(0)] public partial class TalkingToWisps : BaseBook { public static readonly BookContent Content = new( @@ -3561,7 +3563,7 @@ namespace Server.Items public override BookContent DefaultContent => Content; } - [Serializable(0)] + [SerializationGenerator(0)] public partial class TamingDragons : BaseBook { public static readonly BookContent Content = new( @@ -3651,7 +3653,7 @@ namespace Server.Items public override BookContent DefaultContent => Content; } - [Serializable(0)] + [SerializationGenerator(0)] public partial class BoldStranger : BaseBook { public static readonly BookContent Content = new( @@ -3804,7 +3806,7 @@ namespace Server.Items public override BookContent DefaultContent => Content; } - [Serializable(0)] + [SerializationGenerator(0)] public partial class BurningOfTrinsic : BaseBook { public static readonly BookContent Content = new( @@ -4048,7 +4050,7 @@ namespace Server.Items public override BookContent DefaultContent => Content; } - [Serializable(0)] + [SerializationGenerator(0)] public partial class TheFight : BaseBook { public static readonly BookContent Content = new( @@ -4190,7 +4192,7 @@ namespace Server.Items public override BookContent DefaultContent => Content; } - [Serializable(0)] + [SerializationGenerator(0)] public partial class LifeOfATravellingMinstrel : BaseBook { public static readonly BookContent Content = new( @@ -4379,7 +4381,7 @@ namespace Server.Items public override BookContent DefaultContent => Content; } - [Serializable(0)] + [SerializationGenerator(0)] public partial class MajorTradeAssociation : BaseBook { public static readonly BookContent Content = new( @@ -4569,7 +4571,7 @@ namespace Server.Items public override BookContent DefaultContent => Content; } - [Serializable(0)] + [SerializationGenerator(0)] public partial class RankingsOfTrades : BaseBook { public static readonly BookContent Content = new( @@ -4670,7 +4672,7 @@ namespace Server.Items public override BookContent DefaultContent => Content; } - [Serializable(0)] + [SerializationGenerator(0)] public partial class WildGirlOfTheForest : BaseBook { public static readonly BookContent Content = new( @@ -4844,7 +4846,7 @@ namespace Server.Items public override BookContent DefaultContent => Content; } - [Serializable(0)] + [SerializationGenerator(0)] public partial class TreatiseOnAlchemy : BaseBook { public static readonly BookContent Content = new( @@ -4973,7 +4975,7 @@ namespace Server.Items public override BookContent DefaultContent => Content; } - [Serializable(0)] + [SerializationGenerator(0)] public partial class VirtueBook : BaseBook { public static readonly BookContent Content = new( diff --git a/Projects/UOContent/Items/Books/Defined/NewAquariumBook.cs b/Projects/UOContent/Items/Books/Defined/NewAquariumBook.cs index 5604809c5..da04506f7 100644 --- a/Projects/UOContent/Items/Books/Defined/NewAquariumBook.cs +++ b/Projects/UOContent/Items/Books/Defined/NewAquariumBook.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class NewAquariumBook : BlueBook { public static readonly BookContent Content = new( diff --git a/Projects/UOContent/Items/Books/Defined/TranslatedGargoyleJournal.cs b/Projects/UOContent/Items/Books/Defined/TranslatedGargoyleJournal.cs index dd676212d..735ecc9e0 100644 --- a/Projects/UOContent/Items/Books/Defined/TranslatedGargoyleJournal.cs +++ b/Projects/UOContent/Items/Books/Defined/TranslatedGargoyleJournal.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class TranslatedGargoyleJournal : BlueBook { public static readonly BookContent Content = new( diff --git a/Projects/UOContent/Items/Books/RedBook.cs b/Projects/UOContent/Items/Books/RedBook.cs index 2ea2a86c5..4832ca690 100644 --- a/Projects/UOContent/Items/Books/RedBook.cs +++ b/Projects/UOContent/Items/Books/RedBook.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class RedBook : BaseBook { [Constructible] diff --git a/Projects/UOContent/Items/Books/TanBook.cs b/Projects/UOContent/Items/Books/TanBook.cs index 0bb86277f..07fdd67cd 100644 --- a/Projects/UOContent/Items/Books/TanBook.cs +++ b/Projects/UOContent/Items/Books/TanBook.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class TanBook : BaseBook { [Constructible] diff --git a/Projects/UOContent/Items/Bulletin Boards/BulletinBoard.cs b/Projects/UOContent/Items/Bulletin Boards/BulletinBoard.cs index 21c57f33e..17d3670af 100644 --- a/Projects/UOContent/Items/Bulletin Boards/BulletinBoard.cs +++ b/Projects/UOContent/Items/Bulletin Boards/BulletinBoard.cs @@ -1,5 +1,6 @@ using System; using System.Runtime.CompilerServices; +using ModernUO.Serialization; using Server.Collections; using Server.Network; @@ -33,7 +34,7 @@ namespace Server.Items public static bool CheckReplyTime(DateTime time) => time + ThreadReplyTime < Core.Now; } - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1E5E, 0x1E5F)] public partial class BulletinBoard : BaseBulletinBoard { @@ -43,7 +44,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public abstract partial class BaseBulletinBoard : Item { [SerializableField(0)] diff --git a/Projects/UOContent/Items/Bulletin Boards/BulletinMessage.cs b/Projects/UOContent/Items/Bulletin Boards/BulletinMessage.cs index 3a2ff59f7..cfc3b2024 100644 --- a/Projects/UOContent/Items/Bulletin Boards/BulletinMessage.cs +++ b/Projects/UOContent/Items/Bulletin Boards/BulletinMessage.cs @@ -1,10 +1,11 @@ using System; using System.Collections.Generic; +using ModernUO.Serialization; using Server.Targeting; namespace Server.Items { - [Serializable(2, false)] + [SerializationGenerator(2, false)] public partial class BulletinMessage : Item { public BulletinMessage(Mobile poster, BulletinMessage thread, string subject, string[] lines) : base(0xEB0) diff --git a/Projects/UOContent/Items/Champion Artifacts/Decorative/ArtifactLargeVase.cs b/Projects/UOContent/Items/Champion Artifacts/Decorative/ArtifactLargeVase.cs index 8c54e75c3..b71bd9f6b 100644 --- a/Projects/UOContent/Items/Champion Artifacts/Decorative/ArtifactLargeVase.cs +++ b/Projects/UOContent/Items/Champion Artifacts/Decorative/ArtifactLargeVase.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class ArtifactLargeVase : Item { [Constructible] diff --git a/Projects/UOContent/Items/Champion Artifacts/Decorative/ArtifactVase.cs b/Projects/UOContent/Items/Champion Artifacts/Decorative/ArtifactVase.cs index 183fb8dd8..a78cc2208 100644 --- a/Projects/UOContent/Items/Champion Artifacts/Decorative/ArtifactVase.cs +++ b/Projects/UOContent/Items/Champion Artifacts/Decorative/ArtifactVase.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class ArtifactVase : Item { [Constructible] diff --git a/Projects/UOContent/Items/Champion Artifacts/Decorative/DemonSkull.cs b/Projects/UOContent/Items/Champion Artifacts/Decorative/DemonSkull.cs index 2b80cff4a..177553ed7 100644 --- a/Projects/UOContent/Items/Champion Artifacts/Decorative/DemonSkull.cs +++ b/Projects/UOContent/Items/Champion Artifacts/Decorative/DemonSkull.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class DemonSkull : Item { [Constructible] diff --git a/Projects/UOContent/Items/Champion Artifacts/Decorative/DirtPatch.cs b/Projects/UOContent/Items/Champion Artifacts/Decorative/DirtPatch.cs index 20ba1d3d0..0940a950d 100644 --- a/Projects/UOContent/Items/Champion Artifacts/Decorative/DirtPatch.cs +++ b/Projects/UOContent/Items/Champion Artifacts/Decorative/DirtPatch.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class DirtPatch : Item { [Constructible] diff --git a/Projects/UOContent/Items/Champion Artifacts/Decorative/EvilIdolSkull.cs b/Projects/UOContent/Items/Champion Artifacts/Decorative/EvilIdolSkull.cs index 1f04c447a..fa9310a36 100644 --- a/Projects/UOContent/Items/Champion Artifacts/Decorative/EvilIdolSkull.cs +++ b/Projects/UOContent/Items/Champion Artifacts/Decorative/EvilIdolSkull.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class EvilIdolSkull : Item { [Constructible] diff --git a/Projects/UOContent/Items/Champion Artifacts/Decorative/Futon.cs b/Projects/UOContent/Items/Champion Artifacts/Decorative/Futon.cs index 6b60903b0..78e53af72 100644 --- a/Projects/UOContent/Items/Champion Artifacts/Decorative/Futon.cs +++ b/Projects/UOContent/Items/Champion Artifacts/Decorative/Futon.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Futon : Item { [Constructible] diff --git a/Projects/UOContent/Items/Champion Artifacts/Decorative/LavaTile.cs b/Projects/UOContent/Items/Champion Artifacts/Decorative/LavaTile.cs index 1c5fa4861..b74a353d5 100644 --- a/Projects/UOContent/Items/Champion Artifacts/Decorative/LavaTile.cs +++ b/Projects/UOContent/Items/Champion Artifacts/Decorative/LavaTile.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LavaTile : Item { [Constructible] diff --git a/Projects/UOContent/Items/Champion Artifacts/Decorative/Pier.cs b/Projects/UOContent/Items/Champion Artifacts/Decorative/Pier.cs index ab0fc2255..45f842475 100644 --- a/Projects/UOContent/Items/Champion Artifacts/Decorative/Pier.cs +++ b/Projects/UOContent/Items/Champion Artifacts/Decorative/Pier.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Pier : Item { /* diff --git a/Projects/UOContent/Items/Champion Artifacts/Decorative/SkullPole.cs b/Projects/UOContent/Items/Champion Artifacts/Decorative/SkullPole.cs index 4263727e9..5834239ec 100644 --- a/Projects/UOContent/Items/Champion Artifacts/Decorative/SkullPole.cs +++ b/Projects/UOContent/Items/Champion Artifacts/Decorative/SkullPole.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class SkullPole : Item { [Constructible] diff --git a/Projects/UOContent/Items/Champion Artifacts/Decorative/SwampTile.cs b/Projects/UOContent/Items/Champion Artifacts/Decorative/SwampTile.cs index 40121b44b..6982e4887 100644 --- a/Projects/UOContent/Items/Champion Artifacts/Decorative/SwampTile.cs +++ b/Projects/UOContent/Items/Champion Artifacts/Decorative/SwampTile.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class SwampTile : Item { [Constructible] diff --git a/Projects/UOContent/Items/Champion Artifacts/Decorative/TatteredAncientMummyWrapping.cs b/Projects/UOContent/Items/Champion Artifacts/Decorative/TatteredAncientMummyWrapping.cs index fbb942680..2c06008e6 100644 --- a/Projects/UOContent/Items/Champion Artifacts/Decorative/TatteredAncientMummyWrapping.cs +++ b/Projects/UOContent/Items/Champion Artifacts/Decorative/TatteredAncientMummyWrapping.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class TatteredAncientMummyWrapping : Item { [Constructible] diff --git a/Projects/UOContent/Items/Champion Artifacts/Decorative/WallBlood.cs b/Projects/UOContent/Items/Champion Artifacts/Decorative/WallBlood.cs index 8c0aecbc0..cc4e20d33 100644 --- a/Projects/UOContent/Items/Champion Artifacts/Decorative/WallBlood.cs +++ b/Projects/UOContent/Items/Champion Artifacts/Decorative/WallBlood.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class WallBlood : Item { [Constructible] diff --git a/Projects/UOContent/Items/Champion Artifacts/Decorative/WaterTile.cs b/Projects/UOContent/Items/Champion Artifacts/Decorative/WaterTile.cs index 313491582..172e427a4 100644 --- a/Projects/UOContent/Items/Champion Artifacts/Decorative/WaterTile.cs +++ b/Projects/UOContent/Items/Champion Artifacts/Decorative/WaterTile.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class WaterTile : Item { [Constructible] diff --git a/Projects/UOContent/Items/Champion Artifacts/Decorative/Web.cs b/Projects/UOContent/Items/Champion Artifacts/Decorative/Web.cs index 75758ccfd..b93c086f3 100644 --- a/Projects/UOContent/Items/Champion Artifacts/Decorative/Web.cs +++ b/Projects/UOContent/Items/Champion Artifacts/Decorative/Web.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Web : Item { private static readonly int[] ItemIds = { 0x10d7, 0x10d8, 0x10dd }; diff --git a/Projects/UOContent/Items/Champion Artifacts/Decorative/WindSpirit.cs b/Projects/UOContent/Items/Champion Artifacts/Decorative/WindSpirit.cs index 4fd415434..7e1d98e34 100644 --- a/Projects/UOContent/Items/Champion Artifacts/Decorative/WindSpirit.cs +++ b/Projects/UOContent/Items/Champion Artifacts/Decorative/WindSpirit.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class WindSpirit : Item { [Constructible] diff --git a/Projects/UOContent/Items/Champion Artifacts/Shared/ANecromancerShroud.cs b/Projects/UOContent/Items/Champion Artifacts/Shared/ANecromancerShroud.cs index d668d63df..7c9cade7d 100644 --- a/Projects/UOContent/Items/Champion Artifacts/Shared/ANecromancerShroud.cs +++ b/Projects/UOContent/Items/Champion Artifacts/Shared/ANecromancerShroud.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class ANecromancerShroud : Robe { [Constructible] diff --git a/Projects/UOContent/Items/Champion Artifacts/Shared/BraveKnightOfTheBritannia.cs b/Projects/UOContent/Items/Champion Artifacts/Shared/BraveKnightOfTheBritannia.cs index bbcf01a26..f85db031c 100644 --- a/Projects/UOContent/Items/Champion Artifacts/Shared/BraveKnightOfTheBritannia.cs +++ b/Projects/UOContent/Items/Champion Artifacts/Shared/BraveKnightOfTheBritannia.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class BraveKnightOfTheBritannia : Katana { [Constructible] diff --git a/Projects/UOContent/Items/Champion Artifacts/Shared/CaptainJohnsHat.cs b/Projects/UOContent/Items/Champion Artifacts/Shared/CaptainJohnsHat.cs index 08b0a775d..23451b324 100644 --- a/Projects/UOContent/Items/Champion Artifacts/Shared/CaptainJohnsHat.cs +++ b/Projects/UOContent/Items/Champion Artifacts/Shared/CaptainJohnsHat.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class CaptainJohnsHat : TricorneHat { [Constructible] diff --git a/Projects/UOContent/Items/Champion Artifacts/Shared/DetectiveBoots.cs b/Projects/UOContent/Items/Champion Artifacts/Shared/DetectiveBoots.cs index 5654d2f2d..ad10d215a 100644 --- a/Projects/UOContent/Items/Champion Artifacts/Shared/DetectiveBoots.cs +++ b/Projects/UOContent/Items/Champion Artifacts/Shared/DetectiveBoots.cs @@ -1,8 +1,9 @@ using System; +using ModernUO.Serialization; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class DetectiveBoots : Boots { private int m_Level; diff --git a/Projects/UOContent/Items/Champion Artifacts/Shared/DjinnisRing.cs b/Projects/UOContent/Items/Champion Artifacts/Shared/DjinnisRing.cs index b43cf24eb..a14acdba1 100644 --- a/Projects/UOContent/Items/Champion Artifacts/Shared/DjinnisRing.cs +++ b/Projects/UOContent/Items/Champion Artifacts/Shared/DjinnisRing.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class DjinnisRing : SilverRing { [Constructible] diff --git a/Projects/UOContent/Items/Champion Artifacts/Shared/EmbroideredOakLeafCloak.cs b/Projects/UOContent/Items/Champion Artifacts/Shared/EmbroideredOakLeafCloak.cs index 0b7e24153..3ae676a8a 100644 --- a/Projects/UOContent/Items/Champion Artifacts/Shared/EmbroideredOakLeafCloak.cs +++ b/Projects/UOContent/Items/Champion Artifacts/Shared/EmbroideredOakLeafCloak.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class EmbroideredOakLeafCloak : BaseOuterTorso { [Constructible] diff --git a/Projects/UOContent/Items/Champion Artifacts/Shared/GauntletsOfAnger.cs b/Projects/UOContent/Items/Champion Artifacts/Shared/GauntletsOfAnger.cs index 2c5bc40ec..8369e6d08 100644 --- a/Projects/UOContent/Items/Champion Artifacts/Shared/GauntletsOfAnger.cs +++ b/Projects/UOContent/Items/Champion Artifacts/Shared/GauntletsOfAnger.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class GuantletsOfAnger : PlateGloves { [Constructible] diff --git a/Projects/UOContent/Items/Champion Artifacts/Shared/LieutenantOfTheBritannianRoyalGuard.cs b/Projects/UOContent/Items/Champion Artifacts/Shared/LieutenantOfTheBritannianRoyalGuard.cs index 5dad1988a..f0d5f9446 100644 --- a/Projects/UOContent/Items/Champion Artifacts/Shared/LieutenantOfTheBritannianRoyalGuard.cs +++ b/Projects/UOContent/Items/Champion Artifacts/Shared/LieutenantOfTheBritannianRoyalGuard.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LieutenantOfTheBritannianRoyalGuard : BodySash { [Constructible] diff --git a/Projects/UOContent/Items/Champion Artifacts/Shared/OblivionsNeedle.cs b/Projects/UOContent/Items/Champion Artifacts/Shared/OblivionsNeedle.cs index 38413d3a5..628aaedbd 100644 --- a/Projects/UOContent/Items/Champion Artifacts/Shared/OblivionsNeedle.cs +++ b/Projects/UOContent/Items/Champion Artifacts/Shared/OblivionsNeedle.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class OblivionsNeedle : Dagger { [Constructible] diff --git a/Projects/UOContent/Items/Champion Artifacts/Shared/RoyalGuardSurvivalKnife.cs b/Projects/UOContent/Items/Champion Artifacts/Shared/RoyalGuardSurvivalKnife.cs index 386d03981..63418410d 100644 --- a/Projects/UOContent/Items/Champion Artifacts/Shared/RoyalGuardSurvivalKnife.cs +++ b/Projects/UOContent/Items/Champion Artifacts/Shared/RoyalGuardSurvivalKnife.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class RoyalGuardSurvivalKnife : SkinningKnife { [Constructible] diff --git a/Projects/UOContent/Items/Champion Artifacts/Shared/SamaritanRobe.cs b/Projects/UOContent/Items/Champion Artifacts/Shared/SamaritanRobe.cs index 05d33aff1..bb06bd893 100644 --- a/Projects/UOContent/Items/Champion Artifacts/Shared/SamaritanRobe.cs +++ b/Projects/UOContent/Items/Champion Artifacts/Shared/SamaritanRobe.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class SamaritanRobe : Robe { [Constructible] diff --git a/Projects/UOContent/Items/Champion Artifacts/Shared/TheMostKnowledgePerson.cs b/Projects/UOContent/Items/Champion Artifacts/Shared/TheMostKnowledgePerson.cs index 26e825c14..604f860f0 100644 --- a/Projects/UOContent/Items/Champion Artifacts/Shared/TheMostKnowledgePerson.cs +++ b/Projects/UOContent/Items/Champion Artifacts/Shared/TheMostKnowledgePerson.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class TheMostKnowledgePerson : BaseOuterTorso { [Constructible] diff --git a/Projects/UOContent/Items/Champion Artifacts/Shared/TheRobeOfBritanniaAri.cs b/Projects/UOContent/Items/Champion Artifacts/Shared/TheRobeOfBritanniaAri.cs index c9ebf2fa5..77d947fc8 100644 --- a/Projects/UOContent/Items/Champion Artifacts/Shared/TheRobeOfBritanniaAri.cs +++ b/Projects/UOContent/Items/Champion Artifacts/Shared/TheRobeOfBritanniaAri.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class TheRobeOfBritanniaAri : BaseOuterTorso { [Constructible] diff --git a/Projects/UOContent/Items/Champion Artifacts/Unique/AcidProofRobe.cs b/Projects/UOContent/Items/Champion Artifacts/Unique/AcidProofRobe.cs index 5da7d1c85..7f81126d5 100644 --- a/Projects/UOContent/Items/Champion Artifacts/Unique/AcidProofRobe.cs +++ b/Projects/UOContent/Items/Champion Artifacts/Unique/AcidProofRobe.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class AcidProofRobe : Robe { [Constructible] diff --git a/Projects/UOContent/Items/Champion Artifacts/Unique/Calm.cs b/Projects/UOContent/Items/Champion Artifacts/Unique/Calm.cs index 7c22325c7..8aca9981e 100644 --- a/Projects/UOContent/Items/Champion Artifacts/Unique/Calm.cs +++ b/Projects/UOContent/Items/Champion Artifacts/Unique/Calm.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Calm : Halberd { [Constructible] diff --git a/Projects/UOContent/Items/Champion Artifacts/Unique/CrownOfTalKeesh.cs b/Projects/UOContent/Items/Champion Artifacts/Unique/CrownOfTalKeesh.cs index 483529384..58eefd2db 100644 --- a/Projects/UOContent/Items/Champion Artifacts/Unique/CrownOfTalKeesh.cs +++ b/Projects/UOContent/Items/Champion Artifacts/Unique/CrownOfTalKeesh.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class CrownOfTalKeesh : Bandana { [Constructible] diff --git a/Projects/UOContent/Items/Champion Artifacts/Unique/FangOfRactus.cs b/Projects/UOContent/Items/Champion Artifacts/Unique/FangOfRactus.cs index 6586b7216..91c023041 100644 --- a/Projects/UOContent/Items/Champion Artifacts/Unique/FangOfRactus.cs +++ b/Projects/UOContent/Items/Champion Artifacts/Unique/FangOfRactus.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class FangOfRactus : Kryss { [Constructible] diff --git a/Projects/UOContent/Items/Champion Artifacts/Unique/GladiatorsCollar.cs b/Projects/UOContent/Items/Champion Artifacts/Unique/GladiatorsCollar.cs index 197b7f9af..efe64c461 100644 --- a/Projects/UOContent/Items/Champion Artifacts/Unique/GladiatorsCollar.cs +++ b/Projects/UOContent/Items/Champion Artifacts/Unique/GladiatorsCollar.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class GladiatorsCollar : PlateGorget { [Constructible] diff --git a/Projects/UOContent/Items/Champion Artifacts/Unique/OrcChieftainHelm.cs b/Projects/UOContent/Items/Champion Artifacts/Unique/OrcChieftainHelm.cs index ebd3a5c79..ce30b89af 100644 --- a/Projects/UOContent/Items/Champion Artifacts/Unique/OrcChieftainHelm.cs +++ b/Projects/UOContent/Items/Champion Artifacts/Unique/OrcChieftainHelm.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class OrcChieftainHelm : OrcHelm { [Constructible] diff --git a/Projects/UOContent/Items/Champion Artifacts/Unique/Pacify.cs b/Projects/UOContent/Items/Champion Artifacts/Unique/Pacify.cs index c78ac17f7..996fcf0cc 100644 --- a/Projects/UOContent/Items/Champion Artifacts/Unique/Pacify.cs +++ b/Projects/UOContent/Items/Champion Artifacts/Unique/Pacify.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Pacify : Pike { [Constructible] diff --git a/Projects/UOContent/Items/Champion Artifacts/Unique/Quell.cs b/Projects/UOContent/Items/Champion Artifacts/Unique/Quell.cs index 821c2b5f6..56cd24045 100644 --- a/Projects/UOContent/Items/Champion Artifacts/Unique/Quell.cs +++ b/Projects/UOContent/Items/Champion Artifacts/Unique/Quell.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Quell : Bardiche { [Constructible] diff --git a/Projects/UOContent/Items/Champion Artifacts/Unique/ShroudOfDeceit.cs b/Projects/UOContent/Items/Champion Artifacts/Unique/ShroudOfDeceit.cs index 83c94194c..77a304f35 100644 --- a/Projects/UOContent/Items/Champion Artifacts/Unique/ShroudOfDeceit.cs +++ b/Projects/UOContent/Items/Champion Artifacts/Unique/ShroudOfDeceit.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class ShroudOfDeciet : BoneChest { [Constructible] diff --git a/Projects/UOContent/Items/Champion Artifacts/Unique/Subdue.cs b/Projects/UOContent/Items/Champion Artifacts/Unique/Subdue.cs index 61b3efc9e..2fcc7e9ee 100644 --- a/Projects/UOContent/Items/Champion Artifacts/Unique/Subdue.cs +++ b/Projects/UOContent/Items/Champion Artifacts/Unique/Subdue.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Subdue : Scythe { [Constructible] diff --git a/Projects/UOContent/Items/Clothing/Artifacts/CrimsonCincture.cs b/Projects/UOContent/Items/Clothing/Artifacts/CrimsonCincture.cs index ea81189ec..9088a8a64 100644 --- a/Projects/UOContent/Items/Clothing/Artifacts/CrimsonCincture.cs +++ b/Projects/UOContent/Items/Clothing/Artifacts/CrimsonCincture.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class CrimsonCincture : HalfApron { [Constructible] diff --git a/Projects/UOContent/Items/Clothing/Artifacts/DivineCountenance.cs b/Projects/UOContent/Items/Clothing/Artifacts/DivineCountenance.cs index 302c2acec..b67adf5b2 100644 --- a/Projects/UOContent/Items/Clothing/Artifacts/DivineCountenance.cs +++ b/Projects/UOContent/Items/Clothing/Artifacts/DivineCountenance.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class DivineCountenance : HornedTribalMask { [Constructible] diff --git a/Projects/UOContent/Items/Clothing/Artifacts/HatOfTheMagi.cs b/Projects/UOContent/Items/Clothing/Artifacts/HatOfTheMagi.cs index 717d14ac1..a4ca80c28 100644 --- a/Projects/UOContent/Items/Clothing/Artifacts/HatOfTheMagi.cs +++ b/Projects/UOContent/Items/Clothing/Artifacts/HatOfTheMagi.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class HatOfTheMagi : WizardsHat { [Constructible] diff --git a/Projects/UOContent/Items/Clothing/Artifacts/HuntersHeaddress.cs b/Projects/UOContent/Items/Clothing/Artifacts/HuntersHeaddress.cs index eef2c19e4..eac1867bd 100644 --- a/Projects/UOContent/Items/Clothing/Artifacts/HuntersHeaddress.cs +++ b/Projects/UOContent/Items/Clothing/Artifacts/HuntersHeaddress.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class HuntersHeaddress : DeerMask { [Constructible] diff --git a/Projects/UOContent/Items/Clothing/Artifacts/SpiritOfTheTotem.cs b/Projects/UOContent/Items/Clothing/Artifacts/SpiritOfTheTotem.cs index ff90f494f..bb995fa71 100644 --- a/Projects/UOContent/Items/Clothing/Artifacts/SpiritOfTheTotem.cs +++ b/Projects/UOContent/Items/Clothing/Artifacts/SpiritOfTheTotem.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class SpiritOfTheTotem : BearMask { [Constructible] diff --git a/Projects/UOContent/Items/Clothing/BaseClothing.cs b/Projects/UOContent/Items/Clothing/BaseClothing.cs index 90070675e..02af85c53 100644 --- a/Projects/UOContent/Items/Clothing/BaseClothing.cs +++ b/Projects/UOContent/Items/Clothing/BaseClothing.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using ModernUO.Serialization; using Server.Engines.Craft; using Server.Ethics; using Server.Factions; @@ -22,7 +23,7 @@ namespace Server.Items int MaxArcaneCharges { get; set; } } - [Serializable(7, false)] + [SerializationGenerator(7, false)] public abstract partial class BaseClothing : Item, IDyable, IScissorable, IFactionItem, ICraftable, IWearableDurability { [SerializableField(0, "private", "private")] diff --git a/Projects/UOContent/Items/Clothing/Cloaks.cs b/Projects/UOContent/Items/Clothing/Cloaks.cs index f5b3a0a5f..8b6ff62e5 100644 --- a/Projects/UOContent/Items/Clothing/Cloaks.cs +++ b/Projects/UOContent/Items/Clothing/Cloaks.cs @@ -1,8 +1,9 @@ +using ModernUO.Serialization; using Server.Engines.VeteranRewards; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public abstract partial class BaseCloak : BaseClothing { public BaseCloak(int itemID, int hue = 0) : base(itemID, Layer.Cloak, hue) @@ -11,7 +12,7 @@ namespace Server.Items } [Flippable] - [Serializable(2, false)] + [SerializationGenerator(2, false)] public partial class Cloak : BaseCloak, IArcaneEquip { private int _maxArcaneCharges; @@ -111,7 +112,7 @@ namespace Server.Items } [Flippable] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class RewardCloak : BaseCloak, IRewardItem { [InvalidateProperties] @@ -188,7 +189,7 @@ namespace Server.Items } [Flippable(0x230A, 0x2309)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class FurCape : BaseCloak { [Constructible] diff --git a/Projects/UOContent/Items/Clothing/Hats.cs b/Projects/UOContent/Items/Clothing/Hats.cs index 98c31d746..80b4d7580 100644 --- a/Projects/UOContent/Items/Clothing/Hats.cs +++ b/Projects/UOContent/Items/Clothing/Hats.cs @@ -1,12 +1,13 @@ using System; using System.Collections.Generic; +using ModernUO.Serialization; using Server.Engines.Craft; using Server.Misc; using Server.Network; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public abstract partial class BaseHat : BaseClothing, IShipwreckedItem { [SerializableField(0)] @@ -57,7 +58,7 @@ namespace Server.Items } [Flippable(0x2798, 0x27E3)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Kasa : BaseHat { [Constructible] @@ -74,7 +75,7 @@ namespace Server.Items } [Flippable(0x278F, 0x27DA)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class ClothNinjaHood : BaseHat { [Constructible] @@ -91,7 +92,7 @@ namespace Server.Items } [Flippable(0x2306, 0x2305)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class FlowerGarland : BaseHat { [Constructible] @@ -107,7 +108,7 @@ namespace Server.Items public override int InitMaxHits => 30; } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class FloppyHat : BaseHat { [Constructible] @@ -123,7 +124,7 @@ namespace Server.Items public override int InitMaxHits => 30; } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class WideBrimHat : BaseHat { [Constructible] @@ -139,7 +140,7 @@ namespace Server.Items public override int InitMaxHits => 30; } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Cap : BaseHat { [Constructible] @@ -155,7 +156,7 @@ namespace Server.Items public override int InitMaxHits => 30; } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class SkullCap : BaseHat { [Constructible] @@ -171,7 +172,7 @@ namespace Server.Items public override int InitMaxHits => Core.ML ? 28 : 12; } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Bandana : BaseHat { [Constructible] @@ -187,7 +188,7 @@ namespace Server.Items public override int InitMaxHits => 30; } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class BearMask : BaseHat { [Constructible] @@ -209,7 +210,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class DeerMask : BaseHat { [Constructible] @@ -231,7 +232,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class HornedTribalMask : BaseHat { [Constructible] @@ -253,7 +254,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class TribalMask : BaseHat { [Constructible] @@ -275,7 +276,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class TallStrawHat : BaseHat { [Constructible] @@ -291,7 +292,7 @@ namespace Server.Items public override int InitMaxHits => 30; } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class StrawHat : BaseHat { [Constructible] @@ -307,7 +308,7 @@ namespace Server.Items public override int InitMaxHits => 30; } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class OrcishKinMask : BaseHat { [Constructible] @@ -357,7 +358,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class SavageMask : BaseHat { [Constructible] @@ -396,7 +397,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class WizardsHat : BaseHat { [Constructible] @@ -412,7 +413,7 @@ namespace Server.Items public override int InitMaxHits => 30; } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class MagicWizardsHat : BaseHat { [Constructible] @@ -434,7 +435,7 @@ namespace Server.Items public override int BaseIntBonus => +5; } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Bonnet : BaseHat { [Constructible] @@ -450,7 +451,7 @@ namespace Server.Items public override int InitMaxHits => 30; } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class FeatheredHat : BaseHat { [Constructible] @@ -466,7 +467,7 @@ namespace Server.Items public override int InitMaxHits => 30; } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class TricorneHat : BaseHat { [Constructible] @@ -482,7 +483,7 @@ namespace Server.Items public override int InitMaxHits => 30; } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class JesterHat : BaseHat { [Constructible] diff --git a/Projects/UOContent/Items/Clothing/MiddleTorso.cs b/Projects/UOContent/Items/Clothing/MiddleTorso.cs index ae7957bcd..27e3bc4b6 100644 --- a/Projects/UOContent/Items/Clothing/MiddleTorso.cs +++ b/Projects/UOContent/Items/Clothing/MiddleTorso.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public abstract partial class BaseMiddleTorso : BaseClothing { public BaseMiddleTorso(int itemID, int hue = 0) : base(itemID, Layer.MiddleTorso, hue) @@ -8,7 +10,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1541, 0x1542)] public partial class BodySash : BaseMiddleTorso { @@ -16,7 +18,7 @@ namespace Server.Items public BodySash(int hue = 0) : base(0x1541, hue) => Weight = 1.0; } - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x153d, 0x153e)] public partial class FullApron : BaseMiddleTorso { @@ -24,7 +26,7 @@ namespace Server.Items public FullApron(int hue = 0) : base(0x153d, hue) => Weight = 4.0; } - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1f7b, 0x1f7c)] public partial class Doublet : BaseMiddleTorso { @@ -32,7 +34,7 @@ namespace Server.Items public Doublet(int hue = 0) : base(0x1F7B, hue) => Weight = 2.0; } - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1ffd, 0x1ffe)] public partial class Surcoat : BaseMiddleTorso { @@ -40,7 +42,7 @@ namespace Server.Items public Surcoat(int hue = 0) : base(0x1FFD, hue) => Weight = 6.0; } - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1fa1, 0x1fa2)] public partial class Tunic : BaseMiddleTorso { @@ -48,7 +50,7 @@ namespace Server.Items public Tunic(int hue = 0) : base(0x1FA1, hue) => Weight = 5.0; } - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x2310, 0x230F)] public partial class FormalShirt : BaseMiddleTorso { @@ -56,7 +58,7 @@ namespace Server.Items public FormalShirt(int hue = 0) : base(0x2310, hue) => Weight = 1.0; } - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1f9f, 0x1fa0)] public partial class JesterSuit : BaseMiddleTorso { @@ -64,7 +66,7 @@ namespace Server.Items public JesterSuit(int hue = 0) : base(0x1F9F, hue) => Weight = 4.0; } - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x27A1, 0x27EC)] public partial class JinBaori : BaseMiddleTorso { diff --git a/Projects/UOContent/Items/Clothing/OuterLegs.cs b/Projects/UOContent/Items/Clothing/OuterLegs.cs index d5bef9eea..d060c306f 100644 --- a/Projects/UOContent/Items/Clothing/OuterLegs.cs +++ b/Projects/UOContent/Items/Clothing/OuterLegs.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public abstract partial class BaseOuterLegs : BaseClothing { public BaseOuterLegs(int itemID, int hue = 0) : base(itemID, Layer.OuterLegs, hue) @@ -8,7 +10,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x230C, 0x230B)] public partial class FurSarong : BaseOuterLegs { @@ -16,7 +18,7 @@ namespace Server.Items public FurSarong(int hue = 0) : base(0x230C, hue) => Weight = 3.0; } - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1516, 0x1531)] public partial class Skirt : BaseOuterLegs { @@ -24,7 +26,7 @@ namespace Server.Items public Skirt(int hue = 0) : base(0x1516, hue) => Weight = 4.0; } - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1537, 0x1538)] public partial class Kilt : BaseOuterLegs { @@ -32,7 +34,7 @@ namespace Server.Items public Kilt(int hue = 0) : base(0x1537, hue) => Weight = 2.0; } - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x279A, 0x27E5)] public partial class Hakama : BaseOuterLegs { diff --git a/Projects/UOContent/Items/Clothing/OuterTorso.cs b/Projects/UOContent/Items/Clothing/OuterTorso.cs index 07cdf59ab..e05a7ff43 100644 --- a/Projects/UOContent/Items/Clothing/OuterTorso.cs +++ b/Projects/UOContent/Items/Clothing/OuterTorso.cs @@ -1,10 +1,11 @@ using System; using System.Runtime.CompilerServices; +using ModernUO.Serialization; using Server.Engines.VeteranRewards; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public abstract partial class BaseOuterTorso : BaseClothing { public BaseOuterTorso(int itemID, int hue = 0) : base(itemID, Layer.OuterTorso, hue) @@ -12,7 +13,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x230E, 0x230D)] public partial class GildedDress : BaseOuterTorso { @@ -20,7 +21,7 @@ namespace Server.Items public GildedDress(int hue = 0) : base(0x230E, hue) => Weight = 3.0; } - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1F00, 0x1EFF)] public partial class FancyDress : BaseOuterTorso { @@ -28,7 +29,7 @@ namespace Server.Items public FancyDress(int hue = 0) : base(0x1F00, hue) => Weight = 3.0; } - [Serializable(3, false)] + [SerializationGenerator(3, false)] public partial class DeathRobe : Robe { private static readonly TimeSpan m_DefaultDecayTime = TimeSpan.FromMinutes(1.0); @@ -141,7 +142,7 @@ namespace Server.Items } [Flippable] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class RewardRobe : BaseOuterTorso, IRewardItem { [InvalidateProperties] @@ -223,7 +224,7 @@ namespace Server.Items } [Flippable] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class RewardDress : BaseOuterTorso, IRewardItem { [InvalidateProperties] @@ -305,7 +306,7 @@ namespace Server.Items } [Flippable] - [Serializable(2, false)] + [SerializationGenerator(2, false)] public partial class Robe : BaseOuterTorso, IArcaneEquip { private int _curArcaneCharges; @@ -404,7 +405,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class MonkRobe : BaseOuterTorso { [Constructible] @@ -425,7 +426,7 @@ namespace Server.Items } [Flippable(0x1f01, 0x1f02)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class PlainDress : BaseOuterTorso { [Constructible] @@ -433,7 +434,7 @@ namespace Server.Items } [Flippable(0x2799, 0x27E4)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Kamishimo : BaseOuterTorso { [Constructible] @@ -441,7 +442,7 @@ namespace Server.Items } [Flippable(0x279C, 0x27E7)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class HakamaShita : BaseOuterTorso { [Constructible] @@ -449,7 +450,7 @@ namespace Server.Items } [Flippable(0x2782, 0x27CD)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class MaleKimono : BaseOuterTorso { [Constructible] @@ -457,7 +458,7 @@ namespace Server.Items } [Flippable(0x2783, 0x27CE)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class FemaleKimono : BaseOuterTorso { [Constructible] @@ -465,7 +466,7 @@ namespace Server.Items } [Flippable(0x2FB9, 0x3173)] - [Serializable(0)] + [SerializationGenerator(0)] public partial class MaleElvenRobe : BaseOuterTorso { [Constructible] @@ -473,7 +474,7 @@ namespace Server.Items } [Flippable(0x2FBA, 0x3174)] - [Serializable(0)] + [SerializationGenerator(0)] public partial class FemaleElvenRobe : BaseOuterTorso { [Constructible] diff --git a/Projects/UOContent/Items/Clothing/Pants.cs b/Projects/UOContent/Items/Clothing/Pants.cs index 00fc3df06..efee4e379 100644 --- a/Projects/UOContent/Items/Clothing/Pants.cs +++ b/Projects/UOContent/Items/Clothing/Pants.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public abstract partial class BasePants : BaseClothing { public BasePants(int itemID, int hue = 0) : base(itemID, Layer.Pants, hue) @@ -9,7 +11,7 @@ namespace Server.Items } [Flippable(0x152e, 0x152f)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class ShortPants : BasePants { [Constructible] @@ -17,7 +19,7 @@ namespace Server.Items } [Flippable(0x1539, 0x153a)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LongPants : BasePants { [Constructible] @@ -25,7 +27,7 @@ namespace Server.Items } [Flippable(0x279B, 0x27E6)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class TattsukeHakama : BasePants { [Constructible] @@ -33,7 +35,7 @@ namespace Server.Items } [Flippable(0x2FC3, 0x3179)] - [Serializable(0)] + [SerializationGenerator(0)] public partial class ElvenPants : BasePants { [Constructible] diff --git a/Projects/UOContent/Items/Clothing/Shirts.cs b/Projects/UOContent/Items/Clothing/Shirts.cs index cf8f8b316..6ba43a870 100644 --- a/Projects/UOContent/Items/Clothing/Shirts.cs +++ b/Projects/UOContent/Items/Clothing/Shirts.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public abstract partial class BaseShirt : BaseClothing { public BaseShirt(int itemID, int hue = 0) : base(itemID, Layer.Shirt, hue) @@ -9,7 +11,7 @@ namespace Server.Items } [Flippable(0x1efd, 0x1efe)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class FancyShirt : BaseShirt { [Constructible] @@ -17,7 +19,7 @@ namespace Server.Items } [Flippable(0x1517, 0x1518)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Shirt : BaseShirt { [Constructible] @@ -25,7 +27,7 @@ namespace Server.Items } [Flippable(0x2794, 0x27DF)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class ClothNinjaJacket : BaseShirt { [Constructible] @@ -36,7 +38,7 @@ namespace Server.Items } } - [Serializable(0)] + [SerializationGenerator(0)] public partial class ElvenShirt : BaseShirt { [Constructible] @@ -45,7 +47,7 @@ namespace Server.Items public override int RequiredRaces => Race.AllowElvesOnly; } - [Serializable(0)] + [SerializationGenerator(0)] public partial class ElvenDarkShirt : BaseShirt { [Constructible] diff --git a/Projects/UOContent/Items/Clothing/Shoes.cs b/Projects/UOContent/Items/Clothing/Shoes.cs index 0887acd81..03fcd4436 100644 --- a/Projects/UOContent/Items/Clothing/Shoes.cs +++ b/Projects/UOContent/Items/Clothing/Shoes.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public abstract partial class BaseShoes : BaseClothing { public BaseShoes(int itemID, int hue = 0) : base(itemID, Layer.Shoes, hue) @@ -20,7 +22,7 @@ namespace Server.Items } [Flippable(0x2307, 0x2308)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class FurBoots : BaseShoes { [Constructible] @@ -28,7 +30,7 @@ namespace Server.Items } [Flippable(0x170b, 0x170c)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Boots : BaseShoes { [Constructible] @@ -38,7 +40,7 @@ namespace Server.Items } [Flippable] - [Serializable(2, false)] + [SerializationGenerator(2, false)] public partial class ThighBoots : BaseShoes, IArcaneEquip { private int _maxArcaneCharges; @@ -140,7 +142,7 @@ namespace Server.Items } [Flippable(0x170f, 0x1710)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Shoes : BaseShoes { [Constructible] @@ -150,7 +152,7 @@ namespace Server.Items } [Flippable(0x170d, 0x170e)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Sandals : BaseShoes { [Constructible] @@ -162,7 +164,7 @@ namespace Server.Items } [Flippable(0x2797, 0x27E2)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class NinjaTabi : BaseShoes { [Constructible] @@ -170,7 +172,7 @@ namespace Server.Items } [Flippable(0x2796, 0x27E1)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class SamuraiTabi : BaseShoes { [Constructible] @@ -178,7 +180,7 @@ namespace Server.Items } [Flippable(0x2796, 0x27E1)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Waraji : BaseShoes { [Constructible] @@ -186,7 +188,7 @@ namespace Server.Items } [Flippable(0x2FC4, 0x317A)] - [Serializable(0)] + [SerializationGenerator(0)] public partial class ElvenBoots : BaseShoes { [Constructible] diff --git a/Projects/UOContent/Items/Clothing/Waist.cs b/Projects/UOContent/Items/Clothing/Waist.cs index eaccfd32b..45f34d768 100644 --- a/Projects/UOContent/Items/Clothing/Waist.cs +++ b/Projects/UOContent/Items/Clothing/Waist.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public abstract partial class BaseWaist : BaseClothing { public BaseWaist(int itemID, int hue = 0) : base(itemID, Layer.Waist, hue) @@ -9,7 +11,7 @@ namespace Server.Items } [Flippable(0x153b, 0x153c)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class HalfApron : BaseWaist { [Constructible] @@ -17,7 +19,7 @@ namespace Server.Items } [Flippable(0x27A0, 0x27EB)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Obi : BaseWaist { [Constructible] @@ -25,7 +27,7 @@ namespace Server.Items } [Flippable(0x2B68, 0x315F)] - [Serializable(0)] + [SerializationGenerator(0)] public partial class WoodlandBelt : BaseWaist { [Constructible] diff --git a/Projects/UOContent/Items/Construction/Ankhs.cs b/Projects/UOContent/Items/Construction/Ankhs.cs index d75e968f5..41e69dec3 100644 --- a/Projects/UOContent/Items/Construction/Ankhs.cs +++ b/Projects/UOContent/Items/Construction/Ankhs.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using ModernUO.Serialization; using Server.ContextMenus; using Server.Gumps; using Server.Mobiles; @@ -111,7 +112,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class AnkhWest : Item { [SerializableField(0, getter: "private", setter: "private")] @@ -183,7 +184,7 @@ namespace Server.Items _item?.Delete(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] private partial class InternalItem : Item { [SerializableField(0)] @@ -257,7 +258,7 @@ namespace Server.Items } [TypeAlias("Server.Items.AnkhEast")] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class AnkhNorth : Item { [SerializableField(0, getter: "private", setter: "private")] @@ -331,7 +332,7 @@ namespace Server.Items } [TypeAlias("Server.Items.AnkhEast+InternalItem")] - [Serializable(0, false)] + [SerializationGenerator(0, false)] private partial class InternalItem : Item { [SerializableField(0)] diff --git a/Projects/UOContent/Items/Construction/Chairs/Benchs.cs b/Projects/UOContent/Items/Construction/Chairs/Benchs.cs index a29606366..f37deba0b 100644 --- a/Projects/UOContent/Items/Construction/Chairs/Benchs.cs +++ b/Projects/UOContent/Items/Construction/Chairs/Benchs.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Furniture] - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0xB2D, 0xB2C)] public partial class WoodenBench : Item { diff --git a/Projects/UOContent/Items/Construction/Chairs/Chairs.cs b/Projects/UOContent/Items/Construction/Chairs/Chairs.cs index 67dfd1878..12b2b9ad8 100644 --- a/Projects/UOContent/Items/Construction/Chairs/Chairs.cs +++ b/Projects/UOContent/Items/Construction/Chairs/Chairs.cs @@ -1,8 +1,10 @@ +using ModernUO.Serialization; + namespace Server.Items { [Furniture] [Flippable(0xB4F, 0xB4E, 0xB50, 0xB51)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class FancyWoodenChairCushion : Item { [Constructible] @@ -11,7 +13,7 @@ namespace Server.Items [Furniture] [Flippable(0xB53, 0xB52, 0xB54, 0xB55)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class WoodenChairCushion : Item { [Constructible] @@ -20,7 +22,7 @@ namespace Server.Items [Furniture] [Flippable(0xB57, 0xB56, 0xB59, 0xB58)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class WoodenChair : Item { [Constructible] @@ -29,7 +31,7 @@ namespace Server.Items [Furniture] [Flippable(0xB5B, 0xB5A, 0xB5C, 0xB5D)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class BambooChair : Item { [Constructible] @@ -38,7 +40,7 @@ namespace Server.Items [DynamicFlipping] [Flippable(0x1218, 0x1219, 0x121A, 0x121B)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class StoneChair : Item { [Constructible] @@ -47,7 +49,7 @@ namespace Server.Items [DynamicFlipping] [Flippable(0x2DE3, 0x2DE4, 0x2DE5, 0x2DE6)] - [Serializable(0)] + [SerializationGenerator(0)] public partial class OrnateElvenChair : Item { [Constructible] @@ -56,7 +58,7 @@ namespace Server.Items [DynamicFlipping] [Flippable(0x2DEB, 0x2DEC, 0x2DED, 0x2DEE)] - [Serializable(0)] + [SerializationGenerator(0)] public partial class BigElvenChair : Item { [Constructible] @@ -67,7 +69,7 @@ namespace Server.Items [DynamicFlipping] [Flippable(0x2DF5, 0x2DF6)] - [Serializable(0)] + [SerializationGenerator(0)] public partial class ElvenReadingChair : Item { [Constructible] diff --git a/Projects/UOContent/Items/Construction/Chairs/Stools.cs b/Projects/UOContent/Items/Construction/Chairs/Stools.cs index a9e76afc6..837b36972 100644 --- a/Projects/UOContent/Items/Construction/Chairs/Stools.cs +++ b/Projects/UOContent/Items/Construction/Chairs/Stools.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Furniture] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Stool : Item { [Constructible] @@ -9,7 +11,7 @@ namespace Server.Items } [Furniture] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class FootStool : Item { [Constructible] diff --git a/Projects/UOContent/Items/Construction/Chairs/Thrones.cs b/Projects/UOContent/Items/Construction/Chairs/Thrones.cs index 2478489ab..de189504f 100644 --- a/Projects/UOContent/Items/Construction/Chairs/Thrones.cs +++ b/Projects/UOContent/Items/Construction/Chairs/Thrones.cs @@ -1,8 +1,10 @@ +using ModernUO.Serialization; + namespace Server.Items { [Furniture] [Flippable(0xB32, 0xB33)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Throne : Item { [Constructible] @@ -11,7 +13,7 @@ namespace Server.Items [Furniture] [Flippable(0xB2E, 0xB2F, 0xB31, 0xB30)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class WoodenThrone : Item { [Constructible] diff --git a/Projects/UOContent/Items/Construction/Decorative/DecorativeShield.cs b/Projects/UOContent/Items/Construction/Decorative/DecorativeShield.cs index 286bd0a98..157f240c3 100644 --- a/Projects/UOContent/Items/Construction/Decorative/DecorativeShield.cs +++ b/Projects/UOContent/Items/Construction/Decorative/DecorativeShield.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x156C, 0x156D)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class DecorativeShield1 : Item { [Constructible] @@ -9,7 +11,7 @@ namespace Server.Items } [Flippable(0x156E, 0x156F)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class DecorativeShield2 : Item { [Constructible] @@ -17,7 +19,7 @@ namespace Server.Items } [Flippable(0x1570, 0x1571)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class DecorativeShield3 : Item { [Constructible] @@ -25,7 +27,7 @@ namespace Server.Items } [Flippable(0x1572, 0x1573)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class DecorativeShield4 : Item { [Constructible] @@ -33,7 +35,7 @@ namespace Server.Items } [Flippable(0x1574, 0x1575)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class DecorativeShield5 : Item { [Constructible] @@ -41,7 +43,7 @@ namespace Server.Items } [Flippable(0x1576, 0x1577)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class DecorativeShield6 : Item { [Constructible] @@ -49,7 +51,7 @@ namespace Server.Items } [Flippable(0x1578, 0x1579)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class DecorativeShield7 : Item { [Constructible] @@ -57,7 +59,7 @@ namespace Server.Items } [Flippable(0x157A, 0x157B)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class DecorativeShield8 : Item { [Constructible] @@ -65,7 +67,7 @@ namespace Server.Items } [Flippable(0x157C, 0x157D)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class DecorativeShield9 : Item { [Constructible] @@ -73,7 +75,7 @@ namespace Server.Items } [Flippable(0x157E, 0x157F)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class DecorativeShield10 : Item { [Constructible] @@ -81,7 +83,7 @@ namespace Server.Items } [Flippable(0x1580, 0x1581)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class DecorativeShield11 : Item { [Constructible] @@ -89,7 +91,7 @@ namespace Server.Items } [Flippable(0x1582, 0x1583, 0x1634, 0x1635)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class DecorativeShieldSword1North : Item { [Constructible] @@ -97,7 +99,7 @@ namespace Server.Items } [Flippable(0x1634, 0x1635, 0x1582, 0x1583)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class DecorativeShieldSword1West : Item { [Constructible] @@ -105,7 +107,7 @@ namespace Server.Items } [Flippable(0x1584, 0x1585, 0x1636, 0x1637)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class DecorativeShieldSword2North : Item { [Constructible] @@ -113,7 +115,7 @@ namespace Server.Items } [Flippable(0x1636, 0x1637, 0x1584, 0x1585)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class DecorativeShieldSword2West : Item { [Constructible] diff --git a/Projects/UOContent/Items/Construction/Decorative/DecorativeWeapon.cs b/Projects/UOContent/Items/Construction/Decorative/DecorativeWeapon.cs index 4b3d9f087..72157087f 100644 --- a/Projects/UOContent/Items/Construction/Decorative/DecorativeWeapon.cs +++ b/Projects/UOContent/Items/Construction/Decorative/DecorativeWeapon.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x155E, 0x155F, 0x155C, 0x155D)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class DecorativeBowWest : Item { [Constructible] @@ -9,7 +11,7 @@ namespace Server.Items } [Flippable(0x155C, 0x155D, 0x155E, 0x155F)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class DecorativeBowNorth : Item { [Constructible] @@ -17,7 +19,7 @@ namespace Server.Items } [Flippable(0x1560, 0x1561, 0x1562, 0x1563)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class DecorativeAxeNorth : Item { [Constructible] @@ -25,14 +27,14 @@ namespace Server.Items } [Flippable(0x1562, 0x1563, 0x1560, 0x1561)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class DecorativeAxeWest : Item { [Constructible] public DecorativeAxeWest() : base(Utility.Random(0x1562, 2)) => Movable = false; } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class DecorativeSwordNorth : Item { [SerializableField(0, getter: "private", setter: "private")] @@ -68,7 +70,7 @@ namespace Server.Items _item?.Delete(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] private partial class InternalItem : Item { [SerializableField(0, getter: "private", setter: "private")] @@ -106,7 +108,7 @@ namespace Server.Items } } - [Serializable(0)] + [SerializationGenerator(0)] public partial class DecorativeSwordWest : Item { [SerializableField(0, getter: "private", setter: "private")] @@ -142,7 +144,7 @@ namespace Server.Items _item?.Delete(); } - [Serializable(0)] + [SerializationGenerator(0)] private partial class InternalItem : Item { [SerializableField(0, getter: "private", setter: "private")] @@ -179,7 +181,7 @@ namespace Server.Items } } - [Serializable(0)] + [SerializationGenerator(0)] public partial class DecorativeDAxeNorth : Item { [SerializableField(0, getter: "private", setter: "private")] @@ -215,7 +217,7 @@ namespace Server.Items _item?.Delete(); } - [Serializable(0)] + [SerializationGenerator(0)] private partial class InternalItem : Item { [SerializableField(0, getter: "private", setter: "private")] @@ -253,7 +255,7 @@ namespace Server.Items } } - [Serializable(0)] + [SerializationGenerator(0)] public partial class DecorativeDAxeWest : Item { [SerializableField(0, getter: "private", setter: "private")] @@ -290,7 +292,7 @@ namespace Server.Items _item?.Delete(); } - [Serializable(0)] + [SerializationGenerator(0)] private partial class InternalItem : Item { [SerializableField(0, getter: "private", setter: "private")] diff --git a/Projects/UOContent/Items/Construction/Decorative/GiantReplicaAcorn.cs b/Projects/UOContent/Items/Construction/Decorative/GiantReplicaAcorn.cs index e522d12ed..d0a5c7a3e 100644 --- a/Projects/UOContent/Items/Construction/Decorative/GiantReplicaAcorn.cs +++ b/Projects/UOContent/Items/Construction/Decorative/GiantReplicaAcorn.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Furniture] - [Serializable(0)] + [SerializationGenerator(0)] public partial class GiantReplicaAcorn : Item { [Constructible] diff --git a/Projects/UOContent/Items/Construction/Decorative/MountedDreadHorn.cs b/Projects/UOContent/Items/Construction/Decorative/MountedDreadHorn.cs index d73518208..c3126fff4 100644 --- a/Projects/UOContent/Items/Construction/Decorative/MountedDreadHorn.cs +++ b/Projects/UOContent/Items/Construction/Decorative/MountedDreadHorn.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x3158, 0x3159)] - [Serializable(0)] + [SerializationGenerator(0)] public partial class MountedDreadHorn : Item { [Constructible] diff --git a/Projects/UOContent/Items/Construction/Decorative/PaintingPortraits.cs b/Projects/UOContent/Items/Construction/Decorative/PaintingPortraits.cs index 6695b94f5..9ba0d9b4f 100644 --- a/Projects/UOContent/Items/Construction/Decorative/PaintingPortraits.cs +++ b/Projects/UOContent/Items/Construction/Decorative/PaintingPortraits.cs @@ -1,13 +1,15 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LargePainting : Item { [Constructible] public LargePainting() : base(0x0EA0) => Movable = false; } - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x0E9F, 0x0EC8)] public partial class WomanPortrait1 : Item { @@ -15,7 +17,7 @@ namespace Server.Items public WomanPortrait1() : base(0x0E9F) => Movable = false; } - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x0EE7, 0x0EC9)] public partial class WomanPortrait2 : Item { @@ -23,7 +25,7 @@ namespace Server.Items public WomanPortrait2() : base(0x0EE7) => Movable = false; } - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x0EA2, 0x0EA1)] public partial class ManPortrait1 : Item { @@ -31,7 +33,7 @@ namespace Server.Items public ManPortrait1() : base(0x0EA2) => Movable = false; } - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x0EA3, 0x0EA4)] public partial class ManPortrait2 : Item { @@ -39,7 +41,7 @@ namespace Server.Items public ManPortrait2() : base(0x0EA3) => Movable = false; } - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x0EA6, 0x0EA5)] public partial class LadyPortrait1 : Item { @@ -47,7 +49,7 @@ namespace Server.Items public LadyPortrait1() : base(0x0EA6) => Movable = false; } - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x0EA7, 0x0EA8)] public partial class LadyPortrait2 : Item { diff --git a/Projects/UOContent/Items/Construction/Decorative/Tapestry.cs b/Projects/UOContent/Items/Construction/Decorative/Tapestry.cs index 1a5868096..a057d93b2 100644 --- a/Projects/UOContent/Items/Construction/Decorative/Tapestry.cs +++ b/Projects/UOContent/Items/Construction/Decorative/Tapestry.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Tapestry1N : Item { [SerializableField(0, "private", "private")] @@ -35,7 +37,7 @@ namespace Server.Items _item?.Delete(); } - [Serializable(0)] + [SerializationGenerator(0)] private partial class InternalItem : Item { [SerializableField(0, "private", "private")] @@ -71,7 +73,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Tapestry2N : Item { [SerializableField(0, "private", "private")] @@ -106,7 +108,7 @@ namespace Server.Items _item?.Delete(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] private partial class InternalItem : Item { [SerializableField(0, "private", "private")] @@ -142,7 +144,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Tapestry2W : Item { [SerializableField(0, "private", "private")] @@ -177,7 +179,7 @@ namespace Server.Items _item?.Delete(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] private partial class InternalItem : Item { [SerializableField(0, "private", "private")] @@ -213,7 +215,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Tapestry3N : Item { [SerializableField(0, "private", "private")] @@ -248,7 +250,7 @@ namespace Server.Items _item?.Delete(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] private partial class InternalItem : Item { [SerializableField(0, "private", "private")] @@ -284,7 +286,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Tapestry3W : Item { [SerializableField(0, "private", "private")] @@ -319,7 +321,7 @@ namespace Server.Items _item?.Delete(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] private partial class InternalItem : Item { [SerializableField(0, "private", "private")] @@ -355,7 +357,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Tapestry4N : Item { [SerializableField(0, "private", "private")] @@ -390,7 +392,7 @@ namespace Server.Items _item?.Delete(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] private partial class InternalItem : Item { [SerializableField(0, "private", "private")] @@ -426,7 +428,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Tapestry4W : Item { [SerializableField(0, "private", "private")] @@ -461,7 +463,7 @@ namespace Server.Items _item?.Delete(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] private partial class InternalItem : Item { [SerializableField(0, "private", "private")] @@ -497,7 +499,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Tapestry5N : Item { [SerializableField(0, "private", "private")] @@ -532,7 +534,7 @@ namespace Server.Items _item?.Delete(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] private partial class InternalItem : Item { [SerializableField(0, "private", "private")] @@ -568,7 +570,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Tapestry5W : Item { [SerializableField(0, "private", "private")] @@ -603,7 +605,7 @@ namespace Server.Items _item?.Delete(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] private partial class InternalItem : Item { [SerializableField(0, "private", "private")] @@ -639,7 +641,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Tapestry6N : Item { [SerializableField(0, "private", "private")] @@ -674,7 +676,7 @@ namespace Server.Items _item?.Delete(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] private partial class InternalItem : Item { [SerializableField(0, "private", "private")] @@ -710,7 +712,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Tapestry6W : Item { [SerializableField(0, "private", "private")] @@ -745,7 +747,7 @@ namespace Server.Items _item?.Delete(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] private partial class InternalItem : Item { [SerializableField(0, "private", "private")] diff --git a/Projects/UOContent/Items/Construction/Tables/ElvenPodium.cs b/Projects/UOContent/Items/Construction/Tables/ElvenPodium.cs index df9620907..c17fbe287 100644 --- a/Projects/UOContent/Items/Construction/Tables/ElvenPodium.cs +++ b/Projects/UOContent/Items/Construction/Tables/ElvenPodium.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Furniture] - [Serializable(0)] + [SerializationGenerator(0)] [Flippable(0x2DDD, 0x2DDE)] public partial class ElvenPodium : Item { diff --git a/Projects/UOContent/Items/Construction/Tables/Tables.cs b/Projects/UOContent/Items/Construction/Tables/Tables.cs index 65f1bdbf1..b7602efaa 100644 --- a/Projects/UOContent/Items/Construction/Tables/Tables.cs +++ b/Projects/UOContent/Items/Construction/Tables/Tables.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Furniture] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class ElegantLowTable : Item { [Constructible] @@ -9,7 +11,7 @@ namespace Server.Items } [Furniture] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class PlainLowTable : Item { [Constructible] @@ -18,7 +20,7 @@ namespace Server.Items [Furniture] [Flippable(0xB90, 0xB7D)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LargeTable : Item { [Constructible] @@ -27,7 +29,7 @@ namespace Server.Items [Furniture] [Flippable(0xB35, 0xB34)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Nightstand : Item { [Constructible] @@ -36,7 +38,7 @@ namespace Server.Items [Furniture] [Flippable(0xB8F, 0xB7C)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class YewWoodTable : Item { [Constructible] diff --git a/Projects/UOContent/Items/Construction/Tables/WritingTable.cs b/Projects/UOContent/Items/Construction/Tables/WritingTable.cs index 35ec06c37..077978a8d 100644 --- a/Projects/UOContent/Items/Construction/Tables/WritingTable.cs +++ b/Projects/UOContent/Items/Construction/Tables/WritingTable.cs @@ -1,8 +1,10 @@ +using ModernUO.Serialization; + namespace Server.Items { [Furniture] [Flippable(0xB4A, 0xB49, 0xB4B, 0xB4C)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class WritingTable : Item { [Constructible] diff --git a/Projects/UOContent/Items/Construction/Walls/BaseWall.cs b/Projects/UOContent/Items/Construction/Walls/BaseWall.cs index 6b5914a07..7c5684fbe 100644 --- a/Projects/UOContent/Items/Construction/Walls/BaseWall.cs +++ b/Projects/UOContent/Items/Construction/Walls/BaseWall.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public abstract partial class BaseWall : Item { public BaseWall(int itemID) : base(itemID) => Movable = false; diff --git a/Projects/UOContent/Items/Construction/Walls/DarkWoodWall.cs b/Projects/UOContent/Items/Construction/Walls/DarkWoodWall.cs index a1e6e4077..39036ea51 100644 --- a/Projects/UOContent/Items/Construction/Walls/DarkWoodWall.cs +++ b/Projects/UOContent/Items/Construction/Walls/DarkWoodWall.cs @@ -1,3 +1,5 @@ +using ModernUO.Serialization; + namespace Server.Items { public enum DarkWoodWallTypes @@ -24,7 +26,7 @@ namespace Server.Items EastWallVShort } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class DarkWoodWall : BaseWall { [Constructible] diff --git a/Projects/UOContent/Items/Construction/Walls/ThickGrayStoneWall.cs b/Projects/UOContent/Items/Construction/Walls/ThickGrayStoneWall.cs index 17514de42..609ce720b 100644 --- a/Projects/UOContent/Items/Construction/Walls/ThickGrayStoneWall.cs +++ b/Projects/UOContent/Items/Construction/Walls/ThickGrayStoneWall.cs @@ -6,6 +6,8 @@ * CREATED : 10-07.2002 * * **************************************/ +using ModernUO.Serialization; + namespace Server.Items { public enum ThickGrayStoneWallTypes @@ -34,7 +36,7 @@ namespace Server.Items EastWindow2 } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class ThickGrayStoneWall : BaseWall { [Constructible] diff --git a/Projects/UOContent/Items/Construction/Walls/ThinBrickWall.cs b/Projects/UOContent/Items/Construction/Walls/ThinBrickWall.cs index f69a3cda3..4616b6ad0 100644 --- a/Projects/UOContent/Items/Construction/Walls/ThinBrickWall.cs +++ b/Projects/UOContent/Items/Construction/Walls/ThinBrickWall.cs @@ -1,3 +1,5 @@ +using ModernUO.Serialization; + namespace Server.Items { public enum ThinBrickWallTypes @@ -40,7 +42,7 @@ namespace Server.Items EastWallVShort } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class ThinBrickWall : BaseWall { [Constructible] diff --git a/Projects/UOContent/Items/Construction/Walls/ThinStoneWall.cs b/Projects/UOContent/Items/Construction/Walls/ThinStoneWall.cs index 7754c7b10..0b0f14991 100644 --- a/Projects/UOContent/Items/Construction/Walls/ThinStoneWall.cs +++ b/Projects/UOContent/Items/Construction/Walls/ThinStoneWall.cs @@ -1,3 +1,5 @@ +using ModernUO.Serialization; + namespace Server.Items { public enum ThinStoneWallTypes @@ -29,7 +31,7 @@ namespace Server.Items EastWallShort2 } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class ThinStoneWall : BaseWall { [Constructible] diff --git a/Projects/UOContent/Items/Construction/Walls/WhiteStoneWall.cs b/Projects/UOContent/Items/Construction/Walls/WhiteStoneWall.cs index 07a6f0d16..3679905a5 100644 --- a/Projects/UOContent/Items/Construction/Walls/WhiteStoneWall.cs +++ b/Projects/UOContent/Items/Construction/Walls/WhiteStoneWall.cs @@ -6,6 +6,8 @@ * CREATED : 10-07.2002 * * **************************************/ +using ModernUO.Serialization; + namespace Server.Items { public enum WhiteStoneWallTypes @@ -47,7 +49,7 @@ namespace Server.Items EastWallVVShort } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class WhiteStoneWall : BaseWall { [Constructible] diff --git a/Projects/UOContent/Items/Containers/BaseTreasureChest.cs b/Projects/UOContent/Items/Containers/BaseTreasureChest.cs index 95be9334e..0dcbd55ec 100644 --- a/Projects/UOContent/Items/Containers/BaseTreasureChest.cs +++ b/Projects/UOContent/Items/Containers/BaseTreasureChest.cs @@ -1,8 +1,9 @@ using System; +using ModernUO.Serialization; namespace Server.Items; -[Serializable(1, false)] +[SerializationGenerator(1, false)] public partial class BaseTreasureChest : LockableContainer { public enum TreasureLevel diff --git a/Projects/UOContent/Items/Containers/Container.cs b/Projects/UOContent/Items/Containers/Container.cs index eea535f1e..c634237fc 100644 --- a/Projects/UOContent/Items/Containers/Container.cs +++ b/Projects/UOContent/Items/Containers/Container.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using ModernUO.Serialization; using Server.ContextMenus; using Server.Mobiles; using Server.Multis; @@ -159,7 +160,7 @@ public abstract class BaseContainer : Container } } -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class CreatureBackpack : Backpack // Used on BaseCreature { [Constructible] @@ -209,7 +210,7 @@ public partial class CreatureBackpack : Backpack // Used on BaseCreature public override bool TryDropItem(Mobile from, Item dropped, bool sendFullMessage) => false; } -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class StrongBackpack : Backpack // Used on Pack animals { [Constructible] @@ -229,7 +230,7 @@ public partial class StrongBackpack : Backpack // Used on Pack animals base.CheckContentDisplay(from); } -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class Backpack : BaseContainer, IDyable { [Constructible] @@ -265,14 +266,14 @@ public partial class Backpack : BaseContainer, IDyable } } -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class Pouch : TrappableContainer { [Constructible] public Pouch() : base(0xE79) => Weight = 1.0; } -[Serializable(0, false)] +[SerializationGenerator(0, false)] public abstract partial class BaseBagBall : BaseContainer, IDyable { public BaseBagBall(int itemID) : base(itemID) => Weight = 1.0; @@ -290,7 +291,7 @@ public abstract partial class BaseBagBall : BaseContainer, IDyable } } -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class SmallBagBall : BaseBagBall { [Constructible] @@ -299,7 +300,7 @@ public partial class SmallBagBall : BaseBagBall } } -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class LargeBagBall : BaseBagBall { [Constructible] @@ -308,7 +309,7 @@ public partial class LargeBagBall : BaseBagBall } } -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class Bag : BaseContainer, IDyable { [Constructible] @@ -327,28 +328,28 @@ public partial class Bag : BaseContainer, IDyable } } -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class Barrel : BaseContainer { [Constructible] public Barrel() : base(0xE77) => Weight = 25.0; } -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class Keg : BaseContainer { [Constructible] public Keg() : base(0xE7F) => Weight = 15.0; } -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class PicnicBasket : BaseContainer { [Constructible] public PicnicBasket() : base(0xE7A) => Weight = 2.0; } -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class Basket : BaseContainer { [Constructible] @@ -357,7 +358,7 @@ public partial class Basket : BaseContainer [Furniture] [Flippable(0x9AA, 0xE7D)] -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class WoodenBox : LockableContainer { [Constructible] @@ -366,7 +367,7 @@ public partial class WoodenBox : LockableContainer [Furniture] [Flippable(0x9A9, 0xE7E)] -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class SmallCrate : LockableContainer { [Constructible] @@ -375,7 +376,7 @@ public partial class SmallCrate : LockableContainer [Furniture] [Flippable(0xE3F, 0xE3E)] -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class MediumCrate : LockableContainer { [Constructible] @@ -384,7 +385,7 @@ public partial class MediumCrate : LockableContainer [Furniture] [Flippable(0xE3D, 0xE3C)] -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class LargeCrate : LockableContainer { [Constructible] @@ -393,7 +394,7 @@ public partial class LargeCrate : LockableContainer [DynamicFlipping] [Flippable(0x9A8, 0xE80)] -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class MetalBox : LockableContainer { [Constructible] @@ -404,7 +405,7 @@ public partial class MetalBox : LockableContainer [DynamicFlipping] [Flippable(0x9AB, 0xE7C)] -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class MetalChest : LockableContainer { [Constructible] @@ -414,7 +415,7 @@ public partial class MetalChest : LockableContainer } [DynamicFlipping, Flippable(0xE41, 0xE40)] -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class MetalGoldenChest : LockableContainer { [Constructible] @@ -425,7 +426,7 @@ public partial class MetalGoldenChest : LockableContainer [Furniture] [Flippable(0xe43, 0xe42)] -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class WoodenChest : LockableContainer { [Constructible] @@ -434,7 +435,7 @@ public partial class WoodenChest : LockableContainer [Furniture] [Flippable(0x280B, 0x280C)] -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class PlainWoodenChest : LockableContainer { [Constructible] @@ -445,7 +446,7 @@ public partial class PlainWoodenChest : LockableContainer [Furniture] [Flippable(0x280D, 0x280E)] -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class OrnateWoodenChest : LockableContainer { [Constructible] @@ -456,7 +457,7 @@ public partial class OrnateWoodenChest : LockableContainer [Furniture] [Flippable(0x280F, 0x2810)] -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class GildedWoodenChest : LockableContainer { [Constructible] @@ -467,7 +468,7 @@ public partial class GildedWoodenChest : LockableContainer [Furniture] [Flippable(0x2811, 0x2812)] -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class WoodenFootLocker : LockableContainer { [Constructible] @@ -476,7 +477,7 @@ public partial class WoodenFootLocker : LockableContainer [Furniture] [Flippable(0x2813, 0x2814)] -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class FinishedWoodenChest : LockableContainer { [Constructible] @@ -486,7 +487,7 @@ public partial class FinishedWoodenChest : LockableContainer } [Furniture] -[Serializable(0)] +[SerializationGenerator(0)] [Flippable(0x2DF1, 0x2DF2)] public partial class RarewoodChest : LockableContainer { @@ -497,7 +498,7 @@ public partial class RarewoodChest : LockableContainer } [Furniture] -[Serializable(0)] +[SerializationGenerator(0)] [Flippable(0x2DF3, 0x2DF4)] public partial class DecorativeBox : LockableContainer { diff --git a/Projects/UOContent/Items/Containers/FurnitureContainer.cs b/Projects/UOContent/Items/Containers/FurnitureContainer.cs index e718faa1e..e638ab2d7 100644 --- a/Projects/UOContent/Items/Containers/FurnitureContainer.cs +++ b/Projects/UOContent/Items/Containers/FurnitureContainer.cs @@ -1,11 +1,12 @@ using System; using System.Collections.Generic; +using ModernUO.Serialization; namespace Server.Items; [Furniture] [Flippable(0x2815, 0x2816)] -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class TallCabinet : BaseContainer { [Constructible] @@ -14,7 +15,7 @@ public partial class TallCabinet : BaseContainer [Furniture] [Flippable(0x2817, 0x2818)] -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class ShortCabinet : BaseContainer { [Constructible] @@ -23,7 +24,7 @@ public partial class ShortCabinet : BaseContainer [Furniture] [Flippable(0x2857, 0x2858)] -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class RedArmoire : BaseContainer { [Constructible] @@ -32,7 +33,7 @@ public partial class RedArmoire : BaseContainer [Furniture] [Flippable(0x285D, 0x285E)] -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class CherryArmoire : BaseContainer { [Constructible] @@ -41,7 +42,7 @@ public partial class CherryArmoire : BaseContainer [Furniture] [Flippable(0x285B, 0x285C)] -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class MapleArmoire : BaseContainer { [Constructible] @@ -50,7 +51,7 @@ public partial class MapleArmoire : BaseContainer [Furniture] [Flippable(0x2859, 0x285A)] -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class ElegantArmoire : BaseContainer { [Constructible] @@ -58,7 +59,7 @@ public partial class ElegantArmoire : BaseContainer } [Furniture] -[Serializable(0)] +[SerializationGenerator(0)] [Flippable(0x2D07, 0x2D08)] public partial class FancyElvenArmoire : BaseContainer { @@ -69,7 +70,7 @@ public partial class FancyElvenArmoire : BaseContainer } [Furniture] -[Serializable(0)] +[SerializationGenerator(0)] [Flippable(0x2D05, 0x2D06)] public partial class SimpleElvenArmoire : BaseContainer { @@ -81,7 +82,7 @@ public partial class SimpleElvenArmoire : BaseContainer [Furniture] [Flippable(0xa97, 0xa99, 0xa98, 0xa9a, 0xa9b, 0xa9c)] -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class FullBookcase : BaseContainer { [Constructible] @@ -90,7 +91,7 @@ public partial class FullBookcase : BaseContainer [Furniture] [Flippable(0xa9d, 0xa9e)] -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class EmptyBookcase : BaseContainer { [Constructible] @@ -101,7 +102,7 @@ public partial class EmptyBookcase : BaseContainer [Furniture] [Flippable(0xa2c, 0xa34)] -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class Drawer : BaseContainer { [Constructible] @@ -110,7 +111,7 @@ public partial class Drawer : BaseContainer [Furniture] [Flippable(0xa30, 0xa38)] -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class FancyDrawer : BaseContainer { [Constructible] @@ -119,7 +120,7 @@ public partial class FancyDrawer : BaseContainer [Furniture] [Flippable(0xa4f, 0xa53)] -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class Armoire : BaseContainer { [Constructible] @@ -142,7 +143,7 @@ public partial class Armoire : BaseContainer [Furniture] [Flippable(0xa4d, 0xa51)] -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class FancyArmoire : BaseContainer { [Constructible] diff --git a/Projects/UOContent/Items/Containers/LockableContainer.cs b/Projects/UOContent/Items/Containers/LockableContainer.cs index 2d465001f..1bbad4d64 100644 --- a/Projects/UOContent/Items/Containers/LockableContainer.cs +++ b/Projects/UOContent/Items/Containers/LockableContainer.cs @@ -1,10 +1,11 @@ using System; +using ModernUO.Serialization; using Server.Engines.Craft; using Server.Network; namespace Server.Items; -[Serializable(0, false)] +[SerializationGenerator(0, false)] public abstract partial class LockableContainer : TrappableContainer, ILockable, ILockpickable, ICraftable, IShipwreckedItem { public LockableContainer(int itemID) : base(itemID) => MaxLockLevel = 100; diff --git a/Projects/UOContent/Items/Containers/MarkContainer.cs b/Projects/UOContent/Items/Containers/MarkContainer.cs index 5099c7e3e..59846b477 100644 --- a/Projects/UOContent/Items/Containers/MarkContainer.cs +++ b/Projects/UOContent/Items/Containers/MarkContainer.cs @@ -1,8 +1,9 @@ using System; +using ModernUO.Serialization; namespace Server.Items; -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class MarkContainer : LockableContainer { [SerializableField(0, getter: "private", setter: "private")] diff --git a/Projects/UOContent/Items/Containers/ParagonChest.cs b/Projects/UOContent/Items/Containers/ParagonChest.cs index 9dab1ed92..8f95fbfa4 100644 --- a/Projects/UOContent/Items/Containers/ParagonChest.cs +++ b/Projects/UOContent/Items/Containers/ParagonChest.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items; [Flippable] -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class ParagonChest : LockableContainer { private static readonly int[] _itemIDs = diff --git a/Projects/UOContent/Items/Containers/SalvageBag.cs b/Projects/UOContent/Items/Containers/SalvageBag.cs index 365a9e39d..1a75f8449 100644 --- a/Projects/UOContent/Items/Containers/SalvageBag.cs +++ b/Projects/UOContent/Items/Containers/SalvageBag.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using ModernUO.Serialization; using Server.ContextMenus; using Server.Engines.Craft; using Server.Network; @@ -8,7 +9,7 @@ using Server.Utilities; namespace Server.Items; -[Serializable(0)] +[SerializationGenerator(0)] public partial class SalvageBag : Bag { private bool m_Failure; diff --git a/Projects/UOContent/Items/Containers/Strongbox.cs b/Projects/UOContent/Items/Containers/Strongbox.cs index 880192a72..245bbd9c9 100644 --- a/Projects/UOContent/Items/Containers/Strongbox.cs +++ b/Projects/UOContent/Items/Containers/Strongbox.cs @@ -1,11 +1,12 @@ using System; using System.Collections.Generic; +using ModernUO.Serialization; using Server.Multis; namespace Server.Items; [Flippable(0xE80, 0x9A8)] -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class StrongBox : BaseContainer, IChoppable { [InvalidateProperties] diff --git a/Projects/UOContent/Items/Containers/TrappableContainer.cs b/Projects/UOContent/Items/Containers/TrappableContainer.cs index f4b4f51f7..ebe9cfc8b 100644 --- a/Projects/UOContent/Items/Containers/TrappableContainer.cs +++ b/Projects/UOContent/Items/Containers/TrappableContainer.cs @@ -1,3 +1,4 @@ +using ModernUO.Serialization; using Server.Network; namespace Server.Items; @@ -11,7 +12,7 @@ public enum TrapType PoisonTrap } -[Serializable(3, false)] +[SerializationGenerator(3, false)] public abstract partial class TrappableContainer : BaseContainer, ITelekinesisable { [SerializableField(0)] diff --git a/Projects/UOContent/Items/Containers/TreasureChest.cs b/Projects/UOContent/Items/Containers/TreasureChest.cs index d0f9f3acb..b1e01bb14 100644 --- a/Projects/UOContent/Items/Containers/TreasureChest.cs +++ b/Projects/UOContent/Items/Containers/TreasureChest.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items; [Flippable(0xe43, 0xe42)] -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class WoodenTreasureChest : BaseTreasureChest { [Constructible] @@ -11,7 +13,7 @@ public partial class WoodenTreasureChest : BaseTreasureChest } [Flippable(0xe41, 0xe40)] -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class MetalGoldenTreasureChest : BaseTreasureChest { [Constructible] @@ -21,7 +23,7 @@ public partial class MetalGoldenTreasureChest : BaseTreasureChest } [Flippable(0x9ab, 0xe7c)] -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class MetalTreasureChest : BaseTreasureChest { [Constructible] diff --git a/Projects/UOContent/Items/Containers/TreasureMapChest.cs b/Projects/UOContent/Items/Containers/TreasureMapChest.cs index bbe01747f..03e7922ee 100644 --- a/Projects/UOContent/Items/Containers/TreasureMapChest.cs +++ b/Projects/UOContent/Items/Containers/TreasureMapChest.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using ModernUO.Serialization; using Server.ContextMenus; using Server.Engines.PartySystem; using Server.Gumps; @@ -8,7 +9,7 @@ using Server.Utilities; namespace Server.Items; -[Serializable(2, false)] +[SerializationGenerator(2, false)] public partial class TreasureMapChest : LockableContainer { [SerializableField(0, setter: "private")] diff --git a/Projects/UOContent/Items/Decoration Artifacts/AcademicBooksArtifacts.cs b/Projects/UOContent/Items/Decoration Artifacts/AcademicBooksArtifacts.cs index 186e919e9..11698d565 100644 --- a/Projects/UOContent/Items/Decoration Artifacts/AcademicBooksArtifacts.cs +++ b/Projects/UOContent/Items/Decoration Artifacts/AcademicBooksArtifacts.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class AcademicBooksArtifact : BaseDecorationArtifact { public override int ArtifactRarity => 8; diff --git a/Projects/UOContent/Items/Decoration Artifacts/BaseDecorationArtifact.cs b/Projects/UOContent/Items/Decoration Artifacts/BaseDecorationArtifact.cs index 5f6843333..079bb9d30 100644 --- a/Projects/UOContent/Items/Decoration Artifacts/BaseDecorationArtifact.cs +++ b/Projects/UOContent/Items/Decoration Artifacts/BaseDecorationArtifact.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items; -[Serializable(0)] +[SerializationGenerator(0)] public abstract partial class BaseDecorationArtifact : Item { public BaseDecorationArtifact(int itemID) : base(itemID) => Weight = 10.0; @@ -17,7 +19,7 @@ public abstract partial class BaseDecorationArtifact : Item } } -[Serializable(0)] +[SerializationGenerator(0)] public abstract partial class BaseDecorationContainerArtifact : BaseContainer { public BaseDecorationContainerArtifact(int itemID) : base(itemID) => Weight = 10.0; diff --git a/Projects/UOContent/Items/Decoration Artifacts/DoomDecorationArtifacts.cs b/Projects/UOContent/Items/Decoration Artifacts/DoomDecorationArtifacts.cs index 70af11141..c758b8000 100644 --- a/Projects/UOContent/Items/Decoration Artifacts/DoomDecorationArtifacts.cs +++ b/Projects/UOContent/Items/Decoration Artifacts/DoomDecorationArtifacts.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items; -[Serializable(0)] +[SerializationGenerator(0)] public partial class BackpackArtifact : BaseDecorationContainerArtifact { [Constructible] @@ -11,7 +13,7 @@ public partial class BackpackArtifact : BaseDecorationContainerArtifact public override int ArtifactRarity => 5; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class BloodyWaterArtifact : BaseDecorationArtifact { [Constructible] @@ -22,7 +24,7 @@ public partial class BloodyWaterArtifact : BaseDecorationArtifact public override int ArtifactRarity => 5; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class BooksWestArtifact : BaseDecorationArtifact { [Constructible] @@ -33,7 +35,7 @@ public partial class BooksWestArtifact : BaseDecorationArtifact public override int ArtifactRarity => 3; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class BooksNorthArtifact : BaseDecorationArtifact { [Constructible] @@ -44,7 +46,7 @@ public partial class BooksNorthArtifact : BaseDecorationArtifact public override int ArtifactRarity => 3; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class BooksFaceDownArtifact : BaseDecorationArtifact { [Constructible] @@ -55,7 +57,7 @@ public partial class BooksFaceDownArtifact : BaseDecorationArtifact public override int ArtifactRarity => 3; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class BottleArtifact : BaseDecorationArtifact { [Constructible] @@ -66,7 +68,7 @@ public partial class BottleArtifact : BaseDecorationArtifact public override int ArtifactRarity => 1; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class BrazierArtifact : BaseDecorationArtifact { [Constructible] @@ -75,7 +77,7 @@ public partial class BrazierArtifact : BaseDecorationArtifact public override int ArtifactRarity => 2; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class CocoonArtifact : BaseDecorationArtifact { [Constructible] @@ -86,7 +88,7 @@ public partial class CocoonArtifact : BaseDecorationArtifact public override int ArtifactRarity => 7; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class DamagedBooksArtifact : BaseDecorationArtifact { [Constructible] @@ -97,7 +99,7 @@ public partial class DamagedBooksArtifact : BaseDecorationArtifact public override int ArtifactRarity => 1; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class EggCaseArtifact : BaseDecorationArtifact { [Constructible] @@ -108,7 +110,7 @@ public partial class EggCaseArtifact : BaseDecorationArtifact public override int ArtifactRarity => 5; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class GruesomeStandardArtifact : BaseDecorationArtifact { [Constructible] @@ -119,7 +121,7 @@ public partial class GruesomeStandardArtifact : BaseDecorationArtifact public override int ArtifactRarity => 5; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class LampPostArtifact : BaseDecorationArtifact { [Constructible] @@ -128,7 +130,7 @@ public partial class LampPostArtifact : BaseDecorationArtifact public override int ArtifactRarity => 3; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class LeatherTunicArtifact : BaseDecorationArtifact { [Constructible] @@ -139,7 +141,7 @@ public partial class LeatherTunicArtifact : BaseDecorationArtifact public override int ArtifactRarity => 9; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class RockArtifact : BaseDecorationArtifact { [Constructible] @@ -150,7 +152,7 @@ public partial class RockArtifact : BaseDecorationArtifact public override int ArtifactRarity => 1; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class RuinedPaintingArtifact : BaseDecorationArtifact { [Constructible] @@ -161,7 +163,7 @@ public partial class RuinedPaintingArtifact : BaseDecorationArtifact public override int ArtifactRarity => 12; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class SaddleArtifact : BaseDecorationArtifact { [Constructible] @@ -172,7 +174,7 @@ public partial class SaddleArtifact : BaseDecorationArtifact public override int ArtifactRarity => 9; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class SkinnedDeerArtifact : BaseDecorationArtifact { [Constructible] @@ -183,7 +185,7 @@ public partial class SkinnedDeerArtifact : BaseDecorationArtifact public override int ArtifactRarity => 8; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class SkinnedGoatArtifact : BaseDecorationArtifact { [Constructible] @@ -194,7 +196,7 @@ public partial class SkinnedGoatArtifact : BaseDecorationArtifact public override int ArtifactRarity => 5; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class SkullCandleArtifact : BaseDecorationArtifact { [Constructible] @@ -203,7 +205,7 @@ public partial class SkullCandleArtifact : BaseDecorationArtifact public override int ArtifactRarity => 1; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class StretchedHideArtifact : BaseDecorationArtifact { [Constructible] @@ -214,7 +216,7 @@ public partial class StretchedHideArtifact : BaseDecorationArtifact public override int ArtifactRarity => 2; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class StuddedLeggingsArtifact : BaseDecorationArtifact { [Constructible] @@ -225,7 +227,7 @@ public partial class StuddedLeggingsArtifact : BaseDecorationArtifact public override int ArtifactRarity => 5; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class StuddedTunicArtifact : BaseDecorationArtifact { [Constructible] @@ -236,7 +238,7 @@ public partial class StuddedTunicArtifact : BaseDecorationArtifact public override int ArtifactRarity => 7; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class TarotCardsArtifact : BaseDecorationArtifact { [Constructible] diff --git a/Projects/UOContent/Items/Decoration Artifacts/SEDecorationArtifacts.cs b/Projects/UOContent/Items/Decoration Artifacts/SEDecorationArtifacts.cs index 2f1ce0be6..a637e282f 100644 --- a/Projects/UOContent/Items/Decoration Artifacts/SEDecorationArtifacts.cs +++ b/Projects/UOContent/Items/Decoration Artifacts/SEDecorationArtifacts.cs @@ -1,8 +1,9 @@ +using ModernUO.Serialization; using Server.Network; namespace Server.Items; -[Serializable(0)] +[SerializationGenerator(0)] public partial class Basket1Artifact : BaseDecorationContainerArtifact { [Constructible] @@ -13,7 +14,7 @@ public partial class Basket1Artifact : BaseDecorationContainerArtifact public override int ArtifactRarity => 1; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class Basket2Artifact : BaseDecorationContainerArtifact { [Constructible] @@ -24,7 +25,7 @@ public partial class Basket2Artifact : BaseDecorationContainerArtifact public override int ArtifactRarity => 1; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class Basket3WestArtifact : BaseDecorationContainerArtifact { [Constructible] @@ -35,7 +36,7 @@ public partial class Basket3WestArtifact : BaseDecorationContainerArtifact public override int ArtifactRarity => 1; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class Basket3NorthArtifact : BaseDecorationContainerArtifact { [Constructible] @@ -46,7 +47,7 @@ public partial class Basket3NorthArtifact : BaseDecorationContainerArtifact public override int ArtifactRarity => 1; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class Basket4Artifact : BaseDecorationContainerArtifact { [Constructible] @@ -57,7 +58,7 @@ public partial class Basket4Artifact : BaseDecorationContainerArtifact public override int ArtifactRarity => 2; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class Basket5WestArtifact : BaseDecorationContainerArtifact { [Constructible] @@ -68,7 +69,7 @@ public partial class Basket5WestArtifact : BaseDecorationContainerArtifact public override int ArtifactRarity => 2; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class Basket5NorthArtifact : BaseDecorationContainerArtifact { [Constructible] @@ -79,7 +80,7 @@ public partial class Basket5NorthArtifact : BaseDecorationContainerArtifact public override int ArtifactRarity => 2; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class Basket6Artifact : BaseDecorationContainerArtifact { [Constructible] @@ -90,7 +91,7 @@ public partial class Basket6Artifact : BaseDecorationContainerArtifact public override int ArtifactRarity => 2; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class BowlArtifact : BaseDecorationArtifact { [Constructible] @@ -101,7 +102,7 @@ public partial class BowlArtifact : BaseDecorationArtifact public override int ArtifactRarity => 4; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class BowlsVerticalArtifact : BaseDecorationArtifact { [Constructible] @@ -112,7 +113,7 @@ public partial class BowlsVerticalArtifact : BaseDecorationArtifact public override int ArtifactRarity => 3; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class BowlsHorizontalArtifact : BaseDecorationArtifact { [Constructible] @@ -123,7 +124,7 @@ public partial class BowlsHorizontalArtifact : BaseDecorationArtifact public override int ArtifactRarity => 4; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class CupsArtifact : BaseDecorationArtifact { [Constructible] @@ -134,7 +135,7 @@ public partial class CupsArtifact : BaseDecorationArtifact public override int ArtifactRarity => 4; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class FanWestArtifact : BaseDecorationArtifact { [Constructible] @@ -145,7 +146,7 @@ public partial class FanWestArtifact : BaseDecorationArtifact public override int ArtifactRarity => 3; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class FanNorthArtifact : BaseDecorationArtifact { [Constructible] @@ -156,7 +157,7 @@ public partial class FanNorthArtifact : BaseDecorationArtifact public override int ArtifactRarity => 3; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class TripleFanWestArtifact : BaseDecorationArtifact { [Constructible] @@ -167,7 +168,7 @@ public partial class TripleFanWestArtifact : BaseDecorationArtifact public override int ArtifactRarity => 4; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class TripleFanNorthArtifact : BaseDecorationArtifact { [Constructible] @@ -178,7 +179,7 @@ public partial class TripleFanNorthArtifact : BaseDecorationArtifact public override int ArtifactRarity => 4; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class FlowersArtifact : BaseDecorationArtifact { [Constructible] @@ -189,7 +190,7 @@ public partial class FlowersArtifact : BaseDecorationArtifact public override int ArtifactRarity => 7; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class Painting1WestArtifact : BaseDecorationArtifact { [Constructible] @@ -200,7 +201,7 @@ public partial class Painting1WestArtifact : BaseDecorationArtifact public override int ArtifactRarity => 4; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class Painting1NorthArtifact : BaseDecorationArtifact { [Constructible] @@ -211,7 +212,7 @@ public partial class Painting1NorthArtifact : BaseDecorationArtifact public override int ArtifactRarity => 4; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class Painting2WestArtifact : BaseDecorationArtifact { [Constructible] @@ -222,7 +223,7 @@ public partial class Painting2WestArtifact : BaseDecorationArtifact public override int ArtifactRarity => 4; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class Painting2NorthArtifact : BaseDecorationArtifact { [Constructible] @@ -233,7 +234,7 @@ public partial class Painting2NorthArtifact : BaseDecorationArtifact public override int ArtifactRarity => 4; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class Painting3Artifact : BaseDecorationArtifact { [Constructible] @@ -244,7 +245,7 @@ public partial class Painting3Artifact : BaseDecorationArtifact public override int ArtifactRarity => 5; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class Painting4WestArtifact : BaseDecorationArtifact { [Constructible] @@ -255,7 +256,7 @@ public partial class Painting4WestArtifact : BaseDecorationArtifact public override int ArtifactRarity => 6; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class Painting4NorthArtifact : BaseDecorationArtifact { [Constructible] @@ -266,7 +267,7 @@ public partial class Painting4NorthArtifact : BaseDecorationArtifact public override int ArtifactRarity => 6; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class Painting5WestArtifact : BaseDecorationArtifact { [Constructible] @@ -277,7 +278,7 @@ public partial class Painting5WestArtifact : BaseDecorationArtifact public override int ArtifactRarity => 8; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class Painting5NorthArtifact : BaseDecorationArtifact { [Constructible] @@ -288,7 +289,7 @@ public partial class Painting5NorthArtifact : BaseDecorationArtifact public override int ArtifactRarity => 8; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class Painting6WestArtifact : BaseDecorationArtifact { [Constructible] @@ -299,7 +300,7 @@ public partial class Painting6WestArtifact : BaseDecorationArtifact public override int ArtifactRarity => 9; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class Painting6NorthArtifact : BaseDecorationArtifact { [Constructible] @@ -310,7 +311,7 @@ public partial class Painting6NorthArtifact : BaseDecorationArtifact public override int ArtifactRarity => 9; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class SakeArtifact : BaseDecorationArtifact { [Constructible] @@ -321,7 +322,7 @@ public partial class SakeArtifact : BaseDecorationArtifact public override int ArtifactRarity => 4; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class Sculpture1Artifact : BaseDecorationArtifact { [Constructible] @@ -332,7 +333,7 @@ public partial class Sculpture1Artifact : BaseDecorationArtifact public override int ArtifactRarity => 3; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class Sculpture2Artifact : BaseDecorationArtifact { [Constructible] @@ -343,7 +344,7 @@ public partial class Sculpture2Artifact : BaseDecorationArtifact public override int ArtifactRarity => 3; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class DolphinLeftArtifact : BaseDecorationArtifact { [Constructible] @@ -354,7 +355,7 @@ public partial class DolphinLeftArtifact : BaseDecorationArtifact public override int ArtifactRarity => 8; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class DolphinRightArtifact : BaseDecorationArtifact { [Constructible] @@ -365,7 +366,7 @@ public partial class DolphinRightArtifact : BaseDecorationArtifact public override int ArtifactRarity => 8; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class ManStatuetteSouthArtifact : BaseDecorationArtifact { [Constructible] @@ -376,7 +377,7 @@ public partial class ManStatuetteSouthArtifact : BaseDecorationArtifact public override int ArtifactRarity => 9; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class ManStatuetteEastArtifact : BaseDecorationArtifact { [Constructible] @@ -387,7 +388,7 @@ public partial class ManStatuetteEastArtifact : BaseDecorationArtifact public override int ArtifactRarity => 9; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class SwordDisplay1WestArtifact : BaseDecorationArtifact { [Constructible] @@ -398,7 +399,7 @@ public partial class SwordDisplay1WestArtifact : BaseDecorationArtifact public override int ArtifactRarity => 5; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class SwordDisplay1NorthArtifact : BaseDecorationArtifact { [Constructible] @@ -409,7 +410,7 @@ public partial class SwordDisplay1NorthArtifact : BaseDecorationArtifact public override int ArtifactRarity => 5; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class SwordDisplay2WestArtifact : BaseDecorationArtifact { [Constructible] @@ -420,7 +421,7 @@ public partial class SwordDisplay2WestArtifact : BaseDecorationArtifact public override int ArtifactRarity => 6; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class SwordDisplay2NorthArtifact : BaseDecorationArtifact { [Constructible] @@ -431,7 +432,7 @@ public partial class SwordDisplay2NorthArtifact : BaseDecorationArtifact public override int ArtifactRarity => 6; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class SwordDisplay3SouthArtifact : BaseDecorationArtifact { [Constructible] @@ -442,7 +443,7 @@ public partial class SwordDisplay3SouthArtifact : BaseDecorationArtifact public override int ArtifactRarity => 8; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class SwordDisplay3EastArtifact : BaseDecorationArtifact { [Constructible] @@ -453,7 +454,7 @@ public partial class SwordDisplay3EastArtifact : BaseDecorationArtifact public override int ArtifactRarity => 8; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class SwordDisplay4WestArtifact : BaseDecorationArtifact { [Constructible] @@ -464,7 +465,7 @@ public partial class SwordDisplay4WestArtifact : BaseDecorationArtifact public override int ArtifactRarity => 8; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class SwordDisplay4NorthArtifact : BaseDecorationArtifact { [Constructible] @@ -475,7 +476,7 @@ public partial class SwordDisplay4NorthArtifact : BaseDecorationArtifact public override int ArtifactRarity => 9; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class SwordDisplay5WestArtifact : BaseDecorationArtifact { [Constructible] @@ -486,7 +487,7 @@ public partial class SwordDisplay5WestArtifact : BaseDecorationArtifact public override int ArtifactRarity => 9; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class SwordDisplay5NorthArtifact : BaseDecorationArtifact { [Constructible] @@ -497,7 +498,7 @@ public partial class SwordDisplay5NorthArtifact : BaseDecorationArtifact public override int ArtifactRarity => 9; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class TeapotWestArtifact : BaseDecorationArtifact { [Constructible] @@ -508,7 +509,7 @@ public partial class TeapotWestArtifact : BaseDecorationArtifact public override int ArtifactRarity => 3; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class TeapotNorthArtifact : BaseDecorationArtifact { [Constructible] @@ -519,7 +520,7 @@ public partial class TeapotNorthArtifact : BaseDecorationArtifact public override int ArtifactRarity => 3; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class TowerLanternArtifact : BaseDecorationArtifact { [Constructible] @@ -556,7 +557,7 @@ public partial class TowerLanternArtifact : BaseDecorationArtifact } } -[Serializable(0)] +[SerializationGenerator(0)] public partial class Urn1Artifact : BaseDecorationArtifact { [Constructible] @@ -567,7 +568,7 @@ public partial class Urn1Artifact : BaseDecorationArtifact public override int ArtifactRarity => 3; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class Urn2Artifact : BaseDecorationArtifact { [Constructible] @@ -578,7 +579,7 @@ public partial class Urn2Artifact : BaseDecorationArtifact public override int ArtifactRarity => 3; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class ZenRock1Artifact : BaseDecorationArtifact { [Constructible] @@ -589,7 +590,7 @@ public partial class ZenRock1Artifact : BaseDecorationArtifact public override int ArtifactRarity => 2; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class ZenRock2Artifact : BaseDecorationArtifact { [Constructible] @@ -600,7 +601,7 @@ public partial class ZenRock2Artifact : BaseDecorationArtifact public override int ArtifactRarity => 3; } -[Serializable(0)] +[SerializationGenerator(0)] public partial class ZenRock3Artifact : BaseDecorationArtifact { [Constructible] diff --git a/Projects/UOContent/Items/Deeds/BarkeepContract.cs b/Projects/UOContent/Items/Deeds/BarkeepContract.cs index c1fa4b22c..c3f94ee22 100644 --- a/Projects/UOContent/Items/Deeds/BarkeepContract.cs +++ b/Projects/UOContent/Items/Deeds/BarkeepContract.cs @@ -1,10 +1,11 @@ +using ModernUO.Serialization; using Server.Mobiles; using Server.Multis; using Server.Network; namespace Server.Items; -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class BarkeepContract : Item { [Constructible] diff --git a/Projects/UOContent/Items/Deeds/ClothingBlessDeed.cs b/Projects/UOContent/Items/Deeds/ClothingBlessDeed.cs index cb6186600..816a0cc0c 100644 --- a/Projects/UOContent/Items/Deeds/ClothingBlessDeed.cs +++ b/Projects/UOContent/Items/Deeds/ClothingBlessDeed.cs @@ -1,3 +1,4 @@ +using ModernUO.Serialization; using Server.Targeting; namespace Server.Items; @@ -51,7 +52,7 @@ public class ClothingBlessTarget : Target // Create our targeting class (which w } } -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class ClothingBlessDeed : Item // Create the item class which is derived from the base item class { [Constructible] diff --git a/Projects/UOContent/Items/Deeds/CommodityDeed.cs b/Projects/UOContent/Items/Deeds/CommodityDeed.cs index 3aa141533..25ddf29e3 100644 --- a/Projects/UOContent/Items/Deeds/CommodityDeed.cs +++ b/Projects/UOContent/Items/Deeds/CommodityDeed.cs @@ -1,3 +1,4 @@ +using ModernUO.Serialization; using Server.Targeting; namespace Server.Items; @@ -8,7 +9,7 @@ public interface ICommodity /* added IsDeedable prop so expansion-based deedable bool IsDeedable { get; } } -[Serializable(1, false)] +[SerializationGenerator(1, false)] public partial class CommodityDeed : Item { [SerializableField(0, setter: "private")] diff --git a/Projects/UOContent/Items/Deeds/DragonBardingDeed.cs b/Projects/UOContent/Items/Deeds/DragonBardingDeed.cs index 75840190b..0cb85790a 100644 --- a/Projects/UOContent/Items/Deeds/DragonBardingDeed.cs +++ b/Projects/UOContent/Items/Deeds/DragonBardingDeed.cs @@ -1,4 +1,5 @@ using System; +using ModernUO.Serialization; using Server.Engines.Craft; using Server.Mobiles; using Server.Targeting; @@ -6,7 +7,7 @@ using Server.Targeting; namespace Server.Items; [TypeAlias("Server.Items.DragonBarding")] -[Serializable(2, false)] +[SerializationGenerator(2, false)] public partial class DragonBardingDeed : Item, ICraftable { [InvalidateProperties] diff --git a/Projects/UOContent/Items/Deeds/HairRestylingDeed.cs b/Projects/UOContent/Items/Deeds/HairRestylingDeed.cs index e87eb7d1d..64dc56845 100644 --- a/Projects/UOContent/Items/Deeds/HairRestylingDeed.cs +++ b/Projects/UOContent/Items/Deeds/HairRestylingDeed.cs @@ -1,10 +1,11 @@ +using ModernUO.Serialization; using Server.Gumps; using Server.Mobiles; using Server.Network; namespace Server.Items; -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class HairRestylingDeed : Item { [Constructible] diff --git a/Projects/UOContent/Items/Deeds/HolidayTreeDeed.cs b/Projects/UOContent/Items/Deeds/HolidayTreeDeed.cs index da5ca4a71..47230c1b1 100644 --- a/Projects/UOContent/Items/Deeds/HolidayTreeDeed.cs +++ b/Projects/UOContent/Items/Deeds/HolidayTreeDeed.cs @@ -1,3 +1,4 @@ +using ModernUO.Serialization; using Server.Gumps; using Server.Multis; using Server.Network; @@ -5,7 +6,7 @@ using Server.Targeting; namespace Server.Items; -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class HolidayTreeDeed : Item { [Constructible] diff --git a/Projects/UOContent/Items/Deeds/NameChangeDeed.cs b/Projects/UOContent/Items/Deeds/NameChangeDeed.cs index 45fd6e080..70f9b7bcd 100644 --- a/Projects/UOContent/Items/Deeds/NameChangeDeed.cs +++ b/Projects/UOContent/Items/Deeds/NameChangeDeed.cs @@ -1,10 +1,11 @@ +using ModernUO.Serialization; using Server.Gumps; using Server.Misc; using Server.Network; namespace Server.Items; -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class NameChangeDeed : Item { [Constructible] diff --git a/Projects/UOContent/Items/Deeds/NewPlayerTicket.cs b/Projects/UOContent/Items/Deeds/NewPlayerTicket.cs index 1b75e9eaf..d19fdf762 100644 --- a/Projects/UOContent/Items/Deeds/NewPlayerTicket.cs +++ b/Projects/UOContent/Items/Deeds/NewPlayerTicket.cs @@ -1,10 +1,11 @@ +using ModernUO.Serialization; using Server.Gumps; using Server.Network; using Server.Targeting; namespace Server.Items; -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class NewPlayerTicket : Item { [SerializableField(0)] diff --git a/Projects/UOContent/Items/Resources/Blacksmithing/Ingots.cs b/Projects/UOContent/Items/Resources/Blacksmithing/Ingots.cs index 9931c0708..1d034e0cc 100644 --- a/Projects/UOContent/Items/Resources/Blacksmithing/Ingots.cs +++ b/Projects/UOContent/Items/Resources/Blacksmithing/Ingots.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(2, false)] + [SerializationGenerator(2, false)] public abstract partial class BaseIngot : Item, ICommodity { [InvalidateProperties] @@ -98,7 +100,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1BF2, 0x1BEF)] public partial class IronIngot : BaseIngot { @@ -108,7 +110,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1BF2, 0x1BEF)] public partial class DullCopperIngot : BaseIngot { @@ -118,7 +120,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1BF2, 0x1BEF)] public partial class ShadowIronIngot : BaseIngot { @@ -128,7 +130,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1BF2, 0x1BEF)] public partial class CopperIngot : BaseIngot { @@ -138,7 +140,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1BF2, 0x1BEF)] public partial class BronzeIngot : BaseIngot { @@ -148,7 +150,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1BF2, 0x1BEF)] public partial class GoldIngot : BaseIngot { @@ -158,7 +160,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1BF2, 0x1BEF)] public partial class AgapiteIngot : BaseIngot { @@ -168,7 +170,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1BF2, 0x1BEF)] public partial class VeriteIngot : BaseIngot { @@ -178,7 +180,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1BF2, 0x1BEF)] public partial class ValoriteIngot : BaseIngot { diff --git a/Projects/UOContent/Items/Resources/Blacksmithing/Ore.cs b/Projects/UOContent/Items/Resources/Blacksmithing/Ore.cs index 70d8f484e..d5f26bb55 100644 --- a/Projects/UOContent/Items/Resources/Blacksmithing/Ore.cs +++ b/Projects/UOContent/Items/Resources/Blacksmithing/Ore.cs @@ -1,10 +1,11 @@ +using ModernUO.Serialization; using Server.Engines.Craft; using Server.Mobiles; using Server.Targeting; namespace Server.Items { - [Serializable(2, false)] + [SerializationGenerator(2, false)] public abstract partial class BaseOre : Item { public BaseOre(CraftResource resource, int amount = 1) : base(RandomSize()) @@ -363,7 +364,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class IronOre : BaseOre { [Constructible] @@ -382,7 +383,7 @@ namespace Server.Items public override BaseIngot GetIngot() => new IronIngot(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class DullCopperOre : BaseOre { [Constructible] @@ -393,7 +394,7 @@ namespace Server.Items public override BaseIngot GetIngot() => new DullCopperIngot(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class ShadowIronOre : BaseOre { [Constructible] @@ -404,7 +405,7 @@ namespace Server.Items public override BaseIngot GetIngot() => new ShadowIronIngot(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class CopperOre : BaseOre { [Constructible] @@ -415,7 +416,7 @@ namespace Server.Items public override BaseIngot GetIngot() => new CopperIngot(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class BronzeOre : BaseOre { [Constructible] @@ -426,7 +427,7 @@ namespace Server.Items public override BaseIngot GetIngot() => new BronzeIngot(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class GoldOre : BaseOre { [Constructible] @@ -437,7 +438,7 @@ namespace Server.Items public override BaseIngot GetIngot() => new GoldIngot(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class AgapiteOre : BaseOre { [Constructible] @@ -448,7 +449,7 @@ namespace Server.Items public override BaseIngot GetIngot() => new AgapiteIngot(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class VeriteOre : BaseOre { [Constructible] @@ -459,7 +460,7 @@ namespace Server.Items public override BaseIngot GetIngot() => new VeriteIngot(); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class ValoriteOre : BaseOre { [Constructible] diff --git a/Projects/UOContent/Items/Resources/Fishing/BigFish.cs b/Projects/UOContent/Items/Resources/Fishing/BigFish.cs index 4d0e40ae3..7ccaef1ea 100644 --- a/Projects/UOContent/Items/Resources/Fishing/BigFish.cs +++ b/Projects/UOContent/Items/Resources/Fishing/BigFish.cs @@ -1,8 +1,9 @@ using System; +using ModernUO.Serialization; namespace Server.Items { - [Serializable(1, false)] + [SerializationGenerator(1, false)] public partial class BigFish : Item, ICarvable { [InvalidateProperties] diff --git a/Projects/UOContent/Items/Resources/Fishing/Fish.cs b/Projects/UOContent/Items/Resources/Fishing/Fish.cs index a84a1f002..0007f92b7 100644 --- a/Projects/UOContent/Items/Resources/Fishing/Fish.cs +++ b/Projects/UOContent/Items/Resources/Fishing/Fish.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Fish : Item, ICarvable { [Constructible] diff --git a/Projects/UOContent/Items/Resources/Fishing/MagicFish.cs b/Projects/UOContent/Items/Resources/Fishing/MagicFish.cs index e64f6ddc0..e89d7b6ac 100644 --- a/Projects/UOContent/Items/Resources/Fishing/MagicFish.cs +++ b/Projects/UOContent/Items/Resources/Fishing/MagicFish.cs @@ -1,10 +1,11 @@ using System; +using ModernUO.Serialization; using Server.Network; using Server.Spells; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public abstract partial class BaseMagicFish : Item { public BaseMagicFish(int hue) : base(0xDD6) => Hue = hue; @@ -42,7 +43,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class PrizedFish : BaseMagicFish { [Constructible] @@ -56,7 +57,7 @@ namespace Server.Items public override int LabelNumber => 1041073; // prized fish } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class WondrousFish : BaseMagicFish { [Constructible] @@ -70,7 +71,7 @@ namespace Server.Items public override int LabelNumber => 1041074; // wondrous fish } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class TrulyRareFish : BaseMagicFish { [Constructible] @@ -84,7 +85,7 @@ namespace Server.Items public override int LabelNumber => 1041075; // truly rare fish } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class PeculiarFish : BaseMagicFish { [Constructible] diff --git a/Projects/UOContent/Items/Resources/MiscMLResources.cs b/Projects/UOContent/Items/Resources/MiscMLResources.cs index a0c6d30b4..f72b20447 100644 --- a/Projects/UOContent/Items/Resources/MiscMLResources.cs +++ b/Projects/UOContent/Items/Resources/MiscMLResources.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Blight : Item { [Constructible] @@ -11,7 +13,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LuminescentFungi : Item { [Constructible] @@ -22,7 +24,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class CapturedEssence : Item { [Constructible] @@ -33,7 +35,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class EyeOfTheTravesty : Item { [Constructible] @@ -49,7 +51,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Corruption : Item { [Constructible] @@ -65,7 +67,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class DreadHornMane : Item { [Constructible] @@ -81,7 +83,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class ParasiticPlant : Item { [Constructible] @@ -97,7 +99,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Muculent : Item { [Constructible] @@ -113,7 +115,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class DiseasedBark : Item { [Constructible] @@ -129,7 +131,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class BarkFragment : Item { [Constructible] @@ -145,7 +147,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class GrizzledBones : Item { [Constructible] @@ -161,7 +163,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LardOfParoxysmus : Item { [Constructible] @@ -177,7 +179,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class PerfectEmerald : Item { [Constructible] @@ -193,7 +195,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class DarkSapphire : Item { [Constructible] @@ -209,7 +211,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Turquoise : Item { [Constructible] @@ -225,7 +227,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class EcruCitrine : Item { [Constructible] @@ -241,7 +243,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class WhitePearl : Item { [Constructible] @@ -257,7 +259,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class FireRuby : Item { [Constructible] @@ -273,7 +275,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class BlueDiamond : Item { [Constructible] @@ -289,7 +291,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class BrilliantAmber : Item { [Constructible] @@ -305,7 +307,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Scourge : Item { [Constructible] @@ -322,7 +324,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Putrefication : Item { [Constructible] @@ -339,7 +341,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Taint : Item { [Constructible] @@ -356,7 +358,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x315A, 0x315B)] public partial class PristineDreadHorn : Item { @@ -366,7 +368,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class SwitchItem : Item { [Constructible] diff --git a/Projects/UOContent/Items/Resources/Reagents/BaseReagent.cs b/Projects/UOContent/Items/Resources/Reagents/BaseReagent.cs index 66c5fb678..32bfdb4cc 100644 --- a/Projects/UOContent/Items/Resources/Reagents/BaseReagent.cs +++ b/Projects/UOContent/Items/Resources/Reagents/BaseReagent.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public abstract partial class BaseReagent : Item { public BaseReagent(int itemID, int amount = 1) : base(itemID) diff --git a/Projects/UOContent/Items/Resources/Reagents/BatWing.cs b/Projects/UOContent/Items/Resources/Reagents/BatWing.cs index 479c9bffb..474284936 100644 --- a/Projects/UOContent/Items/Resources/Reagents/BatWing.cs +++ b/Projects/UOContent/Items/Resources/Reagents/BatWing.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class BatWing : BaseReagent, ICommodity { [Constructible] diff --git a/Projects/UOContent/Items/Resources/Reagents/BlackPearl.cs b/Projects/UOContent/Items/Resources/Reagents/BlackPearl.cs index 7720c2cee..d2d32f419 100644 --- a/Projects/UOContent/Items/Resources/Reagents/BlackPearl.cs +++ b/Projects/UOContent/Items/Resources/Reagents/BlackPearl.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class BlackPearl : BaseReagent, ICommodity { [Constructible] diff --git a/Projects/UOContent/Items/Resources/Reagents/Bloodmoss.cs b/Projects/UOContent/Items/Resources/Reagents/Bloodmoss.cs index e3405f42b..70559a3b3 100644 --- a/Projects/UOContent/Items/Resources/Reagents/Bloodmoss.cs +++ b/Projects/UOContent/Items/Resources/Reagents/Bloodmoss.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Bloodmoss : BaseReagent, ICommodity { [Constructible] diff --git a/Projects/UOContent/Items/Resources/Reagents/DaemonBlood.cs b/Projects/UOContent/Items/Resources/Reagents/DaemonBlood.cs index 6d49f0b42..10350ebed 100644 --- a/Projects/UOContent/Items/Resources/Reagents/DaemonBlood.cs +++ b/Projects/UOContent/Items/Resources/Reagents/DaemonBlood.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class DaemonBlood : BaseReagent, ICommodity { [Constructible] diff --git a/Projects/UOContent/Items/Resources/Reagents/DaemonBone.cs b/Projects/UOContent/Items/Resources/Reagents/DaemonBone.cs index 8c9cc9ce6..6c8b9a818 100644 --- a/Projects/UOContent/Items/Resources/Reagents/DaemonBone.cs +++ b/Projects/UOContent/Items/Resources/Reagents/DaemonBone.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class DaemonBone : BaseReagent, ICommodity { [Constructible] diff --git a/Projects/UOContent/Items/Resources/Reagents/DeadWood.cs b/Projects/UOContent/Items/Resources/Reagents/DeadWood.cs index 92036861d..39e9e6459 100644 --- a/Projects/UOContent/Items/Resources/Reagents/DeadWood.cs +++ b/Projects/UOContent/Items/Resources/Reagents/DeadWood.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class DeadWood : BaseReagent, ICommodity { [Constructible] diff --git a/Projects/UOContent/Items/Resources/Reagents/DragonsBlood.cs b/Projects/UOContent/Items/Resources/Reagents/DragonsBlood.cs index 4d07593b0..0e695ab43 100644 --- a/Projects/UOContent/Items/Resources/Reagents/DragonsBlood.cs +++ b/Projects/UOContent/Items/Resources/Reagents/DragonsBlood.cs @@ -1,6 +1,8 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class DragonsBlood : BaseReagent, ICommodity { [Constructible] diff --git a/Projects/UOContent/Items/Resources/Reagents/Garlic.cs b/Projects/UOContent/Items/Resources/Reagents/Garlic.cs index 35873ab76..fb616980b 100644 --- a/Projects/UOContent/Items/Resources/Reagents/Garlic.cs +++ b/Projects/UOContent/Items/Resources/Reagents/Garlic.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Garlic : BaseReagent, ICommodity { [Constructible] diff --git a/Projects/UOContent/Items/Resources/Reagents/Ginseng.cs b/Projects/UOContent/Items/Resources/Reagents/Ginseng.cs index 7fce79ee5..60df8c379 100644 --- a/Projects/UOContent/Items/Resources/Reagents/Ginseng.cs +++ b/Projects/UOContent/Items/Resources/Reagents/Ginseng.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Ginseng : BaseReagent, ICommodity { [Constructible] diff --git a/Projects/UOContent/Items/Resources/Reagents/GraveDust.cs b/Projects/UOContent/Items/Resources/Reagents/GraveDust.cs index 81a6c4872..f87cf5bf0 100644 --- a/Projects/UOContent/Items/Resources/Reagents/GraveDust.cs +++ b/Projects/UOContent/Items/Resources/Reagents/GraveDust.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class GraveDust : BaseReagent, ICommodity { [Constructible] diff --git a/Projects/UOContent/Items/Resources/Reagents/MandrakeRoot.cs b/Projects/UOContent/Items/Resources/Reagents/MandrakeRoot.cs index 4ad411c42..8493e2991 100644 --- a/Projects/UOContent/Items/Resources/Reagents/MandrakeRoot.cs +++ b/Projects/UOContent/Items/Resources/Reagents/MandrakeRoot.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class MandrakeRoot : BaseReagent, ICommodity { [Constructible] diff --git a/Projects/UOContent/Items/Resources/Reagents/Nightshade.cs b/Projects/UOContent/Items/Resources/Reagents/Nightshade.cs index e5e5c8a28..d39535bb8 100644 --- a/Projects/UOContent/Items/Resources/Reagents/Nightshade.cs +++ b/Projects/UOContent/Items/Resources/Reagents/Nightshade.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Nightshade : BaseReagent, ICommodity { [Constructible] diff --git a/Projects/UOContent/Items/Resources/Reagents/NoxCrystal.cs b/Projects/UOContent/Items/Resources/Reagents/NoxCrystal.cs index 8cd02c9e9..6380167b0 100644 --- a/Projects/UOContent/Items/Resources/Reagents/NoxCrystal.cs +++ b/Projects/UOContent/Items/Resources/Reagents/NoxCrystal.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class NoxCrystal : BaseReagent, ICommodity { [Constructible] diff --git a/Projects/UOContent/Items/Resources/Reagents/PigIron.cs b/Projects/UOContent/Items/Resources/Reagents/PigIron.cs index 46d818737..3b8f81711 100644 --- a/Projects/UOContent/Items/Resources/Reagents/PigIron.cs +++ b/Projects/UOContent/Items/Resources/Reagents/PigIron.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class PigIron : BaseReagent, ICommodity { [Constructible] diff --git a/Projects/UOContent/Items/Resources/Reagents/SpidersSilk.cs b/Projects/UOContent/Items/Resources/Reagents/SpidersSilk.cs index d4b7754d2..9f97f37ea 100644 --- a/Projects/UOContent/Items/Resources/Reagents/SpidersSilk.cs +++ b/Projects/UOContent/Items/Resources/Reagents/SpidersSilk.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class SpidersSilk : BaseReagent, ICommodity { [Constructible] diff --git a/Projects/UOContent/Items/Resources/Reagents/SulfurousAsh.cs b/Projects/UOContent/Items/Resources/Reagents/SulfurousAsh.cs index 34b178ebd..40de7e27c 100644 --- a/Projects/UOContent/Items/Resources/Reagents/SulfurousAsh.cs +++ b/Projects/UOContent/Items/Resources/Reagents/SulfurousAsh.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class SulfurousAsh : BaseReagent, ICommodity { [Constructible] diff --git a/Projects/UOContent/Items/Resources/Tailor/BoltOfCloth.cs b/Projects/UOContent/Items/Resources/Tailor/BoltOfCloth.cs index 857a8c7a0..e87b0f521 100644 --- a/Projects/UOContent/Items/Resources/Tailor/BoltOfCloth.cs +++ b/Projects/UOContent/Items/Resources/Tailor/BoltOfCloth.cs @@ -1,8 +1,9 @@ +using ModernUO.Serialization; using Server.Network; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0xF95, 0xF96, 0xF97, 0xF98, 0xF99, 0xF9A, 0xF9B, 0xF9C)] public partial class BoltOfCloth : Item, IScissorable, IDyable, ICommodity { diff --git a/Projects/UOContent/Items/Resources/Tailor/Bone.cs b/Projects/UOContent/Items/Resources/Tailor/Bone.cs index 374aa0d66..5b27f8cbe 100644 --- a/Projects/UOContent/Items/Resources/Tailor/Bone.cs +++ b/Projects/UOContent/Items/Resources/Tailor/Bone.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Bone : Item, ICommodity { [Constructible] diff --git a/Projects/UOContent/Items/Resources/Tailor/Cloth.cs b/Projects/UOContent/Items/Resources/Tailor/Cloth.cs index d66970c29..b8f49714d 100644 --- a/Projects/UOContent/Items/Resources/Tailor/Cloth.cs +++ b/Projects/UOContent/Items/Resources/Tailor/Cloth.cs @@ -1,8 +1,9 @@ +using ModernUO.Serialization; using Server.Network; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1766, 0x1768)] public partial class Cloth : Item, IScissorable, IDyable, ICommodity { diff --git a/Projects/UOContent/Items/Resources/Tailor/Cotton.cs b/Projects/UOContent/Items/Resources/Tailor/Cotton.cs index 886f1f3e3..61d6c64fc 100644 --- a/Projects/UOContent/Items/Resources/Tailor/Cotton.cs +++ b/Projects/UOContent/Items/Resources/Tailor/Cotton.cs @@ -1,8 +1,9 @@ +using ModernUO.Serialization; using Server.Targeting; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Cotton : Item, IDyable { [Constructible] diff --git a/Projects/UOContent/Items/Resources/Tailor/Flax.cs b/Projects/UOContent/Items/Resources/Tailor/Flax.cs index a0e265caf..ec40e4ee6 100644 --- a/Projects/UOContent/Items/Resources/Tailor/Flax.cs +++ b/Projects/UOContent/Items/Resources/Tailor/Flax.cs @@ -1,8 +1,9 @@ +using ModernUO.Serialization; using Server.Targeting; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Flax : Item { [Constructible] diff --git a/Projects/UOContent/Items/Resources/Tailor/Hides.cs b/Projects/UOContent/Items/Resources/Tailor/Hides.cs index e2b32e2f7..39acdc6c7 100644 --- a/Projects/UOContent/Items/Resources/Tailor/Hides.cs +++ b/Projects/UOContent/Items/Resources/Tailor/Hides.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(2, false)] + [SerializationGenerator(2, false)] public abstract partial class BaseHides : Item, ICommodity { [InvalidateProperties] @@ -85,7 +87,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1079, 0x1078)] public partial class Hides : BaseHides, IScissorable { @@ -113,7 +115,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1079, 0x1078)] public partial class SpinedHides : BaseHides, IScissorable { @@ -141,7 +143,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1079, 0x1078)] public partial class HornedHides : BaseHides, IScissorable { @@ -169,7 +171,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1079, 0x1078)] public partial class BarbedHides : BaseHides, IScissorable { diff --git a/Projects/UOContent/Items/Resources/Tailor/Leathers.cs b/Projects/UOContent/Items/Resources/Tailor/Leathers.cs index 2b616b4bb..3ed3f4a7c 100644 --- a/Projects/UOContent/Items/Resources/Tailor/Leathers.cs +++ b/Projects/UOContent/Items/Resources/Tailor/Leathers.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(2, false)] + [SerializationGenerator(2, false)] public abstract partial class BaseLeather : Item, ICommodity { [InvalidateProperties] @@ -85,7 +87,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1081, 0x1082)] public partial class Leather : BaseLeather { @@ -95,7 +97,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1081, 0x1082)] public partial class SpinedLeather : BaseLeather { @@ -105,7 +107,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1081, 0x1082)] public partial class HornedLeather : BaseLeather { @@ -115,7 +117,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1081, 0x1082)] public partial class BarbedLeather : BaseLeather { diff --git a/Projects/UOContent/Items/Resources/Tailor/UncutCloth.cs b/Projects/UOContent/Items/Resources/Tailor/UncutCloth.cs index 3daf072b0..05ed011f7 100644 --- a/Projects/UOContent/Items/Resources/Tailor/UncutCloth.cs +++ b/Projects/UOContent/Items/Resources/Tailor/UncutCloth.cs @@ -1,8 +1,9 @@ +using ModernUO.Serialization; using Server.Network; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1765, 0x1767)] public partial class UncutCloth : Item, IScissorable, IDyable, ICommodity { diff --git a/Projects/UOContent/Items/Resources/Tailor/Wool.cs b/Projects/UOContent/Items/Resources/Tailor/Wool.cs index 53437fd37..578de9600 100644 --- a/Projects/UOContent/Items/Resources/Tailor/Wool.cs +++ b/Projects/UOContent/Items/Resources/Tailor/Wool.cs @@ -1,8 +1,9 @@ +using ModernUO.Serialization; using Server.Targeting; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Wool : Item, IDyable { [Constructible] @@ -91,7 +92,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class TaintedWool : Wool { [Constructible] diff --git a/Projects/UOContent/Items/Resources/Tailor/YarnsAndThreads.cs b/Projects/UOContent/Items/Resources/Tailor/YarnsAndThreads.cs index a644f9f3b..f5fef0825 100644 --- a/Projects/UOContent/Items/Resources/Tailor/YarnsAndThreads.cs +++ b/Projects/UOContent/Items/Resources/Tailor/YarnsAndThreads.cs @@ -1,8 +1,9 @@ +using ModernUO.Serialization; using Server.Targeting; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public abstract partial class BaseClothMaterial : Item, IDyable { public BaseClothMaterial(int itemID, int amount = 1) : base(itemID) @@ -91,7 +92,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class DarkYarn : BaseClothMaterial { [Constructible] @@ -100,7 +101,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LightYarn : BaseClothMaterial { [Constructible] @@ -109,7 +110,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LightYarnUnraveled : BaseClothMaterial { [Constructible] @@ -118,7 +119,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class SpoolOfThread : BaseClothMaterial { [Constructible] diff --git a/Projects/UOContent/Items/Shields/GargishWoodenShield.cs b/Projects/UOContent/Items/Shields/GargishWoodenShield.cs index a64473eb5..e332c7cb1 100644 --- a/Projects/UOContent/Items/Shields/GargishWoodenShield.cs +++ b/Projects/UOContent/Items/Shields/GargishWoodenShield.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x4200, 0x4207)] - [Serializable(0)] + [SerializationGenerator(0)] public partial class GargishWoodenShield : BaseShield { [Constructible] diff --git a/Projects/UOContent/Items/Skill Items/Lumberjack/Log.cs b/Projects/UOContent/Items/Skill Items/Lumberjack/Log.cs index f3b692cb9..19db4c169 100644 --- a/Projects/UOContent/Items/Skill Items/Lumberjack/Log.cs +++ b/Projects/UOContent/Items/Skill Items/Lumberjack/Log.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(2, false)] + [SerializationGenerator(2, false)] [Flippable(0x1bdd, 0x1be0)] public partial class Log : Item, ICommodity, IAxe { @@ -86,7 +88,7 @@ namespace Server.Items } } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class HeartwoodLog : Log { [Constructible] @@ -97,7 +99,7 @@ namespace Server.Items public override bool Axe(Mobile from, BaseAxe axe) => TryCreateBoards(from, 100, new HeartwoodBoard()); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class BloodwoodLog : Log { [Constructible] @@ -108,7 +110,7 @@ namespace Server.Items public override bool Axe(Mobile from, BaseAxe axe) => TryCreateBoards(from, 100, new BloodwoodBoard()); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class FrostwoodLog : Log { [Constructible] @@ -119,7 +121,7 @@ namespace Server.Items public override bool Axe(Mobile from, BaseAxe axe) => TryCreateBoards(from, 100, new FrostwoodBoard()); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class OakLog : Log { [Constructible] @@ -130,7 +132,7 @@ namespace Server.Items public override bool Axe(Mobile from, BaseAxe axe) => TryCreateBoards(from, 65, new OakBoard()); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class AshLog : Log { [Constructible] @@ -141,7 +143,7 @@ namespace Server.Items public override bool Axe(Mobile from, BaseAxe axe) => TryCreateBoards(from, 80, new AshBoard()); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class YewLog : Log { [Constructible] diff --git a/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/BlackDyeTub.cs b/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/BlackDyeTub.cs index da621fd74..d4e1e769e 100644 --- a/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/BlackDyeTub.cs +++ b/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/BlackDyeTub.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class BlackDyeTub : DyeTub { [Constructible] diff --git a/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/BlazeDyeTub.cs b/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/BlazeDyeTub.cs index e59f8115c..04a733169 100644 --- a/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/BlazeDyeTub.cs +++ b/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/BlazeDyeTub.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class BlazeDyeTub : DyeTub { [Constructible] diff --git a/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/DyeTub.cs b/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/DyeTub.cs index be13e0150..2cf95b183 100644 --- a/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/DyeTub.cs +++ b/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/DyeTub.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using ModernUO.Serialization; using Server.ContextMenus; using Server.Gumps; using Server.Multis; @@ -11,7 +12,7 @@ namespace Server.Items bool Dye(Mobile from, DyeTub sender); } - [Serializable(2, false)] + [SerializationGenerator(2, false)] public partial class DyeTub : Item, ISecurable { [SerializableField(0)] diff --git a/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/FurnitureDyeTub.cs b/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/FurnitureDyeTub.cs index 4bab7dab3..615661514 100644 --- a/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/FurnitureDyeTub.cs +++ b/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/FurnitureDyeTub.cs @@ -1,8 +1,9 @@ +using ModernUO.Serialization; using Server.Engines.VeteranRewards; namespace Server.Items { - [Serializable(1, false)] + [SerializationGenerator(1, false)] public partial class FurnitureDyeTub : DyeTub, IRewardItem { [SerializableField(0)] diff --git a/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/LeatherDyeTub.cs b/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/LeatherDyeTub.cs index a33ceb428..85c65be00 100644 --- a/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/LeatherDyeTub.cs +++ b/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/LeatherDyeTub.cs @@ -1,8 +1,9 @@ +using ModernUO.Serialization; using Server.Engines.VeteranRewards; namespace Server.Items { - [Serializable(1, false)] + [SerializationGenerator(1, false)] public partial class LeatherDyeTub : DyeTub, IRewardItem { [SerializableField(0)] diff --git a/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/MetallicClothDyetub.cs b/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/MetallicClothDyetub.cs index fb1b9d20a..c917fbeb8 100644 --- a/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/MetallicClothDyetub.cs +++ b/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/MetallicClothDyetub.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class MetallicClothDyetub : DyeTub { [Constructible] diff --git a/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/MetallicLeatherDyeTub.cs b/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/MetallicLeatherDyeTub.cs index 7b11c8fbb..28c81f2ae 100644 --- a/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/MetallicLeatherDyeTub.cs +++ b/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/MetallicLeatherDyeTub.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class MetallicLeatherDyeTub : LeatherDyeTub { [Constructible] diff --git a/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/RewardBlackDyeTub.cs b/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/RewardBlackDyeTub.cs index d04d01ea9..a0f75f358 100644 --- a/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/RewardBlackDyeTub.cs +++ b/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/RewardBlackDyeTub.cs @@ -1,8 +1,9 @@ +using ModernUO.Serialization; using Server.Engines.VeteranRewards; namespace Server.Items { - [Serializable(1, false)] + [SerializationGenerator(1, false)] public partial class RewardBlackDyeTub : DyeTub, IRewardItem { [SerializableField(0)] diff --git a/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/RunebookDyeTub.cs b/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/RunebookDyeTub.cs index 7f04fe35a..7adee4071 100644 --- a/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/RunebookDyeTub.cs +++ b/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/RunebookDyeTub.cs @@ -1,8 +1,9 @@ +using ModernUO.Serialization; using Server.Engines.VeteranRewards; namespace Server.Items { - [Serializable(1, false)] + [SerializationGenerator(1, false)] public partial class RunebookDyeTub : DyeTub, IRewardItem { [SerializableField(0)] diff --git a/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/SpecialDyeTub.cs b/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/SpecialDyeTub.cs index da2ca3921..ec30f803d 100644 --- a/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/SpecialDyeTub.cs +++ b/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/SpecialDyeTub.cs @@ -1,8 +1,9 @@ +using ModernUO.Serialization; using Server.Engines.VeteranRewards; namespace Server.Items { - [Serializable(1, false)] + [SerializationGenerator(1, false)] public partial class SpecialDyeTub : DyeTub, IRewardItem { [SerializableField(0)] diff --git a/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/StatuetteDyeTub.cs b/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/StatuetteDyeTub.cs index 4d5d53e05..a988c8d0a 100644 --- a/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/StatuetteDyeTub.cs +++ b/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/StatuetteDyeTub.cs @@ -1,8 +1,9 @@ +using ModernUO.Serialization; using Server.Engines.VeteranRewards; namespace Server.Items { - [Serializable(1, false)] + [SerializationGenerator(1, false)] public partial class StatuetteDyeTub : DyeTub, IRewardItem { [SerializableField(0)] diff --git a/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/WhiteClothDyeTub.cs b/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/WhiteClothDyeTub.cs index 6ea785a37..33583c7c5 100644 --- a/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/WhiteClothDyeTub.cs +++ b/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/WhiteClothDyeTub.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items /* High seas, loot from merchant ship's hold, also a "uncommon" loot item */ { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class WhiteClothDyeTub : DyeTub { [Constructible] diff --git a/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/WhiteLeatherDyeTub.cs b/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/WhiteLeatherDyeTub.cs index 504c680a1..d0f2974db 100644 --- a/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/WhiteLeatherDyeTub.cs +++ b/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/WhiteLeatherDyeTub.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class WhiteLeatherDyeTub : LeatherDyeTub /* OSI UO 13th anniv gift, from redeemable gift tickets */ { [Constructible] diff --git a/Projects/UOContent/Items/Skill Items/Tools/TinkerTools.cs b/Projects/UOContent/Items/Skill Items/Tools/TinkerTools.cs index 872bc099a..cf5503a50 100644 --- a/Projects/UOContent/Items/Skill Items/Tools/TinkerTools.cs +++ b/Projects/UOContent/Items/Skill Items/Tools/TinkerTools.cs @@ -1,9 +1,10 @@ +using ModernUO.Serialization; using Server.Engines.Craft; namespace Server.Items { [Flippable(0x1EB8, 0x1EB9)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class TinkerTools : BaseTool { [Constructible] @@ -15,7 +16,7 @@ namespace Server.Items public override CraftSystem CraftSystem => DefTinkering.CraftSystem; } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class TinkersTools : BaseTool { [Constructible] diff --git a/Projects/UOContent/Items/Special/SoulStone.cs b/Projects/UOContent/Items/Special/SoulStone.cs index a951f169f..15ffc2862 100644 --- a/Projects/UOContent/Items/Special/SoulStone.cs +++ b/Projects/UOContent/Items/Special/SoulStone.cs @@ -1,5 +1,4 @@ using System; -using Server.Accounting; using Server.Engines.VeteranRewards; using Server.Factions; using Server.Gumps; diff --git a/Projects/UOContent/Items/TreasureChests/TreasureChestLevel1.cs b/Projects/UOContent/Items/TreasureChests/TreasureChestLevel1.cs index 28dacc9a7..61dfd853d 100644 --- a/Projects/UOContent/Items/TreasureChests/TreasureChestLevel1.cs +++ b/Projects/UOContent/Items/TreasureChests/TreasureChestLevel1.cs @@ -1,8 +1,9 @@ using System; +using ModernUO.Serialization; namespace Server.Items; -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class TreasureChestLevel1 : LockableContainer { [Constructible] diff --git a/Projects/UOContent/Items/TreasureChests/TreasureChestLevel2.cs b/Projects/UOContent/Items/TreasureChests/TreasureChestLevel2.cs index 74b78fe39..bc3fe877c 100644 --- a/Projects/UOContent/Items/TreasureChests/TreasureChestLevel2.cs +++ b/Projects/UOContent/Items/TreasureChests/TreasureChestLevel2.cs @@ -1,8 +1,9 @@ using System; +using ModernUO.Serialization; namespace Server.Items; -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class TreasureChestLevel2 : LockableContainer { [Constructible] diff --git a/Projects/UOContent/Items/TreasureChests/TreasureChestLevel3.cs b/Projects/UOContent/Items/TreasureChests/TreasureChestLevel3.cs index fe227b27a..9ec26c7bb 100644 --- a/Projects/UOContent/Items/TreasureChests/TreasureChestLevel3.cs +++ b/Projects/UOContent/Items/TreasureChests/TreasureChestLevel3.cs @@ -1,8 +1,9 @@ using System; +using ModernUO.Serialization; namespace Server.Items; -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class TreasureChestLevel3 : LockableContainer { [Constructible] diff --git a/Projects/UOContent/Items/TreasureChests/TreasureChestLevel4.cs b/Projects/UOContent/Items/TreasureChests/TreasureChestLevel4.cs index bc4afcc72..a4bbd17bc 100644 --- a/Projects/UOContent/Items/TreasureChests/TreasureChestLevel4.cs +++ b/Projects/UOContent/Items/TreasureChests/TreasureChestLevel4.cs @@ -1,8 +1,9 @@ using System; +using ModernUO.Serialization; namespace Server.Items; -[Serializable(0, false)] +[SerializationGenerator(0, false)] public partial class TreasureChestLevel4 : LockableContainer { [Constructible] diff --git a/Projects/UOContent/Items/Wands/BaseWand.cs b/Projects/UOContent/Items/Wands/BaseWand.cs index 310ffe526..7d404413f 100644 --- a/Projects/UOContent/Items/Wands/BaseWand.cs +++ b/Projects/UOContent/Items/Wands/BaseWand.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using ModernUO.Serialization; using Server.Network; using Server.Spells; using Server.Targeting; @@ -21,7 +22,7 @@ namespace Server.Items ManaDraining } - [Serializable(1, false)] + [SerializationGenerator(1, false)] public abstract partial class BaseWand : BaseBashing { [InvalidateProperties] diff --git a/Projects/UOContent/Items/Wands/ClumsyWand.cs b/Projects/UOContent/Items/Wands/ClumsyWand.cs index 2cb94a7af..cbe1653de 100644 --- a/Projects/UOContent/Items/Wands/ClumsyWand.cs +++ b/Projects/UOContent/Items/Wands/ClumsyWand.cs @@ -1,8 +1,9 @@ +using ModernUO.Serialization; using Server.Spells.First; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class ClumsyWand : BaseWand { [Constructible] diff --git a/Projects/UOContent/Items/Wands/FeebleWand.cs b/Projects/UOContent/Items/Wands/FeebleWand.cs index 1fa71810f..93965c518 100644 --- a/Projects/UOContent/Items/Wands/FeebleWand.cs +++ b/Projects/UOContent/Items/Wands/FeebleWand.cs @@ -1,8 +1,9 @@ +using ModernUO.Serialization; using Server.Spells.First; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class FeebleWand : BaseWand { [Constructible] diff --git a/Projects/UOContent/Items/Wands/FireballWand.cs b/Projects/UOContent/Items/Wands/FireballWand.cs index 2c80cc160..1024112b8 100644 --- a/Projects/UOContent/Items/Wands/FireballWand.cs +++ b/Projects/UOContent/Items/Wands/FireballWand.cs @@ -1,8 +1,9 @@ +using ModernUO.Serialization; using Server.Spells.Third; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class FireballWand : BaseWand { [Constructible] diff --git a/Projects/UOContent/Items/Wands/GreaterHealWand.cs b/Projects/UOContent/Items/Wands/GreaterHealWand.cs index 2e9ee8291..9624de117 100644 --- a/Projects/UOContent/Items/Wands/GreaterHealWand.cs +++ b/Projects/UOContent/Items/Wands/GreaterHealWand.cs @@ -1,8 +1,9 @@ +using ModernUO.Serialization; using Server.Spells.Fourth; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class GreaterHealWand : BaseWand { [Constructible] diff --git a/Projects/UOContent/Items/Wands/HarmWand.cs b/Projects/UOContent/Items/Wands/HarmWand.cs index 853957195..e727fcb31 100644 --- a/Projects/UOContent/Items/Wands/HarmWand.cs +++ b/Projects/UOContent/Items/Wands/HarmWand.cs @@ -1,8 +1,9 @@ +using ModernUO.Serialization; using Server.Spells.Second; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class HarmWand : BaseWand { [Constructible] diff --git a/Projects/UOContent/Items/Wands/HealWand.cs b/Projects/UOContent/Items/Wands/HealWand.cs index ad40234fa..7319b10fe 100644 --- a/Projects/UOContent/Items/Wands/HealWand.cs +++ b/Projects/UOContent/Items/Wands/HealWand.cs @@ -1,8 +1,9 @@ +using ModernUO.Serialization; using Server.Spells.First; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class HealWand : BaseWand { [Constructible] diff --git a/Projects/UOContent/Items/Wands/IDWand.cs b/Projects/UOContent/Items/Wands/IDWand.cs index 1c6328ff6..1e916f4a7 100644 --- a/Projects/UOContent/Items/Wands/IDWand.cs +++ b/Projects/UOContent/Items/Wands/IDWand.cs @@ -1,8 +1,9 @@ using System; +using ModernUO.Serialization; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class IDWand : BaseWand { [Constructible] diff --git a/Projects/UOContent/Items/Wands/LightningWand.cs b/Projects/UOContent/Items/Wands/LightningWand.cs index caf69aee5..9c02f2288 100644 --- a/Projects/UOContent/Items/Wands/LightningWand.cs +++ b/Projects/UOContent/Items/Wands/LightningWand.cs @@ -1,8 +1,9 @@ +using ModernUO.Serialization; using Server.Spells.Fourth; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LightningWand : BaseWand { [Constructible] diff --git a/Projects/UOContent/Items/Wands/MagicArrowWand.cs b/Projects/UOContent/Items/Wands/MagicArrowWand.cs index 036602ae2..1e9eb79c0 100644 --- a/Projects/UOContent/Items/Wands/MagicArrowWand.cs +++ b/Projects/UOContent/Items/Wands/MagicArrowWand.cs @@ -1,8 +1,9 @@ +using ModernUO.Serialization; using Server.Spells.First; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class MagicArrowWand : BaseWand { [Constructible] diff --git a/Projects/UOContent/Items/Wands/ManaDrainWand.cs b/Projects/UOContent/Items/Wands/ManaDrainWand.cs index 61b49bcb9..7e3c78885 100644 --- a/Projects/UOContent/Items/Wands/ManaDrainWand.cs +++ b/Projects/UOContent/Items/Wands/ManaDrainWand.cs @@ -1,8 +1,9 @@ +using ModernUO.Serialization; using Server.Spells.Fourth; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class ManaDrainWand : BaseWand { [Constructible] diff --git a/Projects/UOContent/Items/Wands/WeaknessWand.cs b/Projects/UOContent/Items/Wands/WeaknessWand.cs index 5361d0bcb..ff0fdeb5f 100644 --- a/Projects/UOContent/Items/Wands/WeaknessWand.cs +++ b/Projects/UOContent/Items/Wands/WeaknessWand.cs @@ -1,8 +1,9 @@ +using ModernUO.Serialization; using Server.Spells.First; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class WeaknessWand : BaseWand { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Artifacts/AxeOfTheHeavens.cs b/Projects/UOContent/Items/Weapons/Artifacts/AxeOfTheHeavens.cs index a4137f17d..09193ba45 100644 --- a/Projects/UOContent/Items/Weapons/Artifacts/AxeOfTheHeavens.cs +++ b/Projects/UOContent/Items/Weapons/Artifacts/AxeOfTheHeavens.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class AxeOfTheHeavens : DoubleAxe { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Artifacts/BladeOfInsanity.cs b/Projects/UOContent/Items/Weapons/Artifacts/BladeOfInsanity.cs index ed6b2b14e..4652aff5a 100644 --- a/Projects/UOContent/Items/Weapons/Artifacts/BladeOfInsanity.cs +++ b/Projects/UOContent/Items/Weapons/Artifacts/BladeOfInsanity.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class BladeOfInsanity : Katana { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Artifacts/BladeOfTheRighteous.cs b/Projects/UOContent/Items/Weapons/Artifacts/BladeOfTheRighteous.cs index 61f5ad7c7..f89bddd43 100644 --- a/Projects/UOContent/Items/Weapons/Artifacts/BladeOfTheRighteous.cs +++ b/Projects/UOContent/Items/Weapons/Artifacts/BladeOfTheRighteous.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class BladeOfTheRighteous : Longsword { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Artifacts/BoneCrusher.cs b/Projects/UOContent/Items/Weapons/Artifacts/BoneCrusher.cs index b2d5a640d..e682d7428 100644 --- a/Projects/UOContent/Items/Weapons/Artifacts/BoneCrusher.cs +++ b/Projects/UOContent/Items/Weapons/Artifacts/BoneCrusher.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class BoneCrusher : WarMace { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Artifacts/BreathOfTheDead.cs b/Projects/UOContent/Items/Weapons/Artifacts/BreathOfTheDead.cs index ab9f8d808..b0242f8f7 100644 --- a/Projects/UOContent/Items/Weapons/Artifacts/BreathOfTheDead.cs +++ b/Projects/UOContent/Items/Weapons/Artifacts/BreathOfTheDead.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class BreathOfTheDead : BoneHarvester { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Artifacts/Frostbringer.cs b/Projects/UOContent/Items/Weapons/Artifacts/Frostbringer.cs index 7ef940a63..f974b7a72 100644 --- a/Projects/UOContent/Items/Weapons/Artifacts/Frostbringer.cs +++ b/Projects/UOContent/Items/Weapons/Artifacts/Frostbringer.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Frostbringer : Bow { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Artifacts/LegacyOfTheDreadLord.cs b/Projects/UOContent/Items/Weapons/Artifacts/LegacyOfTheDreadLord.cs index f8512843d..8c6bebbab 100644 --- a/Projects/UOContent/Items/Weapons/Artifacts/LegacyOfTheDreadLord.cs +++ b/Projects/UOContent/Items/Weapons/Artifacts/LegacyOfTheDreadLord.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class LegacyOfTheDreadLord : Bardiche { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Artifacts/SerpentsFang.cs b/Projects/UOContent/Items/Weapons/Artifacts/SerpentsFang.cs index 516cc4bc0..8d7603efc 100644 --- a/Projects/UOContent/Items/Weapons/Artifacts/SerpentsFang.cs +++ b/Projects/UOContent/Items/Weapons/Artifacts/SerpentsFang.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class SerpentsFang : Kryss { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Artifacts/StaffOfTheMagi.cs b/Projects/UOContent/Items/Weapons/Artifacts/StaffOfTheMagi.cs index f4c993a95..35aa73085 100644 --- a/Projects/UOContent/Items/Weapons/Artifacts/StaffOfTheMagi.cs +++ b/Projects/UOContent/Items/Weapons/Artifacts/StaffOfTheMagi.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class StaffOfTheMagi : BlackStaff { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Artifacts/TheBeserkersMaul.cs b/Projects/UOContent/Items/Weapons/Artifacts/TheBeserkersMaul.cs index 76a166e97..10d86f619 100644 --- a/Projects/UOContent/Items/Weapons/Artifacts/TheBeserkersMaul.cs +++ b/Projects/UOContent/Items/Weapons/Artifacts/TheBeserkersMaul.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class TheBeserkersMaul : Maul { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Artifacts/TheDragonSlayer.cs b/Projects/UOContent/Items/Weapons/Artifacts/TheDragonSlayer.cs index cbdb46dc4..54c9c71a7 100644 --- a/Projects/UOContent/Items/Weapons/Artifacts/TheDragonSlayer.cs +++ b/Projects/UOContent/Items/Weapons/Artifacts/TheDragonSlayer.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class TheDragonSlayer : Lance { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Artifacts/TheDryadBow.cs b/Projects/UOContent/Items/Weapons/Artifacts/TheDryadBow.cs index f0cb1edf7..35f4a1282 100644 --- a/Projects/UOContent/Items/Weapons/Artifacts/TheDryadBow.cs +++ b/Projects/UOContent/Items/Weapons/Artifacts/TheDryadBow.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class TheDryadBow : Bow { private static readonly SkillName[] m_PossibleBonusSkills = diff --git a/Projects/UOContent/Items/Weapons/Artifacts/TheTaskmaster.cs b/Projects/UOContent/Items/Weapons/Artifacts/TheTaskmaster.cs index 7d4444026..36cb33b63 100644 --- a/Projects/UOContent/Items/Weapons/Artifacts/TheTaskmaster.cs +++ b/Projects/UOContent/Items/Weapons/Artifacts/TheTaskmaster.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class TheTaskmaster : WarFork { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Artifacts/TitansHammer.cs b/Projects/UOContent/Items/Weapons/Artifacts/TitansHammer.cs index 90c9ddda1..f2f717e79 100644 --- a/Projects/UOContent/Items/Weapons/Artifacts/TitansHammer.cs +++ b/Projects/UOContent/Items/Weapons/Artifacts/TitansHammer.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class TitansHammer : WarHammer { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Artifacts/ZyronicClaw.cs b/Projects/UOContent/Items/Weapons/Artifacts/ZyronicClaw.cs index ffb46240b..eddc87e3d 100644 --- a/Projects/UOContent/Items/Weapons/Artifacts/ZyronicClaw.cs +++ b/Projects/UOContent/Items/Weapons/Artifacts/ZyronicClaw.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class ZyronicClaw : ExecutionersAxe { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Axes/Axe.cs b/Projects/UOContent/Items/Weapons/Axes/Axe.cs index f333739ee..71f47b3b5 100644 --- a/Projects/UOContent/Items/Weapons/Axes/Axe.cs +++ b/Projects/UOContent/Items/Weapons/Axes/Axe.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0xF49, 0xF4a)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Axe : BaseAxe { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Axes/BaseAxe.cs b/Projects/UOContent/Items/Weapons/Axes/BaseAxe.cs index 05087567e..1051e22c7 100644 --- a/Projects/UOContent/Items/Weapons/Axes/BaseAxe.cs +++ b/Projects/UOContent/Items/Weapons/Axes/BaseAxe.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using ModernUO.Serialization; using Server.ContextMenus; using Server.Engines.ConPVP; using Server.Engines.Harvest; @@ -12,7 +13,7 @@ namespace Server.Items bool Axe(Mobile from, BaseAxe axe); } - [Serializable(0, false)] + [SerializationGenerator(0, false)] public abstract partial class BaseAxe : BaseMeleeWeapon { [SerializableField(0)] diff --git a/Projects/UOContent/Items/Weapons/Axes/BattleAxe.cs b/Projects/UOContent/Items/Weapons/Axes/BattleAxe.cs index a27548485..00352dbd3 100644 --- a/Projects/UOContent/Items/Weapons/Axes/BattleAxe.cs +++ b/Projects/UOContent/Items/Weapons/Axes/BattleAxe.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0xF47, 0xF48)] public partial class BattleAxe : BaseAxe { diff --git a/Projects/UOContent/Items/Weapons/Axes/DoubleAxe.cs b/Projects/UOContent/Items/Weapons/Axes/DoubleAxe.cs index b16feeb88..fea645c8e 100644 --- a/Projects/UOContent/Items/Weapons/Axes/DoubleAxe.cs +++ b/Projects/UOContent/Items/Weapons/Axes/DoubleAxe.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0xf4b, 0xf4c)] public partial class DoubleAxe : BaseAxe { diff --git a/Projects/UOContent/Items/Weapons/Axes/DualShortAxes.cs b/Projects/UOContent/Items/Weapons/Axes/DualShortAxes.cs index d3dfb4d18..5bf018f2d 100644 --- a/Projects/UOContent/Items/Weapons/Axes/DualShortAxes.cs +++ b/Projects/UOContent/Items/Weapons/Axes/DualShortAxes.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x8FD, 0x4068)] - [Serializable(0)] + [SerializationGenerator(0)] public partial class DualShortAxes : BaseAxe { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Axes/ExecutionersAxe.cs b/Projects/UOContent/Items/Weapons/Axes/ExecutionersAxe.cs index ec5e4cd81..6302a26c0 100644 --- a/Projects/UOContent/Items/Weapons/Axes/ExecutionersAxe.cs +++ b/Projects/UOContent/Items/Weapons/Axes/ExecutionersAxe.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0xf45, 0xf46)] public partial class ExecutionersAxe : BaseAxe { diff --git a/Projects/UOContent/Items/Weapons/Axes/GuardianAxe.cs b/Projects/UOContent/Items/Weapons/Axes/GuardianAxe.cs index 8db584957..99fe86632 100644 --- a/Projects/UOContent/Items/Weapons/Axes/GuardianAxe.cs +++ b/Projects/UOContent/Items/Weapons/Axes/GuardianAxe.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class GuardianAxe : OrnateAxe { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Axes/Hatchet.cs b/Projects/UOContent/Items/Weapons/Axes/Hatchet.cs index 45c538f5c..924a54891 100644 --- a/Projects/UOContent/Items/Weapons/Axes/Hatchet.cs +++ b/Projects/UOContent/Items/Weapons/Axes/Hatchet.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0xF43, 0xF44)] public partial class Hatchet : BaseAxe { diff --git a/Projects/UOContent/Items/Weapons/Axes/HeavyOrnateAxe.cs b/Projects/UOContent/Items/Weapons/Axes/HeavyOrnateAxe.cs index 77c75599c..5c9a43e78 100644 --- a/Projects/UOContent/Items/Weapons/Axes/HeavyOrnateAxe.cs +++ b/Projects/UOContent/Items/Weapons/Axes/HeavyOrnateAxe.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class HeavyOrnateAxe : OrnateAxe { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Axes/LargeBattleAxe.cs b/Projects/UOContent/Items/Weapons/Axes/LargeBattleAxe.cs index c2b41c08d..37f6668f6 100644 --- a/Projects/UOContent/Items/Weapons/Axes/LargeBattleAxe.cs +++ b/Projects/UOContent/Items/Weapons/Axes/LargeBattleAxe.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x13FB, 0x13FA)] public partial class LargeBattleAxe : BaseAxe { diff --git a/Projects/UOContent/Items/Weapons/Axes/Pickaxe.cs b/Projects/UOContent/Items/Weapons/Axes/Pickaxe.cs index 0ad19652c..07cac1b08 100644 --- a/Projects/UOContent/Items/Weapons/Axes/Pickaxe.cs +++ b/Projects/UOContent/Items/Weapons/Axes/Pickaxe.cs @@ -1,8 +1,9 @@ +using ModernUO.Serialization; using Server.Engines.Harvest; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0xE86, 0xE85)] public partial class Pickaxe : BaseAxe, IUsesRemaining { diff --git a/Projects/UOContent/Items/Weapons/Axes/SingingAxe.cs b/Projects/UOContent/Items/Weapons/Axes/SingingAxe.cs index ac816d766..987cc0401 100644 --- a/Projects/UOContent/Items/Weapons/Axes/SingingAxe.cs +++ b/Projects/UOContent/Items/Weapons/Axes/SingingAxe.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class SingingAxe : OrnateAxe { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Axes/ThunderingAxe.cs b/Projects/UOContent/Items/Weapons/Axes/ThunderingAxe.cs index c75735cc5..fee1b8006 100644 --- a/Projects/UOContent/Items/Weapons/Axes/ThunderingAxe.cs +++ b/Projects/UOContent/Items/Weapons/Axes/ThunderingAxe.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class ThunderingAxe : OrnateAxe { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Axes/TwoHandedAxe.cs b/Projects/UOContent/Items/Weapons/Axes/TwoHandedAxe.cs index 1a11b2f63..1a87091b2 100644 --- a/Projects/UOContent/Items/Weapons/Axes/TwoHandedAxe.cs +++ b/Projects/UOContent/Items/Weapons/Axes/TwoHandedAxe.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x1443, 0x1442)] public partial class TwoHandedAxe : BaseAxe { diff --git a/Projects/UOContent/Items/Weapons/Axes/WarAxe.cs b/Projects/UOContent/Items/Weapons/Axes/WarAxe.cs index ed7895871..b11db81e0 100644 --- a/Projects/UOContent/Items/Weapons/Axes/WarAxe.cs +++ b/Projects/UOContent/Items/Weapons/Axes/WarAxe.cs @@ -1,8 +1,9 @@ +using ModernUO.Serialization; using Server.Engines.Harvest; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] [Flippable(0x13B0, 0x13AF)] public partial class WarAxe : BaseAxe { diff --git a/Projects/UOContent/Items/Weapons/Fists.cs b/Projects/UOContent/Items/Weapons/Fists.cs index e20c66c77..4a4696987 100644 --- a/Projects/UOContent/Items/Weapons/Fists.cs +++ b/Projects/UOContent/Items/Weapons/Fists.cs @@ -1,9 +1,10 @@ using System; +using ModernUO.Serialization; using Server.Engines.ConPVP; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Fists : BaseMeleeWeapon { public Fists() : base(0) diff --git a/Projects/UOContent/Items/Weapons/Knives/BaseKnife.cs b/Projects/UOContent/Items/Weapons/Knives/BaseKnife.cs index d9dd99bb2..febf56b00 100644 --- a/Projects/UOContent/Items/Weapons/Knives/BaseKnife.cs +++ b/Projects/UOContent/Items/Weapons/Knives/BaseKnife.cs @@ -1,8 +1,9 @@ +using ModernUO.Serialization; using Server.Targets; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public abstract partial class BaseKnife : BaseMeleeWeapon { public BaseKnife(int itemID) : base(itemID) diff --git a/Projects/UOContent/Items/Weapons/Knives/ButcherKnife.cs b/Projects/UOContent/Items/Weapons/Knives/ButcherKnife.cs index 0812fd30e..19743996b 100644 --- a/Projects/UOContent/Items/Weapons/Knives/ButcherKnife.cs +++ b/Projects/UOContent/Items/Weapons/Knives/ButcherKnife.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x13F6, 0x13F7)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class ButcherKnife : BaseKnife { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Knives/Cleaver.cs b/Projects/UOContent/Items/Weapons/Knives/Cleaver.cs index 830cf58d0..1738cf81c 100644 --- a/Projects/UOContent/Items/Weapons/Knives/Cleaver.cs +++ b/Projects/UOContent/Items/Weapons/Knives/Cleaver.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0xEC3, 0xEC2)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Cleaver : BaseKnife { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Knives/Dagger.cs b/Projects/UOContent/Items/Weapons/Knives/Dagger.cs index db175fb13..fadcb7daf 100644 --- a/Projects/UOContent/Items/Weapons/Knives/Dagger.cs +++ b/Projects/UOContent/Items/Weapons/Knives/Dagger.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0xF52, 0xF51)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Dagger : BaseKnife { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Knives/SkinningKnife.cs b/Projects/UOContent/Items/Weapons/Knives/SkinningKnife.cs index 70041398d..dedd24265 100644 --- a/Projects/UOContent/Items/Weapons/Knives/SkinningKnife.cs +++ b/Projects/UOContent/Items/Weapons/Knives/SkinningKnife.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0xEC4, 0xEC5)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class SkinningKnife : BaseKnife { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Knives/ThrowingDagger.cs b/Projects/UOContent/Items/Weapons/Knives/ThrowingDagger.cs index 8a2baf755..92ba5842c 100644 --- a/Projects/UOContent/Items/Weapons/Knives/ThrowingDagger.cs +++ b/Projects/UOContent/Items/Weapons/Knives/ThrowingDagger.cs @@ -1,10 +1,11 @@ using System; +using ModernUO.Serialization; using Server.Targeting; namespace Server.Items { [Flippable(0xF52, 0xF51)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class ThrowingDagger : Item { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/ML Weapons/Artifacts/BlightGrippedLongbow.cs b/Projects/UOContent/Items/Weapons/ML Weapons/Artifacts/BlightGrippedLongbow.cs index 70fda78d0..de7d6de37 100644 --- a/Projects/UOContent/Items/Weapons/ML Weapons/Artifacts/BlightGrippedLongbow.cs +++ b/Projects/UOContent/Items/Weapons/ML Weapons/Artifacts/BlightGrippedLongbow.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class BlightGrippedLongbow : ElvenCompositeLongbow { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/ML Weapons/Artifacts/ColdForgedBlade.cs b/Projects/UOContent/Items/Weapons/ML Weapons/Artifacts/ColdForgedBlade.cs index 2eb3ed9b0..9cf54f71e 100644 --- a/Projects/UOContent/Items/Weapons/ML Weapons/Artifacts/ColdForgedBlade.cs +++ b/Projects/UOContent/Items/Weapons/ML Weapons/Artifacts/ColdForgedBlade.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class ColdForgedBlade : ElvenSpellblade { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/ML Weapons/Artifacts/FaerieFire.cs b/Projects/UOContent/Items/Weapons/ML Weapons/Artifacts/FaerieFire.cs index 77d76c981..597942a57 100644 --- a/Projects/UOContent/Items/Weapons/ML Weapons/Artifacts/FaerieFire.cs +++ b/Projects/UOContent/Items/Weapons/ML Weapons/Artifacts/FaerieFire.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class FaerieFire : ElvenCompositeLongbow { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/ML Weapons/Artifacts/LuminousRuneBlade.cs b/Projects/UOContent/Items/Weapons/ML Weapons/Artifacts/LuminousRuneBlade.cs index 230879940..df00c30ec 100644 --- a/Projects/UOContent/Items/Weapons/ML Weapons/Artifacts/LuminousRuneBlade.cs +++ b/Projects/UOContent/Items/Weapons/ML Weapons/Artifacts/LuminousRuneBlade.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class LuminousRuneBlade : RuneBlade { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/ML Weapons/Artifacts/MischiefMaker.cs b/Projects/UOContent/Items/Weapons/ML Weapons/Artifacts/MischiefMaker.cs index cc1c5354e..f7770d0e0 100644 --- a/Projects/UOContent/Items/Weapons/ML Weapons/Artifacts/MischiefMaker.cs +++ b/Projects/UOContent/Items/Weapons/ML Weapons/Artifacts/MischiefMaker.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class MischiefMaker : MagicalShortbow { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/ML Weapons/Artifacts/OverseerSunderedBlade.cs b/Projects/UOContent/Items/Weapons/ML Weapons/Artifacts/OverseerSunderedBlade.cs index 81587f840..1d7dac8e2 100644 --- a/Projects/UOContent/Items/Weapons/ML Weapons/Artifacts/OverseerSunderedBlade.cs +++ b/Projects/UOContent/Items/Weapons/ML Weapons/Artifacts/OverseerSunderedBlade.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class OverseerSunderedBlade : RadiantScimitar { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/ML Weapons/Artifacts/PhantomStaff.cs b/Projects/UOContent/Items/Weapons/ML Weapons/Artifacts/PhantomStaff.cs index f7617bfe3..c7ef49486 100644 --- a/Projects/UOContent/Items/Weapons/ML Weapons/Artifacts/PhantomStaff.cs +++ b/Projects/UOContent/Items/Weapons/ML Weapons/Artifacts/PhantomStaff.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class PhantomStaff : WildStaff { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/ML Weapons/Artifacts/RuneCarvingKnife.cs b/Projects/UOContent/Items/Weapons/ML Weapons/Artifacts/RuneCarvingKnife.cs index e1d850722..4ed88bdff 100644 --- a/Projects/UOContent/Items/Weapons/ML Weapons/Artifacts/RuneCarvingKnife.cs +++ b/Projects/UOContent/Items/Weapons/ML Weapons/Artifacts/RuneCarvingKnife.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class RuneCarvingKnife : AssassinSpike { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/ML Weapons/Artifacts/ShardTrasher.cs b/Projects/UOContent/Items/Weapons/ML Weapons/Artifacts/ShardTrasher.cs index 6c1c6c73a..e883ff7cd 100644 --- a/Projects/UOContent/Items/Weapons/ML Weapons/Artifacts/ShardTrasher.cs +++ b/Projects/UOContent/Items/Weapons/ML Weapons/Artifacts/ShardTrasher.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class ShardThrasher : DiamondMace { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/ML Weapons/Artifacts/SilvanisFeywoodBow.cs b/Projects/UOContent/Items/Weapons/ML Weapons/Artifacts/SilvanisFeywoodBow.cs index 22082ff89..d02d8c09d 100644 --- a/Projects/UOContent/Items/Weapons/ML Weapons/Artifacts/SilvanisFeywoodBow.cs +++ b/Projects/UOContent/Items/Weapons/ML Weapons/Artifacts/SilvanisFeywoodBow.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class SilvanisFeywoodBow : ElvenCompositeLongbow { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/ML Weapons/Artifacts/TheNightReaper.cs b/Projects/UOContent/Items/Weapons/ML Weapons/Artifacts/TheNightReaper.cs index 2a2258fa7..1945e64d8 100644 --- a/Projects/UOContent/Items/Weapons/ML Weapons/Artifacts/TheNightReaper.cs +++ b/Projects/UOContent/Items/Weapons/ML Weapons/Artifacts/TheNightReaper.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class TheNightReaper : RepeatingCrossbow { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/ML Weapons/AssassinSpike.cs b/Projects/UOContent/Items/Weapons/ML Weapons/AssassinSpike.cs index 7d39764d4..f0560945e 100644 --- a/Projects/UOContent/Items/Weapons/ML Weapons/AssassinSpike.cs +++ b/Projects/UOContent/Items/Weapons/ML Weapons/AssassinSpike.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x2D21, 0x2D2D)] - [Serializable(0)] + [SerializationGenerator(0)] public partial class AssassinSpike : BaseKnife { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/ML Weapons/ButchersWarCleaver.cs b/Projects/UOContent/Items/Weapons/ML Weapons/ButchersWarCleaver.cs index 4afeed5c1..30ccfb29b 100644 --- a/Projects/UOContent/Items/Weapons/ML Weapons/ButchersWarCleaver.cs +++ b/Projects/UOContent/Items/Weapons/ML Weapons/ButchersWarCleaver.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class ButchersWarCleaver : WarCleaver { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/ML Weapons/DiamondMace.cs b/Projects/UOContent/Items/Weapons/ML Weapons/DiamondMace.cs index 9fbf8d9fa..453e67e19 100644 --- a/Projects/UOContent/Items/Weapons/ML Weapons/DiamondMace.cs +++ b/Projects/UOContent/Items/Weapons/ML Weapons/DiamondMace.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x2D24, 0x2D30)] - [Serializable(0)] + [SerializationGenerator(0)] public partial class DiamondMace : BaseBashing { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/ML Weapons/ElvenCompositeLongbow.cs b/Projects/UOContent/Items/Weapons/ML Weapons/ElvenCompositeLongbow.cs index d0b4aa941..199c76d82 100644 --- a/Projects/UOContent/Items/Weapons/ML Weapons/ElvenCompositeLongbow.cs +++ b/Projects/UOContent/Items/Weapons/ML Weapons/ElvenCompositeLongbow.cs @@ -1,9 +1,10 @@ using System; +using ModernUO.Serialization; namespace Server.Items { [Flippable(0x2D1E, 0x2D2A)] - [Serializable(0)] + [SerializationGenerator(0)] public partial class ElvenCompositeLongbow : BaseRanged { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/ML Weapons/ElvenMachete.cs b/Projects/UOContent/Items/Weapons/ML Weapons/ElvenMachete.cs index 6c47e6382..459c76a66 100644 --- a/Projects/UOContent/Items/Weapons/ML Weapons/ElvenMachete.cs +++ b/Projects/UOContent/Items/Weapons/ML Weapons/ElvenMachete.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x2D35, 0x2D29)] - [Serializable(0)] + [SerializationGenerator(0)] public partial class ElvenMachete : BaseSword { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/ML Weapons/ElvenSpellblade.cs b/Projects/UOContent/Items/Weapons/ML Weapons/ElvenSpellblade.cs index cb06ecc6c..ebe89b1a5 100644 --- a/Projects/UOContent/Items/Weapons/ML Weapons/ElvenSpellblade.cs +++ b/Projects/UOContent/Items/Weapons/ML Weapons/ElvenSpellblade.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x2D20, 0x2D2C)] - [Serializable(0)] + [SerializationGenerator(0)] public partial class ElvenSpellblade : BaseKnife { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/ML Weapons/Leafblade.cs b/Projects/UOContent/Items/Weapons/ML Weapons/Leafblade.cs index 9153375fc..79fe3730f 100644 --- a/Projects/UOContent/Items/Weapons/ML Weapons/Leafblade.cs +++ b/Projects/UOContent/Items/Weapons/ML Weapons/Leafblade.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x2D22, 0x2D2E)] - [Serializable(0)] + [SerializationGenerator(0)] public partial class Leafblade : BaseKnife { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/ML Weapons/MagicalShortbow.cs b/Projects/UOContent/Items/Weapons/ML Weapons/MagicalShortbow.cs index e51e3ca59..63f3e0ae0 100644 --- a/Projects/UOContent/Items/Weapons/ML Weapons/MagicalShortbow.cs +++ b/Projects/UOContent/Items/Weapons/ML Weapons/MagicalShortbow.cs @@ -1,9 +1,10 @@ using System; +using ModernUO.Serialization; namespace Server.Items { [Flippable(0x2D2B, 0x2D1F)] - [Serializable(0)] + [SerializationGenerator(0)] public partial class MagicalShortbow : BaseRanged { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/ML Weapons/OrnateAxe.cs b/Projects/UOContent/Items/Weapons/ML Weapons/OrnateAxe.cs index f19f09ca7..1c4f89602 100644 --- a/Projects/UOContent/Items/Weapons/ML Weapons/OrnateAxe.cs +++ b/Projects/UOContent/Items/Weapons/ML Weapons/OrnateAxe.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x2D28, 0x2D34)] - [Serializable(0)] + [SerializationGenerator(0)] public partial class OrnateAxe : BaseAxe { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/ML Weapons/RadiantScimitar.cs b/Projects/UOContent/Items/Weapons/ML Weapons/RadiantScimitar.cs index 4f1c037be..6783f36d3 100644 --- a/Projects/UOContent/Items/Weapons/ML Weapons/RadiantScimitar.cs +++ b/Projects/UOContent/Items/Weapons/ML Weapons/RadiantScimitar.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x2D33, 0x2D27)] - [Serializable(0)] + [SerializationGenerator(0)] public partial class RadiantScimitar : BaseSword { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/ML Weapons/RuneBlade.cs b/Projects/UOContent/Items/Weapons/ML Weapons/RuneBlade.cs index d5a6bfa79..1adda77d6 100644 --- a/Projects/UOContent/Items/Weapons/ML Weapons/RuneBlade.cs +++ b/Projects/UOContent/Items/Weapons/ML Weapons/RuneBlade.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x2D32, 0x2D26)] - [Serializable(0)] + [SerializationGenerator(0)] public partial class RuneBlade : BaseSword { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/ML Weapons/WarCleaver.cs b/Projects/UOContent/Items/Weapons/ML Weapons/WarCleaver.cs index 679ab6773..153bf26b7 100644 --- a/Projects/UOContent/Items/Weapons/ML Weapons/WarCleaver.cs +++ b/Projects/UOContent/Items/Weapons/ML Weapons/WarCleaver.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x2D2F, 0x2D23)] - [Serializable(0)] + [SerializationGenerator(0)] public partial class WarCleaver : BaseKnife { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/ML Weapons/WildStaff.cs b/Projects/UOContent/Items/Weapons/ML Weapons/WildStaff.cs index a7cc68c0f..4f307bcaa 100644 --- a/Projects/UOContent/Items/Weapons/ML Weapons/WildStaff.cs +++ b/Projects/UOContent/Items/Weapons/ML Weapons/WildStaff.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x2D25, 0x2D31)] - [Serializable(0)] + [SerializationGenerator(0)] public partial class WildStaff : BaseStaff { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Maces/BaseBashing.cs b/Projects/UOContent/Items/Weapons/Maces/BaseBashing.cs index 4c2e7dc77..b9870332b 100644 --- a/Projects/UOContent/Items/Weapons/Maces/BaseBashing.cs +++ b/Projects/UOContent/Items/Weapons/Maces/BaseBashing.cs @@ -1,8 +1,9 @@ +using ModernUO.Serialization; using Server.Engines.ConPVP; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public abstract partial class BaseBashing : BaseMeleeWeapon { public BaseBashing(int itemID) : base(itemID) diff --git a/Projects/UOContent/Items/Weapons/Maces/Club.cs b/Projects/UOContent/Items/Weapons/Maces/Club.cs index bf192959c..a4b3333e3 100644 --- a/Projects/UOContent/Items/Weapons/Maces/Club.cs +++ b/Projects/UOContent/Items/Weapons/Maces/Club.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x13b4, 0x13b3)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Club : BaseBashing { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Maces/DiscMace.cs b/Projects/UOContent/Items/Weapons/Maces/DiscMace.cs index 7152cc377..de634920d 100644 --- a/Projects/UOContent/Items/Weapons/Maces/DiscMace.cs +++ b/Projects/UOContent/Items/Weapons/Maces/DiscMace.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x903, 0x406E)] - [Serializable(0)] + [SerializationGenerator(0)] public partial class DiscMace : BaseBashing { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Maces/EmeraldMace.cs b/Projects/UOContent/Items/Weapons/Maces/EmeraldMace.cs index b76750f90..a166ad5ac 100644 --- a/Projects/UOContent/Items/Weapons/Maces/EmeraldMace.cs +++ b/Projects/UOContent/Items/Weapons/Maces/EmeraldMace.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class EmeraldMace : DiamondMace { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Maces/FireworksWand.cs b/Projects/UOContent/Items/Weapons/Maces/FireworksWand.cs index 8210c2c7a..916a5a6be 100644 --- a/Projects/UOContent/Items/Weapons/Maces/FireworksWand.cs +++ b/Projects/UOContent/Items/Weapons/Maces/FireworksWand.cs @@ -1,8 +1,9 @@ using System; +using ModernUO.Serialization; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class FireworksWand : MagicWand { [SerializableField(0)] diff --git a/Projects/UOContent/Items/Weapons/Maces/HammerPick.cs b/Projects/UOContent/Items/Weapons/Maces/HammerPick.cs index 99d0ed0d1..88a74b2aa 100644 --- a/Projects/UOContent/Items/Weapons/Maces/HammerPick.cs +++ b/Projects/UOContent/Items/Weapons/Maces/HammerPick.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x143D, 0x143C)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class HammerPick : BaseBashing { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Maces/Mace.cs b/Projects/UOContent/Items/Weapons/Maces/Mace.cs index 5d47a060d..b362f04fe 100644 --- a/Projects/UOContent/Items/Weapons/Maces/Mace.cs +++ b/Projects/UOContent/Items/Weapons/Maces/Mace.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0xF5C, 0xF5D)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Mace : BaseBashing { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Maces/MagicWand.cs b/Projects/UOContent/Items/Weapons/Maces/MagicWand.cs index a50669b31..31e92e79f 100644 --- a/Projects/UOContent/Items/Weapons/Maces/MagicWand.cs +++ b/Projects/UOContent/Items/Weapons/Maces/MagicWand.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class MagicWand : BaseBashing { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Maces/Maul.cs b/Projects/UOContent/Items/Weapons/Maces/Maul.cs index 6252761a9..ee3054c76 100644 --- a/Projects/UOContent/Items/Weapons/Maces/Maul.cs +++ b/Projects/UOContent/Items/Weapons/Maces/Maul.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x143B, 0x143A)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Maul : BaseBashing { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Maces/RubyMace.cs b/Projects/UOContent/Items/Weapons/Maces/RubyMace.cs index 27de75f36..f7d559314 100644 --- a/Projects/UOContent/Items/Weapons/Maces/RubyMace.cs +++ b/Projects/UOContent/Items/Weapons/Maces/RubyMace.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class RubyMace : DiamondMace { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Maces/SapphireMace.cs b/Projects/UOContent/Items/Weapons/Maces/SapphireMace.cs index 7a4c8ef66..c85732798 100644 --- a/Projects/UOContent/Items/Weapons/Maces/SapphireMace.cs +++ b/Projects/UOContent/Items/Weapons/Maces/SapphireMace.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class SapphireMace : DiamondMace { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Maces/Scepter.cs b/Projects/UOContent/Items/Weapons/Maces/Scepter.cs index bf19702cb..d48793e15 100644 --- a/Projects/UOContent/Items/Weapons/Maces/Scepter.cs +++ b/Projects/UOContent/Items/Weapons/Maces/Scepter.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x26BC, 0x26C6)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Scepter : BaseBashing { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Maces/SilverEtchedMace.cs b/Projects/UOContent/Items/Weapons/Maces/SilverEtchedMace.cs index 804838cae..4e3e48228 100644 --- a/Projects/UOContent/Items/Weapons/Maces/SilverEtchedMace.cs +++ b/Projects/UOContent/Items/Weapons/Maces/SilverEtchedMace.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class SilverEtchedMace : DiamondMace { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Maces/WarHammer.cs b/Projects/UOContent/Items/Weapons/Maces/WarHammer.cs index 591a64ae3..dd5ab6944 100644 --- a/Projects/UOContent/Items/Weapons/Maces/WarHammer.cs +++ b/Projects/UOContent/Items/Weapons/Maces/WarHammer.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x1439, 0x1438)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class WarHammer : BaseBashing { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Maces/WarMace.cs b/Projects/UOContent/Items/Weapons/Maces/WarMace.cs index 45527f97e..0ed10402c 100644 --- a/Projects/UOContent/Items/Weapons/Maces/WarMace.cs +++ b/Projects/UOContent/Items/Weapons/Maces/WarMace.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x1407, 0x1406)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class WarMace : BaseBashing { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/PoleArms/Bardiche.cs b/Projects/UOContent/Items/Weapons/PoleArms/Bardiche.cs index 2f7601fb1..a19bc33c5 100644 --- a/Projects/UOContent/Items/Weapons/PoleArms/Bardiche.cs +++ b/Projects/UOContent/Items/Weapons/PoleArms/Bardiche.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0xF4D, 0xF4E)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Bardiche : BasePoleArm { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/PoleArms/BasePoleArm.cs b/Projects/UOContent/Items/Weapons/PoleArms/BasePoleArm.cs index cb960208d..ea56669ff 100644 --- a/Projects/UOContent/Items/Weapons/PoleArms/BasePoleArm.cs +++ b/Projects/UOContent/Items/Weapons/PoleArms/BasePoleArm.cs @@ -1,12 +1,13 @@ using System; using System.Collections.Generic; +using ModernUO.Serialization; using Server.ContextMenus; using Server.Engines.ConPVP; using Server.Engines.Harvest; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public abstract partial class BasePoleArm : BaseMeleeWeapon, IUsesRemaining { [SerializableField(0)] diff --git a/Projects/UOContent/Items/Weapons/PoleArms/Halberd.cs b/Projects/UOContent/Items/Weapons/PoleArms/Halberd.cs index 0ed0cf584..9356842a5 100644 --- a/Projects/UOContent/Items/Weapons/PoleArms/Halberd.cs +++ b/Projects/UOContent/Items/Weapons/PoleArms/Halberd.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x143E, 0x143F)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Halberd : BasePoleArm { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/PoleArms/Scythe.cs b/Projects/UOContent/Items/Weapons/PoleArms/Scythe.cs index 18f802927..62038c4d4 100644 --- a/Projects/UOContent/Items/Weapons/PoleArms/Scythe.cs +++ b/Projects/UOContent/Items/Weapons/PoleArms/Scythe.cs @@ -1,9 +1,10 @@ +using ModernUO.Serialization; using Server.Engines.Harvest; namespace Server.Items { [Flippable(0x26BA, 0x26C4)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Scythe : BasePoleArm { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Ranged/AssassinsShortbow.cs b/Projects/UOContent/Items/Weapons/Ranged/AssassinsShortbow.cs index 802b34385..ea2c2411e 100644 --- a/Projects/UOContent/Items/Weapons/Ranged/AssassinsShortbow.cs +++ b/Projects/UOContent/Items/Weapons/Ranged/AssassinsShortbow.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class AssassinsShortbow : MagicalShortbow { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Ranged/BarbedLongbow.cs b/Projects/UOContent/Items/Weapons/Ranged/BarbedLongbow.cs index 7fdf8f1bd..c27d6071b 100644 --- a/Projects/UOContent/Items/Weapons/Ranged/BarbedLongbow.cs +++ b/Projects/UOContent/Items/Weapons/Ranged/BarbedLongbow.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class BarbedLongbow : ElvenCompositeLongbow { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Ranged/BaseRanged.cs b/Projects/UOContent/Items/Weapons/Ranged/BaseRanged.cs index 05f3bf3da..f4cdc12bc 100644 --- a/Projects/UOContent/Items/Weapons/Ranged/BaseRanged.cs +++ b/Projects/UOContent/Items/Weapons/Ranged/BaseRanged.cs @@ -1,11 +1,12 @@ using System; +using ModernUO.Serialization; using Server.Mobiles; using Server.Network; using Server.Spells; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public abstract partial class BaseRanged : BaseMeleeWeapon { [SerializableField(0)] diff --git a/Projects/UOContent/Items/Weapons/Ranged/Bow.cs b/Projects/UOContent/Items/Weapons/Ranged/Bow.cs index b5940a5d4..400d2bf8a 100644 --- a/Projects/UOContent/Items/Weapons/Ranged/Bow.cs +++ b/Projects/UOContent/Items/Weapons/Ranged/Bow.cs @@ -1,9 +1,10 @@ using System; +using ModernUO.Serialization; namespace Server.Items { [Flippable(0x13B2, 0x13B1)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Bow : BaseRanged { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Ranged/CompositeBow.cs b/Projects/UOContent/Items/Weapons/Ranged/CompositeBow.cs index 19b1ebf28..58515ae4c 100644 --- a/Projects/UOContent/Items/Weapons/Ranged/CompositeBow.cs +++ b/Projects/UOContent/Items/Weapons/Ranged/CompositeBow.cs @@ -1,9 +1,10 @@ using System; +using ModernUO.Serialization; namespace Server.Items { [Flippable(0x26C2, 0x26CC)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class CompositeBow : BaseRanged { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Ranged/Crossbow.cs b/Projects/UOContent/Items/Weapons/Ranged/Crossbow.cs index 05675d117..cccfd0103 100644 --- a/Projects/UOContent/Items/Weapons/Ranged/Crossbow.cs +++ b/Projects/UOContent/Items/Weapons/Ranged/Crossbow.cs @@ -1,9 +1,10 @@ using System; +using ModernUO.Serialization; namespace Server.Items { [Flippable(0xF50, 0xF4F)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Crossbow : BaseRanged { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Ranged/FrozenLongbow.cs b/Projects/UOContent/Items/Weapons/Ranged/FrozenLongbow.cs index e372369df..74829ed1d 100644 --- a/Projects/UOContent/Items/Weapons/Ranged/FrozenLongbow.cs +++ b/Projects/UOContent/Items/Weapons/Ranged/FrozenLongbow.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class FrozenLongbow : ElvenCompositeLongbow { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Ranged/HeavyCrossbow.cs b/Projects/UOContent/Items/Weapons/Ranged/HeavyCrossbow.cs index e41923e75..84679ce07 100644 --- a/Projects/UOContent/Items/Weapons/Ranged/HeavyCrossbow.cs +++ b/Projects/UOContent/Items/Weapons/Ranged/HeavyCrossbow.cs @@ -1,9 +1,10 @@ using System; +using ModernUO.Serialization; namespace Server.Items { [Flippable(0x13FD, 0x13FC)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class HeavyCrossbow : BaseRanged { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Ranged/JukaBow.cs b/Projects/UOContent/Items/Weapons/Ranged/JukaBow.cs index 658c9d39c..763d2b373 100644 --- a/Projects/UOContent/Items/Weapons/Ranged/JukaBow.cs +++ b/Projects/UOContent/Items/Weapons/Ranged/JukaBow.cs @@ -1,9 +1,10 @@ +using ModernUO.Serialization; using Server.Targeting; namespace Server.Items { [Flippable(0x13B2, 0x13B1)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class JukaBow : Bow { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Ranged/LightweightShortbow.cs b/Projects/UOContent/Items/Weapons/Ranged/LightweightShortbow.cs index d450d14d6..102ef3677 100644 --- a/Projects/UOContent/Items/Weapons/Ranged/LightweightShortbow.cs +++ b/Projects/UOContent/Items/Weapons/Ranged/LightweightShortbow.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class LightweightShortbow : MagicalShortbow { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Ranged/LongbowOfMight.cs b/Projects/UOContent/Items/Weapons/Ranged/LongbowOfMight.cs index c45a14965..20dd19f29 100644 --- a/Projects/UOContent/Items/Weapons/Ranged/LongbowOfMight.cs +++ b/Projects/UOContent/Items/Weapons/Ranged/LongbowOfMight.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class LongbowOfMight : ElvenCompositeLongbow { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Ranged/MysticalShortbow.cs b/Projects/UOContent/Items/Weapons/Ranged/MysticalShortbow.cs index 83526b00c..4ffea36ae 100644 --- a/Projects/UOContent/Items/Weapons/Ranged/MysticalShortbow.cs +++ b/Projects/UOContent/Items/Weapons/Ranged/MysticalShortbow.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class MysticalShortbow : MagicalShortbow { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Ranged/RangersShortbow.cs b/Projects/UOContent/Items/Weapons/Ranged/RangersShortbow.cs index 125a18efb..63cd5f80e 100644 --- a/Projects/UOContent/Items/Weapons/Ranged/RangersShortbow.cs +++ b/Projects/UOContent/Items/Weapons/Ranged/RangersShortbow.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class RangersShortbow : MagicalShortbow { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Ranged/RepeatingCrossbow.cs b/Projects/UOContent/Items/Weapons/Ranged/RepeatingCrossbow.cs index 06978f985..71bac450f 100644 --- a/Projects/UOContent/Items/Weapons/Ranged/RepeatingCrossbow.cs +++ b/Projects/UOContent/Items/Weapons/Ranged/RepeatingCrossbow.cs @@ -1,9 +1,10 @@ using System; +using ModernUO.Serialization; namespace Server.Items { [Flippable(0x26C3, 0x26CD)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class RepeatingCrossbow : BaseRanged { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Ranged/SlayerLongbow.cs b/Projects/UOContent/Items/Weapons/Ranged/SlayerLongbow.cs index f0ceb5161..f7e310ca8 100644 --- a/Projects/UOContent/Items/Weapons/Ranged/SlayerLongbow.cs +++ b/Projects/UOContent/Items/Weapons/Ranged/SlayerLongbow.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class SlayerLongbow : ElvenCompositeLongbow { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/SE Weapons/Bokuto.cs b/Projects/UOContent/Items/Weapons/SE Weapons/Bokuto.cs index 8abd83332..1f3f9db30 100644 --- a/Projects/UOContent/Items/Weapons/SE Weapons/Bokuto.cs +++ b/Projects/UOContent/Items/Weapons/SE Weapons/Bokuto.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x27A8, 0x27F3)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Bokuto : BaseSword { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/SE Weapons/Daisho.cs b/Projects/UOContent/Items/Weapons/SE Weapons/Daisho.cs index 0eef9f732..136897fdf 100644 --- a/Projects/UOContent/Items/Weapons/SE Weapons/Daisho.cs +++ b/Projects/UOContent/Items/Weapons/SE Weapons/Daisho.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x27A9, 0x27F4)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Daisho : BaseSword { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/SE Weapons/Kama.cs b/Projects/UOContent/Items/Weapons/SE Weapons/Kama.cs index aad267a06..23d054bb6 100644 --- a/Projects/UOContent/Items/Weapons/SE Weapons/Kama.cs +++ b/Projects/UOContent/Items/Weapons/SE Weapons/Kama.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x27AD, 0x27F8)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Kama : BaseKnife { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/SE Weapons/Lajatang.cs b/Projects/UOContent/Items/Weapons/SE Weapons/Lajatang.cs index 7c75dd00a..963b1219f 100644 --- a/Projects/UOContent/Items/Weapons/SE Weapons/Lajatang.cs +++ b/Projects/UOContent/Items/Weapons/SE Weapons/Lajatang.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x27A7, 0x27F2)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Lajatang : BaseKnife { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/SE Weapons/NoDachi.cs b/Projects/UOContent/Items/Weapons/SE Weapons/NoDachi.cs index 3e2f35343..7d61ea419 100644 --- a/Projects/UOContent/Items/Weapons/SE Weapons/NoDachi.cs +++ b/Projects/UOContent/Items/Weapons/SE Weapons/NoDachi.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x27A2, 0x27ED)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class NoDachi : BaseSword { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/SE Weapons/Nunchaku.cs b/Projects/UOContent/Items/Weapons/SE Weapons/Nunchaku.cs index 7018a110f..2e5bf689c 100644 --- a/Projects/UOContent/Items/Weapons/SE Weapons/Nunchaku.cs +++ b/Projects/UOContent/Items/Weapons/SE Weapons/Nunchaku.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x27AE, 0x27F9)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Nunchaku : BaseBashing { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/SE Weapons/Sai.cs b/Projects/UOContent/Items/Weapons/SE Weapons/Sai.cs index 94d8357af..df60344a2 100644 --- a/Projects/UOContent/Items/Weapons/SE Weapons/Sai.cs +++ b/Projects/UOContent/Items/Weapons/SE Weapons/Sai.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x27AF, 0x27FA)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Sai : BaseKnife { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/SE Weapons/Tekagi.cs b/Projects/UOContent/Items/Weapons/SE Weapons/Tekagi.cs index 2e8cda833..388186818 100644 --- a/Projects/UOContent/Items/Weapons/SE Weapons/Tekagi.cs +++ b/Projects/UOContent/Items/Weapons/SE Weapons/Tekagi.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x27Ab, 0x27F6)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Tekagi : BaseKnife { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/SE Weapons/Tessen.cs b/Projects/UOContent/Items/Weapons/SE Weapons/Tessen.cs index 7ad363f5c..442ae9e55 100644 --- a/Projects/UOContent/Items/Weapons/SE Weapons/Tessen.cs +++ b/Projects/UOContent/Items/Weapons/SE Weapons/Tessen.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x27A3, 0x27EE)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Tessen : BaseBashing { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/SE Weapons/Tetsubo.cs b/Projects/UOContent/Items/Weapons/SE Weapons/Tetsubo.cs index 7d2cfa6d3..ab32c41a4 100644 --- a/Projects/UOContent/Items/Weapons/SE Weapons/Tetsubo.cs +++ b/Projects/UOContent/Items/Weapons/SE Weapons/Tetsubo.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x27A6, 0x27F1)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Tetsubo : BaseBashing { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/SE Weapons/Wakizashi.cs b/Projects/UOContent/Items/Weapons/SE Weapons/Wakizashi.cs index ab3b75c33..5bb6b0fd4 100644 --- a/Projects/UOContent/Items/Weapons/SE Weapons/Wakizashi.cs +++ b/Projects/UOContent/Items/Weapons/SE Weapons/Wakizashi.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x27A4, 0x27EF)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Wakizashi : BaseSword { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/SE Weapons/Yumi.cs b/Projects/UOContent/Items/Weapons/SE Weapons/Yumi.cs index d1f69eaf2..56ee5b3a3 100644 --- a/Projects/UOContent/Items/Weapons/SE Weapons/Yumi.cs +++ b/Projects/UOContent/Items/Weapons/SE Weapons/Yumi.cs @@ -1,9 +1,10 @@ using System; +using ModernUO.Serialization; namespace Server.Items { [Flippable(0x27A5, 0x27F0)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Yumi : BaseRanged { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/SpearsAndForks/BaseSpear.cs b/Projects/UOContent/Items/Weapons/SpearsAndForks/BaseSpear.cs index 0a1c911f4..574e2749d 100644 --- a/Projects/UOContent/Items/Weapons/SpearsAndForks/BaseSpear.cs +++ b/Projects/UOContent/Items/Weapons/SpearsAndForks/BaseSpear.cs @@ -1,9 +1,10 @@ using System; +using ModernUO.Serialization; using Server.Engines.ConPVP; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public abstract partial class BaseSpear : BaseMeleeWeapon { public BaseSpear(int itemID) : base(itemID) diff --git a/Projects/UOContent/Items/Weapons/SpearsAndForks/BladedStaff.cs b/Projects/UOContent/Items/Weapons/SpearsAndForks/BladedStaff.cs index f11dbe9cb..102ceb361 100644 --- a/Projects/UOContent/Items/Weapons/SpearsAndForks/BladedStaff.cs +++ b/Projects/UOContent/Items/Weapons/SpearsAndForks/BladedStaff.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x26BD, 0x26C7)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class BladedStaff : BaseSpear { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/SpearsAndForks/DoubleBladedStaff.cs b/Projects/UOContent/Items/Weapons/SpearsAndForks/DoubleBladedStaff.cs index cb9d3e603..7d7bfc05a 100644 --- a/Projects/UOContent/Items/Weapons/SpearsAndForks/DoubleBladedStaff.cs +++ b/Projects/UOContent/Items/Weapons/SpearsAndForks/DoubleBladedStaff.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x26BF, 0x26C9)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class DoubleBladedStaff : BaseSpear { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/SpearsAndForks/DualPointedSpear.cs b/Projects/UOContent/Items/Weapons/SpearsAndForks/DualPointedSpear.cs index 2aee19229..275800cd4 100644 --- a/Projects/UOContent/Items/Weapons/SpearsAndForks/DualPointedSpear.cs +++ b/Projects/UOContent/Items/Weapons/SpearsAndForks/DualPointedSpear.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x904, 0x406D)] - [Serializable(0)] + [SerializationGenerator(0)] public partial class DualPointedSpear : BaseSpear { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/SpearsAndForks/Pike.cs b/Projects/UOContent/Items/Weapons/SpearsAndForks/Pike.cs index 27754df5b..6c8b724c9 100644 --- a/Projects/UOContent/Items/Weapons/SpearsAndForks/Pike.cs +++ b/Projects/UOContent/Items/Weapons/SpearsAndForks/Pike.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x26BE, 0x26C8)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Pike : BaseSpear { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/SpearsAndForks/Pitchfork.cs b/Projects/UOContent/Items/Weapons/SpearsAndForks/Pitchfork.cs index b3fdd2d1b..fc3ac6a21 100644 --- a/Projects/UOContent/Items/Weapons/SpearsAndForks/Pitchfork.cs +++ b/Projects/UOContent/Items/Weapons/SpearsAndForks/Pitchfork.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0xE87, 0xE88)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Pitchfork : BaseSpear { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/SpearsAndForks/ShortSpear.cs b/Projects/UOContent/Items/Weapons/SpearsAndForks/ShortSpear.cs index 86e914010..32b566a0b 100644 --- a/Projects/UOContent/Items/Weapons/SpearsAndForks/ShortSpear.cs +++ b/Projects/UOContent/Items/Weapons/SpearsAndForks/ShortSpear.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x1403, 0x1402)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class ShortSpear : BaseSpear { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/SpearsAndForks/Spear.cs b/Projects/UOContent/Items/Weapons/SpearsAndForks/Spear.cs index 98d2ee1c2..26d3e2636 100644 --- a/Projects/UOContent/Items/Weapons/SpearsAndForks/Spear.cs +++ b/Projects/UOContent/Items/Weapons/SpearsAndForks/Spear.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0xF62, 0xF63)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Spear : BaseSpear { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/SpearsAndForks/TribalSpear.cs b/Projects/UOContent/Items/Weapons/SpearsAndForks/TribalSpear.cs index d2164a0d8..3f3f17ecc 100644 --- a/Projects/UOContent/Items/Weapons/SpearsAndForks/TribalSpear.cs +++ b/Projects/UOContent/Items/Weapons/SpearsAndForks/TribalSpear.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0xF62, 0xF63)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class TribalSpear : BaseSpear { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/SpearsAndForks/WarFork.cs b/Projects/UOContent/Items/Weapons/SpearsAndForks/WarFork.cs index 9857de710..94b672b63 100644 --- a/Projects/UOContent/Items/Weapons/SpearsAndForks/WarFork.cs +++ b/Projects/UOContent/Items/Weapons/SpearsAndForks/WarFork.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x1405, 0x1404)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class WarFork : BaseSpear { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Staves/BaseStaff.cs b/Projects/UOContent/Items/Weapons/Staves/BaseStaff.cs index 6686b9cc2..57ee0a7a1 100644 --- a/Projects/UOContent/Items/Weapons/Staves/BaseStaff.cs +++ b/Projects/UOContent/Items/Weapons/Staves/BaseStaff.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public abstract partial class BaseStaff : BaseMeleeWeapon { public BaseStaff(int itemID) : base(itemID) diff --git a/Projects/UOContent/Items/Weapons/Staves/BlackStaff.cs b/Projects/UOContent/Items/Weapons/Staves/BlackStaff.cs index 6b26eb0f5..a4508680c 100644 --- a/Projects/UOContent/Items/Weapons/Staves/BlackStaff.cs +++ b/Projects/UOContent/Items/Weapons/Staves/BlackStaff.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0xDF1, 0xDF0)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class BlackStaff : BaseStaff { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Staves/GlacialStaff.cs b/Projects/UOContent/Items/Weapons/Staves/GlacialStaff.cs index 02fd7936b..3f66a7c16 100644 --- a/Projects/UOContent/Items/Weapons/Staves/GlacialStaff.cs +++ b/Projects/UOContent/Items/Weapons/Staves/GlacialStaff.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class GlacialStaff : BlackStaff { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Staves/GlassStaff.cs b/Projects/UOContent/Items/Weapons/Staves/GlassStaff.cs index 03d3b0bbc..db2250053 100644 --- a/Projects/UOContent/Items/Weapons/Staves/GlassStaff.cs +++ b/Projects/UOContent/Items/Weapons/Staves/GlassStaff.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x905, 0x4070)] - [Serializable(0)] + [SerializationGenerator(0)] public partial class GlassStaff : BaseStaff { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Staves/GnarledStaff.cs b/Projects/UOContent/Items/Weapons/Staves/GnarledStaff.cs index 8ca5f06a6..3611907b5 100644 --- a/Projects/UOContent/Items/Weapons/Staves/GnarledStaff.cs +++ b/Projects/UOContent/Items/Weapons/Staves/GnarledStaff.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x13F8, 0x13F9)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class GnarledStaff : BaseStaff { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Staves/QuarterStaff.cs b/Projects/UOContent/Items/Weapons/Staves/QuarterStaff.cs index bb65230ad..e0d5c567d 100644 --- a/Projects/UOContent/Items/Weapons/Staves/QuarterStaff.cs +++ b/Projects/UOContent/Items/Weapons/Staves/QuarterStaff.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0xE89, 0xE8a)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class QuarterStaff : BaseStaff { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Staves/SerpentstoneStaff.cs b/Projects/UOContent/Items/Weapons/Staves/SerpentstoneStaff.cs index a75b82ae4..2caebfb21 100644 --- a/Projects/UOContent/Items/Weapons/Staves/SerpentstoneStaff.cs +++ b/Projects/UOContent/Items/Weapons/Staves/SerpentstoneStaff.cs @@ -1,8 +1,10 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x906, 0x406F)] [TypeAlias("Server.Items.SerpentStoneStaff")] - [Serializable(0)] + [SerializationGenerator(0)] public partial class SerpentstoneStaff : BaseStaff { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Staves/ShepherdsCrook.cs b/Projects/UOContent/Items/Weapons/Staves/ShepherdsCrook.cs index 054c53c07..13b1cd9f5 100644 --- a/Projects/UOContent/Items/Weapons/Staves/ShepherdsCrook.cs +++ b/Projects/UOContent/Items/Weapons/Staves/ShepherdsCrook.cs @@ -1,4 +1,5 @@ using System; +using ModernUO.Serialization; using Server.Engines.CannedEvil; using Server.Mobiles; using Server.Network; @@ -7,7 +8,7 @@ using Server.Targeting; namespace Server.Items { [Flippable(0xE81, 0xE82)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class ShepherdsCrook : BaseStaff { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Swords/AdventurersMachete.cs b/Projects/UOContent/Items/Weapons/Swords/AdventurersMachete.cs index 8415307c7..b721a3cb1 100644 --- a/Projects/UOContent/Items/Weapons/Swords/AdventurersMachete.cs +++ b/Projects/UOContent/Items/Weapons/Swords/AdventurersMachete.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class AdventurersMachete : ElvenMachete { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Swords/BaseSword.cs b/Projects/UOContent/Items/Weapons/Swords/BaseSword.cs index 6527c8de8..ffe129d16 100644 --- a/Projects/UOContent/Items/Weapons/Swords/BaseSword.cs +++ b/Projects/UOContent/Items/Weapons/Swords/BaseSword.cs @@ -1,8 +1,9 @@ +using ModernUO.Serialization; using Server.Targets; namespace Server.Items { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public abstract partial class BaseSword : BaseMeleeWeapon { public BaseSword(int itemID) : base(itemID) diff --git a/Projects/UOContent/Items/Weapons/Swords/BloodBlade.cs b/Projects/UOContent/Items/Weapons/Swords/BloodBlade.cs index 4bcf21831..21ba7e61f 100644 --- a/Projects/UOContent/Items/Weapons/Swords/BloodBlade.cs +++ b/Projects/UOContent/Items/Weapons/Swords/BloodBlade.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x8FE, 0x4072)] - [Serializable(0)] + [SerializationGenerator(0)] public partial class BloodBlade : BaseSword { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Swords/BoneHarvester.cs b/Projects/UOContent/Items/Weapons/Swords/BoneHarvester.cs index 6eb52ee86..8c3d9fbd2 100644 --- a/Projects/UOContent/Items/Weapons/Swords/BoneHarvester.cs +++ b/Projects/UOContent/Items/Weapons/Swords/BoneHarvester.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x26BB, 0x26C5)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class BoneHarvester : BaseSword { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Swords/BoneMachete.cs b/Projects/UOContent/Items/Weapons/Swords/BoneMachete.cs index 247dfbb8a..80981472e 100644 --- a/Projects/UOContent/Items/Weapons/Swords/BoneMachete.cs +++ b/Projects/UOContent/Items/Weapons/Swords/BoneMachete.cs @@ -1,8 +1,9 @@ +using ModernUO.Serialization; using Server.Engines.MLQuests.Items; namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class BoneMachete : ElvenMachete, ITicket { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Swords/Broadsword.cs b/Projects/UOContent/Items/Weapons/Swords/Broadsword.cs index 2ed8317af..e980b11ad 100644 --- a/Projects/UOContent/Items/Weapons/Swords/Broadsword.cs +++ b/Projects/UOContent/Items/Weapons/Swords/Broadsword.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0xF5E, 0xF5F)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Broadsword : BaseSword { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Swords/ChargedAssassinSpike.cs b/Projects/UOContent/Items/Weapons/Swords/ChargedAssassinSpike.cs index e71c77e21..1e6aac8fe 100644 --- a/Projects/UOContent/Items/Weapons/Swords/ChargedAssassinSpike.cs +++ b/Projects/UOContent/Items/Weapons/Swords/ChargedAssassinSpike.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class ChargedAssassinSpike : AssassinSpike { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Swords/CorruptedRuneBlade.cs b/Projects/UOContent/Items/Weapons/Swords/CorruptedRuneBlade.cs index 934dd5304..60a0aec08 100644 --- a/Projects/UOContent/Items/Weapons/Swords/CorruptedRuneBlade.cs +++ b/Projects/UOContent/Items/Weapons/Swords/CorruptedRuneBlade.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class CorruptedRuneBlade : RuneBlade { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Swords/CrescentBlade.cs b/Projects/UOContent/Items/Weapons/Swords/CrescentBlade.cs index a20e948b1..7bb7f1470 100644 --- a/Projects/UOContent/Items/Weapons/Swords/CrescentBlade.cs +++ b/Projects/UOContent/Items/Weapons/Swords/CrescentBlade.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x26C1, 0x26CB)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class CrescentBlade : BaseSword { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Swords/Cutlass.cs b/Projects/UOContent/Items/Weapons/Swords/Cutlass.cs index 49782febf..922c1fd04 100644 --- a/Projects/UOContent/Items/Weapons/Swords/Cutlass.cs +++ b/Projects/UOContent/Items/Weapons/Swords/Cutlass.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x1441, 0x1440)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Cutlass : BaseSword { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Swords/DarkglowScimitar.cs b/Projects/UOContent/Items/Weapons/Swords/DarkglowScimitar.cs index e57b39401..9fc2684f3 100644 --- a/Projects/UOContent/Items/Weapons/Swords/DarkglowScimitar.cs +++ b/Projects/UOContent/Items/Weapons/Swords/DarkglowScimitar.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class DarkglowScimitar : RadiantScimitar { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Swords/DiseasedMachete.cs b/Projects/UOContent/Items/Weapons/Swords/DiseasedMachete.cs index e4bacc043..3a21a070f 100644 --- a/Projects/UOContent/Items/Weapons/Swords/DiseasedMachete.cs +++ b/Projects/UOContent/Items/Weapons/Swords/DiseasedMachete.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class DiseasedMachete : ElvenMachete { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Swords/DreadSword.cs b/Projects/UOContent/Items/Weapons/Swords/DreadSword.cs index 9f2df661f..4b628fe20 100644 --- a/Projects/UOContent/Items/Weapons/Swords/DreadSword.cs +++ b/Projects/UOContent/Items/Weapons/Swords/DreadSword.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x90B, 0x4074)] - [Serializable(0)] + [SerializationGenerator(0)] public partial class DreadSword : BaseSword { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Swords/FierySpellblade.cs b/Projects/UOContent/Items/Weapons/Swords/FierySpellblade.cs index ffa064f9e..43428bb9f 100644 --- a/Projects/UOContent/Items/Weapons/Swords/FierySpellblade.cs +++ b/Projects/UOContent/Items/Weapons/Swords/FierySpellblade.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class FierySpellblade : ElvenSpellblade { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Swords/GargishTalwar.cs b/Projects/UOContent/Items/Weapons/Swords/GargishTalwar.cs index 713e684b6..c78c49db2 100644 --- a/Projects/UOContent/Items/Weapons/Swords/GargishTalwar.cs +++ b/Projects/UOContent/Items/Weapons/Swords/GargishTalwar.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x908, 0x4075)] - [Serializable(0)] + [SerializationGenerator(0)] public partial class GargishTalwar : BaseSword { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Swords/GlassSword.cs b/Projects/UOContent/Items/Weapons/Swords/GlassSword.cs index 1bb290332..e821588ab 100644 --- a/Projects/UOContent/Items/Weapons/Swords/GlassSword.cs +++ b/Projects/UOContent/Items/Weapons/Swords/GlassSword.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x90C, 0x4073)] - [Serializable(0)] + [SerializationGenerator(0)] public partial class GlassSword : BaseSword { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Swords/IcyScimitar.cs b/Projects/UOContent/Items/Weapons/Swords/IcyScimitar.cs index 20fb37ac4..8e256e1ab 100644 --- a/Projects/UOContent/Items/Weapons/Swords/IcyScimitar.cs +++ b/Projects/UOContent/Items/Weapons/Swords/IcyScimitar.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class IcyScimitar : RadiantScimitar { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Swords/IcySpellblade.cs b/Projects/UOContent/Items/Weapons/Swords/IcySpellblade.cs index e29c8449d..8b51dcc13 100644 --- a/Projects/UOContent/Items/Weapons/Swords/IcySpellblade.cs +++ b/Projects/UOContent/Items/Weapons/Swords/IcySpellblade.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class IcySpellblade : ElvenSpellblade { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Swords/Katana.cs b/Projects/UOContent/Items/Weapons/Swords/Katana.cs index 80c4507c9..34e4110eb 100644 --- a/Projects/UOContent/Items/Weapons/Swords/Katana.cs +++ b/Projects/UOContent/Items/Weapons/Swords/Katana.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x13FF, 0x13FE)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Katana : BaseSword { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Swords/KnightsWarCleaver.cs b/Projects/UOContent/Items/Weapons/Swords/KnightsWarCleaver.cs index 384fe615f..4533600b8 100644 --- a/Projects/UOContent/Items/Weapons/Swords/KnightsWarCleaver.cs +++ b/Projects/UOContent/Items/Weapons/Swords/KnightsWarCleaver.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class KnightsWarCleaver : WarCleaver { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Swords/Kryss.cs b/Projects/UOContent/Items/Weapons/Swords/Kryss.cs index ff508f726..e6ae7a663 100644 --- a/Projects/UOContent/Items/Weapons/Swords/Kryss.cs +++ b/Projects/UOContent/Items/Weapons/Swords/Kryss.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x1401, 0x1400)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Kryss : BaseSword { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Swords/Lance.cs b/Projects/UOContent/Items/Weapons/Swords/Lance.cs index 71ca9ba82..3520855ca 100644 --- a/Projects/UOContent/Items/Weapons/Swords/Lance.cs +++ b/Projects/UOContent/Items/Weapons/Swords/Lance.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x26C0, 0x26CA)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Lance : BaseSword { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Swords/LeafbladeOfEase.cs b/Projects/UOContent/Items/Weapons/Swords/LeafbladeOfEase.cs index c1aaadace..64859eb2f 100644 --- a/Projects/UOContent/Items/Weapons/Swords/LeafbladeOfEase.cs +++ b/Projects/UOContent/Items/Weapons/Swords/LeafbladeOfEase.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class LeafbladeOfEase : Leafblade { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Swords/Longsword.cs b/Projects/UOContent/Items/Weapons/Swords/Longsword.cs index 039f6fbbb..df3310606 100644 --- a/Projects/UOContent/Items/Weapons/Swords/Longsword.cs +++ b/Projects/UOContent/Items/Weapons/Swords/Longsword.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0xF61, 0xF60)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Longsword : BaseSword { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Swords/Luckblade.cs b/Projects/UOContent/Items/Weapons/Swords/Luckblade.cs index 14d9a0f72..65d2ebd58 100644 --- a/Projects/UOContent/Items/Weapons/Swords/Luckblade.cs +++ b/Projects/UOContent/Items/Weapons/Swords/Luckblade.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class Luckblade : Leafblade { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Swords/MacheteOfDefense.cs b/Projects/UOContent/Items/Weapons/Swords/MacheteOfDefense.cs index 8a06374c9..b4c985370 100644 --- a/Projects/UOContent/Items/Weapons/Swords/MacheteOfDefense.cs +++ b/Projects/UOContent/Items/Weapons/Swords/MacheteOfDefense.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class MacheteOfDefense : ElvenMachete { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Swords/MagekillerAssassinSpike.cs b/Projects/UOContent/Items/Weapons/Swords/MagekillerAssassinSpike.cs index 081a62789..db87b7890 100644 --- a/Projects/UOContent/Items/Weapons/Swords/MagekillerAssassinSpike.cs +++ b/Projects/UOContent/Items/Weapons/Swords/MagekillerAssassinSpike.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class MagekillerAssassinSpike : AssassinSpike { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Swords/MagekillerLeafblade.cs b/Projects/UOContent/Items/Weapons/Swords/MagekillerLeafblade.cs index b65e1c134..66c1fc1af 100644 --- a/Projects/UOContent/Items/Weapons/Swords/MagekillerLeafblade.cs +++ b/Projects/UOContent/Items/Weapons/Swords/MagekillerLeafblade.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class MagekillerLeafblade : Leafblade { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Swords/MagesRuneBlade.cs b/Projects/UOContent/Items/Weapons/Swords/MagesRuneBlade.cs index 2d36fbab8..2b06addb3 100644 --- a/Projects/UOContent/Items/Weapons/Swords/MagesRuneBlade.cs +++ b/Projects/UOContent/Items/Weapons/Swords/MagesRuneBlade.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class MagesRuneBlade : RuneBlade { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Swords/OrcishMachete.cs b/Projects/UOContent/Items/Weapons/Swords/OrcishMachete.cs index 3db06037d..e1da83502 100644 --- a/Projects/UOContent/Items/Weapons/Swords/OrcishMachete.cs +++ b/Projects/UOContent/Items/Weapons/Swords/OrcishMachete.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class OrcishMachete : ElvenMachete { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Swords/RuneBladeOfKnowledge.cs b/Projects/UOContent/Items/Weapons/Swords/RuneBladeOfKnowledge.cs index b98243b02..c9b948cfd 100644 --- a/Projects/UOContent/Items/Weapons/Swords/RuneBladeOfKnowledge.cs +++ b/Projects/UOContent/Items/Weapons/Swords/RuneBladeOfKnowledge.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class RuneBladeOfKnowledge : RuneBlade { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Swords/Runesabre.cs b/Projects/UOContent/Items/Weapons/Swords/Runesabre.cs index ebf11c10e..584355ac3 100644 --- a/Projects/UOContent/Items/Weapons/Swords/Runesabre.cs +++ b/Projects/UOContent/Items/Weapons/Swords/Runesabre.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class Runesabre : RuneBlade { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Swords/Scimitar.cs b/Projects/UOContent/Items/Weapons/Swords/Scimitar.cs index d23458660..d49112d38 100644 --- a/Projects/UOContent/Items/Weapons/Swords/Scimitar.cs +++ b/Projects/UOContent/Items/Weapons/Swords/Scimitar.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x13B6, 0x13B5)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class Scimitar : BaseSword { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Swords/SerratedWarCleaver.cs b/Projects/UOContent/Items/Weapons/Swords/SerratedWarCleaver.cs index 688741bf7..2c94eb4f3 100644 --- a/Projects/UOContent/Items/Weapons/Swords/SerratedWarCleaver.cs +++ b/Projects/UOContent/Items/Weapons/Swords/SerratedWarCleaver.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class SerratedWarCleaver : WarCleaver { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Swords/SpellbladeOfDefense.cs b/Projects/UOContent/Items/Weapons/Swords/SpellbladeOfDefense.cs index 3534d1740..bb68850d2 100644 --- a/Projects/UOContent/Items/Weapons/Swords/SpellbladeOfDefense.cs +++ b/Projects/UOContent/Items/Weapons/Swords/SpellbladeOfDefense.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class SpellbladeOfDefense : ElvenSpellblade { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Swords/ThinLongsword.cs b/Projects/UOContent/Items/Weapons/Swords/ThinLongsword.cs index ee8298272..0e17985ca 100644 --- a/Projects/UOContent/Items/Weapons/Swords/ThinLongsword.cs +++ b/Projects/UOContent/Items/Weapons/Swords/ThinLongsword.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x13B8, 0x13B7)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class ThinLongsword : BaseSword { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Swords/TrueAssassinSpike.cs b/Projects/UOContent/Items/Weapons/Swords/TrueAssassinSpike.cs index dae410257..c701b007b 100644 --- a/Projects/UOContent/Items/Weapons/Swords/TrueAssassinSpike.cs +++ b/Projects/UOContent/Items/Weapons/Swords/TrueAssassinSpike.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class TrueAssassinSpike : AssassinSpike { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Swords/TrueLeafblade.cs b/Projects/UOContent/Items/Weapons/Swords/TrueLeafblade.cs index afbbfbe0c..846966093 100644 --- a/Projects/UOContent/Items/Weapons/Swords/TrueLeafblade.cs +++ b/Projects/UOContent/Items/Weapons/Swords/TrueLeafblade.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class TrueLeafblade : Leafblade { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Swords/TrueRadiantScimitar.cs b/Projects/UOContent/Items/Weapons/Swords/TrueRadiantScimitar.cs index 8442d7b26..6582519bc 100644 --- a/Projects/UOContent/Items/Weapons/Swords/TrueRadiantScimitar.cs +++ b/Projects/UOContent/Items/Weapons/Swords/TrueRadiantScimitar.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class TrueRadiantScimitar : RadiantScimitar { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Swords/TrueSpellblade.cs b/Projects/UOContent/Items/Weapons/Swords/TrueSpellblade.cs index 5079243c3..06430b24a 100644 --- a/Projects/UOContent/Items/Weapons/Swords/TrueSpellblade.cs +++ b/Projects/UOContent/Items/Weapons/Swords/TrueSpellblade.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class TrueSpellblade : ElvenSpellblade { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Swords/TrueWarCleaver.cs b/Projects/UOContent/Items/Weapons/Swords/TrueWarCleaver.cs index 423d995bb..fd5c5c2a7 100644 --- a/Projects/UOContent/Items/Weapons/Swords/TrueWarCleaver.cs +++ b/Projects/UOContent/Items/Weapons/Swords/TrueWarCleaver.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class TrueWarCleaver : WarCleaver { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Swords/TwinklingScimitar.cs b/Projects/UOContent/Items/Weapons/Swords/TwinklingScimitar.cs index bdfee5f2b..eac934560 100644 --- a/Projects/UOContent/Items/Weapons/Swords/TwinklingScimitar.cs +++ b/Projects/UOContent/Items/Weapons/Swords/TwinklingScimitar.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class TwinklingScimitar : RadiantScimitar { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Swords/VikingSword.cs b/Projects/UOContent/Items/Weapons/Swords/VikingSword.cs index 422be352a..83c6f4de9 100644 --- a/Projects/UOContent/Items/Weapons/Swords/VikingSword.cs +++ b/Projects/UOContent/Items/Weapons/Swords/VikingSword.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { [Flippable(0x13B9, 0x13Ba)] - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class VikingSword : BaseSword { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Swords/WoundingAssassinSpike.cs b/Projects/UOContent/Items/Weapons/Swords/WoundingAssassinSpike.cs index fa5615838..96ae8721d 100644 --- a/Projects/UOContent/Items/Weapons/Swords/WoundingAssassinSpike.cs +++ b/Projects/UOContent/Items/Weapons/Swords/WoundingAssassinSpike.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class WoundingAssassinSpike : AssassinSpike { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Wooden/AncientWildStaff.cs b/Projects/UOContent/Items/Weapons/Wooden/AncientWildStaff.cs index d4ef499b6..277599f81 100644 --- a/Projects/UOContent/Items/Weapons/Wooden/AncientWildStaff.cs +++ b/Projects/UOContent/Items/Weapons/Wooden/AncientWildStaff.cs @@ -1,7 +1,9 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class AncientWildStaff : WildStaff { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Wooden/ArcanistsWildStaff.cs b/Projects/UOContent/Items/Weapons/Wooden/ArcanistsWildStaff.cs index d8e14ccd2..19864932e 100644 --- a/Projects/UOContent/Items/Weapons/Wooden/ArcanistsWildStaff.cs +++ b/Projects/UOContent/Items/Weapons/Wooden/ArcanistsWildStaff.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class ArcanistsWildStaff : WildStaff { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Wooden/HardenedWildStaff.cs b/Projects/UOContent/Items/Weapons/Wooden/HardenedWildStaff.cs index 522b719b4..72c251be1 100644 --- a/Projects/UOContent/Items/Weapons/Wooden/HardenedWildStaff.cs +++ b/Projects/UOContent/Items/Weapons/Wooden/HardenedWildStaff.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class HardenedWildStaff : WildStaff { [Constructible] diff --git a/Projects/UOContent/Items/Weapons/Wooden/ThornedWildStaff.cs b/Projects/UOContent/Items/Weapons/Wooden/ThornedWildStaff.cs index 6fc83d763..3f0bdce7f 100644 --- a/Projects/UOContent/Items/Weapons/Wooden/ThornedWildStaff.cs +++ b/Projects/UOContent/Items/Weapons/Wooden/ThornedWildStaff.cs @@ -1,6 +1,8 @@ +using ModernUO.Serialization; + namespace Server.Items { - [Serializable(0)] + [SerializationGenerator(0)] public partial class ThornedWildStaff : WildStaff { [Constructible] diff --git a/Projects/UOContent/Migrations/Server.Items.Aquarium.v4.json b/Projects/UOContent/Migrations/Server.Items.Aquarium.v4.json index 6cd8c06de..142c61178 100644 --- a/Projects/UOContent/Migrations/Server.Items.Aquarium.v4.json +++ b/Projects/UOContent/Migrations/Server.Items.Aquarium.v4.json @@ -31,7 +31,7 @@ "type": "Server.Items.AquariumState", "rule": "RawSerializableMigrationRule", "ruleArguments": [ - "" + "DeserializationRequiresParent" ] }, { @@ -39,7 +39,7 @@ "type": "Server.Items.AquariumState", "rule": "RawSerializableMigrationRule", "ruleArguments": [ - "" + "DeserializationRequiresParent" ] }, { diff --git a/Projects/UOContent/Migrations/Server.Items.BaseArmor.v8.json b/Projects/UOContent/Migrations/Server.Items.BaseArmor.v8.json index c81b88b8f..8ce625193 100644 --- a/Projects/UOContent/Migrations/Server.Items.BaseArmor.v8.json +++ b/Projects/UOContent/Migrations/Server.Items.BaseArmor.v8.json @@ -8,7 +8,7 @@ "usesSaveFlag": true, "rule": "RawSerializableMigrationRule", "ruleArguments": [ - "" + "DeserializationRequiresParent" ] }, { @@ -17,7 +17,7 @@ "usesSaveFlag": true, "rule": "RawSerializableMigrationRule", "ruleArguments": [ - "" + "DeserializationRequiresParent" ] }, { @@ -197,7 +197,7 @@ "usesSaveFlag": true, "rule": "RawSerializableMigrationRule", "ruleArguments": [ - "" + "DeserializationRequiresParent" ] }, { @@ -210,4 +210,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/Projects/UOContent/Migrations/Server.Items.BaseArmor.v9.json b/Projects/UOContent/Migrations/Server.Items.BaseArmor.v9.json index 56579b4a3..2ea3ab105 100644 --- a/Projects/UOContent/Migrations/Server.Items.BaseArmor.v9.json +++ b/Projects/UOContent/Migrations/Server.Items.BaseArmor.v9.json @@ -8,7 +8,7 @@ "usesSaveFlag": true, "rule": "RawSerializableMigrationRule", "ruleArguments": [ - "" + "DeserializationRequiresParent" ] }, { @@ -17,7 +17,7 @@ "usesSaveFlag": true, "rule": "RawSerializableMigrationRule", "ruleArguments": [ - "" + "DeserializationRequiresParent" ] }, { @@ -200,7 +200,7 @@ "usesSaveFlag": true, "rule": "RawSerializableMigrationRule", "ruleArguments": [ - "" + "DeserializationRequiresParent" ] }, { diff --git a/Projects/UOContent/Migrations/Server.Items.BaseClothing.v6.json b/Projects/UOContent/Migrations/Server.Items.BaseClothing.v6.json index c59f0615f..ed16ed9f3 100644 --- a/Projects/UOContent/Migrations/Server.Items.BaseClothing.v6.json +++ b/Projects/UOContent/Migrations/Server.Items.BaseClothing.v6.json @@ -14,7 +14,7 @@ "usesSaveFlag": true, "rule": "RawSerializableMigrationRule", "ruleArguments": [ - "" + "DeserializationRequiresParent" ] }, { @@ -23,7 +23,7 @@ "usesSaveFlag": true, "rule": "RawSerializableMigrationRule", "ruleArguments": [ - "" + "DeserializationRequiresParent" ] }, { @@ -32,7 +32,7 @@ "usesSaveFlag": true, "rule": "RawSerializableMigrationRule", "ruleArguments": [ - "" + "DeserializationRequiresParent" ] }, { @@ -41,7 +41,7 @@ "usesSaveFlag": true, "rule": "RawSerializableMigrationRule", "ruleArguments": [ - "" + "DeserializationRequiresParent" ] }, { @@ -93,4 +93,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/Projects/UOContent/Migrations/Server.Items.BaseClothing.v7.json b/Projects/UOContent/Migrations/Server.Items.BaseClothing.v7.json index ade6ff6cb..0ea558c62 100644 --- a/Projects/UOContent/Migrations/Server.Items.BaseClothing.v7.json +++ b/Projects/UOContent/Migrations/Server.Items.BaseClothing.v7.json @@ -14,7 +14,7 @@ "usesSaveFlag": true, "rule": "RawSerializableMigrationRule", "ruleArguments": [ - "" + "DeserializationRequiresParent" ] }, { @@ -23,7 +23,7 @@ "usesSaveFlag": true, "rule": "RawSerializableMigrationRule", "ruleArguments": [ - "" + "DeserializationRequiresParent" ] }, { @@ -32,7 +32,7 @@ "usesSaveFlag": true, "rule": "RawSerializableMigrationRule", "ruleArguments": [ - "" + "DeserializationRequiresParent" ] }, { @@ -41,7 +41,7 @@ "usesSaveFlag": true, "rule": "RawSerializableMigrationRule", "ruleArguments": [ - "" + "DeserializationRequiresParent" ] }, { diff --git a/Projects/UOContent/Migrations/Server.Items.ElvenGlasses.v0.json b/Projects/UOContent/Migrations/Server.Items.ElvenGlasses.v0.json index e6524c997..8a640dc28 100644 --- a/Projects/UOContent/Migrations/Server.Items.ElvenGlasses.v0.json +++ b/Projects/UOContent/Migrations/Server.Items.ElvenGlasses.v0.json @@ -8,7 +8,7 @@ "usesSaveFlag": true, "rule": "RawSerializableMigrationRule", "ruleArguments": [ - "" + "DeserializationRequiresParent" ] } ] diff --git a/Projects/UOContent/Misc/AOS.cs b/Projects/UOContent/Misc/AOS.cs index 025631871..79e49c57b 100644 --- a/Projects/UOContent/Misc/AOS.cs +++ b/Projects/UOContent/Misc/AOS.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using ModernUO.Serialization; using Server.Items; using Server.Mobiles; using Server.Spells; @@ -1295,7 +1296,7 @@ namespace Server } [PropertyObject] - [EmbeddedSerializable(0)] + [SerializationGenerator(0)] public abstract partial class BaseAttributes { [SerializableField(0, setter: "private")] @@ -1321,9 +1322,9 @@ namespace Server public bool IsEmpty => _names == 0; - [SerializableParent] - private readonly Item _owner; + private Item _owner; + [DirtyTrackingEntity] public Item Owner => _owner; public int GetValue(int bitmask) diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/EvilMage.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/EvilMage.cs index e2929ae18..110365c12 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/EvilMage.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/EvilMage.cs @@ -1,8 +1,9 @@ +using ModernUO.Serialization; using Server.Items; namespace Server.Mobiles { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class EvilMage : BaseCreature { [Constructible] diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/EvilMageLord.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/EvilMageLord.cs index 197f4acd0..14169921b 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/EvilMageLord.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/EvilMageLord.cs @@ -1,8 +1,9 @@ +using ModernUO.Serialization; using Server.Items; namespace Server.Mobiles { - [Serializable(0, false)] + [SerializationGenerator(0, false)] public partial class EvilMageLord : BaseCreature { [Constructible] diff --git a/Projects/UOContent/Spells/Bushido/MomentumStrike.cs b/Projects/UOContent/Spells/Bushido/MomentumStrike.cs index 3fbe7b592..c3b291d01 100644 --- a/Projects/UOContent/Spells/Bushido/MomentumStrike.cs +++ b/Projects/UOContent/Spells/Bushido/MomentumStrike.cs @@ -1,4 +1,3 @@ -using System.Linq; using Server.Collections; namespace Server.Spells.Bushido diff --git a/Projects/UOContent/UOContent.csproj b/Projects/UOContent/UOContent.csproj index 4981eed58..90da5adac 100755 --- a/Projects/UOContent/UOContent.csproj +++ b/Projects/UOContent/UOContent.csproj @@ -38,14 +38,15 @@ false - + - + + From 0565f9076eb6fc5a20369a24875e2180280ba70e Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 17 Apr 2022 08:03:21 -0700 Subject: [PATCH 140/213] Bumps to 0.9.1 to reflect serialization updates. --- version.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.json b/version.json index f1698afbc..ea27bd978 100644 --- a/version.json +++ b/version.json @@ -1,4 +1,4 @@ { "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", - "version": "0.9.0" + "version": "0.9.1" } From dbb75f78a0f26e15fcf70efbcc38665f3f1d2869 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 17 Apr 2022 09:06:24 -0700 Subject: [PATCH 141/213] chore: Deletes ConnectUO support (#999) Looks like connectuo is dead so deleting the support for it. --- Projects/UOContent/Network/ConnectUO.cs | 122 ------------------------ 1 file changed, 122 deletions(-) delete mode 100644 Projects/UOContent/Network/ConnectUO.cs diff --git a/Projects/UOContent/Network/ConnectUO.cs b/Projects/UOContent/Network/ConnectUO.cs deleted file mode 100644 index 12745c420..000000000 --- a/Projects/UOContent/Network/ConnectUO.cs +++ /dev/null @@ -1,122 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright (C) 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: ConnectUO.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System; -using System.Buffers; -using Server.Accounting; -using Server.Logging; -using Server.Text; - -namespace Server.Network -{ - public static class ConnectUO - { - private static readonly ILogger logger = LogFactory.GetLogger(typeof(ConnectUO)); - - public enum ConnectUOServerType - { - RunUO, - ServUO, - UOX3, - POL, - Sphere, - ModernUO - } - - public const byte ConnectUOProtocolVersion = 0; - private const int _connectUOTokenLength = 32; - private const ConnectUOServerType _serverType = ConnectUOServerType.ModernUO; - private static byte[] _token; - - public static void Configure() - { - var enabled = ServerConfiguration.GetOrUpdateSetting("connectuo.enabled", true); - var token = ServerConfiguration.GetOrUpdateSetting("connectuo.token", ""); - - if (enabled) - { - try - { - if (!string.IsNullOrWhiteSpace(token)) - { - if (token.Length != _connectUOTokenLength * 2) - { - throw new Exception("Invalid length for ConnectUO token"); - } - - _token = GC.AllocateUninitializedArray(_connectUOTokenLength); - token.ToUpperInvariant().GetBytes(_token); - } - } - catch - { - logger.Warning("ConnectUO token could not be parsed. Make sure modernuo.json is properly configured"); - _token = null; - } - - FreeshardProtocol.Register(0xC0, false, PollInfo); - } - } - - public static void PollInfo(NetState state, CircularBufferReader reader, int packetLength) - { - var version = reader.ReadByte(); - - if (_token != null) - { - unsafe { - byte* tok = stackalloc byte[_token.Length]; - var span = new Span(tok, _token.Length); - reader.Read(span); - - if (!span.SequenceEqual(_token)) - { - state.Disconnect("Invalid token sent for ConnectUO"); - return; - } - } - } - - state.LogInfo($"ConnectUO (v{version}) is requesting stats."); - if (version > ConnectUOProtocolVersion) - { - Utility.PushColor(ConsoleColor.Yellow); - state.LogInfo("Warning! ConnectUO (v{version}) is newer than what is supported."); - Utility.PopColor(); - } - - state.SendServerPollInfo(); - } - - public static void SendServerPollInfo(this NetState ns) - { - if (ns.CannotSendPackets()) - { - return; - } - - var writer = new SpanWriter(stackalloc byte[15]); - writer.Write((byte)0xC0); // Packet ID - writer.Write((ushort)17); // Length - writer.Write(ConnectUOProtocolVersion); // Version - writer.Write((byte)_serverType); - writer.Write((int)(Core.TickCount / 1000)); - writer.Write(Accounts.Count); // Shame if you modify this! - writer.Write(TcpServer.Instances.Count - 1); // Shame if you modify this! - - ns.Send(writer.Span); - } - } -} From 4bde9a4c863bf9f8e1d8a900007dbe9675f6f8b9 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 17 Apr 2022 16:51:59 -0700 Subject: [PATCH 142/213] fix: Codegens vendor contracts (#1000) --- .../Items/Deeds/VendorRentalContract.cs | 572 +++++++-------- .../Server.Items.VendorRentalContract.v0.json | 30 + .../Server.Mobiles.RentedVendor.v0.json | 62 ++ .../UOContent/Mobiles/Vendors/RentedVendor.cs | 669 +++++++++--------- 4 files changed, 686 insertions(+), 647 deletions(-) create mode 100644 Projects/UOContent/Migrations/Server.Items.VendorRentalContract.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Mobiles.RentedVendor.v0.json diff --git a/Projects/UOContent/Items/Deeds/VendorRentalContract.cs b/Projects/UOContent/Items/Deeds/VendorRentalContract.cs index 6c37f9f55..ea2dc6cfc 100644 --- a/Projects/UOContent/Items/Deeds/VendorRentalContract.cs +++ b/Projects/UOContent/Items/Deeds/VendorRentalContract.cs @@ -1,369 +1,347 @@ using System; using System.Collections.Generic; +using ModernUO.Serialization; using Server.ContextMenus; using Server.Gumps; using Server.Mobiles; using Server.Multis; using Server.Targeting; -namespace Server.Items +namespace Server.Items; + +[SerializationGenerator(0)] +public partial class VendorRentalContract : Item { - public class VendorRentalContract : Item + [SerializableField(0, getter: "private", setter: "private")] + private int _rentalDurationId; // TODO: Replace this with something more robust + + private VendorRentalDuration _duration; + + private Mobile _offeree; + private Timer _offerExpireTimer; + + [SerializableField(1)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private int _price; + + [SerializableField(2)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private bool _landlordRenew; + + [Constructible] + public VendorRentalContract() : base(0x14F0) { - private VendorRentalDuration m_Duration; + Weight = 1.0; + Hue = 0x672; - private Mobile m_Offeree; - private Timer m_OfferExpireTimer; + _duration = VendorRentalDuration.Instances[0]; + Price = 1500; + } - [Constructible] - public VendorRentalContract() : base(0x14F0) + public override int LabelNumber => 1062332; // a vendor rental contract + + public VendorRentalDuration Duration + { + get => _duration; + set { - Weight = 1.0; - Hue = 0x672; - - m_Duration = VendorRentalDuration.Instances[0]; - Price = 1500; - } - - public VendorRentalContract(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1062332; // a vendor rental contract - - public VendorRentalDuration Duration - { - get => m_Duration; - set + if (value != null) { - if (value != null) - { - m_Duration = value; - } + _duration = value; + _rentalDurationId = _duration.ID; + } + } + } + + public Mobile Offeree + { + get => _offeree; + set + { + if (_offerExpireTimer != null) + { + _offerExpireTimer.Stop(); + _offerExpireTimer = null; + } + + _offeree = value; + + if (value != null) + { + _offerExpireTimer = new OfferExpireTimer(this); + _offerExpireTimer.Start(); + } + + InvalidateProperties(); + } + } + + public override void GetProperties(ObjectPropertyList list) + { + base.GetProperties(list); + + if (Offeree != null) + { + list.Add(1062368, Offeree.Name); // Being Offered To ~1_NAME~ + } + } + + public bool IsLandlord(Mobile m) + { + if (IsLockedDown) + { + var house = BaseHouse.FindHouseAt(this); + + if (house != null && house.DecayType != DecayType.Condemned) + { + return house.IsOwner(m); } } - [CommandProperty(AccessLevel.GameMaster)] - public int Price { get; set; } + return false; + } - [CommandProperty(AccessLevel.GameMaster)] - public bool LandlordRenew { get; set; } - - public Mobile Offeree + public bool IsUsableBy(Mobile from, bool byLandlord, bool byBackpack, bool noOfferee, bool sendMessage) + { + if (Deleted || !from.CheckAlive(sendMessage)) { - get => m_Offeree; - set - { - if (m_OfferExpireTimer != null) - { - m_OfferExpireTimer.Stop(); - m_OfferExpireTimer = null; - } - - m_Offeree = value; - - if (value != null) - { - m_OfferExpireTimer = new OfferExpireTimer(this); - m_OfferExpireTimer.Start(); - } - - InvalidateProperties(); - } - } - - public override void GetProperties(ObjectPropertyList list) - { - base.GetProperties(list); - - if (Offeree != null) - { - list.Add(1062368, Offeree.Name); // Being Offered To ~1_NAME~ - } - } - - public bool IsLandlord(Mobile m) - { - if (IsLockedDown) - { - var house = BaseHouse.FindHouseAt(this); - - if (house != null && house.DecayType != DecayType.Condemned) - { - return house.IsOwner(m); - } - } - return false; } - public bool IsUsableBy(Mobile from, bool byLandlord, bool byBackpack, bool noOfferee, bool sendMessage) + if (noOfferee && Offeree != null) { - if (Deleted || !from.CheckAlive(sendMessage)) - { - return false; - } - - if (noOfferee && Offeree != null) - { - if (sendMessage) - { - from.SendLocalizedMessage(1062343); // That item is currently in use. - } - - return false; - } - - if (byBackpack && IsChildOf(from.Backpack)) - { - return true; - } - - if (byLandlord && IsLandlord(from)) - { - if (from.Map != Map || !from.InRange(this, 5)) - { - if (sendMessage) - { - from.SendLocalizedMessage(501853); // Target is too far away. - } - - return false; - } - - return true; - } - - return false; - } - - public override void OnDelete() - { - if (IsLockedDown) - { - var house = BaseHouse.FindHouseAt(this); - - house?.VendorRentalContracts.Remove(this); - } - } - - public override void OnDoubleClick(Mobile from) - { - if (Offeree != null) + if (sendMessage) { from.SendLocalizedMessage(1062343); // That item is currently in use. } - else if (!IsLockedDown) - { - if (!IsChildOf(from.Backpack)) - { - from.SendLocalizedMessage(1062334); // This item must be in your backpack to be used. - return; - } - var house = BaseHouse.FindHouseAt(from); + return false; + } - if (house?.IsOwner(from) != true) - { - from.SendLocalizedMessage( - 1062333 - ); // You must be standing inside of a house that you own to make use of this contract. - } - else if (!house.IsAosRules) - { - from.SendMessage("Rental contracts can only be placed in AOS-enabled houses."); - } - else if (!house.Public) - { - from.SendLocalizedMessage(1062335); // Rental contracts can only be placed in public houses. - } - else if (!house.CanPlaceNewVendor()) - { - from.SendLocalizedMessage(1062352); // You do not have enough storage available to place this contract. - } - else - { - from.SendLocalizedMessage(1062337); // Target the exact location you wish to rent out. - from.Target = new RentTarget(this); - } - } - else if (IsLandlord(from)) + if (byBackpack && IsChildOf(from.Backpack)) + { + return true; + } + + if (byLandlord && IsLandlord(from)) + { + if (from.Map != Map || !from.InRange(this, 5)) { - if (from.InRange(this, 5)) - { - from.CloseGump(); - from.SendGump(new VendorRentalContractGump(this, from)); - } - else + if (sendMessage) { from.SendLocalizedMessage(501853); // Target is too far away. } + + return false; } + + return true; } - public override void GetContextMenuEntries(Mobile from, List list) - { - base.GetContextMenuEntries(from, list); + return false; + } - if (IsUsableBy(from, true, true, true, false)) + public override void OnDelete() + { + if (IsLockedDown) + { + var house = BaseHouse.FindHouseAt(this); + + house?.VendorRentalContracts.Remove(this); + } + } + + public override void OnDoubleClick(Mobile from) + { + if (Offeree != null) + { + from.SendLocalizedMessage(1062343); // That item is currently in use. + } + else if (!IsLockedDown) + { + if (!IsChildOf(from.Backpack)) { - list.Add(new ContractOptionEntry(this)); + from.SendLocalizedMessage(1062334); // This item must be in your backpack to be used. + return; } - } - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); + var house = BaseHouse.FindHouseAt(from); - writer.WriteEncodedInt(0); // version - - writer.WriteEncodedInt(m_Duration.ID); - - writer.Write(Price); - writer.Write(LandlordRenew); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - - var durationID = reader.ReadEncodedInt(); - if (durationID < VendorRentalDuration.Instances.Length) + if (house?.IsOwner(from) != true) { - m_Duration = VendorRentalDuration.Instances[durationID]; + from.SendLocalizedMessage( + 1062333 + ); // You must be standing inside of a house that you own to make use of this contract. + } + else if (!house.IsAosRules) + { + from.SendMessage("Rental contracts can only be placed in AOS-enabled houses."); + } + else if (!house.Public) + { + from.SendLocalizedMessage(1062335); // Rental contracts can only be placed in public houses. + } + else if (!house.CanPlaceNewVendor()) + { + from.SendLocalizedMessage(1062352); // You do not have enough storage available to place this contract. } else { - m_Duration = VendorRentalDuration.Instances[0]; - } - - Price = reader.ReadInt(); - LandlordRenew = reader.ReadBool(); - } - - private class ContractOptionEntry : ContextMenuEntry - { - private readonly VendorRentalContract m_Contract; - - public ContractOptionEntry(VendorRentalContract contract) : base(6209) => m_Contract = contract; - - public override void OnClick() - { - var from = Owner.From; - - if (m_Contract.IsUsableBy(from, true, true, true, true)) - { - from.CloseGump(); - from.SendGump(new VendorRentalContractGump(m_Contract, from)); - } + from.SendLocalizedMessage(1062337); // Target the exact location you wish to rent out. + from.Target = new RentTarget(this); } } - - private class RentTarget : Target + else if (IsLandlord(from)) { - private readonly VendorRentalContract m_Contract; - - public RentTarget(VendorRentalContract contract) : base(-1, false, TargetFlags.None) => m_Contract = contract; - - protected override void OnTarget(Mobile from, object targeted) + if (from.InRange(this, 5)) { - if (!m_Contract.IsUsableBy(from, false, true, true, true)) - { - return; - } + from.CloseGump(); + from.SendGump(new VendorRentalContractGump(this, from)); + } + else + { + from.SendLocalizedMessage(501853); // Target is too far away. + } + } + } - if (targeted is not IPoint3D location) - { - return; - } + public override void GetContextMenuEntries(Mobile from, List list) + { + base.GetContextMenuEntries(from, list); - var pLocation = new Point3D(location); - var map = from.Map; + if (IsUsableBy(from, true, true, true, false)) + { + list.Add(new ContractOptionEntry(this)); + } + } - var house = BaseHouse.FindHouseAt(pLocation, map, 0); + [AfterDeserialization] + private void AfterDeserialization() + { + var index = Math.Clamp(_rentalDurationId, 0, VendorRentalDuration.Instances.Length); + _duration = VendorRentalDuration.Instances[index]; + } - if (house?.IsOwner(from) != true) + private class ContractOptionEntry : ContextMenuEntry + { + private readonly VendorRentalContract m_Contract; + + public ContractOptionEntry(VendorRentalContract contract) : base(6209) => m_Contract = contract; + + public override void OnClick() + { + var from = Owner.From; + + if (m_Contract.IsUsableBy(from, true, true, true, true)) + { + from.CloseGump(); + from.SendGump(new VendorRentalContractGump(m_Contract, from)); + } + } + } + + private class RentTarget : Target + { + private readonly VendorRentalContract m_Contract; + + public RentTarget(VendorRentalContract contract) : base(-1, false, TargetFlags.None) => m_Contract = contract; + + protected override void OnTarget(Mobile from, object targeted) + { + if (!m_Contract.IsUsableBy(from, false, true, true, true)) + { + return; + } + + if (targeted is not IPoint3D location) + { + return; + } + + var pLocation = new Point3D(location); + var map = from.Map; + + var house = BaseHouse.FindHouseAt(pLocation, map, 0); + + if (house?.IsOwner(from) != true) + { + from.SendLocalizedMessage(1062338); // The location being rented out must be inside of your house. + } + else if (BaseHouse.FindHouseAt(from) != house) + { + // You must be located inside of the house in which you are trying to place the contract. + from.SendLocalizedMessage(1062339); + } + else if (!house.IsAosRules) + { + from.SendMessage("Rental contracts can only be placed in AOS-enabled houses."); + } + else if (!house.Public) + { + from.SendLocalizedMessage(1062335); // Rental contracts can only be placed in public houses. + } + else if (house.DecayType == DecayType.Condemned) + { + from.SendLocalizedMessage(1062468); // You cannot place a contract in a condemned house. + } + else if (!house.CanPlaceNewVendor()) + { + from.SendLocalizedMessage(1062352); // You do not have enought storage available to place this contract. + } + else if (!map.CanFit(pLocation, 16, false, false)) + { + from.SendLocalizedMessage(1062486); // A vendor cannot exist at that location. Please try again. + } + else + { + BaseHouse.IsThereVendor(pLocation, map, out var vendor, out var contract); + + if (vendor) { - from.SendLocalizedMessage(1062338); // The location being rented out must be inside of your house. + // You may not place a rental contract at this location while other beings occupy it. + from.SendLocalizedMessage(1062342); } - else if (BaseHouse.FindHouseAt(from) != house) + else if (contract) { - // You must be located inside of the house in which you are trying to place the contract. - from.SendLocalizedMessage(1062339); - } - else if (!house.IsAosRules) - { - from.SendMessage("Rental contracts can only be placed in AOS-enabled houses."); - } - else if (!house.Public) - { - from.SendLocalizedMessage(1062335); // Rental contracts can only be placed in public houses. - } - else if (house.DecayType == DecayType.Condemned) - { - from.SendLocalizedMessage(1062468); // You cannot place a contract in a condemned house. - } - else if (!house.CanPlaceNewVendor()) - { - from.SendLocalizedMessage(1062352); // You do not have enought storage available to place this contract. - } - else if (!map.CanFit(pLocation, 16, false, false)) - { - from.SendLocalizedMessage(1062486); // A vendor cannot exist at that location. Please try again. + // That location is cluttered. Please clear out any objects there and try again. + from.SendLocalizedMessage(1062341); } else { - BaseHouse.IsThereVendor(pLocation, map, out var vendor, out var contract); + m_Contract.MoveToWorld(pLocation, map); - if (vendor) + if (!house.LockDown(from, m_Contract)) { - // You may not place a rental contract at this location while other beings occupy it. - from.SendLocalizedMessage(1062342); - } - else if (contract) - { - // That location is cluttered. Please clear out any objects there and try again. - from.SendLocalizedMessage(1062341); - } - else - { - m_Contract.MoveToWorld(pLocation, map); - - if (!house.LockDown(from, m_Contract)) - { - from.AddToBackpack(m_Contract); - } + from.AddToBackpack(m_Contract); } } } - - protected override void OnTargetCancel(Mobile from, TargetCancelType cancelType) - { - from.SendLocalizedMessage(1062336); // You decide not to place the contract at this time. - } } - private class OfferExpireTimer : Timer + protected override void OnTargetCancel(Mobile from, TargetCancelType cancelType) { - private readonly VendorRentalContract m_Contract; + from.SendLocalizedMessage(1062336); // You decide not to place the contract at this time. + } + } - public OfferExpireTimer(VendorRentalContract contract) : base(TimeSpan.FromSeconds(30.0)) + private class OfferExpireTimer : Timer + { + private readonly VendorRentalContract m_Contract; + + public OfferExpireTimer(VendorRentalContract contract) : base(TimeSpan.FromSeconds(30.0)) + { + m_Contract = contract; + } + + protected override void OnTick() + { + var offeree = m_Contract.Offeree; + + if (offeree != null) { - m_Contract = contract; - } + offeree.CloseGump(); - protected override void OnTick() - { - var offeree = m_Contract.Offeree; - - if (offeree != null) - { - offeree.CloseGump(); - - m_Contract.Offeree = null; - } + m_Contract.Offeree = null; } } } diff --git a/Projects/UOContent/Migrations/Server.Items.VendorRentalContract.v0.json b/Projects/UOContent/Migrations/Server.Items.VendorRentalContract.v0.json new file mode 100644 index 000000000..691547581 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.VendorRentalContract.v0.json @@ -0,0 +1,30 @@ +{ + "version": 0, + "type": "Server.Items.VendorRentalContract", + "properties": [ + { + "name": "RentalDurationId", + "type": "int", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "Price", + "type": "int", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "LandlordRenew", + "type": "bool", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Mobiles.RentedVendor.v0.json b/Projects/UOContent/Migrations/Server.Mobiles.RentedVendor.v0.json new file mode 100644 index 000000000..54f9c360a --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Mobiles.RentedVendor.v0.json @@ -0,0 +1,62 @@ +{ + "version": 0, + "type": "Server.Mobiles.RentedVendor", + "properties": [ + { + "name": "RentalDurationId", + "type": "int", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "RentalPrice", + "type": "int", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "LandlordRenew", + "type": "bool", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "RenterRenew", + "type": "bool", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "RenewalPrice", + "type": "int", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "RentalGold", + "type": "int", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "RentalExpireTime", + "type": "System.DateTime", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "DeltaTime" + ] + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Mobiles/Vendors/RentedVendor.cs b/Projects/UOContent/Mobiles/Vendors/RentedVendor.cs index 10ede3f19..d2192f64e 100644 --- a/Projects/UOContent/Mobiles/Vendors/RentedVendor.cs +++ b/Projects/UOContent/Mobiles/Vendors/RentedVendor.cs @@ -1,390 +1,359 @@ using System; using System.Collections.Generic; +using ModernUO.Serialization; using Server.ContextMenus; using Server.Gumps; using Server.Misc; using Server.Multis; using Server.Prompts; -namespace Server.Mobiles -{ - public class VendorRentalDuration - { - public static readonly VendorRentalDuration[] Instances = - { - new(TimeSpan.FromDays(7.0), 1062361), // 1 Week - new(TimeSpan.FromDays(14.0), 1062362), // 2 Weeks - new(TimeSpan.FromDays(21.0), 1062363), // 3 Weeks - new(TimeSpan.FromDays(28.0), 1062364) // 1 Month - }; +namespace Server.Mobiles; - private VendorRentalDuration(TimeSpan duration, int name) +public class VendorRentalDuration +{ + public static readonly VendorRentalDuration[] Instances = + { + new(TimeSpan.FromDays(7.0), 1062361), // 1 Week + new(TimeSpan.FromDays(14.0), 1062362), // 2 Weeks + new(TimeSpan.FromDays(21.0), 1062363), // 3 Weeks + new(TimeSpan.FromDays(28.0), 1062364) // 1 Month + }; + + private VendorRentalDuration(TimeSpan duration, int name) + { + Duration = duration; + Name = name; + } + + public TimeSpan Duration { get; } + + public int Name { get; } + + public int ID + { + get { - Duration = duration; - Name = name; + for (var i = 0; i < Instances.Length; i++) + { + if (Instances[i] == this) + { + return i; + } + } + + return 0; + } + } +} + +[SerializationGenerator(0)] +public partial class RentedVendor : PlayerVendor +{ + private Timer _rentalExpireTimer; + + public RentedVendor( + Mobile owner, BaseHouse house, VendorRentalDuration duration, int rentalPrice, + bool landlordRenew, int rentalGold + ) : base(owner, house) + { + RentalDuration = duration; + RentalPrice = RenewalPrice = rentalPrice; + LandlordRenew = landlordRenew; + RenterRenew = false; + + RentalGold = rentalGold; + + RentalExpireTime = Core.Now + duration.Duration; + _rentalExpireTimer = new RentalExpireTimer(this, duration.Duration); + _rentalExpireTimer.Start(); + } + + public VendorRentalDuration RentalDuration { get; private set; } + + [SerializableField(0, getter: "private", setter: "private")] + private int _rentalDurationId; // TODO: Replace this with something more robust + + [SerializableField(1)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private int _rentalPrice; + + [SerializableField(2)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private bool _landlordRenew; + + [SerializableField(3)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private bool _renterRenew; + + [SerializableField(4)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private int _renewalPrice; + + [SerializableField(5)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private int _rentalGold; + + [DeltaDateTime] + [SerializableField(6)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private DateTime _rentalExpireTime; + + [CommandProperty(AccessLevel.GameMaster)] + public Mobile Landlord => House?.Owner; + + [CommandProperty(AccessLevel.GameMaster)] + public bool Renew => LandlordRenew && RenterRenew && House != null && House.DecayType != DecayType.Condemned; + + public override bool IsOwner(Mobile m) => m == Owner || m.AccessLevel >= AccessLevel.GameMaster || + Core.ML && AccountHandler.CheckAccount(m, Owner); + + public bool IsLandlord(Mobile m) => House?.IsOwner(m) == true; + + public void ComputeRentalExpireDelay(out int days, out int hours) + { + var delay = RentalExpireTime - Core.Now; + + if (delay <= TimeSpan.Zero) + { + days = 0; + hours = 0; + } + else + { + days = delay.Days; + hours = delay.Hours; + } + } + + public void SendRentalExpireMessage(Mobile to) + { + ComputeRentalExpireDelay(out var days, out var hours); + + to.SendLocalizedMessage( + 1062464, + $"{days}\t{hours}" + ); // The rental contract on this vendor will expire in ~1_DAY~ day(s) and ~2_HOUR~ hour(s). + } + + public override void OnAfterDelete() + { + base.OnAfterDelete(); + + _rentalExpireTimer.Stop(); + } + + public override void Destroy(bool toBackpack) + { + if (RentalGold > 0 && House?.IsAosRules == true) + { + House.MovingCrate ??= new MovingCrate(House); + + Banker.Deposit(House.MovingCrate, RentalGold); + RentalGold = 0; } - public TimeSpan Duration { get; } + base.Destroy(toBackpack); + } - public int Name { get; } - - public int ID + public override void GetContextMenuEntries(Mobile from, List list) + { + if (from.Alive) { - get + if (IsOwner(from)) { - for (var i = 0; i < Instances.Length; i++) + list.Add(new ContractOptionsEntry(this)); + } + else if (IsLandlord(from)) + { + if (RentalGold > 0) { - if (Instances[i] == this) - { - return i; - } + list.Add(new CollectRentEntry(this)); } - return 0; + list.Add(new TerminateContractEntry(this)); + list.Add(new ContractOptionsEntry(this)); + } + } + + base.GetContextMenuEntries(from, list); + } + + [AfterDeserialization] + private void AfterDeserialization() + { + var index = Math.Clamp(_rentalDurationId, 0, VendorRentalDuration.Instances.Length - 1); + RentalDuration = VendorRentalDuration.Instances[index]; + + var delay = _rentalExpireTime - Core.Now; + _rentalExpireTimer = new RentalExpireTimer(this, delay > TimeSpan.Zero ? delay : TimeSpan.Zero).Start(); + } + + private class ContractOptionsEntry : ContextMenuEntry + { + private readonly RentedVendor m_Vendor; + + public ContractOptionsEntry(RentedVendor vendor) : base(6209) => m_Vendor = vendor; + + public override void OnClick() + { + var from = Owner.From; + + if (m_Vendor.Deleted || !from.CheckAlive()) + { + return; + } + + if (m_Vendor.IsOwner(from)) + { + from.CloseGump(); + from.SendGump(new RenterVendorRentalGump(m_Vendor)); + + m_Vendor.SendRentalExpireMessage(from); + } + else if (m_Vendor.IsLandlord(from)) + { + from.CloseGump(); + from.SendGump(new LandlordVendorRentalGump(m_Vendor)); + + m_Vendor.SendRentalExpireMessage(from); } } } - public class RentedVendor : PlayerVendor + private class CollectRentEntry : ContextMenuEntry { - private Timer m_RentalExpireTimer; + private readonly RentedVendor m_Vendor; - public RentedVendor( - Mobile owner, BaseHouse house, VendorRentalDuration duration, int rentalPrice, - bool landlordRenew, int rentalGold - ) : base(owner, house) + public CollectRentEntry(RentedVendor vendor) : base(6212) => m_Vendor = vendor; + + public override void OnClick() { - RentalDuration = duration; - RentalPrice = RenewalPrice = rentalPrice; - LandlordRenew = landlordRenew; - RenterRenew = false; + var from = Owner.From; - RentalGold = rentalGold; - - RentalExpireTime = Core.Now + duration.Duration; - m_RentalExpireTimer = new RentalExpireTimer(this, duration.Duration); - m_RentalExpireTimer.Start(); - } - - public RentedVendor(Serial serial) : base(serial) - { - } - - public VendorRentalDuration RentalDuration { get; private set; } - - [CommandProperty(AccessLevel.GameMaster)] - public int RentalPrice { get; set; } - - [CommandProperty(AccessLevel.GameMaster)] - public bool LandlordRenew { get; set; } - - [CommandProperty(AccessLevel.GameMaster)] - public bool RenterRenew { get; set; } - - [CommandProperty(AccessLevel.GameMaster)] - public bool Renew => LandlordRenew && RenterRenew && House != null && House.DecayType != DecayType.Condemned; - - [CommandProperty(AccessLevel.GameMaster)] - public int RenewalPrice { get; set; } - - [CommandProperty(AccessLevel.GameMaster)] - public int RentalGold { get; set; } - - [CommandProperty(AccessLevel.GameMaster)] - public DateTime RentalExpireTime { get; private set; } - - [CommandProperty(AccessLevel.GameMaster)] - public Mobile Landlord => House?.Owner; - - public override bool IsOwner(Mobile m) => m == Owner || m.AccessLevel >= AccessLevel.GameMaster || - Core.ML && AccountHandler.CheckAccount(m, Owner); - - public bool IsLandlord(Mobile m) => House?.IsOwner(m) == true; - - public void ComputeRentalExpireDelay(out int days, out int hours) - { - var delay = RentalExpireTime - Core.Now; - - if (delay <= TimeSpan.Zero) + if (m_Vendor.Deleted || !from.CheckAlive() || !m_Vendor.IsLandlord(from)) { - days = 0; - hours = 0; - } - else - { - days = delay.Days; - hours = delay.Hours; - } - } - - public void SendRentalExpireMessage(Mobile to) - { - ComputeRentalExpireDelay(out var days, out var hours); - - to.SendLocalizedMessage( - 1062464, - $"{days}\t{hours}" - ); // The rental contract on this vendor will expire in ~1_DAY~ day(s) and ~2_HOUR~ hour(s). - } - - public override void OnAfterDelete() - { - base.OnAfterDelete(); - - m_RentalExpireTimer.Stop(); - } - - public override void Destroy(bool toBackpack) - { - if (RentalGold > 0 && House?.IsAosRules == true) - { - House.MovingCrate ??= new MovingCrate(House); - - Banker.Deposit(House.MovingCrate, RentalGold); - RentalGold = 0; + return; } - base.Destroy(toBackpack); - } - - public override void GetContextMenuEntries(Mobile from, List list) - { - if (from.Alive) + if (m_Vendor.RentalGold > 0) { - if (IsOwner(from)) + var depositedGold = Banker.DepositUpTo(from, m_Vendor.RentalGold); + m_Vendor.RentalGold -= depositedGold; + + if (depositedGold > 0) { - list.Add(new ContractOptionsEntry(this)); - } - else if (IsLandlord(from)) - { - if (RentalGold > 0) - { - list.Add(new CollectRentEntry(this)); - } - - list.Add(new TerminateContractEntry(this)); - list.Add(new ContractOptionsEntry(this)); - } - } - - base.GetContextMenuEntries(from, list); - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - - writer.WriteEncodedInt(RentalDuration.ID); - - writer.Write(RentalPrice); - writer.Write(LandlordRenew); - writer.Write(RenterRenew); - writer.Write(RenewalPrice); - - writer.Write(RentalGold); - - writer.WriteDeltaTime(RentalExpireTime); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - - var durationID = reader.ReadEncodedInt(); - if (durationID < VendorRentalDuration.Instances.Length) - { - RentalDuration = VendorRentalDuration.Instances[durationID]; - } - else - { - RentalDuration = VendorRentalDuration.Instances[0]; - } - - RentalPrice = reader.ReadInt(); - LandlordRenew = reader.ReadBool(); - RenterRenew = reader.ReadBool(); - RenewalPrice = reader.ReadInt(); - - RentalGold = reader.ReadInt(); - - RentalExpireTime = reader.ReadDeltaTime(); - - var delay = RentalExpireTime - Core.Now; - m_RentalExpireTimer = new RentalExpireTimer(this, delay > TimeSpan.Zero ? delay : TimeSpan.Zero); - m_RentalExpireTimer.Start(); - } - - private class ContractOptionsEntry : ContextMenuEntry - { - private readonly RentedVendor m_Vendor; - - public ContractOptionsEntry(RentedVendor vendor) : base(6209) => m_Vendor = vendor; - - public override void OnClick() - { - var from = Owner.From; - - if (m_Vendor.Deleted || !from.CheckAlive()) - { - return; - } - - if (m_Vendor.IsOwner(from)) - { - from.CloseGump(); - from.SendGump(new RenterVendorRentalGump(m_Vendor)); - - m_Vendor.SendRentalExpireMessage(from); - } - else if (m_Vendor.IsLandlord(from)) - { - from.CloseGump(); - from.SendGump(new LandlordVendorRentalGump(m_Vendor)); - - m_Vendor.SendRentalExpireMessage(from); - } - } - } - - private class CollectRentEntry : ContextMenuEntry - { - private readonly RentedVendor m_Vendor; - - public CollectRentEntry(RentedVendor vendor) : base(6212) => m_Vendor = vendor; - - public override void OnClick() - { - var from = Owner.From; - - if (m_Vendor.Deleted || !from.CheckAlive() || !m_Vendor.IsLandlord(from)) - { - return; + from.SendLocalizedMessage( + 1060397, + depositedGold.ToString() + ); // ~1_AMOUNT~ gold has been deposited into your bank box. } if (m_Vendor.RentalGold > 0) { - var depositedGold = Banker.DepositUpTo(from, m_Vendor.RentalGold); - m_Vendor.RentalGold -= depositedGold; - - if (depositedGold > 0) - { - from.SendLocalizedMessage( - 1060397, - depositedGold.ToString() - ); // ~1_AMOUNT~ gold has been deposited into your bank box. - } - - if (m_Vendor.RentalGold > 0) - { - from.SendLocalizedMessage(500390); // Your bank box is full. - } - } - } - } - - private class TerminateContractEntry : ContextMenuEntry - { - private readonly RentedVendor m_Vendor; - - public TerminateContractEntry(RentedVendor vendor) : base(6218) => m_Vendor = vendor; - - public override void OnClick() - { - var from = Owner.From; - - if (m_Vendor.Deleted || !from.CheckAlive() || !m_Vendor.IsLandlord(from)) - { - return; - } - - from.SendLocalizedMessage( - 1062503 - ); // Enter the amount of gold you wish to offer the renter in exchange for immediate termination of this contract? - from.Prompt = new RefundOfferPrompt(m_Vendor); - } - } - - private class RefundOfferPrompt : Prompt - { - private readonly RentedVendor m_Vendor; - - public RefundOfferPrompt(RentedVendor vendor) => m_Vendor = vendor; - - public override void OnResponse(Mobile from, string text) - { - if (!m_Vendor.CanInteractWith(from, false) || !m_Vendor.IsLandlord(from)) - { - return; - } - - text = text.Trim(); - - if (!int.TryParse(text, out var amount)) - { - amount = -1; - } - - var owner = m_Vendor.Owner; - if (owner == null) - { - return; - } - - if (amount < 0) - { - from.SendLocalizedMessage(1062506); // You did not enter a valid amount. Offer canceled. - } - else if (Banker.GetBalance(from) < amount) - { - from.SendLocalizedMessage(1062507); // You do not have that much money in your bank account. - } - else if (owner.Map != m_Vendor.Map || !owner.InRange(m_Vendor, 5)) - { - from.SendLocalizedMessage( - 1062505 - ); // The renter must be closer to the vendor in order for you to make this offer. - } - else - { - from.SendLocalizedMessage(1062504); // Please wait while the renter considers your offer. - - owner.CloseGump(); - owner.SendGump(new VendorRentalRefundGump(m_Vendor, from, amount)); - } - } - } - - private class RentalExpireTimer : Timer - { - private readonly RentedVendor m_Vendor; - - public RentalExpireTimer(RentedVendor vendor, TimeSpan delay) : base(delay, vendor.RentalDuration.Duration) - { - m_Vendor = vendor; - } - - protected override void OnTick() - { - var renewalPrice = m_Vendor.RenewalPrice; - - if (m_Vendor.Renew && m_Vendor.HoldGold >= renewalPrice) - { - m_Vendor.HoldGold -= renewalPrice; - m_Vendor.RentalGold += renewalPrice; - - m_Vendor.RentalPrice = renewalPrice; - - m_Vendor.RentalExpireTime = Core.Now + m_Vendor.RentalDuration.Duration; - } - else - { - m_Vendor.Destroy(false); + from.SendLocalizedMessage(500390); // Your bank box is full. } } } } + + private class TerminateContractEntry : ContextMenuEntry + { + private readonly RentedVendor m_Vendor; + + public TerminateContractEntry(RentedVendor vendor) : base(6218) => m_Vendor = vendor; + + public override void OnClick() + { + var from = Owner.From; + + if (m_Vendor.Deleted || !from.CheckAlive() || !m_Vendor.IsLandlord(from)) + { + return; + } + + from.SendLocalizedMessage( + 1062503 + ); // Enter the amount of gold you wish to offer the renter in exchange for immediate termination of this contract? + from.Prompt = new RefundOfferPrompt(m_Vendor); + } + } + + private class RefundOfferPrompt : Prompt + { + private readonly RentedVendor m_Vendor; + + public RefundOfferPrompt(RentedVendor vendor) => m_Vendor = vendor; + + public override void OnResponse(Mobile from, string text) + { + if (!m_Vendor.CanInteractWith(from, false) || !m_Vendor.IsLandlord(from)) + { + return; + } + + text = text.Trim(); + + if (!int.TryParse(text, out var amount)) + { + amount = -1; + } + + var owner = m_Vendor.Owner; + if (owner == null) + { + return; + } + + if (amount < 0) + { + from.SendLocalizedMessage(1062506); // You did not enter a valid amount. Offer canceled. + } + else if (Banker.GetBalance(from) < amount) + { + from.SendLocalizedMessage(1062507); // You do not have that much money in your bank account. + } + else if (owner.Map != m_Vendor.Map || !owner.InRange(m_Vendor, 5)) + { + from.SendLocalizedMessage( + 1062505 + ); // The renter must be closer to the vendor in order for you to make this offer. + } + else + { + from.SendLocalizedMessage(1062504); // Please wait while the renter considers your offer. + + owner.CloseGump(); + owner.SendGump(new VendorRentalRefundGump(m_Vendor, from, amount)); + } + } + } + + private class RentalExpireTimer : Timer + { + private readonly RentedVendor m_Vendor; + + public RentalExpireTimer(RentedVendor vendor, TimeSpan delay) : base(delay, vendor.RentalDuration.Duration) + { + m_Vendor = vendor; + } + + protected override void OnTick() + { + var renewalPrice = m_Vendor.RenewalPrice; + + if (m_Vendor.Renew && m_Vendor.HoldGold >= renewalPrice) + { + m_Vendor.HoldGold -= renewalPrice; + m_Vendor.RentalGold += renewalPrice; + + m_Vendor.RentalPrice = renewalPrice; + + m_Vendor.RentalExpireTime = Core.Now + m_Vendor.RentalDuration.Duration; + } + else + { + m_Vendor.Destroy(false); + } + } + } } From 933c41070fe4b38324ee5ca3b01a55d9f2eddd63 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 17 Apr 2022 17:10:45 -0700 Subject: [PATCH 143/213] fix: Codegens farmables (#1001) --- .../Items/Farming/FarmableCabbage.cs | 55 +++----- .../UOContent/Items/Farming/FarmableCarrot.cs | 55 +++----- .../UOContent/Items/Farming/FarmableCotton.cs | 44 ++----- .../UOContent/Items/Farming/FarmableCrop.cs | 122 ++++++++---------- .../UOContent/Items/Farming/FarmableFlax.cs | 55 +++----- .../Items/Farming/FarmableLettuce.cs | 55 +++----- .../UOContent/Items/Farming/FarmableOnion.cs | 55 +++----- .../Items/Farming/FarmablePumpkin.cs | 58 +++------ .../UOContent/Items/Farming/FarmableTurnip.cs | 55 +++----- .../UOContent/Items/Farming/FarmableWheat.cs | 44 ++----- .../Server.Items.FarmableCabbage.v0.json | 4 + .../Server.Items.FarmableCarrot.v0.json | 4 + .../Server.Items.FarmableCotton.v0.json | 4 + .../Server.Items.FarmableCrop.v0.json | 14 ++ .../Server.Items.FarmableFlax.v0.json | 4 + .../Server.Items.FarmableLettuce.v0.json | 4 + .../Server.Items.FarmableOnion.v0.json | 4 + .../Server.Items.FarmablePumpkin.v0.json | 4 + .../Server.Items.FarmableTurnip.v0.json | 4 + .../Server.Items.FarmableWheat.v0.json | 4 + 20 files changed, 256 insertions(+), 392 deletions(-) create mode 100644 Projects/UOContent/Migrations/Server.Items.FarmableCabbage.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.FarmableCarrot.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.FarmableCotton.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.FarmableCrop.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.FarmableFlax.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.FarmableLettuce.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.FarmableOnion.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.FarmablePumpkin.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.FarmableTurnip.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.FarmableWheat.v0.json diff --git a/Projects/UOContent/Items/Farming/FarmableCabbage.cs b/Projects/UOContent/Items/Farming/FarmableCabbage.cs index f9fb4563b..3b4e32d59 100644 --- a/Projects/UOContent/Items/Farming/FarmableCabbage.cs +++ b/Projects/UOContent/Items/Farming/FarmableCabbage.cs @@ -1,41 +1,22 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0)] +public partial class FarmableCabbage : FarmableCrop { - public class FarmableCabbage : FarmableCrop + [Constructible] + public FarmableCabbage() : base(GetCropID()) { - [Constructible] - public FarmableCabbage() : base(GetCropID()) - { - } - - public FarmableCabbage(Serial serial) : base(serial) - { - } - - public static int GetCropID() => 3254; - - public override Item GetCropObject() - { - var cabbage = new Cabbage(); - - cabbage.ItemID = Utility.Random(3195, 2); - - return cabbage; - } - - public override int GetPickedID() => 3254; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } + + public static int GetCropID() => 3254; + + public override Item GetCropObject() => + new Cabbage + { + ItemID = Utility.Random(3195, 2) + }; + + public override int GetPickedID() => 3254; } diff --git a/Projects/UOContent/Items/Farming/FarmableCarrot.cs b/Projects/UOContent/Items/Farming/FarmableCarrot.cs index 5c4e79f5d..41c3e1c7a 100644 --- a/Projects/UOContent/Items/Farming/FarmableCarrot.cs +++ b/Projects/UOContent/Items/Farming/FarmableCarrot.cs @@ -1,41 +1,22 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0)] +public partial class FarmableCarrot : FarmableCrop { - public class FarmableCarrot : FarmableCrop + [Constructible] + public FarmableCarrot() : base(GetCropID()) { - [Constructible] - public FarmableCarrot() : base(GetCropID()) - { - } - - public FarmableCarrot(Serial serial) : base(serial) - { - } - - public static int GetCropID() => 3190; - - public override Item GetCropObject() - { - var carrot = new Carrot(); - - carrot.ItemID = Utility.Random(3191, 2); - - return carrot; - } - - public override int GetPickedID() => 3254; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } + + public static int GetCropID() => 3190; + + public override Item GetCropObject() => + new Carrot + { + ItemID = Utility.Random(3191, 2) + }; + + public override int GetPickedID() => 3254; } diff --git a/Projects/UOContent/Items/Farming/FarmableCotton.cs b/Projects/UOContent/Items/Farming/FarmableCotton.cs index f4ff49e08..1ec1e5b16 100644 --- a/Projects/UOContent/Items/Farming/FarmableCotton.cs +++ b/Projects/UOContent/Items/Farming/FarmableCotton.cs @@ -1,34 +1,18 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0)] +public partial class FarmableCotton : FarmableCrop { - public class FarmableCotton : FarmableCrop + [Constructible] + public FarmableCotton() : base(GetCropID()) { - [Constructible] - public FarmableCotton() : base(GetCropID()) - { - } - - public FarmableCotton(Serial serial) : base(serial) - { - } - - public static int GetCropID() => Utility.Random(3153, 4); - - public override Item GetCropObject() => new Cotton(); - - public override int GetPickedID() => 3254; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } + + public static int GetCropID() => Utility.Random(3153, 4); + + public override Item GetCropObject() => new Cotton(); + + public override int GetPickedID() => 3254; } diff --git a/Projects/UOContent/Items/Farming/FarmableCrop.cs b/Projects/UOContent/Items/Farming/FarmableCrop.cs index 5ec0340f6..5f0bfa56e 100644 --- a/Projects/UOContent/Items/Farming/FarmableCrop.cs +++ b/Projects/UOContent/Items/Farming/FarmableCrop.cs @@ -1,91 +1,71 @@ using System; +using ModernUO.Serialization; using Server.Network; -namespace Server.Items +namespace Server.Items; + +[SerializationGenerator(0)] +public abstract partial class FarmableCrop : Item { - public abstract class FarmableCrop : Item + [SerializableField(0)] + private bool _picked; + + public FarmableCrop(int itemID) : base(itemID) => Movable = false; + + public abstract Item GetCropObject(); + public abstract int GetPickedID(); + + public override void OnDoubleClick(Mobile from) { - private bool m_Picked; + var map = Map; + var loc = Location; - public FarmableCrop(int itemID) : base(itemID) => Movable = false; - - public FarmableCrop(Serial serial) : base(serial) + if (Parent != null || Movable || IsLockedDown || IsSecure || map == null || map == Map.Internal) { + return; } - public abstract Item GetCropObject(); - public abstract int GetPickedID(); - - public override void OnDoubleClick(Mobile from) + if (!from.InRange(loc, 2) || !from.InLOS(this)) { - var map = Map; - var loc = Location; - - if (Parent != null || Movable || IsLockedDown || IsSecure || map == null || map == Map.Internal) - { - return; - } - - if (!from.InRange(loc, 2) || !from.InLOS(this)) - { - from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that. - } - else if (!m_Picked) - { - OnPicked(from, loc, map); - } + from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that. } - - public virtual void OnPicked(Mobile from, Point3D loc, Map map) + else if (!_picked) { - ItemID = GetPickedID(); + OnPicked(from, loc, map); + } + } - var spawn = GetCropObject(); + public virtual void OnPicked(Mobile from, Point3D loc, Map map) + { + ItemID = GetPickedID(); - spawn?.MoveToWorld(loc, map); + var spawn = GetCropObject(); - m_Picked = true; + spawn?.MoveToWorld(loc, map); + _picked = true; + + Unlink(); + + Timer.StartTimer(TimeSpan.FromMinutes(5.0), Delete); + } + + public void Unlink() + { + if (Spawner != null) + { + Spawner.Remove(this); + Spawner = null; + } + } + + [AfterDeserialization] + private void AfterDeserialization() + { + if (_picked) + { Unlink(); - - Timer.StartTimer(TimeSpan.FromMinutes(5.0), Delete); - } - - public void Unlink() - { - if (Spawner != null) - { - Spawner.Remove(this); - Spawner = null; - } - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - - writer.Write(m_Picked); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - - m_Picked = version switch - { - 0 => reader.ReadBool(), - _ => m_Picked - }; - - if (m_Picked) - { - Unlink(); - Delete(); - } + Delete(); } } } diff --git a/Projects/UOContent/Items/Farming/FarmableFlax.cs b/Projects/UOContent/Items/Farming/FarmableFlax.cs index e698b6560..5dd7fe755 100644 --- a/Projects/UOContent/Items/Farming/FarmableFlax.cs +++ b/Projects/UOContent/Items/Farming/FarmableFlax.cs @@ -1,41 +1,22 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0)] +public partial class FarmableFlax : FarmableCrop { - public class FarmableFlax : FarmableCrop + [Constructible] + public FarmableFlax() : base(GetCropID()) { - [Constructible] - public FarmableFlax() : base(GetCropID()) - { - } - - public FarmableFlax(Serial serial) : base(serial) - { - } - - public static int GetCropID() => Utility.Random(6809, 3); - - public override Item GetCropObject() - { - var flax = new Flax(); - - flax.ItemID = Utility.Random(6812, 2); - - return flax; - } - - public override int GetPickedID() => 3254; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } + + public static int GetCropID() => Utility.Random(6809, 3); + + public override Item GetCropObject() => + new Flax + { + ItemID = Utility.Random(6812, 2) + }; + + public override int GetPickedID() => 3254; } diff --git a/Projects/UOContent/Items/Farming/FarmableLettuce.cs b/Projects/UOContent/Items/Farming/FarmableLettuce.cs index bc930b824..d443acf9f 100644 --- a/Projects/UOContent/Items/Farming/FarmableLettuce.cs +++ b/Projects/UOContent/Items/Farming/FarmableLettuce.cs @@ -1,41 +1,22 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0)] +public partial class FarmableLettuce : FarmableCrop { - public class FarmableLettuce : FarmableCrop + [Constructible] + public FarmableLettuce() : base(GetCropID()) { - [Constructible] - public FarmableLettuce() : base(GetCropID()) - { - } - - public FarmableLettuce(Serial serial) : base(serial) - { - } - - public static int GetCropID() => 3254; - - public override Item GetCropObject() - { - var lettuce = new Lettuce(); - - lettuce.ItemID = Utility.Random(3184, 2); - - return lettuce; - } - - public override int GetPickedID() => 3254; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } + + public static int GetCropID() => 3254; + + public override Item GetCropObject() => + new Lettuce + { + ItemID = Utility.Random(3184, 2) + }; + + public override int GetPickedID() => 3254; } diff --git a/Projects/UOContent/Items/Farming/FarmableOnion.cs b/Projects/UOContent/Items/Farming/FarmableOnion.cs index 22d86df48..66921dda7 100644 --- a/Projects/UOContent/Items/Farming/FarmableOnion.cs +++ b/Projects/UOContent/Items/Farming/FarmableOnion.cs @@ -1,41 +1,22 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0)] +public partial class FarmableOnion : FarmableCrop { - public class FarmableOnion : FarmableCrop + [Constructible] + public FarmableOnion() : base(GetCropID()) { - [Constructible] - public FarmableOnion() : base(GetCropID()) - { - } - - public FarmableOnion(Serial serial) : base(serial) - { - } - - public static int GetCropID() => 3183; - - public override Item GetCropObject() - { - var onion = new Onion(); - - onion.ItemID = Utility.Random(3181, 2); - - return onion; - } - - public override int GetPickedID() => 3254; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } + + public static int GetCropID() => 3183; + + public override Item GetCropObject() => + new Onion + { + ItemID = Utility.Random(3181, 2) + }; + + public override int GetPickedID() => 3254; } diff --git a/Projects/UOContent/Items/Farming/FarmablePumpkin.cs b/Projects/UOContent/Items/Farming/FarmablePumpkin.cs index dc6c0f4be..986345e84 100644 --- a/Projects/UOContent/Items/Farming/FarmablePumpkin.cs +++ b/Projects/UOContent/Items/Farming/FarmablePumpkin.cs @@ -1,43 +1,23 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0)] +public partial class FarmablePumpkin : FarmableCrop { - public class FarmablePumpkin : FarmableCrop + [Constructible] + public FarmablePumpkin() + : base(GetCropID()) { - [Constructible] - public FarmablePumpkin() - : base(GetCropID()) - { - } - - public FarmablePumpkin(Serial serial) - : base(serial) - { - } - - public static int GetCropID() => Utility.Random(3166, 3); - - public override Item GetCropObject() - { - var pumpkin = new Pumpkin(); - - pumpkin.ItemID = Utility.Random(3178, 3); - - return pumpkin; - } - - public override int GetPickedID() => Utility.Random(3166, 3); - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } + + public static int GetCropID() => Utility.Random(3166, 3); + + public override Item GetCropObject() => + new Pumpkin + { + ItemID = Utility.Random(3178, 3) + }; + + public override int GetPickedID() => Utility.Random(3166, 3); } diff --git a/Projects/UOContent/Items/Farming/FarmableTurnip.cs b/Projects/UOContent/Items/Farming/FarmableTurnip.cs index eec9facbd..94fc10733 100644 --- a/Projects/UOContent/Items/Farming/FarmableTurnip.cs +++ b/Projects/UOContent/Items/Farming/FarmableTurnip.cs @@ -1,41 +1,22 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0)] +public partial class FarmableTurnip : FarmableCrop { - public class FarmableTurnip : FarmableCrop + [Constructible] + public FarmableTurnip() : base(GetCropID()) { - [Constructible] - public FarmableTurnip() : base(GetCropID()) - { - } - - public FarmableTurnip(Serial serial) : base(serial) - { - } - - public static int GetCropID() => Utility.Random(3169, 3); - - public override Item GetCropObject() - { - var turnip = new Turnip(); - - turnip.ItemID = Utility.Random(3385, 2); - - return turnip; - } - - public override int GetPickedID() => 3254; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } + + public static int GetCropID() => Utility.Random(3169, 3); + + public override Item GetCropObject() => + new Turnip + { + ItemID = Utility.Random(3385, 2) + }; + + public override int GetPickedID() => 3254; } diff --git a/Projects/UOContent/Items/Farming/FarmableWheat.cs b/Projects/UOContent/Items/Farming/FarmableWheat.cs index d3fcbf109..f15d9b21e 100644 --- a/Projects/UOContent/Items/Farming/FarmableWheat.cs +++ b/Projects/UOContent/Items/Farming/FarmableWheat.cs @@ -1,34 +1,18 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0)] +public partial class FarmableWheat : FarmableCrop { - public class FarmableWheat : FarmableCrop + [Constructible] + public FarmableWheat() : base(GetCropID()) { - [Constructible] - public FarmableWheat() : base(GetCropID()) - { - } - - public FarmableWheat(Serial serial) : base(serial) - { - } - - public static int GetCropID() => Utility.Random(3157, 4); - - public override Item GetCropObject() => new WheatSheaf(); - - public override int GetPickedID() => Utility.Random(3502, 2); - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } + + public static int GetCropID() => Utility.Random(3157, 4); + + public override Item GetCropObject() => new WheatSheaf(); + + public override int GetPickedID() => Utility.Random(3502, 2); } diff --git a/Projects/UOContent/Migrations/Server.Items.FarmableCabbage.v0.json b/Projects/UOContent/Migrations/Server.Items.FarmableCabbage.v0.json new file mode 100644 index 000000000..8776b3e00 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.FarmableCabbage.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.FarmableCabbage" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.FarmableCarrot.v0.json b/Projects/UOContent/Migrations/Server.Items.FarmableCarrot.v0.json new file mode 100644 index 000000000..77b6c7539 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.FarmableCarrot.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.FarmableCarrot" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.FarmableCotton.v0.json b/Projects/UOContent/Migrations/Server.Items.FarmableCotton.v0.json new file mode 100644 index 000000000..7f44351fa --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.FarmableCotton.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.FarmableCotton" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.FarmableCrop.v0.json b/Projects/UOContent/Migrations/Server.Items.FarmableCrop.v0.json new file mode 100644 index 000000000..72bd19707 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.FarmableCrop.v0.json @@ -0,0 +1,14 @@ +{ + "version": 0, + "type": "Server.Items.FarmableCrop", + "properties": [ + { + "name": "Picked", + "type": "bool", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.FarmableFlax.v0.json b/Projects/UOContent/Migrations/Server.Items.FarmableFlax.v0.json new file mode 100644 index 000000000..738e26776 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.FarmableFlax.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.FarmableFlax" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.FarmableLettuce.v0.json b/Projects/UOContent/Migrations/Server.Items.FarmableLettuce.v0.json new file mode 100644 index 000000000..7377cd821 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.FarmableLettuce.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.FarmableLettuce" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.FarmableOnion.v0.json b/Projects/UOContent/Migrations/Server.Items.FarmableOnion.v0.json new file mode 100644 index 000000000..9e83694b8 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.FarmableOnion.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.FarmableOnion" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.FarmablePumpkin.v0.json b/Projects/UOContent/Migrations/Server.Items.FarmablePumpkin.v0.json new file mode 100644 index 000000000..5a3efdfb0 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.FarmablePumpkin.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.FarmablePumpkin" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.FarmableTurnip.v0.json b/Projects/UOContent/Migrations/Server.Items.FarmableTurnip.v0.json new file mode 100644 index 000000000..476ee5fec --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.FarmableTurnip.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.FarmableTurnip" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.FarmableWheat.v0.json b/Projects/UOContent/Migrations/Server.Items.FarmableWheat.v0.json new file mode 100644 index 000000000..c91c597d5 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.FarmableWheat.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.FarmableWheat" +} \ No newline at end of file From fc3d9b926d10b771eecaf6f212109f19386bdf8f Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Mon, 18 Apr 2022 00:05:44 -0700 Subject: [PATCH 144/213] fix: Adds Poison to codegen (#1002) --- .config/dotnet-tools.json | 2 +- Projects/Server/Mobiles/Mobile.cs | 4 +- Projects/Server/Poison.cs | 30 ----- .../Server/Serialization/IRawSerializable.cs | 23 ---- .../Serialization/SerializationExtensions.cs | 118 ++++++++++++++++++ Projects/Server/Server.csproj | 2 +- Projects/Server/World/World.cs | 94 -------------- Projects/UOContent/Items/Food/Beverage.cs | 4 +- Projects/UOContent/Items/Food/Food.cs | 6 +- .../Items/Skill Items/Ninjitsu/Fukiya.cs | 4 +- .../Items/Skill Items/Ninjitsu/FukiyaDarts.cs | 4 +- .../Skill Items/Ninjitsu/LeatherNinjaBelt.cs | 4 +- .../Items/Skill Items/Ninjitsu/Shuriken.cs | 4 +- Projects/UOContent/Items/Traps/GasTrap.cs | 4 +- .../UOContent/Items/Weapons/BaseWeapon.cs | 6 +- Projects/UOContent/UOContent.csproj | 2 +- 16 files changed, 140 insertions(+), 171 deletions(-) delete mode 100644 Projects/Server/Serialization/IRawSerializable.cs create mode 100644 Projects/Server/Serialization/SerializationExtensions.cs diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 524152c71..2074240b9 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "modernuoschemagenerator": { - "version": "2.0.3", + "version": "2.0.4", "commands": [ "ModernUOSchemaGenerator" ] diff --git a/Projects/Server/Mobiles/Mobile.cs b/Projects/Server/Mobiles/Mobile.cs index b348f1041..91737ff4f 100644 --- a/Projects/Server/Mobiles/Mobile.cs +++ b/Projects/Server/Mobiles/Mobile.cs @@ -2571,8 +2571,6 @@ namespace Server writer.Write(DisarmReady); writer.Write(StunReady); - // Poison.Serialize( m_Poison, writer ); - writer.Write(m_StatCap); writer.Write(NameHue); @@ -6386,7 +6384,7 @@ namespace Server { if (version <= 25) { - Poison.Deserialize(reader); + reader.ReadPoison(); } goto case 3; diff --git a/Projects/Server/Poison.cs b/Projects/Server/Poison.cs index e9ddee248..f309370a5 100644 --- a/Projects/Server/Poison.cs +++ b/Projects/Server/Poison.cs @@ -76,35 +76,5 @@ namespace Server return null; } - - public static void Serialize(Poison p, IGenericWriter writer) - { - if (p == null) - { - writer.Write((byte)0); - } - else - { - writer.Write((byte)1); - writer.Write((byte)p.Level); - } - } - - public static Poison Deserialize(IGenericReader reader) - { - switch (reader.ReadByte()) - { - case 1: return GetPoison(reader.ReadByte()); - case 2: - // no longer used, safe to remove? - reader.ReadInt(); - reader.ReadDouble(); - reader.ReadInt(); - reader.ReadTimeSpan(); - break; - } - - return null; - } } } diff --git a/Projects/Server/Serialization/IRawSerializable.cs b/Projects/Server/Serialization/IRawSerializable.cs deleted file mode 100644 index 731b56bd0..000000000 --- a/Projects/Server/Serialization/IRawSerializable.cs +++ /dev/null @@ -1,23 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: IRawSerializable.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -namespace Server -{ - public interface IRawSerializable - { - void Deserialize(IGenericReader reader); - void Serialize(IGenericWriter writer); - } -} diff --git a/Projects/Server/Serialization/SerializationExtensions.cs b/Projects/Server/Serialization/SerializationExtensions.cs new file mode 100644 index 000000000..a9d6d94a2 --- /dev/null +++ b/Projects/Server/Serialization/SerializationExtensions.cs @@ -0,0 +1,118 @@ +using System; +using System.Collections.Generic; +using Server.Guilds; + +namespace Server; + +public static class SerializationExtensions +{ + public static T ReadEntity(this IGenericReader reader) where T : class, ISerializable + { + Serial serial = reader.ReadSerial(); + var typeT = typeof(T); + + T entity; + + // Add to this list when creating new serializable types + if (typeof(BaseGuild).IsAssignableFrom(typeT)) + { + entity = World.FindGuild(serial) as T; + // If we check for `entity.Deleted` here during deserialization then all guilds are deleted because + // Deleted -> Disbanded -> No leader, which is the case before deserialization. + // TODO: Use a deleted flag instead, and actively check for dibanded guilds properly. + } + else + { + entity = World.FindEntity(serial) as T; + if (entity?.Deleted == false) + { + return entity; + } + } + + return entity?.Created <= reader.LastSerialized ? entity : null; + } + + public static List ReadEntityList(this IGenericReader reader) where T : class, ISerializable + { + var count = reader.ReadInt(); + + var list = new List(count); + + for (var i = 0; i < count; ++i) + { + var entity = reader.ReadEntity(); + if (entity != null) + { + list.Add(entity); + } + } + + return list; + } + + public static HashSet ReadEntitySet(this IGenericReader reader) where T : class, ISerializable + { + var count = reader.ReadInt(); + + var set = new HashSet(count); + + for (var i = 0; i < count; ++i) + { + var entity = reader.ReadEntity(); + if (entity != null) + { + set.Add(entity); + } + } + + return set; + } + + public static void Write(this IGenericWriter writer, ISerializable value) + { + writer.Write(value?.Deleted != false ? Serial.MinusOne : value.Serial); + } + + public static void Write(this IGenericWriter writer, ICollection coll) where T : class, ISerializable + { + writer.Write(coll.Count); + foreach (var entry in coll) + { + writer.Write(entry); + } + } + + public static void Write( + this IGenericWriter writer, ICollection coll, Action action + ) where T : class, ISerializable + { + if (coll == null) + { + writer.Write(0); + return; + } + + writer.Write(coll.Count); + foreach (var entry in coll) + { + action(writer, entry); + } + } + + public static void Write(this IGenericWriter writer, Poison p) + { + if (p == null) + { + writer.Write(false); + } + else + { + writer.Write(true); + writer.Write((byte)p.Level); + } + } + + public static Poison ReadPoison(this IGenericReader reader) => + reader.ReadBool() ? Poison.GetPoison(reader.ReadByte()) : null; +} diff --git a/Projects/Server/Server.csproj b/Projects/Server/Server.csproj index 68191b6ec..a77dac609 100755 --- a/Projects/Server/Server.csproj +++ b/Projects/Server/Server.csproj @@ -39,7 +39,7 @@ - + diff --git a/Projects/Server/World/World.cs b/Projects/Server/World/World.cs index 119555733..cb2606918 100644 --- a/Projects/Server/World/World.cs +++ b/Projects/Server/World/World.cs @@ -657,99 +657,5 @@ namespace Server [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void RemoveGuild(BaseGuild guild) => Guilds.Remove(guild.Serial); - - public static T ReadEntity(this IGenericReader reader) where T : class, ISerializable - { - Serial serial = reader.ReadSerial(); - var typeT = typeof(T); - - T entity; - - // Add to this list when creating new serializable types - if (typeof(BaseGuild).IsAssignableFrom(typeT)) - { - entity = FindGuild(serial) as T; - // If we check for `entity.Deleted` here during deserialization then all guilds are deleted because - // Deleted -> Disbanded -> No leader, which is the case before deserialization. - // TODO: Use a deleted flag instead, and actively check for dibanded guilds properly. - } - else - { - entity = FindEntity(serial) as T; - if (entity?.Deleted == false) - { - return entity; - } - } - - return entity?.Created <= reader.LastSerialized ? entity : null; - } - - public static List ReadEntityList(this IGenericReader reader) where T : class, ISerializable - { - var count = reader.ReadInt(); - - var list = new List(count); - - for (var i = 0; i < count; ++i) - { - var entity = reader.ReadEntity(); - if (entity != null) - { - list.Add(entity); - } - } - - return list; - } - - public static HashSet ReadEntitySet(this IGenericReader reader) where T : class, ISerializable - { - var count = reader.ReadInt(); - - var set = new HashSet(count); - - for (var i = 0; i < count; ++i) - { - var entity = reader.ReadEntity(); - if (entity != null) - { - set.Add(entity); - } - } - - return set; - } - - public static void Write(this IGenericWriter writer, ISerializable value) - { - writer.Write(value?.Deleted != false ? Serial.MinusOne : value.Serial); - } - - public static void Write(this IGenericWriter writer, ICollection coll) where T : class, ISerializable - { - writer.Write(coll.Count); - foreach (var entry in coll) - { - writer.Write(entry); - } - } - - public static void Write( - this IGenericWriter writer, ICollection coll, Action action - ) where T : class, ISerializable - { - if (coll == null) - { - writer.Write(0); - return; - } - - writer.Write(coll.Count); - foreach (var entry in coll) - { - action(writer, entry); - } - } } } diff --git a/Projects/UOContent/Items/Food/Beverage.cs b/Projects/UOContent/Items/Food/Beverage.cs index 91edd8426..49280cbe8 100644 --- a/Projects/UOContent/Items/Food/Beverage.cs +++ b/Projects/UOContent/Items/Food/Beverage.cs @@ -1101,7 +1101,7 @@ namespace Server.Items writer.Write(Poisoner); - Poison.Serialize(Poison, writer); + writer.Write(Poison); writer.Write((int)m_Content); writer.Write(m_Quantity); } @@ -1133,7 +1133,7 @@ namespace Server.Items } case 0: { - Poison = Poison.Deserialize(reader); + Poison = reader.ReadPoison(); m_Content = (BeverageType)reader.ReadInt(); m_Quantity = reader.ReadInt(); break; diff --git a/Projects/UOContent/Items/Food/Food.cs b/Projects/UOContent/Items/Food/Food.cs index 7049c0a22..b976c8e6f 100644 --- a/Projects/UOContent/Items/Food/Food.cs +++ b/Projects/UOContent/Items/Food/Food.cs @@ -142,7 +142,7 @@ namespace Server.Items writer.Write(Poisoner); - Poison.Serialize(Poison, writer); + writer.Write(Poison); writer.Write(FillFactor); } @@ -170,12 +170,12 @@ namespace Server.Items } case 2: { - Poison = Poison.Deserialize(reader); + Poison = reader.ReadPoison(); break; } case 3: { - Poison = Poison.Deserialize(reader); + Poison = reader.ReadPoison(); FillFactor = reader.ReadInt(); break; } diff --git a/Projects/UOContent/Items/Skill Items/Ninjitsu/Fukiya.cs b/Projects/UOContent/Items/Skill Items/Ninjitsu/Fukiya.cs index fbc502329..45b78a979 100644 --- a/Projects/UOContent/Items/Skill Items/Ninjitsu/Fukiya.cs +++ b/Projects/UOContent/Items/Skill Items/Ninjitsu/Fukiya.cs @@ -123,7 +123,7 @@ namespace Server.Items writer.Write(m_UsesRemaining); - Poison.Serialize(m_Poison, writer); + writer.Write(m_Poison); writer.Write(m_PoisonCharges); } @@ -139,7 +139,7 @@ namespace Server.Items { m_UsesRemaining = reader.ReadInt(); - m_Poison = Poison.Deserialize(reader); + m_Poison = reader.ReadPoison(); m_PoisonCharges = reader.ReadInt(); break; diff --git a/Projects/UOContent/Items/Skill Items/Ninjitsu/FukiyaDarts.cs b/Projects/UOContent/Items/Skill Items/Ninjitsu/FukiyaDarts.cs index 77624e823..858e9c1a7 100644 --- a/Projects/UOContent/Items/Skill Items/Ninjitsu/FukiyaDarts.cs +++ b/Projects/UOContent/Items/Skill Items/Ninjitsu/FukiyaDarts.cs @@ -93,7 +93,7 @@ namespace Server.Items writer.Write(m_UsesRemaining); - Poison.Serialize(m_Poison, writer); + writer.Write(m_Poison); writer.Write(m_PoisonCharges); } @@ -109,7 +109,7 @@ namespace Server.Items { m_UsesRemaining = reader.ReadInt(); - m_Poison = Poison.Deserialize(reader); + m_Poison = reader.ReadPoison(); m_PoisonCharges = reader.ReadInt(); break; diff --git a/Projects/UOContent/Items/Skill Items/Ninjitsu/LeatherNinjaBelt.cs b/Projects/UOContent/Items/Skill Items/Ninjitsu/LeatherNinjaBelt.cs index e93abc6e8..5e58cc004 100644 --- a/Projects/UOContent/Items/Skill Items/Ninjitsu/LeatherNinjaBelt.cs +++ b/Projects/UOContent/Items/Skill Items/Ninjitsu/LeatherNinjaBelt.cs @@ -136,7 +136,7 @@ namespace Server.Items writer.Write(m_UsesRemaining); - Poison.Serialize(m_Poison, writer); + writer.Write(m_Poison); writer.Write(m_PoisonCharges); } @@ -152,7 +152,7 @@ namespace Server.Items { m_UsesRemaining = reader.ReadInt(); - m_Poison = Poison.Deserialize(reader); + m_Poison = reader.ReadPoison(); m_PoisonCharges = reader.ReadInt(); break; diff --git a/Projects/UOContent/Items/Skill Items/Ninjitsu/Shuriken.cs b/Projects/UOContent/Items/Skill Items/Ninjitsu/Shuriken.cs index d87751222..5f07c665f 100644 --- a/Projects/UOContent/Items/Skill Items/Ninjitsu/Shuriken.cs +++ b/Projects/UOContent/Items/Skill Items/Ninjitsu/Shuriken.cs @@ -94,7 +94,7 @@ namespace Server.Items writer.Write(m_UsesRemaining); - Poison.Serialize(m_Poison, writer); + writer.Write(m_Poison); writer.Write(m_PoisonCharges); } @@ -110,7 +110,7 @@ namespace Server.Items { m_UsesRemaining = reader.ReadInt(); - m_Poison = Poison.Deserialize(reader); + m_Poison = reader.ReadPoison(); m_PoisonCharges = reader.ReadInt(); break; diff --git a/Projects/UOContent/Items/Traps/GasTrap.cs b/Projects/UOContent/Items/Traps/GasTrap.cs index 8e07d5646..656a38617 100644 --- a/Projects/UOContent/Items/Traps/GasTrap.cs +++ b/Projects/UOContent/Items/Traps/GasTrap.cs @@ -85,7 +85,7 @@ namespace Server.Items writer.Write(0); // version - Poison.Serialize(Poison, writer); + writer.Write(Poison); } public override void Deserialize(IGenericReader reader) @@ -98,7 +98,7 @@ namespace Server.Items { case 0: { - Poison = Poison.Deserialize(reader); + Poison = reader.ReadPoison(); break; } } diff --git a/Projects/UOContent/Items/Weapons/BaseWeapon.cs b/Projects/UOContent/Items/Weapons/BaseWeapon.cs index 43b45990c..ad0bf9863 100644 --- a/Projects/UOContent/Items/Weapons/BaseWeapon.cs +++ b/Projects/UOContent/Items/Weapons/BaseWeapon.cs @@ -3614,7 +3614,7 @@ namespace Server.Items if (GetSaveFlag(flags, SaveFlag.Poison)) { - Poison.Serialize(m_Poison, writer); + writer.Write(m_Poison); } if (GetSaveFlag(flags, SaveFlag.PoisonCharges)) @@ -3797,7 +3797,7 @@ namespace Server.Items if (GetSaveFlag(flags, SaveFlag.Poison)) { - m_Poison = Poison.Deserialize(reader); + m_Poison = reader.ReadPoison(); } if (GetSaveFlag(flags, SaveFlag.PoisonCharges)) @@ -4057,7 +4057,7 @@ namespace Server.Items m_Crafter = reader.ReadEntity(); - m_Poison = Poison.Deserialize(reader); + m_Poison = reader.ReadPoison(); m_PoisonCharges = reader.ReadInt(); if (m_StrReq == OldStrengthReq) diff --git a/Projects/UOContent/UOContent.csproj b/Projects/UOContent/UOContent.csproj index 90da5adac..024d9bd98 100755 --- a/Projects/UOContent/UOContent.csproj +++ b/Projects/UOContent/UOContent.csproj @@ -46,7 +46,7 @@ - + From 3a0f2b0b9016250f7fe63074c44b78c30f8bc1c1 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Mon, 18 Apr 2022 15:01:13 -0700 Subject: [PATCH 145/213] fix: Fixes cutting cloth (#1003) --- .../UOContent/Items/Clothing/BaseClothing.cs | 32 ++++++++++++------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/Projects/UOContent/Items/Clothing/BaseClothing.cs b/Projects/UOContent/Items/Clothing/BaseClothing.cs index 02af85c53..e993de5ed 100644 --- a/Projects/UOContent/Items/Clothing/BaseClothing.cs +++ b/Projects/UOContent/Items/Clothing/BaseClothing.cs @@ -271,25 +271,33 @@ namespace Server.Items var item = system.CraftItems.SearchFor(GetType()); - if (item?.Resources.Count == 1 && item.Resources[0].Amount >= 2) + if (item?.Resources.Count == 1) { - try + var resource = item.Resources[0]; + if (resource.Amount >= 2) { - var info = CraftResources.GetInfo(_rawResource); + try + { + var info = CraftResources.GetInfo(_rawResource); - var resourceType = info.ResourceTypes?[0] ?? item.Resources[0].ItemType; + Type resourceType = null; + if (info?.ResourceTypes.Length > 0) + { + resourceType = info.ResourceTypes[0]; + } - var res = resourceType.CreateInstance(); + var res = (resourceType ?? resource.ItemType).CreateInstance(); - ScissorHelper(from, res, PlayerConstructed ? item.Resources[0].Amount / 2 : 1); + ScissorHelper(from, res, PlayerConstructed ? resource.Amount / 2 : 1); - res.LootType = LootType.Regular; + res.LootType = LootType.Regular; - return true; - } - catch - { - // ignored + return true; + } + catch + { + // ignored + } } } From f2275cb65b3c73858b5ac8cfdf4f4071614d10de Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Tue, 19 Apr 2022 00:34:02 -0700 Subject: [PATCH 146/213] fix: Adds OnBeforeDisconnected and BeforeDisconnected eventsink (#1004) --- Projects/Server/Events/EventSink.cs | 3 +++ Projects/Server/Mobiles/Mobile.cs | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/Projects/Server/Events/EventSink.cs b/Projects/Server/Events/EventSink.cs index 9e168c742..29f8fda70 100644 --- a/Projects/Server/Events/EventSink.cs +++ b/Projects/Server/Events/EventSink.cs @@ -64,6 +64,9 @@ namespace Server public static event Action Connected; public static void InvokeConnected(Mobile m) => Connected?.Invoke(m); + public static event Action BeforeDisconnected; + public static void InvokeBeforeDisconnected(Mobile m) => BeforeDisconnected?.Invoke(m); + public static event Action Disconnected; public static void InvokeDisconnected(Mobile m) => Disconnected?.Invoke(m); diff --git a/Projects/Server/Mobiles/Mobile.cs b/Projects/Server/Mobiles/Mobile.cs index 91737ff4f..1c69579c7 100644 --- a/Projects/Server/Mobiles/Mobile.cs +++ b/Projects/Server/Mobiles/Mobile.cs @@ -1464,6 +1464,9 @@ namespace Server box.Close(); } + OnBeforeDisconnected(); + EventSink.InvokeBeforeDisconnected(this); + m_NetState = value; _logoutTimerToken.Cancel(); @@ -7195,6 +7198,10 @@ namespace Server { } + public virtual void OnBeforeDisconnected() + { + } + public virtual void OnDisconnected() { } From 848db6fc4b1ef75569028b17bbca2c5766c028ba Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Tue, 19 Apr 2022 14:23:10 -0700 Subject: [PATCH 147/213] fix: Fixes mount blocking and adds permanent option for customization (#1005) --- Projects/UOContent/Mobiles/PlayerMobile.cs | 36 ++++++++++++------- .../UOContent/Spells/Ninjitsu/AnimalForm.cs | 3 +- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/Projects/UOContent/Mobiles/PlayerMobile.cs b/Projects/UOContent/Mobiles/PlayerMobile.cs index 3e9895002..c8f0e000c 100644 --- a/Projects/UOContent/Mobiles/PlayerMobile.cs +++ b/Projects/UOContent/Mobiles/PlayerMobile.cs @@ -181,7 +181,7 @@ namespace Server.Mobiles private DateTime m_LastYoungMessage = DateTime.MinValue; private TimeSpan m_LongTermElapse; - private MountBlock m_MountBlock; + private MountBlock _mountBlock; private DateTime m_NextJustAward; @@ -240,7 +240,7 @@ namespace Server.Mobiles public DesignContext DesignContext { get; set; } - public BlockMountType MountBlockReason => CheckBlock(m_MountBlock) ? m_MountBlock.m_Type : BlockMountType.None; + public BlockMountType MountBlockReason => _mountBlock?.MountBlockReason ?? BlockMountType.None; public override int MaxWeight => (Core.ML && Race == Race.Human ? 100 : 40) + (int)(3.5 * Str); @@ -394,7 +394,7 @@ namespace Server.Mobiles public bool NinjaWepCooldown { get; set; } - public List AllFollowers => m_AllFollowers ?? (m_AllFollowers = new List()); + public List AllFollowers => m_AllFollowers ??= new List(); public RankDefinition GuildRank { @@ -1102,8 +1102,8 @@ namespace Server.Mobiles } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static bool CheckBlock(MountBlock block) => block?._timerToken.Running == true; + public void SetMountBlock(BlockMountType type, bool dismount) => + SetMountBlock(type, TimeSpan.MaxValue, dismount); public void SetMountBlock(BlockMountType type, TimeSpan duration, bool dismount) { @@ -1119,9 +1119,10 @@ namespace Server.Mobiles } } - if (!CheckBlock(m_MountBlock) || m_MountBlock._timerToken.Next < Core.Now + duration) + if (!_mountBlock.CheckBlock() || _mountBlock.Expiration < Core.Now + duration) { - m_MountBlock = new MountBlock(duration, type, this); + _mountBlock?.RemoveBlock(this); + _mountBlock = new MountBlock(duration, type, this); } } @@ -4634,21 +4635,30 @@ namespace Server.Mobiles private class MountBlock { - public TimerExecutionToken _timerToken; - public readonly BlockMountType m_Type; + private TimerExecutionToken _timerToken; + private BlockMountType _type; public MountBlock(TimeSpan duration, BlockMountType type, Mobile mobile) { - m_Type = type; + _type = type; - Timer.StartTimer(duration, () => RemoveBlock(mobile), out _timerToken); + if (duration < TimeSpan.MaxValue) + { + Timer.StartTimer(duration, () => RemoveBlock(mobile), out _timerToken); + } } - private void RemoveBlock(Mobile mobile) + public DateTime Expiration => _timerToken.Next; + + public BlockMountType MountBlockReason => CheckBlock() ? _type : BlockMountType.None; + + public bool CheckBlock() => _timerToken.Next == DateTime.MinValue || _timerToken.Running; + + public void RemoveBlock(Mobile mobile) { if (mobile is PlayerMobile pm) { - pm.m_MountBlock = null; + pm._mountBlock = null; } _timerToken.Cancel(); diff --git a/Projects/UOContent/Spells/Ninjitsu/AnimalForm.cs b/Projects/UOContent/Spells/Ninjitsu/AnimalForm.cs index 1d9cc9ccd..680718eb5 100644 --- a/Projects/UOContent/Spells/Ninjitsu/AnimalForm.cs +++ b/Projects/UOContent/Spells/Ninjitsu/AnimalForm.cs @@ -589,8 +589,7 @@ namespace Server.Spells.Ninjitsu m_LastTarget = m_Mobile.Combatant; } - if (m_Mobile.Warmode && m_LastTarget?.Alive == true && m_LastTarget?.Deleted != true && - m_Counter-- <= 0) + if (m_Mobile.Warmode && m_LastTarget is { Alive: true, Deleted: false } && m_Counter-- <= 0) { if (m_Mobile.CanBeHarmful(m_LastTarget) && m_LastTarget.Map == m_Mobile.Map && m_LastTarget.InRange(m_Mobile.Location, BaseCreature.DefaultRangePerception) && From 0f304d77c41d8d3e2e5643177937767cc485d8b9 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Tue, 19 Apr 2022 17:25:38 -0700 Subject: [PATCH 148/213] fix: Fixes CAGLoader NPE (#1006) --- .../Commands/Object Creation/CAGLoader.cs | 139 ++++++++++-------- 1 file changed, 76 insertions(+), 63 deletions(-) diff --git a/Projects/UOContent/Commands/Object Creation/CAGLoader.cs b/Projects/UOContent/Commands/Object Creation/CAGLoader.cs index 47c54071f..bb3329264 100644 --- a/Projects/UOContent/Commands/Object Creation/CAGLoader.cs +++ b/Projects/UOContent/Commands/Object Creation/CAGLoader.cs @@ -20,78 +20,82 @@ using System.Text.Json; using System.Text.Json.Serialization; using Server.Items; using Server.Json; +using Server.Logging; using Server.Utilities; -namespace Server.Commands +namespace Server.Commands; + +public static class CAGLoader { - public static class CAGLoader + private static readonly ILogger logger = LogFactory.GetLogger(typeof(CAGLoader)); + + public static CAGCategory Load() { - public static CAGCategory Load() + var root = new CAGCategory("Add Menu"); + var path = Path.Combine(Core.BaseDirectory, "Data/categorization.json"); + + var list = JsonConfig.Deserialize>(path); + if (list == null) { - var root = new CAGCategory("Add Menu"); - var path = Path.Combine(Core.BaseDirectory, "Data/categorization.json"); + throw new JsonException($"Failed to deserialize {path}."); + } - var list = JsonConfig.Deserialize>(path); - if (list == null) + // Not an optimized solution + foreach (var cag in list) + { + var parent = root; + // Navigate through the dot notation categories until we find the last one + var categories = cag.Category.Split("."); + for (var i = 0; i < categories.Length; i++) { - throw new JsonException($"Failed to deserialize {path}."); - } + var category = categories[i]; - // Not an optimized solution - foreach (var cag in list) - { - var parent = root; - // Navigate through the dot notation categories until we find the last one - var categories = cag.Category.Split("."); - for (var i = 0; i < categories.Length; i++) + // No children, so let's make one + if (parent.Nodes == null) { - var category = categories[i]; + var cat = new CAGCategory(category, parent); + parent.Nodes = new CAGNode[] { cat }; + parent = cat; + continue; + } - // No children, so let's make one - if (parent.Nodes == null) + var oldParent = parent; + for (var j = 0; j < parent.Nodes.Length; j++) + { + var node = parent.Nodes[j]; + if (category == node.Title && node is CAGCategory cat) { - var cat = new CAGCategory(category, parent); - parent.Nodes = new CAGNode[] { cat }; - parent = cat; - continue; - } - - var oldParent = parent; - for (var j = 0; j < parent.Nodes.Length; j++) - { - var node = parent.Nodes[j]; - if (category == node.Title && node is CAGCategory cat) - { - parent = cat; - break; - } - } - - // Didn't find the child, let's add it - if (oldParent == parent) - { - var nodes = parent.Nodes; - parent.Nodes = new CAGNode[nodes.Length + 1]; - Array.Copy(nodes, parent.Nodes, nodes.Length); - var cat = new CAGCategory(category, parent); - parent.Nodes[^1] = cat; parent = cat; + break; } } - // Set the objects associated with the child most node - parent.Nodes = new CAGNode[cag.Objects.Length]; - for (var i = 0; i < cag.Objects.Length; i++) + // Didn't find the child, let's add it + if (oldParent == parent) { - var cagObj = cag.Objects[i]; - cagObj.Parent = parent; - parent.Nodes[i] = cagObj; + var nodes = parent.Nodes; + parent.Nodes = new CAGNode[nodes.Length + 1]; + Array.Copy(nodes, parent.Nodes, nodes.Length); + var cat = new CAGCategory(category, parent); + parent.Nodes[^1] = cat; + parent = cat; + } + } - // Set ItemID and Hue - if (cagObj.Hue == null || cagObj.ItemID == null) + // Set the objects associated with the child most node + var pooledList = new List(cag.Objects.Length); + for (var i = 0; i < cag.Objects.Length; i++) + { + var cagObj = cag.Objects[i]; + cagObj.Parent = parent; + + // Set ItemID and Hue + if (cagObj.Hue == null || cagObj.ItemID == null) + { + var type = cagObj.Type; + + try { - var type = cagObj.Type; - if (type.IsAssignableTo(typeof(Item))) { var item = cagObj.Type.CreateInstance(); @@ -138,19 +142,28 @@ namespace Server.Commands m.Delete(); } } + catch (Exception e) + { + logger.Warning(e, "Failed to instantiate type {Type}.", type); + continue; + } } + + pooledList.Add(cagObj); } - return root; + parent.Nodes = pooledList.ToArray(); } - } - public record CAGJson - { - [JsonPropertyName("category")] - public string Category { get; init; } - - [JsonPropertyName("objects")] - public CAGObject[] Objects { get; init; } + return root; } } + +public record CAGJson +{ + [JsonPropertyName("category")] + public string Category { get; init; } + + [JsonPropertyName("objects")] + public CAGObject[] Objects { get; init; } +} From d1a3c9b0c7d7c621da24fa554f4f88a10e7547c1 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Tue, 26 Apr 2022 12:27:45 -0700 Subject: [PATCH 149/213] fix: Removes dummy mobiles (#1007) --- Distribution/Data/categorization.json | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/Distribution/Data/categorization.json b/Distribution/Data/categorization.json index 6eff0b152..229014caa 100644 --- a/Distribution/Data/categorization.json +++ b/Distribution/Data/categorization.json @@ -3337,7 +3337,6 @@ { "type": "DiseasedCat" }, { "type": "Doppleganger" }, { "type": "Drithen" }, - { "type": "DummyThief" }, { "type": "Efreet" }, { "type": "ElderAbbein" }, { "type": "ElderAcob" }, @@ -3630,19 +3629,6 @@ { "type": "SeaSerpent" } ] }, - { - "category": "Mobiles.Dummies", - "objects": [ - { "type": "DummyAssassin" }, - { "type": "DummyFence" }, - { "type": "DummyHealer" }, - { "type": "DummyMace" }, - { "type": "DummyNox" }, - { "type": "DummyStun" }, - { "type": "DummySuper" }, - { "type": "DummySword" } - ] - }, { "category": "Mobiles.Escortables", "objects": [ From 8f1240d25ee6d994fe17d6bc063d2912e777c41d Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 1 May 2022 18:35:42 -0700 Subject: [PATCH 150/213] fix: Fixes expansion flags for animations (#1009) --- Distribution/Data/expansion.json | 64 ++++--------------- Projects/Server/ExpansionInfo.cs | 33 ++-------- .../Server/Json/Converters/FlagsConverter.cs | 7 +- .../Network/Packets/OutgoingAccountPackets.cs | 5 ++ 4 files changed, 29 insertions(+), 80 deletions(-) diff --git a/Distribution/Data/expansion.json b/Distribution/Data/expansion.json index 90be17229..a89041813 100644 --- a/Distribution/Data/expansion.json +++ b/Distribution/Data/expansion.json @@ -4,7 +4,6 @@ "ClientVersion": null, "ClientFlags": null, "FeatureFlags": { - "None": true, "T2A": false, "UOR": false, "UOTD": false, @@ -31,7 +30,6 @@ "EJ": false }, "CharacterListFlags": { - "None": true, "Unk1": false, "OverwriteConfigButton": false, "OneCharacterSlot": false, @@ -50,7 +48,6 @@ "NewFeluccaAreas": false }, "HousingFlags": { - "None": true, "AOS": false, "SE": false, "ML": false, @@ -70,7 +67,6 @@ "ClientVersion": null, "ClientFlags": "Felucca", "FeatureFlags": { - "None": false, "T2A": true, "UOR": false, "UOTD": false, @@ -97,7 +93,6 @@ "EJ": false }, "CharacterListFlags": { - "None": false, "Unk1": false, "OverwriteConfigButton": false, "OneCharacterSlot": false, @@ -116,7 +111,6 @@ "NewFeluccaAreas": false }, "HousingFlags": { - "None": true, "AOS": false, "SE": false, "ML": false, @@ -136,7 +130,6 @@ "ClientVersion": null, "ClientFlags": "Trammel", "FeatureFlags": { - "None": false, "T2A": true, "UOR": true, "UOTD": false, @@ -163,7 +156,6 @@ "EJ": false }, "CharacterListFlags": { - "None": false, "Unk1": false, "OverwriteConfigButton": false, "OneCharacterSlot": false, @@ -182,7 +174,6 @@ "NewFeluccaAreas": false }, "HousingFlags": { - "None": true, "AOS": false, "SE": false, "ML": false, @@ -202,7 +193,6 @@ "ClientVersion": null, "ClientFlags": "Ilshenar", "FeatureFlags": { - "None": false, "T2A": true, "UOR": true, "UOTD": true, @@ -229,7 +219,6 @@ "EJ": false }, "CharacterListFlags": { - "None": false, "Unk1": false, "OverwriteConfigButton": false, "OneCharacterSlot": false, @@ -248,7 +237,6 @@ "NewFeluccaAreas": false }, "HousingFlags": { - "None": true, "AOS": false, "SE": false, "ML": false, @@ -268,7 +256,6 @@ "ClientVersion": null, "ClientFlags": "Ilshenar", "FeatureFlags": { - "None": false, "T2A": true, "UOR": true, "UOTD": true, @@ -295,7 +282,6 @@ "EJ": false }, "CharacterListFlags": { - "None": false, "Unk1": false, "OverwriteConfigButton": false, "OneCharacterSlot": false, @@ -314,7 +300,6 @@ "NewFeluccaAreas": false }, "HousingFlags": { - "None": true, "AOS": false, "SE": false, "ML": false, @@ -334,9 +319,8 @@ "ClientVersion": null, "ClientFlags": "Malas", "FeatureFlags": { - "None": false, - "T2A": false, - "UOR": false, + "T2A": true, + "UOR": true, "UOTD": false, "LBR": true, "AOS": true, @@ -361,7 +345,6 @@ "EJ": false }, "CharacterListFlags": { - "None": false, "Unk1": false, "OverwriteConfigButton": false, "OneCharacterSlot": false, @@ -380,7 +363,6 @@ "NewFeluccaAreas": false }, "HousingFlags": { - "None": false, "AOS": true, "SE": false, "ML": false, @@ -400,9 +382,8 @@ "ClientVersion": null, "ClientFlags": "Tokuno", "FeatureFlags": { - "None": false, - "T2A": false, - "UOR": false, + "T2A": true, + "UOR": true, "UOTD": false, "LBR": true, "AOS": true, @@ -427,7 +408,6 @@ "EJ": false }, "CharacterListFlags": { - "None": false, "Unk1": false, "OverwriteConfigButton": false, "OneCharacterSlot": false, @@ -446,7 +426,6 @@ "NewFeluccaAreas": false }, "HousingFlags": { - "None": false, "AOS": true, "SE": true, "ML": false, @@ -466,9 +445,8 @@ "ClientVersion": "5.0.0a", "ClientFlags": null, "FeatureFlags": { - "None": false, - "T2A": false, - "UOR": false, + "T2A": true, + "UOR": true, "UOTD": false, "LBR": true, "AOS": true, @@ -493,7 +471,6 @@ "EJ": false }, "CharacterListFlags": { - "None": false, "Unk1": false, "OverwriteConfigButton": false, "OneCharacterSlot": false, @@ -512,7 +489,6 @@ "NewFeluccaAreas": false }, "HousingFlags": { - "None": false, "AOS": true, "SE": true, "ML": true, @@ -532,9 +508,8 @@ "ClientVersion": null, "ClientFlags": "TerMur", "FeatureFlags": { - "None": false, - "T2A": false, - "UOR": false, + "T2A": true, + "UOR": true, "UOTD": false, "LBR": true, "AOS": true, @@ -559,7 +534,6 @@ "EJ": false }, "CharacterListFlags": { - "None": false, "Unk1": false, "OverwriteConfigButton": false, "OneCharacterSlot": false, @@ -578,7 +552,6 @@ "NewFeluccaAreas": false }, "HousingFlags": { - "None": false, "AOS": true, "SE": true, "ML": true, @@ -598,9 +571,8 @@ "ClientVersion": "7.0.9.0", "ClientFlags": null, "FeatureFlags": { - "None": false, - "T2A": false, - "UOR": false, + "T2A": true, + "UOR": true, "UOTD": false, "LBR": true, "AOS": true, @@ -625,7 +597,6 @@ "EJ": false }, "CharacterListFlags": { - "None": false, "Unk1": false, "OverwriteConfigButton": false, "OneCharacterSlot": false, @@ -644,7 +615,6 @@ "NewFeluccaAreas": false }, "HousingFlags": { - "None": false, "AOS": true, "SE": true, "ML": true, @@ -664,9 +634,8 @@ "ClientVersion": "7.0.45.65", "ClientFlags": null, "FeatureFlags": { - "None": false, - "T2A": false, - "UOR": false, + "T2A": true, + "UOR": true, "UOTD": false, "LBR": true, "AOS": true, @@ -691,7 +660,6 @@ "EJ": false }, "CharacterListFlags": { - "None": false, "Unk1": false, "OverwriteConfigButton": false, "OneCharacterSlot": false, @@ -710,7 +678,6 @@ "NewFeluccaAreas": false }, "HousingFlags": { - "None": false, "AOS": true, "SE": true, "ML": true, @@ -730,9 +697,8 @@ "ClientVersion": "7.0.61.0", "ClientFlags": null, "FeatureFlags": { - "None": false, - "T2A": false, - "UOR": false, + "T2A": true, + "UOR": true, "UOTD": false, "LBR": true, "AOS": true, @@ -757,7 +723,6 @@ "EJ": true }, "CharacterListFlags": { - "None": false, "Unk1": false, "OverwriteConfigButton": false, "OneCharacterSlot": false, @@ -776,7 +741,6 @@ "NewFeluccaAreas": false }, "HousingFlags": { - "None": false, "AOS": true, "SE": true, "ML": true, diff --git a/Projects/Server/ExpansionInfo.cs b/Projects/Server/ExpansionInfo.cs index 3d9ca5cd5..909658add 100644 --- a/Projects/Server/ExpansionInfo.cs +++ b/Projects/Server/ExpansionInfo.cs @@ -86,7 +86,6 @@ namespace Server ExpansionUOR = ExpansionT2A | UOR, ExpansionUOTD = ExpansionUOR | UOTD, ExpansionLBR = ExpansionUOTD | LBR, - // In later clients, the AOS+ expansions include the Publish 16 LBR flag, but not the previous expansions. ExpansionAOS = LBR | AOS | LiveAccount, ExpansionSE = ExpansionAOS | SE, ExpansionML = ExpansionSE | ML | NinthAge, @@ -159,6 +158,12 @@ namespace Server public class ExpansionInfo { + public static bool ForceOldAnimations { get; private set; } + public static void Configure() + { + ForceOldAnimations = ServerConfiguration.GetSetting("expansion.forceOldAnimations", false); + } + public static string GetEraFolder(string parentDirectory) { var expansion = Core.Expansion; @@ -265,32 +270,6 @@ namespace Server public ClientVersion RequiredClient { get; set; } public HousingFlags CustomHousingFlag { get; set; } - public static FeatureFlags GetFeatures(Expansion ex) - { - var info = GetInfo(ex); - - if (info != null) - { - return info.SupportedFeatures; - } - - return ex switch - { - Expansion.T2A => FeatureFlags.ExpansionT2A, - Expansion.UOR => FeatureFlags.ExpansionUOR, - Expansion.UOTD => FeatureFlags.ExpansionUOTD, - Expansion.LBR => FeatureFlags.ExpansionLBR, - Expansion.AOS => FeatureFlags.ExpansionAOS, - Expansion.SE => FeatureFlags.ExpansionSE, - Expansion.ML => FeatureFlags.ExpansionML, - Expansion.SA => FeatureFlags.ExpansionSA, - Expansion.HS => FeatureFlags.ExpansionHS, - Expansion.TOL => FeatureFlags.ExpansionTOL, - Expansion.EJ => FeatureFlags.EJ, - _ => FeatureFlags.ExpansionNone - }; - } - public static ExpansionInfo GetInfo(Expansion ex) => GetInfo((int)ex); public static ExpansionInfo GetInfo(int ex) diff --git a/Projects/Server/Json/Converters/FlagsConverter.cs b/Projects/Server/Json/Converters/FlagsConverter.cs index 38584d05a..b174e6681 100644 --- a/Projects/Server/Json/Converters/FlagsConverter.cs +++ b/Projects/Server/Json/Converters/FlagsConverter.cs @@ -100,16 +100,17 @@ namespace Server.Json { writer.WriteStartObject(); var underlyingType = Enum.GetUnderlyingType(typeof(T)); - var size = GetUnderlyingTypeLength(Type.GetTypeCode(underlyingType)) - 1; var intValue = ConvertToUInt64(underlyingType, value); foreach (var flagName in Enum.GetNames(typeof(T))) { var flagValue = Enum.Parse(flagName, false); var flag = ConvertToUInt64(underlyingType, flagValue); - if (flag == 0 || (flag & size) == 0) + + // Do not write out multi-bit values. This is a custom behavior + if (flag > 0 && (flag & (flag - 1)) == 0) { - writer.WriteBoolean(flagName, (intValue & flag) != 0); + writer.WriteBoolean(flagName, (intValue & flag) == flag); } } diff --git a/Projects/Server/Network/Packets/OutgoingAccountPackets.cs b/Projects/Server/Network/Packets/OutgoingAccountPackets.cs index 8e6e56d32..59e6db66e 100644 --- a/Projects/Server/Network/Packets/OutgoingAccountPackets.cs +++ b/Projects/Server/Network/Packets/OutgoingAccountPackets.cs @@ -160,6 +160,11 @@ public static class OutgoingAccountPackets } } + if (ExpansionInfo.ForceOldAnimations) + { + flags &= ~FeatureFlags.LBR; + } + var length = ns.ExtendedSupportedFeatures ? 5 : 3; var writer = new SpanWriter(stackalloc byte[length]); writer.Write((byte)0xB9); // Packet ID From 861ff307c006952266c0b033928d270588352d54 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Wed, 4 May 2022 14:40:49 -0700 Subject: [PATCH 151/213] fix: Fixes missing invalidate properties for default name (#1012) --- Projects/UOContent/Items/Body Parts/Head.cs | 2 ++ Projects/UOContent/Items/Containers/BaseTreasureChest.cs | 2 ++ Projects/UOContent/Items/Special/Holiday/HolidayBell.cs | 6 +++++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Projects/UOContent/Items/Body Parts/Head.cs b/Projects/UOContent/Items/Body Parts/Head.cs index c5c67ed6a..4bcf2cdae 100644 --- a/Projects/UOContent/Items/Body Parts/Head.cs +++ b/Projects/UOContent/Items/Body Parts/Head.cs @@ -12,10 +12,12 @@ namespace Server.Items [SerializationGenerator(1, false)] public partial class Head : Item { + [InvalidateProperties] [SerializableField(0)] [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] private string _playerName; + [InvalidateProperties] [SerializableField(1)] [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] private HeadType _headType; diff --git a/Projects/UOContent/Items/Containers/BaseTreasureChest.cs b/Projects/UOContent/Items/Containers/BaseTreasureChest.cs index 0dcbd55ec..8e0294f09 100644 --- a/Projects/UOContent/Items/Containers/BaseTreasureChest.cs +++ b/Projects/UOContent/Items/Containers/BaseTreasureChest.cs @@ -57,6 +57,8 @@ public partial class BaseTreasureChest : LockableContainer { StartResetTimer(); } + + InvalidateProperties(); } } } diff --git a/Projects/UOContent/Items/Special/Holiday/HolidayBell.cs b/Projects/UOContent/Items/Special/Holiday/HolidayBell.cs index 33b131645..50b578b73 100644 --- a/Projects/UOContent/Items/Special/Holiday/HolidayBell.cs +++ b/Projects/UOContent/Items/Special/Holiday/HolidayBell.cs @@ -73,7 +73,11 @@ public string Giver { get => m_Maker; - set => m_Maker = value; + set + { + m_Maker = value; + InvalidateProperties(); + } } public override string DefaultName => $"A Holiday Bell From {Giver}"; From 790cb5d7332f2b0dad0e190efa2bc3424430a0e8 Mon Sep 17 00:00:00 2001 From: Tellundro <101518037+tellundro@users.noreply.github.com> Date: Wed, 4 May 2022 23:10:55 -0300 Subject: [PATCH 152/213] fix: Fixes NPE in TreasureMapChest (#1010) --- Projects/UOContent/Items/Containers/TreasureMapChest.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Projects/UOContent/Items/Containers/TreasureMapChest.cs b/Projects/UOContent/Items/Containers/TreasureMapChest.cs index 03e7922ee..5b3153892 100644 --- a/Projects/UOContent/Items/Containers/TreasureMapChest.cs +++ b/Projects/UOContent/Items/Containers/TreasureMapChest.cs @@ -361,12 +361,12 @@ public partial class TreasureMapChest : LockableContainer public override void OnItemLifted(Mobile from, Item item) { - var notYetLifted = !_lifted.Contains(item); - + var notYetLifted = _lifted?.Contains(item) != true; from.RevealingAction(); if (notYetLifted) { + _lifted ??= new HashSet(); _lifted.Add(item); if (Utility.RandomDouble() <= 0.1) // 10% chance to spawn a new monster From be7da3a3dccf22fafcc7fbd7309bbd126900555b Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 8 May 2022 21:24:32 -0700 Subject: [PATCH 153/213] feat: Adds cliloc support and fixes valuestringbuilder ctor (#1013) - [X] Adds cliloc support using the following API: ```cs public static class Localization { string GetText(int number); string GetText(int number, string lang); string Format(int number, params object[] args); string Format(int number, string lang, params object[] args); string Format(int number, $"{arg1}{arg2}{arg3}"); string Format(int number, lang, $"{arg1}{arg2}{arg3}"); bool TryGetLocalization(int number, out LocalizationEntry entry); bool TryGetLocalization(int number, string lang, out LocalizationEntry entry); } public class LocalizationEntry { string Language { get; } string Number { get; } string Text { get; } string?[] TextSlices { get; } // Used for string building string StringFormatter { get; } string Format(params object[] args); string Format($"{arg1}{arg2}{arg3}"); } ``` - [X] Fixes a bug with ValueStringBuilder and default initialization size - [X] Optimizes ValueStringBuilder to use `ISpanFormattable` - [X] Adds `Append(T value);` support ValueStringBuilder - [X] Adds `Append($"");` string interpolation support to ValueStringBuider --- .../Buffers/PooledArraySpanFormattable.cs | 71 +++ Projects/Server/Buffers/ValueStringBuilder.cs | 261 ++++++++--- .../Buffers/ValueStringBuilderExtensions.cs | 31 ++ Projects/Server/Localization/Localization.cs | 201 ++++++++ .../Server/Localization/LocalizationEntry.cs | 104 +++++ .../LocalizationInterpolationHandler.cs | 429 ++++++++++++++++++ Projects/Server/Main.cs | 15 + Projects/Server/Utilities/Utility.cs | 90 ---- 8 files changed, 1046 insertions(+), 156 deletions(-) create mode 100644 Projects/Server/Buffers/PooledArraySpanFormattable.cs create mode 100644 Projects/Server/Buffers/ValueStringBuilderExtensions.cs create mode 100644 Projects/Server/Localization/Localization.cs create mode 100644 Projects/Server/Localization/LocalizationEntry.cs create mode 100644 Projects/Server/Localization/LocalizationInterpolationHandler.cs diff --git a/Projects/Server/Buffers/PooledArraySpanFormattable.cs b/Projects/Server/Buffers/PooledArraySpanFormattable.cs new file mode 100644 index 000000000..50e7df384 --- /dev/null +++ b/Projects/Server/Buffers/PooledArraySpanFormattable.cs @@ -0,0 +1,71 @@ +/************************************************************************* + * ModernUO * + * Copyright 2019-2022 - ModernUO Development Team * + * Email: hi@modernuo.com * + * File: PooledArraySpanFormattable.cs * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + +#nullable enable +using System; +using System.Buffers; + +namespace Server.Buffers; + +public struct PooledArraySpanFormattable : ISpanFormattable, IDisposable +{ + private char[] _arrayToReturnToPool; + private int _pos; + + public PooledArraySpanFormattable(char[] arrayToReturnToPool, int length) + { + _arrayToReturnToPool = arrayToReturnToPool; + _pos = length; + } + + public ReadOnlySpan Chars => _arrayToReturnToPool.AsSpan(.._pos); + + public static implicit operator string(PooledArraySpanFormattable f) => f.ToString(); + + public string ToString(string? format = null, IFormatProvider formatProvider = null) + { + var result = new string(_arrayToReturnToPool.AsSpan(0, _pos)); + Dispose(); + + return result; + } + + public bool TryFormat( + Span destination, out int charsWritten, ReadOnlySpan format = default, + IFormatProvider provider = null + ) + { + if (destination.Length < _pos) + { + charsWritten = 0; + return false; + } + + _arrayToReturnToPool.AsSpan(0, _pos).CopyTo(destination); + Dispose(); + + charsWritten = _pos; + return true; + } + + public void Dispose() + { + if (_arrayToReturnToPool != null) + { + ArrayPool.Shared.Return(_arrayToReturnToPool); + _arrayToReturnToPool = null; + } + } +} diff --git a/Projects/Server/Buffers/ValueStringBuilder.cs b/Projects/Server/Buffers/ValueStringBuilder.cs index 316c2960e..99a400036 100644 --- a/Projects/Server/Buffers/ValueStringBuilder.cs +++ b/Projects/Server/Buffers/ValueStringBuilder.cs @@ -1,8 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable using System; -using System.Globalization; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -14,6 +14,10 @@ public ref struct ValueStringBuilder private Span _chars; private int _length; + public ValueStringBuilder() : this(64) + { + } + // If this ctor is used, you cannot pass in stackalloc ROS for append/replace. public ValueStringBuilder(ReadOnlySpan initialString) : this(initialString.Length) { @@ -140,7 +144,7 @@ public ref struct ValueStringBuilder } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Insert(int index, string s) + public void Insert(int index, string? s) { if (s == null) { @@ -160,67 +164,39 @@ public ref struct ValueStringBuilder _length += count; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(char c) + public void Append(T value, string? format = null) { - int pos = _length; - if ((uint)pos < (uint)_chars.Length) + if (value is IFormattable) { - _chars[pos] = c; - _length = pos + 1; - } - else - { - GrowAndAppend(c); - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(int value, NumberFormatInfo info = null) - { - if (value >= 0) - { - Append((uint)value); - return; - } - - Append((info ?? NumberFormatInfo.CurrentInfo).NegativeSign); - Append((uint)-value); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe void Append(uint value) - { - int bufferLength = value.CountDigits(); - - int pos = _length; - if ((uint)pos + (uint)bufferLength >= _chars.Length) - { - Grow(bufferLength); - } - - if (bufferLength == 1) - { - _chars[pos] = (char)(value + '0'); - _length = pos + 1; - return; - } - - fixed (char* buffer = _chars[pos..]) - { - char* p = buffer + bufferLength; - do + if (value is ISpanFormattable) { - value = Utility.DivRem(value, 10, out uint remainder); - *--p = (char)(remainder + '0'); - } while (value != 0); - } + Span destination = _chars[_length..]; + int charsWritten; + while (!((ISpanFormattable)value).TryFormat(destination, out charsWritten, format, default)) + { + Grow(1); + } - _length = pos + bufferLength; + if ((uint)charsWritten > (uint)destination.Length) + { + throw new FormatException("Invalid string"); + } + + _length += charsWritten; + } + else + { + Append(((IFormattable)value).ToString(format, default)); // constrained call avoiding boxing for value types + } + } + else if (value is not null) + { + Append(value.ToString()); + } } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(string s) + public void Append(string? s) { if (s == null) { @@ -240,7 +216,7 @@ public ref struct ValueStringBuilder } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(string s) + public void AppendLine(string? s) { if (s == null) { @@ -261,7 +237,7 @@ public ref struct ValueStringBuilder } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void AppendSlow(string s) + private void AppendSlow(string? s) { int pos = _length; if (pos > _chars.Length - s.Length) @@ -332,14 +308,6 @@ public ref struct ValueStringBuilder return _chars.Slice(origPos, length); } - [MethodImpl(MethodImplOptions.NoInlining)] - private void GrowAndAppend(char c) - { - Grow(1); - Append(c); - } - -#nullable enable /// /// Resize the internal buffer either by doubling current buffer size or /// by adding to @@ -469,4 +437,165 @@ public ref struct ValueStringBuilder _length -= length; } + + /// Provides a handler used by the language compiler to append interpolated strings into instances. + [InterpolatedStringHandler] + public ref struct AppendInterpolatedStringHandler + { + // Implementation note: + // As this type is only intended to be targeted by the compiler, public APIs eschew argument validation logic + // in a variety of places, e.g. allowing a null input when one isn't expected to produce a NullReferenceException rather + // than an ArgumentNullException. + + /// The associated StringBuilder to which to append. + internal ValueStringBuilder _stringBuilder; + + /// Creates a handler used to append an interpolated string into a . + /// The number of constant characters outside of interpolation expressions in the interpolated string. + /// The number of interpolation expressions in the interpolated string. + /// The associated StringBuilder to which to append. + /// This is intended to be called only by compiler-generated code. Arguments are not validated as they'd otherwise be for members intended to be used directly. + public AppendInterpolatedStringHandler(int literalLength, int formattedCount, ValueStringBuilder stringBuilder) + { + _stringBuilder = stringBuilder; + } + + /// Writes the specified string to the handler. + /// The string to write. + public void AppendLiteral(string value) => _stringBuilder.Append(value); + + // Design note: + // This provides the same set of overloads and semantics as DefaultInterpolatedStringHandler. + + /// Writes the specified value to the handler. + /// The value to write. + public void AppendFormatted(T value) => _stringBuilder.Append(value); + + /// Writes the specified value to the handler. + /// The value to write. + /// The format string. + public void AppendFormatted(T value, string? format) => _stringBuilder.Append(value, format); + + /// Writes the specified value to the handler. + /// The value to write. + /// Minimum number of characters that should be written for this value. If the value is negative, it indicates left-aligned and the required minimum is the absolute value. + public void AppendFormatted(T value, int alignment) => + AppendFormatted(value, alignment, format: null); + + /// Writes the specified value to the handler. + /// The value to write. + /// The format string. + /// Minimum number of characters that should be written for this value. If the value is negative, it indicates left-aligned and the required minimum is the absolute value. + public void AppendFormatted(T value, int alignment, string? format) + { + if (alignment == 0) + { + // This overload is used as a fallback from several disambiguation overloads, so special-case 0. + AppendFormatted(value, format); + } + else if (alignment < 0) + { + // Left aligned: format into the handler, then append any additional padding required. + int start = _stringBuilder.Length; + AppendFormatted(value, format); + int paddingRequired = -alignment - (_stringBuilder.Length - start); + if (paddingRequired > 0) + { + _stringBuilder.Append(' ', paddingRequired); + } + } + else + { + var startingPos = _stringBuilder._length; + AppendFormatted(value, format); + + InsertAlignment(startingPos, alignment); + } + } + + /// Writes the specified character span to the handler. + /// The span to write. + public void AppendFormatted(ReadOnlySpan value) => _stringBuilder.Append(value); + + /// Writes the specified string of chars to the handler. + /// The span to write. + /// Minimum number of characters that should be written for this value. If the value is negative, it indicates left-aligned and the required minimum is the absolute value. + /// The format string. + public void AppendFormatted(ReadOnlySpan value, int alignment = 0, string? format = null) + { + if (alignment == 0) + { + _stringBuilder.Append(value); + } + else + { + bool leftAlign = false; + if (alignment < 0) + { + leftAlign = true; + alignment = -alignment; + } + + int paddingRequired = alignment - value.Length; + if (paddingRequired <= 0) + { + _stringBuilder.Append(value); + } + else if (leftAlign) + { + _stringBuilder.Append(value); + _stringBuilder.Append(' ', paddingRequired); + } + else + { + _stringBuilder.Append(' ', paddingRequired); + _stringBuilder.Append(value); + } + } + } + + /// Writes the specified value to the handler. + /// The value to write. + public void AppendFormatted(string? value) => _stringBuilder.Append(value); + + /// Writes the specified value to the handler. + /// The value to write. + /// Minimum number of characters that should be written for this value. If the value is negative, it indicates left-aligned and the required minimum is the absolute value. + /// The format string. + public void AppendFormatted(string? value, int alignment = 0, string? format = null) => + // Format is meaningless for strings and doesn't make sense for someone to specify. We have the overload + // simply to disambiguate between ROS and object, just in case someone does specify a format, as + // string is implicitly convertible to both. Just delegate to the T-based implementation. + AppendFormatted(value, alignment, format); + + /// Writes the specified value to the handler. + /// The value to write. + /// Minimum number of characters that should be written for this value. If the value is negative, it indicates left-aligned and the required minimum is the absolute value. + /// The format string. + public void AppendFormatted(object? value, int alignment = 0, string? format = null) => + // This overload is expected to be used rarely, only if either a) something strongly typed as object is + // formatted with both an alignment and a format, or b) the compiler is unable to target type to T. It + // exists purely to help make cases from (b) compile. Just delegate to the T-based implementation. + AppendFormatted(value, alignment, format); + + private void InsertAlignment(int startingPos, int alignment) + { + var charsWritten = _stringBuilder._length - startingPos; + + var paddingNeeded = alignment - charsWritten; + if (paddingNeeded > 0) + { + var chars = _stringBuilder._chars; + if (chars.Length - _stringBuilder._length < paddingNeeded) + { + _stringBuilder.Grow(paddingNeeded); + } + + chars.Slice(startingPos, charsWritten).CopyTo(chars[(startingPos + paddingNeeded)..]); + chars.Slice(startingPos, paddingNeeded).Fill(' '); + + _stringBuilder._length += paddingNeeded; + } + } + } } diff --git a/Projects/Server/Buffers/ValueStringBuilderExtensions.cs b/Projects/Server/Buffers/ValueStringBuilderExtensions.cs new file mode 100644 index 000000000..1ec588e80 --- /dev/null +++ b/Projects/Server/Buffers/ValueStringBuilderExtensions.cs @@ -0,0 +1,31 @@ +/************************************************************************* + * ModernUO * + * Copyright 2019-2022 - ModernUO Development Team * + * Email: hi@modernuo.com * + * File: ValueStringBuilderExtensions.cs * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + +using System.Runtime.CompilerServices; + +namespace Server.Buffers; + +public static class ValueStringBuilderExtensions +{ + // Compiler generated + public static void Append( + this ref ValueStringBuilder stringBuilder, + [InterpolatedStringHandlerArgument("stringBuilder")] + ref ValueStringBuilder.AppendInterpolatedStringHandler handler) + { + // Reassign since the string builder stored on the interpolated handler is by-value + stringBuilder = handler._stringBuilder; + } +} diff --git a/Projects/Server/Localization/Localization.cs b/Projects/Server/Localization/Localization.cs new file mode 100644 index 000000000..fe3128c67 --- /dev/null +++ b/Projects/Server/Localization/Localization.cs @@ -0,0 +1,201 @@ +/************************************************************************* + * ModernUO * + * Copyright 2019-2022 - ModernUO Development Team * + * Email: hi@modernuo.com * + * File: Localization.cs * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + +using System; +using System.Collections.Generic; +using System.IO; +using System.Runtime.CompilerServices; +using System.Text; +using Server.Buffers; + +namespace Server; + +public static class Localization +{ + private const bool _loadLocalizationOnStartup = false; + public const string FallbackLanguage = "enu"; + + private static Dictionary _fallbackEntries; + private static Dictionary> _localizations = new(); + + public static void Configure() + { + if (_loadLocalizationOnStartup) + { + foreach (var file in Core.FindDataFileByPattern("cliloc.*")) + { + var fi = new FileInfo(file); + LoadClilocs(fi.Extension.ToLowerInvariant(), file); + } + } + } + + public static Dictionary LoadClilocs(string lang) => + LoadClilocs(lang, Core.FindDataFile($"cliloc.{lang}", false)); + + private static Dictionary LoadClilocs(string lang, string file) + { + Dictionary entries = _localizations[lang] = new Dictionary(); + if (lang == FallbackLanguage) + { + _fallbackEntries = entries; + } + + if (File.Exists(file)) + { + using var fs = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read); + using var bin = new BinaryReader(fs); + + bin.ReadInt32(); + bin.ReadInt16(); + + byte[] buffer = null; + while (bin.BaseStream.Length != bin.BaseStream.Position) + { + var number = bin.ReadInt32(); + var flag = bin.ReadByte(); // Original, Custom, Modified + var length = bin.ReadInt16(); + + if (buffer == null || buffer.Length < length) + { + buffer = GC.AllocateUninitializedArray(length); + } + + var bytesRead = bin.Read(buffer, 0, length); + if (bytesRead != length) + { + throw new Exception($"Could not read enough bytes from {file}"); + } + + var text = Encoding.UTF8.GetString(buffer.AsSpan(0, length)); + entries[number] = new LocalizationEntry(lang, number, text); + } + } + + return entries; + } + + /// + /// Returns the original text for a localization entry. + /// + /// Localization number + /// Language in ISO 639‑2 format + /// Original text for the localizaton entry + public static string GetText(int number, string lang = FallbackLanguage) => + TryGetLocalization(lang, number, out var entry) ? entry.Text : null; + + public static string Format(int number, string lang = FallbackLanguage) => GetText(number, lang); + + /// + /// Creates a formatted string of the localization entry using the . + /// Uses under the hood. + /// Note: This method is not recommended since it uses almost double the memory and 50% more processing. + /// Instead use Format with string interpolation. + /// + /// Localization number + /// An object array containing zero or more objects to format + /// A copy of the localization text where the placeholder arguments have been replaced with string representations of the provided arguments + public static string Format(int number, params object[] args) => + !TryGetLocalization(number, out var entry) ? null : string.Format(entry.StringFormatter, args); + + /// + /// Creates a formatted string of the localization entry using the specified language. + /// Uses under the hood. + /// Note: This method is not recommended since it uses almost double the memory and 50% more processing. + /// Instead use Format with string interpolation. + /// + /// Localization number + /// Language in ISO 639-2 format + /// An object array containing zero or more objects to format + /// A copy of the localization text where the placeholder arguments have been replaced with string representations of the provided arguments + public static string Format(int number, string lang, params object[] args) => + !TryGetLocalization(lang, number, out var entry) ? null : string.Format(entry.StringFormatter, args); + + /// + /// Gets a localization entry using the . + /// + /// Localization number + /// Localization entry retrieved + /// True if the entry exists, otherwise false. + public static bool TryGetLocalization(int number, out LocalizationEntry entry) => + TryGetLocalization(FallbackLanguage, number, out entry); + + /// + /// Gets a localization entry. + /// + /// Language in ISO 639-2 format + /// Localization number + /// Localization entry retrieved + /// True if the entry exists, otherwise false. + public static bool TryGetLocalization(string lang, int number, out LocalizationEntry entry) + { + if (lang != FallbackLanguage) + { + if (!_localizations.TryGetValue(lang, out var entries)) + { + entries = LoadClilocs(lang); + } + + if (entries.TryGetValue(number, out entry)) + { + return true; + } + } + + _fallbackEntries ??= LoadClilocs(FallbackLanguage); + return _fallbackEntries.TryGetValue(number, out entry); + } + + /// + /// Creates a formatted string of the localization entry using the specified language. + /// Uses string interpolation under the hood. This method is preferably relative to the object array method signature. + /// Example: + /// Localization.Format(1073841, "jpn", $"{totalItems}{maxItems}{totalWeight}"); + /// + /// Language in ISO 639-2 format + /// Localization number + /// interpolated string handler used by the compiler as a string builder during compilation + /// A copy of the localization text where the placeholder arguments have been replaced with string representations of the provided interpolation arguments + public static PooledArraySpanFormattable Format( + int number, string lang, + [InterpolatedStringHandlerArgument("number", "lang")] + ref LocalizationInterpolationHandler handler + ) + { + var chars = handler.ToPooledArray(out var length); + handler = default; // Defensive clear + return new PooledArraySpanFormattable(chars, length); + } + + /// + /// Creates a formatted string of the localization entry using the . + /// Uses string interpolation under the hood. This method is preferably relative to the object array method signature. + /// Example: + /// Localization.Format(1073841, $"{totalItems}{maxItems}{totalWeight}"); + /// + /// Localization number + /// interpolated string handler used by the compiler as a string builder during compilation + /// A copy of the localization text where the placeholder arguments have been replaced with string representations of the provided interpolation arguments + public static PooledArraySpanFormattable Format( + int number, + [InterpolatedStringHandlerArgument("number")] + ref LocalizationInterpolationHandler handler + ) + { + var chars = handler.ToPooledArray(out var length); + handler = default; // Defensive clear + return new PooledArraySpanFormattable(chars, length); + } +} diff --git a/Projects/Server/Localization/LocalizationEntry.cs b/Projects/Server/Localization/LocalizationEntry.cs new file mode 100644 index 000000000..61211fbdb --- /dev/null +++ b/Projects/Server/Localization/LocalizationEntry.cs @@ -0,0 +1,104 @@ +/************************************************************************* + * ModernUO * + * Copyright 2019-2022 - ModernUO Development Team * + * Email: hi@modernuo.com * + * File: LocalizationEntry.cs * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + +using System.Runtime.CompilerServices; +using System.Text.RegularExpressions; +using Server.Buffers; +using Server.Collections; + +namespace Server; + +public class LocalizationEntry +{ + private static readonly Regex _textRegex = new( + @"~(\d+)[_\w]+~", + RegexOptions.Compiled | + RegexOptions.IgnoreCase | + RegexOptions.Singleline | + RegexOptions.CultureInvariant + ); + + public string Language { get; } + public int Number { get; } + public string Text { get; } + public string[] TextSlices { get; } + public string StringFormatter { get; } + + public LocalizationEntry(string lang, int number, string text) + { + Language = lang; + Number = number; + Text = text; + + ParseText(text, out var textSlices, out var stringFormatter); + TextSlices = textSlices; + StringFormatter = stringFormatter; + } + + private static void ParseText(string text, out string[] textSlices, out string stringFormatter) + { + bool hasMatch = false; + var prevIndex = 0; + var builder = new ValueStringBuilder(stackalloc char[256]); + using var queue = PooledRefQueue.Create(); + foreach (Match match in _textRegex.Matches(text)) + { + if (prevIndex < match.Index) + { + var substr = text[prevIndex..match.Index]; + builder.Append(substr); + + queue.Enqueue(substr); + } + + queue.Enqueue(null); + hasMatch = true; + builder.Append($"{{{int.Parse(match.Groups[1].Value) - 1}}}"); + prevIndex = match.Index + match.Length; + } + + if (prevIndex < text.Length - 1) + { + var substr = prevIndex == 0 ? text : text[prevIndex..]; + builder.Append(substr); + queue.Enqueue(substr); + } + + textSlices = queue.ToArray(); + stringFormatter = hasMatch ? builder.ToString() : null; + + builder.Dispose(); + } + + public string Format(params object[] args) => string.Format(StringFormatter, args); + + /// + /// Creates a formatted string of the localization entry. + /// Uses string interpolation under the hood. This method is preferably relative to the object array method signature. + /// Example: + /// Format($"{totalItems}{maxItems}{totalWeight}"); + /// + /// interpolated string handler used by the compiler as a string builder during compilation + /// A copy of the localization text where the placeholder arguments have been replaced with string representations of the provided interpolation arguments + public PooledArraySpanFormattable Format( + [InterpolatedStringHandlerArgument("")] + ref LocalizationInterpolationHandler handler + ) + { + var chars = handler.ToPooledArray(out var length); + handler = default; // Defensive clear + return new PooledArraySpanFormattable(chars, length); + } +} diff --git a/Projects/Server/Localization/LocalizationInterpolationHandler.cs b/Projects/Server/Localization/LocalizationInterpolationHandler.cs new file mode 100644 index 000000000..62908ea3c --- /dev/null +++ b/Projects/Server/Localization/LocalizationInterpolationHandler.cs @@ -0,0 +1,429 @@ +/************************************************************************* + * ModernUO * + * Copyright 2019-2022 - ModernUO Development Team * + * Email: hi@modernuo.com * + * File: LocalizationInterpolationHandler.cs * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + +#nullable enable +using System; +using System.Buffers; +using System.Runtime.CompilerServices; + +namespace Server; + +[InterpolatedStringHandler] +public ref struct LocalizationInterpolationHandler +{ + private static string[] _empty = Array.Empty(); + + private char[]? _arrayToReturnToPool; + private Span _chars; + private int _pos; + + private int _index; + private string?[] _slices; + private string? _current; + + public LocalizationInterpolationHandler(int literalLength, int formattedCount, LocalizationEntry entry, out bool isValid) + { + _slices = entry.TextSlices; + _chars = _arrayToReturnToPool = ArrayPool.Shared.Rent(256); + isValid = true; + + _pos = 0; + _index = 0; + _current = null; + } + + public LocalizationInterpolationHandler(int literalLength, int formattedCount, int number, out bool isValid) + : this(literalLength, formattedCount, number, Localization.FallbackLanguage, out isValid) + { + } + + public LocalizationInterpolationHandler(int literalLength, int formattedCount, int number, string lang, out bool isValid) + { + if (Localization.TryGetLocalization(lang, number, out var entry)) + { + _slices = entry.TextSlices; + _chars = _arrayToReturnToPool = ArrayPool.Shared.Rent(256); + isValid = true; + } + else + { + _slices = _empty; + _chars = _arrayToReturnToPool = default; + isValid = false; + } + + _pos = 0; + _index = 0; + _current = null; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private bool MoveNext() + { + if ((uint)_index >= (uint)_slices.Length) + { + return false; + } + + _current = _slices[_index++]; + return true; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private bool ReadyToAppend() + { + if (!MoveNext()) + { + return false; + } + + if (_current == null) + { + return true; + } + + AppendStringDirect(_current); + return MoveNext(); + } + + public void AppendLiteral(string value) + { + } + + private void AppendStringDirect(string value) + { + if (value.TryCopyTo(_chars[_pos..])) + { + _pos += value.Length; + } + else + { + GrowThenCopyString(value); + } + } + + public void AppendFormatted(T value) + { + if (!ReadyToAppend()) + { + return; + } + + string? s; + if (value is IFormattable) + { + // If the value can format itself directly into our buffer, do so. + if (value is ISpanFormattable) + { + int charsWritten; + while (!((ISpanFormattable)value).TryFormat(_chars[_pos..], out charsWritten, default, default)) // constrained call avoiding boxing for value types + { + Grow(); + } + + _pos += charsWritten; + return; + } + + s = ((IFormattable)value).ToString(format: null, default); // constrained call avoiding boxing for value types + } + else + { + s = value?.ToString(); + } + + if (s is not null) + { + AppendStringDirect(s); + } + } + + public void AppendFormatted(T value, string? format) + { + if (!ReadyToAppend()) + { + return; + } + + string? s; + if (value is IFormattable) + { + // If the value can format itself directly into our buffer, do so. + if (value is ISpanFormattable) + { + int charsWritten; + while (!((ISpanFormattable)value).TryFormat(_chars[_pos..], out charsWritten, format, default)) // constrained call avoiding boxing for value types + { + Grow(); + } + + _pos += charsWritten; + return; + } + + s = ((IFormattable)value).ToString(format, default); // constrained call avoiding boxing for value types + } + else + { + s = value?.ToString(); + } + + if (s is not null) + { + AppendStringDirect(s); + } + } + + public void AppendFormatted(T value, int alignment) + { + if (!ReadyToAppend()) + { + return; + } + + var startingPos = _pos; + AppendFormatted(value); + if (alignment != 0) + { + AppendOrInsertAlignmentIfNeeded(startingPos, alignment); + } + } + + public void AppendFormatted(T value, int alignment, string? format) + { + if (!ReadyToAppend()) + { + return; + } + + var startingPos = _pos; + AppendFormatted(value, format); + if (alignment != 0) + { + AppendOrInsertAlignmentIfNeeded(startingPos, alignment); + } + } + + public void AppendFormatted(ReadOnlySpan value) + { + if (!ReadyToAppend()) + { + return; + } + + if (value.TryCopyTo(_chars[_pos..])) + { + _pos += value.Length; + } + else + { + GrowThenCopySpan(value); + } + } + + public void AppendFormatted(ReadOnlySpan value, int alignment, string? format = null) + { + if (!ReadyToAppend()) + { + return; + } + + var leftAlign = false; + if (alignment < 0) + { + leftAlign = true; + alignment = -alignment; + } + + var paddingRequired = alignment - value.Length; + if (paddingRequired <= 0) + { + // The value is as large or larger than the required amount of padding, + // so just write the value. + AppendFormatted(value); + return; + } + + // Write the value along with the appropriate padding. + EnsureCapacityForAdditionalChars(value.Length + paddingRequired); + if (leftAlign) + { + value.CopyTo(_chars[_pos..]); + _pos += value.Length; + _chars.Slice(_pos, paddingRequired).Fill(' '); + _pos += paddingRequired; + } + else + { + _chars.Slice(_pos, paddingRequired).Fill(' '); + _pos += paddingRequired; + value.CopyTo(_chars[_pos..]); + _pos += value.Length; + } + } + + public void AppendFormatted(object? value, int alignment = 0, string? format = null) => + AppendFormatted(value, alignment, format); + + public void AppendFormatted(string? value) + { + if (ReadyToAppend()) + { + if (value?.TryCopyTo(_chars[_pos..]) == true) + { + _pos += value.Length; + } + else + { + AppendFormattedSlow(value); + } + } + } + + public void AppendFormatted(string? value, int alignment, string? format = null) => + AppendFormatted(value, alignment, format); + + private void AppendOrInsertAlignmentIfNeeded(int startingPos, int alignment) + { + var charsWritten = _pos - startingPos; + + var leftAlign = false; + if (alignment < 0) + { + leftAlign = true; + alignment = -alignment; + } + + var paddingNeeded = alignment - charsWritten; + if (paddingNeeded > 0) + { + EnsureCapacityForAdditionalChars(paddingNeeded); + + if (leftAlign) + { + _chars.Slice(_pos, paddingNeeded).Fill(' '); + } + else + { + _chars.Slice(startingPos, charsWritten).CopyTo(_chars[(startingPos + paddingNeeded)..]); + _chars.Slice(startingPos, paddingNeeded).Fill(' '); + } + + _pos += paddingNeeded; + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private void AppendFormattedSlow(string? value) + { + if (value is not null) + { + EnsureCapacityForAdditionalChars(value.Length); + value.CopyTo(_chars[_pos..]); + _pos += value.Length; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void EnsureCapacityForAdditionalChars(int additionalChars) + { + if (_chars.Length - _pos < additionalChars) + { + Grow(additionalChars); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private void GrowThenCopyString(string value) + { + Grow(value.Length); + value.CopyTo(_chars[_pos..]); + _pos += value.Length; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private void GrowThenCopySpan(ReadOnlySpan value) + { + Grow(value.Length); + value.CopyTo(_chars[_pos..]); + _pos += value.Length; + } + + [MethodImpl(MethodImplOptions.NoInlining)] // keep consumers as streamlined as possible + private void Grow(int additionalChars) + { + GrowCore((uint)_pos + (uint)additionalChars); + } + + [MethodImpl(MethodImplOptions.NoInlining)] // keep consumers as streamlined as possible + private void Grow() + { + GrowCore((uint)_chars.Length + 1); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void GrowCore(uint requiredMinCapacity) + { + var newCapacity = Math.Max(requiredMinCapacity, Math.Min((uint)_chars.Length * 2, 1073741823)); + var arraySize = (int)Math.Clamp(newCapacity, 256, int.MaxValue); + + var newArray = ArrayPool.Shared.Rent(arraySize); + _chars[.._pos].CopyTo(newArray); + + var toReturn = _arrayToReturnToPool; + _chars = _arrayToReturnToPool = newArray; + + if (toReturn is not null) + { + ArrayPool.Shared.Return(toReturn); + } + } + + internal ReadOnlySpan Text => _chars[.._pos]; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal void Clear() + { + var toReturn = _arrayToReturnToPool; + this = default; // defensive clear + if (toReturn is not null) + { + ArrayPool.Shared.Return(toReturn); + } + } + + public string ToStringAndClear() + { + if (MoveNext() && _current != null) + { + AppendStringDirect(_current); + } + + var result = new string(Text); + Clear(); + return result; + } + + public char[] ToPooledArray(out int length) + { + if (MoveNext() && _current != null) + { + AppendStringDirect(_current); + } + + length = _pos; + return _arrayToReturnToPool; + } +} diff --git a/Projects/Server/Main.cs b/Projects/Server/Main.cs index f9ab272b7..bd1316858 100644 --- a/Projects/Server/Main.cs +++ b/Projects/Server/Main.cs @@ -274,6 +274,21 @@ namespace Server return fullPath; } + public static IEnumerable FindDataFileByPattern(string pattern) + { + var options = new EnumerationOptions { MatchCasing = MatchCasing.CaseInsensitive }; + foreach (var p in ServerConfiguration.DataDirectories) + { + if (Directory.Exists(p)) + { + foreach (var file in Directory.EnumerateFiles(p, pattern, options)) + { + yield return file; + } + } + } + } + private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { Console.WriteLine(e.IsTerminating ? "Error:" : "Warning:"); diff --git a/Projects/Server/Utilities/Utility.cs b/Projects/Server/Utilities/Utility.cs index ba4877fc9..34e90c4d1 100644 --- a/Projects/Server/Utilities/Utility.cs +++ b/Projects/Server/Utilities/Utility.cs @@ -1284,96 +1284,6 @@ namespace Server return (value + mask) ^ mask; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static long Abs(this long value) - { - long mask = value >> 63; - return (value + mask) ^ mask; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int CountDigits(this uint value) - { - int digits = 1; - if (value >= 100000) - { - value /= 100000; - digits += 5; - } - - if (value < 10) - { - // no-op - } - else if (value < 100) - { - digits++; - } - else if (value < 1000) - { - digits += 2; - } - else if (value < 10000) - { - digits += 3; - } - else - { - digits += 4; - } - - return digits; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int CountDigits(this int value) - { - int absValue = Abs(value); - - int digits = 1; - if (absValue >= 100000) - { - absValue /= 100000; - digits += 5; - } - - if (absValue < 10) - { - // no-op - } - else if (absValue < 100) - { - digits++; - } - else if (absValue < 1000) - { - digits += 2; - } - else if (absValue < 10000) - { - digits += 3; - } - else - { - digits += 4; - } - - if (value < 0) - { - digits += 1; // negative - } - - return digits; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static uint DivRem(uint a, uint b, out uint result) - { - uint div = a / b; - result = a - div * b; - return div; - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string GetTimeStamp() => Core.Now.ToTimeStamp(); From 47d427ed6e44d6ecd958531c732063d3163d1f3f Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Mon, 9 May 2022 21:10:58 -0700 Subject: [PATCH 154/213] fix: Adds cliloc replacement support (#1014) --- .../LocalizationInterpolationHandler.cs | 50 +++++++++++++++---- 1 file changed, 40 insertions(+), 10 deletions(-) diff --git a/Projects/Server/Localization/LocalizationInterpolationHandler.cs b/Projects/Server/Localization/LocalizationInterpolationHandler.cs index 62908ea3c..2ad07e3b1 100644 --- a/Projects/Server/Localization/LocalizationInterpolationHandler.cs +++ b/Projects/Server/Localization/LocalizationInterpolationHandler.cs @@ -32,6 +32,7 @@ public ref struct LocalizationInterpolationHandler private int _index; private string?[] _slices; private string? _current; + private string _lang; public LocalizationInterpolationHandler(int literalLength, int formattedCount, LocalizationEntry entry, out bool isValid) { @@ -42,6 +43,7 @@ public ref struct LocalizationInterpolationHandler _pos = 0; _index = 0; _current = null; + _lang = entry.Language; } public LocalizationInterpolationHandler(int literalLength, int formattedCount, int number, out bool isValid) @@ -67,6 +69,7 @@ public ref struct LocalizationInterpolationHandler _pos = 0; _index = 0; _current = null; + _lang = lang; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -218,7 +221,7 @@ public ref struct LocalizationInterpolationHandler public void AppendFormatted(ReadOnlySpan value) { - if (!ReadyToAppend()) + if (!ReadyToAppend() || TryAppendClilocNumber(value)) { return; } @@ -279,22 +282,49 @@ public ref struct LocalizationInterpolationHandler public void AppendFormatted(string? value) { - if (ReadyToAppend()) + if (!ReadyToAppend() || TryAppendClilocNumber(value)) { - if (value?.TryCopyTo(_chars[_pos..]) == true) - { - _pos += value.Length; - } - else - { - AppendFormattedSlow(value); - } + return; + } + + if (value?.TryCopyTo(_chars[_pos..]) == true) + { + _pos += value.Length; + } + else + { + AppendFormattedSlow(value); } } public void AppendFormatted(string? value, int alignment, string? format = null) => AppendFormatted(value, alignment, format); + private bool TryAppendClilocNumber(ReadOnlySpan value) + { + if ( + value[0] != '#' || + !int.TryParse(value[1..], out var number) || + !Localization.TryGetLocalization(_lang, number, out var entry) + ) + { + return false; + } + + var text = entry.Text; + + if (text.TryCopyTo(_chars[_pos..])) + { + _pos += text.Length; + } + else + { + AppendFormattedSlow(text); + } + + return true; + } + private void AppendOrInsertAlignmentIfNeeded(int startingPos, int alignment) { var charsWritten = _pos - startingPos; From 8031de47384e41dd2f06cf21cb9d1e20c5adadfc Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Tue, 10 May 2022 00:37:07 -0700 Subject: [PATCH 155/213] fix: Fixes string format of cliloc arguments (#1015) --- Projects/Server/Localization/Localization.cs | 22 +- .../Server/Localization/LocalizationEntry.cs | 453 ++++++++++++++++- .../LocalizationInterpolationHandler.cs | 459 ------------------ 3 files changed, 456 insertions(+), 478 deletions(-) delete mode 100644 Projects/Server/Localization/LocalizationInterpolationHandler.cs diff --git a/Projects/Server/Localization/Localization.cs b/Projects/Server/Localization/Localization.cs index fe3128c67..e178bbd95 100644 --- a/Projects/Server/Localization/Localization.cs +++ b/Projects/Server/Localization/Localization.cs @@ -96,20 +96,6 @@ public static class Localization public static string GetText(int number, string lang = FallbackLanguage) => TryGetLocalization(lang, number, out var entry) ? entry.Text : null; - public static string Format(int number, string lang = FallbackLanguage) => GetText(number, lang); - - /// - /// Creates a formatted string of the localization entry using the . - /// Uses under the hood. - /// Note: This method is not recommended since it uses almost double the memory and 50% more processing. - /// Instead use Format with string interpolation. - /// - /// Localization number - /// An object array containing zero or more objects to format - /// A copy of the localization text where the placeholder arguments have been replaced with string representations of the provided arguments - public static string Format(int number, params object[] args) => - !TryGetLocalization(number, out var entry) ? null : string.Format(entry.StringFormatter, args); - /// /// Creates a formatted string of the localization entry using the specified language. /// Uses under the hood. @@ -120,8 +106,8 @@ public static class Localization /// Language in ISO 639-2 format /// An object array containing zero or more objects to format /// A copy of the localization text where the placeholder arguments have been replaced with string representations of the provided arguments - public static string Format(int number, string lang, params object[] args) => - !TryGetLocalization(lang, number, out var entry) ? null : string.Format(entry.StringFormatter, args); + public static string Format(int number, string lang = FallbackLanguage, params object[] args) => + TryGetLocalization(lang, number, out var entry) ? entry.Format(args) : null; /// /// Gets a localization entry using the . @@ -171,7 +157,7 @@ public static class Localization public static PooledArraySpanFormattable Format( int number, string lang, [InterpolatedStringHandlerArgument("number", "lang")] - ref LocalizationInterpolationHandler handler + ref LocalizationEntry.LocalizationInterpolationHandler handler ) { var chars = handler.ToPooledArray(out var length); @@ -191,7 +177,7 @@ public static class Localization public static PooledArraySpanFormattable Format( int number, [InterpolatedStringHandlerArgument("number")] - ref LocalizationInterpolationHandler handler + ref LocalizationEntry.LocalizationInterpolationHandler handler ) { var chars = handler.ToPooledArray(out var length); diff --git a/Projects/Server/Localization/LocalizationEntry.cs b/Projects/Server/Localization/LocalizationEntry.cs index 61211fbdb..c2914601f 100644 --- a/Projects/Server/Localization/LocalizationEntry.cs +++ b/Projects/Server/Localization/LocalizationEntry.cs @@ -13,6 +13,8 @@ * along with this program. If not, see . * *************************************************************************/ +using System; +using System.Buffers; using System.Runtime.CompilerServices; using System.Text.RegularExpressions; using Server.Buffers; @@ -82,7 +84,23 @@ public class LocalizationEntry builder.Dispose(); } - public string Format(params object[] args) => string.Format(StringFormatter, args); + public string Format(params object[] args) + { + if (args == null || args.Length == 0 || StringFormatter == null) + { + return Text; + } + + for (var i = 0; i < args.Length; i++) + { + if (args[i] is string s && s[0] == '#' && int.TryParse(s.AsSpan(1), out var number)) + { + args[i] = Localization.GetText(number, Language); + } + } + + return string.Format(StringFormatter, args); + } /// /// Creates a formatted string of the localization entry. @@ -101,4 +119,437 @@ public class LocalizationEntry handler = default; // Defensive clear return new PooledArraySpanFormattable(chars, length); } + + [InterpolatedStringHandler] + public ref struct LocalizationInterpolationHandler + { + private static string[] _empty = Array.Empty(); + + private char[]? _arrayToReturnToPool; + private Span _chars; + private int _pos; + + private int _index; + private string?[] _slices; + private string? _current; + private string _lang; + + public LocalizationInterpolationHandler(int literalLength, int formattedCount, LocalizationEntry entry, out bool isValid) + { + _slices = entry.TextSlices; + _chars = _arrayToReturnToPool = ArrayPool.Shared.Rent(256); + isValid = true; + + _pos = 0; + _index = 0; + _current = null; + _lang = entry.Language; + } + + public LocalizationInterpolationHandler(int literalLength, int formattedCount, int number, string lang, out bool isValid) + { + if (Localization.TryGetLocalization(lang, number, out var entry)) + { + _slices = entry.TextSlices; + _chars = _arrayToReturnToPool = ArrayPool.Shared.Rent(256); + isValid = true; + } + else + { + _slices = _empty; + _chars = _arrayToReturnToPool = default; + isValid = false; + } + + _pos = 0; + _index = 0; + _current = null; + _lang = lang; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private bool MoveNext() + { + if ((uint)_index >= (uint)_slices.Length) + { + return false; + } + + _current = _slices[_index++]; + return true; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private bool ReadyToAppend() + { + if (!MoveNext()) + { + return false; + } + + if (_current == null) + { + return true; + } + + AppendStringDirect(_current); + return MoveNext(); + } + + public void AppendLiteral(string value) + { + } + + private void AppendStringDirect(string value) + { + if (value.TryCopyTo(_chars[_pos..])) + { + _pos += value.Length; + } + else + { + GrowThenCopyString(value); + } + } + + public void AppendFormatted(T value) + { + if (!ReadyToAppend()) + { + return; + } + + string? s; + if (value is IFormattable) + { + // If the value can format itself directly into our buffer, do so. + if (value is ISpanFormattable) + { + int charsWritten; + while (!((ISpanFormattable)value).TryFormat(_chars[_pos..], out charsWritten, default, default)) // constrained call avoiding boxing for value types + { + Grow(); + } + + _pos += charsWritten; + return; + } + + s = ((IFormattable)value).ToString(format: null, default); // constrained call avoiding boxing for value types + } + else + { + s = value?.ToString(); + } + + if (s is not null) + { + AppendStringDirect(s); + } + } + + public void AppendFormatted(T value, string? format) + { + if (!ReadyToAppend()) + { + return; + } + + string? s; + if (value is IFormattable) + { + // If the value can format itself directly into our buffer, do so. + if (value is ISpanFormattable) + { + int charsWritten; + while (!((ISpanFormattable)value).TryFormat(_chars[_pos..], out charsWritten, format, default)) // constrained call avoiding boxing for value types + { + Grow(); + } + + _pos += charsWritten; + return; + } + + s = ((IFormattable)value).ToString(format, default); // constrained call avoiding boxing for value types + } + else + { + s = value?.ToString(); + } + + if (s is not null) + { + AppendStringDirect(s); + } + } + + public void AppendFormatted(T value, int alignment) + { + if (!ReadyToAppend()) + { + return; + } + + var startingPos = _pos; + AppendFormatted(value); + if (alignment != 0) + { + AppendOrInsertAlignmentIfNeeded(startingPos, alignment); + } + } + + public void AppendFormatted(T value, int alignment, string? format) + { + if (!ReadyToAppend()) + { + return; + } + + var startingPos = _pos; + AppendFormatted(value, format); + if (alignment != 0) + { + AppendOrInsertAlignmentIfNeeded(startingPos, alignment); + } + } + + public void AppendFormatted(ReadOnlySpan value) + { + if (!ReadyToAppend() || TryAppendClilocNumber(value)) + { + return; + } + + if (value.TryCopyTo(_chars[_pos..])) + { + _pos += value.Length; + } + else + { + GrowThenCopySpan(value); + } + } + + public void AppendFormatted(ReadOnlySpan value, int alignment, string? format = null) + { + if (!ReadyToAppend()) + { + return; + } + + var leftAlign = false; + if (alignment < 0) + { + leftAlign = true; + alignment = -alignment; + } + + var paddingRequired = alignment - value.Length; + if (paddingRequired <= 0) + { + // The value is as large or larger than the required amount of padding, + // so just write the value. + AppendFormatted(value); + return; + } + + // Write the value along with the appropriate padding. + EnsureCapacityForAdditionalChars(value.Length + paddingRequired); + if (leftAlign) + { + value.CopyTo(_chars[_pos..]); + _pos += value.Length; + _chars.Slice(_pos, paddingRequired).Fill(' '); + _pos += paddingRequired; + } + else + { + _chars.Slice(_pos, paddingRequired).Fill(' '); + _pos += paddingRequired; + value.CopyTo(_chars[_pos..]); + _pos += value.Length; + } + } + + public void AppendFormatted(object? value, int alignment = 0, string? format = null) => + AppendFormatted(value, alignment, format); + + public void AppendFormatted(string? value) + { + if (!ReadyToAppend() || TryAppendClilocNumber(value)) + { + return; + } + + if (value?.TryCopyTo(_chars[_pos..]) == true) + { + _pos += value.Length; + } + else + { + AppendFormattedSlow(value); + } + } + + public void AppendFormatted(string? value, int alignment, string? format = null) => + AppendFormatted(value, alignment, format); + + private bool TryAppendClilocNumber(ReadOnlySpan value) + { + if ( + value[0] != '#' || + !int.TryParse(value[1..], out var number) || + !Localization.TryGetLocalization(_lang, number, out var entry) + ) + { + return false; + } + + var text = entry.Text; + + if (text.TryCopyTo(_chars[_pos..])) + { + _pos += text.Length; + } + else + { + AppendFormattedSlow(text); + } + + return true; + } + + private void AppendOrInsertAlignmentIfNeeded(int startingPos, int alignment) + { + var charsWritten = _pos - startingPos; + + var leftAlign = false; + if (alignment < 0) + { + leftAlign = true; + alignment = -alignment; + } + + var paddingNeeded = alignment - charsWritten; + if (paddingNeeded > 0) + { + EnsureCapacityForAdditionalChars(paddingNeeded); + + if (leftAlign) + { + _chars.Slice(_pos, paddingNeeded).Fill(' '); + } + else + { + _chars.Slice(startingPos, charsWritten).CopyTo(_chars[(startingPos + paddingNeeded)..]); + _chars.Slice(startingPos, paddingNeeded).Fill(' '); + } + + _pos += paddingNeeded; + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private void AppendFormattedSlow(string? value) + { + if (value is not null) + { + EnsureCapacityForAdditionalChars(value.Length); + value.CopyTo(_chars[_pos..]); + _pos += value.Length; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void EnsureCapacityForAdditionalChars(int additionalChars) + { + if (_chars.Length - _pos < additionalChars) + { + Grow(additionalChars); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private void GrowThenCopyString(string value) + { + Grow(value.Length); + value.CopyTo(_chars[_pos..]); + _pos += value.Length; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private void GrowThenCopySpan(ReadOnlySpan value) + { + Grow(value.Length); + value.CopyTo(_chars[_pos..]); + _pos += value.Length; + } + + [MethodImpl(MethodImplOptions.NoInlining)] // keep consumers as streamlined as possible + private void Grow(int additionalChars) + { + GrowCore((uint)_pos + (uint)additionalChars); + } + + [MethodImpl(MethodImplOptions.NoInlining)] // keep consumers as streamlined as possible + private void Grow() + { + GrowCore((uint)_chars.Length + 1); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void GrowCore(uint requiredMinCapacity) + { + var newCapacity = Math.Max(requiredMinCapacity, Math.Min((uint)_chars.Length * 2, 1073741823)); + var arraySize = (int)Math.Clamp(newCapacity, 256, int.MaxValue); + + var newArray = ArrayPool.Shared.Rent(arraySize); + _chars[.._pos].CopyTo(newArray); + + var toReturn = _arrayToReturnToPool; + _chars = _arrayToReturnToPool = newArray; + + if (toReturn is not null) + { + ArrayPool.Shared.Return(toReturn); + } + } + + internal ReadOnlySpan Text => _chars[.._pos]; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal void Clear() + { + var toReturn = _arrayToReturnToPool; + this = default; // defensive clear + if (toReturn is not null) + { + ArrayPool.Shared.Return(toReturn); + } + } + + public string ToStringAndClear() + { + if (MoveNext() && _current != null) + { + AppendStringDirect(_current); + } + + var result = new string(Text); + Clear(); + return result; + } + + public char[] ToPooledArray(out int length) + { + if (MoveNext() && _current != null) + { + AppendStringDirect(_current); + } + + length = _pos; + return _arrayToReturnToPool; + } + } } diff --git a/Projects/Server/Localization/LocalizationInterpolationHandler.cs b/Projects/Server/Localization/LocalizationInterpolationHandler.cs deleted file mode 100644 index 2ad07e3b1..000000000 --- a/Projects/Server/Localization/LocalizationInterpolationHandler.cs +++ /dev/null @@ -1,459 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2022 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: LocalizationInterpolationHandler.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -#nullable enable -using System; -using System.Buffers; -using System.Runtime.CompilerServices; - -namespace Server; - -[InterpolatedStringHandler] -public ref struct LocalizationInterpolationHandler -{ - private static string[] _empty = Array.Empty(); - - private char[]? _arrayToReturnToPool; - private Span _chars; - private int _pos; - - private int _index; - private string?[] _slices; - private string? _current; - private string _lang; - - public LocalizationInterpolationHandler(int literalLength, int formattedCount, LocalizationEntry entry, out bool isValid) - { - _slices = entry.TextSlices; - _chars = _arrayToReturnToPool = ArrayPool.Shared.Rent(256); - isValid = true; - - _pos = 0; - _index = 0; - _current = null; - _lang = entry.Language; - } - - public LocalizationInterpolationHandler(int literalLength, int formattedCount, int number, out bool isValid) - : this(literalLength, formattedCount, number, Localization.FallbackLanguage, out isValid) - { - } - - public LocalizationInterpolationHandler(int literalLength, int formattedCount, int number, string lang, out bool isValid) - { - if (Localization.TryGetLocalization(lang, number, out var entry)) - { - _slices = entry.TextSlices; - _chars = _arrayToReturnToPool = ArrayPool.Shared.Rent(256); - isValid = true; - } - else - { - _slices = _empty; - _chars = _arrayToReturnToPool = default; - isValid = false; - } - - _pos = 0; - _index = 0; - _current = null; - _lang = lang; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private bool MoveNext() - { - if ((uint)_index >= (uint)_slices.Length) - { - return false; - } - - _current = _slices[_index++]; - return true; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private bool ReadyToAppend() - { - if (!MoveNext()) - { - return false; - } - - if (_current == null) - { - return true; - } - - AppendStringDirect(_current); - return MoveNext(); - } - - public void AppendLiteral(string value) - { - } - - private void AppendStringDirect(string value) - { - if (value.TryCopyTo(_chars[_pos..])) - { - _pos += value.Length; - } - else - { - GrowThenCopyString(value); - } - } - - public void AppendFormatted(T value) - { - if (!ReadyToAppend()) - { - return; - } - - string? s; - if (value is IFormattable) - { - // If the value can format itself directly into our buffer, do so. - if (value is ISpanFormattable) - { - int charsWritten; - while (!((ISpanFormattable)value).TryFormat(_chars[_pos..], out charsWritten, default, default)) // constrained call avoiding boxing for value types - { - Grow(); - } - - _pos += charsWritten; - return; - } - - s = ((IFormattable)value).ToString(format: null, default); // constrained call avoiding boxing for value types - } - else - { - s = value?.ToString(); - } - - if (s is not null) - { - AppendStringDirect(s); - } - } - - public void AppendFormatted(T value, string? format) - { - if (!ReadyToAppend()) - { - return; - } - - string? s; - if (value is IFormattable) - { - // If the value can format itself directly into our buffer, do so. - if (value is ISpanFormattable) - { - int charsWritten; - while (!((ISpanFormattable)value).TryFormat(_chars[_pos..], out charsWritten, format, default)) // constrained call avoiding boxing for value types - { - Grow(); - } - - _pos += charsWritten; - return; - } - - s = ((IFormattable)value).ToString(format, default); // constrained call avoiding boxing for value types - } - else - { - s = value?.ToString(); - } - - if (s is not null) - { - AppendStringDirect(s); - } - } - - public void AppendFormatted(T value, int alignment) - { - if (!ReadyToAppend()) - { - return; - } - - var startingPos = _pos; - AppendFormatted(value); - if (alignment != 0) - { - AppendOrInsertAlignmentIfNeeded(startingPos, alignment); - } - } - - public void AppendFormatted(T value, int alignment, string? format) - { - if (!ReadyToAppend()) - { - return; - } - - var startingPos = _pos; - AppendFormatted(value, format); - if (alignment != 0) - { - AppendOrInsertAlignmentIfNeeded(startingPos, alignment); - } - } - - public void AppendFormatted(ReadOnlySpan value) - { - if (!ReadyToAppend() || TryAppendClilocNumber(value)) - { - return; - } - - if (value.TryCopyTo(_chars[_pos..])) - { - _pos += value.Length; - } - else - { - GrowThenCopySpan(value); - } - } - - public void AppendFormatted(ReadOnlySpan value, int alignment, string? format = null) - { - if (!ReadyToAppend()) - { - return; - } - - var leftAlign = false; - if (alignment < 0) - { - leftAlign = true; - alignment = -alignment; - } - - var paddingRequired = alignment - value.Length; - if (paddingRequired <= 0) - { - // The value is as large or larger than the required amount of padding, - // so just write the value. - AppendFormatted(value); - return; - } - - // Write the value along with the appropriate padding. - EnsureCapacityForAdditionalChars(value.Length + paddingRequired); - if (leftAlign) - { - value.CopyTo(_chars[_pos..]); - _pos += value.Length; - _chars.Slice(_pos, paddingRequired).Fill(' '); - _pos += paddingRequired; - } - else - { - _chars.Slice(_pos, paddingRequired).Fill(' '); - _pos += paddingRequired; - value.CopyTo(_chars[_pos..]); - _pos += value.Length; - } - } - - public void AppendFormatted(object? value, int alignment = 0, string? format = null) => - AppendFormatted(value, alignment, format); - - public void AppendFormatted(string? value) - { - if (!ReadyToAppend() || TryAppendClilocNumber(value)) - { - return; - } - - if (value?.TryCopyTo(_chars[_pos..]) == true) - { - _pos += value.Length; - } - else - { - AppendFormattedSlow(value); - } - } - - public void AppendFormatted(string? value, int alignment, string? format = null) => - AppendFormatted(value, alignment, format); - - private bool TryAppendClilocNumber(ReadOnlySpan value) - { - if ( - value[0] != '#' || - !int.TryParse(value[1..], out var number) || - !Localization.TryGetLocalization(_lang, number, out var entry) - ) - { - return false; - } - - var text = entry.Text; - - if (text.TryCopyTo(_chars[_pos..])) - { - _pos += text.Length; - } - else - { - AppendFormattedSlow(text); - } - - return true; - } - - private void AppendOrInsertAlignmentIfNeeded(int startingPos, int alignment) - { - var charsWritten = _pos - startingPos; - - var leftAlign = false; - if (alignment < 0) - { - leftAlign = true; - alignment = -alignment; - } - - var paddingNeeded = alignment - charsWritten; - if (paddingNeeded > 0) - { - EnsureCapacityForAdditionalChars(paddingNeeded); - - if (leftAlign) - { - _chars.Slice(_pos, paddingNeeded).Fill(' '); - } - else - { - _chars.Slice(startingPos, charsWritten).CopyTo(_chars[(startingPos + paddingNeeded)..]); - _chars.Slice(startingPos, paddingNeeded).Fill(' '); - } - - _pos += paddingNeeded; - } - } - - [MethodImpl(MethodImplOptions.NoInlining)] - private void AppendFormattedSlow(string? value) - { - if (value is not null) - { - EnsureCapacityForAdditionalChars(value.Length); - value.CopyTo(_chars[_pos..]); - _pos += value.Length; - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void EnsureCapacityForAdditionalChars(int additionalChars) - { - if (_chars.Length - _pos < additionalChars) - { - Grow(additionalChars); - } - } - - [MethodImpl(MethodImplOptions.NoInlining)] - private void GrowThenCopyString(string value) - { - Grow(value.Length); - value.CopyTo(_chars[_pos..]); - _pos += value.Length; - } - - [MethodImpl(MethodImplOptions.NoInlining)] - private void GrowThenCopySpan(ReadOnlySpan value) - { - Grow(value.Length); - value.CopyTo(_chars[_pos..]); - _pos += value.Length; - } - - [MethodImpl(MethodImplOptions.NoInlining)] // keep consumers as streamlined as possible - private void Grow(int additionalChars) - { - GrowCore((uint)_pos + (uint)additionalChars); - } - - [MethodImpl(MethodImplOptions.NoInlining)] // keep consumers as streamlined as possible - private void Grow() - { - GrowCore((uint)_chars.Length + 1); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void GrowCore(uint requiredMinCapacity) - { - var newCapacity = Math.Max(requiredMinCapacity, Math.Min((uint)_chars.Length * 2, 1073741823)); - var arraySize = (int)Math.Clamp(newCapacity, 256, int.MaxValue); - - var newArray = ArrayPool.Shared.Rent(arraySize); - _chars[.._pos].CopyTo(newArray); - - var toReturn = _arrayToReturnToPool; - _chars = _arrayToReturnToPool = newArray; - - if (toReturn is not null) - { - ArrayPool.Shared.Return(toReturn); - } - } - - internal ReadOnlySpan Text => _chars[.._pos]; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void Clear() - { - var toReturn = _arrayToReturnToPool; - this = default; // defensive clear - if (toReturn is not null) - { - ArrayPool.Shared.Return(toReturn); - } - } - - public string ToStringAndClear() - { - if (MoveNext() && _current != null) - { - AppendStringDirect(_current); - } - - var result = new string(Text); - Clear(); - return result; - } - - public char[] ToPooledArray(out int length) - { - if (MoveNext() && _current != null) - { - AppendStringDirect(_current); - } - - length = _pos; - return _arrayToReturnToPool; - } -} From 097c0143b0b5a600b7b02c869035fdd7af21ce8e Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Tue, 10 May 2022 00:42:59 -0700 Subject: [PATCH 156/213] fix: Fixes missing localization interpolation handler (#1016) --- Projects/Server/Localization/LocalizationEntry.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Projects/Server/Localization/LocalizationEntry.cs b/Projects/Server/Localization/LocalizationEntry.cs index c2914601f..9bb2d4540 100644 --- a/Projects/Server/Localization/LocalizationEntry.cs +++ b/Projects/Server/Localization/LocalizationEntry.cs @@ -146,7 +146,15 @@ public class LocalizationEntry _lang = entry.Language; } - public LocalizationInterpolationHandler(int literalLength, int formattedCount, int number, string lang, out bool isValid) + public LocalizationInterpolationHandler( + int literalLength, int formattedCount, int number, out bool isValid + ) : this(literalLength, formattedCount, number, Localization.FallbackLanguage, out isValid) + { + } + + public LocalizationInterpolationHandler( + int literalLength, int formattedCount, int number, string lang, out bool isValid + ) { if (Localization.TryGetLocalization(lang, number, out var entry)) { From f7cbeacf4803058af4f43d37736e0eb3cce3d5b8 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Tue, 10 May 2022 11:57:37 -0700 Subject: [PATCH 157/213] fix: Fixes factions and makes it static (#993) --- Projects/Server/Serialization/Persistence.cs | 2 + .../Engines/Factions/Core/FactionSystem.cs | 120 ++++++++++++++++++ .../Engines/Factions/Core/Generator.cs | 2 +- .../Engines/Factions/Core/Persistance.cs | 91 ------------- .../Engines/Stealables/StealableArtifacts.cs | 7 +- 5 files changed, 129 insertions(+), 93 deletions(-) create mode 100644 Projects/UOContent/Engines/Factions/Core/FactionSystem.cs delete mode 100644 Projects/UOContent/Engines/Factions/Core/Persistance.cs diff --git a/Projects/Server/Serialization/Persistence.cs b/Projects/Server/Serialization/Persistence.cs index c4abd1458..8c76165c7 100644 --- a/Projects/Server/Serialization/Persistence.cs +++ b/Projects/Server/Serialization/Persistence.cs @@ -46,6 +46,8 @@ namespace Server ); } + public static void Unregister(string name) => _registry.RemoveWhere(entry => entry.Name == name); + public static void Load(string path) { // This should probably not be parallel since Mobiles must be loaded before Items diff --git a/Projects/UOContent/Engines/Factions/Core/FactionSystem.cs b/Projects/UOContent/Engines/Factions/Core/FactionSystem.cs new file mode 100644 index 000000000..e1513b0a4 --- /dev/null +++ b/Projects/UOContent/Engines/Factions/Core/FactionSystem.cs @@ -0,0 +1,120 @@ +using System; + +namespace Server.Factions; + +public static class FactionSystem +{ + public static bool Enabled { get; private set; } + + public static void Configure() + { + Enabled = ServerConfiguration.GetSetting("factions.enabled", false); + + if (Enabled) + { + GenericPersistence.Register("Factions", Serialize, Deserialize); + } + } + + // This does not do the actual work of removing faction stuff, only turns off the persistence. + public static void Disable() + { + if (!Enabled) + { + return; + } + + Persistence.Unregister("Factions"); + Enabled = false; + ServerConfiguration.SetSetting("factions.enabled", false); + } + + // This does not do the actual work of creating faction stuff, only turns on the persistence. + public static void Enable() + { + if (Enabled) + { + return; + } + + GenericPersistence.Register("Factions", Serialize, Deserialize); + Enabled = true; + ServerConfiguration.SetSetting("factions.enabled", true); + } + + private static void Serialize(IGenericWriter writer) + { + writer.WriteEncodedInt(0); // version + + var factions = Faction.Factions; + + for (var i = 0; i < factions.Count; i++) + { + factions[i].State.Serialize(writer); + } + + var towns = Town.Towns; + + for (var i = 0; i < towns.Count; i++) + { + towns[i].State.Serialize(writer); + } + } + + private static void Deserialize(IGenericReader reader) + { + var version = reader.ReadEncodedInt(); + + var count = reader.ReadEncodedInt(); + for (var i = 0; i < count; i++) + { + new FactionState(reader); + } + + count = reader.ReadEncodedInt(); + for (var i = 0; i < count; i++) + { + new TownState(reader); + } + } +} + +[ManualDirtyChecking] +[TypeAlias("Server.Factions.FactionPersistance")] +[Obsolete("Deprecated in favor of the static system. Only used for legacy deserialization")] +public class FactionPersistence : Item +{ + public FactionPersistence() + { + Delete(); + } + + public FactionPersistence(Serial serial) : base(serial) + { + } + + public override void Serialize(IGenericWriter writer) + { + } + + public override void Deserialize(IGenericReader reader) + { + base.Deserialize(reader); + + var version = reader.ReadInt(); + + int type; + + while ((type = reader.ReadEncodedInt()) != 0) + { + if (type == 1) + { + new FactionState(reader); + } + else if (type == 2) + { + new TownState(reader); + } + } + } +} diff --git a/Projects/UOContent/Engines/Factions/Core/Generator.cs b/Projects/UOContent/Engines/Factions/Core/Generator.cs index 13e255343..de45b99a8 100644 --- a/Projects/UOContent/Engines/Factions/Core/Generator.cs +++ b/Projects/UOContent/Engines/Factions/Core/Generator.cs @@ -11,7 +11,7 @@ namespace Server.Factions public static void GenerateFactions_OnCommand(CommandEventArgs e) { - new FactionPersistance(); + FactionSystem.Enable(); var factions = Faction.Factions; diff --git a/Projects/UOContent/Engines/Factions/Core/Persistance.cs b/Projects/UOContent/Engines/Factions/Core/Persistance.cs deleted file mode 100644 index 882ac72d0..000000000 --- a/Projects/UOContent/Engines/Factions/Core/Persistance.cs +++ /dev/null @@ -1,91 +0,0 @@ -namespace Server.Factions -{ - public class FactionPersistance : Item - { - public FactionPersistance() : base(1) - { - Movable = false; - - if (Instance?.Deleted == true) - { - Instance = this; - } - else - { - base.Delete(); - } - } - - public FactionPersistance(Serial serial) : base(serial) => Instance = this; - - public static FactionPersistance Instance { get; private set; } - - public override string DefaultName => "Faction Persistance - Internal"; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); // version - - var factions = Faction.Factions; - - for (var i = 0; i < factions.Count; ++i) - { - writer.WriteEncodedInt((int)PersistedType.Faction); - factions[i].State.Serialize(writer); - } - - var towns = Town.Towns; - - for (var i = 0; i < towns.Count; ++i) - { - writer.WriteEncodedInt((int)PersistedType.Town); - towns[i].State.Serialize(writer); - } - - writer.WriteEncodedInt((int)PersistedType.Terminator); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - switch (version) - { - case 0: - { - PersistedType type; - - while ((type = (PersistedType)reader.ReadEncodedInt()) != PersistedType.Terminator) - { - switch (type) - { - case PersistedType.Faction: - new FactionState(reader); - break; - case PersistedType.Town: - new TownState(reader); - break; - } - } - - break; - } - } - } - - public override void Delete() - { - } - - private enum PersistedType - { - Terminator, - Faction, - Town - } - } -} diff --git a/Projects/UOContent/Engines/Stealables/StealableArtifacts.cs b/Projects/UOContent/Engines/Stealables/StealableArtifacts.cs index d3e2d2219..5b2112386 100644 --- a/Projects/UOContent/Engines/Stealables/StealableArtifacts.cs +++ b/Projects/UOContent/Engines/Stealables/StealableArtifacts.cs @@ -19,7 +19,7 @@ public static class StealableArtifacts public static void Configure() { - GenericPersistence.Register("stealable-artifacts", Serialize, Deserialize); + GenericPersistence.Register("StealableArtifacts", Serialize, Deserialize); } private static void RemoveStealableArtifacts() @@ -426,12 +426,17 @@ public static class StealableArtifacts { private StealableArtifactsSpawner() { + Delete(); } public StealableArtifactsSpawner(Serial serial) : base(serial) { } + public override void Serialize(IGenericWriter writer) + { + } + public override void Deserialize(IGenericReader reader) { base.Deserialize(reader); From 87b63b38a53d61eb7287d7dd1b2525868cd14be4 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Tue, 10 May 2022 18:50:23 -0700 Subject: [PATCH 158/213] fix: Eliminates string allocations while writing gump packets (#1017) * Introduces `RawInterpolatedStringHandler` which is exactly the same as `DefaultInterpolatedStringHandler` except it _unsafely exposes_ it's `ReadOnlySpan` buffer. This is useful for writing the string's data without actually building the string. * Uses this new string interpolation handler in `SpanWriter` to eliminate intermediate strings built. This is immensely useful in eliminating string allocations in writing Gump packets. --- .../Server/Buffers/CircularBufferReader.cs | 16 +- .../Buffers/PooledArraySpanFormattable.cs | 3 +- .../Buffers/RawInterpolatedStringHandler.cs | 600 ++++++++++++++++++ Projects/Server/Buffers/SpanReader.cs | 8 +- Projects/Server/Buffers/SpanWriter.cs | 76 ++- .../Server/Localization/LocalizationEntry.cs | 12 +- Projects/Server/Text/TextEncoding.cs | 2 +- 7 files changed, 674 insertions(+), 43 deletions(-) create mode 100644 Projects/Server/Buffers/RawInterpolatedStringHandler.cs diff --git a/Projects/Server/Buffers/CircularBufferReader.cs b/Projects/Server/Buffers/CircularBufferReader.cs index 40eeafc2f..aa8b9aa08 100644 --- a/Projects/Server/Buffers/CircularBufferReader.cs +++ b/Projects/Server/Buffers/CircularBufferReader.cs @@ -245,7 +245,7 @@ namespace Server.Network [MethodImpl(MethodImplOptions.AggressiveInlining)] public string ReadString(Encoding encoding, bool safeString = false, int fixedLength = -1) { - int sizeT = TextEncoding.GetByteLengthForEncoding(encoding); + int byteLength = encoding.GetByteLengthForEncoding(); bool isFixedLength = fixedLength > -1; @@ -254,7 +254,7 @@ namespace Server.Network if (isFixedLength) { - size = fixedLength * sizeT; + size = fixedLength * byteLength; if (size > Remaining) { throw new OutOfMemoryException(); @@ -262,7 +262,7 @@ namespace Server.Network } else { - size = remaining - (remaining & (sizeT - 1)); + size = remaining - (remaining & (byteLength - 1)); } ReadOnlySpan span; @@ -273,7 +273,7 @@ namespace Server.Network var firstLength = Math.Min(_first.Length - Position, size); // Find terminator - index = _first.Slice(Position, firstLength).IndexOfTerminator(sizeT); + index = _first.Slice(Position, firstLength).IndexOfTerminator(byteLength); if (index < 0) { @@ -285,7 +285,7 @@ namespace Server.Network } else { - index = _second[..remaining].IndexOfTerminator(sizeT); + index = _second[..remaining].IndexOfTerminator(byteLength); int secondLength = index < 0 ? remaining : index; int length = firstLength + secondLength; @@ -295,7 +295,7 @@ namespace Server.Network _first[Position..].CopyTo(bytes); _second[..secondLength].CopyTo(bytes[firstLength..]); - Position += length + (index >= 0 ? sizeT : 0); + Position += length + (index >= 0 ? byteLength : 0); return TextEncoding.GetString(bytes, encoding, safeString); } } @@ -306,7 +306,7 @@ namespace Server.Network { size = Math.Min(remaining, size); span = _second.Slice( Position - _first.Length, size); - index = span.IndexOfTerminator(sizeT); + index = span.IndexOfTerminator(byteLength); if (index >= 0) { @@ -318,7 +318,7 @@ namespace Server.Network } } - Position += isFixedLength ? size : index + sizeT; + Position += isFixedLength ? size : index + byteLength; return TextEncoding.GetString(span, encoding, safeString); } diff --git a/Projects/Server/Buffers/PooledArraySpanFormattable.cs b/Projects/Server/Buffers/PooledArraySpanFormattable.cs index 50e7df384..a210a7ff9 100644 --- a/Projects/Server/Buffers/PooledArraySpanFormattable.cs +++ b/Projects/Server/Buffers/PooledArraySpanFormattable.cs @@ -15,7 +15,6 @@ #nullable enable using System; -using System.Buffers; namespace Server.Buffers; @@ -64,7 +63,7 @@ public struct PooledArraySpanFormattable : ISpanFormattable, IDisposable { if (_arrayToReturnToPool != null) { - ArrayPool.Shared.Return(_arrayToReturnToPool); + STArrayPool.Shared.Return(_arrayToReturnToPool); _arrayToReturnToPool = null; } } diff --git a/Projects/Server/Buffers/RawInterpolatedStringHandler.cs b/Projects/Server/Buffers/RawInterpolatedStringHandler.cs new file mode 100644 index 000000000..20c996ead --- /dev/null +++ b/Projects/Server/Buffers/RawInterpolatedStringHandler.cs @@ -0,0 +1,600 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Diagnostics; +using System.Globalization; +using System.Runtime.CompilerServices; + +namespace Server.Buffers; + +/// Provides a handler to interpolate strings which UNSAFELY exposes it's internal character span. +[InterpolatedStringHandler] +public ref struct RawInterpolatedStringHandler +{ + // Implementation note: + // As this type lives in CompilerServices and is only intended to be targeted by the compiler, + // public APIs eschew argument validation logic in a variety of places, e.g. allowing a null input + // when one isn't expected to produce a NullReferenceException rather than an ArgumentNullException. + + /// Expected average length of formatted data used for an individual interpolation expression result. + /// + /// This is inherited from string.Format, and could be changed based on further data. + /// string.Format actually uses `format.Length + args.Length * 8`, but format.Length + /// includes the format items themselves, e.g. "{0}", and since it's rare to have double-digit + /// numbers of items, we bump the 8 up to 11 to account for the three extra characters in "{d}", + /// since the compiler-provided base length won't include the equivalent character count. + /// + private const int GuessedLengthPerHole = 11; + /// Minimum size array to rent from the pool. + /// Same as stack-allocation size used today by string.Format. + private const int MinimumArrayPoolLength = 256; + + /// Optional provider to pass to IFormattable.ToString or ISpanFormattable.TryFormat calls. + private readonly IFormatProvider? _provider; + /// Array rented from the array pool and used to back . + private char[]? _arrayToReturnToPool; + /// The span to write into. + private Span _chars; + /// Position at which to write the next character. + private int _pos; + /// Whether provides an ICustomFormatter. + /// + /// Custom formatters are very rare. We want to support them, but it's ok if we make them more expensive + /// in order to make them as pay-for-play as possible. So, we avoid adding another reference type field + /// to reduce the size of the handler and to reduce required zero'ing, by only storing whether the provider + /// provides a formatter, rather than actually storing the formatter. This in turn means, if there is a + /// formatter, we pay for the extra interface call on each AppendFormatted that needs it. + /// + private readonly bool _hasCustomFormatter; + + /// Creates a handler used to translate an interpolated string into a . + /// The number of constant characters outside of interpolation expressions in the interpolated string. + /// The number of interpolation expressions in the interpolated string. + /// This is intended to be called only by compiler-generated code. Arguments are not validated as they'd otherwise be for members intended to be used directly. + public RawInterpolatedStringHandler(int literalLength, int formattedCount) + { + _provider = null; + _chars = _arrayToReturnToPool = STArrayPool.Shared.Rent(GetDefaultLength(literalLength, formattedCount)); + _pos = 0; + _hasCustomFormatter = false; + } + + /// Creates a handler used to translate an interpolated string into a . + /// The number of constant characters outside of interpolation expressions in the interpolated string. + /// The number of interpolation expressions in the interpolated string. + /// An object that supplies culture-specific formatting information. + /// This is intended to be called only by compiler-generated code. Arguments are not validated as they'd otherwise be for members intended to be used directly. + public RawInterpolatedStringHandler(int literalLength, int formattedCount, IFormatProvider? provider) + { + _provider = provider; + _chars = _arrayToReturnToPool = STArrayPool.Shared.Rent(GetDefaultLength(literalLength, formattedCount)); + _pos = 0; + _hasCustomFormatter = provider is not null && HasCustomFormatter(provider); + } + + /// Derives a default length with which to seed the handler. + /// The number of constant characters outside of interpolation expressions in the interpolated string. + /// The number of interpolation expressions in the interpolated string. + [MethodImpl(MethodImplOptions.AggressiveInlining)] // becomes a constant when inputs are constant + internal static int GetDefaultLength(int literalLength, int formattedCount) => + Math.Max(MinimumArrayPoolLength, literalLength + (formattedCount * GuessedLengthPerHole)); + + /// Clears the handler, returning any rented array to the pool. + [MethodImpl(MethodImplOptions.AggressiveInlining)] // used only on a few hot paths + public void Clear() + { + char[]? toReturn = _arrayToReturnToPool; + this = default; // defensive clear + if (toReturn is not null) + { + STArrayPool.Shared.Return(toReturn); + } + } + + /// Gets a span of the written characters thus far. + public ReadOnlySpan Text => _chars[.._pos]; + + /// Writes the specified string to the handler. + /// The string to write. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLiteral(string value) + { + if (value.Length == 1) + { + Span chars = _chars; + int pos = _pos; + if ((uint)pos < (uint)chars.Length) + { + chars[pos] = value[0]; + _pos = pos + 1; + } + else + { + GrowThenCopyString(value); + } + return; + } + + AppendStringDirect(value); + } + + /// Writes the specified string to the handler. + /// The string to write. + private void AppendStringDirect(string value) + { + if (value.TryCopyTo(_chars[_pos..])) + { + _pos += value.Length; + } + else + { + GrowThenCopyString(value); + } + } + + #region AppendFormatted + // Design note: + // The compiler requires a AppendFormatted overload for anything that might be within an interpolation expression; + // if it can't find an appropriate overload, for handlers in general it'll simply fail to compile. + // (For target-typing to string where it uses DefaultInterpolatedStringHandler implicitly, it'll instead fall back to + // its other mechanisms, e.g. using string.Format. This fallback has the benefit that if we miss a case, + // interpolated strings will still work, but it has the downside that a developer generally won't know + // if the fallback is happening and they're paying more.) + // + // At a minimum, then, we would need an overload that accepts: + // (object value, int alignment = 0, string? format = null) + // Such an overload would provide the same expressiveness as string.Format. However, this has several + // shortcomings: + // - Every value type in an interpolation expression would be boxed. + // - ReadOnlySpan could not be used in interpolation expressions. + // - Every AppendFormatted call would have three arguments at the call site, bloating the IL further. + // - Every invocation would be more expensive, due to lack of specialization, every call needing to account + // for alignment and format, etc. + // + // To address that, we could just have overloads for T and ReadOnlySpan: + // (T) + // (T, int alignment) + // (T, string? format) + // (T, int alignment, string? format) + // (ReadOnlySpan) + // (ReadOnlySpan, int alignment) + // (ReadOnlySpan, string? format) + // (ReadOnlySpan, int alignment, string? format) + // but this also has shortcomings: + // - Some expressions that would have worked with an object overload will now force a fallback to string.Format + // (or fail to compile if the handler is used in places where the fallback isn't provided), because the compiler + // can't always target type to T, e.g. `b switch { true => 1, false => null }` where `b` is a bool can successfully + // be passed as an argument of type `object` but not of type `T`. + // - Reference types get no benefit from going through the generic code paths, and actually incur some overheads + // from doing so. + // - Nullable value types also pay a heavy price, in particular around interface checks that would generally evaporate + // at compile time for value types but don't (currently) if the Nullable goes through the same code paths + // (see https://github.com/dotnet/runtime/issues/50915). + // + // We could try to take a more elaborate approach for DefaultInterpolatedStringHandler, since it is the most common handler + // and we want to minimize overheads both at runtime and in IL size, e.g. have a complete set of overloads for each of: + // (T, ...) where T : struct + // (T?, ...) where T : struct + // (object, ...) + // (ReadOnlySpan, ...) + // (string, ...) + // but this also has shortcomings, most importantly: + // - If you have an unconstrained T that happens to be a value type, it'll now end up getting boxed to use the object overload. + // This also necessitates the T? overload, since nullable value types don't meet a T : struct constraint, so without those + // they'd all map to the object overloads as well. + // - Any reference type with an implicit cast to ROS will fail to compile due to ambiguities between the overloads. string + // is one such type, hence needing dedicated overloads for it that can be bound to more tightly. + // + // A middle ground we've settled on, which is likely to be the right approach for most other handlers as well, would be the set: + // (T, ...) with no constraint + // (ReadOnlySpan) and (ReadOnlySpan, int) + // (object, int alignment = 0, string? format = null) + // (string) and (string, int) + // This would address most of the concerns, at the expense of: + // - Most reference types going through the generic code paths and so being a bit more expensive. + // - Nullable types being more expensive until https://github.com/dotnet/runtime/issues/50915 is addressed. + // We could choose to add a T? where T : struct set of overloads if necessary. + // Strings don't require their own overloads here, but as they're expected to be very common and as we can + // optimize them in several ways (can copy the contents directly, don't need to do any interface checks, don't + // need to pay the shared generic overheads, etc.) we can add overloads specifically to optimize for them. + // + // Hole values are formatted according to the following policy: + // 1. If an IFormatProvider was supplied and it provides an ICustomFormatter, use ICustomFormatter.Format (even if the value is null). + // 2. If the type implements ISpanFormattable, use ISpanFormattable.TryFormat. + // 3. If the type implements IFormattable, use IFormattable.ToString. + // 4. Otherwise, use object.ToString. + // This matches the behavior of string.Format, StringBuilder.AppendFormat, etc. The only overloads for which this doesn't + // apply is ReadOnlySpan, which isn't supported by either string.Format nor StringBuilder.AppendFormat, but more + // importantly which can't be boxed to be passed to ICustomFormatter.Format. + + #region AppendFormatted T + /// Writes the specified value to the handler. + /// The value to write. + public void AppendFormatted(T value) + { + // This method could delegate to AppendFormatted with a null format, but explicitly passing + // default as the format to TryFormat helps to improve code quality in some cases when TryFormat is inlined, + // e.g. for Int32 it enables the JIT to eliminate code in the inlined method based on a length check on the format. + + // If there's a custom formatter, always use it. + if (_hasCustomFormatter) + { + AppendCustomFormatter(value, format: null); + return; + } + + // Check first for IFormattable, even though we'll prefer to use ISpanFormattable, as the latter + // requires the former. For value types, it won't matter as the type checks devolve into + // JIT-time constants. For reference types, they're more likely to implement IFormattable + // than they are to implement ISpanFormattable: if they don't implement either, we save an + // interface check over first checking for ISpanFormattable and then for IFormattable, and + // if it only implements IFormattable, we come out even: only if it implements both do we + // end up paying for an extra interface check. + string? s; + if (value is IFormattable) + { + // If the value can format itself directly into our buffer, do so. + if (value is ISpanFormattable) + { + int charsWritten; + while (!((ISpanFormattable)value).TryFormat(_chars[_pos..], out charsWritten, default, _provider)) // constrained call avoiding boxing for value types + { + Grow(); + } + + _pos += charsWritten; + return; + } + + s = ((IFormattable)value).ToString(format: null, _provider); // constrained call avoiding boxing for value types + } + else + { + s = value?.ToString(); + } + + if (s is not null) + { + AppendStringDirect(s); + } + } + /// Writes the specified value to the handler. + /// The value to write. + /// The format string. + public void AppendFormatted(T value, string? format) + { + // If there's a custom formatter, always use it. + if (_hasCustomFormatter) + { + AppendCustomFormatter(value, format); + return; + } + + // Check first for IFormattable, even though we'll prefer to use ISpanFormattable, as the latter + // requires the former. For value types, it won't matter as the type checks devolve into + // JIT-time constants. For reference types, they're more likely to implement IFormattable + // than they are to implement ISpanFormattable: if they don't implement either, we save an + // interface check over first checking for ISpanFormattable and then for IFormattable, and + // if it only implements IFormattable, we come out even: only if it implements both do we + // end up paying for an extra interface check. + string? s; + if (value is IFormattable) + { + // If the value can format itself directly into our buffer, do so. + if (value is ISpanFormattable) + { + int charsWritten; + while (!((ISpanFormattable)value).TryFormat(_chars[_pos..], out charsWritten, format, _provider)) // constrained call avoiding boxing for value types + { + Grow(); + } + + _pos += charsWritten; + return; + } + + s = ((IFormattable)value).ToString(format, _provider); // constrained call avoiding boxing for value types + } + else + { + s = value?.ToString(); + } + + if (s is not null) + { + AppendStringDirect(s); + } + } + + /// Writes the specified value to the handler. + /// The value to write. + /// Minimum number of characters that should be written for this value. If the value is negative, it indicates left-aligned and the required minimum is the absolute value. + public void AppendFormatted(T value, int alignment) + { + int startingPos = _pos; + AppendFormatted(value); + if (alignment != 0) + { + AppendOrInsertAlignmentIfNeeded(startingPos, alignment); + } + } + + /// Writes the specified value to the handler. + /// The value to write. + /// The format string. + /// Minimum number of characters that should be written for this value. If the value is negative, it indicates left-aligned and the required minimum is the absolute value. + public void AppendFormatted(T value, int alignment, string? format) + { + int startingPos = _pos; + AppendFormatted(value, format); + if (alignment != 0) + { + AppendOrInsertAlignmentIfNeeded(startingPos, alignment); + } + } + #endregion + + #region AppendFormatted ReadOnlySpan + /// Writes the specified character span to the handler. + /// The span to write. + public void AppendFormatted(ReadOnlySpan value) + { + // Fast path for when the value fits in the current buffer + if (value.TryCopyTo(_chars[_pos..])) + { + _pos += value.Length; + } + else + { + GrowThenCopySpan(value); + } + } + + /// Writes the specified string of chars to the handler. + /// The span to write. + /// Minimum number of characters that should be written for this value. If the value is negative, it indicates left-aligned and the required minimum is the absolute value. + /// The format string. + public void AppendFormatted(ReadOnlySpan value, int alignment = 0, string? format = null) + { + bool leftAlign = false; + if (alignment < 0) + { + leftAlign = true; + alignment = -alignment; + } + + int paddingRequired = alignment - value.Length; + if (paddingRequired <= 0) + { + // The value is as large or larger than the required amount of padding, + // so just write the value. + AppendFormatted(value); + return; + } + + // Write the value along with the appropriate padding. + EnsureCapacityForAdditionalChars(value.Length + paddingRequired); + if (leftAlign) + { + value.CopyTo(_chars[_pos..]); + _pos += value.Length; + _chars.Slice(_pos, paddingRequired).Fill(' '); + _pos += paddingRequired; + } + else + { + _chars.Slice(_pos, paddingRequired).Fill(' '); + _pos += paddingRequired; + value.CopyTo(_chars[_pos..]); + _pos += value.Length; + } + } + #endregion + + #region AppendFormatted string + /// Writes the specified value to the handler. + /// The value to write. + public void AppendFormatted(string? value) + { + // Fast-path for no custom formatter and a non-null string that fits in the current destination buffer. + if (!_hasCustomFormatter && value?.TryCopyTo(_chars[_pos..]) == true) + { + _pos += value.Length; + } + else + { + AppendFormattedSlow(value); + } + } + + /// Writes the specified value to the handler. + /// The value to write. + /// + /// Slow path to handle a custom formatter, potentially null value, + /// or a string that doesn't fit in the current buffer. + /// + [MethodImpl(MethodImplOptions.NoInlining)] + private void AppendFormattedSlow(string? value) + { + if (_hasCustomFormatter) + { + AppendCustomFormatter(value, format: null); + } + else if (value is not null) + { + EnsureCapacityForAdditionalChars(value.Length); + value.CopyTo(_chars[_pos..]); + _pos += value.Length; + } + } + + /// Writes the specified value to the handler. + /// The value to write. + /// Minimum number of characters that should be written for this value. If the value is negative, it indicates left-aligned and the required minimum is the absolute value. + /// The format string. + public void AppendFormatted(string? value, int alignment = 0, string? format = null) => + // Format is meaningless for strings and doesn't make sense for someone to specify. We have the overload + // simply to disambiguate between ROS and object, just in case someone does specify a format, as + // string is implicitly convertible to both. Just delegate to the T-based implementation. + AppendFormatted(value, alignment, format); + #endregion + + #region AppendFormatted object + /// Writes the specified value to the handler. + /// The value to write. + /// Minimum number of characters that should be written for this value. If the value is negative, it indicates left-aligned and the required minimum is the absolute value. + /// The format string. + public void AppendFormatted(object? value, int alignment = 0, string? format = null) => + // This overload is expected to be used rarely, only if either a) something strongly typed as object is + // formatted with both an alignment and a format, or b) the compiler is unable to target type to T. It + // exists purely to help make cases from (b) compile. Just delegate to the T-based implementation. + AppendFormatted(value, alignment, format); + #endregion + #endregion + + /// Gets whether the provider provides a custom formatter. + [MethodImpl(MethodImplOptions.AggressiveInlining)] // only used in a few hot path call sites + internal static bool HasCustomFormatter(IFormatProvider provider) + { + Debug.Assert(provider is not null); + Debug.Assert(provider is not CultureInfo || provider.GetFormat(typeof(ICustomFormatter)) is null, "Expected CultureInfo to not provide a custom formatter"); + return + provider.GetType() != typeof(CultureInfo) && // optimization to avoid GetFormat in the majority case + provider.GetFormat(typeof(ICustomFormatter)) != null; + } + + /// Formats the value using the custom formatter from the provider. + /// The value to write. + /// The format string. + [MethodImpl(MethodImplOptions.NoInlining)] + private void AppendCustomFormatter(T value, string? format) + { + // This case is very rare, but we need to handle it prior to the other checks in case + // a provider was used that supplied an ICustomFormatter which wanted to intercept the particular value. + // We do the cast here rather than in the ctor, even though this could be executed multiple times per + // formatting, to make the cast pay for play. + Debug.Assert(_hasCustomFormatter); + Debug.Assert(_provider != null); + + ICustomFormatter? formatter = (ICustomFormatter?)_provider.GetFormat(typeof(ICustomFormatter)); + Debug.Assert(formatter != null, "An incorrectly written provider said it implemented ICustomFormatter, and then didn't"); + + if (formatter?.Format(format, value, _provider) is string customFormatted) + { + AppendStringDirect(customFormatted); + } + } + + /// Handles adding any padding required for aligning a formatted value in an interpolation expression. + /// The position at which the written value started. + /// Non-zero minimum number of characters that should be written for this value. If the value is negative, it indicates left-aligned and the required minimum is the absolute value. + private void AppendOrInsertAlignmentIfNeeded(int startingPos, int alignment) + { + Debug.Assert(startingPos >= 0 && startingPos <= _pos); + Debug.Assert(alignment != 0); + + int charsWritten = _pos - startingPos; + + bool leftAlign = false; + if (alignment < 0) + { + leftAlign = true; + alignment = -alignment; + } + + int paddingNeeded = alignment - charsWritten; + if (paddingNeeded > 0) + { + EnsureCapacityForAdditionalChars(paddingNeeded); + + if (leftAlign) + { + _chars.Slice(_pos, paddingNeeded).Fill(' '); + } + else + { + _chars.Slice(startingPos, charsWritten).CopyTo(_chars[(startingPos + paddingNeeded)..]); + _chars.Slice(startingPos, paddingNeeded).Fill(' '); + } + + _pos += paddingNeeded; + } + } + + /// Ensures has the capacity to store beyond . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void EnsureCapacityForAdditionalChars(int additionalChars) + { + if (_chars.Length - _pos < additionalChars) + { + Grow(additionalChars); + } + } + + /// Fallback for fast path in when there's not enough space in the destination. + /// The string to write. + [MethodImpl(MethodImplOptions.NoInlining)] + private void GrowThenCopyString(string value) + { + Grow(value.Length); + value.CopyTo(_chars[_pos..]); + _pos += value.Length; + } + + /// Fallback for for when not enough space exists in the current buffer. + /// The span to write. + [MethodImpl(MethodImplOptions.NoInlining)] + private void GrowThenCopySpan(ReadOnlySpan value) + { + Grow(value.Length); + value.CopyTo(_chars[_pos..]); + _pos += value.Length; + } + + /// Grows to have the capacity to store at least beyond . + [MethodImpl(MethodImplOptions.NoInlining)] // keep consumers as streamlined as possible + private void Grow(int additionalChars) + { + // This method is called when the remaining space (_chars.Length - _pos) is + // insufficient to store a specific number of additional characters. Thus, we + // need to grow to at least that new total. GrowCore will handle growing by more + // than that if possible. + Debug.Assert(additionalChars > _chars.Length - _pos); + GrowCore((uint)_pos + (uint)additionalChars); + } + + /// Grows the size of . + [MethodImpl(MethodImplOptions.NoInlining)] // keep consumers as streamlined as possible + private void Grow() + { + // This method is called when the remaining space in _chars isn't sufficient to continue + // the operation. Thus, we need at least one character beyond _chars.Length. GrowCore + // will handle growing by more than that if possible. + GrowCore((uint)_chars.Length + 1); + } + + /// Grow the size of to at least the specified . + [MethodImpl(MethodImplOptions.AggressiveInlining)] // but reuse this grow logic directly in both of the above grow routines + private void GrowCore(uint requiredMinCapacity) + { + // We want the max of how much space we actually required and doubling our capacity (without going beyond the max allowed length). We + // also want to avoid asking for small arrays, to reduce the number of times we need to grow, and since we're working with unsigned + // ints that could technically overflow if someone tried to, for example, append a huge string to a huge string, we also clamp to int.MaxValue. + // Even if the array creation fails in such a case, we may later fail in ToStringAndClear. + + uint newCapacity = Math.Max(requiredMinCapacity, Math.Min((uint)_chars.Length * 2, 0x3FFFFFDF)); + int arraySize = (int)Math.Clamp(newCapacity, MinimumArrayPoolLength, int.MaxValue); + + char[] newArray = STArrayPool.Shared.Rent(arraySize); + _chars[.._pos].CopyTo(newArray); + + char[]? toReturn = _arrayToReturnToPool; + _chars = _arrayToReturnToPool = newArray; + + if (toReturn is not null) + { + STArrayPool.Shared.Return(toReturn); + } + } +} diff --git a/Projects/Server/Buffers/SpanReader.cs b/Projects/Server/Buffers/SpanReader.cs index d9459c8f2..cbff16597 100644 --- a/Projects/Server/Buffers/SpanReader.cs +++ b/Projects/Server/Buffers/SpanReader.cs @@ -166,7 +166,7 @@ namespace System.Buffers [MethodImpl(MethodImplOptions.AggressiveInlining)] public string ReadString(Encoding encoding, bool safeString = false, int fixedLength = -1) { - int sizeT = TextEncoding.GetByteLengthForEncoding(encoding); + int byteLength = encoding.GetByteLengthForEncoding(); bool isFixedLength = fixedLength > -1; @@ -174,7 +174,7 @@ namespace System.Buffers int size; if (isFixedLength) { - size = fixedLength * sizeT; + size = fixedLength * byteLength; if (size > Remaining) { throw new OutOfMemoryException(); @@ -183,8 +183,8 @@ namespace System.Buffers else { // In case the remaining is not evenly divisible - size = remaining - (remaining & (sizeT - 1)); - int index = _buffer.Slice(Position, size).IndexOfTerminator(sizeT); + size = remaining - (remaining & (byteLength - 1)); + int index = _buffer.Slice(Position, size).IndexOfTerminator(byteLength); size = index < 0 ? size : index; } diff --git a/Projects/Server/Buffers/SpanWriter.cs b/Projects/Server/Buffers/SpanWriter.cs index 89981cc5e..aaf7b17f3 100644 --- a/Projects/Server/Buffers/SpanWriter.cs +++ b/Projects/Server/Buffers/SpanWriter.cs @@ -16,6 +16,7 @@ using System.Buffers.Binary; using System.Data; using System.Diagnostics; +using System.Globalization; using System.IO; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -275,21 +276,52 @@ public ref struct SpanWriter [MethodImpl(MethodImplOptions.AggressiveInlining)] public void WriteAscii(char chr) => Write((byte)chr); - public void WriteString(string value, Encoding encoding, int fixedLength = -1) where T : struct, IEquatable + public void WriteAscii( + ref RawInterpolatedStringHandler handler) { - int sizeT = Unsafe.SizeOf(); + Write(handler.Text, Encoding.ASCII); + handler.Clear(); + } - if (sizeT > 2) + public void WriteAscii( + IFormatProvider? formatProvider, + [InterpolatedStringHandlerArgument("formatProvider")] + ref RawInterpolatedStringHandler handler) + { + Write(handler.Text, Encoding.ASCII); + handler.Clear(); + } + + public void Write( + Encoding encoding, + ref RawInterpolatedStringHandler handler) + { + Write(handler.Text, encoding); + handler.Clear(); + } + + public void Write( + Encoding encoding, + IFormatProvider? formatProvider, + [InterpolatedStringHandlerArgument("formatProvider")] + ref RawInterpolatedStringHandler handler) + { + Write(handler.Text, encoding); + handler.Clear(); + } + + public void Write(ReadOnlySpan value, Encoding encoding, int fixedLength = -1) + { + var charLength = Math.Min(fixedLength > -1 ? fixedLength : value.Length, value.Length); + var src = value[..charLength]; + + var byteLength = encoding.GetByteLengthForEncoding(); + var byteCount = encoding.GetByteCount(src); + if (fixedLength > src.Length) { - throw new InvalidConstraintException("WriteString only accepts byte, sbyte, char, short, and ushort as a constraint"); + byteCount += (fixedLength - src.Length) * byteLength; } - value ??= string.Empty; - - var charLength = Math.Min(fixedLength > -1 ? fixedLength : value.Length, value.Length); - var src = value.AsSpan(0, charLength); - - var byteCount = fixedLength > -1 ? fixedLength * sizeT : encoding.GetByteCount(value); if (byteCount == 0) { return; @@ -302,7 +334,7 @@ public ref struct SpanWriter if (fixedLength > -1) { - var extra = fixedLength * sizeT - bytesWritten; + var extra = fixedLength * byteLength - bytesWritten; if (extra > 0) { Clear(extra); @@ -311,53 +343,53 @@ public ref struct SpanWriter } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void WriteLittleUni(string value) => WriteString(value, TextEncoding.UnicodeLE); + public void WriteLittleUni(string value) => Write(value, TextEncoding.UnicodeLE); [MethodImpl(MethodImplOptions.AggressiveInlining)] public void WriteLittleUniNull(string value) { - WriteString(value, TextEncoding.UnicodeLE); + Write(value, TextEncoding.UnicodeLE); Write((ushort)0); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void WriteLittleUni(string value, int fixedLength) => WriteString(value, TextEncoding.UnicodeLE, fixedLength); + public void WriteLittleUni(string value, int fixedLength) => Write(value, TextEncoding.UnicodeLE, fixedLength); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void WriteBigUni(string value) => WriteString(value, TextEncoding.Unicode); + public void WriteBigUni(string value) => Write(value, TextEncoding.Unicode); [MethodImpl(MethodImplOptions.AggressiveInlining)] public void WriteBigUniNull(string value) { - WriteString(value, TextEncoding.Unicode); + Write(value, TextEncoding.Unicode); Write((ushort)0); // '\0' } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void WriteBigUni(string value, int fixedLength) => WriteString(value, TextEncoding.Unicode, fixedLength); + public void WriteBigUni(string value, int fixedLength) => Write(value, TextEncoding.Unicode, fixedLength); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void WriteUTF8(string value) => WriteString(value, TextEncoding.UTF8); + public void WriteUTF8(string value) => Write(value, TextEncoding.UTF8); [MethodImpl(MethodImplOptions.AggressiveInlining)] public void WriteUTF8Null(string value) { - WriteString(value, TextEncoding.UTF8); + Write(value, TextEncoding.UTF8); Write((byte)0); // '\0' } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void WriteAscii(string value) => WriteString(value, Encoding.ASCII); + public void WriteAscii(string value) => Write(value, Encoding.ASCII); [MethodImpl(MethodImplOptions.AggressiveInlining)] public void WriteAsciiNull(string value) { - WriteString(value, Encoding.ASCII); + Write(value, Encoding.ASCII); Write((byte)0); // '\0' } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void WriteAscii(string value, int fixedLength) => WriteString(value, Encoding.ASCII, fixedLength); + public void WriteAscii(string value, int fixedLength) => Write(value, Encoding.ASCII, fixedLength); [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Clear(int count) diff --git a/Projects/Server/Localization/LocalizationEntry.cs b/Projects/Server/Localization/LocalizationEntry.cs index 9bb2d4540..f91bcbce0 100644 --- a/Projects/Server/Localization/LocalizationEntry.cs +++ b/Projects/Server/Localization/LocalizationEntry.cs @@ -137,7 +137,7 @@ public class LocalizationEntry public LocalizationInterpolationHandler(int literalLength, int formattedCount, LocalizationEntry entry, out bool isValid) { _slices = entry.TextSlices; - _chars = _arrayToReturnToPool = ArrayPool.Shared.Rent(256); + _chars = _arrayToReturnToPool = STArrayPool.Shared.Rent(256); isValid = true; _pos = 0; @@ -159,7 +159,7 @@ public class LocalizationEntry if (Localization.TryGetLocalization(lang, number, out var entry)) { _slices = entry.TextSlices; - _chars = _arrayToReturnToPool = ArrayPool.Shared.Rent(256); + _chars = _arrayToReturnToPool = STArrayPool.Shared.Rent(256); isValid = true; } else @@ -509,10 +509,10 @@ public class LocalizationEntry [MethodImpl(MethodImplOptions.AggressiveInlining)] private void GrowCore(uint requiredMinCapacity) { - var newCapacity = Math.Max(requiredMinCapacity, Math.Min((uint)_chars.Length * 2, 1073741823)); + var newCapacity = Math.Max(requiredMinCapacity, Math.Min((uint)_chars.Length * 2, 0x3FFFFFDF)); var arraySize = (int)Math.Clamp(newCapacity, 256, int.MaxValue); - var newArray = ArrayPool.Shared.Rent(arraySize); + var newArray = STArrayPool.Shared.Rent(arraySize); _chars[.._pos].CopyTo(newArray); var toReturn = _arrayToReturnToPool; @@ -520,7 +520,7 @@ public class LocalizationEntry if (toReturn is not null) { - ArrayPool.Shared.Return(toReturn); + STArrayPool.Shared.Return(toReturn); } } @@ -533,7 +533,7 @@ public class LocalizationEntry this = default; // defensive clear if (toReturn is not null) { - ArrayPool.Shared.Return(toReturn); + STArrayPool.Shared.Return(toReturn); } } diff --git a/Projects/Server/Text/TextEncoding.cs b/Projects/Server/Text/TextEncoding.cs index c84e01def..41d6df2b2 100644 --- a/Projects/Server/Text/TextEncoding.cs +++ b/Projects/Server/Text/TextEncoding.cs @@ -105,7 +105,7 @@ namespace Server.Text public static int GetBytesUtf8(this ReadOnlySpan str, Span buffer) => UTF8.GetBytes(str, buffer); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int GetByteLengthForEncoding(Encoding encoding) => + public static int GetByteLengthForEncoding(this Encoding encoding) => encoding.BodyName switch { "utf-16BE" => 2, From 6ec84b3c01077e74f4961a4c6d73c9fb1ceaf31b Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sat, 14 May 2022 16:56:03 -0700 Subject: [PATCH 159/213] fix: Cleans up string substring (#1018) --- Projects/Server/Client/ClientVersion.cs | 31 +++++++------------ Projects/Server/Geometry/Point2D.cs | 4 +-- Projects/Server/Geometry/Point3D.cs | 6 ++-- Projects/Server/Geometry/Rectangle2D.cs | 10 +++--- Projects/Server/Geometry/WorldLocation.cs | 8 ++--- .../Json/Converters/ClientVersionConverter.cs | 2 +- .../Server/Json/Converters/MapConverter.cs | 2 +- Projects/Server/Maps/Map.cs | 11 +++++-- Projects/UOContent/Misc/LootPack.cs | 6 ++-- 9 files changed, 40 insertions(+), 40 deletions(-) diff --git a/Projects/Server/Client/ClientVersion.cs b/Projects/Server/Client/ClientVersion.cs index 09e68d582..3c4eafe00 100644 --- a/Projects/Server/Client/ClientVersion.cs +++ b/Projects/Server/Client/ClientVersion.cs @@ -75,8 +75,8 @@ public class ClientVersion : IComparable, IComparer, IComparer, IComparer 5 || Minor > 0 || Revision > 6) { - if (Patch > 0) - { - builder.Append((char)('a' + (Patch - 1))); - } + builder.Append($"{Major}.{Minor}.{Revision}.{Patch}"); + } + else if (Patch > 0) + { + builder.Append($"{Major}.{Minor}.{Revision}{(char)('a' + (Patch - 1))}"); } else { - builder.Append('.'); - builder.Append(Patch.ToString()); + builder.Append($"{Major}.{Minor}.{Revision}"); } - if (Type != ClientType.Regular) + if (Type == ClientType.UOTD) { - builder.Append(' '); - builder.Append(Type.ToString().ToLower()); + builder.Append(" uotd"); } return builder.ToString(); diff --git a/Projects/Server/Geometry/Point2D.cs b/Projects/Server/Geometry/Point2D.cs index 0f1dba7d2..efee210dd 100644 --- a/Projects/Server/Geometry/Point2D.cs +++ b/Projects/Server/Geometry/Point2D.cs @@ -58,12 +58,12 @@ namespace Server var start = value.IndexOfOrdinal('('); var end = value.IndexOf(',', start + 1); - Utility.ToInt32(value.Substring(start + 1, end - (start + 1)).Trim(), out var x); + Utility.ToInt32(value.AsSpan(start + 1, end - (start + 1)).Trim(), out var x); start = end; end = value.IndexOf(')', start + 1); - Utility.ToInt32(value.Substring(start + 1, end - (start + 1)).Trim(), out var y); + Utility.ToInt32(value.AsSpan(start + 1, end - (start + 1)).Trim(), out var y); return new Point2D(x, y); } diff --git a/Projects/Server/Geometry/Point3D.cs b/Projects/Server/Geometry/Point3D.cs index 6a65b7c26..96ce2f94e 100644 --- a/Projects/Server/Geometry/Point3D.cs +++ b/Projects/Server/Geometry/Point3D.cs @@ -86,17 +86,17 @@ namespace Server var start = value.IndexOfOrdinal('('); var end = value.IndexOf(',', start + 1); - Utility.ToInt32(value.Substring(start + 1, end - (start + 1)).Trim(), out var x); + Utility.ToInt32(value.AsSpan(start + 1, end - (start + 1)).Trim(), out var x); start = end; end = value.IndexOf(',', start + 1); - Utility.ToInt32(value.Substring(start + 1, end - (start + 1)).Trim(), out var y); + Utility.ToInt32(value.AsSpan(start + 1, end - (start + 1)).Trim(), out var y); start = end; end = value.IndexOf(')', start + 1); - Utility.ToInt32(value.Substring(start + 1, end - (start + 1)).Trim(), out var z); + Utility.ToInt32(value.AsSpan(start + 1, end - (start + 1)).Trim(), out var z); return new Point3D(x, y, z); } diff --git a/Projects/Server/Geometry/Rectangle2D.cs b/Projects/Server/Geometry/Rectangle2D.cs index 901cea1c2..3eaefc70a 100644 --- a/Projects/Server/Geometry/Rectangle2D.cs +++ b/Projects/Server/Geometry/Rectangle2D.cs @@ -13,6 +13,8 @@ * along with this program. If not, see . * *************************************************************************/ +using System; + namespace Server { [NoSort] @@ -46,22 +48,22 @@ namespace Server var start = value.IndexOfOrdinal('('); var end = value.IndexOf(',', start + 1); - Utility.ToInt32(value.Substring(start + 1, end - (start + 1)).Trim(), out var x); + Utility.ToInt32(value.AsSpan(start + 1, end - (start + 1)).Trim(), out var x); start = end; end = value.IndexOf(',', start + 1); - Utility.ToInt32(value.Substring(start + 1, end - (start + 1)).Trim(), out var y); + Utility.ToInt32(value.AsSpan(start + 1, end - (start + 1)).Trim(), out var y); start = end; end = value.IndexOf(',', start + 1); - Utility.ToInt32(value.Substring(start + 1, end - (start + 1)).Trim(), out var w); + Utility.ToInt32(value.AsSpan(start + 1, end - (start + 1)).Trim(), out var w); start = end; end = value.IndexOf(')', start + 1); - Utility.ToInt32(value.Substring(start + 1, end - (start + 1)).Trim(), out var h); + Utility.ToInt32(value.AsSpan(start + 1, end - (start + 1)).Trim(), out var h); return new Rectangle2D(x, y, w, h); } diff --git a/Projects/Server/Geometry/WorldLocation.cs b/Projects/Server/Geometry/WorldLocation.cs index 466f8ef82..f2e28eaac 100644 --- a/Projects/Server/Geometry/WorldLocation.cs +++ b/Projects/Server/Geometry/WorldLocation.cs @@ -145,22 +145,22 @@ namespace Server var start = value.IndexOfOrdinal('('); var end = value.IndexOf(',', start + 1); - Utility.ToInt32(value.Substring(start + 1, end - (start + 1)).Trim(), out var x); + Utility.ToInt32(value.AsSpan(start + 1, end - (start + 1)).Trim(), out var x); start = end; end = value.IndexOf(',', start + 1); - Utility.ToInt32(value.Substring(start + 1, end - (start + 1)).Trim(), out var y); + Utility.ToInt32(value.AsSpan(start + 1, end - (start + 1)).Trim(), out var y); start = end; end = value.IndexOf(',', start + 1); - Utility.ToInt32(value.Substring(start + 1, end - (start + 1)).Trim(), out var z); + Utility.ToInt32(value.AsSpan(start + 1, end - (start + 1)).Trim(), out var z); start = end; end = value.IndexOf(')', start + 1); - var map = Map.Parse(value.Substring(start + 1, end - (start + 1)).Trim()); + var map = Map.Parse(value.AsSpan(start + 1, end - (start + 1)).Trim()); return new WorldLocation(x, y, z, map); } diff --git a/Projects/Server/Json/Converters/ClientVersionConverter.cs b/Projects/Server/Json/Converters/ClientVersionConverter.cs index c1dc8ecb9..f5f4b41ee 100644 --- a/Projects/Server/Json/Converters/ClientVersionConverter.cs +++ b/Projects/Server/Json/Converters/ClientVersionConverter.cs @@ -28,7 +28,7 @@ namespace Server.Json return new ClientVersion(reader.GetString()); } - throw new JsonException($"Value must be a string"); + throw new JsonException("Value must be a string"); } public override void Write(Utf8JsonWriter writer, ClientVersion value, JsonSerializerOptions options) => diff --git a/Projects/Server/Json/Converters/MapConverter.cs b/Projects/Server/Json/Converters/MapConverter.cs index 71109ef88..832c366ab 100644 --- a/Projects/Server/Json/Converters/MapConverter.cs +++ b/Projects/Server/Json/Converters/MapConverter.cs @@ -26,7 +26,7 @@ namespace Server.Json { JsonTokenType.String => Map.Parse(reader.GetString()), JsonTokenType.Number => Map.Maps[reader.GetInt32()], - _ => throw new JsonException($"Value must be a number or string") + _ => throw new JsonException("Value must be a number or string") }; public override void Write(Utf8JsonWriter writer, Map value, JsonSerializerOptions options) => diff --git a/Projects/Server/Maps/Map.cs b/Projects/Server/Maps/Map.cs index e11ae4bd1..8f5239248 100644 --- a/Projects/Server/Maps/Map.cs +++ b/Projects/Server/Maps/Map.cs @@ -484,9 +484,14 @@ public sealed class Map : IComparable return mapValues; } - public static Map Parse(string value) + // Handles null checks + public static Map Parse(string value) => Parse(value ?? ReadOnlySpan.Empty); + + public static Map Parse(ReadOnlySpan value) { - if (string.IsNullOrWhiteSpace(value)) + value = value.Trim(); + + if (value.Length == 0) { return null; } @@ -513,7 +518,7 @@ public sealed class Map : IComparable continue; } - if (index >= 0 && map.MapIndex == index || map.Name.InsensitiveEquals(value)) + if (index >= 0 && map.MapIndex == index || value.InsensitiveEquals(map.Name)) { return map; } diff --git a/Projects/UOContent/Misc/LootPack.cs b/Projects/UOContent/Misc/LootPack.cs index 4e71aa7d9..6939c4d4c 100644 --- a/Projects/UOContent/Misc/LootPack.cs +++ b/Projects/UOContent/Misc/LootPack.cs @@ -1092,7 +1092,7 @@ namespace Server return; } - Count = Utility.ToInt32(str.Substring(start, index)); + Count = Utility.ToInt32(str.AsSpan(start, index)); start = index + 1; index = str.IndexOf('+', start); @@ -1109,7 +1109,7 @@ namespace Server index = str.Length; } - Sides = Utility.ToInt32(str.Substring(start, index - start)); + Sides = Utility.ToInt32(str.AsSpan(start, index - start)); if (index == str.Length) { @@ -1119,7 +1119,7 @@ namespace Server start = index + 1; index = str.Length; - Bonus = Utility.ToInt32(str.Substring(start, index - start)); + Bonus = Utility.ToInt32(str.AsSpan(start, index - start)); if (negative) { From eee8494558692cb97a14093f204d89288d9db97b Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 15 May 2022 10:01:14 -0700 Subject: [PATCH 160/213] fix: Removes scale speed by dex for monsters, fixes NPC movement/thinking speed (#1019) * Removes scaled speed by dex for monsters * Changes scaled speed by dex for pets (HS+ expansion) to be 400ms -> 100ms between 50 -> 200 dex * Removes speed changes that were broken for various mobs * Combines "Legacy" speed and renames the class to `NPCSpeeds` * Creates speed "classes" (slow, medium, fast, very fast) * Introduces a new overridable property `SpeedClass`. Register a new speed class using `NPCSpeeds.Register()` and then set the speed class to bulk/mass apply speeds. Order of speed determination: 1. SpeedMod 2. SpeedClass property (not null) 3. SpeedClass entry in Data\npc-speeds.json for that type 4. "Fast" (200ms Active, 400ms Passive) --- Distribution/Data/npc-speeds.json | 102 ++++---- .../Ethics/Evil/Mobiles/UnholySteed.cs | 2 +- .../Engines/Ethics/Hero/Mobiles/HolySteed.cs | 2 +- .../Factions/Mobiles/FactionWarHorse.cs | 2 +- .../Mobiles/Guards/BaseFactionGuard.cs | 1 - .../ML Quests/Definitions/AGhostOfCovetous.cs | 3 +- .../Engines/ML Quests/Definitions/Bedlam.cs | 6 +- .../ML Quests/Definitions/Britannia.cs | 4 +- .../ML Quests/Definitions/Heartwood.cs | 96 +++---- .../Engines/ML Quests/Definitions/Heritage.cs | 8 +- .../ML Quests/Definitions/HonestBeggar.cs | 4 +- .../Engines/ML Quests/Definitions/Ilshenar.cs | 6 +- .../Engines/ML Quests/Definitions/Malas.cs | 2 +- .../ML Quests/Definitions/MistakenIdentity.cs | 6 +- .../Definitions/NewHavenSkillTraining.cs | 48 ++-- .../ML Quests/Definitions/NewHavenTraining.cs | 24 +- .../Dark Tides/Mobiles/SummonedPaladin.cs | 1 - .../Emino's Undertaking/Mobiles/Henchman.cs | 1 - .../Haochi's Trials/Mobiles/CursedSoul.cs | 1 - .../Haochi's Trials/Mobiles/DeadlyImp.cs | 1 - .../Haochi's Trials/Mobiles/DiseasedCat.cs | 1 - .../Haochi's Trials/Mobiles/FierceDragon.cs | 1 - .../Haochi's Trials/Mobiles/InjuredWolf.cs | 1 - .../Haochi's Trials/Mobiles/YoungNinja.cs | 1 - .../Haochi's Trials/Mobiles/YoungRonin.cs | 1 - .../Uzeraan Turmoil/Mobiles/MilitiaFighter.cs | 1 - .../Halloween/2006/Engines/TrickOrTreat.cs | 1 - .../Halloween/2012/Engines/PlayerZombies.cs | 1 - .../Items/Talismans/TalismanSummons.cs | 1 - Projects/UOContent/Mobiles/AI/BaseAI.cs | 35 +-- .../UOContent/Mobiles/AI/LegacySpeedInfo.cs | 77 ------ Projects/UOContent/Mobiles/AI/SpeedInfo.cs | 49 ---- .../Mobiles/Animals/Mounts/Nightmare.cs | 22 +- .../Mobiles/Animals/Mounts/SeaHorse.cs | 1 - .../Mobiles/Animals/Mounts/SilverSteed.cs | 2 - .../Mobiles/Animals/Mounts/SkeletalMount.cs | 1 - Projects/UOContent/Mobiles/BaseCreature.cs | 235 +++++++++++------- .../Mobiles/Familiars/BaseFamiliar.cs | 2 +- .../Mobiles/Monsters/AOS/Revenant.cs | 2 - .../Humanoid/Melee/KhaldunRevenant.cs | 2 - .../Monsters/LBR/Jukas/ChaosDragoon.cs | 2 +- .../Monsters/LBR/Jukas/ChaosDragoonElite.cs | 2 +- .../Mobiles/Monsters/ML/Animal/CuSidhe.cs | 2 +- .../Mobiles/Monsters/ML/Animal/Ferret.cs | 1 - .../Monsters/ML/Animal/RagingGrizzlyBear.cs | 1 - .../Mobiles/Monsters/ML/Animal/Squirrel.cs | 1 - .../ML/Humanoid/Melee/CorruptedSoul.cs | 3 +- .../Mobiles/Monsters/ML/Labyrinth/Miasma.cs | 2 - .../Monsters/ML/Misc/Melee/Reptalon.cs | 2 - .../Monsters/Misc/Melee/BladeSpirits.cs | 1 - .../Mobiles/Monsters/Misc/Melee/Golem.cs | 2 - .../Mobiles/Monsters/SE/EliteNinja.cs | 2 +- .../Mobiles/Monsters/SE/FireBeetle.cs | 5 +- Projects/UOContent/Mobiles/NPCSpeeds.cs | 102 ++++++++ .../UOContent/Mobiles/Special/BaseChampion.cs | 1 - .../Mobiles/Special/BaseShieldGuard.cs | 3 +- .../UOContent/Mobiles/Special/Mephitis.cs | 2 - Projects/UOContent/Mobiles/Special/Semidar.cs | 2 - Projects/UOContent/Mobiles/Special/Silvani.cs | 2 - Projects/UOContent/Mobiles/Townfolk/Actor.cs | 3 +- Projects/UOContent/Mobiles/Townfolk/Artist.cs | 3 +- .../Mobiles/Townfolk/BaseEscortable.cs | 4 +- Projects/UOContent/Mobiles/Townfolk/Gypsy.cs | 6 +- .../Mobiles/Townfolk/HarborMaster.cs | 3 +- Projects/UOContent/Mobiles/Townfolk/Ninja.cs | 3 +- .../UOContent/Mobiles/Townfolk/Samurai.cs | 2 +- .../UOContent/Mobiles/Townfolk/Sculptor.cs | 2 +- .../Mobiles/Townfolk/SeekerOfAdventure.cs | 10 +- .../UOContent/Mobiles/Vendors/BaseVendor.cs | 3 +- Projects/UOContent/Skills/AnimalTaming.cs | 11 +- .../UOContent/Spells/Ninjitsu/MirrorImage.cs | 1 - .../Spells/Spellweaving/Mobiles/ArcaneFey.cs | 1 - .../Spellweaving/Mobiles/ArcaneFiend.cs | 1 - .../Spells/Spellweaving/Mobiles/NatureFury.cs | 1 - 74 files changed, 477 insertions(+), 472 deletions(-) delete mode 100644 Projects/UOContent/Mobiles/AI/LegacySpeedInfo.cs delete mode 100644 Projects/UOContent/Mobiles/AI/SpeedInfo.cs create mode 100644 Projects/UOContent/Mobiles/NPCSpeeds.cs diff --git a/Distribution/Data/npc-speeds.json b/Distribution/Data/npc-speeds.json index ea3146211..5ea8371ae 100644 --- a/Distribution/Data/npc-speeds.json +++ b/Distribution/Data/npc-speeds.json @@ -1,8 +1,8 @@ [ { "name": "Slow", - "active": 0.6, - "passive": 1.4, + "active": 0.3, + "passive": 0.6, "types": [ "AntLion", "ArcticOgreLord", "BogThing", "Bogle", "BoneKnight", "EarthElemental", @@ -18,57 +18,10 @@ "GreaterDragon", "PlagueBeastLord" ] }, - { - "name": "Fast", - "active": 0.3, - "passive": 1.0, - "types": [ - "LordOaks", "Silvani", "AirElemental", - "AncientWyrm", "Balron", "BladeSpirits", - "DreadSpider", "Efreet", "EtherealWarrior", - "Lich", "Nightmare", "OphidianArchmage", - "OphidianMage", "OphidianWarrior", "OphidianMatriarch", - "OphidianKnight", "PoisonElemental", "Revenant", - "SandVortex", "SavageRider", "SavageShaman", - "SnowElemental", "WhiteWyrm", "Wisp", - "DemonKnight", "GiantBlackWidow", "SummonedAirElemental", - "LesserHiryu", "Hiryu", "LadyOfTheSnow", - "RaiJu", "Ronin", "RuneBeetle", - "Changeling", "LadyJennifyr", "LadyMarai", "MasterJonath", - "MasterMikael", "MasterTheophilus", "RedDeath", - "SirPatrick", "Miasma", "Rend", - "Grobu", "Gnaw", "Guile", - "Irk", "Spite", "LadyLissith", - "LadySabrix", "Malefic", "Silk", - "Virulent", "SeaHorse", "UnholyFamiliar", - "HolyFamiliar", "GiantIceWorm", "Phoenix", - "Succubus", "EnragedRabbit", "EnragedHind", - "EnragedHart", "EnragedBlackBear", "EnragedEagle", - "RagingGrizzlyBear", "CorrosiveSlime", "DarkWisp", - "DarkGuardian", "HarrowerTentacles", "ServantOfSemidar", - "Ninja", "Samurai" - ] - }, - { - "name": "Very Fast", - "active": 0.25, - "passive": 0.7, - "types": [ - "Barracoon", "Mephitis", "Neira", - "Rikktor", "Semidar", "EnergyVortex", - "EliteNinja", "Pixie", "SilverSerpent", - "VorpalBunny", "FleshRenderer", "KhaldunRevenant", - "FactionDragoon", "FactionKnight", "FactionPaladin", - "FactionHenchman", "FactionMercenary", "FactionNecromancer", - "FactionSorceress", "FactionWizard", "FactionBerserker", - "FactionPaladin", "Leviathan", "FireBeetle", - "FanDancer", "FactionDeathKnight" - ] - }, { "name": "Medium", - "active": 0.5, - "passive": 1.2, + "active": 0.25, + "passive": 0.5, "types": [ "AcidElemental", "AgapiteElemental", "Alligator", "AncientLich", "Betrayer", "Bird", @@ -144,5 +97,52 @@ "Parrot", "ElfBrigand", "GreaterMongbat", "AnimatedWeapon", "Reaper", "Corpser" ] + }, + { + "name": "Fast", + "active": 0.2, + "passive": 0.4, + "types": [ + "LordOaks", "Silvani", "AirElemental", + "AncientWyrm", "Balron", "BladeSpirits", + "DreadSpider", "Efreet", "EtherealWarrior", + "Lich", "Nightmare", "OphidianArchmage", + "OphidianMage", "OphidianWarrior", "OphidianMatriarch", + "OphidianKnight", "PoisonElemental", + "SandVortex", "SavageRider", "SavageShaman", + "SnowElemental", "WhiteWyrm", "Wisp", + "DemonKnight", "GiantBlackWidow", "SummonedAirElemental", + "LesserHiryu", "Hiryu", "LadyOfTheSnow", + "RaiJu", "Ronin", "RuneBeetle", + "Changeling", "LadyJennifyr", "LadyMarai", "MasterJonath", + "MasterMikael", "MasterTheophilus", "RedDeath", + "SirPatrick", "Miasma", "Rend", + "Grobu", "Gnaw", "Guile", + "Irk", "Spite", "LadyLissith", + "LadySabrix", "Malefic", "Silk", + "Virulent", "SeaHorse", "UnholyFamiliar", + "HolyFamiliar", "GiantIceWorm", "Phoenix", + "Succubus", "EnragedRabbit", "EnragedHind", + "EnragedHart", "EnragedBlackBear", "EnragedEagle", + "RagingGrizzlyBear", "CorrosiveSlime", "DarkWisp", + "DarkGuardian", "HarrowerTentacles", "ServantOfSemidar", + "Reptalon" + ] + }, + { + "name": "Very Fast", + "active": 0.175, + "passive": 0.35, + "types": [ + "Barracoon", "Mephitis", "Neira", + "Rikktor", "Semidar", "EnergyVortex", + "EliteNinja", "Pixie", "SilverSerpent", + "VorpalBunny", "FleshRenderer", "KhaldunRevenant", + "FactionDragoon", "FactionKnight", "FactionPaladin", + "FactionHenchman", "FactionMercenary", "FactionNecromancer", + "FactionSorceress", "FactionWizard", "FactionBerserker", + "FactionPaladin", "Leviathan", "FireBeetle", + "FanDancer", "FactionDeathKnight", "Revenant" + ] } ] diff --git a/Projects/UOContent/Engines/Ethics/Evil/Mobiles/UnholySteed.cs b/Projects/UOContent/Engines/Ethics/Evil/Mobiles/UnholySteed.cs index 5546f571c..ec13266a9 100644 --- a/Projects/UOContent/Engines/Ethics/Evil/Mobiles/UnholySteed.cs +++ b/Projects/UOContent/Engines/Ethics/Evil/Mobiles/UnholySteed.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles { [Constructible] public UnholySteed() - : base("a dark steed", 0x74, 0x3EA7, AIType.AI_Melee, FightMode.Aggressor, 10, 1) + : base("a dark steed", 0x74, 0x3EA7, AIType.AI_Melee, FightMode.Aggressor) { SetStr(496, 525); SetDex(86, 105); diff --git a/Projects/UOContent/Engines/Ethics/Hero/Mobiles/HolySteed.cs b/Projects/UOContent/Engines/Ethics/Hero/Mobiles/HolySteed.cs index c6c41aa1e..da52600f8 100644 --- a/Projects/UOContent/Engines/Ethics/Hero/Mobiles/HolySteed.cs +++ b/Projects/UOContent/Engines/Ethics/Hero/Mobiles/HolySteed.cs @@ -6,7 +6,7 @@ namespace Server.Mobiles { [Constructible] public HolySteed() - : base("a silver steed", 0x75, 0x3EA8, AIType.AI_Melee, FightMode.Aggressor, 10, 1) + : base("a silver steed", 0x75, 0x3EA8, AIType.AI_Melee, FightMode.Aggressor) { SetStr(496, 525); SetDex(86, 105); diff --git a/Projects/UOContent/Engines/Factions/Mobiles/FactionWarHorse.cs b/Projects/UOContent/Engines/Factions/Mobiles/FactionWarHorse.cs index e313de059..e0aa13256 100644 --- a/Projects/UOContent/Engines/Factions/Mobiles/FactionWarHorse.cs +++ b/Projects/UOContent/Engines/Factions/Mobiles/FactionWarHorse.cs @@ -10,7 +10,7 @@ namespace Server.Factions [Constructible] public FactionWarHorse(Faction faction = null) - : base("a war horse", 0xE2, 0x3EA0, AIType.AI_Melee, FightMode.Aggressor, 10, 1) + : base("a war horse", 0xE2, 0x3EA0, AIType.AI_Melee, FightMode.Aggressor) { BaseSoundID = 0xA8; diff --git a/Projects/UOContent/Engines/Factions/Mobiles/Guards/BaseFactionGuard.cs b/Projects/UOContent/Engines/Factions/Mobiles/Guards/BaseFactionGuard.cs index ebabde5c0..5b59ecb6f 100644 --- a/Projects/UOContent/Engines/Factions/Mobiles/Guards/BaseFactionGuard.cs +++ b/Projects/UOContent/Engines/Factions/Mobiles/Guards/BaseFactionGuard.cs @@ -37,7 +37,6 @@ namespace Server.Factions public BaseFactionGuard(string title) : base(AIType.AI_Melee) { - SetSpeed(0.3, 1.0); Orders = new Orders(this); Title = title; diff --git a/Projects/UOContent/Engines/ML Quests/Definitions/AGhostOfCovetous.cs b/Projects/UOContent/Engines/ML Quests/Definitions/AGhostOfCovetous.cs index 63ebe8524..d8e567687 100644 --- a/Projects/UOContent/Engines/ML Quests/Definitions/AGhostOfCovetous.cs +++ b/Projects/UOContent/Engines/ML Quests/Definitions/AGhostOfCovetous.cs @@ -96,8 +96,7 @@ namespace Server.Engines.MLQuests.Definitions public class Ben : BaseCreature { [Constructible] - public Ben() - : base(AIType.AI_Vendor, FightMode.None, 2) + public Ben() : base(AIType.AI_Vendor, FightMode.None, 2) { Title = "the Apprentice Necromancer"; Body = 0x190; diff --git a/Projects/UOContent/Engines/ML Quests/Definitions/Bedlam.cs b/Projects/UOContent/Engines/ML Quests/Definitions/Bedlam.cs index 390262e51..fe4fbdcec 100644 --- a/Projects/UOContent/Engines/ML Quests/Definitions/Bedlam.cs +++ b/Projects/UOContent/Engines/ML Quests/Definitions/Bedlam.cs @@ -77,7 +77,7 @@ namespace Server.Engines.MLQuests.Definitions Female = true; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -122,7 +122,7 @@ namespace Server.Engines.MLQuests.Definitions Female = false; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -175,7 +175,7 @@ namespace Server.Engines.MLQuests.Definitions Female = true; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); diff --git a/Projects/UOContent/Engines/ML Quests/Definitions/Britannia.cs b/Projects/UOContent/Engines/ML Quests/Definitions/Britannia.cs index 5f3b2ce96..df01d3119 100644 --- a/Projects/UOContent/Engines/ML Quests/Definitions/Britannia.cs +++ b/Projects/UOContent/Engines/ML Quests/Definitions/Britannia.cs @@ -116,7 +116,7 @@ namespace Server.Engines.MLQuests.Definitions Female = true; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -169,7 +169,7 @@ namespace Server.Engines.MLQuests.Definitions Hue = 0x83F2; // TODO: Random human hue? Why??? Body = 0x32; - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); } diff --git a/Projects/UOContent/Engines/ML Quests/Definitions/Heartwood.cs b/Projects/UOContent/Engines/ML Quests/Definitions/Heartwood.cs index 1dd07828e..6594c71fb 100644 --- a/Projects/UOContent/Engines/ML Quests/Definitions/Heartwood.cs +++ b/Projects/UOContent/Engines/ML Quests/Definitions/Heartwood.cs @@ -2012,7 +2012,7 @@ namespace Server.Engines.MLQuests.Definitions Female = true; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -2079,7 +2079,7 @@ namespace Server.Engines.MLQuests.Definitions Female = true; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -2147,7 +2147,7 @@ namespace Server.Engines.MLQuests.Definitions Female = false; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -2213,7 +2213,7 @@ namespace Server.Engines.MLQuests.Definitions Female = false; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -2280,7 +2280,7 @@ namespace Server.Engines.MLQuests.Definitions Female = true; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -2346,7 +2346,7 @@ namespace Server.Engines.MLQuests.Definitions Female = false; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -2410,7 +2410,7 @@ namespace Server.Engines.MLQuests.Definitions Female = true; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -2482,7 +2482,7 @@ namespace Server.Engines.MLQuests.Definitions Female = false; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -2546,7 +2546,7 @@ namespace Server.Engines.MLQuests.Definitions Female = false; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -2624,7 +2624,7 @@ namespace Server.Engines.MLQuests.Definitions Female = true; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -2684,7 +2684,7 @@ namespace Server.Engines.MLQuests.Definitions Female = false; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -2748,7 +2748,7 @@ namespace Server.Engines.MLQuests.Definitions Female = true; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -2810,7 +2810,7 @@ namespace Server.Engines.MLQuests.Definitions Female = false; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -2887,7 +2887,7 @@ namespace Server.Engines.MLQuests.Definitions Female = true; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -2971,7 +2971,7 @@ namespace Server.Engines.MLQuests.Definitions Female = false; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -3039,7 +3039,7 @@ namespace Server.Engines.MLQuests.Definitions Female = false; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -3109,7 +3109,7 @@ namespace Server.Engines.MLQuests.Definitions Female = true; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -3172,7 +3172,7 @@ namespace Server.Engines.MLQuests.Definitions Female = false; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -3242,7 +3242,7 @@ namespace Server.Engines.MLQuests.Definitions Female = true; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -3306,7 +3306,7 @@ namespace Server.Engines.MLQuests.Definitions Female = true; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -3369,7 +3369,7 @@ namespace Server.Engines.MLQuests.Definitions Female = false; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -3419,7 +3419,7 @@ namespace Server.Engines.MLQuests.Definitions Female = false; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -3492,7 +3492,7 @@ namespace Server.Engines.MLQuests.Definitions Female = true; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -3555,7 +3555,7 @@ namespace Server.Engines.MLQuests.Definitions Female = false; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -3625,7 +3625,7 @@ namespace Server.Engines.MLQuests.Definitions Female = true; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -3690,7 +3690,7 @@ namespace Server.Engines.MLQuests.Definitions Female = false; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -3754,7 +3754,7 @@ namespace Server.Engines.MLQuests.Definitions Female = true; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -3817,7 +3817,7 @@ namespace Server.Engines.MLQuests.Definitions Female = false; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -3881,7 +3881,7 @@ namespace Server.Engines.MLQuests.Definitions Female = true; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -3943,7 +3943,7 @@ namespace Server.Engines.MLQuests.Definitions Female = true; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -3988,7 +3988,7 @@ namespace Server.Engines.MLQuests.Definitions Female = false; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -4046,7 +4046,7 @@ namespace Server.Engines.MLQuests.Definitions Female = true; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -4090,7 +4090,7 @@ namespace Server.Engines.MLQuests.Definitions Female = true; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -4139,7 +4139,7 @@ namespace Server.Engines.MLQuests.Definitions Female = false; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -4185,7 +4185,7 @@ namespace Server.Engines.MLQuests.Definitions Female = true; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -4231,7 +4231,7 @@ namespace Server.Engines.MLQuests.Definitions Female = true; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -4275,7 +4275,7 @@ namespace Server.Engines.MLQuests.Definitions Female = false; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -4319,7 +4319,7 @@ namespace Server.Engines.MLQuests.Definitions Female = true; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -4364,7 +4364,7 @@ namespace Server.Engines.MLQuests.Definitions Female = false; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -4415,7 +4415,7 @@ namespace Server.Engines.MLQuests.Definitions Female = false; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -4459,7 +4459,7 @@ namespace Server.Engines.MLQuests.Definitions Female = false; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -4512,7 +4512,7 @@ namespace Server.Engines.MLQuests.Definitions Female = true; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -4569,7 +4569,7 @@ namespace Server.Engines.MLQuests.Definitions Female = true; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -4621,7 +4621,7 @@ namespace Server.Engines.MLQuests.Definitions Female = false; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -4686,7 +4686,7 @@ namespace Server.Engines.MLQuests.Definitions Female = false; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -4742,7 +4742,7 @@ namespace Server.Engines.MLQuests.Definitions Female = false; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -4797,7 +4797,7 @@ namespace Server.Engines.MLQuests.Definitions Female = true; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -4853,7 +4853,7 @@ namespace Server.Engines.MLQuests.Definitions Female = true; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); diff --git a/Projects/UOContent/Engines/ML Quests/Definitions/Heritage.cs b/Projects/UOContent/Engines/ML Quests/Definitions/Heritage.cs index 92fa5d7bb..d705f351e 100644 --- a/Projects/UOContent/Engines/ML Quests/Definitions/Heritage.cs +++ b/Projects/UOContent/Engines/ML Quests/Definitions/Heritage.cs @@ -283,7 +283,7 @@ namespace Server.Engines.MLQuests.Definitions Body = 788; BaseSoundID = 0x3EE; - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); } @@ -622,7 +622,7 @@ namespace Server.Engines.MLQuests.Definitions Body = 400; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); AddItem(new Tunic(Utility.RandomNeutralHue())); @@ -678,7 +678,7 @@ namespace Server.Engines.MLQuests.Definitions Body = 400; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); AddItem(new FancyShirt(Utility.RandomNeutralHue())); @@ -722,7 +722,7 @@ namespace Server.Engines.MLQuests.Definitions Body = 401; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); diff --git a/Projects/UOContent/Engines/ML Quests/Definitions/HonestBeggar.cs b/Projects/UOContent/Engines/ML Quests/Definitions/HonestBeggar.cs index d9f5a2bdb..2b54401c5 100644 --- a/Projects/UOContent/Engines/ML Quests/Definitions/HonestBeggar.cs +++ b/Projects/UOContent/Engines/ML Quests/Definitions/HonestBeggar.cs @@ -63,7 +63,7 @@ namespace Server.Engines.MLQuests.Definitions Female = false; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -107,7 +107,7 @@ namespace Server.Engines.MLQuests.Definitions Female = true; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); diff --git a/Projects/UOContent/Engines/ML Quests/Definitions/Ilshenar.cs b/Projects/UOContent/Engines/ML Quests/Definitions/Ilshenar.cs index 3d9967a7a..7887057f4 100644 --- a/Projects/UOContent/Engines/ML Quests/Definitions/Ilshenar.cs +++ b/Projects/UOContent/Engines/ML Quests/Definitions/Ilshenar.cs @@ -180,7 +180,7 @@ namespace Server.Engines.MLQuests.Definitions Body = 400; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); var hairHue = 0x3B2 + Utility.Random(2); @@ -235,7 +235,7 @@ namespace Server.Engines.MLQuests.Definitions Female = true; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -286,7 +286,7 @@ namespace Server.Engines.MLQuests.Definitions Female = false; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); diff --git a/Projects/UOContent/Engines/ML Quests/Definitions/Malas.cs b/Projects/UOContent/Engines/ML Quests/Definitions/Malas.cs index 0c60b8265..56a595140 100644 --- a/Projects/UOContent/Engines/ML Quests/Definitions/Malas.cs +++ b/Projects/UOContent/Engines/ML Quests/Definitions/Malas.cs @@ -35,7 +35,7 @@ namespace Server.Engines.MLQuests.Definitions Female = false; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); AddItem(new Backpack()); diff --git a/Projects/UOContent/Engines/ML Quests/Definitions/MistakenIdentity.cs b/Projects/UOContent/Engines/ML Quests/Definitions/MistakenIdentity.cs index cb07d63cb..42b2eed73 100644 --- a/Projects/UOContent/Engines/ML Quests/Definitions/MistakenIdentity.cs +++ b/Projects/UOContent/Engines/ML Quests/Definitions/MistakenIdentity.cs @@ -203,7 +203,7 @@ namespace Server.Engines.MLQuests.Definitions Female = true; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -250,7 +250,7 @@ namespace Server.Engines.MLQuests.Definitions Female = false; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); AddItem(new Backpack()); @@ -308,7 +308,7 @@ namespace Server.Engines.MLQuests.Definitions Female = false; Hue = 0x83E8; - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); HairItemID = 0x2049; diff --git a/Projects/UOContent/Engines/ML Quests/Definitions/NewHavenSkillTraining.cs b/Projects/UOContent/Engines/ML Quests/Definitions/NewHavenSkillTraining.cs index 5e4535cd1..bdcca750f 100644 --- a/Projects/UOContent/Engines/ML Quests/Definitions/NewHavenSkillTraining.cs +++ b/Projects/UOContent/Engines/ML Quests/Definitions/NewHavenSkillTraining.cs @@ -654,7 +654,7 @@ namespace Server.Engines.MLQuests.Definitions FacialHairItemID = 0x204D; FacialHairHue = 0x47D; - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); SetSkill(SkillName.Anatomy, 120.0); @@ -719,7 +719,7 @@ namespace Server.Engines.MLQuests.Definitions FacialHairItemID = 0x204D; FacialHairHue = 0x455; - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); SetSkill(SkillName.EvalInt, 120.0); @@ -776,7 +776,7 @@ namespace Server.Engines.MLQuests.Definitions HairItemID = 0x203C; HairHue = 0x455; - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); SetSkill(SkillName.Anatomy, 120.0); @@ -855,7 +855,7 @@ namespace Server.Engines.MLQuests.Definitions HairHue = 0x47D; Female = true; - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); SetSkill(SkillName.Anatomy, 120.0); @@ -939,7 +939,7 @@ namespace Server.Engines.MLQuests.Definitions FacialHairItemID = 0x204D; FacialHairHue = 0x455; - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); SetSkill(SkillName.Anatomy, 120.0); @@ -1021,7 +1021,7 @@ namespace Server.Engines.MLQuests.Definitions HairItemID = 0x203B; HairHue = 0x44E; - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); SetSkill(SkillName.Anatomy, 120.0); @@ -1086,7 +1086,7 @@ namespace Server.Engines.MLQuests.Definitions HairItemID = 0x203C; HairHue = 0x8A7; - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); SetSkill(SkillName.Anatomy, 120.0); @@ -1146,7 +1146,7 @@ namespace Server.Engines.MLQuests.Definitions Hue = 0x8374; HairItemID = 0; - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); SetSkill(SkillName.Anatomy, 120.0); @@ -1228,7 +1228,7 @@ namespace Server.Engines.MLQuests.Definitions HairItemID = 0x203D; HairHue = 0x457; - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); SetSkill(SkillName.EvalInt, 120.0); @@ -1284,7 +1284,7 @@ namespace Server.Engines.MLQuests.Definitions HairItemID = 0x203B; HairHue = 0x455; - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); SetSkill(SkillName.EvalInt, 120.0); @@ -1367,7 +1367,7 @@ namespace Server.Engines.MLQuests.Definitions HairItemID = 0x203D; HairHue = 0x455; - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); SetSkill(SkillName.EvalInt, 120.0); @@ -1424,7 +1424,7 @@ namespace Server.Engines.MLQuests.Definitions HairItemID = 0x203C; HairHue = 0x47D; - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); SetSkill(SkillName.EvalInt, 120.0); @@ -1480,7 +1480,7 @@ namespace Server.Engines.MLQuests.Definitions HairItemID = 0x203C; HairHue = 0x455; - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); SetSkill(SkillName.EvalInt, 120.0); @@ -1542,7 +1542,7 @@ namespace Server.Engines.MLQuests.Definitions HairItemID = 0x203D; HairHue = 0x46C; - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); SetSkill(SkillName.ArmsLore, 120.0); @@ -1604,7 +1604,7 @@ namespace Server.Engines.MLQuests.Definitions FacialHairItemID = 0x203E; FacialHairHue = 0x477; - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); SetSkill(SkillName.Anatomy, 120.0); @@ -1662,7 +1662,7 @@ namespace Server.Engines.MLQuests.Definitions HairItemID = 0x203B; HairHue = 0x477; - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); SetSkill(SkillName.Anatomy, 120.0); @@ -1720,7 +1720,7 @@ namespace Server.Engines.MLQuests.Definitions HairItemID = 0x203C; HairHue = 0x456; - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); SetSkill(SkillName.Anatomy, 120.0); @@ -1848,7 +1848,7 @@ namespace Server.Engines.MLQuests.Definitions Title = "the Hiding Instructor"; Body = 0xF7; - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); SetSkill(SkillName.Hiding, 120.0); @@ -1900,7 +1900,7 @@ namespace Server.Engines.MLQuests.Definitions HairItemID = 0x203B; HairHue = 0x455; - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); SetSkill(SkillName.Hiding, 120.0); @@ -1962,7 +1962,7 @@ namespace Server.Engines.MLQuests.Definitions FacialHairItemID = 0x204B; FacialHairHue = 0x47D; - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); SetSkill(SkillName.Hiding, 120.0); @@ -2100,7 +2100,7 @@ namespace Server.Engines.MLQuests.Definitions HairItemID = 0x203D; HairHue = 0x457; - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); SetSkill(SkillName.Magery, 120.0); @@ -2180,7 +2180,7 @@ namespace Server.Engines.MLQuests.Definitions HairItemID = 0x203C; HairHue = 0x455; - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); SetSkill(SkillName.Magery, 120.0); @@ -2240,7 +2240,7 @@ namespace Server.Engines.MLQuests.Definitions FacialHairItemID = 0x204D; FacialHairHue = 0x44E; - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); SetSkill(SkillName.ArmsLore, 120.0); @@ -2301,7 +2301,7 @@ namespace Server.Engines.MLQuests.Definitions HairItemID = 0x203B; HairHue = 0x47B; - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); SetSkill(SkillName.ArmsLore, 120.0); diff --git a/Projects/UOContent/Engines/ML Quests/Definitions/NewHavenTraining.cs b/Projects/UOContent/Engines/ML Quests/Definitions/NewHavenTraining.cs index 97ebd7e94..f3d9b8ba9 100644 --- a/Projects/UOContent/Engines/ML Quests/Definitions/NewHavenTraining.cs +++ b/Projects/UOContent/Engines/ML Quests/Definitions/NewHavenTraining.cs @@ -270,7 +270,7 @@ namespace Server.Engines.MLQuests.Definitions Female = false; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -349,7 +349,7 @@ namespace Server.Engines.MLQuests.Definitions Female = true; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -412,7 +412,7 @@ namespace Server.Engines.MLQuests.Definitions Female = false; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -473,7 +473,7 @@ namespace Server.Engines.MLQuests.Definitions Female = true; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -530,7 +530,7 @@ namespace Server.Engines.MLQuests.Definitions Female = false; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -599,7 +599,7 @@ namespace Server.Engines.MLQuests.Definitions Female = false; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -653,7 +653,7 @@ namespace Server.Engines.MLQuests.Definitions Female = false; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -712,7 +712,7 @@ namespace Server.Engines.MLQuests.Definitions Female = false; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -769,7 +769,7 @@ namespace Server.Engines.MLQuests.Definitions Female = false; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -815,7 +815,7 @@ namespace Server.Engines.MLQuests.Definitions Female = false; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -874,7 +874,7 @@ namespace Server.Engines.MLQuests.Definitions Female = true; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); @@ -935,7 +935,7 @@ namespace Server.Engines.MLQuests.Definitions Female = false; Hue = Race.RandomSkinHue(); - SetSpeed(0.5, 2); + SetSpeed(0.5, 2.0); InitStats(100, 100, 25); Utility.AssignRandomHair(this); diff --git a/Projects/UOContent/Engines/Quests/Dark Tides/Mobiles/SummonedPaladin.cs b/Projects/UOContent/Engines/Quests/Dark Tides/Mobiles/SummonedPaladin.cs index 6164a70f0..a01569975 100644 --- a/Projects/UOContent/Engines/Quests/Dark Tides/Mobiles/SummonedPaladin.cs +++ b/Projects/UOContent/Engines/Quests/Dark Tides/Mobiles/SummonedPaladin.cs @@ -13,7 +13,6 @@ namespace Server.Engines.Quests.Necro { m_Necromancer = necromancer; - SetSpeed(0.3, 1.0); InitStats(45, 30, 5); Title = "the Paladin"; diff --git a/Projects/UOContent/Engines/Quests/Emino's Undertaking/Mobiles/Henchman.cs b/Projects/UOContent/Engines/Quests/Emino's Undertaking/Mobiles/Henchman.cs index 69d17d058..d4e24e217 100644 --- a/Projects/UOContent/Engines/Quests/Emino's Undertaking/Mobiles/Henchman.cs +++ b/Projects/UOContent/Engines/Quests/Emino's Undertaking/Mobiles/Henchman.cs @@ -8,7 +8,6 @@ namespace Server.Engines.Quests.Ninja [Constructible] public Henchman() : base(AIType.AI_Melee, FightMode.Aggressor) { - SetSpeed(0.3, 1.0); InitStats(45, 30, 5); Hue = Race.Human.RandomSkinHue(); diff --git a/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/CursedSoul.cs b/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/CursedSoul.cs index 4e9e4b2d2..151f85901 100644 --- a/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/CursedSoul.cs +++ b/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/CursedSoul.cs @@ -11,7 +11,6 @@ namespace Server.Engines.Quests.Samurai Body = 3; BaseSoundID = 471; - SetSpeed(0.3, 1.0); SetStr(20, 40); SetDex(40, 60); SetInt(15, 25); diff --git a/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/DeadlyImp.cs b/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/DeadlyImp.cs index abfcf594b..7d9085567 100644 --- a/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/DeadlyImp.cs +++ b/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/DeadlyImp.cs @@ -11,7 +11,6 @@ namespace Server.Engines.Quests.Samurai BaseSoundID = 422; Hue = 0x66A; - SetSpeed(0.3, 1.0); SetStr(91, 115); SetDex(61, 80); SetInt(86, 105); diff --git a/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/DiseasedCat.cs b/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/DiseasedCat.cs index 6b47e683d..c73bbc558 100644 --- a/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/DiseasedCat.cs +++ b/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/DiseasedCat.cs @@ -11,7 +11,6 @@ namespace Server.Engines.Quests.Samurai Hue = Utility.RandomAnimalHue(); BaseSoundID = 0x69; - SetSpeed(0.3, 1.0); SetStr(9); SetDex(35); SetInt(5); diff --git a/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/FierceDragon.cs b/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/FierceDragon.cs index 010514878..914aec85e 100644 --- a/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/FierceDragon.cs +++ b/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/FierceDragon.cs @@ -10,7 +10,6 @@ namespace Server.Engines.Quests.Samurai Body = 103; BaseSoundID = 362; - SetSpeed(0.3, 1.0); SetStr(6000, 6020); SetDex(0); SetInt(850, 870); diff --git a/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/InjuredWolf.cs b/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/InjuredWolf.cs index 484342255..fd7ab7078 100644 --- a/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/InjuredWolf.cs +++ b/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/InjuredWolf.cs @@ -12,7 +12,6 @@ namespace Server.Engines.Quests.Samurai Hue = Utility.RandomAnimalHue(); - SetSpeed(0.3, 1.0); SetStr(10, 20); SetDex(45, 65); SetInt(10, 15); diff --git a/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/YoungNinja.cs b/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/YoungNinja.cs index 51d97861a..f3b63e1b2 100644 --- a/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/YoungNinja.cs +++ b/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/YoungNinja.cs @@ -8,7 +8,6 @@ namespace Server.Engines.Quests.Samurai [Constructible] public YoungNinja() : base(AIType.AI_Melee, FightMode.Aggressor) { - SetSpeed(0.3, 1.0); InitStats(45, 30, 5); SetHits(20, 30); diff --git a/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/YoungRonin.cs b/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/YoungRonin.cs index 29644ffbd..c2f1aed70 100644 --- a/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/YoungRonin.cs +++ b/Projects/UOContent/Engines/Quests/Haochi's Trials/Mobiles/YoungRonin.cs @@ -8,7 +8,6 @@ namespace Server.Engines.Quests.Samurai [Constructible] public YoungRonin() : base(AIType.AI_Melee, FightMode.Aggressor) { - SetSpeed(0.3, 1.0); InitStats(45, 30, 5); SetHits(10, 20); diff --git a/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Mobiles/MilitiaFighter.cs b/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Mobiles/MilitiaFighter.cs index 505add3d7..34b3947a6 100644 --- a/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Mobiles/MilitiaFighter.cs +++ b/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Mobiles/MilitiaFighter.cs @@ -11,7 +11,6 @@ namespace Server.Engines.Quests.Haven [Constructible] public MilitiaFighter() : base(AIType.AI_Melee) { - SetSpeed(0.3, 1.0); InitStats(40, 30, 5); Title = "the Militia Fighter"; diff --git a/Projects/UOContent/Holiday Stuff/Halloween/2006/Engines/TrickOrTreat.cs b/Projects/UOContent/Holiday Stuff/Halloween/2006/Engines/TrickOrTreat.cs index 9eda894b9..992214b14 100644 --- a/Projects/UOContent/Holiday Stuff/Halloween/2006/Engines/TrickOrTreat.cs +++ b/Projects/UOContent/Holiday Stuff/Halloween/2006/Engines/TrickOrTreat.cs @@ -278,7 +278,6 @@ namespace Server.Engines.Events public NaughtyTwin(Mobile from) : base(AIType.AI_Melee, FightMode.None) { - SetSpeed(0.3, 1.0); if (TrickOrTreat.CheckMobile(from)) { Body = from.Body; diff --git a/Projects/UOContent/Holiday Stuff/Halloween/2012/Engines/PlayerZombies.cs b/Projects/UOContent/Holiday Stuff/Halloween/2012/Engines/PlayerZombies.cs index efb2cf1e0..30e41249e 100644 --- a/Projects/UOContent/Holiday Stuff/Halloween/2012/Engines/PlayerZombies.cs +++ b/Projects/UOContent/Holiday Stuff/Halloween/2012/Engines/PlayerZombies.cs @@ -166,7 +166,6 @@ namespace Server.Engines.Events Body = 0x93; BaseSoundID = 0x1c3; - SetSpeed(0.3, 1.0); SetStr(500); SetDex(500); SetInt(500); diff --git a/Projects/UOContent/Items/Talismans/TalismanSummons.cs b/Projects/UOContent/Items/Talismans/TalismanSummons.cs index 4f8a4ddf9..262334eb7 100644 --- a/Projects/UOContent/Items/Talismans/TalismanSummons.cs +++ b/Projects/UOContent/Items/Talismans/TalismanSummons.cs @@ -11,7 +11,6 @@ namespace Server.Mobiles public BaseTalismanSummon() : base(AIType.AI_Melee, FightMode.None) { - SetSpeed(0.3, 1.0); // TODO: Stats/skills } diff --git a/Projects/UOContent/Mobiles/AI/BaseAI.cs b/Projects/UOContent/Mobiles/AI/BaseAI.cs index dc6e47c81..4b8a4772a 100644 --- a/Projects/UOContent/Mobiles/AI/BaseAI.cs +++ b/Projects/UOContent/Mobiles/AI/BaseAI.cs @@ -7,6 +7,7 @@ using Server.Engines.Spawners; using Server.Factions; using Server.Gumps; using Server.Items; +using Server.Logging; using Server.Network; using Server.Spells; using Server.Spells.Spellweaving; @@ -1091,7 +1092,7 @@ namespace Server.Mobiles m_Mobile.ControlMaster.RevealingAction(); m_Mobile.CurrentSpeed = m_Mobile.PassiveSpeed; m_Mobile.PlaySound(m_Mobile.GetIdleSound()); - m_Mobile.Warmode = true; + m_Mobile.Warmode = false; m_Mobile.Combatant = null; break; } @@ -1110,8 +1111,7 @@ namespace Server.Mobiles m_Mobile.PlaySound(m_Mobile.GetIdleSound()); m_Mobile.Warmode = true; m_Mobile.Combatant = null; - var petname = $"{m_Mobile.Name}"; - m_Mobile.ControlMaster.SendLocalizedMessage(1049671, petname); // ~1_PETNAME~ is now guarding you. + m_Mobile.ControlMaster.SendLocalizedMessage(1049671, m_Mobile.Name); // ~1_PETNAME~ is now guarding you. break; } @@ -1368,10 +1368,6 @@ namespace Server.Mobiles { m_Mobile.CurrentSpeed = 0.1; } - else if (m_Mobile.CurrentSpeed == m_Mobile.ActiveSpeed && m_Mobile.ControlTarget == m_Mobile.ControlMaster) - { - m_Mobile.CurrentSpeed = Math.Max(SpeedInfo.MinDelay, m_Mobile.CurrentSpeed * 0.5); - } } } } @@ -1923,19 +1919,31 @@ namespace Server.Mobiles public double TransformMoveDelay(double delay) { - // Non-monsters in PVP combat (like pets) are penalized - if (!m_Mobile.IsMonster && m_Mobile.InActivePVPCombat() && delay <= SpeedInfo.MaxDelay) + // Monster is passive + if (m_Mobile is { Controlled: false, Summoned: false } && Math.Abs(delay - m_Mobile.PassiveSpeed) < 0.0001) { - delay += 0.4; + delay *= 3; } if (!m_Mobile.IsDeadPet && (m_Mobile.ReduceSpeedWithDamage || m_Mobile.IsSubdued)) { - double offset = m_Mobile.StamMax <= 0 ? 1.0 : Math.Max(0, m_Mobile.Stam) / (double)m_Mobile.StamMax; + int stats, statsMax; + if (Core.HS) + { + stats = m_Mobile.Stam; + statsMax = m_Mobile.StamMax; + } + else + { + stats = m_Mobile.Hits; + statsMax = m_Mobile.HitsMax; + } + + var offset = statsMax <= 0 ? 1.0 : Math.Max(0, stats) / (double)statsMax; if (offset < 1.0) { - delay += delay * (1.0 - offset); + delay += m_Mobile.PassiveSpeed * (1.0 - offset); } } @@ -1969,7 +1977,6 @@ namespace Server.Mobiles m_Mobile.Direction = d; var delay = (int)(TransformMoveDelay(m_Mobile.CurrentSpeed) * 1000); - NextMove += delay; if (Core.TickCount - NextMove > 0) @@ -2708,7 +2715,7 @@ namespace Server.Mobiles */ public virtual void OnCurrentSpeedChanged() { - m_Timer.Interval = TimeSpan.FromSeconds(Math.Max(0.0, m_Mobile.CurrentSpeed)); + m_Timer.Interval = TimeSpan.FromSeconds(Math.Max(0.008, m_Mobile.CurrentSpeed)); } private class InternalEntry : ContextMenuEntry diff --git a/Projects/UOContent/Mobiles/AI/LegacySpeedInfo.cs b/Projects/UOContent/Mobiles/AI/LegacySpeedInfo.cs deleted file mode 100644 index d4182b3b9..000000000 --- a/Projects/UOContent/Mobiles/AI/LegacySpeedInfo.cs +++ /dev/null @@ -1,77 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Text.Json.Serialization; -using Server.Json; -using Server.Logging; - -namespace Server; - -public class LegacySpeedInfo -{ - private static readonly ILogger logger = LogFactory.GetLogger(typeof(LegacySpeedInfo)); - - private const string _tablePath = "Data/npc-speeds.json"; - private static Dictionary m_Table; - - public static bool Enabled { get; private set; } - - public static bool GetSpeeds(Type type, out double activeSpeed, out double passiveSpeed) - { - if (!(Enabled && m_Table.TryGetValue(type, out var sp))) - { - activeSpeed = 0; - passiveSpeed = 0; - return false; - } - - activeSpeed = sp.ActiveSpeed; - passiveSpeed = sp.PassiveSpeed; - - return true; - } - - public static void Configure() - { - Enabled = ServerConfiguration.GetSetting("movement.delay.useLegacySpeeds", !Core.HS); - - if (!Enabled) - { - return; - } - - var path = Path.Combine(Core.BaseDirectory, _tablePath); - if (!File.Exists(path)) - { - logger.Warning($"Cannot find {path}. Disabling legacy speed system."); - Enabled = false; - return; - } - - var speeds = JsonConfig.Deserialize(path); - - m_Table = new Dictionary(); - - for (var i = 0; i < speeds.Length; ++i) - { - var info = speeds[i]; - - foreach (var type in info.Types) - { - m_Table[type] = info; - } - } - } - - public record LegacySpeedEntry - { - [JsonPropertyName("active")] - public double ActiveSpeed { get; init; } - - [JsonPropertyName("passive")] - public double PassiveSpeed { get; init; } - - [JsonPropertyName("types")] - public HashSet Types { get; init; } - } -} diff --git a/Projects/UOContent/Mobiles/AI/SpeedInfo.cs b/Projects/UOContent/Mobiles/AI/SpeedInfo.cs deleted file mode 100644 index 36811f37a..000000000 --- a/Projects/UOContent/Mobiles/AI/SpeedInfo.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System; -using Server.Mobiles; - -namespace Server; - -public static class SpeedInfo -{ - public static double MinDelay { get; private set; } - public static double MaxDelay { get; private set; } - public static double MinMonsterDelay { get; private set; } - public static double MaxMonsterDelay { get; private set; } - - // Determines the maximum dex for delay by dex - public static int MaxDex { get; private set; } - public static int MaxMonsterDex { get; private set; } - - public static void Configure() - { - // Default speed determined by dex (0 -> 190) for non-monster NPCs including pets - MinDelay = ServerConfiguration.GetOrUpdateSetting("movement.delay.npcMinDelay", 0.1); - MaxDelay = ServerConfiguration.GetOrUpdateSetting("movement.delay.npcMaxDelay", 0.5); - MaxDex = ServerConfiguration.GetOrUpdateSetting("movement.delay.maxDex", 190); - - // Default speed determined by dex (0 -> 150) for monsters - MinMonsterDelay = ServerConfiguration.GetOrUpdateSetting("movement.delay.monsterMinDelay", 0.4); - MaxMonsterDelay = ServerConfiguration.GetOrUpdateSetting("movement.delay.monsterMaxDelay", 0.8); - MaxMonsterDex = ServerConfiguration.GetOrUpdateSetting("movement.delay.monsterMaxDex", 150); - } - - public static void GetSpeeds(BaseCreature bc, out double activeSpeed, out double passiveSpeed) - { - // Legacy is used if it is enabled, and the type is in the table - if (LegacySpeedInfo.GetSpeeds(bc.GetType(), out activeSpeed, out passiveSpeed)) - { - return; - } - - var isMonster = bc.IsMonster; - var maxDex = isMonster ? MaxMonsterDex : MaxDex; - - var dex = Math.Clamp(bc.Dex, 25, maxDex); - - double min = isMonster ? MinMonsterDelay : MinDelay; - double max = isMonster ? MaxMonsterDelay : MaxDelay; - - activeSpeed = Math.Max(max - (max - min) * ((double)dex / maxDex), min); - passiveSpeed = activeSpeed * 2; - } -} diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/Nightmare.cs b/Projects/UOContent/Mobiles/Animals/Mounts/Nightmare.cs index 6c058f86c..e186bec7c 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/Nightmare.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/Nightmare.cs @@ -14,7 +14,26 @@ namespace Server.Mobiles { BaseSoundID = Core.AOS ? 0xA8 : 0x16A; - SetStr(496, 525); + // Publish 97 + if (Core.TOL) + { + if (Utility.RandomDouble() < 0.3) + { + SetStr(296, 315); + ControlSlots = 2; + } + else + { + SetStr(496, 525); + ControlSlots = 3; + } + } + else + { + SetStr(496, 525); + ControlSlots = 2; + } + SetDex(86, 105); SetInt(86, 125); @@ -44,7 +63,6 @@ namespace Server.Mobiles VirtualArmor = 60; Tamable = true; - ControlSlots = 2; MinTameSkill = 95.1; switch (Utility.Random(3)) diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/SeaHorse.cs b/Projects/UOContent/Mobiles/Animals/Mounts/SeaHorse.cs index be56e80a6..4f799c9ad 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/SeaHorse.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/SeaHorse.cs @@ -5,7 +5,6 @@ namespace Server.Mobiles [Constructible] public SeaHorse(string name = "a sea horse") : base(name, 0x90, 0x3EB3, AIType.AI_Animal, FightMode.Aggressor) { - SetSpeed(0.4, 0.8); InitStats(Utility.Random(50, 30), Utility.Random(50, 30), 10); Skills.MagicResist.Base = 25.0 + Utility.RandomDouble() * 5.0; Skills.Wrestling.Base = 35.0 + Utility.RandomDouble() * 10.0; diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/SilverSteed.cs b/Projects/UOContent/Mobiles/Animals/Mounts/SilverSteed.cs index d8ed1fafe..43d32abe8 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/SilverSteed.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/SilverSteed.cs @@ -5,8 +5,6 @@ namespace Server.Mobiles [Constructible] public SilverSteed(string name = "a silver steed") : base(name, 0x75, 0x3EA8, AIType.AI_Animal, FightMode.Aggressor) { - SetSpeed(0.55, 1.1); - InitStats(Utility.Random(50, 30), Utility.Random(50, 30), 10); Skills.MagicResist.Base = 25.0 + Utility.RandomDouble() * 5.0; Skills.Wrestling.Base = 35.0 + Utility.RandomDouble() * 10.0; diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/SkeletalMount.cs b/Projects/UOContent/Mobiles/Animals/Mounts/SkeletalMount.cs index 4e14da8ea..2b2f76a3b 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/SkeletalMount.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/SkeletalMount.cs @@ -5,7 +5,6 @@ namespace Server.Mobiles [Constructible] public SkeletalMount(string name = null) : base(name, 793, 0x3EBB, AIType.AI_Animal, FightMode.Aggressor) { - SetSpeed(0.55, 1.1); SetStr(91, 100); SetDex(46, 55); SetInt(46, 60); diff --git a/Projects/UOContent/Mobiles/BaseCreature.cs b/Projects/UOContent/Mobiles/BaseCreature.cs index a57f8443a..602955362 100644 --- a/Projects/UOContent/Mobiles/BaseCreature.cs +++ b/Projects/UOContent/Mobiles/BaseCreature.cs @@ -338,12 +338,7 @@ namespace Server.Mobiles FightMode = mode; - if (LegacySpeedInfo.Enabled && LegacySpeedInfo.GetSpeeds(GetType(), out var activeSpeed, out var passiveSpeed)) - { - ActiveSpeed = activeSpeed; - PassiveSpeed = passiveSpeed; - CurrentSpeed = passiveSpeed; - } + ResetSpeeds(); m_Team = 0; @@ -879,6 +874,8 @@ namespace Server.Mobiles public virtual bool ReturnsToHome => SeeksHome && Home != Point3D.Zero && !m_ReturnQueued && !Controlled && !Summoned; + public virtual bool ScaleSpeedByDex => NPCSpeeds.ScaleSpeedByDex && !IsMonster; + // used for deleting untamed creatures [in houses] [CommandProperty(AccessLevel.GameMaster)] public bool RemoveIfUntamed { get; set; } @@ -1363,7 +1360,8 @@ namespace Server.Mobiles public override void OnRawDexChange(int oldValue) { - if (oldValue != RawDex && ActiveSpeed <= 0 && PassiveSpeed <= 0) + // This only really happens for pets or when a GM modifies a mob. + if (oldValue != RawDex && ScaleSpeedByDex) { ResetSpeeds(); } @@ -1627,23 +1625,35 @@ namespace Server.Mobiles switch (sc) { case ScaleType.Red: - corpse.AddCarvedItem(new RedScales(scales), from); - break; + { + corpse.AddCarvedItem(new RedScales(scales), from); + break; + } case ScaleType.Yellow: - corpse.AddCarvedItem(new YellowScales(scales), from); - break; + { + corpse.AddCarvedItem(new YellowScales(scales), from); + break; + } case ScaleType.Black: - corpse.AddCarvedItem(new BlackScales(scales), from); - break; + { + corpse.AddCarvedItem(new BlackScales(scales), from); + break; + } case ScaleType.Green: - corpse.AddCarvedItem(new GreenScales(scales), from); - break; + { + corpse.AddCarvedItem(new GreenScales(scales), from); + break; + } case ScaleType.White: - corpse.AddCarvedItem(new WhiteScales(scales), from); - break; + { + corpse.AddCarvedItem(new WhiteScales(scales), from); + break; + } case ScaleType.Blue: - corpse.AddCarvedItem(new BlueScales(scales), from); - break; + { + corpse.AddCarvedItem(new BlueScales(scales), from); + break; + } case ScaleType.All: { corpse.AddCarvedItem(new RedScales(scales), from); @@ -2567,18 +2577,23 @@ namespace Server.Mobiles return false; // not idling, but don't want to enter idle state } - m_IdleReleaseTime = Core.Now + TimeSpan.FromSeconds(Utility.RandomMinMax(15, 25)); + var idleSeconds = Utility.RandomMinMax(NPCSpeeds.MinIdleSeconds, NPCSpeeds.MaxIdleSeconds); + m_IdleReleaseTime = Core.Now + TimeSpan.FromSeconds(idleSeconds); if (Body.IsHuman) { switch (Utility.Random(2)) { case 0: - CheckedAnimate(5, 5, 1, true, true, 1); - break; + { + CheckedAnimate(5, 5, 1, true, true, 1); + break; + } case 1: - CheckedAnimate(6, 5, 1, true, false, 1); - break; + { + CheckedAnimate(6, 5, 1, true, false, 1); + break; + } } } else if (Body.IsAnimal) @@ -2586,14 +2601,20 @@ namespace Server.Mobiles switch (Utility.Random(3)) { case 0: - CheckedAnimate(3, 3, 1, true, false, 1); - break; + { + CheckedAnimate(3, 3, 1, true, false, 1); + break; + } case 1: - CheckedAnimate(9, 5, 1, true, false, 1); - break; + { + CheckedAnimate(9, 5, 1, true, false, 1); + break; + } case 2: - CheckedAnimate(10, 5, 1, true, false, 1); - break; + { + CheckedAnimate(10, 5, 1, true, false, 1); + break; + } } } else if (Body.IsMonster) @@ -2601,11 +2622,15 @@ namespace Server.Mobiles switch (Utility.Random(2)) { case 0: - CheckedAnimate(17, 5, 1, true, false, 1); - break; + { + CheckedAnimate(17, 5, 1, true, false, 1); + break; + } case 1: - CheckedAnimate(18, 5, 1, true, false, 1); - break; + { + CheckedAnimate(18, 5, 1, true, false, 1); + break; + } } } @@ -2862,17 +2887,25 @@ namespace Server.Mobiles switch (Utility.Random(4)) { case 0: - PackItem(new CocoaButter()); - break; + { + PackItem(new CocoaButter()); + break; + } case 1: - PackItem(new CocoaLiquor()); - break; + { + PackItem(new CocoaLiquor()); + break; + } case 2: - PackItem(new SackOfSugar()); - break; + { + PackItem(new SackOfSugar()); + break; + } case 3: - PackItem(new Vanilla()); - break; + { + PackItem(new Vanilla()); + break; + } } } } @@ -3323,11 +3356,6 @@ namespace Server.Mobiles Controlled = false; ControlTarget = null; ControlOrder = OrderType.None; - Guild = null; - - ResetSpeeds(); - - Delta(MobileDelta.Noto); } else { @@ -3351,19 +3379,20 @@ namespace Server.Mobiles Controlled = true; ControlTarget = null; ControlOrder = OrderType.Come; - Guild = null; + if (m_DeleteTimer != null) { m_DeleteTimer.Stop(); m_DeleteTimer = null; } - - ResetSpeeds(true); - - Delta(MobileDelta.Noto); } + Guild = null; + ResetSpeeds(); + + Delta(MobileDelta.Noto); + InvalidateProperties(); return true; @@ -3953,20 +3982,30 @@ namespace Server.Mobiles switch (Utility.Random(5)) { case 0: - physDamage += BreathChaosDamage; - break; + { + physDamage += BreathChaosDamage; + break; + } case 1: - fireDamage += BreathChaosDamage; - break; + { + fireDamage += BreathChaosDamage; + break; + } case 2: - coldDamage += BreathChaosDamage; - break; + { + coldDamage += BreathChaosDamage; + break; + } case 3: - poisDamage += BreathChaosDamage; - break; + { + poisDamage += BreathChaosDamage; + break; + } case 4: - nrgyDamage += BreathChaosDamage; - break; + { + nrgyDamage += BreathChaosDamage; + break; + } } } @@ -4620,20 +4659,30 @@ namespace Server.Mobiles switch (type) { case ResistanceType.Physical: - PhysicalDamage = val; - break; + { + PhysicalDamage = val; + break; + } case ResistanceType.Fire: - FireDamage = val; - break; + { + FireDamage = val; + break; + } case ResistanceType.Cold: - ColdDamage = val; - break; + { + ColdDamage = val; + break; + } case ResistanceType.Poison: - PoisonDamage = val; - break; + { + PoisonDamage = val; + break; + } case ResistanceType.Energy: - EnergyDamage = val; - break; + { + EnergyDamage = val; + break; + } } } @@ -4647,20 +4696,30 @@ namespace Server.Mobiles switch (type) { case ResistanceType.Physical: - m_PhysicalResistance = val; - break; + { + m_PhysicalResistance = val; + break; + } case ResistanceType.Fire: - m_FireResistance = val; - break; + { + m_FireResistance = val; + break; + } case ResistanceType.Cold: - m_ColdResistance = val; - break; + { + m_ColdResistance = val; + break; + } case ResistanceType.Poison: - m_PoisonResistance = val; - break; + { + m_PoisonResistance = val; + break; + } case ResistanceType.Energy: - m_EnergyResistance = val; - break; + { + m_EnergyResistance = val; + break; + } } UpdateResistances(); @@ -4794,9 +4853,17 @@ namespace Server.Mobiles } } - public virtual void ResetSpeeds(bool currentUseActive = false) + // If this needs to be serialized, recommend creating a hash or registry id. Don't serialize strings. + public virtual string SpeedClass => null; + + public virtual void GetSpeeds(out double activeSpeed, out double passiveSpeed) { - SpeedInfo.GetSpeeds(this, out var activeSpeed, out var passiveSpeed); + NPCSpeeds.GetSpeeds(this, out activeSpeed, out passiveSpeed); + } + + public void ResetSpeeds(bool currentUseActive = false) + { + GetSpeeds(out var activeSpeed, out var passiveSpeed); ActiveSpeed = activeSpeed; PassiveSpeed = passiveSpeed; diff --git a/Projects/UOContent/Mobiles/Familiars/BaseFamiliar.cs b/Projects/UOContent/Mobiles/Familiars/BaseFamiliar.cs index dba69c327..8cad6a780 100644 --- a/Projects/UOContent/Mobiles/Familiars/BaseFamiliar.cs +++ b/Projects/UOContent/Mobiles/Familiars/BaseFamiliar.cs @@ -10,7 +10,7 @@ namespace Server.Mobiles public BaseFamiliar() : base(AIType.AI_Melee) { - SetSpeed(0.1, 0.1); + SetSpeed(0.1, 0.11); } public BaseFamiliar(Serial serial) : base(serial) diff --git a/Projects/UOContent/Mobiles/Monsters/AOS/Revenant.cs b/Projects/UOContent/Mobiles/Monsters/AOS/Revenant.cs index 72517630f..057ad6c58 100644 --- a/Projects/UOContent/Mobiles/Monsters/AOS/Revenant.cs +++ b/Projects/UOContent/Mobiles/Monsters/AOS/Revenant.cs @@ -19,8 +19,6 @@ namespace Server.Mobiles m_Target = target; m_ExpireTime = Core.Now + duration; - SetSpeed(0.25, 0.55); - SetStr(200); SetDex(150); SetInt(150); diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/KhaldunRevenant.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/KhaldunRevenant.cs index 02210c9f1..f3298de78 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/KhaldunRevenant.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/KhaldunRevenant.cs @@ -19,8 +19,6 @@ namespace Server.Mobiles m_Target = target; m_ExpireTime = Core.Now + TimeSpan.FromMinutes(10.0); - SetSpeed(0.25, 0.55); - SetStr(401, 500); SetDex(296, 315); SetInt(101, 200); diff --git a/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/ChaosDragoon.cs b/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/ChaosDragoon.cs index f55806873..fb3b38a7c 100644 --- a/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/ChaosDragoon.cs +++ b/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/ChaosDragoon.cs @@ -10,7 +10,7 @@ namespace Server.Mobiles Body = 0x190; Hue = Race.Human.RandomSkinHue(); - SetSpeed(0.25, 1.0); + SetSpeed(0.15, 0.4); SetStr(176, 225); SetDex(81, 95); diff --git a/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/ChaosDragoonElite.cs b/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/ChaosDragoonElite.cs index 331056eb8..5e6bf3b5e 100644 --- a/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/ChaosDragoonElite.cs +++ b/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/ChaosDragoonElite.cs @@ -10,7 +10,7 @@ namespace Server.Mobiles Body = 0x190; Hue = Race.Human.RandomSkinHue(); - SetSpeed(0.25, 1.0); + SetSpeed(0.15, 0.4); SetStr(276, 350); SetDex(66, 90); diff --git a/Projects/UOContent/Mobiles/Monsters/ML/Animal/CuSidhe.cs b/Projects/UOContent/Mobiles/Monsters/ML/Animal/CuSidhe.cs index a06b0fa9f..b6ab6b169 100644 --- a/Projects/UOContent/Mobiles/Monsters/ML/Animal/CuSidhe.cs +++ b/Projects/UOContent/Mobiles/Monsters/ML/Animal/CuSidhe.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles public class CuSidhe : BaseMount { [Constructible] - public CuSidhe(string name = null) : base(name, 277, 0x3E91, AIType.AI_Animal, FightMode.Aggressor, 10, 1) + public CuSidhe(string name = null) : base(name, 277, 0x3E91, AIType.AI_Animal, FightMode.Aggressor) { var chance = Utility.RandomDouble() * 23301; diff --git a/Projects/UOContent/Mobiles/Monsters/ML/Animal/Ferret.cs b/Projects/UOContent/Mobiles/Monsters/ML/Animal/Ferret.cs index 9441427ae..413886152 100644 --- a/Projects/UOContent/Mobiles/Monsters/ML/Animal/Ferret.cs +++ b/Projects/UOContent/Mobiles/Monsters/ML/Animal/Ferret.cs @@ -19,7 +19,6 @@ namespace Server.Mobiles { Body = 0x117; - SetSpeed(0.3, 1.0); SetStr(41, 48); SetDex(55); SetInt(75); diff --git a/Projects/UOContent/Mobiles/Monsters/ML/Animal/RagingGrizzlyBear.cs b/Projects/UOContent/Mobiles/Monsters/ML/Animal/RagingGrizzlyBear.cs index e2d67ddca..d02acc83e 100644 --- a/Projects/UOContent/Mobiles/Monsters/ML/Animal/RagingGrizzlyBear.cs +++ b/Projects/UOContent/Mobiles/Monsters/ML/Animal/RagingGrizzlyBear.cs @@ -8,7 +8,6 @@ namespace Server.Mobiles Body = 212; BaseSoundID = 0xA3; - SetSpeed(0.3, 1.0); SetStr(1251, 1550); SetDex(801, 1050); SetInt(151, 400); diff --git a/Projects/UOContent/Mobiles/Monsters/ML/Animal/Squirrel.cs b/Projects/UOContent/Mobiles/Monsters/ML/Animal/Squirrel.cs index 3ca9ff581..1749f7d73 100644 --- a/Projects/UOContent/Mobiles/Monsters/ML/Animal/Squirrel.cs +++ b/Projects/UOContent/Mobiles/Monsters/ML/Animal/Squirrel.cs @@ -7,7 +7,6 @@ namespace Server.Mobiles { Body = 0x116; - SetSpeed(0.3, 1.0); SetStr(44, 50); SetDex(35); SetInt(5); diff --git a/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Melee/CorruptedSoul.cs b/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Melee/CorruptedSoul.cs index a65b126d8..bed118762 100644 --- a/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Melee/CorruptedSoul.cs +++ b/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Melee/CorruptedSoul.cs @@ -8,14 +8,13 @@ namespace Server.Mobiles Body = 0x3CA; Hue = 0x453; - SetSpeed(0.25, 5); - SetStr(102, 115); SetDex(101, 115); SetInt(203, 215); SetHits(61, 69); + SetSpeed(0.25, 2.5); SetDamage(4, 40); SetDamageType(ResistanceType.Physical, 100); diff --git a/Projects/UOContent/Mobiles/Monsters/ML/Labyrinth/Miasma.cs b/Projects/UOContent/Mobiles/Monsters/ML/Labyrinth/Miasma.cs index 2e8ba905c..456198c9e 100644 --- a/Projects/UOContent/Mobiles/Monsters/ML/Labyrinth/Miasma.cs +++ b/Projects/UOContent/Mobiles/Monsters/ML/Labyrinth/Miasma.cs @@ -11,8 +11,6 @@ namespace Server.Mobiles Hue = 0x8FD; - SetSpeed(0.1, 0.6); - SetStr(255, 847); SetDex(145, 428); SetInt(26, 380); diff --git a/Projects/UOContent/Mobiles/Monsters/ML/Misc/Melee/Reptalon.cs b/Projects/UOContent/Mobiles/Monsters/ML/Misc/Melee/Reptalon.cs index e057936ce..fe27e5c56 100644 --- a/Projects/UOContent/Mobiles/Monsters/ML/Misc/Melee/Reptalon.cs +++ b/Projects/UOContent/Mobiles/Monsters/ML/Misc/Melee/Reptalon.cs @@ -9,8 +9,6 @@ namespace Server.Mobiles { BaseSoundID = 0x16A; - SetSpeed(0.25, 0.55); - SetStr(1001, 1025); SetDex(152, 164); SetInt(251, 289); diff --git a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/BladeSpirits.cs b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/BladeSpirits.cs index d05ffb814..c0ea74690 100644 --- a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/BladeSpirits.cs +++ b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/BladeSpirits.cs @@ -11,7 +11,6 @@ public class BladeSpirits : BaseCreature { Body = 574; - SetSpeed(0.5, 1.2); SetStr(150); SetDex(150); SetInt(100); diff --git a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/Golem.cs b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/Golem.cs index 7dc6ffe5c..7bd41f3f4 100644 --- a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/Golem.cs +++ b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/Golem.cs @@ -18,8 +18,6 @@ namespace Server.Mobiles Hue = 2101; } - SetSpeed(0.9, 1.5); - SetStr((int)(251 * scalar), (int)(350 * scalar)); SetDex((int)(76 * scalar), (int)(100 * scalar)); SetInt((int)(101 * scalar), (int)(150 * scalar)); diff --git a/Projects/UOContent/Mobiles/Monsters/SE/EliteNinja.cs b/Projects/UOContent/Mobiles/Monsters/SE/EliteNinja.cs index 8d21aa003..a16c794c0 100644 --- a/Projects/UOContent/Mobiles/Monsters/SE/EliteNinja.cs +++ b/Projects/UOContent/Mobiles/Monsters/SE/EliteNinja.cs @@ -16,7 +16,7 @@ namespace Server.Mobiles SetHits(251, 350); SetStr(126, 225); - SetDex(81, 95); + SetDex(175, 275); SetInt(151, 165); SetDamage(12, 20); diff --git a/Projects/UOContent/Mobiles/Monsters/SE/FireBeetle.cs b/Projects/UOContent/Mobiles/Monsters/SE/FireBeetle.cs index b6ea95b88..7f4daea42 100644 --- a/Projects/UOContent/Mobiles/Monsters/SE/FireBeetle.cs +++ b/Projects/UOContent/Mobiles/Monsters/SE/FireBeetle.cs @@ -7,10 +7,11 @@ namespace Server.Mobiles public class FireBeetle : BaseMount { [Constructible] - public FireBeetle() : base("a fire beetle", 0xA9, 0x3E95, AIType.AI_Melee, FightMode.Closest, 10, 1) + public FireBeetle() : base("a fire beetle", 0xA9, 0x3E95, AIType.AI_Melee) { + SetStam(100); SetStr(300); - SetDex(100); + SetDex(65, 100); SetInt(500); SetHits(200); diff --git a/Projects/UOContent/Mobiles/NPCSpeeds.cs b/Projects/UOContent/Mobiles/NPCSpeeds.cs new file mode 100644 index 000000000..e6317c91f --- /dev/null +++ b/Projects/UOContent/Mobiles/NPCSpeeds.cs @@ -0,0 +1,102 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text.Json.Serialization; +using Server.Json; + +namespace Server.Mobiles; + +public static class NPCSpeeds +{ + private const string _tablePath = "Data/npc-speeds.json"; + private static Dictionary _speedsByType = new(); + private static Dictionary _speedsByName = new(); + + // Enabled for pets on HS+ + public static bool ScaleSpeedByDex { get; private set; } + public static double MinDelay { get; private set; } + public static double MaxDelay { get; private set; } + public static int MinDex { get; private set; } + public static int MaxDex { get; private set; } + + // Time period to lock NPCs into idling + public static int MinIdleSeconds { get; private set; } + public static int MaxIdleSeconds { get; private set; } + + public static void GetSpeeds(BaseCreature bc, out double activeSpeed, out double passiveSpeed) + { + // Used for scaling pet's speed by dex in HS+ + if (bc.ScaleSpeedByDex) + { + var maxDex = MaxDex; + double min = MinDelay; + double max = MaxDelay; + var dex = Math.Clamp(bc.Dex, MinDex, maxDex); + + activeSpeed = Math.Max(max - (max - min) * ((double)dex / maxDex), min); + passiveSpeed = activeSpeed * 2; + return; + } + + if (bc.SpeedClass != null && _speedsByName.TryGetValue(bc.SpeedClass, out var sp) || + _speedsByType.TryGetValue(bc.GetType(), out sp)) + { + activeSpeed = sp.ActiveSpeed; + passiveSpeed = sp.PassiveSpeed; + return; + } + + // "Fast" + activeSpeed = 0.2; + passiveSpeed = 0.4; + } + + public static void RegisterSpeed(SpeedClassEntry entry) + { + _speedsByName[entry.Name] = entry; + + foreach (var type in entry.Types) + { + _speedsByType[type] = entry; + } + } + + public static void Configure() + { + ScaleSpeedByDex = ServerConfiguration.GetSetting("movement.delay.scaleSpeedByDex", Core.HS); + MinDelay = ServerConfiguration.GetSetting("movement.delay.npcMinDelay", 0.1); + MaxDelay = ServerConfiguration.GetSetting("movement.delay.npcMaxDelay", 0.4); + MaxDex = ServerConfiguration.GetSetting("movement.delay.npcMinDex", 50); + MaxDex = ServerConfiguration.GetSetting("movement.delay.npcMaxDex", 200); + MinIdleSeconds = ServerConfiguration.GetSetting("movement.delay.npcMinIdle", 15); + MaxIdleSeconds = ServerConfiguration.GetSetting("movement.delay.npcMaxIdle", 25); + + var path = Path.Combine(Core.BaseDirectory, _tablePath); + if (!File.Exists(path)) + { + return; + } + + var speeds = JsonConfig.Deserialize(path); + + for (var i = 0; i < speeds.Length; i++) + { + RegisterSpeed(speeds[i]); + } + } + + public record SpeedClassEntry + { + [JsonPropertyName("name")] + public string Name { get; init; } + + [JsonPropertyName("active")] + public double ActiveSpeed { get; init; } + + [JsonPropertyName("passive")] + public double PassiveSpeed { get; init; } + + [JsonPropertyName("types")] + public HashSet Types { get; init; } + } +} diff --git a/Projects/UOContent/Mobiles/Special/BaseChampion.cs b/Projects/UOContent/Mobiles/Special/BaseChampion.cs index 4983292da..0085781a7 100644 --- a/Projects/UOContent/Mobiles/Special/BaseChampion.cs +++ b/Projects/UOContent/Mobiles/Special/BaseChampion.cs @@ -9,7 +9,6 @@ namespace Server.Mobiles { public BaseChampion(AIType aiType, FightMode mode = FightMode.Closest) : base(aiType, mode, 18) { - SetSpeed(0.25, 0.55); } public BaseChampion(Serial serial) : base(serial) diff --git a/Projects/UOContent/Mobiles/Special/BaseShieldGuard.cs b/Projects/UOContent/Mobiles/Special/BaseShieldGuard.cs index 829cea481..3ca4c3232 100644 --- a/Projects/UOContent/Mobiles/Special/BaseShieldGuard.cs +++ b/Projects/UOContent/Mobiles/Special/BaseShieldGuard.cs @@ -7,12 +7,11 @@ namespace Server.Mobiles { public BaseShieldGuard() : base(AIType.AI_Melee, FightMode.Aggressor, 14) { - SetSpeed(0.5, 2.0); InitStats(1000, 1000, 1000); Title = "the guard"; + SetSpeed(0.5, 2.0); SpeechHue = Utility.RandomDyedHue(); - Hue = Race.Human.RandomSkinHue(); if (Female = Utility.RandomBool()) diff --git a/Projects/UOContent/Mobiles/Special/Mephitis.cs b/Projects/UOContent/Mobiles/Special/Mephitis.cs index f7bfe79d5..f6af38c11 100644 --- a/Projects/UOContent/Mobiles/Special/Mephitis.cs +++ b/Projects/UOContent/Mobiles/Special/Mephitis.cs @@ -12,8 +12,6 @@ namespace Server.Mobiles Body = 173; BaseSoundID = 0x183; - SetSpeed(0.1, 0.6); - SetStr(505, 1000); SetDex(102, 300); SetInt(402, 600); diff --git a/Projects/UOContent/Mobiles/Special/Semidar.cs b/Projects/UOContent/Mobiles/Special/Semidar.cs index f2227a90b..e6092bd43 100644 --- a/Projects/UOContent/Mobiles/Special/Semidar.cs +++ b/Projects/UOContent/Mobiles/Special/Semidar.cs @@ -12,8 +12,6 @@ namespace Server.Mobiles Body = 174; BaseSoundID = 0x4B0; - SetSpeed(0.1, 0.6); - SetStr(502, 600); SetDex(102, 200); SetInt(601, 750); diff --git a/Projects/UOContent/Mobiles/Special/Silvani.cs b/Projects/UOContent/Mobiles/Special/Silvani.cs index cdd9c0e75..c103169e8 100644 --- a/Projects/UOContent/Mobiles/Special/Silvani.cs +++ b/Projects/UOContent/Mobiles/Special/Silvani.cs @@ -8,8 +8,6 @@ namespace Server.Mobiles Body = 176; BaseSoundID = 0x467; - SetSpeed(0.25, 0.55); - SetStr(253, 400); SetDex(157, 850); SetInt(503, 800); diff --git a/Projects/UOContent/Mobiles/Townfolk/Actor.cs b/Projects/UOContent/Mobiles/Townfolk/Actor.cs index 38078b040..7dbe6eec6 100644 --- a/Projects/UOContent/Mobiles/Townfolk/Actor.cs +++ b/Projects/UOContent/Mobiles/Townfolk/Actor.cs @@ -7,11 +7,10 @@ namespace Server.Mobiles [Constructible] public Actor() : base(AIType.AI_Animal, FightMode.None) { - SetSpeed(0.6, 1.2); InitStats(31, 41, 51); + SetSpeed(0.2, 0.4); SpeechHue = Utility.RandomDyedHue(); - Hue = Race.Human.RandomSkinHue(); if (Female = Utility.RandomBool()) diff --git a/Projects/UOContent/Mobiles/Townfolk/Artist.cs b/Projects/UOContent/Mobiles/Townfolk/Artist.cs index 4f6276882..de9567ab7 100644 --- a/Projects/UOContent/Mobiles/Townfolk/Artist.cs +++ b/Projects/UOContent/Mobiles/Townfolk/Artist.cs @@ -7,11 +7,10 @@ namespace Server.Mobiles [Constructible] public Artist() : base(AIType.AI_Animal, FightMode.None) { - SetSpeed(0.6, 1.2); InitStats(31, 41, 51); - SetSkill(SkillName.Healing, 36, 68); + SetSpeed(0.2, 0.4); SpeechHue = Utility.RandomDyedHue(); Title = "the artist"; Hue = Race.Human.RandomSkinHue(); diff --git a/Projects/UOContent/Mobiles/Townfolk/BaseEscortable.cs b/Projects/UOContent/Mobiles/Townfolk/BaseEscortable.cs index e7726c6c8..9cecc6c78 100644 --- a/Projects/UOContent/Mobiles/Townfolk/BaseEscortable.cs +++ b/Projects/UOContent/Mobiles/Townfolk/BaseEscortable.cs @@ -94,13 +94,13 @@ namespace Server.Mobiles [Constructible] public BaseEscortable() : base(AIType.AI_Melee, FightMode.Aggressor, 22) { - SetSpeed(0.3, 1.0); - InitBody(); InitOutfit(); Fame = 200; Karma = 4000; + + SetSpeed(0.2, 1.0); } public BaseEscortable(Serial serial) diff --git a/Projects/UOContent/Mobiles/Townfolk/Gypsy.cs b/Projects/UOContent/Mobiles/Townfolk/Gypsy.cs index b6cc02447..b15e221d2 100644 --- a/Projects/UOContent/Mobiles/Townfolk/Gypsy.cs +++ b/Projects/UOContent/Mobiles/Townfolk/Gypsy.cs @@ -7,15 +7,13 @@ namespace Server.Mobiles [Constructible] public Gypsy() : base(AIType.AI_Animal, FightMode.None) { - SetSpeed(0.6, 1.2); InitStats(31, 41, 51); - - SpeechHue = Utility.RandomDyedHue(); - SetSkill(SkillName.Cooking, 65, 88); SetSkill(SkillName.Snooping, 65, 88); SetSkill(SkillName.Stealing, 65, 88); + SetSpeed(0.2, 0.4); + SpeechHue = Utility.RandomDyedHue(); Hue = Race.Human.RandomSkinHue(); if (Female = Utility.RandomBool()) diff --git a/Projects/UOContent/Mobiles/Townfolk/HarborMaster.cs b/Projects/UOContent/Mobiles/Townfolk/HarborMaster.cs index 50b2edd3f..844eb7876 100644 --- a/Projects/UOContent/Mobiles/Townfolk/HarborMaster.cs +++ b/Projects/UOContent/Mobiles/Townfolk/HarborMaster.cs @@ -7,11 +7,10 @@ namespace Server.Mobiles [Constructible] public HarborMaster() : base(AIType.AI_Animal, FightMode.None) { - SetSpeed(0.6, 1.2); InitStats(31, 41, 51); - SetSkill(SkillName.Mining, 36, 68); + SetSpeed(0.2, 0.4); SpeechHue = Utility.RandomDyedHue(); Hue = Race.Human.RandomSkinHue(); Blessed = true; diff --git a/Projects/UOContent/Mobiles/Townfolk/Ninja.cs b/Projects/UOContent/Mobiles/Townfolk/Ninja.cs index d7ff674a3..0026e20d1 100644 --- a/Projects/UOContent/Mobiles/Townfolk/Ninja.cs +++ b/Projects/UOContent/Mobiles/Townfolk/Ninja.cs @@ -8,7 +8,6 @@ namespace Server.Mobiles public Ninja() : base(AIType.AI_Melee, FightMode.Aggressor) { Title = "the ninja"; - InitStats(100, 100, 25); SetSkill(SkillName.Fencing, 64.0, 80.0); @@ -18,8 +17,8 @@ namespace Server.Mobiles SetSkill(SkillName.Tactics, 64.0, 85.0); SetSkill(SkillName.Swords, 64.0, 85.0); + SetSpeed(0.2, 0.4); SpeechHue = Utility.RandomDyedHue(); - Hue = Race.Human.RandomSkinHue(); if (Female = Utility.RandomBool()) diff --git a/Projects/UOContent/Mobiles/Townfolk/Samurai.cs b/Projects/UOContent/Mobiles/Townfolk/Samurai.cs index 3f4022367..14e9f1072 100644 --- a/Projects/UOContent/Mobiles/Townfolk/Samurai.cs +++ b/Projects/UOContent/Mobiles/Townfolk/Samurai.cs @@ -16,8 +16,8 @@ namespace Server.Mobiles SetSkill(SkillName.Parry, 64.0, 80.0); SetSkill(SkillName.Swords, 64.0, 85.0); + SetSpeed(0.2, 0.4); SpeechHue = Utility.RandomDyedHue(); - Hue = Race.Human.RandomSkinHue(); if (Female = Utility.RandomBool()) diff --git a/Projects/UOContent/Mobiles/Townfolk/Sculptor.cs b/Projects/UOContent/Mobiles/Townfolk/Sculptor.cs index 2ce527740..15c126cdb 100644 --- a/Projects/UOContent/Mobiles/Townfolk/Sculptor.cs +++ b/Projects/UOContent/Mobiles/Townfolk/Sculptor.cs @@ -7,9 +7,9 @@ namespace Server.Mobiles [Constructible] public Sculptor() : base(AIType.AI_Animal, FightMode.None) { - SetSpeed(0.6, 1.2); InitStats(31, 41, 51); + SetSpeed(0.2, 0.4); SpeechHue = Utility.RandomDyedHue(); Title = "the sculptor"; Hue = Race.Human.RandomSkinHue(); diff --git a/Projects/UOContent/Mobiles/Townfolk/SeekerOfAdventure.cs b/Projects/UOContent/Mobiles/Townfolk/SeekerOfAdventure.cs index 59bd0b575..fd14c5a38 100644 --- a/Projects/UOContent/Mobiles/Townfolk/SeekerOfAdventure.cs +++ b/Projects/UOContent/Mobiles/Townfolk/SeekerOfAdventure.cs @@ -26,15 +26,7 @@ namespace Server.Mobiles public override bool ClickTitle => false; // Do not display 'the seeker of adventure' when single-clicking - public override string[] GetPossibleDestinations() - { - if (Core.ML) - { - return m_MLDestinations; - } - - return m_Dungeons; - } + public override string[] GetPossibleDestinations() => Core.ML ? m_MLDestinations : m_Dungeons; private static int GetRandomHue() { diff --git a/Projects/UOContent/Mobiles/Vendors/BaseVendor.cs b/Projects/UOContent/Mobiles/Vendors/BaseVendor.cs index ddd4a87e7..0266aa7b0 100644 --- a/Projects/UOContent/Mobiles/Vendors/BaseVendor.cs +++ b/Projects/UOContent/Mobiles/Vendors/BaseVendor.cs @@ -54,12 +54,11 @@ namespace Server.Mobiles public BaseVendor(string title = null) : base(AIType.AI_Vendor, FightMode.None, 2) { - SetSpeed(0.5, 2); LoadSBInfo(); - Title = title; InitBody(); InitOutfit(); + SetSpeed(0.5, 2.0); // these packs MUST exist, or the client will crash when the packets are sent Container pack = new Backpack { Layer = Layer.ShopBuy, Movable = false, Visible = false }; diff --git a/Projects/UOContent/Skills/AnimalTaming.cs b/Projects/UOContent/Skills/AnimalTaming.cs index 99b1293ef..b7a9ffed3 100644 --- a/Projects/UOContent/Skills/AnimalTaming.cs +++ b/Projects/UOContent/Skills/AnimalTaming.cs @@ -486,16 +486,13 @@ namespace Server.SkillHandlers if (m_Creature is GreaterDragon) { ScaleSkills(m_Creature, 0.72, 0.90); // 72% of original skills trainable to 90% - m_Creature.Skills.Magery.Base = - m_Creature.Skills.Magery - .Cap; // Greater dragons have a 90% cap reduction and 90% skill reduction on magery + // Greater dragons have a 90% cap reduction and 90% skill reduction on magery + m_Creature.Skills.Magery.Base = m_Creature.Skills.Magery.Cap; } else if (m_Paralyzed) { - ScaleSkills( - m_Creature, - 0.86 - ); // 86% of original skills if they were paralyzed during the taming + // 86% of original skills if they were paralyzed during the taming + ScaleSkills(m_Creature, 0.86); } else { diff --git a/Projects/UOContent/Spells/Ninjitsu/MirrorImage.cs b/Projects/UOContent/Spells/Ninjitsu/MirrorImage.cs index ed4712940..896d01456 100644 --- a/Projects/UOContent/Spells/Ninjitsu/MirrorImage.cs +++ b/Projects/UOContent/Spells/Ninjitsu/MirrorImage.cs @@ -130,7 +130,6 @@ namespace Server.Mobiles public Clone(Mobile caster) : base(AIType.AI_Melee, FightMode.None) { - SetSpeed(0.3, 1.0); m_Caster = caster; Body = caster.Body; diff --git a/Projects/UOContent/Spells/Spellweaving/Mobiles/ArcaneFey.cs b/Projects/UOContent/Spells/Spellweaving/Mobiles/ArcaneFey.cs index 243dffd13..3f1defbde 100644 --- a/Projects/UOContent/Spells/Spellweaving/Mobiles/ArcaneFey.cs +++ b/Projects/UOContent/Spells/Spellweaving/Mobiles/ArcaneFey.cs @@ -9,7 +9,6 @@ namespace Server.Mobiles Body = 128; BaseSoundID = 0x467; - SetSpeed(0.3, 1.0); SetStr(20); SetDex(150); SetInt(125); diff --git a/Projects/UOContent/Spells/Spellweaving/Mobiles/ArcaneFiend.cs b/Projects/UOContent/Spells/Spellweaving/Mobiles/ArcaneFiend.cs index 34300b5aa..6041979af 100644 --- a/Projects/UOContent/Spells/Spellweaving/Mobiles/ArcaneFiend.cs +++ b/Projects/UOContent/Spells/Spellweaving/Mobiles/ArcaneFiend.cs @@ -8,7 +8,6 @@ namespace Server.Mobiles Body = 74; BaseSoundID = 422; - SetSpeed(0.3, 1.0); SetStr(55); SetDex(40); SetInt(60); diff --git a/Projects/UOContent/Spells/Spellweaving/Mobiles/NatureFury.cs b/Projects/UOContent/Spells/Spellweaving/Mobiles/NatureFury.cs index 61bad44b1..d91aa4318 100644 --- a/Projects/UOContent/Spells/Spellweaving/Mobiles/NatureFury.cs +++ b/Projects/UOContent/Spells/Spellweaving/Mobiles/NatureFury.cs @@ -10,7 +10,6 @@ namespace Server.Mobiles Body = 0x33; Hue = 0x4001; - SetSpeed(0.3, 1.0); SetStr(150); SetDex(150); SetInt(100); From 7b619f23b8fbc8addd93689b470bdda7637eee7c Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 15 May 2022 12:45:51 -0700 Subject: [PATCH 161/213] fix: Fixes static persistence of faction system (#1020) --- Projects/UOContent/Engines/Factions/Core/FactionSystem.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Projects/UOContent/Engines/Factions/Core/FactionSystem.cs b/Projects/UOContent/Engines/Factions/Core/FactionSystem.cs index e1513b0a4..13a8a6df4 100644 --- a/Projects/UOContent/Engines/Factions/Core/FactionSystem.cs +++ b/Projects/UOContent/Engines/Factions/Core/FactionSystem.cs @@ -47,14 +47,12 @@ public static class FactionSystem writer.WriteEncodedInt(0); // version var factions = Faction.Factions; - for (var i = 0; i < factions.Count; i++) { factions[i].State.Serialize(writer); } var towns = Town.Towns; - for (var i = 0; i < towns.Count; i++) { towns[i].State.Serialize(writer); @@ -65,13 +63,13 @@ public static class FactionSystem { var version = reader.ReadEncodedInt(); - var count = reader.ReadEncodedInt(); + var count = Faction.Factions.Count; for (var i = 0; i < count; i++) { new FactionState(reader); } - count = reader.ReadEncodedInt(); + count = Town.Towns.Count; for (var i = 0; i < count; i++) { new TownState(reader); From dd95a8a1e3d910aedc00fd8e8a52e8342c7fba77 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 15 May 2022 21:56:04 -0700 Subject: [PATCH 162/213] fix: Codegens Food & Beverages (#1021) - [X] Simplifies beverages - [X] Codegens food & beverages --- Projects/UOContent/Items/Food/Asian.cs | 482 ++--- Projects/UOContent/Items/Food/Beverage.cs | 1859 +++++++---------- .../Server.Items.AwaseMisoSoup.v0.json | 4 + .../Server.Items.BaseBeverage.v2.json | 32 + .../Migrations/Server.Items.BentoBox.v0.json | 4 + .../Server.Items.BeverageBottle.v0.json | 4 + .../Server.Items.CeramicMug.v0.json | 4 + .../Server.Items.EmptyBentoBox.v0.json | 4 + .../Migrations/Server.Items.GlassMug.v0.json | 4 + .../Migrations/Server.Items.Goblet.v0.json | 4 + .../Migrations/Server.Items.GreenTea.v0.json | 4 + .../Server.Items.GreenTeaBasket.v0.json | 4 + .../Migrations/Server.Items.Jug.v0.json | 4 + .../Migrations/Server.Items.MisoSoup.v0.json | 4 + .../Migrations/Server.Items.PewterMug.v0.json | 4 + .../Migrations/Server.Items.Pitcher.v0.json | 4 + .../Server.Items.RedMisoSoup.v0.json | 4 + .../Server.Items.SushiPlatter.v0.json | 4 + .../Server.Items.SushiRolls.v0.json | 4 + .../Migrations/Server.Items.Wasabi.v0.json | 4 + .../Server.Items.WasabiClumps.v0.json | 4 + .../Server.Items.WhiteMisoSoup.v0.json | 4 + Projects/UOContent/Misc/Poison.cs | 4 +- 23 files changed, 965 insertions(+), 1488 deletions(-) create mode 100644 Projects/UOContent/Migrations/Server.Items.AwaseMisoSoup.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.BaseBeverage.v2.json create mode 100644 Projects/UOContent/Migrations/Server.Items.BentoBox.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.BeverageBottle.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.CeramicMug.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.EmptyBentoBox.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.GlassMug.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Goblet.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.GreenTea.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.GreenTeaBasket.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Jug.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.MisoSoup.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.PewterMug.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Pitcher.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.RedMisoSoup.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.SushiPlatter.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.SushiRolls.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Wasabi.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.WasabiClumps.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.WhiteMisoSoup.v0.json diff --git a/Projects/UOContent/Items/Food/Asian.cs b/Projects/UOContent/Items/Food/Asian.cs index b7ea61a6b..b80e5f2d9 100644 --- a/Projects/UOContent/Items/Food/Asian.cs +++ b/Projects/UOContent/Items/Food/Asian.cs @@ -1,346 +1,144 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class Wasabi : Food { - public class Wasabi : Item + [Constructible] + public Wasabi() : base(0x24E8) => Weight = 1.0; +} + +[SerializationGenerator(0, false)] +public partial class WasabiClumps : Food +{ + [Constructible] + public WasabiClumps() : base(0x24EB) { - [Constructible] - public Wasabi() : base(0x24E8) => Weight = 1.0; - - public Wasabi(Serial serial) : base(serial) - { - } - - 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 WasabiClumps : Food - { - [Constructible] - public WasabiClumps() : base(0x24EB) - { - Stackable = false; - Weight = 1.0; - FillFactor = 2; - } - - public WasabiClumps(Serial serial) : base(serial) - { - } - - 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 EmptyBentoBox : Item - { - [Constructible] - public EmptyBentoBox() : base(0x2834) => Weight = 5.0; - - public EmptyBentoBox(Serial serial) : base(serial) - { - } - - 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 BentoBox : Food - { - [Constructible] - public BentoBox() : base(0x2836) - { - Stackable = false; - Weight = 5.0; - FillFactor = 2; - } - - public BentoBox(Serial serial) : base(serial) - { - } - - public override bool Eat(Mobile from) - { - if (!base.Eat(from)) - { - return false; - } - - from.AddToBackpack(new EmptyBentoBox()); - return 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 SushiRolls : Food - { - [Constructible] - public SushiRolls() : base(0x283E) - { - Stackable = false; - Weight = 3.0; - FillFactor = 2; - } - - public SushiRolls(Serial serial) : base(serial) - { - } - - 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 SushiPlatter : Food - { - [Constructible] - public SushiPlatter() : base(0x2840) - { - Stackable = Core.ML; - Weight = 3.0; - FillFactor = 2; - } - - public SushiPlatter(Serial serial) : base(serial) - { - } - - 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 GreenTeaBasket : Item - { - [Constructible] - public GreenTeaBasket() : base(0x284B) => Weight = 10.0; - - public GreenTeaBasket(Serial serial) : base(serial) - { - } - - 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 GreenTea : Food - { - [Constructible] - public GreenTea() : base(0x284C) - { - Stackable = false; - Weight = 4.0; - FillFactor = 2; - } - - public GreenTea(Serial serial) : base(serial) - { - } - - 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 MisoSoup : Food - { - [Constructible] - public MisoSoup() : base(0x284D) - { - Stackable = false; - Weight = 4.0; - FillFactor = 2; - } - - public MisoSoup(Serial serial) : base(serial) - { - } - - 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 WhiteMisoSoup : Food - { - [Constructible] - public WhiteMisoSoup() : base(0x284E) - { - Stackable = false; - Weight = 4.0; - FillFactor = 2; - } - - public WhiteMisoSoup(Serial serial) : base(serial) - { - } - - 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 RedMisoSoup : Food - { - [Constructible] - public RedMisoSoup() : base(0x284F) - { - Stackable = false; - Weight = 4.0; - FillFactor = 2; - } - - public RedMisoSoup(Serial serial) : base(serial) - { - } - - 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 AwaseMisoSoup : Food - { - [Constructible] - public AwaseMisoSoup() : base(0x2850) - { - Stackable = false; - Weight = 4.0; - FillFactor = 2; - } - - public AwaseMisoSoup(Serial serial) : base(serial) - { - } - - 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(); - } + Stackable = false; + Weight = 1.0; + FillFactor = 2; + } +} + +[SerializationGenerator(0, false)] +public partial class EmptyBentoBox : Item +{ + [Constructible] + public EmptyBentoBox() : base(0x2834) => Weight = 5.0; + +} + +[SerializationGenerator(0, false)] +public partial class BentoBox : Food +{ + [Constructible] + public BentoBox() : base(0x2836) + { + Stackable = false; + Weight = 5.0; + FillFactor = 2; + } + + public override bool Eat(Mobile from) + { + if (!base.Eat(from)) + { + return false; + } + + from.AddToBackpack(new EmptyBentoBox()); + return true; + } +} + +[SerializationGenerator(0, false)] +public partial class SushiRolls : Food +{ + [Constructible] + public SushiRolls() : base(0x283E) + { + Stackable = false; + Weight = 3.0; + FillFactor = 2; + } +} + +[SerializationGenerator(0, false)] +public partial class SushiPlatter : Food +{ + [Constructible] + public SushiPlatter() : base(0x2840) + { + Stackable = Core.ML; + Weight = 3.0; + FillFactor = 2; + } +} + +[SerializationGenerator(0, false)] +public partial class GreenTeaBasket : Item +{ + [Constructible] + public GreenTeaBasket() : base(0x284B) => Weight = 10.0; +} + +[SerializationGenerator(0, false)] +public partial class GreenTea : Food +{ + [Constructible] + public GreenTea() : base(0x284C) + { + Stackable = false; + Weight = 4.0; + FillFactor = 2; + } +} + +[SerializationGenerator(0, false)] +public partial class MisoSoup : Food +{ + [Constructible] + public MisoSoup() : base(0x284D) + { + Stackable = false; + Weight = 4.0; + FillFactor = 2; + } +} + +[SerializationGenerator(0, false)] +public partial class WhiteMisoSoup : Food +{ + [Constructible] + public WhiteMisoSoup() : base(0x284E) + { + Stackable = false; + Weight = 4.0; + FillFactor = 2; + } +} + +[SerializationGenerator(0, false)] +public partial class RedMisoSoup : Food +{ + [Constructible] + public RedMisoSoup() : base(0x284F) + { + Stackable = false; + Weight = 4.0; + FillFactor = 2; + } +} + +[SerializationGenerator(0, false)] +public partial class AwaseMisoSoup : Food +{ + [Constructible] + public AwaseMisoSoup() : base(0x2850) + { + Stackable = false; + Weight = 4.0; + FillFactor = 2; } } diff --git a/Projects/UOContent/Items/Food/Beverage.cs b/Projects/UOContent/Items/Food/Beverage.cs index 49280cbe8..10f71c6a6 100644 --- a/Projects/UOContent/Items/Food/Beverage.cs +++ b/Projects/UOContent/Items/Food/Beverage.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using ModernUO.Serialization; using Server.Engines.Plants; using Server.Engines.Quests; using Server.Engines.Quests.Hag; @@ -9,1233 +10,803 @@ using Server.Multis; using Server.Network; using Server.Targeting; -namespace Server.Items +namespace Server.Items; + +public enum BeverageType { - public enum BeverageType + Ale, + Cider, + Liquor, + Milk, + Wine, + Water +} + +public interface IHasQuantity +{ + int Quantity { get; set; } +} + +public interface IWaterSource : IHasQuantity +{ +} + +// TODO: Flippable attributes +[SerializationGenerator(0, false)] +[TypeAlias("Server.Items.BottleAle", "Server.Items.BottleLiquor", "Server.Items.BottleWine")] +public partial class BeverageBottle : BaseBeverage +{ + [Constructible] + public BeverageBottle(BeverageType type) : base(type) => Weight = 1.0; + + public override int BaseLabelNumber => 1042959; // a bottle of Ale + public override int MaxQuantity => 5; + public override bool Fillable => false; + + public override int ComputeItemID() { - Ale, - Cider, - Liquor, - Milk, - Wine, - Water - } - - public interface IHasQuantity - { - int Quantity { get; set; } - } - - public interface IWaterSource : IHasQuantity - { - } - - // TODO: Flippable attributes - - [TypeAlias("Server.Items.BottleAle", "Server.Items.BottleLiquor", "Server.Items.BottleWine")] - public class BeverageBottle : BaseBeverage - { - [Constructible] - public BeverageBottle(BeverageType type) - : base(type) => - Weight = 1.0; - - public BeverageBottle(Serial serial) - : base(serial) + if (IsEmpty) { - } - - public override int BaseLabelNumber => 1042959; // a bottle of Ale - public override int MaxQuantity => 5; - public override bool Fillable => false; - - public override int ComputeItemID() - { - if (!IsEmpty) - { - switch (Content) - { - case BeverageType.Ale: return 0x99F; - case BeverageType.Cider: return 0x99F; - case BeverageType.Liquor: return 0x99B; - case BeverageType.Milk: return 0x99B; - case BeverageType.Wine: return 0x9C7; - case BeverageType.Water: return 0x99B; - } - } - return 0; } - public override void Serialize(IGenericWriter writer) + return Content switch { - base.Serialize(writer); + BeverageType.Ale => 0x99F, + BeverageType.Cider => 0x99F, + BeverageType.Liquor => 0x99B, + BeverageType.Milk => 0x99B, + BeverageType.Wine => 0x9C7, + BeverageType.Water => 0x99B, + _ => 0 + }; + } +} - writer.Write(1); // version +[SerializationGenerator(0, false)] +public partial class Jug : BaseBeverage +{ + [Constructible] + public Jug(BeverageType type) : base(type) => Weight = 1.0; + + public override int BaseLabelNumber => 1042965; // a jug of Ale + public override int MaxQuantity => 10; + public override bool Fillable => false; + + public override int ComputeItemID() => !IsEmpty ? 0x9C8 : 0; +} + +[SerializationGenerator(0, false)] +public partial class CeramicMug : BaseBeverage +{ + [Constructible] + public CeramicMug() => Weight = 1.0; + + [Constructible] + public CeramicMug(BeverageType type) : base(type) => Weight = 1.0; + + public override int BaseLabelNumber => 1042982; // a ceramic mug of Ale + public override int MaxQuantity => 1; + + public override int ComputeItemID() => ItemID is (< 0x995 or > 0x999) and not 0x9CA ? 0x995 : ItemID; +} + +[SerializationGenerator(0, false)] +public partial class PewterMug : BaseBeverage +{ + [Constructible] + public PewterMug() => Weight = 1.0; + + [Constructible] + public PewterMug(BeverageType type) : base(type) => Weight = 1.0; + + public override int BaseLabelNumber => 1042994; // a pewter mug with Ale + public override int MaxQuantity => 1; + + public override int ComputeItemID() => ItemID is >= 0xFFF and <= 0x1002 ? ItemID : 0xFFF; +} + +[SerializationGenerator(0, false)] +public partial class Goblet : BaseBeverage +{ + [Constructible] + public Goblet() => Weight = 1.0; + + [Constructible] + public Goblet(BeverageType type) : base(type) => Weight = 1.0; + + public override int BaseLabelNumber => 1043000; // a goblet of Ale + public override int MaxQuantity => 1; + + public override int ComputeItemID() => ItemID is 0x99A or 0x9B3 or 0x9BF or 0x9CB ? ItemID : 0x99A; +} + +[TypeAlias( + "Server.Items.MugAle", + "Server.Items.GlassCider", + "Server.Items.GlassLiquor", + "Server.Items.GlassMilk", + "Server.Items.GlassWine", + "Server.Items.GlassWater" +)] +[SerializationGenerator(0, false)] +public partial class GlassMug : BaseBeverage +{ + [Constructible] + public GlassMug() => Weight = 1.0; + + [Constructible] + public GlassMug(BeverageType type) : base(type) => Weight = 1.0; + + public override int EmptyLabelNumber => 1022456; // mug + public override int BaseLabelNumber => 1042976; // a mug of Ale + public override int MaxQuantity => 5; + + public override int ComputeItemID() + { + if (IsEmpty) + { + return ItemID is >= 0x1F81 and <= 0x1F84 ? ItemID : 0x1F81; } - public override void Deserialize(IGenericReader reader) + return Content switch { - base.Deserialize(reader); + BeverageType.Ale => ItemID == 0x9EF ? 0x9EF : 0x9EE, + BeverageType.Cider => Math.Clamp(ItemID, 0x1F7D, 0x1F80), + BeverageType.Liquor => Math.Clamp(ItemID, 0x1F85, 0x1F88), + BeverageType.Milk => Math.Clamp(ItemID, 0x1F89, 0x1F8C), + BeverageType.Wine => Math.Clamp(ItemID, 0x1F8D, 0x1F90), + BeverageType.Water => Math.Clamp(ItemID, 0x1F91, 0x1F94), + _ => 0 + }; + } +} - var version = reader.ReadInt(); +[TypeAlias( + "Server.Items.PitcherAle", + "Server.Items.PitcherCider", + "Server.Items.PitcherLiquor", + "Server.Items.PitcherMilk", + "Server.Items.PitcherWine", + "Server.Items.PitcherWater", + "Server.Items.GlassPitcher" +)] +[SerializationGenerator(0, false)] +public partial class Pitcher : BaseBeverage +{ + [Constructible] + public Pitcher() => Weight = 2.0; - switch (version) - { - case 0: - { - if (CheckType("BottleAle")) - { - Quantity = MaxQuantity; - Content = BeverageType.Ale; - } - else if (CheckType("BottleLiquor")) - { - Quantity = MaxQuantity; - Content = BeverageType.Liquor; - } - else if (CheckType("BottleWine")) - { - Quantity = MaxQuantity; - Content = BeverageType.Wine; - } - else - { - throw new Exception("Invalid beverage type"); - } + [Constructible] + public Pitcher(BeverageType type) : base(type) => Weight = 2.0; - break; - } - } + public override int BaseLabelNumber => 1048128; // a Pitcher of Ale + public override int MaxQuantity => 5; + + public override int ComputeItemID() + { + if (IsEmpty) + { + return ItemID is 0x9A7 or 0xFF7 ? ItemID : 0xFF6; } + + return Content switch + { + BeverageType.Ale => ItemID == 0x1F96 ? ItemID : 0x1F95, + BeverageType.Cider => ItemID == 0x1F98 ? ItemID : 0x1F97, + BeverageType.Liquor => ItemID == 0x1F9A ? ItemID : 0x1F99, + BeverageType.Milk => ItemID == 0x9AD ? ItemID : 0x9F0, + BeverageType.Wine => ItemID == 0x1F9C ? ItemID : 0x1F9B, + BeverageType.Water => ItemID is 0xFF8 or 0xFF9 or 0x1F9E ? ItemID : 0x1F9D, + _ => 0 + }; + } +} + +[SerializationGenerator(2, false)] +public abstract partial class BaseBeverage : Item, IHasQuantity +{ + private readonly int[] _swampTiles = + { + 0x9C4, 0x9EB, + 0x3D65, 0x3D65, + 0x3DC0, 0x3DD9, + 0x3DDB, 0x3DDC, + 0x3DDE, 0x3EF0, + 0x3FF6, 0x3FF6, + 0x3FFC, 0x3FFE + }; + + private static readonly Dictionary m_Table = new(); + + [SerializableField(0)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private Poison _poison; + + [SerializableField(1)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private Mobile _poisoner; + + [SerializableField(2, getter: "private", setter: "private")] + private BeverageType _rawContent; + + [SerializableField(3, getter: "private", setter: "private")] + private int _rawQuantity; + + public BaseBeverage() => ItemID = ComputeItemID(); + + public BaseBeverage(BeverageType type) + { + _rawContent = type; + _rawQuantity = MaxQuantity; + ItemID = ComputeItemID(); } - public class Jug : BaseBeverage + public override int LabelNumber => + IsEmpty || BaseLabelNumber == 0 ? EmptyLabelNumber : BaseLabelNumber + (int)_rawContent; + + public virtual bool ShowQuantity => MaxQuantity > 1; + public virtual bool Fillable => true; + public virtual bool Pourable => true; + + public virtual int EmptyLabelNumber => base.LabelNumber; + public virtual int BaseLabelNumber => 0; + + public abstract int MaxQuantity { get; } + + [CommandProperty(AccessLevel.GameMaster)] + public bool IsEmpty => _rawQuantity <= 0; + + [CommandProperty(AccessLevel.GameMaster)] + public bool ContainsAlcohol => !IsEmpty && _rawContent is not BeverageType.Milk and not BeverageType.Water; + + [CommandProperty(AccessLevel.GameMaster)] + public bool IsFull => _rawQuantity >= MaxQuantity; + + [CommandProperty(AccessLevel.GameMaster)] + public BeverageType Content { - [Constructible] - public Jug(BeverageType type) - : base(type) => - Weight = 1.0; - - public Jug(Serial serial) - : base(serial) + get => _rawContent; + set { - } + RawContent = value; - public override int BaseLabelNumber => 1042965; // a jug of Ale - public override int MaxQuantity => 10; - public override bool Fillable => false; + InvalidateProperties(); - public override int ComputeItemID() - { - if (!IsEmpty) + var itemID = ComputeItemID(); + + if (itemID > 0) { - return 0x9C8; - } - - return 0; - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(1); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } - - public class CeramicMug : BaseBeverage - { - [Constructible] - public CeramicMug() => Weight = 1.0; - - [Constructible] - public CeramicMug(BeverageType type) - : base(type) => - Weight = 1.0; - - public CeramicMug(Serial serial) - : base(serial) - { - } - - public override int BaseLabelNumber => 1042982; // a ceramic mug of Ale - public override int MaxQuantity => 1; - - public override int ComputeItemID() - { - if (ItemID >= 0x995 && ItemID <= 0x999) - { - return ItemID; - } - - if (ItemID == 0x9CA) - { - return ItemID; - } - - return 0x995; - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(1); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } - - public class PewterMug : BaseBeverage - { - [Constructible] - public PewterMug() => Weight = 1.0; - - [Constructible] - public PewterMug(BeverageType type) - : base(type) => - Weight = 1.0; - - public PewterMug(Serial serial) - : base(serial) - { - } - - public override int BaseLabelNumber => 1042994; // a pewter mug with Ale - public override int MaxQuantity => 1; - - public override int ComputeItemID() - { - if (ItemID >= 0xFFF && ItemID <= 0x1002) - { - return ItemID; - } - - return 0xFFF; - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(1); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } - - public class Goblet : BaseBeverage - { - [Constructible] - public Goblet() => Weight = 1.0; - - [Constructible] - public Goblet(BeverageType type) - : base(type) => - Weight = 1.0; - - public Goblet(Serial serial) - : base(serial) - { - } - - public override int BaseLabelNumber => 1043000; // a goblet of Ale - public override int MaxQuantity => 1; - - public override int ComputeItemID() - { - if (ItemID is 0x99A or 0x9B3 or 0x9BF or 0x9CB) - { - return ItemID; - } - - return 0x99A; - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(1); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } - - [TypeAlias( - "Server.Items.MugAle", - "Server.Items.GlassCider", - "Server.Items.GlassLiquor", - "Server.Items.GlassMilk", - "Server.Items.GlassWine", - "Server.Items.GlassWater" - )] - public class GlassMug : BaseBeverage - { - [Constructible] - public GlassMug() => Weight = 1.0; - - [Constructible] - public GlassMug(BeverageType type) - : base(type) => - Weight = 1.0; - - public GlassMug(Serial serial) - : base(serial) - { - } - - public override int EmptyLabelNumber => 1022456; // mug - public override int BaseLabelNumber => 1042976; // a mug of Ale - public override int MaxQuantity => 5; - - public override int ComputeItemID() - { - if (IsEmpty) - { - return ItemID >= 0x1F81 && ItemID <= 0x1F84 ? ItemID : 0x1F81; - } - - return Content switch - { - BeverageType.Ale => ItemID == 0x9EF ? 0x9EF : 0x9EE, - BeverageType.Cider => ItemID >= 0x1F7D && ItemID <= 0x1F80 ? ItemID : 0x1F7D, - BeverageType.Liquor => ItemID >= 0x1F85 && ItemID <= 0x1F88 ? ItemID : 0x1F85, - BeverageType.Milk => ItemID >= 0x1F89 && ItemID <= 0x1F8C ? ItemID : 0x1F89, - BeverageType.Wine => ItemID >= 0x1F8D && ItemID <= 0x1F90 ? ItemID : 0x1F8D, - BeverageType.Water => ItemID >= 0x1F91 && ItemID <= 0x1F94 ? ItemID : 0x1F91, - _ => 0 - }; - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(1); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - switch (version) - { - case 0: - { - if (CheckType("MugAle")) - { - Quantity = MaxQuantity; - Content = BeverageType.Ale; - } - else if (CheckType("GlassCider")) - { - Quantity = MaxQuantity; - Content = BeverageType.Cider; - } - else if (CheckType("GlassLiquor")) - { - Quantity = MaxQuantity; - Content = BeverageType.Liquor; - } - else if (CheckType("GlassMilk")) - { - Quantity = MaxQuantity; - Content = BeverageType.Milk; - } - else if (CheckType("GlassWine")) - { - Quantity = MaxQuantity; - Content = BeverageType.Wine; - } - else if (CheckType("GlassWater")) - { - Quantity = MaxQuantity; - Content = BeverageType.Water; - } - else - { - throw new Exception("Invalid beverage type"); - } - - break; - } - } - } - } - - [TypeAlias( - "Server.Items.PitcherAle", - "Server.Items.PitcherCider", - "Server.Items.PitcherLiquor", - "Server.Items.PitcherMilk", - "Server.Items.PitcherWine", - "Server.Items.PitcherWater", - "Server.Items.GlassPitcher" - )] - public class Pitcher : BaseBeverage - { - [Constructible] - public Pitcher() => Weight = 2.0; - - [Constructible] - public Pitcher(BeverageType type) - : base(type) => - Weight = 2.0; - - public Pitcher(Serial serial) - : base(serial) - { - } - - public override int BaseLabelNumber => 1048128; // a Pitcher of Ale - public override int MaxQuantity => 5; - - public override int ComputeItemID() - { - if (IsEmpty) - { - if (ItemID is 0x9A7 or 0xFF7) - { - return ItemID; - } - - return 0xFF6; - } - - switch (Content) - { - case BeverageType.Ale: - { - if (ItemID == 0x1F96) - { - return ItemID; - } - - return 0x1F95; - } - case BeverageType.Cider: - { - if (ItemID == 0x1F98) - { - return ItemID; - } - - return 0x1F97; - } - case BeverageType.Liquor: - { - if (ItemID == 0x1F9A) - { - return ItemID; - } - - return 0x1F99; - } - case BeverageType.Milk: - { - if (ItemID == 0x9AD) - { - return ItemID; - } - - return 0x9F0; - } - case BeverageType.Wine: - { - if (ItemID == 0x1F9C) - { - return ItemID; - } - - return 0x1F9B; - } - case BeverageType.Water: - { - if (ItemID is 0xFF8 or 0xFF9 or 0x1F9E) - { - return ItemID; - } - - return 0x1F9D; - } - } - - return 0; - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(1); // version - } - - public override void Deserialize(IGenericReader reader) - { - if (CheckType("PitcherWater") || CheckType("GlassPitcher")) - { - InternalDeserialize(reader, false); + ItemID = itemID; } else { - InternalDeserialize(reader, true); - } - - var version = reader.ReadInt(); - - switch (version) - { - case 0: - { - if (CheckType("PitcherAle")) - { - Quantity = MaxQuantity; - Content = BeverageType.Ale; - } - else if (CheckType("PitcherCider")) - { - Quantity = MaxQuantity; - Content = BeverageType.Cider; - } - else if (CheckType("PitcherLiquor")) - { - Quantity = MaxQuantity; - Content = BeverageType.Liquor; - } - else if (CheckType("PitcherMilk")) - { - Quantity = MaxQuantity; - Content = BeverageType.Milk; - } - else if (CheckType("PitcherWine")) - { - Quantity = MaxQuantity; - Content = BeverageType.Wine; - } - else if (CheckType("PitcherWater")) - { - Quantity = MaxQuantity; - Content = BeverageType.Water; - } - else if (CheckType("GlassPitcher")) - { - Quantity = 0; - Content = BeverageType.Water; - } - else - { - throw new Exception("Invalid beverage type"); - } - - break; - } + Delete(); } } } - public abstract class BaseBeverage : Item, IHasQuantity + [CommandProperty(AccessLevel.GameMaster)] + public int Quantity { - private static readonly int[] m_SwampTiles = + get => _rawQuantity; + set { - 0x9C4, 0x9EB, - 0x3D65, 0x3D65, - 0x3DC0, 0x3DD9, - 0x3DDB, 0x3DDC, - 0x3DDE, 0x3EF0, - 0x3FF6, 0x3FF6, - 0x3FFC, 0x3FFE + RawQuantity = Math.Clamp(value, 0, MaxQuantity); + + InvalidateProperties(); + + var itemID = ComputeItemID(); + + if (itemID > 0) + { + ItemID = itemID; + } + else + { + Delete(); + } + } + } + + public abstract int ComputeItemID(); + + public virtual int GetQuantityDescription() + { + return (_rawQuantity * 100 / MaxQuantity) switch + { + <= 0 => 1042975, + <= 33 => 1042974, + <= 66 => 1042973, + _ => 1042972 }; + } - private static readonly Dictionary m_Table = new(); + public override void GetProperties(ObjectPropertyList list) + { + base.GetProperties(list); - private BeverageType m_Content; - private int m_Quantity; - - public BaseBeverage() => ItemID = ComputeItemID(); - - public BaseBeverage(BeverageType type) + if (ShowQuantity) { - m_Content = type; - m_Quantity = MaxQuantity; - ItemID = ComputeItemID(); + list.Add(GetQuantityDescription()); + } + } + + public override void OnSingleClick(Mobile from) + { + base.OnSingleClick(from); + + if (ShowQuantity) + { + LabelTo(from, GetQuantityDescription()); + } + } + + public virtual bool ValidateUse(Mobile from, bool message) + { + if (Deleted) + { + return false; } - public BaseBeverage(Serial serial) - : base(serial) + if (!Movable && !Fillable) { - } + var house = BaseHouse.FindHouseAt(this); - public override int LabelNumber - { - get - { - var num = BaseLabelNumber; - - if (IsEmpty || num == 0) - { - return EmptyLabelNumber; - } - - return BaseLabelNumber + (int)m_Content; - } - } - - public virtual bool ShowQuantity => MaxQuantity > 1; - public virtual bool Fillable => true; - public virtual bool Pourable => true; - - public virtual int EmptyLabelNumber => base.LabelNumber; - public virtual int BaseLabelNumber => 0; - - public abstract int MaxQuantity { get; } - - [CommandProperty(AccessLevel.GameMaster)] - public bool IsEmpty => m_Quantity <= 0; - - [CommandProperty(AccessLevel.GameMaster)] - public bool ContainsAlchohol => !IsEmpty && m_Content != BeverageType.Milk && m_Content != BeverageType.Water; - - [CommandProperty(AccessLevel.GameMaster)] - public bool IsFull => m_Quantity >= MaxQuantity; - - [CommandProperty(AccessLevel.GameMaster)] - public Poison Poison { get; set; } - - [CommandProperty(AccessLevel.GameMaster)] - public Mobile Poisoner { get; set; } - - [CommandProperty(AccessLevel.GameMaster)] - public BeverageType Content - { - get => m_Content; - set - { - m_Content = value; - - InvalidateProperties(); - - var itemID = ComputeItemID(); - - if (itemID > 0) - { - ItemID = itemID; - } - else - { - Delete(); - } - } - } - - [CommandProperty(AccessLevel.GameMaster)] - public int Quantity - { - get => m_Quantity; - set - { - m_Quantity = Math.Clamp(value, 0, MaxQuantity); - - InvalidateProperties(); - - var itemID = ComputeItemID(); - - if (itemID > 0) - { - ItemID = itemID; - } - else - { - Delete(); - } - } - } - - public abstract int ComputeItemID(); - - public virtual int GetQuantityDescription() - { - var perc = m_Quantity * 100 / MaxQuantity; - - if (perc <= 0) - { - return 1042975; // It's empty. - } - - if (perc <= 33) - { - return 1042974; // It's nearly empty. - } - - if (perc <= 66) - { - return 1042973; // It's half full. - } - - return 1042972; // It's full. - } - - public override void GetProperties(ObjectPropertyList list) - { - base.GetProperties(list); - - if (ShowQuantity) - { - list.Add(GetQuantityDescription()); - } - } - - public override void OnSingleClick(Mobile from) - { - base.OnSingleClick(from); - - if (ShowQuantity) - { - LabelTo(from, GetQuantityDescription()); - } - } - - public virtual bool ValidateUse(Mobile from, bool message) - { - if (Deleted) - { - return false; - } - - if (!Movable && !Fillable) - { - var house = BaseHouse.FindHouseAt(this); - - if (house?.HasLockedDownItem(this) != true) - { - if (message) - { - from.SendLocalizedMessage(502946, "", 0x59); // That belongs to someone else. - } - - return false; - } - } - - if (from.Map != Map || !from.InRange(GetWorldLocation(), 2) || !from.InLOS(this)) + if (house?.HasLockedDownItem(this) != true) { if (message) { - from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that. + from.SendLocalizedMessage(502946, "", 0x59); // That belongs to someone else. } return false; } - - return true; } - public virtual void Fill_OnTarget(Mobile from, object targ) + if (from.Map != Map || !from.InRange(GetWorldLocation(), 2) || !from.InLOS(this)) { - if (!IsEmpty || !Fillable || !ValidateUse(from, false)) + if (message) { - return; - } - - if (targ is BaseBeverage bev) - { - if (bev.IsEmpty || !bev.ValidateUse(from, true)) - { - return; - } - - Content = bev.Content; - Poison = bev.Poison; - Poisoner = bev.Poisoner; - - if (bev.Quantity > MaxQuantity) - { - Quantity = MaxQuantity; - bev.Quantity -= MaxQuantity; - } - else - { - Quantity += bev.Quantity; - bev.Quantity = 0; - } - } - else if (targ is BaseWaterContainer bwc) - { - if (Quantity == 0 || Content == BeverageType.Water && !IsFull) - { - var iNeed = Math.Min(MaxQuantity - Quantity, bwc.Quantity); - - if (iNeed > 0 && !bwc.IsEmpty && !IsFull) - { - bwc.Quantity -= iNeed; - Quantity += iNeed; - Content = BeverageType.Water; - - from.PlaySound(0x4E); - } - } - } - else if (targ is Item item) - { - var src = item as IWaterSource; - - if (src == null && item is AddonComponent component) - { - src = component.Addon as IWaterSource; - } - - if (src == null || src.Quantity <= 0) - { - return; - } - - if (from.Map != item.Map || !from.InRange(item.GetWorldLocation(), 2) || !from.InLOS(item)) - { - from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that. - return; - } - - Content = BeverageType.Water; - Poison = null; - Poisoner = null; - - if (src.Quantity > MaxQuantity) - { - Quantity = MaxQuantity; - src.Quantity -= MaxQuantity; - } - else - { - Quantity += src.Quantity; - src.Quantity = 0; - } - - from.SendLocalizedMessage(1010089); // You fill the container with water. - } - else if (targ is Cow cow) - { - if (cow.TryMilk(from)) - { - Content = BeverageType.Milk; - Quantity = MaxQuantity; - from.SendLocalizedMessage(1080197); // You fill the container with milk. - } - } - else if (targ is LandTarget target) - { - var tileID = target.TileID; - - if (from is PlayerMobile player) - { - var qs = player.Quest; - - if (qs is not WitchApprenticeQuest) - { - return; - } - - var obj = qs.FindObjective(); - - if (obj?.Completed == true && obj.Ingredient == Ingredient.SwampWater) - { - var contains = false; - - for (var i = 0; !contains && i < m_SwampTiles.Length; i += 2) - { - contains = tileID >= m_SwampTiles[i] && tileID <= m_SwampTiles[i + 1]; - } - - if (contains) - { - Delete(); - - player.SendLocalizedMessage( - 1055035 - ); // You dip the container into the disgusting swamp water, collecting enough for the Hag's vile stew. - obj.Complete(); - } - } - } - } - } - - public virtual void Pour_OnTarget(Mobile from, object targ) - { - if (IsEmpty || !Pourable || !ValidateUse(from, false)) - { - return; - } - - if (targ is BaseBeverage bev) - { - if (!bev.ValidateUse(from, true)) - { - return; - } - - if (bev.IsFull && bev.Content == Content) - { - from.SendLocalizedMessage(500848); // Couldn't pour it there. It was already full. - } - else if (!bev.IsEmpty) - { - from.SendLocalizedMessage(500846); // Can't pour it there. - } - else - { - bev.Content = Content; - bev.Poison = Poison; - bev.Poisoner = Poisoner; - - if (Quantity > bev.MaxQuantity) - { - bev.Quantity = bev.MaxQuantity; - Quantity -= bev.MaxQuantity; - } - else - { - bev.Quantity += Quantity; - Quantity = 0; - } - - from.PlaySound(0x4E); - } - } - else if (from == targ) - { - if (from.Thirst < 20) - { - from.Thirst += 1; - } - - if (ContainsAlchohol) - { - var bac = Content switch - { - BeverageType.Ale => 1, - BeverageType.Wine => 2, - BeverageType.Cider => 3, - BeverageType.Liquor => 4, - _ => 0 - }; - - from.BAC = Math.Min(from.BAC + bac, 60); - - CheckHeaveTimer(from); - } - - from.PlaySound(Utility.RandomList(0x30, 0x2D6)); - - if (Poison != null) - { - from.ApplyPoison(Poisoner, Poison); - } - - --Quantity; - } - else if (targ is BaseWaterContainer bwc) - { - if (Content != BeverageType.Water) - { - from.SendLocalizedMessage(500842); // Can't pour that in there. - } - else if (bwc.Items.Count != 0) - { - from.SendLocalizedMessage(500841); // That has something in it. - } - else - { - var itNeeds = Math.Min(bwc.MaxQuantity - bwc.Quantity, Quantity); - - if (itNeeds > 0) - { - bwc.Quantity += itNeeds; - Quantity -= itNeeds; - - from.PlaySound(0x4E); - } - } - } - else if (targ is PlantItem item) - { - item.Pour(from, this); - } - else if (targ is AddonComponent component && - component.Addon is WaterVatEast or WaterVatSouth && - Content == BeverageType.Water) - { - if (from is PlayerMobile player) - { - if (player.Quest is SolenMatriarchQuest qs) - { - QuestObjective obj = qs.FindObjective(); - - if (obj?.Completed == false) - { - var vat = component.Addon; - - if (vat.X > 5784 && vat.X < 5814 && vat.Y > 1903 && vat.Y < 1934 && - (qs.RedSolen && vat.Map == Map.Trammel || !qs.RedSolen && vat.Map == Map.Felucca)) - { - if (obj.CurProgress + Quantity > obj.MaxProgress) - { - var delta = obj.MaxProgress - obj.CurProgress; - - Quantity -= delta; - obj.CurProgress = obj.MaxProgress; - } - else - { - obj.CurProgress += Quantity; - Quantity = 0; - } - } - } - } - } - } - else - { - from.SendLocalizedMessage(500846); // Can't pour it there. - } - } - - public override void OnDoubleClick(Mobile from) - { - if (IsEmpty) - { - if (!Fillable || !ValidateUse(from, true)) - { - return; - } - - from.BeginTarget(-1, true, TargetFlags.None, Fill_OnTarget); - SendLocalizedMessageTo(from, 500837); // Fill from what? - } - else if (Pourable && ValidateUse(from, true)) - { - from.BeginTarget(-1, true, TargetFlags.None, Pour_OnTarget); - from.SendLocalizedMessage(1010086); // What do you want to use this on? - } - } - - public static bool ConsumeTotal(Container pack, BeverageType content, int quantity) => - ConsumeTotal(pack, typeof(BaseBeverage), content, quantity); - - public static bool ConsumeTotal(Container pack, Type itemType, BeverageType content, int quantity) - { - var items = pack.FindItemsByType(itemType); - - // First pass, compute total - var total = 0; - - for (var i = 0; i < items.Length; ++i) - { - if (items[i] is BaseBeverage bev && bev.Content == content && !bev.IsEmpty) - { - total += bev.Quantity; - } - } - - if (total >= quantity) - { - // We've enough, so consume it - - var need = quantity; - - for (var i = 0; i < items.Length; ++i) - { - if (items[i] is not BaseBeverage bev || bev.Content != content || bev.IsEmpty) - { - continue; - } - - var theirQuantity = bev.Quantity; - - if (theirQuantity < need) - { - bev.Quantity = 0; - need -= theirQuantity; - } - else - { - bev.Quantity -= need; - return true; - } - } + from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that. } return false; } - public override void Serialize(IGenericWriter writer) + return true; + } + + public virtual void Fill_OnTarget(Mobile from, object targ) + { + if (!IsEmpty || !Fillable || !ValidateUse(from, false)) { - base.Serialize(writer); - - writer.Write(1); // version - - writer.Write(Poisoner); - - writer.Write(Poison); - writer.Write((int)m_Content); - writer.Write(m_Quantity); + return; } - protected bool CheckType(string name) => GetType().FullName == $"Server.Items.{name}"; - - public override void Deserialize(IGenericReader reader) + if (targ is BaseBeverage bev) { - InternalDeserialize(reader, true); - } - - protected void InternalDeserialize(IGenericReader reader, bool read) - { - base.Deserialize(reader); - - if (!read) + if (bev.IsEmpty || !bev.ValidateUse(from, true)) { return; } - var version = reader.ReadInt(); + Content = bev.Content; + Poison = bev.Poison; + Poisoner = bev.Poisoner; - switch (version) + if (bev.Quantity > MaxQuantity) { - case 1: - { - Poisoner = reader.ReadEntity(); - goto case 0; - } - case 0: - { - Poison = reader.ReadPoison(); - m_Content = (BeverageType)reader.ReadInt(); - m_Quantity = reader.ReadInt(); - break; - } + Quantity = MaxQuantity; + bev.Quantity -= MaxQuantity; + } + else + { + Quantity += bev.Quantity; + bev.Quantity = 0; } } - - public static void Initialize() + else if (targ is BaseWaterContainer bwc) { - EventSink.Login += EventSink_Login; - } - - private static void EventSink_Login(Mobile m) - { - CheckHeaveTimer(m); - } - - public static void CheckHeaveTimer(Mobile from) - { - if (from.BAC > 0 && from.Map != Map.Internal && !from.Deleted) + if (Quantity == 0 || Content == BeverageType.Water && !IsFull) { - if (m_Table.ContainsKey(from)) + var iNeed = Math.Min(MaxQuantity - Quantity, bwc.Quantity); + + if (iNeed > 0 && !bwc.IsEmpty && !IsFull) + { + bwc.Quantity -= iNeed; + Quantity += iNeed; + Content = BeverageType.Water; + + from.PlaySound(0x4E); + } + } + } + else if (targ is Item item) + { + var src = item as IWaterSource; + + if (src == null && item is AddonComponent component) + { + src = component.Addon as IWaterSource; + } + + if (src is not { Quantity: > 0 }) + { + return; + } + + if (from.Map != item.Map || !from.InRange(item.GetWorldLocation(), 2) || !from.InLOS(item)) + { + from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that. + return; + } + + Content = BeverageType.Water; + Poison = null; + Poisoner = null; + + if (src.Quantity > MaxQuantity) + { + Quantity = MaxQuantity; + src.Quantity -= MaxQuantity; + } + else + { + Quantity += src.Quantity; + src.Quantity = 0; + } + + from.SendLocalizedMessage(1010089); // You fill the container with water. + } + else if (targ is Cow cow) + { + if (cow.TryMilk(from)) + { + Content = BeverageType.Milk; + Quantity = MaxQuantity; + from.SendLocalizedMessage(1080197); // You fill the container with milk. + } + } + else if (targ is LandTarget target) + { + var tileID = target.TileID; + + if (from is PlayerMobile player) + { + var qs = player.Quest; + + if (qs is not WitchApprenticeQuest) { return; } - if (from.BAC > 60) + var obj = qs.FindObjective(); + + if (obj?.Completed == true && obj.Ingredient == Ingredient.SwampWater) { - from.BAC = 60; - } + var contains = false; - Timer t = new HeaveTimer(from); - t.Start(); - - m_Table[from] = t; - } - else if (m_Table.Remove(from, out var t)) - { - t.Stop(); - - from.SendLocalizedMessage(500850); // You feel sober. - } - } - - private class HeaveTimer : Timer - { - private readonly Mobile m_Drunk; - - public HeaveTimer(Mobile drunk) - : base(TimeSpan.FromSeconds(5.0), TimeSpan.FromSeconds(5.0)) - { - m_Drunk = drunk; - } - - protected override void OnTick() - { - if (m_Drunk.Deleted || m_Drunk.Map == Map.Internal) - { - Stop(); - m_Table.Remove(m_Drunk); - } - else if (m_Drunk.Alive) - { - if (m_Drunk.BAC > 60) + for (var i = 0; !contains && i < _swampTiles.Length; i += 2) { - m_Drunk.BAC = 60; + contains = tileID >= _swampTiles[i] && tileID <= _swampTiles[i + 1]; } - // chance to get sober - if (Utility.Random(100) < 10) + if (contains) { - --m_Drunk.BAC; - } + Delete(); - // lose some stats - m_Drunk.Stam -= 1; - m_Drunk.Mana -= 1; - - if (Utility.Random(1, 4) == 1) - { - if (!m_Drunk.Mounted) - { - // turn in a random direction - m_Drunk.Direction = (Direction)Utility.Random(8); - - // heave - m_Drunk.Animate(32, 5, 1, true, false, 0); - } - - // *hic* - m_Drunk.PublicOverheadMessage(MessageType.Regular, 0x3B2, 500849); - } - - if (m_Drunk.BAC <= 0) - { - Stop(); - m_Table.Remove(m_Drunk); - - m_Drunk.SendLocalizedMessage(500850); // You feel sober. + // You dip the container into the disgusting swamp water, collecting enough for the Hag's vile stew. + player.SendLocalizedMessage(1055035); + obj.Complete(); } } } } } + + public virtual void Pour_OnTarget(Mobile from, object targ) + { + if (IsEmpty || !Pourable || !ValidateUse(from, false)) + { + return; + } + + if (targ is BaseBeverage bev) + { + if (!bev.ValidateUse(from, true)) + { + return; + } + + if (bev.IsFull && bev.Content == Content) + { + from.SendLocalizedMessage(500848); // Couldn't pour it there. It was already full. + } + else if (!bev.IsEmpty) + { + from.SendLocalizedMessage(500846); // Can't pour it there. + } + else + { + bev.Content = Content; + bev.Poison = Poison; + bev.Poisoner = Poisoner; + + if (Quantity > bev.MaxQuantity) + { + bev.Quantity = bev.MaxQuantity; + Quantity -= bev.MaxQuantity; + } + else + { + bev.Quantity += Quantity; + Quantity = 0; + } + + from.PlaySound(0x4E); + } + } + else if (from == targ) + { + if (from.Thirst < 20) + { + from.Thirst += 1; + } + + if (ContainsAlcohol) + { + var bac = Content switch + { + BeverageType.Ale => 1, + BeverageType.Wine => 2, + BeverageType.Cider => 3, + BeverageType.Liquor => 4, + _ => 0 + }; + + from.BAC = Math.Min(from.BAC + bac, 60); + + CheckHeaveTimer(from); + } + + from.PlaySound(Utility.RandomList(0x30, 0x2D6)); + + if (Poison != null) + { + from.ApplyPoison(Poisoner, Poison); + } + + --Quantity; + } + else if (targ is BaseWaterContainer bwc) + { + if (Content != BeverageType.Water) + { + from.SendLocalizedMessage(500842); // Can't pour that in there. + } + else if (bwc.Items.Count != 0) + { + from.SendLocalizedMessage(500841); // That has something in it. + } + else + { + var itNeeds = Math.Min(bwc.MaxQuantity - bwc.Quantity, Quantity); + + if (itNeeds > 0) + { + bwc.Quantity += itNeeds; + Quantity -= itNeeds; + + from.PlaySound(0x4E); + } + } + } + else if (targ is PlantItem item) + { + item.Pour(from, this); + } + else if (targ is AddonComponent component && + component.Addon is WaterVatEast or WaterVatSouth && + Content == BeverageType.Water) + { + if (from is PlayerMobile { Quest: SolenMatriarchQuest qs }) + { + QuestObjective obj = qs.FindObjective(); + + if (obj?.Completed == false) + { + var vat = component.Addon; + + if (vat.X > 5784 && vat.X < 5814 && vat.Y > 1903 && vat.Y < 1934 && + (qs.RedSolen && vat.Map == Map.Trammel || !qs.RedSolen && vat.Map == Map.Felucca)) + { + if (obj.CurProgress + Quantity > obj.MaxProgress) + { + var delta = obj.MaxProgress - obj.CurProgress; + + Quantity -= delta; + obj.CurProgress = obj.MaxProgress; + } + else + { + obj.CurProgress += Quantity; + Quantity = 0; + } + } + } + } + } + else + { + from.SendLocalizedMessage(500846); // Can't pour it there. + } + } + + public override void OnDoubleClick(Mobile from) + { + if (IsEmpty) + { + if (!Fillable || !ValidateUse(from, true)) + { + return; + } + + from.BeginTarget(-1, true, TargetFlags.None, Fill_OnTarget); + SendLocalizedMessageTo(from, 500837); // Fill from what? + } + else if (Pourable && ValidateUse(from, true)) + { + from.BeginTarget(-1, true, TargetFlags.None, Pour_OnTarget); + from.SendLocalizedMessage(1010086); // What do you want to use this on? + } + } + + public static bool ConsumeTotal(Container pack, BeverageType content, int quantity) => + ConsumeTotal(pack, typeof(BaseBeverage), content, quantity); + + public static bool ConsumeTotal(Container pack, Type itemType, BeverageType content, int quantity) + { + var items = pack.FindItemsByType(itemType); + + // First pass, compute total + var total = 0; + + for (var i = 0; i < items.Length; ++i) + { + if (items[i] is BaseBeverage bev && bev.Content == content && !bev.IsEmpty) + { + total += bev.Quantity; + } + } + + if (total >= quantity) + { + // We've enough, so consume it + + var need = quantity; + + for (var i = 0; i < items.Length; ++i) + { + if (items[i] is not BaseBeverage bev || bev.Content != content || bev.IsEmpty) + { + continue; + } + + var theirQuantity = bev.Quantity; + + if (theirQuantity < need) + { + bev.Quantity = 0; + need -= theirQuantity; + } + else + { + bev.Quantity -= need; + return true; + } + } + } + + return false; + } + + private void Deserialize(IGenericReader reader, int version) + { + _poison = reader.ReadPoison(); + _poisoner = reader.ReadEntity(); + _rawContent = (BeverageType)reader.ReadInt(); + _rawQuantity = reader.ReadInt(); + } + + public static void Initialize() + { + EventSink.Login += EventSink_Login; + } + + private static void EventSink_Login(Mobile m) + { + CheckHeaveTimer(m); + } + + public static void CheckHeaveTimer(Mobile from) + { + if (from.BAC > 0 && from.Map != Map.Internal && !from.Deleted) + { + if (m_Table.ContainsKey(from)) + { + return; + } + + if (from.BAC > 60) + { + from.BAC = 60; + } + + m_Table[from] = new HeaveTimer(from).Start(); + } + else if (m_Table.Remove(from, out var t)) + { + t.Stop(); + + from.SendLocalizedMessage(500850); // You feel sober. + } + } + + private class HeaveTimer : Timer + { + private readonly Mobile m_Drunk; + + public HeaveTimer(Mobile drunk) : base(TimeSpan.FromSeconds(5.0), TimeSpan.FromSeconds(5.0)) => + m_Drunk = drunk; + + protected override void OnTick() + { + if (m_Drunk.Deleted || m_Drunk.Map == Map.Internal) + { + Stop(); + m_Table.Remove(m_Drunk); + } + else if (m_Drunk.Alive) + { + if (m_Drunk.BAC > 60) + { + m_Drunk.BAC = 60; + } + + // chance to get sober + if (Utility.Random(100) < 10) + { + --m_Drunk.BAC; + } + + // lose some stats + m_Drunk.Stam -= 1; + m_Drunk.Mana -= 1; + + if (Utility.Random(1, 4) == 1) + { + if (!m_Drunk.Mounted) + { + // turn in a random direction + m_Drunk.Direction = (Direction)Utility.Random(8); + + // heave + m_Drunk.Animate(32, 5, 1, true, false, 0); + } + + // *hic* + m_Drunk.PublicOverheadMessage(MessageType.Regular, 0x3B2, 500849); + } + + if (m_Drunk.BAC <= 0) + { + Stop(); + m_Table.Remove(m_Drunk); + + m_Drunk.SendLocalizedMessage(500850); // You feel sober. + } + } + } + } } diff --git a/Projects/UOContent/Migrations/Server.Items.AwaseMisoSoup.v0.json b/Projects/UOContent/Migrations/Server.Items.AwaseMisoSoup.v0.json new file mode 100644 index 000000000..a66b23b95 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.AwaseMisoSoup.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.AwaseMisoSoup" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.BaseBeverage.v2.json b/Projects/UOContent/Migrations/Server.Items.BaseBeverage.v2.json new file mode 100644 index 000000000..d47ccdf8d --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.BaseBeverage.v2.json @@ -0,0 +1,32 @@ +{ + "version": 2, + "type": "Server.Items.BaseBeverage", + "properties": [ + { + "name": "Poison", + "type": "Server.Poison", + "rule": "PrimitiveUOTypeMigrationRule", + "ruleArguments": [ + "Poison" + ] + }, + { + "name": "Poisoner", + "type": "Server.Mobile", + "rule": "SerializableInterfaceMigrationRule" + }, + { + "name": "RawContent", + "type": "Server.Items.BeverageType", + "rule": "EnumMigrationRule" + }, + { + "name": "RawQuantity", + "type": "int", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.BentoBox.v0.json b/Projects/UOContent/Migrations/Server.Items.BentoBox.v0.json new file mode 100644 index 000000000..9e0e46769 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.BentoBox.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.BentoBox" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.BeverageBottle.v0.json b/Projects/UOContent/Migrations/Server.Items.BeverageBottle.v0.json new file mode 100644 index 000000000..7075dfde9 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.BeverageBottle.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.BeverageBottle" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.CeramicMug.v0.json b/Projects/UOContent/Migrations/Server.Items.CeramicMug.v0.json new file mode 100644 index 000000000..b83ab8bad --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.CeramicMug.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.CeramicMug" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.EmptyBentoBox.v0.json b/Projects/UOContent/Migrations/Server.Items.EmptyBentoBox.v0.json new file mode 100644 index 000000000..334506c92 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.EmptyBentoBox.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.EmptyBentoBox" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.GlassMug.v0.json b/Projects/UOContent/Migrations/Server.Items.GlassMug.v0.json new file mode 100644 index 000000000..31a38da4a --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.GlassMug.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.GlassMug" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Goblet.v0.json b/Projects/UOContent/Migrations/Server.Items.Goblet.v0.json new file mode 100644 index 000000000..86789c133 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Goblet.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Goblet" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.GreenTea.v0.json b/Projects/UOContent/Migrations/Server.Items.GreenTea.v0.json new file mode 100644 index 000000000..ca9179116 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.GreenTea.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.GreenTea" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.GreenTeaBasket.v0.json b/Projects/UOContent/Migrations/Server.Items.GreenTeaBasket.v0.json new file mode 100644 index 000000000..09ae11fea --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.GreenTeaBasket.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.GreenTeaBasket" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Jug.v0.json b/Projects/UOContent/Migrations/Server.Items.Jug.v0.json new file mode 100644 index 000000000..11aa8c3f9 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Jug.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Jug" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.MisoSoup.v0.json b/Projects/UOContent/Migrations/Server.Items.MisoSoup.v0.json new file mode 100644 index 000000000..4aaa4304a --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.MisoSoup.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.MisoSoup" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.PewterMug.v0.json b/Projects/UOContent/Migrations/Server.Items.PewterMug.v0.json new file mode 100644 index 000000000..12010a8c9 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.PewterMug.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.PewterMug" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Pitcher.v0.json b/Projects/UOContent/Migrations/Server.Items.Pitcher.v0.json new file mode 100644 index 000000000..1b34123cc --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Pitcher.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Pitcher" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.RedMisoSoup.v0.json b/Projects/UOContent/Migrations/Server.Items.RedMisoSoup.v0.json new file mode 100644 index 000000000..b1cdf2e03 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.RedMisoSoup.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.RedMisoSoup" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.SushiPlatter.v0.json b/Projects/UOContent/Migrations/Server.Items.SushiPlatter.v0.json new file mode 100644 index 000000000..483d32d8e --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.SushiPlatter.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.SushiPlatter" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.SushiRolls.v0.json b/Projects/UOContent/Migrations/Server.Items.SushiRolls.v0.json new file mode 100644 index 000000000..1028b71aa --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.SushiRolls.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.SushiRolls" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Wasabi.v0.json b/Projects/UOContent/Migrations/Server.Items.Wasabi.v0.json new file mode 100644 index 000000000..0f8c5b12a --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Wasabi.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Wasabi" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.WasabiClumps.v0.json b/Projects/UOContent/Migrations/Server.Items.WasabiClumps.v0.json new file mode 100644 index 000000000..084999ea5 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.WasabiClumps.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.WasabiClumps" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.WhiteMisoSoup.v0.json b/Projects/UOContent/Migrations/Server.Items.WhiteMisoSoup.v0.json new file mode 100644 index 000000000..efe1f9e4b --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.WhiteMisoSoup.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.WhiteMisoSoup" +} \ No newline at end of file diff --git a/Projects/UOContent/Misc/Poison.cs b/Projects/UOContent/Misc/Poison.cs index 68d61d977..e0ce1542b 100644 --- a/Projects/UOContent/Misc/Poison.cs +++ b/Projects/UOContent/Misc/Poison.cs @@ -158,8 +158,8 @@ namespace Server AOS.Damage(m_Mobile, From, damage, 0, 0, 0, 100, 0); - if (Utility.RandomDouble() >= 0.60 - ) // OSI: randomly revealed between first and third damage tick, guessing 60% chance + // OSI: randomly revealed between first and third damage tick, guessing 60% chance + if (Utility.RandomDouble() >= 0.60) { m_Mobile.RevealingAction(); } From a7fd1905e92e180417082f4c0f25fbaa6962361b Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Mon, 16 May 2022 15:10:49 -0700 Subject: [PATCH 163/213] fix: Deletes wanderer (#1023) --- .../UOContent/Mobiles/Special/Wanderer.cs | 66 ------------------- 1 file changed, 66 deletions(-) delete mode 100644 Projects/UOContent/Mobiles/Special/Wanderer.cs diff --git a/Projects/UOContent/Mobiles/Special/Wanderer.cs b/Projects/UOContent/Mobiles/Special/Wanderer.cs deleted file mode 100644 index 62bbd553a..000000000 --- a/Projects/UOContent/Mobiles/Special/Wanderer.cs +++ /dev/null @@ -1,66 +0,0 @@ -using System; - -namespace Server.Mobiles -{ - public class Wanderer : Mobile - { - private readonly Timer m_Timer; - - [Constructible] - public Wanderer() - { - Name = "Me"; - Body = 0x1; - AccessLevel = AccessLevel.Counselor; - - m_Timer = new InternalTimer(this); - m_Timer.Start(); - } - - public Wanderer(Serial serial) : base(serial) - { - m_Timer = new InternalTimer(this); - m_Timer.Start(); - } - - public override void OnDelete() - { - m_Timer.Stop(); - - base.OnDelete(); - } - - 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(); - } - - private class InternalTimer : Timer - { - private readonly Wanderer m_Owner; - private int m_Count; - - public InternalTimer(Wanderer owner) : base(TimeSpan.FromSeconds(0.1), TimeSpan.FromSeconds(0.1)) => - m_Owner = owner; - - protected override void OnTick() - { - if ((m_Count++ & 0x3) == 0) - { - m_Owner.Direction = (Direction)(Utility.Random(8) | 0x80); - } - - m_Owner.Move(m_Owner.Direction); - } - } - } -} From b318fa29cb532d2763d9fd3704365b1ae52bf004 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Mon, 16 May 2022 15:14:08 -0700 Subject: [PATCH 164/213] fix: Removes wanderer from categorization (#1024) --- Distribution/Data/categorization.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Distribution/Data/categorization.json b/Distribution/Data/categorization.json index 229014caa..4ddec6a0a 100644 --- a/Distribution/Data/categorization.json +++ b/Distribution/Data/categorization.json @@ -3668,8 +3668,7 @@ { "category": "Mobiles.Uncategorized", "objects": [ - { "type": "TownCrier" }, - { "type": "Wanderer" } + { "type": "TownCrier" } ] }, { From 6ea5508f5fafcc98dfe6544d60d1b814dd9e4132 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Wed, 18 May 2022 15:03:10 -0700 Subject: [PATCH 165/213] chore: Updates to .NET 6.0.5 (#1026) --- .github/workflows/build-test.yml | 2 +- azure-pipelines.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 2b30cb304..c3f71086e 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -26,7 +26,7 @@ jobs: - name: Setup .NET 6 uses: actions/setup-dotnet@v1 with: - dotnet-version: 6.0.201 + dotnet-version: 6.0.300 - name: Build run: ./publish.cmd - name: Test diff --git a/azure-pipelines.yml b/azure-pipelines.yml index a47ff4c5e..8efb2abc9 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -18,7 +18,7 @@ jobs: displayName: 'Install .NET 6' inputs: packageType: sdk - version: 6.0.201 + version: 6.0.300 - task: NuGetAuthenticate@0 - script: ./publish.cmd Release win displayName: 'Build' @@ -62,7 +62,7 @@ jobs: displayName: 'Install .NET 6' inputs: packageType: sdk - version: 6.0.201 + version: 6.0.300 - task: NuGetAuthenticate@0 - script: ./publish.cmd Release $(os) displayName: 'Build' From 6b3617b08f25838a10be2ec27a536ea4764b62bf Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Wed, 18 May 2022 17:25:03 -0700 Subject: [PATCH 166/213] fix: Fixes BitArray serialization (#1027) Fixes bit array serialization. This may cause objects that were serialized by bit array to fail to deserialize. I am sorry, please accept my condolences. It is probably easiest to just delete those objects. If it becomes a major problem, contact me and I'll help with a hacky per-case solution. --- .../Tests/Collections/BitArrayTests.cs | 29 ++ Projects/Server/Collections/BitArray.cs | 335 +++++++++--------- Projects/Server/Serialization/BufferReader.cs | 6 +- Projects/Server/Serialization/BufferWriter.cs | 4 +- 4 files changed, 207 insertions(+), 167 deletions(-) create mode 100644 Projects/Server.Tests/Tests/Collections/BitArrayTests.cs diff --git a/Projects/Server.Tests/Tests/Collections/BitArrayTests.cs b/Projects/Server.Tests/Tests/Collections/BitArrayTests.cs new file mode 100644 index 000000000..31d2fb2e1 --- /dev/null +++ b/Projects/Server.Tests/Tests/Collections/BitArrayTests.cs @@ -0,0 +1,29 @@ +using Server.Collections; +using Xunit; + +namespace Server.Tests; + +public class BitArrayTests +{ + [Fact] + public void TestBitArray() + { + var bitArray = new BitArray(700); // Restricted Spells; + bitArray.Set(5, true); + bitArray.Set(39, true); + bitArray.Set(125, true); + + // Simulate World Saving + var writer = new BufferWriter(1024, false); + writer.Write(bitArray); // Save it to a file + + // Simulate World Loading + var reader = new BufferReader(writer.Buffer); + var bitArrayTest = reader.ReadBitArray(); + Assert.Equal(700, bitArrayTest.Length); + for (var i = 0; i < bitArrayTest.Length; i++) + { + Assert.Equal(i is 5 or 39 or 125, bitArrayTest.Get(i)); + } + } +} diff --git a/Projects/Server/Collections/BitArray.cs b/Projects/Server/Collections/BitArray.cs index 10f87459d..2ea09a4c2 100644 --- a/Projects/Server/Collections/BitArray.cs +++ b/Projects/Server/Collections/BitArray.cs @@ -63,7 +63,7 @@ public sealed class BitArray : ICollection, ICloneable ** ** Exceptions: ArgumentException if bytes == null. =========================================================================*/ - public BitArray(byte[] bytes) + public BitArray(ReadOnlySpan bytes, int length = -1) { if (bytes == null) { @@ -79,7 +79,7 @@ public sealed class BitArray : ICollection, ICloneable } m_array = new int[GetInt32ArrayLengthFromByteLength(bytes.Length)]; - m_length = bytes.Length * BitsPerByte; + m_length = length == -1 ? bytes.Length * BitsPerByte : length; uint totalCount = (uint)bytes.Length / 4; @@ -96,16 +96,22 @@ public sealed class BitArray : ICollection, ICloneable switch (byteSpan.Length) { case 3: - last = byteSpan[2] << 16; - goto case 2; + { + last = byteSpan[2] << 16; + goto case 2; + } // fall through case 2: - last |= byteSpan[1] << 8; - goto case 1; + { + last |= byteSpan[1] << 8; + goto case 1; + } // fall through case 1: - m_array[totalCount] = last | byteSpan[0]; - break; + { + m_array[totalCount] = last | byteSpan[0]; + break; + } } _version = 0; @@ -119,63 +125,7 @@ public sealed class BitArray : ICollection, ICloneable ** ** Exceptions: ArgumentException if bytes == null. =========================================================================*/ - public BitArray(ReadOnlySpan bytes) - { - if (bytes == null) - { - throw new ArgumentNullException(nameof(bytes)); - } - - // this value is chosen to prevent overflow when computing m_length. - // m_length is of type int32 and is exposed as a property, so - // type of m_length can't be changed to accommodate. - if (bytes.Length > int.MaxValue / BitsPerByte) - { - throw new ArgumentException(string.Format(CollectionThrowStrings.Argument_ArrayTooLarge, BitsPerByte), nameof(bytes)); - } - - m_array = new int[GetInt32ArrayLengthFromByteLength(bytes.Length)]; - m_length = bytes.Length * BitsPerByte; - - uint totalCount = (uint)bytes.Length / 4; - - ReadOnlySpan byteSpan = bytes; - for (int i = 0; i < totalCount; i++) - { - m_array[i] = BinaryPrimitives.ReadInt32LittleEndian(byteSpan); - byteSpan = byteSpan[4..]; - } - - Debug.Assert(byteSpan.Length >= 0 && byteSpan.Length < 4); - - int last = 0; - switch (byteSpan.Length) - { - case 3: - last = byteSpan[2] << 16; - goto case 2; - // fall through - case 2: - last |= byteSpan[1] << 8; - goto case 1; - // fall through - case 1: - m_array[totalCount] = last | byteSpan[0]; - break; - } - - _version = 0; - } - - /*========================================================================= - ** Allocates space to hold the bit values in bytes. bytes[0] represents - ** bits 0 - 7, bytes[1] represents bits 8 - 15, etc. The LSB of each byte - ** represents the lowest index value; bytes[0] & 1 represents bit 0, - ** bytes[0] & 2 represents bit 1, bytes[0] & 4 represents bit 2, etc. - ** - ** Exceptions: ArgumentException if bytes == null. - =========================================================================*/ - public BitArray(BinaryReader reader, int length) + public BitArray(BinaryReader reader, int bitLength) { if (reader == null) { @@ -185,13 +135,15 @@ public sealed class BitArray : ICollection, ICloneable // this value is chosen to prevent overflow when computing m_length. // m_length is of type int32 and is exposed as a property, so // type of m_length can't be changed to accommodate. - if (length > int.MaxValue / BitsPerByte) + if (bitLength > int.MaxValue / BitsPerByte) { throw new ArgumentException(string.Format(CollectionThrowStrings.Argument_ArrayTooLarge, BitsPerByte), nameof(reader)); } + var length = GetByteArrayLengthFromBitLength(bitLength); + m_array = new int[GetInt32ArrayLengthFromByteLength(length)]; - m_length = length * BitsPerByte; + m_length = length; uint totalCount = (uint)length / 4; @@ -207,16 +159,22 @@ public sealed class BitArray : ICollection, ICloneable switch (length) { case 3: - last = reader.ReadInt16(); - goto case 2; + { + last = reader.ReadInt16(); + goto case 2; + } // fall through case 2: - last |= reader.ReadByte(); - goto case 1; + { + last |= reader.ReadByte(); + goto case 1; + } // fall through case 1: - m_array[totalCount] = last | reader.ReadByte(); - break; + { + m_array[totalCount] = last | reader.ReadByte(); + break; + } } _version = 0; @@ -499,14 +457,38 @@ public sealed class BitArray : ICollection, ICloneable // Unroll loop for count less than Vector256 size. switch (count) { - case 7: thisArray[6] &= valueArray[6]; goto case 6; - case 6: thisArray[5] &= valueArray[5]; goto case 5; - case 5: thisArray[4] &= valueArray[4]; goto case 4; - case 4: thisArray[3] &= valueArray[3]; goto case 3; - case 3: thisArray[2] &= valueArray[2]; goto case 2; - case 2: thisArray[1] &= valueArray[1]; goto case 1; - case 1: thisArray[0] &= valueArray[0]; goto Done; - case 0: goto Done; + case 7: + { + thisArray[6] &= valueArray[6]; goto case 6; + } + case 6: + { + thisArray[5] &= valueArray[5]; goto case 5; + } + case 5: + { + thisArray[4] &= valueArray[4]; goto case 4; + } + case 4: + { + thisArray[3] &= valueArray[3]; goto case 3; + } + case 3: + { + thisArray[2] &= valueArray[2]; goto case 2; + } + case 2: + { + thisArray[1] &= valueArray[1]; goto case 1; + } + case 1: + { + thisArray[0] &= valueArray[0]; goto Done; + } + case 0: + { + goto Done; + } } uint i = 0; @@ -597,14 +579,38 @@ public sealed class BitArray : ICollection, ICloneable // Unroll loop for count less than Vector256 size. switch (count) { - case 7: thisArray[6] |= valueArray[6]; goto case 6; - case 6: thisArray[5] |= valueArray[5]; goto case 5; - case 5: thisArray[4] |= valueArray[4]; goto case 4; - case 4: thisArray[3] |= valueArray[3]; goto case 3; - case 3: thisArray[2] |= valueArray[2]; goto case 2; - case 2: thisArray[1] |= valueArray[1]; goto case 1; - case 1: thisArray[0] |= valueArray[0]; goto Done; - case 0: goto Done; + case 7: + { + thisArray[6] |= valueArray[6]; goto case 6; + } + case 6: + { + thisArray[5] |= valueArray[5]; goto case 5; + } + case 5: + { + thisArray[4] |= valueArray[4]; goto case 4; + } + case 4: + { + thisArray[3] |= valueArray[3]; goto case 3; + } + case 3: + { + thisArray[2] |= valueArray[2]; goto case 2; + } + case 2: + { + thisArray[1] |= valueArray[1]; goto case 1; + } + case 1: + { + thisArray[0] |= valueArray[0]; goto Done; + } + case 0: + { + goto Done; + } } uint i = 0; @@ -695,14 +701,38 @@ public sealed class BitArray : ICollection, ICloneable // Unroll loop for count less than Vector256 size. switch (count) { - case 7: thisArray[6] ^= valueArray[6]; goto case 6; - case 6: thisArray[5] ^= valueArray[5]; goto case 5; - case 5: thisArray[4] ^= valueArray[4]; goto case 4; - case 4: thisArray[3] ^= valueArray[3]; goto case 3; - case 3: thisArray[2] ^= valueArray[2]; goto case 2; - case 2: thisArray[1] ^= valueArray[1]; goto case 1; - case 1: thisArray[0] ^= valueArray[0]; goto Done; - case 0: goto Done; + case 7: + { + thisArray[6] ^= valueArray[6]; goto case 6; + } + case 6: + { + thisArray[5] ^= valueArray[5]; goto case 5; + } + case 5: + { + thisArray[4] ^= valueArray[4]; goto case 4; + } + case 4: + { + thisArray[3] ^= valueArray[3]; goto case 3; + } + case 3: + { + thisArray[2] ^= valueArray[2]; goto case 2; + } + case 2: + { + thisArray[1] ^= valueArray[1]; goto case 1; + } + case 1: + { + thisArray[0] ^= valueArray[0]; goto Done; + } + case 0: + { + goto Done; + } } uint i = 0; @@ -781,14 +811,38 @@ public sealed class BitArray : ICollection, ICloneable // Unroll loop for count less than Vector256 size. switch (count) { - case 7: thisArray[6] = ~thisArray[6]; goto case 6; - case 6: thisArray[5] = ~thisArray[5]; goto case 5; - case 5: thisArray[4] = ~thisArray[4]; goto case 4; - case 4: thisArray[3] = ~thisArray[3]; goto case 3; - case 3: thisArray[2] = ~thisArray[2]; goto case 2; - case 2: thisArray[1] = ~thisArray[1]; goto case 1; - case 1: thisArray[0] = ~thisArray[0]; goto Done; - case 0: goto Done; + case 7: + { + thisArray[6] = ~thisArray[6]; goto case 6; + } + case 6: + { + thisArray[5] = ~thisArray[5]; goto case 5; + } + case 5: + { + thisArray[4] = ~thisArray[4]; goto case 4; + } + case 4: + { + thisArray[3] = ~thisArray[3]; goto case 3; + } + case 3: + { + thisArray[2] = ~thisArray[2]; goto case 2; + } + case 2: + { + thisArray[1] = ~thisArray[1]; goto case 1; + } + case 1: + { + thisArray[0] = ~thisArray[0]; goto Done; + } + case 0: + { + goto Done; + } } uint i = 0; @@ -964,10 +1018,7 @@ public sealed class BitArray : ICollection, ICloneable public int Length { - get - { - return m_length; - } + get => m_length; set { if (value < 0) @@ -1035,16 +1086,22 @@ public sealed class BitArray : ICollection, ICloneable switch (remainder) { case 3: - span[2] = (byte)(m_array[quotient] >> 16); - goto case 2; + { + span[2] = (byte)(m_array[quotient] >> 16); + goto case 2; + } // fall through case 2: - span[1] = (byte)(m_array[quotient] >> 8); - goto case 1; + { + span[1] = (byte)(m_array[quotient] >> 8); + goto case 1; + } // fall through case 1: - span[0] = (byte)m_array[quotient]; - break; + { + span[0] = (byte)m_array[quotient]; + break; + } } } @@ -1084,54 +1141,6 @@ public sealed class BitArray : ICollection, ICloneable intArray[index + last] = m_array[last] & unchecked((1 << extraBits) - 1); } } - else if (array is byte[] byteArray) - { - int arrayLength = GetByteArrayLengthFromBitLength(m_length); - if (array.Length - index < arrayLength) - { - throw new ArgumentException(CollectionThrowStrings.Argument_InvalidOffLen); - } - - // equivalent to m_length % BitsPerByte, since BitsPerByte is a power of 2 - uint extraBits = (uint)m_length & (BitsPerByte - 1); - if (extraBits > 0) - { - // last byte is not aligned, we will directly copy one less byte - arrayLength -= 1; - } - - Span span = byteArray.AsSpan(index); - - int quotient = Div4Rem(arrayLength, out int remainder); - for (int i = 0; i < quotient; i++) - { - BinaryPrimitives.WriteInt32LittleEndian(span, m_array[i]); - span = span[4..]; - } - - if (extraBits > 0) - { - Debug.Assert(span.Length > 0); - Debug.Assert(m_array.Length > quotient); - // mask the final byte - span[remainder] = (byte)((m_array[quotient] >> (remainder * 8)) & ((1 << (int)extraBits) - 1)); - } - - switch (remainder) - { - case 3: - span[2] = (byte)(m_array[quotient] >> 16); - goto case 2; - // fall through - case 2: - span[1] = (byte)(m_array[quotient] >> 8); - goto case 1; - // fall through - case 1: - span[0] = (byte)m_array[quotient]; - break; - } - } else if (array is bool[] boolArray) { if (array.Length - index < m_length) diff --git a/Projects/Server/Serialization/BufferReader.cs b/Projects/Server/Serialization/BufferReader.cs index 91641c343..7ba58bb16 100644 --- a/Projects/Server/Serialization/BufferReader.cs +++ b/Projects/Server/Serialization/BufferReader.cs @@ -159,13 +159,15 @@ namespace Server public BitArray ReadBitArray() { - var length = ((IGenericReader)this).ReadEncodedInt(); + var bitLength = ((IGenericReader)this).ReadEncodedInt(); + var length = BitArray.GetByteArrayLengthFromBitLength(bitLength); + if (length > _buffer.Length - _position) { throw new OutOfMemoryException(); } - var bitArray = new BitArray(_buffer.AsSpan(_position, length)); + var bitArray = new BitArray(_buffer.AsSpan(_position, length), bitLength); _position += length; return bitArray; } diff --git a/Projects/Server/Serialization/BufferWriter.cs b/Projects/Server/Serialization/BufferWriter.cs index 167d24edb..044bb8302 100644 --- a/Projects/Server/Serialization/BufferWriter.cs +++ b/Projects/Server/Serialization/BufferWriter.cs @@ -138,9 +138,9 @@ namespace Server public void Write(BitArray bitArray) { var byteLength = BitArray.GetByteArrayLengthFromBitLength(bitArray.Length); - FlushIfNeeded(byteLength + 4); - ((IGenericWriter)this).WriteEncodedInt(byteLength); + ((IGenericWriter)this).WriteEncodedInt(bitArray.Length); + FlushIfNeeded(byteLength); bitArray.CopyTo(_buffer.AsSpan((int)Index, byteLength)); Index += byteLength; } From dfdadd3204047f8c2f7185ace2828fcc033a5821 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Wed, 18 May 2022 17:36:23 -0700 Subject: [PATCH 167/213] fix: Fixes pool of acid and other empty serializations (#1025) Fixes an issue where 0 byte objects are improperly deserialized. They should not be deserialized at all and instead deleted. --- Projects/Server/World/EntityPersistence.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Projects/Server/World/EntityPersistence.cs b/Projects/Server/World/EntityPersistence.cs index bf2f415df..59a9d5e80 100644 --- a/Projects/Server/World/EntityPersistence.cs +++ b/Projects/Server/World/EntityPersistence.cs @@ -200,6 +200,12 @@ namespace Server continue; } + if (entry.Length == 0) + { + t.Delete(); + continue; + } + var buffer = GC.AllocateUninitializedArray(entry.Length); if (br == null) { @@ -310,6 +316,12 @@ namespace Server { var saveBuffer = entity.SaveBuffer; + // If nothing was serialized we expect the object to be deleted on deserialization + if (saveBuffer.Position == 0) + { + return; + } + // Resize to the exact size saveBuffer.Resize((int)saveBuffer.Position); From f2ced497ec9e568144423dcb4c3bacdb0673ad67 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Wed, 18 May 2022 17:53:53 -0700 Subject: [PATCH 168/213] fix: Updates pool of acid (#1028) - [X] Removes duplicate Created property - [X] Removes allocation while damaging mobiles - [X] Adds manual dirty checking since we won't be codegenning it and we won't be serializing it. --- Projects/UOContent/Items/Misc/PoolOfAcid.cs | 157 ++++++++++---------- 1 file changed, 76 insertions(+), 81 deletions(-) diff --git a/Projects/UOContent/Items/Misc/PoolOfAcid.cs b/Projects/UOContent/Items/Misc/PoolOfAcid.cs index db2511df9..a4941b542 100644 --- a/Projects/UOContent/Items/Misc/PoolOfAcid.cs +++ b/Projects/UOContent/Items/Misc/PoolOfAcid.cs @@ -1,102 +1,97 @@ using System; -using System.Collections.Generic; +using Server.Collections; using Server.Mobiles; -namespace Server.Items +namespace Server.Items; + +[ManualDirtyChecking] +[TypeAlias("Server.Items.AcidSlime")] +public class PoolOfAcid : Item { - [TypeAlias("Server.Items.AcidSlime")] - public class PoolOfAcid : Item + private readonly TimeSpan _duration; + private readonly int _maxDamage; + private readonly int _minDamage; + private TimerExecutionToken _timerToken; + private bool _drying; + + [Constructible] + public PoolOfAcid() : this(TimeSpan.FromSeconds(10.0), 2, 5) { - private readonly DateTime m_Created; - private readonly TimeSpan m_Duration; - private readonly int m_MaxDamage; - private readonly int m_MinDamage; - private TimerExecutionToken _timerToken; - private bool m_Drying; + } - [Constructible] - public PoolOfAcid() : this(TimeSpan.FromSeconds(10.0), 2, 5) + [Constructible] + public PoolOfAcid(TimeSpan duration, int minDamage, int maxDamage) : base(0x122A) + { + Hue = 0x3F; + Movable = false; + + _minDamage = minDamage; + _maxDamage = maxDamage; + _duration = duration; + + Timer.StartTimer(TimeSpan.Zero, TimeSpan.FromSeconds(1), OnTick, out _timerToken); + } + + public PoolOfAcid(Serial serial) : base(serial) + { + } + + public override string DefaultName => "a pool of acid"; + + public override void OnDelete() + { + _timerToken.Cancel(); + } + + private void OnTick() + { + var now = Core.Now; + var age = now - Created; + + if (age > _duration) { + Delete(); + return; } - [Constructible] - public PoolOfAcid(TimeSpan duration, int minDamage, int maxDamage) - : base(0x122A) + if (!_drying && age > _duration - age) { - Hue = 0x3F; - Movable = false; - - m_MinDamage = minDamage; - m_MaxDamage = maxDamage; - m_Created = Core.Now; - m_Duration = duration; - - Timer.StartTimer(TimeSpan.Zero, TimeSpan.FromSeconds(1), OnTick, out _timerToken); + _drying = true; + ItemID = 0x122B; } - public PoolOfAcid(Serial serial) : base(serial) + using var queue = PooledRefQueue.Create(); + + foreach (var m in GetMobilesInRange(0)) { - } - - public override string DefaultName => "a pool of acid"; - - public override void OnDelete() - { - _timerToken.Cancel(); - } - - private void OnTick() - { - var now = Core.Now; - var age = now - m_Created; - - if (age > m_Duration) + if (m.Alive && !m.IsDeadBondedPet && (m is not BaseCreature bc || bc.Controlled || bc.Summoned)) { - Delete(); - } - else - { - if (!m_Drying && age > m_Duration - age) - { - m_Drying = true; - ItemID = 0x122B; - } - - var toDamage = new List(); - - foreach (var m in GetMobilesInRange(0)) - { - if (m.Alive && !m.IsDeadBondedPet && (m is not BaseCreature bc || bc.Controlled || bc.Summoned)) - { - toDamage.Add(m); - } - } - - for (var i = 0; i < toDamage.Count; i++) - { - Damage(toDamage[i]); - } + queue.Enqueue(m); } } - public override bool OnMoveOver(Mobile m) - { - Damage(m); - return true; - } - - public void Damage(Mobile m) - { - m.Damage(Utility.RandomMinMax(m_MinDamage, m_MaxDamage)); - } - - public override void Serialize(IGenericWriter writer) - { - // Don't serialize these - } - - public override void Deserialize(IGenericReader reader) + while (queue.Count > 0) { + Damage(queue.Dequeue()); } } + + public override bool OnMoveOver(Mobile m) + { + Damage(m); + return true; + } + + public void Damage(Mobile m) + { + m.Damage(Utility.RandomMinMax(_minDamage, _maxDamage)); + } + + public override void Serialize(IGenericWriter writer) + { + } + + public override void Deserialize(IGenericReader reader) + { + } } From e172dc96616988f6c12660306deb191e54e91a89 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Thu, 19 May 2022 10:51:24 -0700 Subject: [PATCH 169/213] fix: Updates dependencies & adds Fedora 35/36 support (#1029) --- Directory.Build.props | 4 ++-- Projects/Server.Tests/Server.Tests.csproj | 7 +++---- Projects/Server/Server.csproj | 4 +++- Projects/UOContent.Tests/UOContent.Tests.csproj | 6 +++--- Projects/UOContent/UOContent.csproj | 6 +++--- README.md | 2 +- azure-pipelines.yml | 12 ++++++------ 7 files changed, 21 insertions(+), 20 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 6f875b8d0..c0a882066 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -55,11 +55,11 @@ latest - + - 3.4.255 + 3.5.104 all diff --git a/Projects/Server.Tests/Server.Tests.csproj b/Projects/Server.Tests/Server.Tests.csproj index b310c4f69..db30edf70 100644 --- a/Projects/Server.Tests/Server.Tests.csproj +++ b/Projects/Server.Tests/Server.Tests.csproj @@ -3,11 +3,10 @@ false - - + + - - + diff --git a/Projects/Server/Server.csproj b/Projects/Server/Server.csproj index a77dac609..50866b6d6 100755 --- a/Projects/Server/Server.csproj +++ b/Projects/Server/Server.csproj @@ -21,6 +21,8 @@ + + @@ -36,7 +38,7 @@ - + diff --git a/Projects/UOContent.Tests/UOContent.Tests.csproj b/Projects/UOContent.Tests/UOContent.Tests.csproj index 38f0fc1bd..195cec9a4 100644 --- a/Projects/UOContent.Tests/UOContent.Tests.csproj +++ b/Projects/UOContent.Tests/UOContent.Tests.csproj @@ -3,10 +3,10 @@ false - - + + - + diff --git a/Projects/UOContent/UOContent.csproj b/Projects/UOContent/UOContent.csproj index 024d9bd98..cc056a51a 100755 --- a/Projects/UOContent/UOContent.csproj +++ b/Projects/UOContent/UOContent.csproj @@ -41,9 +41,9 @@ - - - + + + diff --git a/README.md b/README.md index 3f4af0244..b7a0230e7 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ ModernUO [![Discord](https://img.shields.io/discord/751317910504603701?logo=disc [![Ubuntu 16/18/20 LTS](https://img.shields.io/badge/-20LTS-E95420?logo=ubuntu&logoColor=white)](https://ubuntu.com/download/server) [![Linux Mint 17/18/19/20](https://img.shields.io/badge/-20-87CF3E?logo=linux%20mint&logoColor=white)](https://linuxmint.com/download.php) [![CentOS 7/8](https://img.shields.io/badge/-8.5-262577?logo=centos&logoColor=white)](https://www.centos.org/download/) -[![Fedora 32/33/34](https://img.shields.io/badge/-34-51a2da?logo=fedora&logoColor=white)](https://getfedora.org/en/server/download/) +[![Fedora 32/33/34/35/36](https://img.shields.io/badge/-36-51a2da?logo=fedora&logoColor=white)](https://getfedora.org/en/server/download/) [![RedHat 7/8](https://img.shields.io/badge/-8-BE0000?logo=red%20hat&logoColor=white)](https://access.redhat.com/downloads) #### Running the server diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 8efb2abc9..51ad8fce0 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -40,15 +40,15 @@ jobs: 'Ubuntu 20': containerImage: mcr.microsoft.com/dotnet/sdk:6.0-focal os: ubuntu.20.04 - 'Fedora 32': - containerImage: fedora:32 - os: fedora.32 - 'Fedora 33': - containerImage: fedora:33 - os: fedora.33 'Fedora 34': containerImage: fedora:34 os: fedora.34 + 'Fedora 35': + containerImage: fedora:35 + os: fedora.34 + 'Fedora 36': + containerImage: fedora:36 + os: fedora.34 displayName: Linux From 9bbcb4b274456fc60dd9e1437fb5392083d6473d Mon Sep 17 00:00:00 2001 From: CA5A <104018036+CA5A@users.noreply.github.com> Date: Fri, 20 May 2022 16:11:31 -0300 Subject: [PATCH 170/213] fix: Removes DropReq6017 (#1030) --- .../Network/Packets/IncomingItemPackets.cs | 38 ------------------- 1 file changed, 38 deletions(-) diff --git a/Projects/Server/Network/Packets/IncomingItemPackets.cs b/Projects/Server/Network/Packets/IncomingItemPackets.cs index 06543cadf..0b9059d19 100644 --- a/Projects/Server/Network/Packets/IncomingItemPackets.cs +++ b/Projects/Server/Network/Packets/IncomingItemPackets.cs @@ -107,44 +107,6 @@ public static class IncomingItemPackets } } - public static void DropReq6017(NetState state, CircularBufferReader reader, int packetLength) - { - reader.ReadInt32(); // serial, ignored - int x = reader.ReadInt16(); - int y = reader.ReadInt16(); - int z = reader.ReadSByte(); - reader.ReadByte(); // Grid Location? - Serial dest = (Serial)reader.ReadUInt32(); - - var loc = new Point3D(x, y, z); - - var from = state.Mobile; - - if (dest.IsMobile) - { - from.Drop(World.FindMobile(dest), loc); - } - else if (dest.IsItem) - { - var item = World.FindItem(dest); - - if (item is BaseMulti multi && multi.AllowsRelativeDrop) - { - loc.m_X += multi.X; - loc.m_Y += multi.Y; - from.Drop(loc); - } - else - { - from.Drop(item, loc); - } - } - else - { - from.Drop(loc); - } - } - public static void EquipMacro(NetState state, CircularBufferReader reader, int packetLength) { int count = reader.ReadByte(); From ef883b2872e54975da9c8720010acd34113c35f9 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sat, 21 May 2022 20:24:46 -0700 Subject: [PATCH 171/213] fix: Fixes socket disconnect on block. Fixes debug logging (#1031) --- Projects/Server/Items/Item.cs | 7 +++-- Projects/Server/Logging/LogFactory.cs | 26 ++++++++-------- Projects/Server/Maps/MapLoader.cs | 4 +-- Projects/Server/Mobiles/Mobile.cs | 4 +-- Projects/Server/Network/NetState/NetState.cs | 31 +++++++------------- 5 files changed, 30 insertions(+), 42 deletions(-) diff --git a/Projects/Server/Items/Item.cs b/Projects/Server/Items/Item.cs index 8dc75c17c..84bdf05d2 100644 --- a/Projects/Server/Items/Item.cs +++ b/Projects/Server/Items/Item.cs @@ -4,6 +4,7 @@ using System.Diagnostics; using System.Runtime.CompilerServices; using Server.ContextMenus; using Server.Items; +using Server.Logging; using Server.Network; using Server.Targeting; @@ -177,6 +178,8 @@ namespace Server public class Item : IHued, IComparable, ISpawnable, IPropertyListObject { + private static readonly ILogger logger = LogFactory.GetLogger(typeof(Item)); + public const int QuestItemHue = 0x4EA; // Hmmmm... "for EA"? public static readonly List EmptyItems = new(); private static readonly Queue m_DeltaQueue = new(); @@ -3277,9 +3280,7 @@ namespace Server } catch (Exception ex) { -#if DEBUG - Console.WriteLine("Process Delta Queue for {0} failed: {1}", item, ex); -#endif + logger.Debug(ex, "Process Delta Queue for {Item} failed", item); } } diff --git a/Projects/Server/Logging/LogFactory.cs b/Projects/Server/Logging/LogFactory.cs index 2bf93a57d..aee8bb927 100644 --- a/Projects/Server/Logging/LogFactory.cs +++ b/Projects/Server/Logging/LogFactory.cs @@ -1,6 +1,6 @@ /************************************************************************* * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * + * Copyright 2019-2022 - ModernUO Development Team * * Email: hi@modernuo.com * * File: LogFactory.cs * * * @@ -16,16 +16,18 @@ using System; using Serilog; -namespace Server.Logging -{ - public static class LogFactory - { - private static readonly Serilog.ILogger serilogLogger = new LoggerConfiguration() - .WriteTo.Async(a => a.Console( - outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj} {NewLine}{Exception}" - )) - .CreateLogger(); +namespace Server.Logging; - public static ILogger GetLogger(Type declaringType) => new SerilogLogger(serilogLogger.ForContext(declaringType)); - } +public static class LogFactory +{ + private static readonly Serilog.ILogger serilogLogger = new LoggerConfiguration() + .WriteTo.Async(a => a.Console( + outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj} {NewLine}{Exception}" + )) +#if DEBUG + .MinimumLevel.Debug() +#endif + .CreateLogger(); + + public static ILogger GetLogger(Type declaringType) => new SerilogLogger(serilogLogger.ForContext(declaringType)); } diff --git a/Projects/Server/Maps/MapLoader.cs b/Projects/Server/Maps/MapLoader.cs index 80294537d..ca0ed6119 100644 --- a/Projects/Server/Maps/MapLoader.cs +++ b/Projects/Server/Maps/MapLoader.cs @@ -70,9 +70,7 @@ namespace Server } catch (Exception ex) { -#if DEBUG - Console.WriteLine(ex); -#endif + logger.Debug(ex, "Failed to load map definition {MapDefName} ({MapDefId})", def.Name, def.Id); failures.Add($"\tInvalid map definition {def.Name} ({def.Id})"); } } diff --git a/Projects/Server/Mobiles/Mobile.cs b/Projects/Server/Mobiles/Mobile.cs index 1c69579c7..8a953447c 100644 --- a/Projects/Server/Mobiles/Mobile.cs +++ b/Projects/Server/Mobiles/Mobile.cs @@ -7908,9 +7908,7 @@ namespace Server } catch (Exception ex) { -#if DEBUG - Console.WriteLine("Process Delta Queue for {0} failed: {1}", mob, ex); -#endif + logger.Debug(ex, "Process Delta Queue for {Mobile} failed", mob); } } diff --git a/Projects/Server/Network/NetState/NetState.cs b/Projects/Server/Network/NetState/NetState.cs index d76846c0b..267a0c0da 100755 --- a/Projects/Server/Network/NetState/NetState.cs +++ b/Projects/Server/Network/NetState/NetState.cs @@ -516,9 +516,6 @@ public partial class NetState : IComparable } catch (Exception ex) { -#if DEBUG - Console.WriteLine(ex); -#endif TraceException(ex); Disconnect("Exception while sending."); } @@ -861,18 +858,14 @@ public partial class NetState : IComparable } catch (SocketException ex) { - // Socket exceptions are generally ok, just spammy -#if DEBUG - Console.WriteLine(ex); -#endif - - Disconnect(string.Empty); + if (ex.SocketErrorCode != SocketError.WouldBlock) + { + logger.Debug(ex, "Disconnected due to socket exception"); + Disconnect(string.Empty); + } } catch (Exception ex) { -#if DEBUG - Console.WriteLine(ex); -#endif Disconnect($"Disconnected with error: {ex}"); TraceException(ex); } @@ -910,19 +903,15 @@ public partial class NetState : IComparable } catch (SocketException ex) { -#if DEBUG - if (ex.ErrorCode != 54 && ex.ErrorCode != 89 && ex.ErrorCode != 995) - { - Console.WriteLine(ex); - } -#endif + if (ex.ErrorCode is not 54 and not 89 and not 995) + { + logger.Debug(ex, "Disconnected due to a socket exception"); + } + Disconnect(string.Empty); } catch (Exception ex) { -#if DEBUG - Console.WriteLine(ex); -#endif Disconnect($"Disconnected with error: {ex}"); TraceException(ex); } From fe225003c6d9eabb16a7a6c87ca821c6b08b8f0c Mon Sep 17 00:00:00 2001 From: Stefano Merotta <97297186+stefanomerotta@users.noreply.github.com> Date: Fri, 27 May 2022 19:25:30 +0200 Subject: [PATCH 172/213] fix: Adds multithread optional flag to ValueStringBuilder (#1033) Added multithread optional flag to ValueStringBuilder for multithread contexts. Enabled new flag for VerifyType method. Resolves #1032 --- Projects/Server/Buffers/ValueStringBuilder.cs | 29 +++++++++++++------ Projects/Server/Main.cs | 2 +- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/Projects/Server/Buffers/ValueStringBuilder.cs b/Projects/Server/Buffers/ValueStringBuilder.cs index 99a400036..f06fdba05 100644 --- a/Projects/Server/Buffers/ValueStringBuilder.cs +++ b/Projects/Server/Buffers/ValueStringBuilder.cs @@ -3,6 +3,7 @@ #nullable enable using System; +using System.Buffers; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -13,35 +14,45 @@ public ref struct ValueStringBuilder private char[] _arrayToReturnToPool; private Span _chars; private int _length; + private bool _mt; - public ValueStringBuilder() : this(64) + private ArrayPool ArrayPool + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => _mt ? ArrayPool.Shared : STArrayPool.Shared; + } + + public ValueStringBuilder(bool mt = false) : this(64, mt) { } // If this ctor is used, you cannot pass in stackalloc ROS for append/replace. - public ValueStringBuilder(ReadOnlySpan initialString) : this(initialString.Length) + public ValueStringBuilder(ReadOnlySpan initialString, bool mt = false) : this(initialString.Length, mt) { Append(initialString); } - public ValueStringBuilder(ReadOnlySpan initialString, Span initialBuffer) : this(initialBuffer) + public ValueStringBuilder(ReadOnlySpan initialString, Span initialBuffer, bool mt = false) : this(initialBuffer, mt) { Append(initialString); } - public ValueStringBuilder(Span initialBuffer) + public ValueStringBuilder(Span initialBuffer, bool mt = false) { + _mt = mt; _arrayToReturnToPool = null; _chars = initialBuffer; _length = 0; } // If this ctor is used, you cannot pass in stackalloc ROS for append/replace. - public ValueStringBuilder(int initialCapacity) + public ValueStringBuilder(int initialCapacity, bool mt = false) { - _arrayToReturnToPool = STArrayPool.Shared.Rent(initialCapacity); + _mt = mt; + _arrayToReturnToPool = null; _chars = _arrayToReturnToPool; _length = 0; + _arrayToReturnToPool = ArrayPool.Rent(initialCapacity); } public int Length => _length; @@ -319,7 +330,7 @@ public ref struct ValueStringBuilder [MethodImpl(MethodImplOptions.NoInlining)] private void Grow(int additionalCapacityBeyondPos) { - char[] poolArray = STArrayPool.Shared.Rent(Math.Max(_length + additionalCapacityBeyondPos, _chars.Length * 2)); + char[] poolArray = ArrayPool.Rent(Math.Max(_length + additionalCapacityBeyondPos, _chars.Length * 2)); _chars[.._length].CopyTo(poolArray); @@ -327,7 +338,7 @@ public ref struct ValueStringBuilder _chars = _arrayToReturnToPool = poolArray; if (toReturn != null) { - STArrayPool.Shared.Return(toReturn); + ArrayPool.Return(toReturn); } } @@ -338,7 +349,7 @@ public ref struct ValueStringBuilder this = default; // for safety, to avoid using pooled array if this instance is erroneously appended to again if (toReturn != null) { - STArrayPool.Shared.Return(toReturn); + ArrayPool.Return(toReturn); } } #nullable restore diff --git a/Projects/Server/Main.cs b/Projects/Server/Main.cs index bd1316858..4120e699c 100644 --- a/Projects/Server/Main.cs +++ b/Projects/Server/Main.cs @@ -607,7 +607,7 @@ namespace Server Interlocked.Increment(ref _mobileCount); } - ValueStringBuilder errors = new ValueStringBuilder(); + ValueStringBuilder errors = new ValueStringBuilder(true); try { From 3b7e3c2fb773cd769f18b5ee238d395507a20fed Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Fri, 27 May 2022 17:49:36 -0700 Subject: [PATCH 173/213] fix: Fixes ValueStringBuilder empty ctor issue (#1035) --- Projects/Server/Buffers/ValueStringBuilder.cs | 8 +++++--- Projects/Server/Main.cs | 2 +- Projects/UOContent/Commands/Properties.cs | 2 +- Projects/UOContent/Compression/TarArchive.cs | 2 +- .../Engines/Ethics/Evil/Powers/UnholySense.cs | 2 +- .../UOContent/Engines/Ethics/Hero/Powers/HolySense.cs | 2 +- Projects/UOContent/Gumps/AdminGump.cs | 10 +++++----- Projects/UOContent/Misc/ClientVerification.cs | 2 +- 8 files changed, 16 insertions(+), 14 deletions(-) diff --git a/Projects/Server/Buffers/ValueStringBuilder.cs b/Projects/Server/Buffers/ValueStringBuilder.cs index f06fdba05..ecc714ee3 100644 --- a/Projects/Server/Buffers/ValueStringBuilder.cs +++ b/Projects/Server/Buffers/ValueStringBuilder.cs @@ -22,9 +22,11 @@ public ref struct ValueStringBuilder get => _mt ? ArrayPool.Shared : STArrayPool.Shared; } - public ValueStringBuilder(bool mt = false) : this(64, mt) - { - } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ValueStringBuilder Create(int capacity = 64, bool mt = false) => new(capacity, mt); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ValueStringBuilder CreateMT(int capacity = 64) => new(capacity, true); // If this ctor is used, you cannot pass in stackalloc ROS for append/replace. public ValueStringBuilder(ReadOnlySpan initialString, bool mt = false) : this(initialString.Length, mt) diff --git a/Projects/Server/Main.cs b/Projects/Server/Main.cs index 4120e699c..c684e5fcf 100644 --- a/Projects/Server/Main.cs +++ b/Projects/Server/Main.cs @@ -607,7 +607,7 @@ namespace Server Interlocked.Increment(ref _mobileCount); } - ValueStringBuilder errors = new ValueStringBuilder(true); + using var errors = ValueStringBuilder.CreateMT(); try { diff --git a/Projects/UOContent/Commands/Properties.cs b/Projects/UOContent/Commands/Properties.cs index 4ff86a699..8d888bb1f 100644 --- a/Projects/UOContent/Commands/Properties.cs +++ b/Projects/UOContent/Commands/Properties.cs @@ -331,7 +331,7 @@ namespace Server.Commands return $"{p.Name} = {toString}"; } - using var builder = new ValueStringBuilder(); + using var builder = ValueStringBuilder.Create(); for (var i = 0; i < chain.Length; i++) { builder.Append(chain[i].Name); diff --git a/Projects/UOContent/Compression/TarArchive.cs b/Projects/UOContent/Compression/TarArchive.cs index 4905a3683..702866122 100755 --- a/Projects/UOContent/Compression/TarArchive.cs +++ b/Projects/UOContent/Compression/TarArchive.cs @@ -96,7 +96,7 @@ namespace Server.Compression new FileInfo(destinationArchiveFileName).EnsureDirectory(); - using var builder = new ValueStringBuilder(); + using var builder = ValueStringBuilder.Create(); var i = 0; foreach (var path in paths) { diff --git a/Projects/UOContent/Engines/Ethics/Evil/Powers/UnholySense.cs b/Projects/UOContent/Engines/Ethics/Evil/Powers/UnholySense.cs index 6494204b1..51b451ded 100644 --- a/Projects/UOContent/Engines/Ethics/Evil/Powers/UnholySense.cs +++ b/Projects/UOContent/Engines/Ethics/Evil/Powers/UnholySense.cs @@ -46,7 +46,7 @@ namespace Server.Ethics.Evil ++enemyCount; } - using var sb = new ValueStringBuilder(); + using var sb = ValueStringBuilder.Create(); sb.Append("You sense "); sb.Append(enemyCount == 0 ? "no" : enemyCount.ToString()); diff --git a/Projects/UOContent/Engines/Ethics/Hero/Powers/HolySense.cs b/Projects/UOContent/Engines/Ethics/Hero/Powers/HolySense.cs index d49597a32..12123d7e9 100644 --- a/Projects/UOContent/Engines/Ethics/Hero/Powers/HolySense.cs +++ b/Projects/UOContent/Engines/Ethics/Hero/Powers/HolySense.cs @@ -46,7 +46,7 @@ namespace Server.Ethics.Hero ++enemyCount; } - using var sb = new ValueStringBuilder(); + using var sb = ValueStringBuilder.Create(); sb.Append("You sense "); sb.Append(enemyCount == 0 ? "no" : enemyCount.ToString()); diff --git a/Projects/UOContent/Gumps/AdminGump.cs b/Projects/UOContent/Gumps/AdminGump.cs index 74dd03fbe..2869bd2b2 100644 --- a/Projects/UOContent/Gumps/AdminGump.cs +++ b/Projects/UOContent/Gumps/AdminGump.cs @@ -221,7 +221,7 @@ namespace Server.Gumps } case AdminGumpPage.Information_Perf: { - using var sb = new ValueStringBuilder(); + using var sb = ValueStringBuilder.Create(); ThreadPool.GetAvailableThreads(out var curUser, out var curIOCP); ThreadPool.GetMaxThreads(out var maxUser, out var maxIOCP); @@ -629,7 +629,7 @@ namespace Server.Gumps AddLabel(12, 140, LabelHue, "There are no accounts to display."); } - using var sb = new ValueStringBuilder(); + using var sb = ValueStringBuilder.Create(); for (int i = 0, index = listPage * 12; i < 12 && index >= 0 && index < sharedAccounts.Count; @@ -1169,7 +1169,7 @@ namespace Server.Gumps AddButtonLabeled(20, 150, GetButtonID(5, 4), "Add Comment"); - var sb = new ValueStringBuilder(); + var sb = ValueStringBuilder.Create(); if (a.Comments.Count == 0) { @@ -1208,7 +1208,7 @@ namespace Server.Gumps AddButtonLabeled(20, 150, GetButtonID(5, 5), "Add Tag"); - var sb = new ValueStringBuilder(); + var sb = ValueStringBuilder.Create(); if (a.Tags.Count == 0) { @@ -3054,7 +3054,7 @@ namespace Server.Gumps if (list.Count > 0) { - using var sb = new ValueStringBuilder(); + using var sb = ValueStringBuilder.Create(); sb.Append("You are about to ban "); sb.Append(list.Count); sb.Append(list.Count != 1 ? "accounts." : "account."); diff --git a/Projects/UOContent/Misc/ClientVerification.cs b/Projects/UOContent/Misc/ClientVerification.cs index 20c90f1f7..08ff2f7dc 100644 --- a/Projects/UOContent/Misc/ClientVerification.cs +++ b/Projects/UOContent/Misc/ClientVerification.cs @@ -81,7 +81,7 @@ namespace Server.Misc private static void EventSink_ClientVersionReceived(NetState state, ClientVersion version) { - using var message = new ValueStringBuilder(); + using var message = ValueStringBuilder.Create(); if (!_enable || state.Mobile?.AccessLevel != AccessLevel.Player) { From 1e6ab794fe9551b1d412351bf43ab03d4e59e0ec Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 29 May 2022 15:01:39 -0700 Subject: [PATCH 174/213] fix: Fixes ValueStringBuilder dispose incorrectly (#1037) --- Projects/Server/Buffers/ValueStringBuilder.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Projects/Server/Buffers/ValueStringBuilder.cs b/Projects/Server/Buffers/ValueStringBuilder.cs index ecc714ee3..e97ac7622 100644 --- a/Projects/Server/Buffers/ValueStringBuilder.cs +++ b/Projects/Server/Buffers/ValueStringBuilder.cs @@ -347,12 +347,12 @@ public ref struct ValueStringBuilder [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Dispose() { - char[] toReturn = _arrayToReturnToPool; - this = default; // for safety, to avoid using pooled array if this instance is erroneously appended to again - if (toReturn != null) + if (_arrayToReturnToPool != null) { - ArrayPool.Return(toReturn); + ArrayPool.Return(_arrayToReturnToPool); } + + this = default; // for safety, to avoid using pooled array if this instance is erroneously appended to again } #nullable restore From d261973ceea890e3d42f59454a2f1760d81f2221 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Mon, 30 May 2022 09:35:46 -0700 Subject: [PATCH 175/213] fix: Adds freeshard protocol to information list (#1038) --- Projects/Server/Network/Packets/IncomingPackets.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Projects/Server/Network/Packets/IncomingPackets.cs b/Projects/Server/Network/Packets/IncomingPackets.cs index 1eaec8c45..3aa6e2597 100644 --- a/Projects/Server/Network/Packets/IncomingPackets.cs +++ b/Projects/Server/Network/Packets/IncomingPackets.cs @@ -79,6 +79,7 @@ public static class IncomingPackets 0xD9 => true, // Hardware Info 0xDD => true, // Gumps (Packed) 0xE1 => true, // Client Type + 0xF1 => true, // Freeshard Protocol 0xF4 => true, // CrashReport _ => false }; From aeec7f78fd535e07606d74d555c8d0fa59007e5a Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Mon, 30 May 2022 14:04:54 -0700 Subject: [PATCH 176/213] fix: Fixes issue with wepoll losing GCHandle. (#1039) - [X] Fixes issue with wepoll losing GCHandle. - [X] `NetState.Disconnect()` is no longer thread safe. - Use `Core.LoopContext.Post()` to post disconnects - [X] Optimizes PollGroup by not processing IntPtr -> GCHandle for discard polls. --- .../Tests/Network/PollGroupTests.cs | 37 ++++++++++++ Projects/Server/Network/NetState/NetState.cs | 58 +++++++++++-------- Projects/Server/Server.csproj | 2 +- 3 files changed, 72 insertions(+), 25 deletions(-) create mode 100644 Projects/Server.Tests/Tests/Network/PollGroupTests.cs diff --git a/Projects/Server.Tests/Tests/Network/PollGroupTests.cs b/Projects/Server.Tests/Tests/Network/PollGroupTests.cs new file mode 100644 index 000000000..34d97e9a2 --- /dev/null +++ b/Projects/Server.Tests/Tests/Network/PollGroupTests.cs @@ -0,0 +1,37 @@ +using System; +using System.Runtime.InteropServices; +using System.Threading; +using Server.Network; +using Xunit; + +namespace Server.Tests.Network; + +public class PollGroupTests +{ + [Fact] + public void TestPollGroup() + { + // var group = new KQueuePollGroup(); + var nss = new NetState[2048]; + var handles = new IntPtr[2048]; + for (var i = 0; i < nss.Length; i++) + { + nss[i] = PacketTestUtilities.CreateTestNetState(); + handles[i] = (IntPtr)nss[i].Handle; + } + + GC.AddMemoryPressure(10000000000); + GC.Collect(); + GC.RemoveMemoryPressure(10000000000); + GC.Collect(); + + Thread.Sleep(1000); + + for (var i = 0; i < nss.Length; i++) + { + Assert.Equal(nss[i].Handle, (GCHandle)handles[i]); + } + + // group.Dispose(); + } +} diff --git a/Projects/Server/Network/NetState/NetState.cs b/Projects/Server/Network/NetState/NetState.cs index 267a0c0da..1bd7cf40f 100755 --- a/Projects/Server/Network/NetState/NetState.cs +++ b/Projects/Server/Network/NetState/NetState.cs @@ -15,7 +15,6 @@ using System; using System.Buffers; -using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Net; @@ -51,9 +50,9 @@ public partial class NetState : IComparable private static GCHandle[] _polledStates = new GCHandle[2048]; private static readonly IPollGroup _pollGroup = PollGroup.Create(); - private static readonly Queue FlushPending = new(2048); - private static readonly Queue FlushedPartials = new(2048); - private static readonly ConcurrentQueue Disposed = new(); + private static readonly Queue _flushPending = new(2048); + private static readonly Queue _flushedPartials = new(256); + private static readonly Queue _disposed = new(256); public static NetStateCreatedCallback CreatedCallback { get; set; } @@ -75,6 +74,8 @@ public partial class NetState : IComparable internal GCHandle _handle; private bool _packetLogging; + public GCHandle Handle => _handle; + internal enum ParserState { AwaitingNextPacket, @@ -508,7 +509,7 @@ public partial class NetState : IComparable if (!_flushQueued) { - FlushPending.Enqueue(this); + _flushPending.Enqueue(this); _flushQueued = true; } @@ -930,15 +931,15 @@ public partial class NetState : IComparable public static void FlushAll() { - while (FlushPending.Count != 0) + while (_flushPending.Count != 0) { - FlushPending.Dequeue()?.Flush(); + _flushPending.Dequeue()?.Flush(); } } public static void Slice() { - int count = _pollGroup.Poll(ref _polledStates); + int count = _pollGroup.Poll(_polledStates); if (count > 0) { @@ -949,24 +950,34 @@ public partial class NetState : IComparable } } - while (FlushPending.TryDequeue(out var ns)) + while (_flushPending.TryDequeue(out var ns)) { if (!ns.Flush()) { // Incomplete data, so we need to requeue - FlushedPartials.Enqueue(ns); + _flushedPartials.Enqueue(ns); } } - var hasDisposes = !Disposed.IsEmpty; - while (Disposed.TryDequeue(out var ns)) + var hasDisposes = false; + while (_disposed.TryDequeue(out var ns)) { + hasDisposes = true; ns.Dispose(); } + // If they weren't disconnected, requeue them + while (_flushedPartials.TryDequeue(out var ns)) + { + if (ns.Running) + { + _flushPending.Enqueue(ns); + } + } + if (hasDisposes) { - _pollGroup.Poll(ref _polledStates); + _pollGroup.Poll(_polledStates.Length); } } @@ -1025,20 +1036,19 @@ public partial class NetState : IComparable _running = false; - try - { - if (_disconnectReason != string.Empty) +#if THREADGUARD + if (Thread.CurrentThread != Core.Thread) { - throw new Exception("Attempted to disconnect a netstate twice."); + Utility.PushColor(ConsoleColor.Red); + Console.WriteLine("Attempting to disconnect a netstate from an invalid thread!"); + Console.WriteLine(new StackTrace()); + Utility.PopColor(); + return; } - } - catch (Exception ex) - { - TraceException(ex); - } +#endif _disconnectReason = reason; - Disposed.Enqueue(this); + _disposed.Enqueue(this); } public static void TraceDisconnect(string reason, string ip) @@ -1088,7 +1098,7 @@ public partial class NetState : IComparable TcpServer.Instances.Remove(this); try { - _pollGroup.Remove(Connection); + _pollGroup.Remove(Connection, _handle); } catch (Exception ex) { diff --git a/Projects/Server/Server.csproj b/Projects/Server/Server.csproj index 50866b6d6..1c7cadb61 100755 --- a/Projects/Server/Server.csproj +++ b/Projects/Server/Server.csproj @@ -37,7 +37,7 @@ - + From 98a74a89c777efa88bb7bd38ae7e591c49ec02cb Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Mon, 30 May 2022 15:47:06 -0700 Subject: [PATCH 177/213] fix: Fixes drag drop bounce issue (#1040) --- Projects/Server/Items/Item.cs | 7 ++- .../Items/Skill Items/Magical/Spellbook.cs | 44 ++++++++++--------- 2 files changed, 28 insertions(+), 23 deletions(-) diff --git a/Projects/Server/Items/Item.cs b/Projects/Server/Items/Item.cs index 84bdf05d2..188bafc47 100644 --- a/Projects/Server/Items/Item.cs +++ b/Projects/Server/Items/Item.cs @@ -2074,9 +2074,12 @@ namespace Server MoveToWorld(from.Location, from.Map); } } - else if ((parent as Mobile)?.EquipItem(this) == false) + else if (parent is Mobile mobile) { - MoveToWorld(bounce.WorldLoc, bounce.Map); + if (!mobile.EquipItem(this)) + { + MoveToWorld(bounce.WorldLoc, bounce.Map); + } } else { diff --git a/Projects/UOContent/Items/Skill Items/Magical/Spellbook.cs b/Projects/UOContent/Items/Skill Items/Magical/Spellbook.cs index 500fc7b5c..cbb60611b 100644 --- a/Projects/UOContent/Items/Skill Items/Magical/Spellbook.cs +++ b/Projects/UOContent/Items/Skill Items/Magical/Spellbook.cs @@ -564,35 +564,37 @@ namespace Server.Items public override bool OnDragDrop(Mobile from, Item dropped) { - if (dropped is SpellScroll scroll && scroll.Amount == 1) + if (dropped is not SpellScroll { Amount: 1 } scroll) { - var type = GetTypeForSpell(scroll.SpellID); + return false; + } - if (type != SpellbookType) - { - return false; - } + var type = GetTypeForSpell(scroll.SpellID); - if (HasSpell(scroll.SpellID)) - { - from.SendLocalizedMessage(500179); // That spell is already present in that spellbook. - return false; - } + if (type != SpellbookType) + { + return false; + } - var val = scroll.SpellID - BookOffset; + if (HasSpell(scroll.SpellID)) + { + from.SendLocalizedMessage(500179); // That spell is already present in that spellbook. + return false; + } - if (val >= 0 && val < BookCount) - { - m_Content |= (ulong)1 << val; - ++SpellCount; + var val = scroll.SpellID - BookOffset; - InvalidateProperties(); + if (val >= 0 && val < BookCount) + { + m_Content |= (ulong)1 << val; + ++SpellCount; - scroll.Delete(); + InvalidateProperties(); - from.SendSound(0x249, GetWorldLocation()); - return true; - } + scroll.Delete(); + + from.SendSound(0x249, GetWorldLocation()); + return true; } return false; From fe31470f05d22b861bc1a9309ac1fe869b067890 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Wed, 1 Jun 2022 09:42:11 -0700 Subject: [PATCH 178/213] chore: Updates 3rd party notices (#1042) --- THIRD-PARTY-NOTICES | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/THIRD-PARTY-NOTICES b/THIRD-PARTY-NOTICES index 68a241499..a9a7cc38f 100644 --- a/THIRD-PARTY-NOTICES +++ b/THIRD-PARTY-NOTICES @@ -6,9 +6,9 @@ bring it to our attention. Post an issue or email us: hi@modernuo.com -The attached notices are provided for information only. +The attached notices are provided for informational purposes only. -License notice for corefx +License notice for dotnet --------------------------- The MIT License (MIT) From ecbee1769087f6ec7293eceb9f5209901642665d Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Thu, 2 Jun 2022 10:09:53 -0700 Subject: [PATCH 179/213] fix: Optimizes OPL using string interpolation (#1041) ## Breaking Changes (New API) ObjectPropertyList supports the following API: ```cs list.Add(500000); list.Add(500001, stringArgument); list.Add("Some text"); list.Add($"Some text with {argument}"); list.Add(500002, $"{arg1}\t{arg2}"); ``` ## Notes 1. All API uses that require a formatter like this: ```cs list.Add(500002, "{0}\t{1}", arg1, arg2); ``` Should be changed to use string interpolation, for example: ```cs list.Add(500002, $"{arg1}\t{arg2}"); ``` 2. The following paradigm should no longer be used: ```cs list.Add(1061170, prop.ToString()); // strength requirement ~1_val~ ``` The new string interpolation API will avoid having to convert the argument to a string before writing it to the packet. Instead use the following: ```cs list.Add(1061170, $"{prop}"); // strength requirement ~1_val~ ``` ### Benchmarks ```cs | Method | Mean | Error | StdDev | Gen 0 | Allocated | |------------------------------- |---------:|--------:|--------:|-------:|----------:| | BenchmarkOldOPL | 241.0 ns | 0.56 ns | 0.47 ns | 0.0105 | 88 B | | BenchmarkStringInterpolatedOPL | 199.9 ns | 2.44 ns | 2.39 ns | - | - | ``` ### Changes - [X] Removes crash in STArray.Return when array is null. - [X] Fixes NPE in OPL when entity is null. Serial in packet will be 0 when entity is null. - [X] Fixes NPE in AosAttributes when Parent is null. - [X] Changes OPL to use string interpolation. - [X] Introduces `IPropertyList` to allow extending PropertyList for other uses. --- .../Buffers/RawInterpolatedStringHandler.cs | 2 +- Projects/Server/Buffers/STArrayPool.cs | 2 +- Projects/Server/Items/Container.cs | 15 +- Projects/Server/Items/Item.cs | 56 +- Projects/Server/Items/VirtualCheck.cs | 2 +- Projects/Server/Mobiles/Mobile.cs | 54 +- .../Network/Packets/OutgoingEntityPackets.cs | 2 +- Projects/Server/ObjectPropertyList.cs | 184 ------- .../PropertyList/IObjectPropertyListEntity.cs | 23 + Projects/Server/PropertyList/IPropertyList.cs | 30 ++ .../Server/PropertyList/ObjectPropertyList.cs | 508 ++++++++++++++++++ .../Text/ISelfInterpolatedStringHandler.cs | 71 +++ Projects/Server/Text/StringHelpers.cs | 18 + Projects/Server/Utilities/Utility.cs | 15 +- .../Bulk Orders/Books/BulkOrderBook.cs | 4 +- .../UOContent/Engines/Bulk Orders/LargeBOD.cs | 7 +- .../UOContent/Engines/Bulk Orders/SmallBOD.cs | 6 +- .../Engines/CannedEvil/ChampionSpawn.cs | 15 +- .../Engines/ConPVP/Gumps/AcceptTeamGump.cs | 21 +- .../Engines/ConPVP/Gumps/ConfirmSignupGump.cs | 21 +- .../ConPVP/Gumps/TournamentBracketGump.cs | 21 +- .../UOContent/Engines/Factions/Items/Sigil.cs | 2 +- .../Items/Traps/FactionTrapRemovalKit.cs | 4 +- .../Mobiles/Guards/BaseFactionGuard.cs | 2 +- .../Items/APersonalLetterAddressedToAhie.cs | 2 +- .../ML Quests/Items/AlchemistsBandage.cs | 2 +- .../Items/BasinOfCrystalClearWater.cs | 2 +- .../Engines/ML Quests/Items/BridesLetter.cs | 2 +- .../CompletedTuitionReimbursementForm.cs | 2 +- .../Engines/ML Quests/Items/CrateForSledge.cs | 2 +- .../ML Quests/Items/DreadSpiderSilk.cs | 2 +- .../ML Quests/Items/FragmentOfAMapDelivery.cs | 2 +- .../Items/FriendsOfTheLibraryApplication.cs | 2 +- .../Engines/ML Quests/Items/GiftForArielle.cs | 2 +- .../ML Quests/Items/NotarizedApplication.cs | 2 +- .../ML Quests/Items/OfficialSealingWax.cs | 2 +- .../ML Quests/Items/PortraitOfTheBride.cs | 2 +- .../Engines/ML Quests/Items/PrismaticAmber.cs | 2 +- .../Engines/ML Quests/Items/QuestGiverItem.cs | 4 +- .../Engines/ML Quests/Items/ReginasLetter.cs | 2 +- .../Engines/ML Quests/Items/ReginasRing.cs | 2 +- .../ML Quests/Items/SealedNotesForJamal.cs | 2 +- .../Items/SealingWaxOrderAddressedToPetrus.cs | 2 +- .../Items/SignedTuitionReimbursementForm.cs | 2 +- .../Engines/ML Quests/Items/SpiritBottle.cs | 2 +- .../ML Quests/Items/TaintedTreeSample.cs | 2 +- .../Engines/ML Quests/Items/Teleporters.cs | 4 +- .../Items/TuitionReimbursementForm.cs | 2 +- .../UOContent/Engines/Plants/PlantItem.cs | 2 +- Projects/UOContent/Engines/Plants/Seed.cs | 2 +- .../Quests/Collector/Items/Obsidian.cs | 2 +- .../Quests/Collector/Items/PaintedImage.cs | 2 +- .../Quests/Core/Items/HornOfRetreat.cs | 4 +- .../Items/SchmendrickApprenticeCorpse.cs | 2 +- .../Uzeraan Turmoil/Mobiles/MilitiaFighter.cs | 2 +- .../Items/HagApprenticeCorpse.cs | 2 +- .../UOContent/Engines/Spawners/BaseSpawner.cs | 21 +- .../Engines/Spawners/RegionSpawner.cs | 4 +- .../BasePigmentsOfTokuno.cs | 4 +- .../Treasures of Tokuno/LesserArtifacts.cs | 4 +- .../Character Statue Maker/CharacterStatue.cs | 4 +- .../CharacterStatueMaker.cs | 2 +- .../Halloween/2006/Items/TwilightLantern.cs | 2 +- .../Valentine/2011/Items/StValentinesBears.cs | 4 +- .../Valentine/2012/Items/CupidsArrow.cs | 2 +- .../UOContent/Items/Addons/AddonComponent.cs | 2 +- .../Items/Addons/AddonContainerComponent.cs | 2 +- .../Items/Addons/BaseAddonContainer.cs | 2 +- .../Items/Addons/BaseAddonContainerDeed.cs | 2 +- Projects/UOContent/Items/Aquarium/Aquarium.cs | 34 +- .../Items/Aquarium/AquariumFishingNet.cs | 2 +- Projects/UOContent/Items/Aquarium/BaseFish.cs | 2 +- Projects/UOContent/Items/Aquarium/FishBowl.cs | 4 +- .../Items/Aquarium/Rewards/AquariumMessage.cs | 2 +- .../Rewards/CaptainBlackheartsFishingPole.cs | 2 +- .../Aquarium/Rewards/CraftysFishingHat.cs | 2 +- .../Items/Aquarium/Rewards/FishBones.cs | 2 +- .../Items/Aquarium/Rewards/IslandStatue.cs | 2 +- .../UOContent/Items/Aquarium/Rewards/Shell.cs | 2 +- .../Items/Aquarium/Rewards/ToyBoat.cs | 2 +- .../Aquarium/Rewards/WaterloggedBoots.cs | 2 +- .../UOContent/Items/Aquarium/VacationWafer.cs | 4 +- Projects/UOContent/Items/Armor/BaseArmor.cs | 99 ++-- .../Items/Armor/Glasses/ElvenGlasses.cs | 32 +- .../Items/Armor/Leather/LeafGloves.cs | 4 +- .../Items/Armor/Leather/LeatherGloves.cs | 4 +- Projects/UOContent/Items/Books/BaseBook.cs | 2 +- .../Items/Books/Defined/FropozJournal.cs | 2 +- .../Items/Books/Defined/KaburJournal.cs | 2 +- .../Defined/TranslatedGargoyleJournal.cs | 2 +- .../UOContent/Items/Clothing/BaseClothing.cs | 70 +-- Projects/UOContent/Items/Clothing/Cloaks.cs | 6 +- Projects/UOContent/Items/Clothing/Hats.cs | 2 +- .../UOContent/Items/Clothing/OuterTorso.cs | 8 +- Projects/UOContent/Items/Clothing/Shoes.cs | 4 +- .../Items/Construction/Signs/SubtextSign.cs | 2 +- .../UOContent/Items/Containers/Container.cs | 2 +- .../Items/Containers/LockableContainer.cs | 2 +- .../Items/Containers/ParagonChest.cs | 2 +- .../UOContent/Items/Containers/Strongbox.cs | 2 +- .../BaseDecorationArtifact.cs | 8 +- .../UOContent/Items/Deeds/CommodityDeed.cs | 2 +- .../Items/Deeds/DragonBardingDeed.cs | 2 +- .../UOContent/Items/Deeds/NewPlayerTicket.cs | 2 +- .../Items/Deeds/VendorRentalContract.cs | 2 +- Projects/UOContent/Items/Food/Beverage.cs | 2 +- .../Items/Games/Mahjong/MahjongGame.cs | 2 +- Projects/UOContent/Items/Guilds/Guildstone.cs | 4 +- Projects/UOContent/Items/Jewels/BaseJewel.cs | 50 +- Projects/UOContent/Items/Lights/Candelabra.cs | 2 +- Projects/UOContent/Items/Maps/TreasureMap.cs | 2 +- Projects/UOContent/Items/Misc/BankCheck.cs | 2 +- .../Blighted Grove/MelisandesFermentedWine.cs | 2 +- .../Misc/Blighted Grove/MelisandesHairDye.cs | 2 +- .../Items/Misc/CommunicationCrystals.cs | 8 +- .../UOContent/Items/Misc/Corpses/Corpse.cs | 2 +- .../Items/Misc/Corpses/DecayedCorpse.cs | 2 +- .../UOContent/Items/Misc/InteriorDecorator.cs | 2 +- Projects/UOContent/Items/Misc/Key.cs | 2 +- .../UOContent/Items/Misc/PromotionalToken.cs | 4 +- Projects/UOContent/Items/Misc/Teleporter.cs | 26 +- Projects/UOContent/Items/Misc/WindChimes.cs | 2 +- .../UOContent/Items/Quivers/BaseQuiver.cs | 78 ++- .../Items/Resources/Blacksmithing/Ingots.cs | 6 +- .../Items/Resources/Blacksmithing/Ore.cs | 6 +- .../Items/Resources/Fishing/BigFish.cs | 4 +- .../Items/Resources/Masonry/Granite.cs | 2 +- .../UOContent/Items/Resources/Tailor/Hides.cs | 6 +- .../Items/Resources/Tailor/Leathers.cs | 6 +- .../Skill Items/Carpenter Items/Board.cs | 2 +- .../Carpenter Items/TaxidermyKit.cs | 8 +- .../Fishing/Misc/ShipwreckedItem.cs | 2 +- .../Fishing/Misc/SpecialFishingNet.cs | 6 +- .../Harvest Tools/BaseHarvestTool.cs | 4 +- .../Items/Skill Items/Lumberjack/Log.cs | 2 +- .../Skill Items/Magical/Misc/PotionKeg.cs | 2 +- .../Skill Items/Magical/Misc/RecallRune.cs | 28 +- .../Items/Skill Items/Magical/Runebook.cs | 2 +- .../Items/Skill Items/Magical/Spellbook.cs | 48 +- .../Items/Skill Items/Misc/RecipeScroll.cs | 4 +- .../Items/Skill Items/Misc/RepairDeed.cs | 4 +- .../Musical Instruments/BaseInstrument.cs | 4 +- .../Items/Skill Items/Ninjitsu/Fukiya.cs | 4 +- .../Items/Skill Items/Ninjitsu/FukiyaDarts.cs | 4 +- .../Skill Items/Ninjitsu/LeatherNinjaBelt.cs | 4 +- .../Items/Skill Items/Ninjitsu/Shuriken.cs | 4 +- .../Tailor Items/Dyetubs/FurnitureDyeTub.cs | 2 +- .../Tailor Items/Dyetubs/LeatherDyeTub.cs | 2 +- .../Dyetubs/MetallicLeatherDyeTub.cs | 2 +- .../Tailor Items/Dyetubs/RewardBlackDyeTub.cs | 2 +- .../Tailor Items/Dyetubs/RunebookDyeTub.cs | 2 +- .../Tailor Items/Dyetubs/SpecialDyeTub.cs | 2 +- .../Tailor Items/Dyetubs/StatuetteDyeTub.cs | 2 +- .../Items/Skill Items/Tools/BaseTool.cs | 4 +- .../Items/Skill Items/Tools/RunicHammer.cs | 2 +- .../Items/Skill Items/Tools/RunicSewingKit.cs | 2 +- .../Dawn's Music Box/DawnsMusicBox.cs | 8 +- .../Dawn's Music Box/DawnsMusicGear.cs | 2 +- .../8th Anniversary Items/FountainOfLife.cs | 6 +- .../8th Anniversary Items/Talismans.cs | 2 +- .../Blacksmithy/AncientSmithyHammer.cs | 4 +- .../Blacksmithy/GlovesOfMining.cs | 4 +- .../Blacksmithy/PowderOfTemperament.cs | 4 +- .../Items/Special/Gifts/RoseOfTrinsic.cs | 4 +- .../UOContent/Items/Special/HeritageToken.cs | 2 +- .../Items/Special/Holiday/Snowman.cs | 2 +- .../Special/House Raffle/HouseRaffleDeed.cs | 13 +- .../Special/House Raffle/HouseRaffleStone.cs | 14 +- .../UOContent/Items/Special/MiniHouses.cs | 2 +- .../Items/Special/MonsterStatuette.cs | 2 +- .../Rares/Containers/BaseWaterContainer.cs | 2 +- .../Items/Special/Solen Items/BagOfSending.cs | 4 +- .../Special/Solen Items/BallOfSummoning.cs | 2 +- .../Special/Solen Items/BraceletOfBinding.cs | 2 +- Projects/UOContent/Items/Special/SoulStone.cs | 18 +- .../Special/Special Scrolls/PowerScroll.cs | 6 +- .../Special Scrolls/ScrollofAlacrity.cs | 4 +- .../Special Scrolls/ScrollofTranscendence.cs | 2 +- .../Special/Special Scrolls/StatScroll.cs | 8 +- .../Special/Valentines/2007/ValentinesCard.cs | 2 +- .../Veteran Rewards/AnkhOfSacrifice.cs | 2 +- .../Items/Special/Veteran Rewards/Banner.cs | 4 +- .../Veteran Rewards/BloodyPentagram.cs | 2 +- .../Items/Special/Veteran Rewards/Brazier.cs | 4 +- .../Items/Special/Veteran Rewards/Cannon.cs | 8 +- .../Veteran Rewards/CommodityDeedBox.cs | 2 +- .../Veteran Rewards/ContestMiniHouse.cs | 2 +- .../Veteran Rewards/DecorativeShield.cs | 4 +- .../Special/Veteran Rewards/FlamingHead.cs | 4 +- .../Veteran Rewards/HangingSkeleton.cs | 4 +- .../Special/Veteran Rewards/MiningCart.cs | 2 +- .../Special/Veteran Rewards/MinotaurStatue.cs | 2 +- .../Special/Veteran Rewards/PottedCactus.cs | 2 +- .../Special/Veteran Rewards/StoneAnkh.cs | 6 +- .../Special/Veteran Rewards/TreeStump.cs | 2 +- .../Special/Veteran Rewards/WallBanner.cs | 2 +- .../Veteran Rewards/WeaponEngravingTool.cs | 4 +- .../UOContent/Items/Talismans/BaseTalisman.cs | 84 ++- Projects/UOContent/Items/Wands/BaseWand.cs | 24 +- .../UOContent/Items/Weapons/BaseWeapon.cs | 122 ++--- .../Weapons/ML Weapons/ButchersWarCleaver.cs | 2 +- .../Items/Weapons/Maces/FireworksWand.cs | 4 +- Projects/UOContent/Misc/AOS.cs | 8 +- .../Gifts/Winter2004/DecorativeTopiary.cs | 2 +- .../Misc/Gifts/Winter2004/FestiveCactus.cs | 2 +- .../Winter2004/LightOfTheWinterSolstice.cs | 2 +- .../Misc/Gifts/Winter2004/Mistletoe.cs | 2 +- .../Gifts/Winter2004/PileOfGlacialSnow.cs | 2 +- .../Misc/Gifts/Winter2004/SnowyTree.cs | 2 +- Projects/UOContent/Misc/TextDefinition.cs | 2 +- Projects/UOContent/Mobiles/AI/BaseAI.cs | 2 +- .../Mobiles/Animals/Mounts/Ethereals.cs | 2 +- .../Mobiles/Animals/Mounts/SwampDragon.cs | 2 +- Projects/UOContent/Mobiles/BaseCreature.cs | 2 +- .../Monsters/LBR/Meers/EnragedCreatures.cs | 2 +- Projects/UOContent/Mobiles/PlayerMobile.cs | 24 +- .../Mobiles/Special/ServantOfSemidar.cs | 2 +- .../UOContent/Mobiles/Vendors/BaseVendor.cs | 16 +- .../UOContent/Mobiles/Vendors/PlayerVendor.cs | 8 +- .../UOContent/Multis/Boats/BaseDockedBoat.cs | 2 +- Projects/UOContent/Multis/Boats/TillerMan.cs | 4 +- Projects/UOContent/Multis/Houses/BaseHouse.cs | 2 +- Projects/UOContent/Multis/Houses/HouseSign.cs | 4 +- .../Items/Stones/GamblingStone.cs | 6 +- .../Spells/Spellweaving/Items/ArcaneFocus.cs | 4 +- .../Spellweaving/Items/TransientItem.cs | 4 +- version.json | 2 +- 227 files changed, 1426 insertions(+), 1008 deletions(-) delete mode 100644 Projects/Server/ObjectPropertyList.cs create mode 100644 Projects/Server/PropertyList/IObjectPropertyListEntity.cs create mode 100644 Projects/Server/PropertyList/IPropertyList.cs create mode 100644 Projects/Server/PropertyList/ObjectPropertyList.cs create mode 100644 Projects/Server/Text/ISelfInterpolatedStringHandler.cs diff --git a/Projects/Server/Buffers/RawInterpolatedStringHandler.cs b/Projects/Server/Buffers/RawInterpolatedStringHandler.cs index 20c996ead..699b61792 100644 --- a/Projects/Server/Buffers/RawInterpolatedStringHandler.cs +++ b/Projects/Server/Buffers/RawInterpolatedStringHandler.cs @@ -78,7 +78,7 @@ public ref struct RawInterpolatedStringHandler /// The number of interpolation expressions in the interpolated string. [MethodImpl(MethodImplOptions.AggressiveInlining)] // becomes a constant when inputs are constant internal static int GetDefaultLength(int literalLength, int formattedCount) => - Math.Max(MinimumArrayPoolLength, literalLength + (formattedCount * GuessedLengthPerHole)); + Math.Max(MinimumArrayPoolLength, literalLength + formattedCount * GuessedLengthPerHole); /// Clears the handler, returning any rented array to the pool. [MethodImpl(MethodImplOptions.AggressiveInlining)] // used only on a few hot paths diff --git a/Projects/Server/Buffers/STArrayPool.cs b/Projects/Server/Buffers/STArrayPool.cs index 8210aa3de..65e8a9d6c 100644 --- a/Projects/Server/Buffers/STArrayPool.cs +++ b/Projects/Server/Buffers/STArrayPool.cs @@ -78,7 +78,7 @@ public class STArrayPool : ArrayPool { if (array is null) { - throw new ArgumentNullException(nameof(array)); + return; } var bucketIndex = SelectBucketIndex(array.Length); diff --git a/Projects/Server/Items/Container.cs b/Projects/Server/Items/Container.cs index 1b8375553..1d06752cc 100644 --- a/Projects/Server/Items/Container.cs +++ b/Projects/Server/Items/Container.cs @@ -755,7 +755,7 @@ namespace Server.Items public virtual void SendContentTo(NetState state) => state.SendContainerContent(state.Mobile, this); - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); @@ -767,21 +767,14 @@ namespace Server.Items { list.Add( 1073841, // Contents: ~1_COUNT~/~2_MAXCOUNT~ items, ~3_WEIGHT~ stones - "{0}\t{1}\t{2}", - TotalItems, - MaxItems, - TotalWeight + $"{TotalItems}\t{MaxItems}\t{TotalWeight}" ); } else { list.Add( 1072241, // Contents: ~1_COUNT~/~2_MAXCOUNT~ items, ~3_WEIGHT~/~4_MAXWEIGHT~ stones - "{0}\t{1}\t{2}\t{3}", - TotalItems, - MaxItems, - TotalWeight, - MaxWeight + $"{TotalItems}\t{MaxItems}\t{TotalWeight}\t{MaxWeight}" ); } @@ -790,7 +783,7 @@ namespace Server.Items else { // ~1_COUNT~ items, ~2_WEIGHT~ stones - list.Add(1050044, "{0}\t{1}", TotalItems, TotalWeight); + list.Add(1050044, $"{TotalItems}\t{TotalWeight}"); } } } diff --git a/Projects/Server/Items/Item.cs b/Projects/Server/Items/Item.cs index 188bafc47..80c1ee96b 100644 --- a/Projects/Server/Items/Item.cs +++ b/Projects/Server/Items/Item.cs @@ -176,7 +176,7 @@ namespace Server Spawner = 0x100 } - public class Item : IHued, IComparable, ISpawnable, IPropertyListObject + public class Item : IHued, IComparable, ISpawnable, IObjectPropertyListEntity { private static readonly ILogger logger = LogFactory.GetLogger(typeof(Item)); @@ -769,7 +769,7 @@ namespace Server /// custom /// properties. /// - public virtual void GetProperties(ObjectPropertyList list) + public virtual void GetProperties(IPropertyList list) { AddNameProperties(list); } @@ -1817,7 +1817,7 @@ namespace Server /// Overridable. Adds the name of this item to the given . This method should be overridden /// if the item requires a complex naming format. /// - public virtual void AddNameProperty(ObjectPropertyList list) + public virtual void AddNameProperty(IPropertyList list) { var name = Name; @@ -1829,7 +1829,7 @@ namespace Server } else { - list.Add(1050039, "{0}\t#{1}", m_Amount, LabelNumber); // ~1_NUMBER~ ~2_ITEMNAME~ + list.Add(1050039, $"{m_Amount}\t#{LabelNumber}"); // ~1_NUMBER~ ~2_ITEMNAME~ } } else @@ -1840,7 +1840,7 @@ namespace Server } else { - list.Add(1050039, "{0}\t{1}", m_Amount, Name); // ~1_NUMBER~ ~2_ITEMNAME~ + list.Add(1050039, $"{m_Amount}\t{Name}"); // ~1_NUMBER~ ~2_ITEMNAME~ } } } @@ -1849,7 +1849,7 @@ namespace Server /// Overridable. Adds the loot type of this item to the given . By default, this will be /// either 'blessed', 'cursed', or 'insured'. /// - public virtual void AddLootTypeProperty(ObjectPropertyList list) + public virtual void AddLootTypeProperty(IPropertyList list) { if (m_LootType == LootType.Blessed) { @@ -1868,59 +1868,51 @@ namespace Server /// /// Overridable. Adds any elemental resistances of this item to the given . /// - public virtual void AddResistanceProperties(ObjectPropertyList list) + public virtual void AddResistanceProperties(IPropertyList list) { var v = PhysicalResistance; if (v != 0) { - list.Add(1060448, v.ToString()); // physical resist ~1_val~% + list.Add(1060448, $"{v}"); // physical resist ~1_val~% } v = FireResistance; if (v != 0) { - list.Add(1060447, v.ToString()); // fire resist ~1_val~% + list.Add(1060447, $"{v}"); // fire resist ~1_val~% } v = ColdResistance; if (v != 0) { - list.Add(1060445, v.ToString()); // cold resist ~1_val~% + list.Add(1060445, $"{v}"); // cold resist ~1_val~% } v = PoisonResistance; if (v != 0) { - list.Add(1060449, v.ToString()); // poison resist ~1_val~% + list.Add(1060449, $"{v}"); // poison resist ~1_val~% } v = EnergyResistance; if (v != 0) { - list.Add(1060446, v.ToString()); // energy resist ~1_val~% + list.Add(1060446, $"{v}"); // energy resist ~1_val~% } } /// /// Overridable. Displays cliloc 1072788-1072789. /// - public virtual void AddWeightProperty(ObjectPropertyList list) + public virtual void AddWeightProperty(IPropertyList list) { var weight = PileWeight + TotalWeight; - - if (weight == 1) - { - list.Add(1072788, weight.ToString()); // Weight: ~1_WEIGHT~ stone - } - else - { - list.Add(1072789, weight.ToString()); // Weight: ~1_WEIGHT~ stones - } + list.Add(weight == 1 ? 1072788 : 1072789, $"{weight}"); } /// @@ -1928,7 +1920,7 @@ namespace Server /// (if applicable), and (if /// ). /// - public virtual void AddNameProperties(ObjectPropertyList list) + public virtual void AddNameProperties(IPropertyList list) { AddNameProperty(list); @@ -1969,7 +1961,7 @@ namespace Server /// /// Overridable. Adds the "Quest Item" property to the given . /// - public virtual void AddQuestItemProperty(ObjectPropertyList list) + public virtual void AddQuestItemProperty(IPropertyList list) { list.Add(1072351); // Quest Item } @@ -1977,7 +1969,7 @@ namespace Server /// /// Overridable. Adds the "Locked Down & Secure" property to the given . /// - public virtual void AddSecureProperty(ObjectPropertyList list) + public virtual void AddSecureProperty(IPropertyList list) { list.Add(501644); // locked down & secure } @@ -1985,7 +1977,7 @@ namespace Server /// /// Overridable. Adds the "Locked Down" property to the given . /// - public virtual void AddLockedDownProperty(ObjectPropertyList list) + public virtual void AddLockedDownProperty(IPropertyList list) { list.Add(501643); // locked down } @@ -1993,9 +1985,9 @@ namespace Server /// /// Overridable. Adds the "Blessed for ~1_NAME~" property to the given . /// - public virtual void AddBlessedForProperty(ObjectPropertyList list, Mobile m) + public virtual void AddBlessedForProperty(IPropertyList list, Mobile m) { - list.Add(1062203, "{0}", m.Name); // Blessed for ~1_NAME~ + list.Add(1062203, m.Name); // Blessed for ~1_NAME~ } /// @@ -2003,7 +1995,7 @@ namespace Server /// Recursively calls Item.GetChildProperties or /// Mobile.GetChildProperties. /// - public virtual void GetChildProperties(ObjectPropertyList list, Item item) + public virtual void GetChildProperties(IPropertyList list, Item item) { if (m_Parent is Item parentItem) { @@ -2021,7 +2013,7 @@ namespace Server /// . Recursively calls Item.GetChildNameProperties or /// Mobile.GetChildNameProperties. /// - public virtual void GetChildNameProperties(ObjectPropertyList list, Item item) + public virtual void GetChildNameProperties(IPropertyList list, Item item) { if (m_Parent is Item parentItem) { @@ -2377,7 +2369,7 @@ namespace Server return bounds; } - public virtual void AppendChildProperties(ObjectPropertyList list) + public virtual void AppendChildProperties(IPropertyList list) { if (m_Parent is Item item) { @@ -2389,7 +2381,7 @@ namespace Server } } - public virtual void AppendChildNameProperties(ObjectPropertyList list) + public virtual void AppendChildNameProperties(IPropertyList list) { if (m_Parent is Item item) { diff --git a/Projects/Server/Items/VirtualCheck.cs b/Projects/Server/Items/VirtualCheck.cs index da952aaef..c72866f20 100644 --- a/Projects/Server/Items/VirtualCheck.cs +++ b/Projects/Server/Items/VirtualCheck.cs @@ -120,7 +120,7 @@ namespace Server.Items LabelTo(from, "Offer: {0:#,0} platinum, {1:#,0} gold", Plat, Gold); } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/Server/Mobiles/Mobile.cs b/Projects/Server/Mobiles/Mobile.cs index 8a953447c..92f007906 100644 --- a/Projects/Server/Mobiles/Mobile.cs +++ b/Projects/Server/Mobiles/Mobile.cs @@ -403,7 +403,7 @@ namespace Server /// /// Base class representing players, npcs, and creatures. /// - public class Mobile : IHued, IComparable, ISpawnable, IPropertyListObject + public class Mobile : IHued, IComparable, ISpawnable, IObjectPropertyListEntity { // Allow four warmode changes in 0.5 seconds, any more will be delay for two seconds private const int WarmodeCatchCount = 4; @@ -2476,7 +2476,7 @@ namespace Server public virtual int HuedItemID => m_Female ? 0x2107 : 0x2106; public ObjectPropertyList PropertyList => m_PropertyList ??= InitializePropertyList(new ObjectPropertyList(this)); - public virtual void GetProperties(ObjectPropertyList list) + public virtual void GetProperties(IPropertyList list) { AddNameProperties(list); } @@ -3445,57 +3445,51 @@ namespace Server public virtual string ApplyNameSuffix(string suffix) => suffix; - public virtual void AddNameProperties(ObjectPropertyList list) + public virtual void AddNameProperties(IPropertyList list) { - var name = Name ?? ""; + var name = Name ?? " "; string prefix; if (ShowFameTitle && (m_Player || m_Body.IsHuman) && m_Fame >= 10000) { - prefix = m_Female ? "Lady" : "Lord"; + prefix = m_Female ? "Lady " : "Lord "; } else { - prefix = ""; + prefix = " "; } - var suffix = ""; - - if (PropertyTitle && !string.IsNullOrEmpty(Title)) - { - suffix = Title; - } + var title = PropertyTitle && !string.IsNullOrEmpty(Title) ? Title : ""; + string suffix; var guild = m_Guild; - if (guild != null && (m_Player || m_DisplayGuildTitle)) { - suffix = suffix.Length > 0 - ? $"{suffix} [{Utility.FixHtml(guild.Abbreviation)}]" + suffix = title.Length > 0 + ? $"{title} [{Utility.FixHtml(guild.Abbreviation)}]" : $"[{Utility.FixHtml(guild.Abbreviation)}]"; } + else + { + suffix = " "; + } - suffix = ApplyNameSuffix(suffix); - - list.Add(1050045, "{0} \t{1}\t {2}", prefix, name, suffix); // ~1_PREFIX~~2_NAME~~3_SUFFIX~ + list.Add(1050045, $"{prefix}\t{name}\t{ApplyNameSuffix(suffix)}"); // ~1_PREFIX~~2_NAME~~3_SUFFIX~ if (guild != null && (m_DisplayGuildTitle || m_Player && guild.Type != GuildType.Regular)) { var type = guild.Type >= 0 && (int)guild.Type < m_GuildTypes.Length ? m_GuildTypes[(int)guild.Type] : ""; - var title = GuildTitle?.Trim() ?? ""; + var guildTitle = GuildTitle?.Trim() ?? ""; - if (title.Length > 0) + if (guildTitle.Length > 0) { - if (NewGuildDisplay) - { - list.Add("{0}, {1}", Utility.FixHtml(title), Utility.FixHtml(guild.Name)); - } - else - { - list.Add("{0}, {1} Guild{2}", Utility.FixHtml(title), Utility.FixHtml(guild.Name), type); - } + list.Add( + NewGuildDisplay + ? $"{Utility.FixHtml(guildTitle)}, {Utility.FixHtml(guild.Name)}" + : $"{Utility.FixHtml(guildTitle)}, {Utility.FixHtml(guild.Name)} Guild{type}" + ); } else { @@ -3504,11 +3498,11 @@ namespace Server } } - public virtual void GetChildProperties(ObjectPropertyList list, Item item) + public virtual void GetChildProperties(IPropertyList list, Item item) { } - public virtual void GetChildNameProperties(ObjectPropertyList list, Item item) + public virtual void GetChildNameProperties(IPropertyList list, Item item) { } diff --git a/Projects/Server/Network/Packets/OutgoingEntityPackets.cs b/Projects/Server/Network/Packets/OutgoingEntityPackets.cs index cf84157e2..1e546c962 100644 --- a/Projects/Server/Network/Packets/OutgoingEntityPackets.cs +++ b/Projects/Server/Network/Packets/OutgoingEntityPackets.cs @@ -41,7 +41,7 @@ public static class OutgoingEntityPackets writer.Write(hash); } - public static void SendOPLInfo(this NetState ns, IPropertyListObject obj) => + public static void SendOPLInfo(this NetState ns, IObjectPropertyListEntity obj) => ns.SendOPLInfo(obj.Serial, obj.PropertyList.Hash); public static void SendOPLInfo(this NetState ns, Serial serial, int hash) diff --git a/Projects/Server/ObjectPropertyList.cs b/Projects/Server/ObjectPropertyList.cs deleted file mode 100644 index 369cfd2ef..000000000 --- a/Projects/Server/ObjectPropertyList.cs +++ /dev/null @@ -1,184 +0,0 @@ -using System; -using System.Buffers; -using System.IO; -using System.Runtime.CompilerServices; -using Server.Network; - -namespace Server -{ - public interface IPropertyListObject : IEntity - { - ObjectPropertyList PropertyList { get; } - - void GetProperties(ObjectPropertyList list); - } - - public sealed class ObjectPropertyList - { - // Each of these are localized to "~1_NOTHING~" which allows the string argument to be used - private static readonly int[] m_StringNumbers = - { - 1042971, - 1070722 - }; - - private int _hash; - private int _strings; - private byte[] _buffer; - private int _position; - - public ObjectPropertyList(IEntity e) - { - Entity = e; - _buffer = GC.AllocateUninitializedArray(64); - - var writer = new SpanWriter(_buffer); - writer.Write((byte)0xD6); // Packet ID - writer.Seek(2, SeekOrigin.Current); - writer.Write((ushort)1); - writer.Write(e.Serial); - writer.Write((ushort)0); - _position = writer.Position + 4; // Hash - } - - public IEntity Entity { get; } - - public int Hash => 0x40000000 + _hash; - - public int Header { get; set; } - - public string HeaderArgs { get; set; } - - public static bool Enabled { get; set; } - - public byte[] Buffer => _buffer; - - public void Reset() - { - _position = 15; - _hash = 0; - _strings = 0; - Header = 0; - HeaderArgs = null; - } - - public void Flush() - { - Resize(_buffer.Length * 2); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void Resize(int amount) - { - var newBuffer = GC.AllocateUninitializedArray(amount); - _buffer.AsSpan(0, Math.Min(amount, _buffer.Length)).CopyTo(newBuffer); - _buffer = newBuffer; - } - - public void Terminate() - { - int length = _position + 4; - if (length != _buffer.Length) - { - Resize(length); - } - - var writer = new SpanWriter(_buffer); - writer.Seek(_position, SeekOrigin.Begin); - writer.Write(0); - - writer.Seek(11, SeekOrigin.Begin); - writer.Write(_hash); - writer.WritePacketLength(); - } - - public void AddHash(int val) - { - _hash ^= val & 0x3FFFFFF; - _hash ^= (val >> 26) & 0x3F; - } - - public void Add(int number, string arguments = null) - { - if (number == 0) - { - return; - } - - arguments ??= ""; - - if (Header == 0) - { - Header = number; - HeaderArgs = arguments; - } - - AddHash(number); - if (arguments.Length > 0) - { - AddHash(arguments.GetHashCode(StringComparison.Ordinal)); - } - - int strLength = arguments.Length * 2; - int length = _position + 6 + strLength; - while (length > _buffer.Length) - { - Flush(); - } - - var writer = new SpanWriter(_buffer.AsSpan(_position)); - writer.Write(number); - writer.Write((ushort)strLength); - writer.WriteLittleUni(arguments); - - _position += writer.BytesWritten; - } - - public void Add(int number, string format, object arg0) - { - Add(number, string.Format(format, arg0)); - } - - public void Add(int number, string format, object arg0, object arg1) - { - Add(number, string.Format(format, arg0, arg1)); - } - - public void Add(int number, string format, object arg0, object arg1, object arg2) - { - Add(number, string.Format(format, arg0, arg1, arg2)); - } - - public void Add(int number, string format, params object[] args) - { - Add(number, string.Format(format, args)); - } - - private int GetStringNumber() => m_StringNumbers[_strings++ % m_StringNumbers.Length]; - - public void Add(string text) - { - Add(GetStringNumber(), text); - } - - public void Add(string format, string arg0) - { - Add(GetStringNumber(), string.Format(format, arg0)); - } - - public void Add(string format, string arg0, string arg1) - { - Add(GetStringNumber(), string.Format(format, arg0, arg1)); - } - - public void Add(string format, string arg0, string arg1, string arg2) - { - Add(GetStringNumber(), string.Format(format, arg0, arg1, arg2)); - } - - public void Add(string format, params object[] args) - { - Add(GetStringNumber(), string.Format(format, args)); - } - } -} diff --git a/Projects/Server/PropertyList/IObjectPropertyListEntity.cs b/Projects/Server/PropertyList/IObjectPropertyListEntity.cs new file mode 100644 index 000000000..4ba8d3735 --- /dev/null +++ b/Projects/Server/PropertyList/IObjectPropertyListEntity.cs @@ -0,0 +1,23 @@ +/************************************************************************* + * ModernUO * + * Copyright 2019-2022 - ModernUO Development Team * + * Email: hi@modernuo.com * + * File: IObjectPropertyListEntity.cs * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + +namespace Server; + +public interface IObjectPropertyListEntity : IEntity +{ + ObjectPropertyList PropertyList { get; } + + void GetProperties(IPropertyList list); +} diff --git a/Projects/Server/PropertyList/IPropertyList.cs b/Projects/Server/PropertyList/IPropertyList.cs new file mode 100644 index 000000000..59d9a57d7 --- /dev/null +++ b/Projects/Server/PropertyList/IPropertyList.cs @@ -0,0 +1,30 @@ +/************************************************************************* + * ModernUO * + * Copyright 2019-2022 - ModernUO Development Team * + * Email: hi@modernuo.com * + * File: IPropertyList.cs * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + +using System.Runtime.CompilerServices; +using Server.Text; + +namespace Server; + +public interface IPropertyList : ISelfInterpolatedStringHandler +{ + public void Reset(); + public void Terminate(); + public void Add(int number, string argument = null); + public void Add(string text); + + // String Interpolation + public void Add(int number, [InterpolatedStringHandlerArgument("")] ref InterpolatedStringHandler handler); +} diff --git a/Projects/Server/PropertyList/ObjectPropertyList.cs b/Projects/Server/PropertyList/ObjectPropertyList.cs new file mode 100644 index 000000000..834afffd8 --- /dev/null +++ b/Projects/Server/PropertyList/ObjectPropertyList.cs @@ -0,0 +1,508 @@ +/************************************************************************* + * ModernUO * + * Copyright 2019-2022 - ModernUO Development Team * + * Email: hi@modernuo.com * + * File: ObjectPropertyList.cs * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + +#nullable enable +using System; +using System.Buffers; +using System.Diagnostics; +using System.IO; +using System.Runtime.CompilerServices; +using Server.Buffers; +using Server.Network; +using Server.Text; + +namespace Server; + +public sealed class ObjectPropertyList : IPropertyList, IDisposable +{ + // Each of these are localized to "~1_NOTHING~" which allows the string argument to be used + private static readonly int[] _stringNumbers = + { + 1042971, + 1070722, + 1114057, // ~1_val~ + 1114778, // ~1_val~ + 1114779 // ~1_val~ + }; + + private int _hash; + private int _stringNumbersIndex; + private byte[] _buffer; + private int _bufferPos; + + // For string interpolation + private int _pos; + private char[]? _arrayToReturnToPool; + + public ObjectPropertyList(IEntity? e) + { + Entity = e; + _buffer = GC.AllocateUninitializedArray(64); + + var writer = new SpanWriter(_buffer); + writer.Write((byte)0xD6); // Packet ID + writer.Seek(2, SeekOrigin.Current); + writer.Write((ushort)1); + writer.Write(e?.Serial ?? Serial.Zero); + writer.Write((ushort)0); + _bufferPos = writer.Position + 4; // Hash + } + + public IEntity? Entity { get; } + + public int Hash => 0x40000000 + _hash; + + public int Header { get; set; } + + public string HeaderArgs { get; set; } + + public static bool Enabled { get; set; } + + public byte[] Buffer => _buffer; + + public void Reset() + { + _bufferPos = 15; + _hash = 0; + _stringNumbersIndex = 0; + Header = 0; + HeaderArgs = null; + STArrayPool.Shared.Return(_arrayToReturnToPool); + _pos = 0; + } + + private void Flush() + { + Resize(_buffer.Length * 2); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void Resize(int amount) + { + var newBuffer = GC.AllocateUninitializedArray(amount); + _buffer.AsSpan(0, Math.Min(amount, _buffer.Length)).CopyTo(newBuffer); + _buffer = newBuffer; + } + + public void Terminate() + { + int length = _bufferPos + 4; + if (length != _buffer.Length) + { + Resize(length); + } + + var writer = new SpanWriter(_buffer); + writer.Seek(_bufferPos, SeekOrigin.Begin); + writer.Write(0); + + writer.Seek(11, SeekOrigin.Begin); + writer.Write(_hash); + writer.WritePacketLength(); + } + + private void AddHash(int val) + { + _hash ^= val & 0x3FFFFFF; + _hash ^= (val >> 26) & 0x3F; + } + + public void Add(int number, string? arguments = null) + { + if (number == 0) + { + return; + } + + arguments ??= ""; + + if (Header == 0) + { + Header = number; + HeaderArgs = arguments; + } + + AddHash(number); + if (arguments.Length > 0) + { + AddHash(arguments.GetHashCode(StringComparison.Ordinal)); + } + + int strLength = arguments.Length * 2; + int length = _bufferPos + 6 + strLength; + while (length > _buffer.Length) + { + Flush(); + } + + var writer = new SpanWriter(_buffer.AsSpan(_bufferPos)); + writer.Write(number); + writer.Write((ushort)strLength); + writer.WriteLittleUni(arguments); + + _bufferPos += writer.BytesWritten; + _pos = 0; + } + + private int GetStringNumber() => _stringNumbers[_stringNumbersIndex++ % _stringNumbers.Length]; + + public void Add(string argument) => Add(GetStringNumber(), argument); + + public void Add( + [InterpolatedStringHandlerArgument("")] + ref IPropertyList.InterpolatedStringHandler handler + ) => Add(GetStringNumber(), ref handler); + + // String Interpolation + public void Add( + int number, + [InterpolatedStringHandlerArgument("")] + ref IPropertyList.InterpolatedStringHandler handler) + { + if (number == 0) + { + return; + } + + var chars = _arrayToReturnToPool.AsSpan(0, _pos); + + if (Header == 0) + { + Header = number; + HeaderArgs = chars.ToString(); + HeaderArgs.GetHashCode(StringComparison.Ordinal); + } + + AddHash(number); + if (chars.Length > 0) + { + AddHash(string.GetHashCode(chars, StringComparison.Ordinal)); + } + + int strLength = chars.Length * 2; + int length = _bufferPos + 6 + strLength; + while (length > _buffer.Length) + { + Flush(); + } + + var writer = new SpanWriter(_buffer.AsSpan(_bufferPos)); + writer.Write(number); + writer.Write((ushort)strLength); + writer.Write(chars, TextEncoding.UnicodeLE); + + _bufferPos += writer.BytesWritten; + } + + public void InitializeInterpolation(int literalLength, int formattedCount) + { + _arrayToReturnToPool ??= STArrayPool.Shared.Rent(GetDefaultLength(literalLength, formattedCount)); + _pos = 0; + } + + // Copied from RawInterpolatedStringHandler + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static int GetDefaultLength(int literalLength, int formattedCount) => + Math.Max(256, literalLength + formattedCount * 11); + + public void AppendLiteral(string value) + { + if (value.Length == 1) + { + Span chars = _arrayToReturnToPool.AsSpan(); + int pos = _pos; + if ((uint)pos < (uint)chars.Length) + { + chars[pos] = value[0]; + _pos = pos + 1; + } + else + { + GrowThenCopyString(value); + } + return; + } + + AppendStringDirect(value); + } + + private void AppendStringDirect(string value) + { + if (value.TryCopyTo(_arrayToReturnToPool.AsSpan(_pos..))) + { + _pos += value.Length; + } + else + { + GrowThenCopyString(value); + } + } + + public void AppendFormatted(T value) + { + + string? s; + if (value is IFormattable) + { + if (value is ISpanFormattable) + { + int charsWritten; + while (!((ISpanFormattable)value).TryFormat(_arrayToReturnToPool.AsSpan(_pos..), out charsWritten, default, null)) + { + Grow(); + } + + _pos += charsWritten; + return; + } + + s = ((IFormattable)value).ToString(format: null, null); + } + else + { + s = value?.ToString(); + } + + if (s is not null) + { + AppendStringDirect(s); + } + } + + public void AppendFormatted(T value, string? format) + { + string? s; + if (value is IFormattable) + { + if (value is ISpanFormattable) + { + int charsWritten; + while (!((ISpanFormattable)value).TryFormat(_arrayToReturnToPool.AsSpan(_pos..), out charsWritten, format, null)) + { + Grow(); + } + + _pos += charsWritten; + return; + } + + s = ((IFormattable)value).ToString(format, null); + } + else + { + s = value?.ToString(); + } + + if (s is not null) + { + AppendStringDirect(s); + } + } + + public void AppendFormatted(T value, int alignment) + { + int startingPos = _pos; + AppendFormatted(value); + if (alignment != 0) + { + AppendOrInsertAlignmentIfNeeded(startingPos, alignment); + } + } + + public void AppendFormatted(T value, int alignment, string? format) + { + int startingPos = _pos; + AppendFormatted(value, format); + if (alignment != 0) + { + AppendOrInsertAlignmentIfNeeded(startingPos, alignment); + } + } + + public void AppendFormatted(ReadOnlySpan value) + { + if (value.TryCopyTo(_arrayToReturnToPool.AsSpan(_pos..))) + { + _pos += value.Length; + } + else + { + GrowThenCopySpan(value); + } + } + + public void AppendFormatted(ReadOnlySpan value, int alignment = 0, string? format = null) + { + bool leftAlign = false; + if (alignment < 0) + { + leftAlign = true; + alignment = -alignment; + } + + int paddingRequired = alignment - value.Length; + if (paddingRequired <= 0) + { + AppendFormatted(value); + return; + } + + EnsureCapacityForAdditionalChars(value.Length + paddingRequired); + var chars = _arrayToReturnToPool.AsSpan(); + if (leftAlign) + { + value.CopyTo(chars[_pos..]); + _pos += value.Length; + chars.Slice(_pos, paddingRequired).Fill(' '); + _pos += paddingRequired; + } + else + { + chars.Slice(_pos, paddingRequired).Fill(' '); + _pos += paddingRequired; + value.CopyTo(chars[_pos..]); + _pos += value.Length; + } + } + + public void AppendFormatted(string? value) + { + if (value?.TryCopyTo(_arrayToReturnToPool.AsSpan(_pos..)) == true) + { + _pos += value.Length; + } + else + { + AppendFormattedSlow(value); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private void AppendFormattedSlow(string? value) + { + if (value is not null) + { + EnsureCapacityForAdditionalChars(value.Length); + value.CopyTo(_arrayToReturnToPool.AsSpan(_pos..)); + _pos += value.Length; + } + } + + public void AppendFormatted(string? value, int alignment = 0, string? format = null) => + AppendFormatted(value, alignment, format); + + public void AppendFormatted(object? value, int alignment = 0, string? format = null) => + AppendFormatted(value, alignment, format); + + private void AppendOrInsertAlignmentIfNeeded(int startingPos, int alignment) + { + Debug.Assert(startingPos >= 0 && startingPos <= _pos); + Debug.Assert(alignment != 0); + + int charsWritten = _pos - startingPos; + + bool leftAlign = false; + if (alignment < 0) + { + leftAlign = true; + alignment = -alignment; + } + + int paddingNeeded = alignment - charsWritten; + if (paddingNeeded > 0) + { + EnsureCapacityForAdditionalChars(paddingNeeded); + + var chars = _arrayToReturnToPool.AsSpan(); + if (leftAlign) + { + chars.Slice(_pos, paddingNeeded).Fill(' '); + } + else + { + chars.Slice(startingPos, charsWritten).CopyTo(chars[(startingPos + paddingNeeded)..]); + chars.Slice(startingPos, paddingNeeded).Fill(' '); + } + + _pos += paddingNeeded; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void EnsureCapacityForAdditionalChars(int additionalChars) + { + if (_arrayToReturnToPool.Length - _pos < additionalChars) + { + Grow(additionalChars); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private void GrowThenCopyString(string value) + { + Grow(value.Length); + value.CopyTo(_arrayToReturnToPool.AsSpan(_pos..)); + _pos += value.Length; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private void GrowThenCopySpan(ReadOnlySpan value) + { + Grow(value.Length); + value.CopyTo(_arrayToReturnToPool.AsSpan(_pos..)); + _pos += value.Length; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private void Grow(int additionalChars) + { + Debug.Assert(additionalChars > _arrayToReturnToPool.Length - _pos); + GrowCore((uint)_pos + (uint)additionalChars); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private void Grow() + { + GrowCore((uint)_arrayToReturnToPool.Length + 1); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void GrowCore(uint requiredMinCapacity) + { + uint newCapacity = Math.Max(requiredMinCapacity, Math.Min((uint)_arrayToReturnToPool.Length * 2, 0x3FFFFFDF)); + int arraySize = (int)Math.Clamp(newCapacity, 256, int.MaxValue); + + char[] newArray = STArrayPool.Shared.Rent(arraySize); + _arrayToReturnToPool.AsSpan(.._pos).CopyTo(newArray); + + char[] toReturn = _arrayToReturnToPool; + _arrayToReturnToPool = newArray; + + STArrayPool.Shared.Return(toReturn); + } + + public void Dispose() + { + STArrayPool.Shared.Return(_arrayToReturnToPool); + _arrayToReturnToPool = null; + } + + ~ObjectPropertyList() + { + STArrayPool.Shared.Return(_arrayToReturnToPool); + _arrayToReturnToPool = null; + } +} diff --git a/Projects/Server/Text/ISelfInterpolatedStringHandler.cs b/Projects/Server/Text/ISelfInterpolatedStringHandler.cs new file mode 100644 index 000000000..d9beb2635 --- /dev/null +++ b/Projects/Server/Text/ISelfInterpolatedStringHandler.cs @@ -0,0 +1,71 @@ +/************************************************************************* + * ModernUO * + * Copyright 2019-2022 - ModernUO Development Team * + * Email: hi@modernuo.com * + * File: ISelfInterpolatedStringHandler.cs * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + +using System; +using System.Runtime.CompilerServices; + +namespace Server.Text; + +public interface ISelfInterpolatedStringHandler +{ + public void Add([InterpolatedStringHandlerArgument("")] ref InterpolatedStringHandler handler); + public void InitializeInterpolation(int literalLength, int formattedCount); + public void AppendLiteral(string value); + public void AppendFormatted(T value); + public void AppendFormatted(T value, string? format); + public void AppendFormatted(T value, int alignment); + public void AppendFormatted(T value, int alignment, string? format); + public void AppendFormatted(ReadOnlySpan value); + public void AppendFormatted(ReadOnlySpan value, int alignment, string? format = null); + public void AppendFormatted(object? value, int alignment = 0, string? format = null); + public void AppendFormatted(string? value); + public void AppendFormatted(string? value, int alignment, string? format = null); + + [InterpolatedStringHandler] + public ref struct InterpolatedStringHandler + { + private ISelfInterpolatedStringHandler _parent; + + public InterpolatedStringHandler(int literalLength, int formattedCount, ISelfInterpolatedStringHandler parent) + { + _parent = parent; + _parent.InitializeInterpolation(literalLength, formattedCount); + } + + public void AppendLiteral(string value) => _parent.AppendLiteral(value); + + public void AppendFormatted(T value) => _parent.AppendFormatted(value); + + public void AppendFormatted(T value, string? format) => _parent.AppendFormatted(value, format); + + public void AppendFormatted(T value, int alignment) => _parent.AppendFormatted(value, alignment); + + public void AppendFormatted(T value, int alignment, string? format) => + _parent.AppendFormatted(value, alignment, format); + + public void AppendFormatted(ReadOnlySpan value) => _parent.AppendFormatted(value); + + public void AppendFormatted(ReadOnlySpan value, int alignment, string? format = null) => + _parent.AppendFormatted(value, alignment, format); + + public void AppendFormatted(object? value, int alignment = 0, string? format = null) => + _parent.AppendFormatted(value, alignment, format); + + public void AppendFormatted(string? value) => _parent.AppendFormatted(value); + + public void AppendFormatted(string? value, int alignment, string? format = null) => + _parent.AppendFormatted(value, alignment, format); + } +} diff --git a/Projects/Server/Text/StringHelpers.cs b/Projects/Server/Text/StringHelpers.cs index ab87a90bb..7e22c6341 100644 --- a/Projects/Server/Text/StringHelpers.cs +++ b/Projects/Server/Text/StringHelpers.cs @@ -285,4 +285,22 @@ public static class StringHelpers 4 => MemoryMarshal.Cast(buffer).IndexOf((uint)0) * 4, _ => buffer.IndexOf((byte)0) }; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ReplaceAny(this Span chars, ReadOnlySpan invalidChars, ReadOnlySpan replacementChars) + { + while (true) + { + var indexOf = chars.IndexOfAny(invalidChars); + if (indexOf == -1) + { + break; + } + + var chr = chars[indexOf]; + + chars[indexOf] = replacementChars[invalidChars.IndexOf(chr)]; + chars = chars[(indexOf + 1)..]; + } + } } diff --git a/Projects/Server/Utilities/Utility.cs b/Projects/Server/Utilities/Utility.cs index 34e90c4d1..347568c98 100644 --- a/Projects/Server/Utilities/Utility.cs +++ b/Projects/Server/Utilities/Utility.cs @@ -560,7 +560,7 @@ namespace Server return str; } - using var sb = new ValueStringBuilder(str, stackalloc char[Math.Min(40960, str.Length)]); + using var sb = new ValueStringBuilder(str, stackalloc char[Math.Min(128, str.Length)]); ReadOnlySpan invalid = stackalloc []{ '<', '>', '#' }; ReadOnlySpan replacement = stackalloc []{ '(', ')', '-' }; sb.ReplaceAny(invalid, replacement, 0, sb.Length); @@ -568,6 +568,19 @@ namespace Server return sb.ToString(); } + public static void FixHtml(Span chars) + { + if (chars.Length == 0) + { + return; + } + + ReadOnlySpan invalid = stackalloc []{ '<', '>', '#' }; + ReadOnlySpan replacement = stackalloc []{ '(', ')', '-' }; + + chars.ReplaceAny(invalid, replacement); + } + public static int InsensitiveCompare(string first, string second) => first.InsensitiveCompare(second); public static bool InsensitiveStartsWith(string first, string second) => first.InsensitiveStartsWith(second); diff --git a/Projects/UOContent/Engines/Bulk Orders/Books/BulkOrderBook.cs b/Projects/UOContent/Engines/Bulk Orders/Books/BulkOrderBook.cs index 6ad18909a..b05ede58c 100644 --- a/Projects/UOContent/Engines/Bulk Orders/Books/BulkOrderBook.cs +++ b/Projects/UOContent/Engines/Bulk Orders/Books/BulkOrderBook.cs @@ -258,11 +258,11 @@ namespace Server.Engines.BulkOrders } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); - list.Add(1062344, Entries.Count.ToString()); // Deeds in book: ~1_val~ + list.Add(1062344, $"{Entries.Count}"); // Deeds in book: ~1_val~ if (!string.IsNullOrEmpty(m_BookName)) { diff --git a/Projects/UOContent/Engines/Bulk Orders/LargeBOD.cs b/Projects/UOContent/Engines/Bulk Orders/LargeBOD.cs index c20ec4e86..d16cdc5c6 100644 --- a/Projects/UOContent/Engines/Bulk Orders/LargeBOD.cs +++ b/Projects/UOContent/Engines/Bulk Orders/LargeBOD.cs @@ -38,7 +38,7 @@ namespace Server.Engines.BulkOrders public override int LabelNumber => 1045151; // a bulk order deed - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); @@ -54,11 +54,12 @@ namespace Server.Engines.BulkOrders list.Add(LargeBODGump.GetMaterialNumberFor(Material)); // All items must be made with x material. } - list.Add(1060656, AmountMax.ToString()); // amount to make: ~1_val~ + list.Add(1060656, $"{AmountMax}"); // amount to make: ~1_val~ for (var i = 0; i < _entries.Length; ++i) { - list.Add(1060658 + i, "#{0}\t{1}", _entries[i].Details.Number, _entries[i].Amount); // ~1_val~: ~2_val~ + var entry = _entries[i]; + list.Add(1060658 + i, $"#{entry.Details.Number}\t{entry.Amount}"); // ~1_val~: ~2_val~ } } diff --git a/Projects/UOContent/Engines/Bulk Orders/SmallBOD.cs b/Projects/UOContent/Engines/Bulk Orders/SmallBOD.cs index 8f0489aa1..206a2d4e0 100644 --- a/Projects/UOContent/Engines/Bulk Orders/SmallBOD.cs +++ b/Projects/UOContent/Engines/Bulk Orders/SmallBOD.cs @@ -61,7 +61,7 @@ namespace Server.Engines.BulkOrders public override int LabelNumber => 1045151; // a bulk order deed - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); @@ -77,8 +77,8 @@ namespace Server.Engines.BulkOrders list.Add(SmallBODGump.GetMaterialNumberFor(Material)); // All items must be made with x material. } - list.Add(1060656, AmountMax.ToString()); // amount to make: ~1_val~ - list.Add(1060658, "#{0}\t{1}", m_Number, m_AmountCur); // ~1_val~: ~2_val~ + list.Add(1060656, $"{AmountMax}"); // amount to make: ~1_val~ + list.Add(1060658, $"#{m_Number}\t{m_AmountCur}"); // ~1_val~: ~2_val~ } public override void OnDoubleClick(Mobile from) diff --git a/Projects/UOContent/Engines/CannedEvil/ChampionSpawn.cs b/Projects/UOContent/Engines/CannedEvil/ChampionSpawn.cs index e4a68b0c5..d98063e56 100755 --- a/Projects/UOContent/Engines/CannedEvil/ChampionSpawn.cs +++ b/Projects/UOContent/Engines/CannedEvil/ChampionSpawn.cs @@ -934,21 +934,22 @@ namespace Server.Engines.CannedEvil return new Point3D(X + x, Y + y, Z - 15); } - public override void AddNameProperty(ObjectPropertyList list) + public override void AddNameProperty(IPropertyList list) { list.Add("champion spawn"); } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); if (m_Active) { list.Add(1060742); // active - list.Add(1060658, "Type\t{0}", m_Type); // ~1_val~: ~2_val~ - list.Add(1060659, "Level\t{0}", Level); // ~1_val~: ~2_val~ - list.Add(1060660, "Kills\t{0} of {1} ({2:F1}%)", m_Kills, MaxKills, 100.0 * ((double)m_Kills / MaxKills)); // ~1_val~: ~2_val~ + list.Add(1060658, $"Type\t{m_Type}"); // ~1_val~: ~2_val~ + list.Add(1060659, $"Level\t{Level}"); // ~1_val~: ~2_val~ + var killRatio = 100.0 * ((double)m_Kills / MaxKills); + list.Add(1060660, $"Kills\t{m_Kills} of {MaxKills} ({killRatio:F1}%)"); // ~1_val~: ~2_val~ //list.Add(1060661, "Spawn Range\t{0}", m_SpawnRange); // ~1_val~: ~2_val~ } else @@ -961,11 +962,11 @@ namespace Server.Engines.CannedEvil { if (m_Active) { - LabelTo(from, "{0} (Active; Level: {1}; Kills: {2}/{3})", m_Type, Level, m_Kills, MaxKills); + LabelTo(from, $"{m_Type} (Active; Level: {Level}; Kills: {m_Kills}/{MaxKills})"); } else { - LabelTo(from, "{0} (Inactive)", m_Type); + LabelTo(from, $"{m_Type} (Inactive)"); } } diff --git a/Projects/UOContent/Engines/ConPVP/Gumps/AcceptTeamGump.cs b/Projects/UOContent/Engines/ConPVP/Gumps/AcceptTeamGump.cs index 28a6c2794..f470806bf 100644 --- a/Projects/UOContent/Engines/ConPVP/Gumps/AcceptTeamGump.cs +++ b/Projects/UOContent/Engines/ConPVP/Gumps/AcceptTeamGump.cs @@ -163,23 +163,20 @@ namespace Server.Engines.ConPVP AddBorderedText(35, y, 190, 20, $"Tiebreaker: {tieText}", LabelColor32, BlackColor32); y += 20; - var sdText = "Off"; + string sdText; if (tourney.SuddenDeath > TimeSpan.Zero) { - sdText = $"{(int)tourney.SuddenDeath.TotalMinutes}:{tourney.SuddenDeath.Seconds:D2}"; - - if (tourney.SuddenDeathRounds > 0) - { - sdText = $"{sdText} (first {tourney.SuddenDeathRounds} rounds)"; - } - else - { - sdText = $"{sdText} (all rounds)"; - } + sdText = tourney.SuddenDeathRounds > 0 ? + $"Sudden Death: {(int)tourney.SuddenDeath.TotalMinutes}:{tourney.SuddenDeath.Seconds:D2} (first {tourney.SuddenDeathRounds} rounds)" : + $"Sudden Death: {(int)tourney.SuddenDeath.TotalMinutes}:{tourney.SuddenDeath.Seconds:D2} (all rounds)"; + } + else + { + sdText = "Sudden Death: Off"; } - AddBorderedText(35, y, 240, 20, $"Sudden Death: {sdText}", LabelColor32, BlackColor32); + AddBorderedText(35, y, 240, 20, sdText, LabelColor32, BlackColor32); y += 20; y += 6; diff --git a/Projects/UOContent/Engines/ConPVP/Gumps/ConfirmSignupGump.cs b/Projects/UOContent/Engines/ConPVP/Gumps/ConfirmSignupGump.cs index 04e235ac6..1bd50b67a 100644 --- a/Projects/UOContent/Engines/ConPVP/Gumps/ConfirmSignupGump.cs +++ b/Projects/UOContent/Engines/ConPVP/Gumps/ConfirmSignupGump.cs @@ -169,23 +169,20 @@ namespace Server.Engines.ConPVP AddBorderedText(35, y, 190, 20, $"Tiebreaker: {tieText}", LabelColor32, BlackColor32); y += 20; - var sdText = "Off"; + string sdText; if (tourney.SuddenDeath > TimeSpan.Zero) { - sdText = $"{(int)tourney.SuddenDeath.TotalMinutes}:{tourney.SuddenDeath.Seconds:D2}"; - - if (tourney.SuddenDeathRounds > 0) - { - sdText = $"{sdText} (first {tourney.SuddenDeathRounds} rounds)"; - } - else - { - sdText = $"{sdText} (all rounds)"; - } + sdText = tourney.SuddenDeathRounds > 0 ? + $"Sudden Death: {(int)tourney.SuddenDeath.TotalMinutes}:{tourney.SuddenDeath.Seconds:D2} (first {tourney.SuddenDeathRounds} rounds)" : + $"Sudden Death: {(int)tourney.SuddenDeath.TotalMinutes}:{tourney.SuddenDeath.Seconds:D2} (all rounds)"; + } + else + { + sdText = "Sudden Death: Off"; } - AddBorderedText(35, y, 240, 20, $"Sudden Death: {sdText}", LabelColor32, BlackColor32); + AddBorderedText(35, y, 240, 20, sdText, LabelColor32, BlackColor32); y += 20; y += 6; diff --git a/Projects/UOContent/Engines/ConPVP/Gumps/TournamentBracketGump.cs b/Projects/UOContent/Engines/ConPVP/Gumps/TournamentBracketGump.cs index 9dc149ce8..8ff340ed0 100644 --- a/Projects/UOContent/Engines/ConPVP/Gumps/TournamentBracketGump.cs +++ b/Projects/UOContent/Engines/ConPVP/Gumps/TournamentBracketGump.cs @@ -214,23 +214,20 @@ namespace Server.Engines.ConPVP AddHtml(35, y, 190, 20, $"Tiebreaker: {tieText}"); y += 20; - var sdText = "Off"; + string sdText; if (tourney.SuddenDeath > TimeSpan.Zero) { - sdText = $"{(int)tourney.SuddenDeath.TotalMinutes}:{tourney.SuddenDeath.Seconds:D2}"; - - if (tourney.SuddenDeathRounds > 0) - { - sdText = $"{sdText} (first {tourney.SuddenDeathRounds} rounds)"; - } - else - { - sdText = $"{sdText} (all rounds)"; - } + sdText = tourney.SuddenDeathRounds > 0 ? + $"Sudden Death: {(int)tourney.SuddenDeath.TotalMinutes}:{tourney.SuddenDeath.Seconds:D2} (first {tourney.SuddenDeathRounds} rounds)" : + $"Sudden Death: {(int)tourney.SuddenDeath.TotalMinutes}:{tourney.SuddenDeath.Seconds:D2} (all rounds)"; + } + else + { + sdText = "Sudden Death: Off"; } - AddHtml(35, y, 240, 20, $"Sudden Death: {sdText}"); + AddHtml(35, y, 240, 20, sdText); y += 20; y += 8; diff --git a/Projects/UOContent/Engines/Factions/Items/Sigil.cs b/Projects/UOContent/Engines/Factions/Items/Sigil.cs index 66606eef3..8fab6abd9 100644 --- a/Projects/UOContent/Engines/Factions/Items/Sigil.cs +++ b/Projects/UOContent/Engines/Factions/Items/Sigil.cs @@ -128,7 +128,7 @@ namespace Server.Factions InvalidateProperties(); } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Engines/Factions/Items/Traps/FactionTrapRemovalKit.cs b/Projects/UOContent/Engines/Factions/Items/Traps/FactionTrapRemovalKit.cs index 78dd3c488..364c98c3a 100644 --- a/Projects/UOContent/Engines/Factions/Items/Traps/FactionTrapRemovalKit.cs +++ b/Projects/UOContent/Engines/Factions/Items/Traps/FactionTrapRemovalKit.cs @@ -30,12 +30,12 @@ namespace Server.Factions } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); // NOTE: OSI does not list uses remaining; intentional difference - list.Add(1060584, Charges.ToString()); // uses remaining: ~1_val~ + list.Add(1060584, $"{Charges}"); // uses remaining: ~1_val~ } public override void Serialize(IGenericWriter writer) diff --git a/Projects/UOContent/Engines/Factions/Mobiles/Guards/BaseFactionGuard.cs b/Projects/UOContent/Engines/Factions/Mobiles/Guards/BaseFactionGuard.cs index 5b59ecb6f..c5fe00653 100644 --- a/Projects/UOContent/Engines/Factions/Mobiles/Guards/BaseFactionGuard.cs +++ b/Projects/UOContent/Engines/Factions/Mobiles/Guards/BaseFactionGuard.cs @@ -308,7 +308,7 @@ namespace Server.Factions } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Engines/ML Quests/Items/APersonalLetterAddressedToAhie.cs b/Projects/UOContent/Engines/ML Quests/Items/APersonalLetterAddressedToAhie.cs index 5dccf5f17..fbb09aab1 100644 --- a/Projects/UOContent/Engines/ML Quests/Items/APersonalLetterAddressedToAhie.cs +++ b/Projects/UOContent/Engines/ML Quests/Items/APersonalLetterAddressedToAhie.cs @@ -15,7 +15,7 @@ namespace Server.Items public override bool Nontransferable => true; - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); AddQuestItemProperty(list); diff --git a/Projects/UOContent/Engines/ML Quests/Items/AlchemistsBandage.cs b/Projects/UOContent/Engines/ML Quests/Items/AlchemistsBandage.cs index 116550434..03526c475 100644 --- a/Projects/UOContent/Engines/ML Quests/Items/AlchemistsBandage.cs +++ b/Projects/UOContent/Engines/ML Quests/Items/AlchemistsBandage.cs @@ -17,7 +17,7 @@ namespace Server.Items public override bool Nontransferable => true; - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); AddQuestItemProperty(list); diff --git a/Projects/UOContent/Engines/ML Quests/Items/BasinOfCrystalClearWater.cs b/Projects/UOContent/Engines/ML Quests/Items/BasinOfCrystalClearWater.cs index b4f725563..0f2068339 100644 --- a/Projects/UOContent/Engines/ML Quests/Items/BasinOfCrystalClearWater.cs +++ b/Projects/UOContent/Engines/ML Quests/Items/BasinOfCrystalClearWater.cs @@ -13,7 +13,7 @@ namespace Server.Items public override bool Nontransferable => true; - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); AddQuestItemProperty(list); diff --git a/Projects/UOContent/Engines/ML Quests/Items/BridesLetter.cs b/Projects/UOContent/Engines/ML Quests/Items/BridesLetter.cs index 83f043636..12f897720 100644 --- a/Projects/UOContent/Engines/ML Quests/Items/BridesLetter.cs +++ b/Projects/UOContent/Engines/ML Quests/Items/BridesLetter.cs @@ -13,7 +13,7 @@ namespace Server.Items public override bool Nontransferable => true; - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); AddQuestItemProperty(list); diff --git a/Projects/UOContent/Engines/ML Quests/Items/CompletedTuitionReimbursementForm.cs b/Projects/UOContent/Engines/ML Quests/Items/CompletedTuitionReimbursementForm.cs index 04f706bf7..efc18c8db 100644 --- a/Projects/UOContent/Engines/ML Quests/Items/CompletedTuitionReimbursementForm.cs +++ b/Projects/UOContent/Engines/ML Quests/Items/CompletedTuitionReimbursementForm.cs @@ -13,7 +13,7 @@ namespace Server.Items public override bool Nontransferable => true; - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); AddQuestItemProperty(list); diff --git a/Projects/UOContent/Engines/ML Quests/Items/CrateForSledge.cs b/Projects/UOContent/Engines/ML Quests/Items/CrateForSledge.cs index 033da30ef..5127ee830 100644 --- a/Projects/UOContent/Engines/ML Quests/Items/CrateForSledge.cs +++ b/Projects/UOContent/Engines/ML Quests/Items/CrateForSledge.cs @@ -15,7 +15,7 @@ namespace Server.Items public override bool Nontransferable => true; - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); AddQuestItemProperty(list); diff --git a/Projects/UOContent/Engines/ML Quests/Items/DreadSpiderSilk.cs b/Projects/UOContent/Engines/ML Quests/Items/DreadSpiderSilk.cs index 8583a7ce3..29788c71f 100644 --- a/Projects/UOContent/Engines/ML Quests/Items/DreadSpiderSilk.cs +++ b/Projects/UOContent/Engines/ML Quests/Items/DreadSpiderSilk.cs @@ -17,7 +17,7 @@ namespace Server.Items public override bool Nontransferable => true; - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); AddQuestItemProperty(list); diff --git a/Projects/UOContent/Engines/ML Quests/Items/FragmentOfAMapDelivery.cs b/Projects/UOContent/Engines/ML Quests/Items/FragmentOfAMapDelivery.cs index 18b52b92f..54a62d187 100644 --- a/Projects/UOContent/Engines/ML Quests/Items/FragmentOfAMapDelivery.cs +++ b/Projects/UOContent/Engines/ML Quests/Items/FragmentOfAMapDelivery.cs @@ -13,7 +13,7 @@ namespace Server.Items public override bool Nontransferable => true; - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); AddQuestItemProperty(list); diff --git a/Projects/UOContent/Engines/ML Quests/Items/FriendsOfTheLibraryApplication.cs b/Projects/UOContent/Engines/ML Quests/Items/FriendsOfTheLibraryApplication.cs index 8bde0ff1f..b2eeb94d8 100644 --- a/Projects/UOContent/Engines/ML Quests/Items/FriendsOfTheLibraryApplication.cs +++ b/Projects/UOContent/Engines/ML Quests/Items/FriendsOfTheLibraryApplication.cs @@ -13,7 +13,7 @@ namespace Server.Items public override bool Nontransferable => true; - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); AddQuestItemProperty(list); diff --git a/Projects/UOContent/Engines/ML Quests/Items/GiftForArielle.cs b/Projects/UOContent/Engines/ML Quests/Items/GiftForArielle.cs index a3fe7a704..414d24622 100644 --- a/Projects/UOContent/Engines/ML Quests/Items/GiftForArielle.cs +++ b/Projects/UOContent/Engines/ML Quests/Items/GiftForArielle.cs @@ -14,7 +14,7 @@ namespace Server.Items public override bool Nontransferable => true; - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); AddQuestItemProperty(list); diff --git a/Projects/UOContent/Engines/ML Quests/Items/NotarizedApplication.cs b/Projects/UOContent/Engines/ML Quests/Items/NotarizedApplication.cs index 06d7d5b6e..c27d26f5a 100644 --- a/Projects/UOContent/Engines/ML Quests/Items/NotarizedApplication.cs +++ b/Projects/UOContent/Engines/ML Quests/Items/NotarizedApplication.cs @@ -13,7 +13,7 @@ namespace Server.Items public override bool Nontransferable => true; - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); AddQuestItemProperty(list); diff --git a/Projects/UOContent/Engines/ML Quests/Items/OfficialSealingWax.cs b/Projects/UOContent/Engines/ML Quests/Items/OfficialSealingWax.cs index e540a50d5..9378ebea6 100644 --- a/Projects/UOContent/Engines/ML Quests/Items/OfficialSealingWax.cs +++ b/Projects/UOContent/Engines/ML Quests/Items/OfficialSealingWax.cs @@ -17,7 +17,7 @@ namespace Server.Items public override bool Nontransferable => true; - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); AddQuestItemProperty(list); diff --git a/Projects/UOContent/Engines/ML Quests/Items/PortraitOfTheBride.cs b/Projects/UOContent/Engines/ML Quests/Items/PortraitOfTheBride.cs index 9f2ca6e75..f95740802 100644 --- a/Projects/UOContent/Engines/ML Quests/Items/PortraitOfTheBride.cs +++ b/Projects/UOContent/Engines/ML Quests/Items/PortraitOfTheBride.cs @@ -13,7 +13,7 @@ namespace Server.Items public override bool Nontransferable => true; - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); AddQuestItemProperty(list); diff --git a/Projects/UOContent/Engines/ML Quests/Items/PrismaticAmber.cs b/Projects/UOContent/Engines/ML Quests/Items/PrismaticAmber.cs index dcf074ddd..cae5ea63a 100644 --- a/Projects/UOContent/Engines/ML Quests/Items/PrismaticAmber.cs +++ b/Projects/UOContent/Engines/ML Quests/Items/PrismaticAmber.cs @@ -13,7 +13,7 @@ namespace Server.Items public override int LabelNumber => 1075299; // Prismatic Amber - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); diff --git a/Projects/UOContent/Engines/ML Quests/Items/QuestGiverItem.cs b/Projects/UOContent/Engines/ML Quests/Items/QuestGiverItem.cs index 4389efdaa..652de737e 100644 --- a/Projects/UOContent/Engines/ML Quests/Items/QuestGiverItem.cs +++ b/Projects/UOContent/Engines/ML Quests/Items/QuestGiverItem.cs @@ -27,7 +27,7 @@ namespace Server.Engines.MLQuests.Items public List MLQuests => m_MLQuests ?? (m_MLQuests = MLQuestSystem.FindQuestList(GetType()) ?? MLQuestSystem.EmptyList); - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); @@ -105,7 +105,7 @@ namespace Server.Engines.MLQuests.Items { } - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); diff --git a/Projects/UOContent/Engines/ML Quests/Items/ReginasLetter.cs b/Projects/UOContent/Engines/ML Quests/Items/ReginasLetter.cs index aaf62201b..1759d5b0e 100644 --- a/Projects/UOContent/Engines/ML Quests/Items/ReginasLetter.cs +++ b/Projects/UOContent/Engines/ML Quests/Items/ReginasLetter.cs @@ -13,7 +13,7 @@ namespace Server.Items public override bool Nontransferable => true; - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); AddQuestItemProperty(list); diff --git a/Projects/UOContent/Engines/ML Quests/Items/ReginasRing.cs b/Projects/UOContent/Engines/ML Quests/Items/ReginasRing.cs index d7a40fb3c..2af14cacd 100644 --- a/Projects/UOContent/Engines/ML Quests/Items/ReginasRing.cs +++ b/Projects/UOContent/Engines/ML Quests/Items/ReginasRing.cs @@ -13,7 +13,7 @@ namespace Server.Items public override bool Nontransferable => true; - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); AddQuestItemProperty(list); diff --git a/Projects/UOContent/Engines/ML Quests/Items/SealedNotesForJamal.cs b/Projects/UOContent/Engines/ML Quests/Items/SealedNotesForJamal.cs index 6cdf61405..488be1a84 100644 --- a/Projects/UOContent/Engines/ML Quests/Items/SealedNotesForJamal.cs +++ b/Projects/UOContent/Engines/ML Quests/Items/SealedNotesForJamal.cs @@ -14,7 +14,7 @@ namespace Server.Items public override bool Nontransferable => true; - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); AddQuestItemProperty(list); diff --git a/Projects/UOContent/Engines/ML Quests/Items/SealingWaxOrderAddressedToPetrus.cs b/Projects/UOContent/Engines/ML Quests/Items/SealingWaxOrderAddressedToPetrus.cs index 59b4eb59a..e1783bdd6 100644 --- a/Projects/UOContent/Engines/ML Quests/Items/SealingWaxOrderAddressedToPetrus.cs +++ b/Projects/UOContent/Engines/ML Quests/Items/SealingWaxOrderAddressedToPetrus.cs @@ -13,7 +13,7 @@ namespace Server.Items public override bool Nontransferable => true; - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); AddQuestItemProperty(list); diff --git a/Projects/UOContent/Engines/ML Quests/Items/SignedTuitionReimbursementForm.cs b/Projects/UOContent/Engines/ML Quests/Items/SignedTuitionReimbursementForm.cs index 3094e5769..66c86bbef 100644 --- a/Projects/UOContent/Engines/ML Quests/Items/SignedTuitionReimbursementForm.cs +++ b/Projects/UOContent/Engines/ML Quests/Items/SignedTuitionReimbursementForm.cs @@ -13,7 +13,7 @@ namespace Server.Items public override bool Nontransferable => true; - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); AddQuestItemProperty(list); diff --git a/Projects/UOContent/Engines/ML Quests/Items/SpiritBottle.cs b/Projects/UOContent/Engines/ML Quests/Items/SpiritBottle.cs index 86767928b..e24768807 100644 --- a/Projects/UOContent/Engines/ML Quests/Items/SpiritBottle.cs +++ b/Projects/UOContent/Engines/ML Quests/Items/SpiritBottle.cs @@ -13,7 +13,7 @@ namespace Server.Items public override bool Nontransferable => true; - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); AddQuestItemProperty(list); diff --git a/Projects/UOContent/Engines/ML Quests/Items/TaintedTreeSample.cs b/Projects/UOContent/Engines/ML Quests/Items/TaintedTreeSample.cs index 545aa65ff..f18a0bb99 100644 --- a/Projects/UOContent/Engines/ML Quests/Items/TaintedTreeSample.cs +++ b/Projects/UOContent/Engines/ML Quests/Items/TaintedTreeSample.cs @@ -17,7 +17,7 @@ namespace Server.Items public override bool Nontransferable => true; - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); AddQuestItemProperty(list); diff --git a/Projects/UOContent/Engines/ML Quests/Items/Teleporters.cs b/Projects/UOContent/Engines/ML Quests/Items/Teleporters.cs index dc7262333..e7abdc648 100644 --- a/Projects/UOContent/Engines/ML Quests/Items/Teleporters.cs +++ b/Projects/UOContent/Engines/ML Quests/Items/Teleporters.cs @@ -71,7 +71,7 @@ namespace Server.Engines.MLQuests.Items return false; } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); @@ -179,7 +179,7 @@ namespace Server.Engines.MLQuests.Items return true; } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Engines/ML Quests/Items/TuitionReimbursementForm.cs b/Projects/UOContent/Engines/ML Quests/Items/TuitionReimbursementForm.cs index 7daaa8b72..16740b154 100644 --- a/Projects/UOContent/Engines/ML Quests/Items/TuitionReimbursementForm.cs +++ b/Projects/UOContent/Engines/ML Quests/Items/TuitionReimbursementForm.cs @@ -13,7 +13,7 @@ namespace Server.Items public override bool Nontransferable => true; - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); AddQuestItemProperty(list); diff --git a/Projects/UOContent/Engines/Plants/PlantItem.cs b/Projects/UOContent/Engines/Plants/PlantItem.cs index b99a0f7c7..22061af38 100644 --- a/Projects/UOContent/Engines/Plants/PlantItem.cs +++ b/Projects/UOContent/Engines/Plants/PlantItem.cs @@ -248,7 +248,7 @@ namespace Server.Engines.Plants InvalidateProperties(); } - public override void AddNameProperty(ObjectPropertyList list) + public override void AddNameProperty(IPropertyList list) { if (m_PlantStatus >= PlantStatus.DeadTwigs) { diff --git a/Projects/UOContent/Engines/Plants/Seed.cs b/Projects/UOContent/Engines/Plants/Seed.cs index bb67f9e4b..ef05f343d 100644 --- a/Projects/UOContent/Engines/Plants/Seed.cs +++ b/Projects/UOContent/Engines/Plants/Seed.cs @@ -124,7 +124,7 @@ namespace Server.Engines.Plants return hueInfo.IsBright() ? 1113491 : 1113490; // ~1_amount~ [bright] ~2_val~ seeds } - public override void AddNameProperty(ObjectPropertyList list) + public override void AddNameProperty(IPropertyList list) { list.Add(GetLabel(out var args), args); } diff --git a/Projects/UOContent/Engines/Quests/Collector/Items/Obsidian.cs b/Projects/UOContent/Engines/Quests/Collector/Items/Obsidian.cs index 7806d403d..d70818d0e 100644 --- a/Projects/UOContent/Engines/Quests/Collector/Items/Obsidian.cs +++ b/Projects/UOContent/Engines/Quests/Collector/Items/Obsidian.cs @@ -141,7 +141,7 @@ namespace Server.Engines.Quests.Collector public static string RandomName(Mobile from) => m_Names.RandomElement() ?? from.Name; - public override void AddNameProperty(ObjectPropertyList list) + public override void AddNameProperty(IPropertyList list) { if (m_Quantity < m_Partial) { diff --git a/Projects/UOContent/Engines/Quests/Collector/Items/PaintedImage.cs b/Projects/UOContent/Engines/Quests/Collector/Items/PaintedImage.cs index afd44311f..659036097 100644 --- a/Projects/UOContent/Engines/Quests/Collector/Items/PaintedImage.cs +++ b/Projects/UOContent/Engines/Quests/Collector/Items/PaintedImage.cs @@ -31,7 +31,7 @@ namespace Server.Engines.Quests.Collector } } - public override void AddNameProperty(ObjectPropertyList list) + public override void AddNameProperty(IPropertyList list) { var info = ImageTypeInfo.Get(m_Image); list.Add(1060847, $"#1055126\t#{info.Name}"); // a painted image of: diff --git a/Projects/UOContent/Engines/Quests/Core/Items/HornOfRetreat.cs b/Projects/UOContent/Engines/Quests/Core/Items/HornOfRetreat.cs index 97774aaa1..a16779d0f 100644 --- a/Projects/UOContent/Engines/Quests/Core/Items/HornOfRetreat.cs +++ b/Projects/UOContent/Engines/Quests/Core/Items/HornOfRetreat.cs @@ -43,11 +43,11 @@ namespace Server.Engines.Quests public virtual bool ValidateUse(Mobile from) => true; - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); - list.Add(1060741, m_Charges.ToString()); // charges: ~1_val~ + list.Add(1060741, $"{m_Charges}"); // charges: ~1_val~ } public override void OnDoubleClick(Mobile from) diff --git a/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Items/SchmendrickApprenticeCorpse.cs b/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Items/SchmendrickApprenticeCorpse.cs index 9dfd386d6..1731abbee 100644 --- a/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Items/SchmendrickApprenticeCorpse.cs +++ b/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Items/SchmendrickApprenticeCorpse.cs @@ -70,7 +70,7 @@ namespace Server.Engines.Quests.Haven return new FacialHairInfo(Race.Human.RandomFacialHair(false), m_HairHue); } - public override void AddNameProperty(ObjectPropertyList list) + public override void AddNameProperty(IPropertyList list) { if (ItemID == 0x2006) // Corpse form { diff --git a/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Mobiles/MilitiaFighter.cs b/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Mobiles/MilitiaFighter.cs index 34b3947a6..cf30f30b9 100644 --- a/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Mobiles/MilitiaFighter.cs +++ b/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Mobiles/MilitiaFighter.cs @@ -108,7 +108,7 @@ namespace Server.Engines.Quests.Haven { } - public override void AddNameProperty(ObjectPropertyList list) + public override void AddNameProperty(IPropertyList list) { if (ItemID == 0x2006) // Corpse form { diff --git a/Projects/UOContent/Engines/Quests/Witch Apprentice/Items/HagApprenticeCorpse.cs b/Projects/UOContent/Engines/Quests/Witch Apprentice/Items/HagApprenticeCorpse.cs index dfaa2e6ad..acc83cd2d 100644 --- a/Projects/UOContent/Engines/Quests/Witch Apprentice/Items/HagApprenticeCorpse.cs +++ b/Projects/UOContent/Engines/Quests/Witch Apprentice/Items/HagApprenticeCorpse.cs @@ -39,7 +39,7 @@ namespace Server.Engines.Quests.Hag private static List GetEquipment() => new(); - public override void AddNameProperty(ObjectPropertyList list) + public override void AddNameProperty(IPropertyList list) { list.Add("a charred corpse"); } diff --git a/Projects/UOContent/Engines/Spawners/BaseSpawner.cs b/Projects/UOContent/Engines/Spawners/BaseSpawner.cs index 239b34072..dd1d7a71f 100644 --- a/Projects/UOContent/Engines/Spawners/BaseSpawner.cs +++ b/Projects/UOContent/Engines/Spawners/BaseSpawner.cs @@ -353,11 +353,11 @@ namespace Server.Engines.Spawners from.SendGump(new SpawnerGump(this)); } - public virtual void GetSpawnerProperties(ObjectPropertyList list) + public virtual void GetSpawnerProperties(IPropertyList list) { } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); @@ -365,18 +365,19 @@ namespace Server.Engines.Spawners { list.Add(1060742); // active - list.Add(1060656, m_Count.ToString()); // amount to make: ~1_val~ - list.Add(1061169, m_HomeRange.ToString()); // range ~1_val~ - list.Add(1050039, "walking range:\t{0}", m_WalkingRange); // ~1_NUMBER~ ~2_ITEMNAME~ - list.Add(1053099, "group:\t{0}", m_Group); // ~1_oretype~: ~2_armortype~ - list.Add(1060847, "team:\t{0}", m_Team); // ~1_val~ ~2_val~ - list.Add(1063483, "delay:\t{0} to {1}", m_MinDelay, m_MaxDelay); // ~1_MATERIAL~: ~2_ITEMNAME~ + list.Add(1060656, $"{m_Count}"); // amount to make: ~1_val~ + list.Add(1061169, $"{m_HomeRange}"); // range ~1_val~ + list.Add(1050039, $"walking range:\t{m_WalkingRange}"); // ~1_NUMBER~ ~2_ITEMNAME~ + list.Add(1053099, $"group:\t{m_Group}"); // ~1_oretype~: ~2_armortype~ + list.Add(1060847, $"team:\t{m_Team}"); // ~1_val~ ~2_val~ + list.Add(1063483, $"delay:\t{m_MinDelay} to {m_MaxDelay}"); // ~1_MATERIAL~: ~2_ITEMNAME~ GetSpawnerProperties(list); for (var i = 0; i < 6 && i < Entries.Count; ++i) { - list.Add(1060658 + i, "\t{0}\t{1}", Entries[i].SpawnedName, CountSpawns(Entries[i])); + var entry = Entries[i]; + list.Add(1060658 + i, $"\t{entry.SpawnedName}\t{CountSpawns(entry)}"); } } else @@ -794,7 +795,7 @@ namespace Server.Engines.Spawners } else { - m_Timer?.Stop(); + m_Timer.Stop(); m_Timer.Delay = delay; } diff --git a/Projects/UOContent/Engines/Spawners/RegionSpawner.cs b/Projects/UOContent/Engines/Spawners/RegionSpawner.cs index a7296cee9..f12a332fe 100644 --- a/Projects/UOContent/Engines/Spawners/RegionSpawner.cs +++ b/Projects/UOContent/Engines/Spawners/RegionSpawner.cs @@ -88,13 +88,13 @@ namespace Server.Engines.Spawners json.SetProperty("region", options, SpawnRegion.Name); } - public override void GetSpawnerProperties(ObjectPropertyList list) + public override void GetSpawnerProperties(IPropertyList list) { base.GetSpawnerProperties(list); if (Running && m_SpawnRegion != null) { - list.Add(1076228, "region:\t{0}", m_SpawnRegion.Name); // ~1_DUMMY~ ~2_DUMMY~ + list.Add(1076228, $"region:\t{m_SpawnRegion.Name}"); // ~1_DUMMY~ ~2_DUMMY~ } } diff --git a/Projects/UOContent/Engines/Treasures of Tokuno/BasePigmentsOfTokuno.cs b/Projects/UOContent/Engines/Treasures of Tokuno/BasePigmentsOfTokuno.cs index af63c592b..8fbd3a1d6 100644 --- a/Projects/UOContent/Engines/Treasures of Tokuno/BasePigmentsOfTokuno.cs +++ b/Projects/UOContent/Engines/Treasures of Tokuno/BasePigmentsOfTokuno.cs @@ -113,7 +113,7 @@ namespace Server.Items set { } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); @@ -122,7 +122,7 @@ namespace Server.Items TextDefinition.AddTo(list, m_Label); } - list.Add(1060584, m_UsesRemaining.ToString()); // uses remaining: ~1_val~ + list.Add(1060584, $"{m_UsesRemaining}"); // uses remaining: ~1_val~ } public override void OnDoubleClick(Mobile from) diff --git a/Projects/UOContent/Engines/Treasures of Tokuno/LesserArtifacts.cs b/Projects/UOContent/Engines/Treasures of Tokuno/LesserArtifacts.cs index e7412891c..9289fa0e7 100644 --- a/Projects/UOContent/Engines/Treasures of Tokuno/LesserArtifacts.cs +++ b/Projects/UOContent/Engines/Treasures of Tokuno/LesserArtifacts.cs @@ -713,7 +713,7 @@ namespace Server.Items Utility.Intern(ref m_UrnName); } - public override void AddNameProperty(ObjectPropertyList list) + public override void AddNameProperty(IPropertyList list) { list.Add(1070935, m_UrnName); // Ancient Urn of ~1_name~ } @@ -772,7 +772,7 @@ namespace Server.Items Utility.Intern(ref m_SwordsName); } - public override void AddNameProperty(ObjectPropertyList list) + public override void AddNameProperty(IPropertyList list) { list.Add(1070936, m_SwordsName); // Honorable Swords of ~1_name~ } diff --git a/Projects/UOContent/Engines/Veteran Rewards/Character Statue Maker/CharacterStatue.cs b/Projects/UOContent/Engines/Veteran Rewards/Character Statue Maker/CharacterStatue.cs index 1ce3132cb..12a279ea2 100644 --- a/Projects/UOContent/Engines/Veteran Rewards/Character Statue Maker/CharacterStatue.cs +++ b/Projects/UOContent/Engines/Veteran Rewards/Character Statue Maker/CharacterStatue.cs @@ -128,7 +128,7 @@ namespace Server.Mobiles DisplayPaperdollTo(from); } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); @@ -496,7 +496,7 @@ namespace Server.Mobiles } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Engines/Veteran Rewards/Character Statue Maker/CharacterStatueMaker.cs b/Projects/UOContent/Engines/Veteran Rewards/Character Statue Maker/CharacterStatueMaker.cs index d1f2ab359..b9e7315cd 100644 --- a/Projects/UOContent/Engines/Veteran Rewards/Character Statue Maker/CharacterStatueMaker.cs +++ b/Projects/UOContent/Engines/Veteran Rewards/Character Statue Maker/CharacterStatueMaker.cs @@ -71,7 +71,7 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Holiday Stuff/Halloween/2006/Items/TwilightLantern.cs b/Projects/UOContent/Holiday Stuff/Halloween/2006/Items/TwilightLantern.cs index 5152901d2..039092fac 100644 --- a/Projects/UOContent/Holiday Stuff/Halloween/2006/Items/TwilightLantern.cs +++ b/Projects/UOContent/Holiday Stuff/Halloween/2006/Items/TwilightLantern.cs @@ -12,7 +12,7 @@ namespace Server.Items public override bool AllowEquippedCast(Mobile from) => true; - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Holiday Stuff/Valentine/2011/Items/StValentinesBears.cs b/Projects/UOContent/Holiday Stuff/Valentine/2011/Items/StValentinesBears.cs index 700080df4..ad60231bd 100644 --- a/Projects/UOContent/Holiday Stuff/Valentine/2011/Items/StValentinesBears.cs +++ b/Projects/UOContent/Holiday Stuff/Valentine/2011/Items/StValentinesBears.cs @@ -47,7 +47,7 @@ namespace Server.Items public bool CanSign => !IsSigned || Core.Now <= EditLimit; - public override void AddNameProperty(ObjectPropertyList list) + public override void AddNameProperty(IPropertyList list) { if (_owner != null) { @@ -63,7 +63,7 @@ namespace Server.Items AddLine(list, 1150303, _line3); // [ ~1_LINE2~ ] } - private static void AddLine(ObjectPropertyList list, int cliloc, string line) + private static void AddLine(IPropertyList list, int cliloc, string line) { if (line != null) { diff --git a/Projects/UOContent/Holiday Stuff/Valentine/2012/Items/CupidsArrow.cs b/Projects/UOContent/Holiday Stuff/Valentine/2012/Items/CupidsArrow.cs index 7b302e836..3c292ceda 100644 --- a/Projects/UOContent/Holiday Stuff/Valentine/2012/Items/CupidsArrow.cs +++ b/Projects/UOContent/Holiday Stuff/Valentine/2012/Items/CupidsArrow.cs @@ -27,7 +27,7 @@ namespace Server.Items public bool IsSigned => _from != null && _to != null; - public override void AddNameProperty(ObjectPropertyList list) + public override void AddNameProperty(IPropertyList list) { base.AddNameProperty(list); diff --git a/Projects/UOContent/Items/Addons/AddonComponent.cs b/Projects/UOContent/Items/Addons/AddonComponent.cs index 3cf10fc20..f07f3da2e 100644 --- a/Projects/UOContent/Items/Addons/AddonComponent.cs +++ b/Projects/UOContent/Items/Addons/AddonComponent.cs @@ -160,7 +160,7 @@ namespace Server.Items } } /* - public override void GetProperties(ObjectPropertyList list) => _addon?.GetProperties(list); + public override void GetProperties(IPropertyList list) => _addon?.GetProperties(list); public override void GetContextMenuEntries(Mobile from, List list) => _addon?.GetContextMenuEntries(from, list); diff --git a/Projects/UOContent/Items/Addons/AddonContainerComponent.cs b/Projects/UOContent/Items/Addons/AddonContainerComponent.cs index 7c612fd03..6e7bf4b08 100644 --- a/Projects/UOContent/Items/Addons/AddonContainerComponent.cs +++ b/Projects/UOContent/Items/Addons/AddonContainerComponent.cs @@ -77,7 +77,7 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) => _addon?.GetProperties(list); + public override void GetProperties(IPropertyList list) => _addon?.GetProperties(list); public override void GetContextMenuEntries(Mobile from, List list) => _addon?.GetContextMenuEntries(from, list); diff --git a/Projects/UOContent/Items/Addons/BaseAddonContainer.cs b/Projects/UOContent/Items/Addons/BaseAddonContainer.cs index 547c4900c..3cf06af23 100644 --- a/Projects/UOContent/Items/Addons/BaseAddonContainer.cs +++ b/Projects/UOContent/Items/Addons/BaseAddonContainer.cs @@ -168,7 +168,7 @@ namespace Server.Items base.OnDelete(); } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Addons/BaseAddonContainerDeed.cs b/Projects/UOContent/Items/Addons/BaseAddonContainerDeed.cs index dc751fe0a..17c9fba16 100644 --- a/Projects/UOContent/Items/Addons/BaseAddonContainerDeed.cs +++ b/Projects/UOContent/Items/Addons/BaseAddonContainerDeed.cs @@ -97,7 +97,7 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Aquarium/Aquarium.cs b/Projects/UOContent/Items/Aquarium/Aquarium.cs index d69041f5d..1671139bd 100644 --- a/Projects/UOContent/Items/Aquarium/Aquarium.cs +++ b/Projects/UOContent/Items/Aquarium/Aquarium.cs @@ -364,18 +364,18 @@ namespace Server.Items } } - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); if (_vacationLeft > 0) { - list.Add(1074430, _vacationLeft.ToString()); // Vacation days left: ~1_DAYS + list.Add(1074430, $"{_vacationLeft}"); // Vacation days left: ~1_DAYS } if (_events.Count > 0) { - list.Add(1074426, _events.Count.ToString()); // ~1_NUM~ event(s) to view! + list.Add(1074426, $"{_events.Count}"); // ~1_NUM~ event(s) to view! } if (_rewardAvailable) @@ -383,60 +383,54 @@ namespace Server.Items list.Add(1074362); // A reward is available! } - list.Add(1074247, "{0}\t{1}", LiveCreatures, MaxLiveCreatures); // Live Creatures: ~1_NUM~ / ~2_MAX~ + list.Add(1074247, $"{LiveCreatures}\t{MaxLiveCreatures}"); // Live Creatures: ~1_NUM~ / ~2_MAX~ var dead = DeadCreatures; if (dead > 0) { - list.Add(1074248, dead.ToString()); // Dead Creatures: ~1_NUM~ + list.Add(1074248, $"{dead}"); // Dead Creatures: ~1_NUM~ } var decorations = Items.Count - LiveCreatures - dead; if (decorations > 0) { - list.Add(1074249, decorations.ToString()); // Decorations: ~1_NUM~ + list.Add(1074249, $"{decorations}"); // Decorations: ~1_NUM~ } - list.Add(1074250, "#{0}", FoodNumber()); // Food state: ~1_STATE~ - list.Add(1074251, "#{0}", WaterNumber()); // Water state: ~1_STATE~ + list.Add(1074250, $"#{FoodNumber()}"); // Food state: ~1_STATE~ + list.Add(1074251, $"#{WaterNumber()}"); // Water state: ~1_STATE~ if (_food.State == (int)FoodState.Dead) { - list.Add(1074577, "{0}\t{1}", _food.Added, _food.Improve); // Food Added: ~1_CUR~ Needed: ~2_NEED~ + list.Add(1074577, $"{_food.Added}\t{_food.Improve}"); // Food Added: ~1_CUR~ Needed: ~2_NEED~ } else if (_food.State == (int)FoodState.Overfed) { - list.Add(1074577, "{0}\t{1}", _food.Added, _food.Maintain); // Food Added: ~1_CUR~ Needed: ~2_NEED~ + list.Add(1074577, $"{_food.Added}\t{_food.Maintain}"); // Food Added: ~1_CUR~ Needed: ~2_NEED~ } else { list.Add( 1074253, // Food Added: ~1_CUR~ Feed: ~2_NEED~ Improve: ~3_GROW~ - "{0}\t{1}\t{2}", - _food.Added, - _food.Maintain, - _food.Improve + $"{_food.Added}\t{_food.Maintain}\t{_food.Improve}" ); } if (_water.State == (int)WaterState.Dead) { - list.Add(1074578, "{0}\t{1}", _water.Added, _water.Improve); // Water Added: ~1_CUR~ Needed: ~2_NEED~ + list.Add(1074578, $"{_water.Added}\t{_water.Improve}"); // Water Added: ~1_CUR~ Needed: ~2_NEED~ } else if (_water.State == (int)WaterState.Strong) { - list.Add(1074578, "{0}\t{1}", _water.Added, _water.Maintain); // Water Added: ~1_CUR~ Needed: ~2_NEED~ + list.Add(1074578, $"{_water.Added}\t{_water.Maintain}"); // Water Added: ~1_CUR~ Needed: ~2_NEED~ } else { list.Add( 1074254, // Water Added: ~1_CUR~ Maintain: ~2_NEED~ Improve: ~3_GROW~ - "{0}\t{1}\t{2}", - _water.Added, - _water.Maintain, - _water.Improve + $"{_water.Added}\t{_water.Maintain}\t{_water.Improve}" ); } } diff --git a/Projects/UOContent/Items/Aquarium/AquariumFishingNet.cs b/Projects/UOContent/Items/Aquarium/AquariumFishingNet.cs index 363351a13..d1da09a97 100644 --- a/Projects/UOContent/Items/Aquarium/AquariumFishingNet.cs +++ b/Projects/UOContent/Items/Aquarium/AquariumFishingNet.cs @@ -15,7 +15,7 @@ namespace Server.Items public override bool RequireDeepWater => false; - protected override void AddNetProperties(ObjectPropertyList list) + protected override void AddNetProperties(IPropertyList list) { } diff --git a/Projects/UOContent/Items/Aquarium/BaseFish.cs b/Projects/UOContent/Items/Aquarium/BaseFish.cs index a3bfdc2aa..358bd3b4b 100644 --- a/Projects/UOContent/Items/Aquarium/BaseFish.cs +++ b/Projects/UOContent/Items/Aquarium/BaseFish.cs @@ -60,7 +60,7 @@ namespace Server.Items return Dead ? 1073623 : 1073622; // A [dead/live] aquarium creature } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Aquarium/FishBowl.cs b/Projects/UOContent/Items/Aquarium/FishBowl.cs index d180b85fb..810078b3a 100644 --- a/Projects/UOContent/Items/Aquarium/FishBowl.cs +++ b/Projects/UOContent/Items/Aquarium/FishBowl.cs @@ -78,7 +78,7 @@ namespace Server.Items return base.CheckLift(from, item, ref reject); } - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); @@ -88,7 +88,7 @@ namespace Server.Items if (fish != null) { - list.Add(1074494, "#{0}", fish.LabelNumber); // Contains: ~1_CREATURE~ + list.Add(1074494, $"#{fish.LabelNumber}"); // Contains: ~1_CREATURE~ } } } diff --git a/Projects/UOContent/Items/Aquarium/Rewards/AquariumMessage.cs b/Projects/UOContent/Items/Aquarium/Rewards/AquariumMessage.cs index 86d5dadb8..219135b62 100644 --- a/Projects/UOContent/Items/Aquarium/Rewards/AquariumMessage.cs +++ b/Projects/UOContent/Items/Aquarium/Rewards/AquariumMessage.cs @@ -12,7 +12,7 @@ namespace Server.Items public override int LabelNumber => 1073894; // Message in a Bottle - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); diff --git a/Projects/UOContent/Items/Aquarium/Rewards/CaptainBlackheartsFishingPole.cs b/Projects/UOContent/Items/Aquarium/Rewards/CaptainBlackheartsFishingPole.cs index ede935971..f46d8d9ac 100644 --- a/Projects/UOContent/Items/Aquarium/Rewards/CaptainBlackheartsFishingPole.cs +++ b/Projects/UOContent/Items/Aquarium/Rewards/CaptainBlackheartsFishingPole.cs @@ -12,7 +12,7 @@ namespace Server.Items public override int LabelNumber => 1074571; // Captain Blackheart's Fishing Pole - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); diff --git a/Projects/UOContent/Items/Aquarium/Rewards/CraftysFishingHat.cs b/Projects/UOContent/Items/Aquarium/Rewards/CraftysFishingHat.cs index 01dd1366f..fb5b91174 100644 --- a/Projects/UOContent/Items/Aquarium/Rewards/CraftysFishingHat.cs +++ b/Projects/UOContent/Items/Aquarium/Rewards/CraftysFishingHat.cs @@ -21,7 +21,7 @@ namespace Server.Items public override int InitMinHits => 20; public override int InitMaxHits => 30; - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); diff --git a/Projects/UOContent/Items/Aquarium/Rewards/FishBones.cs b/Projects/UOContent/Items/Aquarium/Rewards/FishBones.cs index d87e24503..149802bfc 100644 --- a/Projects/UOContent/Items/Aquarium/Rewards/FishBones.cs +++ b/Projects/UOContent/Items/Aquarium/Rewards/FishBones.cs @@ -13,7 +13,7 @@ namespace Server.Items public override int LabelNumber => 1074601; // Fish bones public override double DefaultWeight => 1.0; - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); diff --git a/Projects/UOContent/Items/Aquarium/Rewards/IslandStatue.cs b/Projects/UOContent/Items/Aquarium/Rewards/IslandStatue.cs index c78a92cb5..cd4362581 100644 --- a/Projects/UOContent/Items/Aquarium/Rewards/IslandStatue.cs +++ b/Projects/UOContent/Items/Aquarium/Rewards/IslandStatue.cs @@ -13,7 +13,7 @@ namespace Server.Items public override int LabelNumber => 1074600; // An island statue public override double DefaultWeight => 1.0; - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); diff --git a/Projects/UOContent/Items/Aquarium/Rewards/Shell.cs b/Projects/UOContent/Items/Aquarium/Rewards/Shell.cs index c5ffeb1bb..451c20fef 100644 --- a/Projects/UOContent/Items/Aquarium/Rewards/Shell.cs +++ b/Projects/UOContent/Items/Aquarium/Rewards/Shell.cs @@ -13,7 +13,7 @@ namespace Server.Items public override int LabelNumber => 1074598; // A shell public override double DefaultWeight => 1.0; - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); diff --git a/Projects/UOContent/Items/Aquarium/Rewards/ToyBoat.cs b/Projects/UOContent/Items/Aquarium/Rewards/ToyBoat.cs index fa28f994f..be2346c4a 100644 --- a/Projects/UOContent/Items/Aquarium/Rewards/ToyBoat.cs +++ b/Projects/UOContent/Items/Aquarium/Rewards/ToyBoat.cs @@ -14,7 +14,7 @@ namespace Server.Items public override int LabelNumber => 1074363; // A toy boat public override double DefaultWeight => 1.0; - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); diff --git a/Projects/UOContent/Items/Aquarium/Rewards/WaterloggedBoots.cs b/Projects/UOContent/Items/Aquarium/Rewards/WaterloggedBoots.cs index 973207bc2..ae50b2e81 100644 --- a/Projects/UOContent/Items/Aquarium/Rewards/WaterloggedBoots.cs +++ b/Projects/UOContent/Items/Aquarium/Rewards/WaterloggedBoots.cs @@ -24,7 +24,7 @@ namespace Server.Items public override int LabelNumber => 1074364; // Waterlogged boots - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); diff --git a/Projects/UOContent/Items/Aquarium/VacationWafer.cs b/Projects/UOContent/Items/Aquarium/VacationWafer.cs index 9f4f5707a..b12494255 100644 --- a/Projects/UOContent/Items/Aquarium/VacationWafer.cs +++ b/Projects/UOContent/Items/Aquarium/VacationWafer.cs @@ -14,11 +14,11 @@ namespace Server.Items public override int LabelNumber => 1074431; // An aquarium flake sphere - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); - list.Add(1074432, VacationDays.ToString()); // Vacation days: ~1_DAYS~ + list.Add(1074432, $"{VacationDays}"); // Vacation days: ~1_DAYS~ } } } diff --git a/Projects/UOContent/Items/Armor/BaseArmor.cs b/Projects/UOContent/Items/Armor/BaseArmor.cs index ae821b7ee..026eb0dc2 100644 --- a/Projects/UOContent/Items/Armor/BaseArmor.cs +++ b/Projects/UOContent/Items/Armor/BaseArmor.cs @@ -1223,9 +1223,7 @@ namespace Server.Items base.OnRemoved(parent); } - private string GetNameString() => Name ?? $"#{LabelNumber}"; - - public override void AddNameProperty(ObjectPropertyList list) + public override void AddNameProperty(IPropertyList list) { var oreType = _rawResource switch { @@ -1249,31 +1247,26 @@ namespace Server.Items _ => 0 }; - if (_quality == ArmorQuality.Exceptional) + var name = Name; + + if (oreType != 0) { - if (oreType != 0) - { - list.Add(1053100, "#{0}\t{1}", oreType, GetNameString()); // exceptional ~1_oretype~ ~2_armortype~ - } - else - { - list.Add(1050040, GetNameString()); // exceptional ~1_ITEMNAME~ - } + list.Add( + _quality == ArmorQuality.Exceptional ? 1053100 : 1053099, + name != null ? $"#{oreType}\t{Name}" : $"#{oreType}\t#{LabelNumber}" + ); + } + else if (_quality == ArmorQuality.Exceptional) + { + list.Add(1050040, name ?? $"#{LabelNumber}"); // exceptional ~1_ITEMNAME~ + } + else if (name == null) + { + list.Add(LabelNumber); } else { - if (oreType != 0) - { - list.Add(1053099, "#{0}\t{1}", oreType, GetNameString()); // ~1_oretype~ ~2_armortype~ - } - else if (Name == null) - { - list.Add(LabelNumber); - } - else - { - list.Add(Name); - } + list.Add(Name); } } @@ -1289,7 +1282,7 @@ namespace Server.Items public virtual int GetLuckBonus() => CraftResources.GetInfo(_rawResource)?.AttributeInfo?.ArmorLuck ?? 0; - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); @@ -1319,72 +1312,72 @@ namespace Server.Items if ((prop = ArtifactRarity) > 0) { - list.Add(1061078, prop.ToString()); // artifact rarity ~1_val~ + list.Add(1061078, $"{prop}"); // artifact rarity ~1_val~ } if ((prop = Attributes.WeaponDamage) != 0) { - list.Add(1060401, prop.ToString()); // damage increase ~1_val~% + list.Add(1060401, $"{prop}"); // damage increase ~1_val~% } if ((prop = Attributes.DefendChance) != 0) { - list.Add(1060408, prop.ToString()); // defense chance increase ~1_val~% + list.Add(1060408, $"{prop}"); // defense chance increase ~1_val~% } if ((prop = Attributes.BonusDex) != 0) { - list.Add(1060409, prop.ToString()); // dexterity bonus ~1_val~ + list.Add(1060409, $"{prop}"); // dexterity bonus ~1_val~ } if ((prop = Attributes.EnhancePotions) != 0) { - list.Add(1060411, prop.ToString()); // enhance potions ~1_val~% + list.Add(1060411, $"{prop}"); // enhance potions ~1_val~% } if ((prop = Attributes.CastRecovery) != 0) { - list.Add(1060412, prop.ToString()); // faster cast recovery ~1_val~ + list.Add(1060412, $"{prop}"); // faster cast recovery ~1_val~ } if ((prop = Attributes.CastSpeed) != 0) { - list.Add(1060413, prop.ToString()); // faster casting ~1_val~ + list.Add(1060413, $"{prop}"); // faster casting ~1_val~ } if ((prop = Attributes.AttackChance) != 0) { - list.Add(1060415, prop.ToString()); // hit chance increase ~1_val~% + list.Add(1060415, $"{prop}"); // hit chance increase ~1_val~% } if ((prop = Attributes.BonusHits) != 0) { - list.Add(1060431, prop.ToString()); // hit point increase ~1_val~ + list.Add(1060431, $"{prop}"); // hit point increase ~1_val~ } if ((prop = Attributes.BonusInt) != 0) { - list.Add(1060432, prop.ToString()); // intelligence bonus ~1_val~ + list.Add(1060432, $"{prop}"); // intelligence bonus ~1_val~ } if ((prop = Attributes.LowerManaCost) != 0) { - list.Add(1060433, prop.ToString()); // lower mana cost ~1_val~% + list.Add(1060433, $"{prop}"); // lower mana cost ~1_val~% } if ((prop = Attributes.LowerRegCost) != 0) { - list.Add(1060434, prop.ToString()); // lower reagent cost ~1_val~% + list.Add(1060434, $"{prop}"); // lower reagent cost ~1_val~% } if ((prop = GetLowerStatReq()) != 0) { - list.Add(1060435, prop.ToString()); // lower requirements ~1_val~% + list.Add(1060435, $"{prop}"); // lower requirements ~1_val~% } if ((prop = GetLuckBonus() + Attributes.Luck) != 0) { - list.Add(1060436, prop.ToString()); // luck ~1_val~ + list.Add(1060436, $"{prop}"); // luck ~1_val~ } if (ArmorAttributes.MageArmor != 0) @@ -1394,12 +1387,12 @@ namespace Server.Items if ((prop = Attributes.BonusMana) != 0) { - list.Add(1060439, prop.ToString()); // mana increase ~1_val~ + list.Add(1060439, $"{prop}"); // mana increase ~1_val~ } if ((prop = Attributes.RegenMana) != 0) { - list.Add(1060440, prop.ToString()); // mana regeneration ~1_val~ + list.Add(1060440, $"{prop}"); // mana regeneration ~1_val~ } if (Attributes.NightSight != 0) @@ -1409,22 +1402,22 @@ namespace Server.Items if ((prop = Attributes.ReflectPhysical) != 0) { - list.Add(1060442, prop.ToString()); // reflect physical damage ~1_val~% + list.Add(1060442, $"{prop}"); // reflect physical damage ~1_val~% } if ((prop = Attributes.RegenStam) != 0) { - list.Add(1060443, prop.ToString()); // stamina regeneration ~1_val~ + list.Add(1060443, $"{prop}"); // stamina regeneration ~1_val~ } if ((prop = Attributes.RegenHits) != 0) { - list.Add(1060444, prop.ToString()); // hit point regeneration ~1_val~ + list.Add(1060444, $"{prop}"); // hit point regeneration ~1_val~ } if ((prop = ArmorAttributes.SelfRepair) != 0) { - list.Add(1060450, prop.ToString()); // self repair ~1_val~ + list.Add(1060450, $"{prop}"); // self repair ~1_val~ } if (Attributes.SpellChanneling != 0) @@ -1434,44 +1427,44 @@ namespace Server.Items if ((prop = Attributes.SpellDamage) != 0) { - list.Add(1060483, prop.ToString()); // spell damage increase ~1_val~% + list.Add(1060483, $"{prop}"); // spell damage increase ~1_val~% } if ((prop = Attributes.BonusStam) != 0) { - list.Add(1060484, prop.ToString()); // stamina increase ~1_val~ + list.Add(1060484, $"{prop}"); // stamina increase ~1_val~ } if ((prop = Attributes.BonusStr) != 0) { - list.Add(1060485, prop.ToString()); // strength bonus ~1_val~ + list.Add(1060485, $"{prop}"); // strength bonus ~1_val~ } if ((prop = Attributes.WeaponSpeed) != 0) { - list.Add(1060486, prop.ToString()); // swing speed increase ~1_val~% + list.Add(1060486, $"{prop}"); // swing speed increase ~1_val~% } if (Core.ML && (prop = Attributes.IncreasedKarmaLoss) != 0) { - list.Add(1075210, prop.ToString()); // Increased Karma Loss ~1val~% + list.Add(1075210, $"{prop}"); // Increased Karma Loss ~1val~% } AddResistanceProperties(list); if ((prop = GetDurabilityBonus()) > 0) { - list.Add(1060410, prop.ToString()); // durability ~1_val~% + list.Add(1060410, $"{prop}"); // durability ~1_val~% } if ((prop = ComputeStatReq(StatType.Str)) > 0) { - list.Add(1061170, prop.ToString()); // strength requirement ~1_val~ + list.Add(1061170, $"{prop}"); // strength requirement ~1_val~ } if (_hitPoints >= 0 && _maxHitPoints > 0) { - list.Add(1060639, "{0}\t{1}", _hitPoints, _maxHitPoints); // durability ~1_val~ / ~2_val~ + list.Add(1060639, $"{_hitPoints}\t{_maxHitPoints}"); // durability ~1_val~ / ~2_val~ } } diff --git a/Projects/UOContent/Items/Armor/Glasses/ElvenGlasses.cs b/Projects/UOContent/Items/Armor/Glasses/ElvenGlasses.cs index c9140977a..3469820c0 100644 --- a/Projects/UOContent/Items/Armor/Glasses/ElvenGlasses.cs +++ b/Projects/UOContent/Items/Armor/Glasses/ElvenGlasses.cs @@ -42,7 +42,7 @@ namespace Server.Items [SerializableFieldDefault(0)] private AosWeaponAttributes WeaponAttributesDefaultValue() => new(this); - public override void AppendChildNameProperties(ObjectPropertyList list) + public override void AppendChildNameProperties(IPropertyList list) { base.AppendChildNameProperties(list); @@ -50,77 +50,77 @@ namespace Server.Items if ((prop = _weaponAttributes.HitColdArea) != 0) { - list.Add(1060416, prop.ToString()); // hit cold area ~1_val~% + list.Add(1060416, $"{prop}"); // hit cold area ~1_val~% } if ((prop = _weaponAttributes.HitDispel) != 0) { - list.Add(1060417, prop.ToString()); // hit dispel ~1_val~% + list.Add(1060417, $"{prop}"); // hit dispel ~1_val~% } if ((prop = _weaponAttributes.HitEnergyArea) != 0) { - list.Add(1060418, prop.ToString()); // hit energy area ~1_val~% + list.Add(1060418, $"{prop}"); // hit energy area ~1_val~% } if ((prop = _weaponAttributes.HitFireArea) != 0) { - list.Add(1060419, prop.ToString()); // hit fire area ~1_val~% + list.Add(1060419, $"{prop}"); // hit fire area ~1_val~% } if ((prop = _weaponAttributes.HitFireball) != 0) { - list.Add(1060420, prop.ToString()); // hit fireball ~1_val~% + list.Add(1060420, $"{prop}"); // hit fireball ~1_val~% } if ((prop = _weaponAttributes.HitHarm) != 0) { - list.Add(1060421, prop.ToString()); // hit harm ~1_val~% + list.Add(1060421, $"{prop}"); // hit harm ~1_val~% } if ((prop = _weaponAttributes.HitLeechHits) != 0) { - list.Add(1060422, prop.ToString()); // hit life leech ~1_val~% + list.Add(1060422, $"{prop}"); // hit life leech ~1_val~% } if ((prop = _weaponAttributes.HitLightning) != 0) { - list.Add(1060423, prop.ToString()); // hit lightning ~1_val~% + list.Add(1060423, $"{prop}"); // hit lightning ~1_val~% } if ((prop = _weaponAttributes.HitLowerAttack) != 0) { - list.Add(1060424, prop.ToString()); // hit lower attack ~1_val~% + list.Add(1060424, $"{prop}"); // hit lower attack ~1_val~% } if ((prop = _weaponAttributes.HitLowerDefend) != 0) { - list.Add(1060425, prop.ToString()); // hit lower defense ~1_val~% + list.Add(1060425, $"{prop}"); // hit lower defense ~1_val~% } if ((prop = _weaponAttributes.HitMagicArrow) != 0) { - list.Add(1060426, prop.ToString()); // hit magic arrow ~1_val~% + list.Add(1060426, $"{prop}"); // hit magic arrow ~1_val~% } if ((prop = _weaponAttributes.HitLeechMana) != 0) { - list.Add(1060427, prop.ToString()); // hit mana leech ~1_val~% + list.Add(1060427, $"{prop}"); // hit mana leech ~1_val~% } if ((prop = _weaponAttributes.HitPhysicalArea) != 0) { - list.Add(1060428, prop.ToString()); // hit physical area ~1_val~% + list.Add(1060428, $"{prop}"); // hit physical area ~1_val~% } if ((prop = _weaponAttributes.HitPoisonArea) != 0) { - list.Add(1060429, prop.ToString()); // hit poison area ~1_val~% + list.Add(1060429, $"{prop}"); // hit poison area ~1_val~% } if ((prop = _weaponAttributes.HitLeechStam) != 0) { - list.Add(1060430, prop.ToString()); // hit stamina leech ~1_val~% + list.Add(1060430, $"{prop}"); // hit stamina leech ~1_val~% } } } diff --git a/Projects/UOContent/Items/Armor/Leather/LeafGloves.cs b/Projects/UOContent/Items/Armor/Leather/LeafGloves.cs index 5698e6cd9..fc8028be6 100644 --- a/Projects/UOContent/Items/Armor/Leather/LeafGloves.cs +++ b/Projects/UOContent/Items/Armor/Leather/LeafGloves.cs @@ -89,13 +89,13 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); if (IsArcane) { - list.Add(1061837, "{0}\t{1}", _curArcaneCharges, _maxArcaneCharges); // arcane charges: ~1_val~ / ~2_val~ + list.Add(1061837, $"{_curArcaneCharges}\t{_maxArcaneCharges}"); // arcane charges: ~1_val~ / ~2_val~ } } diff --git a/Projects/UOContent/Items/Armor/Leather/LeatherGloves.cs b/Projects/UOContent/Items/Armor/Leather/LeatherGloves.cs index 7b0a8a2c0..ef8005160 100644 --- a/Projects/UOContent/Items/Armor/Leather/LeatherGloves.cs +++ b/Projects/UOContent/Items/Armor/Leather/LeatherGloves.cs @@ -88,13 +88,13 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); if (IsArcane) { - list.Add(1061837, "{0}\t{1}", _curArcaneCharges, _maxArcaneCharges); // arcane charges: ~1_val~ / ~2_val~ + list.Add(1061837, $"{_curArcaneCharges}\t{_maxArcaneCharges}"); // arcane charges: ~1_val~ / ~2_val~ } } diff --git a/Projects/UOContent/Items/Books/BaseBook.cs b/Projects/UOContent/Items/Books/BaseBook.cs index 85f62eee1..ffd4ddd0b 100644 --- a/Projects/UOContent/Items/Books/BaseBook.cs +++ b/Projects/UOContent/Items/Books/BaseBook.cs @@ -174,7 +174,7 @@ namespace Server.Items } } - public override void AddNameProperty(ObjectPropertyList list) + public override void AddNameProperty(IPropertyList list) { if (!string.IsNullOrEmpty(_title)) { diff --git a/Projects/UOContent/Items/Books/Defined/FropozJournal.cs b/Projects/UOContent/Items/Books/Defined/FropozJournal.cs index 9051e678a..5fdbf1640 100644 --- a/Projects/UOContent/Items/Books/Defined/FropozJournal.cs +++ b/Projects/UOContent/Items/Books/Defined/FropozJournal.cs @@ -137,7 +137,7 @@ namespace Server.Items public override BookContent DefaultContent => Content; - public override void AddNameProperty(ObjectPropertyList list) + public override void AddNameProperty(IPropertyList list) { list.Add("Fropoz's Journal"); } diff --git a/Projects/UOContent/Items/Books/Defined/KaburJournal.cs b/Projects/UOContent/Items/Books/Defined/KaburJournal.cs index fbbad7317..7fa55e582 100644 --- a/Projects/UOContent/Items/Books/Defined/KaburJournal.cs +++ b/Projects/UOContent/Items/Books/Defined/KaburJournal.cs @@ -216,7 +216,7 @@ namespace Server.Items public override BookContent DefaultContent => Content; - public override void AddNameProperty(ObjectPropertyList list) + public override void AddNameProperty(IPropertyList list) { list.Add("Khabur's Journal"); } diff --git a/Projects/UOContent/Items/Books/Defined/TranslatedGargoyleJournal.cs b/Projects/UOContent/Items/Books/Defined/TranslatedGargoyleJournal.cs index 735ecc9e0..f7f46ad6f 100644 --- a/Projects/UOContent/Items/Books/Defined/TranslatedGargoyleJournal.cs +++ b/Projects/UOContent/Items/Books/Defined/TranslatedGargoyleJournal.cs @@ -118,7 +118,7 @@ namespace Server.Items public override BookContent DefaultContent => Content; - public override void AddNameProperty(ObjectPropertyList list) + public override void AddNameProperty(IPropertyList list) { list.Add("Translated Gargoyle Journal"); } diff --git a/Projects/UOContent/Items/Clothing/BaseClothing.cs b/Projects/UOContent/Items/Clothing/BaseClothing.cs index e993de5ed..0de3beadc 100644 --- a/Projects/UOContent/Items/Clothing/BaseClothing.cs +++ b/Projects/UOContent/Items/Clothing/BaseClothing.cs @@ -662,9 +662,7 @@ namespace Server.Items }; } - private string GetNameString() => Name ?? $"#{LabelNumber}"; - - public override void AddNameProperty(ObjectPropertyList list) + public override void AddNameProperty(IPropertyList list) { var oreType = _rawResource switch { @@ -688,21 +686,23 @@ namespace Server.Items _ => 0 }; + var name = Name; + if (oreType != 0) { - list.Add(1053099, "#{0}\t{1}", oreType, GetNameString()); // ~1_oretype~ ~2_armortype~ + list.Add(1053099, name != null ? $"#{oreType}\t{name}" : $"#{oreType}\t#{LabelNumber}"); // ~1_oretype~ ~2_armortype~ } - else if (Name == null) + else if (name == null) { list.Add(LabelNumber); } else { - list.Add(Name); + list.Add(name); } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); @@ -737,72 +737,72 @@ namespace Server.Items if ((prop = ArtifactRarity) > 0) { - list.Add(1061078, prop.ToString()); // artifact rarity ~1_val~ + list.Add(1061078, $"{prop}"); // artifact rarity ~1_val~ } if ((prop = Attributes.WeaponDamage) != 0) { - list.Add(1060401, prop.ToString()); // damage increase ~1_val~% + list.Add(1060401, $"{prop}"); // damage increase ~1_val~% } if ((prop = Attributes.DefendChance) != 0) { - list.Add(1060408, prop.ToString()); // defense chance increase ~1_val~% + list.Add(1060408, $"{prop}"); // defense chance increase ~1_val~% } if ((prop = Attributes.BonusDex) != 0) { - list.Add(1060409, prop.ToString()); // dexterity bonus ~1_val~ + list.Add(1060409, $"{prop}"); // dexterity bonus ~1_val~ } if ((prop = Attributes.EnhancePotions) != 0) { - list.Add(1060411, prop.ToString()); // enhance potions ~1_val~% + list.Add(1060411, $"{prop}"); // enhance potions ~1_val~% } if ((prop = Attributes.CastRecovery) != 0) { - list.Add(1060412, prop.ToString()); // faster cast recovery ~1_val~ + list.Add(1060412, $"{prop}"); // faster cast recovery ~1_val~ } if ((prop = Attributes.CastSpeed) != 0) { - list.Add(1060413, prop.ToString()); // faster casting ~1_val~ + list.Add(1060413, $"{prop}"); // faster casting ~1_val~ } if ((prop = Attributes.AttackChance) != 0) { - list.Add(1060415, prop.ToString()); // hit chance increase ~1_val~% + list.Add(1060415, $"{prop}"); // hit chance increase ~1_val~% } if ((prop = Attributes.BonusHits) != 0) { - list.Add(1060431, prop.ToString()); // hit point increase ~1_val~ + list.Add(1060431, $"{prop}"); // hit point increase ~1_val~ } if ((prop = Attributes.BonusInt) != 0) { - list.Add(1060432, prop.ToString()); // intelligence bonus ~1_val~ + list.Add(1060432, $"{prop}"); // intelligence bonus ~1_val~ } if ((prop = Attributes.LowerManaCost) != 0) { - list.Add(1060433, prop.ToString()); // lower mana cost ~1_val~% + list.Add(1060433, $"{prop}"); // lower mana cost ~1_val~% } if ((prop = Attributes.LowerRegCost) != 0) { - list.Add(1060434, prop.ToString()); // lower reagent cost ~1_val~% + list.Add(1060434, $"{prop}"); // lower reagent cost ~1_val~% } if ((prop = ClothingAttributes.LowerStatReq) != 0) { - list.Add(1060435, prop.ToString()); // lower requirements ~1_val~% + list.Add(1060435, $"{prop}"); // lower requirements ~1_val~% } if ((prop = Attributes.Luck) != 0) { - list.Add(1060436, prop.ToString()); // luck ~1_val~ + list.Add(1060436, $"{prop}"); // luck ~1_val~ } if (ClothingAttributes.MageArmor != 0) @@ -812,12 +812,12 @@ namespace Server.Items if ((prop = Attributes.BonusMana) != 0) { - list.Add(1060439, prop.ToString()); // mana increase ~1_val~ + list.Add(1060439, $"{prop}"); // mana increase ~1_val~ } if ((prop = Attributes.RegenMana) != 0) { - list.Add(1060440, prop.ToString()); // mana regeneration ~1_val~ + list.Add(1060440, $"{prop}"); // mana regeneration ~1_val~ } if (Attributes.NightSight != 0) @@ -827,22 +827,22 @@ namespace Server.Items if ((prop = Attributes.ReflectPhysical) != 0) { - list.Add(1060442, prop.ToString()); // reflect physical damage ~1_val~% + list.Add(1060442, $"{prop}"); // reflect physical damage ~1_val~% } if ((prop = Attributes.RegenStam) != 0) { - list.Add(1060443, prop.ToString()); // stamina regeneration ~1_val~ + list.Add(1060443, $"{prop}"); // stamina regeneration ~1_val~ } if ((prop = Attributes.RegenHits) != 0) { - list.Add(1060444, prop.ToString()); // hit point regeneration ~1_val~ + list.Add(1060444, $"{prop}"); // hit point regeneration ~1_val~ } if ((prop = ClothingAttributes.SelfRepair) != 0) { - list.Add(1060450, prop.ToString()); // self repair ~1_val~ + list.Add(1060450, $"{prop}"); // self repair ~1_val~ } if (Attributes.SpellChanneling != 0) @@ -852,44 +852,44 @@ namespace Server.Items if ((prop = Attributes.SpellDamage) != 0) { - list.Add(1060483, prop.ToString()); // spell damage increase ~1_val~% + list.Add(1060483, $"{prop}"); // spell damage increase ~1_val~% } if ((prop = Attributes.BonusStam) != 0) { - list.Add(1060484, prop.ToString()); // stamina increase ~1_val~ + list.Add(1060484, $"{prop}"); // stamina increase ~1_val~ } if ((prop = Attributes.BonusStr) != 0) { - list.Add(1060485, prop.ToString()); // strength bonus ~1_val~ + list.Add(1060485, $"{prop}"); // strength bonus ~1_val~ } if ((prop = Attributes.WeaponSpeed) != 0) { - list.Add(1060486, prop.ToString()); // swing speed increase ~1_val~% + list.Add(1060486, $"{prop}"); // swing speed increase ~1_val~% } if (Core.ML && (prop = Attributes.IncreasedKarmaLoss) != 0) { - list.Add(1075210, prop.ToString()); // Increased Karma Loss ~1val~% + list.Add(1075210, $"{prop}"); // Increased Karma Loss ~1val~% } AddResistanceProperties(list); if ((prop = ClothingAttributes.DurabilityBonus) > 0) { - list.Add(1060410, prop.ToString()); // durability ~1_val~% + list.Add(1060410, $"{prop}"); // durability ~1_val~% } if ((prop = ComputeStatReq(StatType.Str)) > 0) { - list.Add(1061170, prop.ToString()); // strength requirement ~1_val~ + list.Add(1061170, $"{prop}"); // strength requirement ~1_val~ } if (_hitPoints >= 0 && _maxHitPoints > 0) { - list.Add(1060639, "{0}\t{1}", _hitPoints, _maxHitPoints); // durability ~1_val~ / ~2_val~ + list.Add(1060639, $"{_hitPoints}\t{_maxHitPoints}"); // durability ~1_val~ / ~2_val~ } } diff --git a/Projects/UOContent/Items/Clothing/Cloaks.cs b/Projects/UOContent/Items/Clothing/Cloaks.cs index 8b6ff62e5..d5356dde2 100644 --- a/Projects/UOContent/Items/Clothing/Cloaks.cs +++ b/Projects/UOContent/Items/Clothing/Cloaks.cs @@ -80,13 +80,13 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); if (IsArcane) { - list.Add(1061837, "{0}\t{1}", _curArcaneCharges, _maxArcaneCharges); // arcane charges: ~1_val~ / ~2_val~ + list.Add(1061837, $"{_curArcaneCharges}\t{_maxArcaneCharges}"); // arcane charges: ~1_val~ / ~2_val~ } } @@ -163,7 +163,7 @@ namespace Server.Items return false; } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Clothing/Hats.cs b/Projects/UOContent/Items/Clothing/Hats.cs index 80b4d7580..d6a9167d7 100644 --- a/Projects/UOContent/Items/Clothing/Hats.cs +++ b/Projects/UOContent/Items/Clothing/Hats.cs @@ -28,7 +28,7 @@ namespace Server.Items } } - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); diff --git a/Projects/UOContent/Items/Clothing/OuterTorso.cs b/Projects/UOContent/Items/Clothing/OuterTorso.cs index e05a7ff43..edd737c2f 100644 --- a/Projects/UOContent/Items/Clothing/OuterTorso.cs +++ b/Projects/UOContent/Items/Clothing/OuterTorso.cs @@ -193,7 +193,7 @@ namespace Server.Items return false; } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); @@ -275,7 +275,7 @@ namespace Server.Items return false; } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); @@ -374,13 +374,13 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); if (IsArcane) { - list.Add(1061837, "{0}\t{1}", _curArcaneCharges, _maxArcaneCharges); // arcane charges: ~1_val~ / ~2_val~ + list.Add(1061837, $"{_curArcaneCharges}\t{_maxArcaneCharges}"); // arcane charges: ~1_val~ / ~2_val~ } } diff --git a/Projects/UOContent/Items/Clothing/Shoes.cs b/Projects/UOContent/Items/Clothing/Shoes.cs index 03fcd4436..0615335d9 100644 --- a/Projects/UOContent/Items/Clothing/Shoes.cs +++ b/Projects/UOContent/Items/Clothing/Shoes.cs @@ -120,13 +120,13 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); if (IsArcane) { - list.Add(1061837, "{0}\t{1}", _curArcaneCharges, _maxArcaneCharges); // arcane charges: ~1_val~ / ~2_val~ + list.Add(1061837, $"{_curArcaneCharges}\t{_maxArcaneCharges}"); // arcane charges: ~1_val~ / ~2_val~ } } diff --git a/Projects/UOContent/Items/Construction/Signs/SubtextSign.cs b/Projects/UOContent/Items/Construction/Signs/SubtextSign.cs index 7541fdfed..9b7b63e1d 100644 --- a/Projects/UOContent/Items/Construction/Signs/SubtextSign.cs +++ b/Projects/UOContent/Items/Construction/Signs/SubtextSign.cs @@ -40,7 +40,7 @@ namespace Server.Items } } - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); diff --git a/Projects/UOContent/Items/Containers/Container.cs b/Projects/UOContent/Items/Containers/Container.cs index c634237fc..c3112705b 100644 --- a/Projects/UOContent/Items/Containers/Container.cs +++ b/Projects/UOContent/Items/Containers/Container.cs @@ -172,7 +172,7 @@ public partial class CreatureBackpack : Backpack // Used on BaseCreature Weight = 3.0; } - public override void AddNameProperty(ObjectPropertyList list) + public override void AddNameProperty(IPropertyList list) { if (Name != null) { diff --git a/Projects/UOContent/Items/Containers/LockableContainer.cs b/Projects/UOContent/Items/Containers/LockableContainer.cs index 1bbad4d64..a65670256 100644 --- a/Projects/UOContent/Items/Containers/LockableContainer.cs +++ b/Projects/UOContent/Items/Containers/LockableContainer.cs @@ -214,7 +214,7 @@ public abstract partial class LockableContainer : TrappableContainer, ILockable, base.OnSnoop(from); } - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); diff --git a/Projects/UOContent/Items/Containers/ParagonChest.cs b/Projects/UOContent/Items/Containers/ParagonChest.cs index 8f95fbfa4..d6c730dff 100644 --- a/Projects/UOContent/Items/Containers/ParagonChest.cs +++ b/Projects/UOContent/Items/Containers/ParagonChest.cs @@ -35,7 +35,7 @@ public partial class ParagonChest : LockableContainer LabelTo(from, 1063449, _name); } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Containers/Strongbox.cs b/Projects/UOContent/Items/Containers/Strongbox.cs index 245bbd9c9..e6e1eec3e 100644 --- a/Projects/UOContent/Items/Containers/Strongbox.cs +++ b/Projects/UOContent/Items/Containers/Strongbox.cs @@ -59,7 +59,7 @@ public partial class StrongBox : BaseContainer, IChoppable } } - public override void AddNameProperty(ObjectPropertyList list) + public override void AddNameProperty(IPropertyList list) { if (_owner != null) { diff --git a/Projects/UOContent/Items/Decoration Artifacts/BaseDecorationArtifact.cs b/Projects/UOContent/Items/Decoration Artifacts/BaseDecorationArtifact.cs index 079bb9d30..69719ab90 100644 --- a/Projects/UOContent/Items/Decoration Artifacts/BaseDecorationArtifact.cs +++ b/Projects/UOContent/Items/Decoration Artifacts/BaseDecorationArtifact.cs @@ -11,11 +11,11 @@ public abstract partial class BaseDecorationArtifact : Item public override bool ForceShowProperties => true; - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); - list.Add(1061078, ArtifactRarity.ToString()); // artifact rarity ~1_val~ + list.Add(1061078, $"{ArtifactRarity}"); // artifact rarity ~1_val~ } } @@ -28,10 +28,10 @@ public abstract partial class BaseDecorationContainerArtifact : BaseContainer public override bool ForceShowProperties => true; - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); - list.Add(1061078, ArtifactRarity.ToString()); // artifact rarity ~1_val~ + list.Add(1061078, $"{ArtifactRarity}"); // artifact rarity ~1_val~ } } diff --git a/Projects/UOContent/Items/Deeds/CommodityDeed.cs b/Projects/UOContent/Items/Deeds/CommodityDeed.cs index 25ddf29e3..87772006a 100644 --- a/Projects/UOContent/Items/Deeds/CommodityDeed.cs +++ b/Projects/UOContent/Items/Deeds/CommodityDeed.cs @@ -62,7 +62,7 @@ public partial class CommodityDeed : Item base.OnDelete(); } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Deeds/DragonBardingDeed.cs b/Projects/UOContent/Items/Deeds/DragonBardingDeed.cs index 0cb85790a..78a13404e 100644 --- a/Projects/UOContent/Items/Deeds/DragonBardingDeed.cs +++ b/Projects/UOContent/Items/Deeds/DragonBardingDeed.cs @@ -65,7 +65,7 @@ public partial class DragonBardingDeed : Item, ICraftable return quality; } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Deeds/NewPlayerTicket.cs b/Projects/UOContent/Items/Deeds/NewPlayerTicket.cs index d19fdf762..36c2eea7a 100644 --- a/Projects/UOContent/Items/Deeds/NewPlayerTicket.cs +++ b/Projects/UOContent/Items/Deeds/NewPlayerTicket.cs @@ -23,7 +23,7 @@ public partial class NewPlayerTicket : Item public override bool DisplayLootType => false; - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Deeds/VendorRentalContract.cs b/Projects/UOContent/Items/Deeds/VendorRentalContract.cs index ea2dc6cfc..8a1134014 100644 --- a/Projects/UOContent/Items/Deeds/VendorRentalContract.cs +++ b/Projects/UOContent/Items/Deeds/VendorRentalContract.cs @@ -76,7 +76,7 @@ public partial class VendorRentalContract : Item } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Food/Beverage.cs b/Projects/UOContent/Items/Food/Beverage.cs index 10f71c6a6..305440fcb 100644 --- a/Projects/UOContent/Items/Food/Beverage.cs +++ b/Projects/UOContent/Items/Food/Beverage.cs @@ -322,7 +322,7 @@ public abstract partial class BaseBeverage : Item, IHasQuantity }; } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Games/Mahjong/MahjongGame.cs b/Projects/UOContent/Items/Games/Mahjong/MahjongGame.cs index ab2fa1a63..4bd778ee2 100644 --- a/Projects/UOContent/Items/Games/Mahjong/MahjongGame.cs +++ b/Projects/UOContent/Items/Games/Mahjong/MahjongGame.cs @@ -162,7 +162,7 @@ namespace Server.Engines.Mahjong BuildVerticalWall(ref i, 115, 165, 1, MahjongPieceDirection.Right, typeGenerator); } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Guilds/Guildstone.cs b/Projects/UOContent/Items/Guilds/Guildstone.cs index f002a89b2..89a53b6c6 100644 --- a/Projects/UOContent/Items/Guilds/Guildstone.cs +++ b/Projects/UOContent/Items/Guilds/Guildstone.cs @@ -178,7 +178,7 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); @@ -379,7 +379,7 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Jewels/BaseJewel.cs b/Projects/UOContent/Items/Jewels/BaseJewel.cs index ac7503be4..cbce3546d 100644 --- a/Projects/UOContent/Items/Jewels/BaseJewel.cs +++ b/Projects/UOContent/Items/Jewels/BaseJewel.cs @@ -255,7 +255,7 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); @@ -265,77 +265,77 @@ namespace Server.Items if ((prop = ArtifactRarity) > 0) { - list.Add(1061078, prop.ToString()); // artifact rarity ~1_val~ + list.Add(1061078, $"{prop}"); // artifact rarity ~1_val~ } if ((prop = Attributes.WeaponDamage) != 0) { - list.Add(1060401, prop.ToString()); // damage increase ~1_val~% + list.Add(1060401, $"{prop}"); // damage increase ~1_val~% } if ((prop = Attributes.DefendChance) != 0) { - list.Add(1060408, prop.ToString()); // defense chance increase ~1_val~% + list.Add(1060408, $"{prop}"); // defense chance increase ~1_val~% } if ((prop = Attributes.BonusDex) != 0) { - list.Add(1060409, prop.ToString()); // dexterity bonus ~1_val~ + list.Add(1060409, $"{prop}"); // dexterity bonus ~1_val~ } if ((prop = Attributes.EnhancePotions) != 0) { - list.Add(1060411, prop.ToString()); // enhance potions ~1_val~% + list.Add(1060411, $"{prop}"); // enhance potions ~1_val~% } if ((prop = Attributes.CastRecovery) != 0) { - list.Add(1060412, prop.ToString()); // faster cast recovery ~1_val~ + list.Add(1060412, $"{prop}"); // faster cast recovery ~1_val~ } if ((prop = Attributes.CastSpeed) != 0) { - list.Add(1060413, prop.ToString()); // faster casting ~1_val~ + list.Add(1060413, $"{prop}"); // faster casting ~1_val~ } if ((prop = Attributes.AttackChance) != 0) { - list.Add(1060415, prop.ToString()); // hit chance increase ~1_val~% + list.Add(1060415, $"{prop}"); // hit chance increase ~1_val~% } if ((prop = Attributes.BonusHits) != 0) { - list.Add(1060431, prop.ToString()); // hit point increase ~1_val~ + list.Add(1060431, $"{prop}"); // hit point increase ~1_val~ } if ((prop = Attributes.BonusInt) != 0) { - list.Add(1060432, prop.ToString()); // intelligence bonus ~1_val~ + list.Add(1060432, $"{prop}"); // intelligence bonus ~1_val~ } if ((prop = Attributes.LowerManaCost) != 0) { - list.Add(1060433, prop.ToString()); // lower mana cost ~1_val~% + list.Add(1060433, $"{prop}"); // lower mana cost ~1_val~% } if ((prop = Attributes.LowerRegCost) != 0) { - list.Add(1060434, prop.ToString()); // lower reagent cost ~1_val~% + list.Add(1060434, $"{prop}"); // lower reagent cost ~1_val~% } if ((prop = Attributes.Luck) != 0) { - list.Add(1060436, prop.ToString()); // luck ~1_val~ + list.Add(1060436, $"{prop}"); // luck ~1_val~ } if ((prop = Attributes.BonusMana) != 0) { - list.Add(1060439, prop.ToString()); // mana increase ~1_val~ + list.Add(1060439, $"{prop}"); // mana increase ~1_val~ } if ((prop = Attributes.RegenMana) != 0) { - list.Add(1060440, prop.ToString()); // mana regeneration ~1_val~ + list.Add(1060440, $"{prop}"); // mana regeneration ~1_val~ } if (Attributes.NightSight != 0) @@ -345,17 +345,17 @@ namespace Server.Items if ((prop = Attributes.ReflectPhysical) != 0) { - list.Add(1060442, prop.ToString()); // reflect physical damage ~1_val~% + list.Add(1060442, $"{prop}"); // reflect physical damage ~1_val~% } if ((prop = Attributes.RegenStam) != 0) { - list.Add(1060443, prop.ToString()); // stamina regeneration ~1_val~ + list.Add(1060443, $"{prop}"); // stamina regeneration ~1_val~ } if ((prop = Attributes.RegenHits) != 0) { - list.Add(1060444, prop.ToString()); // hit point regeneration ~1_val~ + list.Add(1060444, $"{prop}"); // hit point regeneration ~1_val~ } if (Attributes.SpellChanneling != 0) @@ -365,34 +365,34 @@ namespace Server.Items if ((prop = Attributes.SpellDamage) != 0) { - list.Add(1060483, prop.ToString()); // spell damage increase ~1_val~% + list.Add(1060483, $"{prop}"); // spell damage increase ~1_val~% } if ((prop = Attributes.BonusStam) != 0) { - list.Add(1060484, prop.ToString()); // stamina increase ~1_val~ + list.Add(1060484, $"{prop}"); // stamina increase ~1_val~ } if ((prop = Attributes.BonusStr) != 0) { - list.Add(1060485, prop.ToString()); // strength bonus ~1_val~ + list.Add(1060485, $"{prop}"); // strength bonus ~1_val~ } if ((prop = Attributes.WeaponSpeed) != 0) { - list.Add(1060486, prop.ToString()); // swing speed increase ~1_val~% + list.Add(1060486, $"{prop}"); // swing speed increase ~1_val~% } if (Core.ML && (prop = Attributes.IncreasedKarmaLoss) != 0) { - list.Add(1075210, prop.ToString()); // Increased Karma Loss ~1val~% + list.Add(1075210, $"{prop}"); // Increased Karma Loss ~1val~% } AddResistanceProperties(list); if (m_HitPoints >= 0 && m_MaxHitPoints > 0) { - list.Add(1060639, "{0}\t{1}", m_HitPoints, m_MaxHitPoints); // durability ~1_val~ / ~2_val~ + list.Add(1060639, $"{m_HitPoints}\t{m_MaxHitPoints}"); // durability ~1_val~ / ~2_val~ } } diff --git a/Projects/UOContent/Items/Lights/Candelabra.cs b/Projects/UOContent/Items/Lights/Candelabra.cs index 81889c01e..30d3b98e8 100644 --- a/Projects/UOContent/Items/Lights/Candelabra.cs +++ b/Projects/UOContent/Items/Lights/Candelabra.cs @@ -46,7 +46,7 @@ namespace Server.Items } } - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); diff --git a/Projects/UOContent/Items/Maps/TreasureMap.cs b/Projects/UOContent/Items/Maps/TreasureMap.cs index be5ca3039..ed4c61ca3 100644 --- a/Projects/UOContent/Items/Maps/TreasureMap.cs +++ b/Projects/UOContent/Items/Maps/TreasureMap.cs @@ -523,7 +523,7 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Misc/BankCheck.cs b/Projects/UOContent/Items/Misc/BankCheck.cs index 8cce66288..db1517471 100644 --- a/Projects/UOContent/Items/Misc/BankCheck.cs +++ b/Projects/UOContent/Items/Misc/BankCheck.cs @@ -68,7 +68,7 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); list.Add(1060738, Core.ML ? $"{m_Worth:N0}" : m_Worth.ToString()); // value: ~1_val~) diff --git a/Projects/UOContent/Items/Misc/Blighted Grove/MelisandesFermentedWine.cs b/Projects/UOContent/Items/Misc/Blighted Grove/MelisandesFermentedWine.cs index 4a292c615..080783aab 100644 --- a/Projects/UOContent/Items/Misc/Blighted Grove/MelisandesFermentedWine.cs +++ b/Projects/UOContent/Items/Misc/Blighted Grove/MelisandesFermentedWine.cs @@ -24,7 +24,7 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Misc/Blighted Grove/MelisandesHairDye.cs b/Projects/UOContent/Items/Misc/Blighted Grove/MelisandesHairDye.cs index 24a51b8f8..c8a40859b 100644 --- a/Projects/UOContent/Items/Misc/Blighted Grove/MelisandesHairDye.cs +++ b/Projects/UOContent/Items/Misc/Blighted Grove/MelisandesHairDye.cs @@ -28,7 +28,7 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Misc/CommunicationCrystals.cs b/Projects/UOContent/Items/Misc/CommunicationCrystals.cs index 357720994..02997aa56 100644 --- a/Projects/UOContent/Items/Misc/CommunicationCrystals.cs +++ b/Projects/UOContent/Items/Misc/CommunicationCrystals.cs @@ -91,17 +91,17 @@ namespace Server.Items public override bool HandlesOnSpeech => true; - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); list.Add(Active ? 1060742 : 1060743); // active / inactive list.Add(1060745); // broadcast - list.Add(1060741, Charges.ToString()); // charges: ~1_val~ + list.Add(1060741, $"{Charges}"); // charges: ~1_val~ if (Receivers.Count > 0) { - list.Add(1060746, Receivers.Count.ToString()); // links: ~1_val~ + list.Add(1060746, $"{Receivers.Count}"); // links: ~1_val~ } } @@ -338,7 +338,7 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Misc/Corpses/Corpse.cs b/Projects/UOContent/Items/Misc/Corpses/Corpse.cs index f3ea9e7b6..15eb2ca25 100644 --- a/Projects/UOContent/Items/Misc/Corpses/Corpse.cs +++ b/Projects/UOContent/Items/Misc/Corpses/Corpse.cs @@ -1130,7 +1130,7 @@ namespace Server.Items public override bool CheckContentDisplay(Mobile from) => false; - public override void AddNameProperty(ObjectPropertyList list) + public override void AddNameProperty(IPropertyList list) { if (ItemID == 0x2006) // Corpse form { diff --git a/Projects/UOContent/Items/Misc/Corpses/DecayedCorpse.cs b/Projects/UOContent/Items/Misc/Corpses/DecayedCorpse.cs index 9eb2da8ac..a38c910aa 100644 --- a/Projects/UOContent/Items/Misc/Corpses/DecayedCorpse.cs +++ b/Projects/UOContent/Items/Misc/Corpses/DecayedCorpse.cs @@ -43,7 +43,7 @@ namespace Server.Items // Do not display (x items, y stones) public override bool CheckContentDisplay(Mobile from) => false; - public override void AddNameProperty(ObjectPropertyList list) + public override void AddNameProperty(IPropertyList list) { list.Add(1046414, Name); // the remains of ~1_NAME~ } diff --git a/Projects/UOContent/Items/Misc/InteriorDecorator.cs b/Projects/UOContent/Items/Misc/InteriorDecorator.cs index 8e40f2f12..953b19c21 100644 --- a/Projects/UOContent/Items/Misc/InteriorDecorator.cs +++ b/Projects/UOContent/Items/Misc/InteriorDecorator.cs @@ -41,7 +41,7 @@ namespace Server.Items public override int LabelNumber => 1041280; // an interior decorator - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Misc/Key.cs b/Projects/UOContent/Items/Misc/Key.cs index 263a9ac03..0f362d47b 100644 --- a/Projects/UOContent/Items/Misc/Key.cs +++ b/Projects/UOContent/Items/Misc/Key.cs @@ -218,7 +218,7 @@ public class Key : Item from.Target = t; } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Misc/PromotionalToken.cs b/Projects/UOContent/Items/Misc/PromotionalToken.cs index 264c5e6bd..857e7548b 100644 --- a/Projects/UOContent/Items/Misc/PromotionalToken.cs +++ b/Projects/UOContent/Items/Misc/PromotionalToken.cs @@ -23,11 +23,11 @@ namespace Server.Items public override int LabelNumber => 1070997; // A promotional token public abstract Item CreateItemFor(Mobile from); - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); - list.Add(1070998, ItemName.ToString()); // Use this to redeem
your ~1_PROMO~ + list.Add(1070998, $"{ItemName}"); // Use this to redeem
your ~1_PROMO~ } public override void OnDoubleClick(Mobile from) diff --git a/Projects/UOContent/Items/Misc/Teleporter.cs b/Projects/UOContent/Items/Misc/Teleporter.cs index 88b689899..ec505662d 100644 --- a/Projects/UOContent/Items/Misc/Teleporter.cs +++ b/Projects/UOContent/Items/Misc/Teleporter.cs @@ -153,7 +153,7 @@ namespace Server.Items public override int LabelNumber => 1026095; // teleporter - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); @@ -168,15 +168,15 @@ namespace Server.Items if (m_MapDest != null) { - list.Add(1060658, "Map\t{0}", m_MapDest); + list.Add(1060658, $"Map\t{m_MapDest}"); } if (m_PointDest != Point3D.Zero) { - list.Add(1060659, "Coords\t{0}", m_PointDest); + list.Add(1060659, $"Coords\t{m_PointDest}"); } - list.Add(1060660, "Creatures\t{0}", m_Creatures ? "Yes" : "No"); + list.Add(1060660, $"Creatures\t{(m_Creatures ? "Yes" : "No")}"); } public override void OnSingleClick(Mobile from) @@ -463,7 +463,7 @@ namespace Server.Items return true; } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); @@ -479,15 +479,15 @@ namespace Server.Items skillName = "(Invalid)"; } - list.Add(1060661, "{0}\t{1:F1}", skillName, m_Required); + list.Add(1060661, $"{skillName}\t{m_Required:F1}"); if (m_MessageString != null) { - list.Add(1060662, "Message\t{0}", m_MessageString); + list.Add(1060662, $"Message\t{m_MessageString}"); } else if (m_MessageNumber != 0) { - list.Add(1060662, "Message\t#{0}", m_MessageNumber); + list.Add(1060662, $"Message\t#{m_MessageNumber}"); } } @@ -621,20 +621,20 @@ namespace Server.Items public override bool OnMoveOver(Mobile m) => true; - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); - list.Add(1060661, "Range\t{0}", m_Range); + list.Add(1060661, $"Range\t{m_Range}"); if (m_Keyword >= 0) { - list.Add(1060662, "Keyword\t{0}", m_Keyword); + list.Add(1060662, $"Keyword\t{m_Keyword}"); } if (m_Substring != null) { - list.Add(1060663, "Substring\t{0}", m_Substring); + list.Add(1060663, $"Substring\t{m_Substring}"); } } @@ -1176,7 +1176,7 @@ namespace Server.Items return true; } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Misc/WindChimes.cs b/Projects/UOContent/Items/Misc/WindChimes.cs index 06eb62e8d..6e1d5e0ef 100644 --- a/Projects/UOContent/Items/Misc/WindChimes.cs +++ b/Projects/UOContent/Items/Misc/WindChimes.cs @@ -42,7 +42,7 @@ namespace Server.Items base.OnMovement(m, oldLocation); } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Quivers/BaseQuiver.cs b/Projects/UOContent/Items/Quivers/BaseQuiver.cs index 6234087bd..ca0c191b9 100644 --- a/Projects/UOContent/Items/Quivers/BaseQuiver.cs +++ b/Projects/UOContent/Items/Quivers/BaseQuiver.cs @@ -236,7 +236,7 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); @@ -256,23 +256,23 @@ namespace Server.Items { if (ammo is Arrow) { - list.Add(1075265, "{0}\t{1}", ammo.Amount, Capacity); // Ammo: ~1_QUANTITY~/~2_CAPACITY~ arrows + list.Add(1075265, $"{ammo.Amount}\t{Capacity}"); // Ammo: ~1_QUANTITY~/~2_CAPACITY~ arrows } else if (ammo is Bolt) { - list.Add(1075266, "{0}\t{1}", ammo.Amount, Capacity); // Ammo: ~1_QUANTITY~/~2_CAPACITY~ bolts + list.Add(1075266, $"{ammo.Amount}\t{Capacity}"); // Ammo: ~1_QUANTITY~/~2_CAPACITY~ bolts } } else { - list.Add(1075265, "{0}\t{1}", 0, Capacity); // Ammo: ~1_QUANTITY~/~2_CAPACITY~ arrows + list.Add(1075265, $"0\t{Capacity}"); // Ammo: ~1_QUANTITY~/~2_CAPACITY~ arrows } int prop; if ((prop = m_DamageIncrease) != 0) { - list.Add(1074762, prop.ToString()); // Damage modifier: ~1_PERCENT~% + list.Add(1074762, $"{prop}"); // Damage modifier: ~1_PERCENT~% } int phys = 0, fire = 0, cold = 0, pois = 0, nrgy = 0, chaos = 0, direct = 0; @@ -281,104 +281,104 @@ namespace Server.Items if (phys != 0) { - list.Add(1060403, phys.ToString()); // physical damage ~1_val~% + list.Add(1060403, $"{phys}"); // physical damage ~1_val~% } if (fire != 0) { - list.Add(1060405, fire.ToString()); // fire damage ~1_val~% + list.Add(1060405, $"{fire}"); // fire damage ~1_val~% } if (cold != 0) { - list.Add(1060404, cold.ToString()); // cold damage ~1_val~% + list.Add(1060404, $"{cold}"); // cold damage ~1_val~% } if (pois != 0) { - list.Add(1060406, pois.ToString()); // poison damage ~1_val~% + list.Add(1060406, $"{pois}"); // poison damage ~1_val~% } if (nrgy != 0) { - list.Add(1060407, nrgy.ToString()); // energy damage ~1_val + list.Add(1060407, $"{nrgy}"); // energy damage ~1_val } if (chaos != 0) { - list.Add(1072846, chaos.ToString()); // chaos damage ~1_val~% + list.Add(1072846, $"{chaos}"); // chaos damage ~1_val~% } if (direct != 0) { - list.Add(1079978, direct.ToString()); // Direct Damage: ~1_PERCENT~% + list.Add(1079978, $"{direct}"); // Direct Damage: ~1_PERCENT~% } list.Add(1075085); // Requirement: Mondain's Legacy if ((prop = Attributes.DefendChance) != 0) { - list.Add(1060408, prop.ToString()); // defense chance increase ~1_val~% + list.Add(1060408, $"{prop}"); // defense chance increase ~1_val~% } if ((prop = Attributes.BonusDex) != 0) { - list.Add(1060409, prop.ToString()); // dexterity bonus ~1_val~ + list.Add(1060409, $"{prop}"); // dexterity bonus ~1_val~ } if ((prop = Attributes.EnhancePotions) != 0) { - list.Add(1060411, prop.ToString()); // enhance potions ~1_val~% + list.Add(1060411, $"{prop}"); // enhance potions ~1_val~% } if ((prop = Attributes.CastRecovery) != 0) { - list.Add(1060412, prop.ToString()); // faster cast recovery ~1_val~ + list.Add(1060412, $"{prop}"); // faster cast recovery ~1_val~ } if ((prop = Attributes.CastSpeed) != 0) { - list.Add(1060413, prop.ToString()); // faster casting ~1_val~ + list.Add(1060413, $"{prop}"); // faster casting ~1_val~ } if ((prop = Attributes.AttackChance) != 0) { - list.Add(1060415, prop.ToString()); // hit chance increase ~1_val~% + list.Add(1060415, $"{prop}"); // hit chance increase ~1_val~% } if ((prop = Attributes.BonusHits) != 0) { - list.Add(1060431, prop.ToString()); // hit point increase ~1_val~ + list.Add(1060431, $"{prop}"); // hit point increase ~1_val~ } if ((prop = Attributes.BonusInt) != 0) { - list.Add(1060432, prop.ToString()); // intelligence bonus ~1_val~ + list.Add(1060432, $"{prop}"); // intelligence bonus ~1_val~ } if ((prop = Attributes.LowerManaCost) != 0) { - list.Add(1060433, prop.ToString()); // lower mana cost ~1_val~% + list.Add(1060433, $"{prop}"); // lower mana cost ~1_val~% } if ((prop = Attributes.LowerRegCost) != 0) { - list.Add(1060434, prop.ToString()); // lower reagent cost ~1_val~% + list.Add(1060434, $"{prop}"); // lower reagent cost ~1_val~% } if ((prop = Attributes.Luck) != 0) { - list.Add(1060436, prop.ToString()); // luck ~1_val~ + list.Add(1060436, $"{prop}"); // luck ~1_val~ } if ((prop = Attributes.BonusMana) != 0) { - list.Add(1060439, prop.ToString()); // mana increase ~1_val~ + list.Add(1060439, $"{prop}"); // mana increase ~1_val~ } if ((prop = Attributes.RegenMana) != 0) { - list.Add(1060440, prop.ToString()); // mana regeneration ~1_val~ + list.Add(1060440, $"{prop}"); // mana regeneration ~1_val~ } if (Attributes.NightSight != 0) @@ -388,58 +388,54 @@ namespace Server.Items if ((prop = Attributes.ReflectPhysical) != 0) { - list.Add(1060442, prop.ToString()); // reflect physical damage ~1_val~% + list.Add(1060442, $"{prop}"); // reflect physical damage ~1_val~% } if ((prop = Attributes.RegenStam) != 0) { - list.Add(1060443, prop.ToString()); // stamina regeneration ~1_val~ + list.Add(1060443, $"{prop}"); // stamina regeneration ~1_val~ } if ((prop = Attributes.RegenHits) != 0) { - list.Add(1060444, prop.ToString()); // hit point regeneration ~1_val~ + list.Add(1060444, $"{prop}"); // hit point regeneration ~1_val~ } if ((prop = Attributes.SpellDamage) != 0) { - list.Add(1060483, prop.ToString()); // spell damage increase ~1_val~% + list.Add(1060483, $"{prop}"); // spell damage increase ~1_val~% } if ((prop = Attributes.BonusStam) != 0) { - list.Add(1060484, prop.ToString()); // stamina increase ~1_val~ + list.Add(1060484, $"{prop}"); // stamina increase ~1_val~ } if ((prop = Attributes.BonusStr) != 0) { - list.Add(1060485, prop.ToString()); // strength bonus ~1_val~ + list.Add(1060485, $"{prop}"); // strength bonus ~1_val~ } if ((prop = Attributes.WeaponSpeed) != 0) { - list.Add(1060486, prop.ToString()); // swing speed increase ~1_val~% + list.Add(1060486, $"{prop}"); // swing speed increase ~1_val~% } if ((prop = m_LowerAmmoCost) > 0) { - list.Add(1075208, prop.ToString()); // Lower Ammo Cost ~1_Percentage~% + list.Add(1075208, $"{prop}"); // Lower Ammo Cost ~1_Percentage~% } var weight = ammo != null ? ammo.Weight + ammo.Amount : 0; list.Add( - 1072241, - "{0}\t{1}\t{2}\t{3}", - Items.Count, - DefaultMaxItems, - (int)weight, - DefaultMaxWeight - ); // Contents: ~1_COUNT~/~2_MAXCOUNT items, ~3_WEIGHT~/~4_MAXWEIGHT~ stones + 1072241, // Contents: ~1_COUNT~/~2_MAXCOUNT items, ~3_WEIGHT~/~4_MAXWEIGHT~ stones + $"{Items.Count}\t{DefaultMaxItems}\t{(int)weight}\t{DefaultMaxWeight}" + ); if ((prop = m_WeightReduction) != 0) { - list.Add(1072210, prop.ToString()); // Weight reduction: ~1_PERCENTAGE~% + list.Add(1072210, $"{prop}"); // Weight reduction: ~1_PERCENTAGE~% } } diff --git a/Projects/UOContent/Items/Resources/Blacksmithing/Ingots.cs b/Projects/UOContent/Items/Resources/Blacksmithing/Ingots.cs index 1d034e0cc..bcf624f90 100644 --- a/Projects/UOContent/Items/Resources/Blacksmithing/Ingots.cs +++ b/Projects/UOContent/Items/Resources/Blacksmithing/Ingots.cs @@ -68,11 +68,11 @@ namespace Server.Items } } - public override void AddNameProperty(ObjectPropertyList list) + public override void AddNameProperty(IPropertyList list) { if (Amount > 1) { - list.Add(1050039, "{0}\t#{1}", Amount, 1027154); // ~1_NUMBER~ ~2_ITEMNAME~ + list.Add(1050039, $"{Amount}\t#{1027154}"); // ~1_NUMBER~ ~2_ITEMNAME~ } else { @@ -80,7 +80,7 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Resources/Blacksmithing/Ore.cs b/Projects/UOContent/Items/Resources/Blacksmithing/Ore.cs index d5f26bb55..093d30d25 100644 --- a/Projects/UOContent/Items/Resources/Blacksmithing/Ore.cs +++ b/Projects/UOContent/Items/Resources/Blacksmithing/Ore.cs @@ -83,11 +83,11 @@ namespace Server.Items dropped.Stackable && Stackable && dropped.GetType() == GetType() && dropped.Hue == Hue && dropped.Name == Name && dropped.Amount + Amount <= 60000 && dropped != this; - public override void AddNameProperty(ObjectPropertyList list) + public override void AddNameProperty(IPropertyList list) { if (Amount > 1) { - list.Add(1050039, "{0}\t#{1}", Amount, 1026583); // ~1_NUMBER~ ~2_ITEMNAME~ + list.Add(1050039, $"{Amount}\t#{1026583}"); // ~1_NUMBER~ ~2_ITEMNAME~ } else { @@ -95,7 +95,7 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Resources/Fishing/BigFish.cs b/Projects/UOContent/Items/Resources/Fishing/BigFish.cs index 7ccaef1ea..49dc2bc76 100644 --- a/Projects/UOContent/Items/Resources/Fishing/BigFish.cs +++ b/Projects/UOContent/Items/Resources/Fishing/BigFish.cs @@ -26,7 +26,7 @@ namespace Server.Items ScissorHelper(from, new RawFishSteak(), Math.Max(16, (int)Weight) / 4, false); } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); @@ -37,7 +37,7 @@ namespace Server.Items list.Add(1070857, _fisher.Name); // Caught by ~1_fisherman~ } - list.Add(1070858, ((int)Weight).ToString()); // ~1_weight~ stones + list.Add(1070858, $"{(int)Weight}"); // ~1_weight~ stones } } diff --git a/Projects/UOContent/Items/Resources/Masonry/Granite.cs b/Projects/UOContent/Items/Resources/Masonry/Granite.cs index 6b473ac20..c24cb757f 100644 --- a/Projects/UOContent/Items/Resources/Masonry/Granite.cs +++ b/Projects/UOContent/Items/Resources/Masonry/Granite.cs @@ -62,7 +62,7 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Resources/Tailor/Hides.cs b/Projects/UOContent/Items/Resources/Tailor/Hides.cs index 39acdc6c7..6c28ac235 100644 --- a/Projects/UOContent/Items/Resources/Tailor/Hides.cs +++ b/Projects/UOContent/Items/Resources/Tailor/Hides.cs @@ -55,11 +55,11 @@ namespace Server.Items } } - public override void AddNameProperty(ObjectPropertyList list) + public override void AddNameProperty(IPropertyList list) { if (Amount > 1) { - list.Add(1050039, "{0}\t#{1}", Amount, 1024216); // ~1_NUMBER~ ~2_ITEMNAME~ + list.Add(1050039, $"{Amount}\t#1024216"); // ~1_NUMBER~ ~2_ITEMNAME~ } else { @@ -67,7 +67,7 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Resources/Tailor/Leathers.cs b/Projects/UOContent/Items/Resources/Tailor/Leathers.cs index 3ed3f4a7c..1d44a86ea 100644 --- a/Projects/UOContent/Items/Resources/Tailor/Leathers.cs +++ b/Projects/UOContent/Items/Resources/Tailor/Leathers.cs @@ -55,11 +55,11 @@ namespace Server.Items } } - public override void AddNameProperty(ObjectPropertyList list) + public override void AddNameProperty(IPropertyList list) { if (Amount > 1) { - list.Add(1050039, "{0}\t#{1}", Amount, 1024199); // ~1_NUMBER~ ~2_ITEMNAME~ + list.Add(1050039, $"{Amount}\t#1024199"); // ~1_NUMBER~ ~2_ITEMNAME~ } else { @@ -67,7 +67,7 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Skill Items/Carpenter Items/Board.cs b/Projects/UOContent/Items/Skill Items/Carpenter Items/Board.cs index 2eac48b20..c5185bb7d 100644 --- a/Projects/UOContent/Items/Skill Items/Carpenter Items/Board.cs +++ b/Projects/UOContent/Items/Skill Items/Carpenter Items/Board.cs @@ -59,7 +59,7 @@ namespace Server.Items bool ICommodity.IsDeedable => true; - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Skill Items/Carpenter Items/TaxidermyKit.cs b/Projects/UOContent/Items/Skill Items/Carpenter Items/TaxidermyKit.cs index 6a6a1dab4..82c2a2aca 100644 --- a/Projects/UOContent/Items/Skill Items/Carpenter Items/TaxidermyKit.cs +++ b/Projects/UOContent/Items/Skill Items/Carpenter Items/TaxidermyKit.cs @@ -253,7 +253,7 @@ namespace Server.Items public Item Deed => new TrophyDeed(WestID, NorthID, DeedNumber, m_AddonNumber, m_Hunter, m_AnimalWeight); - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); @@ -264,7 +264,7 @@ namespace Server.Items list.Add(1070857, m_Hunter.Name); // Caught by ~1_fisherman~ } - list.Add(1070858, m_AnimalWeight.ToString()); // ~1_weight~ stones + list.Add(1070858, $"{m_AnimalWeight}"); // ~1_weight~ stones } } @@ -428,7 +428,7 @@ namespace Server.Items public override int LabelNumber => m_DeedNumber; - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); @@ -439,7 +439,7 @@ namespace Server.Items list.Add(1070857, m_Hunter.Name); // Caught by ~1_fisherman~ } - list.Add(1070858, m_AnimalWeight.ToString()); // ~1_weight~ stones + list.Add(1070858, $"{m_AnimalWeight}"); // ~1_weight~ stones } } diff --git a/Projects/UOContent/Items/Skill Items/Fishing/Misc/ShipwreckedItem.cs b/Projects/UOContent/Items/Skill Items/Fishing/Misc/ShipwreckedItem.cs index b848e9070..6643e1507 100644 --- a/Projects/UOContent/Items/Skill Items/Fishing/Misc/ShipwreckedItem.cs +++ b/Projects/UOContent/Items/Skill Items/Fishing/Misc/ShipwreckedItem.cs @@ -51,7 +51,7 @@ namespace Server.Items LabelTo(from, 1050039, $"#{LabelNumber}\t#1041645"); } - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); list.Add(1041645); // recovered from a shipwreck diff --git a/Projects/UOContent/Items/Skill Items/Fishing/Misc/SpecialFishingNet.cs b/Projects/UOContent/Items/Skill Items/Fishing/Misc/SpecialFishingNet.cs index 8d3f3e515..e49ebba19 100644 --- a/Projects/UOContent/Items/Skill Items/Fishing/Misc/SpecialFishingNet.cs +++ b/Projects/UOContent/Items/Skill Items/Fishing/Misc/SpecialFishingNet.cs @@ -63,14 +63,14 @@ namespace Server.Items public virtual bool RequireDeepWater => true; - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); AddNetProperties(list); } - protected virtual void AddNetProperties(ObjectPropertyList list) + protected virtual void AddNetProperties(IPropertyList list) { // as if the name wasn't enough.. list.Add(1017410); // Special Fishing Net @@ -435,7 +435,7 @@ namespace Server.Items public override int LabelNumber => 1063451; // a fabled fishing net - protected override void AddNetProperties(ObjectPropertyList list) + protected override void AddNetProperties(IPropertyList list) { } diff --git a/Projects/UOContent/Items/Skill Items/Harvest Tools/BaseHarvestTool.cs b/Projects/UOContent/Items/Skill Items/Harvest Tools/BaseHarvestTool.cs index 66a98318f..cb79d1891 100644 --- a/Projects/UOContent/Items/Skill Items/Harvest Tools/BaseHarvestTool.cs +++ b/Projects/UOContent/Items/Skill Items/Harvest Tools/BaseHarvestTool.cs @@ -109,7 +109,7 @@ namespace Server.Items return 100; } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); @@ -122,7 +122,7 @@ namespace Server.Items list.Add(1060636); // exceptional } - list.Add(1060584, m_UsesRemaining.ToString()); // uses remaining: ~1_val~ + list.Add(1060584, $"{m_UsesRemaining}"); // uses remaining: ~1_val~ } public virtual void DisplayDurabilityTo(Mobile m) diff --git a/Projects/UOContent/Items/Skill Items/Lumberjack/Log.cs b/Projects/UOContent/Items/Skill Items/Lumberjack/Log.cs index 19db4c169..e3a37d000 100644 --- a/Projects/UOContent/Items/Skill Items/Lumberjack/Log.cs +++ b/Projects/UOContent/Items/Skill Items/Lumberjack/Log.cs @@ -40,7 +40,7 @@ namespace Server.Items bool ICommodity.IsDeedable => true; - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Skill Items/Magical/Misc/PotionKeg.cs b/Projects/UOContent/Items/Skill Items/Magical/Misc/PotionKeg.cs index e8a633fab..4b09592df 100644 --- a/Projects/UOContent/Items/Skill Items/Magical/Misc/PotionKeg.cs +++ b/Projects/UOContent/Items/Skill Items/Magical/Misc/PotionKeg.cs @@ -98,7 +98,7 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Skill Items/Magical/Misc/RecallRune.cs b/Projects/UOContent/Items/Skill Items/Magical/Misc/RecallRune.cs index d7d6d56fb..e04e97d16 100644 --- a/Projects/UOContent/Items/Skill Items/Magical/Misc/RecallRune.cs +++ b/Projects/UOContent/Items/Skill Items/Magical/Misc/RecallRune.cs @@ -217,7 +217,7 @@ namespace Server.Items InvalidateProperties(); } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); @@ -232,23 +232,23 @@ namespace Server.Items if (m_TargetMap == Map.Tokuno) { - list.Add(House != null ? 1063260 : 1063259, RuneFormat, desc); // ~1_val~ (Tokuno Islands)[(House)] + list.Add(House != null ? 1063260 : 1063259, $"a recall rune for {desc}"); // ~1_val~ (Tokuno Islands)[(House)] } else if (m_TargetMap == Map.Malas) { - list.Add(House != null ? 1062454 : 1060804, RuneFormat, desc); // ~1_val~ (Malas)[(House)] + list.Add(House != null ? 1062454 : 1060804, $"a recall rune for {desc}"); // ~1_val~ (Malas)[(House)] } else if (m_TargetMap == Map.Felucca) { - list.Add(House != null ? 1062452 : 1060805, RuneFormat, desc); // ~1_val~ (Felucca)[(House)] + list.Add(House != null ? 1062452 : 1060805, $"a recall rune for {desc}"); // ~1_val~ (Felucca)[(House)] } else if (m_TargetMap == Map.Trammel) { - list.Add(House != null ? 1062453 : 1060806, RuneFormat, desc); // ~1_val~ (Trammel)[(House)] + list.Add(House != null ? 1062453 : 1060806, $"a recall rune for {desc}"); // ~1_val~ (Trammel)[(House)] } else { - list.Add(House != null ? "{0} ({1})(House)" : "{0} ({1})", string.Format(RuneFormat, desc), m_TargetMap); + list.Add(House != null ? $"a recall rune for {desc} ({m_TargetMap})(House)" : $"a recall rune for {desc} ({m_TargetMap})"); } } } @@ -263,33 +263,33 @@ namespace Server.Items { LabelTo( from, - House != null ? 1063260 : 1063259, + House != null ? 1063260 : 1063259, // ~1_val~ (Tokuno Islands)[(House)] string.Format(RuneFormat, desc) - ); // ~1_val~ (Tokuno Islands)[(House)] + ); } else if (m_TargetMap == Map.Malas) { LabelTo( from, - House != null ? 1062454 : 1060804, + House != null ? 1062454 : 1060804, // ~1_val~ (Malas)[(House)] string.Format(RuneFormat, desc) - ); // ~1_val~ (Malas)[(House)] + ); } else if (m_TargetMap == Map.Felucca) { LabelTo( from, - House != null ? 1062452 : 1060805, + House != null ? 1062452 : 1060805, // ~1_val~ (Felucca)[(House)] string.Format(RuneFormat, desc) - ); // ~1_val~ (Felucca)[(House)] + ); } else if (m_TargetMap == Map.Trammel) { LabelTo( from, - House != null ? 1062453 : 1060806, + House != null ? 1062453 : 1060806, // ~1_val~ (Trammel)[(House)] string.Format(RuneFormat, desc) - ); // ~1_val~ (Trammel)[(House)] + ); } else { diff --git a/Projects/UOContent/Items/Skill Items/Magical/Runebook.cs b/Projects/UOContent/Items/Skill Items/Magical/Runebook.cs index 2088180cb..3d1ac368c 100644 --- a/Projects/UOContent/Items/Skill Items/Magical/Runebook.cs +++ b/Projects/UOContent/Items/Skill Items/Magical/Runebook.cs @@ -276,7 +276,7 @@ namespace Server.Items return false; } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Skill Items/Magical/Spellbook.cs b/Projects/UOContent/Items/Skill Items/Magical/Spellbook.cs index cbb60611b..b8b6ef6be 100644 --- a/Projects/UOContent/Items/Skill Items/Magical/Spellbook.cs +++ b/Projects/UOContent/Items/Skill Items/Magical/Spellbook.cs @@ -695,7 +695,7 @@ namespace Server.Items to.NetState.SendSpellbookContent(Serial, ItemID, BookOffset + 1, m_Content); } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); @@ -738,72 +738,72 @@ namespace Server.Items if ((prop = Attributes.WeaponDamage) != 0) { - list.Add(1060401, prop.ToString()); // damage increase ~1_val~% + list.Add(1060401, $"{prop}"); // damage increase ~1_val~% } if ((prop = Attributes.DefendChance) != 0) { - list.Add(1060408, prop.ToString()); // defense chance increase ~1_val~% + list.Add(1060408, $"{prop}"); // defense chance increase ~1_val~% } if ((prop = Attributes.BonusDex) != 0) { - list.Add(1060409, prop.ToString()); // dexterity bonus ~1_val~ + list.Add(1060409, $"{prop}"); // dexterity bonus ~1_val~ } if ((prop = Attributes.EnhancePotions) != 0) { - list.Add(1060411, prop.ToString()); // enhance potions ~1_val~% + list.Add(1060411, $"{prop}"); // enhance potions ~1_val~% } if ((prop = Attributes.CastRecovery) != 0) { - list.Add(1060412, prop.ToString()); // faster cast recovery ~1_val~ + list.Add(1060412, $"{prop}"); // faster cast recovery ~1_val~ } if ((prop = Attributes.CastSpeed) != 0) { - list.Add(1060413, prop.ToString()); // faster casting ~1_val~ + list.Add(1060413, $"{prop}"); // faster casting ~1_val~ } if ((prop = Attributes.AttackChance) != 0) { - list.Add(1060415, prop.ToString()); // hit chance increase ~1_val~% + list.Add(1060415, $"{prop}"); // hit chance increase ~1_val~% } if ((prop = Attributes.BonusHits) != 0) { - list.Add(1060431, prop.ToString()); // hit point increase ~1_val~ + list.Add(1060431, $"{prop}"); // hit point increase ~1_val~ } if ((prop = Attributes.BonusInt) != 0) { - list.Add(1060432, prop.ToString()); // intelligence bonus ~1_val~ + list.Add(1060432, $"{prop}"); // intelligence bonus ~1_val~ } if ((prop = Attributes.LowerManaCost) != 0) { - list.Add(1060433, prop.ToString()); // lower mana cost ~1_val~% + list.Add(1060433, $"{prop}"); // lower mana cost ~1_val~% } if ((prop = Attributes.LowerRegCost) != 0) { - list.Add(1060434, prop.ToString()); // lower reagent cost ~1_val~% + list.Add(1060434, $"{prop}"); // lower reagent cost ~1_val~% } if ((prop = Attributes.Luck) != 0) { - list.Add(1060436, prop.ToString()); // luck ~1_val~ + list.Add(1060436, $"{prop}"); // luck ~1_val~ } if ((prop = Attributes.BonusMana) != 0) { - list.Add(1060439, prop.ToString()); // mana increase ~1_val~ + list.Add(1060439, $"{prop}"); // mana increase ~1_val~ } if ((prop = Attributes.RegenMana) != 0) { - list.Add(1060440, prop.ToString()); // mana regeneration ~1_val~ + list.Add(1060440, $"{prop}"); // mana regeneration ~1_val~ } if (Attributes.NightSight != 0) @@ -813,17 +813,17 @@ namespace Server.Items if ((prop = Attributes.ReflectPhysical) != 0) { - list.Add(1060442, prop.ToString()); // reflect physical damage ~1_val~% + list.Add(1060442, $"{prop}"); // reflect physical damage ~1_val~% } if ((prop = Attributes.RegenStam) != 0) { - list.Add(1060443, prop.ToString()); // stamina regeneration ~1_val~ + list.Add(1060443, $"{prop}"); // stamina regeneration ~1_val~ } if ((prop = Attributes.RegenHits) != 0) { - list.Add(1060444, prop.ToString()); // hit point regeneration ~1_val~ + list.Add(1060444, $"{prop}"); // hit point regeneration ~1_val~ } if (Attributes.SpellChanneling != 0) @@ -833,30 +833,30 @@ namespace Server.Items if ((prop = Attributes.SpellDamage) != 0) { - list.Add(1060483, prop.ToString()); // spell damage increase ~1_val~% + list.Add(1060483, $"{prop}"); // spell damage increase ~1_val~% } if ((prop = Attributes.BonusStam) != 0) { - list.Add(1060484, prop.ToString()); // stamina increase ~1_val~ + list.Add(1060484, $"{prop}"); // stamina increase ~1_val~ } if ((prop = Attributes.BonusStr) != 0) { - list.Add(1060485, prop.ToString()); // strength bonus ~1_val~ + list.Add(1060485, $"{prop}"); // strength bonus ~1_val~ } if ((prop = Attributes.WeaponSpeed) != 0) { - list.Add(1060486, prop.ToString()); // swing speed increase ~1_val~% + list.Add(1060486, $"{prop}"); // swing speed increase ~1_val~% } if (Core.ML && (prop = Attributes.IncreasedKarmaLoss) != 0) { - list.Add(1075210, prop.ToString()); // Increased Karma Loss ~1val~% + list.Add(1075210, $"{prop}"); // Increased Karma Loss ~1val~% } - list.Add(1042886, SpellCount.ToString()); // ~1_NUMBERS_OF_SPELLS~ Spells + list.Add(1042886, $"{SpellCount}"); // ~1_NUMBERS_OF_SPELLS~ Spells } public override void OnSingleClick(Mobile from) diff --git a/Projects/UOContent/Items/Skill Items/Misc/RecipeScroll.cs b/Projects/UOContent/Items/Skill Items/Misc/RecipeScroll.cs index 31eeddc8c..13673cedc 100644 --- a/Projects/UOContent/Items/Skill Items/Misc/RecipeScroll.cs +++ b/Projects/UOContent/Items/Skill Items/Misc/RecipeScroll.cs @@ -42,7 +42,7 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); @@ -50,7 +50,7 @@ namespace Server.Items if (r != null) { - list.Add(1049644, r.TextDefinition.ToString()); // [~1_stuff~] + list.Add(1049644, $"{r.TextDefinition}"); // [~1_stuff~] } } diff --git a/Projects/UOContent/Items/Skill Items/Misc/RepairDeed.cs b/Projects/UOContent/Items/Skill Items/Misc/RepairDeed.cs index cf99c201c..671506b55 100644 --- a/Projects/UOContent/Items/Skill Items/Misc/RepairDeed.cs +++ b/Projects/UOContent/Items/Skill Items/Misc/RepairDeed.cs @@ -92,7 +92,7 @@ namespace Server.Items } } - public override void AddNameProperty(ObjectPropertyList list) + public override void AddNameProperty(IPropertyList list) { list.Add( 1061133, @@ -100,7 +100,7 @@ namespace Server.Items ); // A repair service contract from ~1_SKILL_TITLE~ ~2_SKILL_NAME~. } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Skill Items/Musical Instruments/BaseInstrument.cs b/Projects/UOContent/Items/Skill Items/Musical Instruments/BaseInstrument.cs index d0faa631e..ce7a15a73 100644 --- a/Projects/UOContent/Items/Skill Items/Musical Instruments/BaseInstrument.cs +++ b/Projects/UOContent/Items/Skill Items/Musical Instruments/BaseInstrument.cs @@ -359,7 +359,7 @@ namespace Server.Items m_Instruments[from] = item; } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { var oldUses = m_UsesRemaining; CheckReplenishUses(false); @@ -376,7 +376,7 @@ namespace Server.Items list.Add(1060636); // exceptional } - list.Add(1060584, m_UsesRemaining.ToString()); // uses remaining: ~1_val~ + list.Add(1060584, $"{m_UsesRemaining}"); // uses remaining: ~1_val~ if (m_ReplenishesCharges) { diff --git a/Projects/UOContent/Items/Skill Items/Ninjitsu/Fukiya.cs b/Projects/UOContent/Items/Skill Items/Ninjitsu/Fukiya.cs index 45b78a979..9411c8efe 100644 --- a/Projects/UOContent/Items/Skill Items/Ninjitsu/Fukiya.cs +++ b/Projects/UOContent/Items/Skill Items/Ninjitsu/Fukiya.cs @@ -87,11 +87,11 @@ namespace Server.Items from.MovingEffect(to, 0x2804, 5, 0, false, false); } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); - list.Add(1060584, m_UsesRemaining.ToString()); // uses remaining: ~1_val~ + list.Add(1060584, $"{m_UsesRemaining}"); // uses remaining: ~1_val~ if (m_Poison != null && m_PoisonCharges > 0) { diff --git a/Projects/UOContent/Items/Skill Items/Ninjitsu/FukiyaDarts.cs b/Projects/UOContent/Items/Skill Items/Ninjitsu/FukiyaDarts.cs index 858e9c1a7..3bdd5ca95 100644 --- a/Projects/UOContent/Items/Skill Items/Ninjitsu/FukiyaDarts.cs +++ b/Projects/UOContent/Items/Skill Items/Ninjitsu/FukiyaDarts.cs @@ -73,11 +73,11 @@ namespace Server.Items set { } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); - list.Add(1060584, m_UsesRemaining.ToString()); // uses remaining: ~1_val~ + list.Add(1060584, $"{m_UsesRemaining}"); // uses remaining: ~1_val~ if (m_Poison != null && m_PoisonCharges > 0) { diff --git a/Projects/UOContent/Items/Skill Items/Ninjitsu/LeatherNinjaBelt.cs b/Projects/UOContent/Items/Skill Items/Ninjitsu/LeatherNinjaBelt.cs index 5e58cc004..2f26f70bf 100644 --- a/Projects/UOContent/Items/Skill Items/Ninjitsu/LeatherNinjaBelt.cs +++ b/Projects/UOContent/Items/Skill Items/Ninjitsu/LeatherNinjaBelt.cs @@ -89,11 +89,11 @@ namespace Server.Items from.MovingEffect(to, 0x27AC, 1, 0, false, false); } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); - list.Add(1060584, m_UsesRemaining.ToString()); // uses remaining: ~1_val~ + list.Add(1060584, $"{m_UsesRemaining}"); // uses remaining: ~1_val~ if (m_Poison != null && m_PoisonCharges > 0) { diff --git a/Projects/UOContent/Items/Skill Items/Ninjitsu/Shuriken.cs b/Projects/UOContent/Items/Skill Items/Ninjitsu/Shuriken.cs index 5f07c665f..8e800e9cd 100644 --- a/Projects/UOContent/Items/Skill Items/Ninjitsu/Shuriken.cs +++ b/Projects/UOContent/Items/Skill Items/Ninjitsu/Shuriken.cs @@ -74,11 +74,11 @@ namespace Server.Items set { } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); - list.Add(1060584, m_UsesRemaining.ToString()); // uses remaining: ~1_val~ + list.Add(1060584, $"{m_UsesRemaining}"); // uses remaining: ~1_val~ if (m_Poison != null && m_PoisonCharges > 0) { diff --git a/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/FurnitureDyeTub.cs b/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/FurnitureDyeTub.cs index 615661514..8b403c3f7 100644 --- a/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/FurnitureDyeTub.cs +++ b/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/FurnitureDyeTub.cs @@ -29,7 +29,7 @@ namespace Server.Items base.OnDoubleClick(from); } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/LeatherDyeTub.cs b/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/LeatherDyeTub.cs index 85c65be00..2e94d43e7 100644 --- a/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/LeatherDyeTub.cs +++ b/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/LeatherDyeTub.cs @@ -30,7 +30,7 @@ namespace Server.Items base.OnDoubleClick(from); } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/MetallicLeatherDyeTub.cs b/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/MetallicLeatherDyeTub.cs index 28c81f2ae..18056ff06 100644 --- a/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/MetallicLeatherDyeTub.cs +++ b/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/MetallicLeatherDyeTub.cs @@ -14,7 +14,7 @@ namespace Server.Items public override bool MetallicHues => true; - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/RewardBlackDyeTub.cs b/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/RewardBlackDyeTub.cs index a0f75f358..c8c0ef7c1 100644 --- a/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/RewardBlackDyeTub.cs +++ b/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/RewardBlackDyeTub.cs @@ -30,7 +30,7 @@ namespace Server.Items base.OnDoubleClick(from); } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/RunebookDyeTub.cs b/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/RunebookDyeTub.cs index 7adee4071..6d202d49a 100644 --- a/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/RunebookDyeTub.cs +++ b/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/RunebookDyeTub.cs @@ -30,7 +30,7 @@ namespace Server.Items base.OnDoubleClick(from); } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/SpecialDyeTub.cs b/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/SpecialDyeTub.cs index ec30f803d..34630ac87 100644 --- a/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/SpecialDyeTub.cs +++ b/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/SpecialDyeTub.cs @@ -26,7 +26,7 @@ namespace Server.Items base.OnDoubleClick(from); } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/StatuetteDyeTub.cs b/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/StatuetteDyeTub.cs index a988c8d0a..9fa04835a 100644 --- a/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/StatuetteDyeTub.cs +++ b/Projects/UOContent/Items/Skill Items/Tailor Items/Dyetubs/StatuetteDyeTub.cs @@ -30,7 +30,7 @@ namespace Server.Items base.OnDoubleClick(from); } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Skill Items/Tools/BaseTool.cs b/Projects/UOContent/Items/Skill Items/Tools/BaseTool.cs index e484fc193..5565c1cf7 100644 --- a/Projects/UOContent/Items/Skill Items/Tools/BaseTool.cs +++ b/Projects/UOContent/Items/Skill Items/Tools/BaseTool.cs @@ -114,7 +114,7 @@ namespace Server.Items return 100; } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); @@ -127,7 +127,7 @@ namespace Server.Items list.Add(1060636); // exceptional } - list.Add(1060584, m_UsesRemaining.ToString()); // uses remaining: ~1_val~ + list.Add(1060584, $"{m_UsesRemaining}"); // uses remaining: ~1_val~ } public virtual void DisplayDurabilityTo(Mobile m) diff --git a/Projects/UOContent/Items/Skill Items/Tools/RunicHammer.cs b/Projects/UOContent/Items/Skill Items/Tools/RunicHammer.cs index f3051982f..5a1604b83 100644 --- a/Projects/UOContent/Items/Skill Items/Tools/RunicHammer.cs +++ b/Projects/UOContent/Items/Skill Items/Tools/RunicHammer.cs @@ -42,7 +42,7 @@ namespace Server.Items } } - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); diff --git a/Projects/UOContent/Items/Skill Items/Tools/RunicSewingKit.cs b/Projects/UOContent/Items/Skill Items/Tools/RunicSewingKit.cs index f980d2391..16a2d49b2 100644 --- a/Projects/UOContent/Items/Skill Items/Tools/RunicSewingKit.cs +++ b/Projects/UOContent/Items/Skill Items/Tools/RunicSewingKit.cs @@ -24,7 +24,7 @@ namespace Server.Items public override CraftSystem CraftSystem => DefTailoring.CraftSystem; - public override void AddNameProperty(ObjectPropertyList list) + public override void AddNameProperty(IPropertyList list) { var v = " "; diff --git a/Projects/UOContent/Items/Special/8th Anniversary Items/Dawn's Music Box/DawnsMusicBox.cs b/Projects/UOContent/Items/Special/8th Anniversary Items/Dawn's Music Box/DawnsMusicBox.cs index bff115f2b..206712650 100644 --- a/Projects/UOContent/Items/Special/8th Anniversary Items/Dawn's Music Box/DawnsMusicBox.cs +++ b/Projects/UOContent/Items/Special/8th Anniversary Items/Dawn's Music Box/DawnsMusicBox.cs @@ -141,7 +141,7 @@ namespace Server.Items box.Tracks.AddRange(Tracks); } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); @@ -169,17 +169,17 @@ namespace Server.Items if (commonSongs > 0) { - list.Add(1075234, commonSongs.ToString()); // ~1_NUMBER~ Common Tracks + list.Add(1075234, $"{commonSongs}"); // ~1_NUMBER~ Common Tracks } if (uncommonSongs > 0) { - list.Add(1075235, uncommonSongs.ToString()); // ~1_NUMBER~ Uncommon Tracks + list.Add(1075235, $"{uncommonSongs}"); // ~1_NUMBER~ Uncommon Tracks } if (rareSongs > 0) { - list.Add(1075236, rareSongs.ToString()); // ~1_NUMBER~ Rare Tracks + list.Add(1075236, $"{rareSongs}"); // ~1_NUMBER~ Rare Tracks } } diff --git a/Projects/UOContent/Items/Special/8th Anniversary Items/Dawn's Music Box/DawnsMusicGear.cs b/Projects/UOContent/Items/Special/8th Anniversary Items/Dawn's Music Box/DawnsMusicGear.cs index 502673f23..85105db91 100644 --- a/Projects/UOContent/Items/Special/8th Anniversary Items/Dawn's Music Box/DawnsMusicGear.cs +++ b/Projects/UOContent/Items/Special/8th Anniversary Items/Dawn's Music Box/DawnsMusicGear.cs @@ -32,7 +32,7 @@ namespace Server.Items [CommandProperty(AccessLevel.GameMaster)] public MusicName Music { get; set; } - public override void AddNameProperty(ObjectPropertyList list) + public override void AddNameProperty(IPropertyList list) { var info = DawnsMusicBox.GetInfo(Music); diff --git a/Projects/UOContent/Items/Special/8th Anniversary Items/FountainOfLife.cs b/Projects/UOContent/Items/Special/8th Anniversary Items/FountainOfLife.cs index a6e2d7e86..8ffa9aaf1 100644 --- a/Projects/UOContent/Items/Special/8th Anniversary Items/FountainOfLife.cs +++ b/Projects/UOContent/Items/Special/8th Anniversary Items/FountainOfLife.cs @@ -20,7 +20,7 @@ namespace Server.Items public override bool Dye(Mobile from, DyeTub sender) => false; - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); @@ -121,11 +121,11 @@ namespace Server.Items return false; } - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); - list.Add(1075217, m_Charges.ToString()); // ~1_val~ charges remaining + list.Add(1075217, $"{m_Charges}"); // ~1_val~ charges remaining } public override void OnDelete() diff --git a/Projects/UOContent/Items/Special/8th Anniversary Items/Talismans.cs b/Projects/UOContent/Items/Special/8th Anniversary Items/Talismans.cs index 8a50d7b88..7c8e49129 100644 --- a/Projects/UOContent/Items/Special/8th Anniversary Items/Talismans.cs +++ b/Projects/UOContent/Items/Special/8th Anniversary Items/Talismans.cs @@ -27,7 +27,7 @@ namespace Server.Items public virtual TalismanForm Form => TalismanForm.Squirrel; - public override void AddNameProperty(ObjectPropertyList list) + public override void AddNameProperty(IPropertyList list) { list.Add(1075200, $"#{(int)Form}"); } diff --git a/Projects/UOContent/Items/Special/Bulk Order Rewards/Blacksmithy/AncientSmithyHammer.cs b/Projects/UOContent/Items/Special/Bulk Order Rewards/Blacksmithy/AncientSmithyHammer.cs index 0a053bc94..b30e7b83d 100644 --- a/Projects/UOContent/Items/Special/Bulk Order Rewards/Blacksmithy/AncientSmithyHammer.cs +++ b/Projects/UOContent/Items/Special/Bulk Order Rewards/Blacksmithy/AncientSmithyHammer.cs @@ -73,13 +73,13 @@ namespace Server.Items m_SkillMod = null; } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); if (m_Bonus != 0) { - list.Add(1060451, "#1042354\t{0}", m_Bonus.ToString()); // ~1_skillname~ +~2_val~ + list.Add(1060451, $"#1042354\t{m_Bonus}"); // ~1_skillname~ +~2_val~ } } diff --git a/Projects/UOContent/Items/Special/Bulk Order Rewards/Blacksmithy/GlovesOfMining.cs b/Projects/UOContent/Items/Special/Bulk Order Rewards/Blacksmithy/GlovesOfMining.cs index e34c1f0ce..959aeca8c 100644 --- a/Projects/UOContent/Items/Special/Bulk Order Rewards/Blacksmithy/GlovesOfMining.cs +++ b/Projects/UOContent/Items/Special/Bulk Order Rewards/Blacksmithy/GlovesOfMining.cs @@ -196,13 +196,13 @@ namespace Server.Items m_SkillMod = null; } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); if (m_Bonus != 0) { - list.Add(1062005, m_Bonus.ToString()); // mining bonus +~1_val~ + list.Add(1062005, $"{m_Bonus}"); // mining bonus +~1_val~ } } diff --git a/Projects/UOContent/Items/Special/Bulk Order Rewards/Blacksmithy/PowderOfTemperament.cs b/Projects/UOContent/Items/Special/Bulk Order Rewards/Blacksmithy/PowderOfTemperament.cs index cb64a2583..c08ed66ae 100644 --- a/Projects/UOContent/Items/Special/Bulk Order Rewards/Blacksmithy/PowderOfTemperament.cs +++ b/Projects/UOContent/Items/Special/Bulk Order Rewards/Blacksmithy/PowderOfTemperament.cs @@ -62,11 +62,11 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); - list.Add(1060584, m_UsesRemaining.ToString()); // uses remaining: ~1_val~ + list.Add(1060584, $"{m_UsesRemaining}"); // uses remaining: ~1_val~ } public virtual void DisplayDurabilityTo(Mobile m) diff --git a/Projects/UOContent/Items/Special/Gifts/RoseOfTrinsic.cs b/Projects/UOContent/Items/Special/Gifts/RoseOfTrinsic.cs index 33bb6fd86..1fe6f266d 100644 --- a/Projects/UOContent/Items/Special/Gifts/RoseOfTrinsic.cs +++ b/Projects/UOContent/Items/Special/Gifts/RoseOfTrinsic.cs @@ -65,11 +65,11 @@ namespace Server.Items [CommandProperty(AccessLevel.GameMaster)] public SecureLevel Level { get; set; } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); - list.Add(1062925, Petals.ToString()); // Petals: ~1_COUNT~ + list.Add(1062925, $"{Petals}"); // Petals: ~1_COUNT~ } public override void GetContextMenuEntries(Mobile from, List list) diff --git a/Projects/UOContent/Items/Special/HeritageToken.cs b/Projects/UOContent/Items/Special/HeritageToken.cs index 2f84d86c5..bf3273dc2 100644 --- a/Projects/UOContent/Items/Special/HeritageToken.cs +++ b/Projects/UOContent/Items/Special/HeritageToken.cs @@ -30,7 +30,7 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Special/Holiday/Snowman.cs b/Projects/UOContent/Items/Special/Holiday/Snowman.cs index f94f8d02b..5033f162e 100644 --- a/Projects/UOContent/Items/Special/Holiday/Snowman.cs +++ b/Projects/UOContent/Items/Special/Holiday/Snowman.cs @@ -117,7 +117,7 @@ namespace Server.Items public static string GetRandomTitle() => titles.RandomElement(); - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Special/House Raffle/HouseRaffleDeed.cs b/Projects/UOContent/Items/Special/House Raffle/HouseRaffleDeed.cs index 92238b11a..5d9ccd8dd 100644 --- a/Projects/UOContent/Items/Special/House Raffle/HouseRaffleDeed.cs +++ b/Projects/UOContent/Items/Special/House Raffle/HouseRaffleDeed.cs @@ -85,19 +85,18 @@ namespace Server.Items public bool ValidLocation() => m_PlotLocation != Point3D.Zero && m_Facet != null && m_Facet != Map.Internal; - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); if (ValidLocation()) { list.Add( - 1060658, - "location\t{0}", - HouseRaffleStone.FormatLocation(m_PlotLocation, m_Facet, false) - ); // ~1_val~: ~2_val~ - list.Add(1060659, "facet\t{0}", m_Facet); // ~1_val~: ~2_val~ - list.Add(1150486); // [Marked Item] + 1060658, // ~1_val~: ~2_val~ + $"location\t{HouseRaffleStone.FormatLocation(m_PlotLocation, m_Facet, false)}" + ); + list.Add(1060659, $"facet\t{m_Facet}"); // ~1_val~: ~2_val~ + list.Add(1150486); // [Marked Item] } if (IsExpired) diff --git a/Projects/UOContent/Items/Special/House Raffle/HouseRaffleStone.cs b/Projects/UOContent/Items/Special/House Raffle/HouseRaffleStone.cs index 248b24751..57f76efa7 100644 --- a/Projects/UOContent/Items/Special/House Raffle/HouseRaffleStone.cs +++ b/Projects/UOContent/Items/Special/House Raffle/HouseRaffleStone.cs @@ -398,7 +398,7 @@ namespace Server.Items public string FormatPrice() => m_TicketPrice == 0 ? "FREE" : $"{m_TicketPrice} gold"; - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); @@ -411,13 +411,13 @@ namespace Server.Items { case HouseRaffleState.Active: { - list.Add(1060658, "ticket price\t{0}", FormatPrice()); // ~1_val~: ~2_val~ - list.Add(1060659, "ends\t{0}", m_Started + m_Duration); // ~1_val~: ~2_val~ + list.Add(1060658, $"ticket price\t{FormatPrice()}"); // ~1_val~: ~2_val~ + list.Add(1060659, $"ends\t{m_Started + m_Duration}"); // ~1_val~: ~2_val~ break; } case HouseRaffleState.Completed: { - list.Add(1060658, "winner\t{0}", m_Winner == null ? "unknown" : m_Winner.Name); // ~1_val~: ~2_val~ + list.Add(1060658, $"winner\t{m_Winner?.Name ?? "Unknown"}"); // ~1_val~: ~2_val~ break; } } @@ -438,9 +438,9 @@ namespace Server.Items { LabelTo( from, - 1060658, - $"Winner\t{(m_Winner == null ? "Unknown" : m_Winner.Name)}" - ); // ~1_val~: ~2_val~ + 1060658, // ~1_val~: ~2_val~ + $"Winner\t{m_Winner?.Name ?? "Unknown"}" + ); break; } } diff --git a/Projects/UOContent/Items/Special/MiniHouses.cs b/Projects/UOContent/Items/Special/MiniHouses.cs index 651f6d3f3..cf18f61d4 100644 --- a/Projects/UOContent/Items/Special/MiniHouses.cs +++ b/Projects/UOContent/Items/Special/MiniHouses.cs @@ -115,7 +115,7 @@ namespace Server.Items public override BaseAddon Addon => new MiniHouseAddon(m_Type); public override int LabelNumber => 1062096; // a mini house deed - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Special/MonsterStatuette.cs b/Projects/UOContent/Items/Special/MonsterStatuette.cs index 1767b0df0..ec7c8e887 100644 --- a/Projects/UOContent/Items/Special/MonsterStatuette.cs +++ b/Projects/UOContent/Items/Special/MonsterStatuette.cs @@ -227,7 +227,7 @@ namespace Server.Items base.OnMovement(m, oldLocation); } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Special/Rares/Containers/BaseWaterContainer.cs b/Projects/UOContent/Items/Special/Rares/Containers/BaseWaterContainer.cs index 9c353c6b5..6c427bb1c 100644 --- a/Projects/UOContent/Items/Special/Rares/Containers/BaseWaterContainer.cs +++ b/Projects/UOContent/Items/Special/Rares/Containers/BaseWaterContainer.cs @@ -101,7 +101,7 @@ } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { if (IsEmpty) { diff --git a/Projects/UOContent/Items/Special/Solen Items/BagOfSending.cs b/Projects/UOContent/Items/Special/Solen Items/BagOfSending.cs index 6deb51f52..710c31b94 100644 --- a/Projects/UOContent/Items/Special/Solen Items/BagOfSending.cs +++ b/Projects/UOContent/Items/Special/Solen Items/BagOfSending.cs @@ -102,11 +102,11 @@ namespace Server.Items }; } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); - list.Add(1060741, m_Charges.ToString()); // charges: ~1_val~ + list.Add(1060741, $"{m_Charges}"); // charges: ~1_val~ } public override void OnSingleClick(Mobile from) diff --git a/Projects/UOContent/Items/Special/Solen Items/BallOfSummoning.cs b/Projects/UOContent/Items/Special/Solen Items/BallOfSummoning.cs index 9f21565a7..ecc6bf688 100644 --- a/Projects/UOContent/Items/Special/Solen Items/BallOfSummoning.cs +++ b/Projects/UOContent/Items/Special/Solen Items/BallOfSummoning.cs @@ -85,7 +85,7 @@ namespace Server.Items public string TranslocationItemName => "crystal ball of pet summoning"; - public override void AddNameProperty(ObjectPropertyList list) + public override void AddNameProperty(IPropertyList list) { list.Add( 1054131, diff --git a/Projects/UOContent/Items/Special/Solen Items/BraceletOfBinding.cs b/Projects/UOContent/Items/Special/Solen Items/BraceletOfBinding.cs index 8cd5832cf..8bec81198 100644 --- a/Projects/UOContent/Items/Special/Solen Items/BraceletOfBinding.cs +++ b/Projects/UOContent/Items/Special/Solen Items/BraceletOfBinding.cs @@ -89,7 +89,7 @@ namespace Server.Items public string TranslocationItemName => "bracelet of binding"; - public override void AddNameProperty(ObjectPropertyList list) + public override void AddNameProperty(IPropertyList list) { list.Add( 1054000, diff --git a/Projects/UOContent/Items/Special/SoulStone.cs b/Projects/UOContent/Items/Special/SoulStone.cs index 15ffc2862..08c1dabb3 100644 --- a/Projects/UOContent/Items/Special/SoulStone.cs +++ b/Projects/UOContent/Items/Special/SoulStone.cs @@ -121,21 +121,19 @@ namespace Server.Items [CommandProperty(AccessLevel.GameMaster)] public SecureLevel Level { get; set; } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); if (!IsEmpty) { list.Add( - 1070721, - "#{0}\t{1:F1}", - AosSkillBonuses.GetLabel(Skill), - SkillValue - ); // Skill stored: ~1_skillname~ ~2_skillamount~ + 1070721, // Skill stored: ~1_skillname~ ~2_skillamount~ + $"#{AosSkillBonuses.GetLabel(Skill)}\t{SkillValue:F1}" + ); } - list.Add(1041602, "{0}", LastUserName ?? $"#{1074235}"); // Owner: ~1_val~ + list.Add(1041602, LastUserName ?? $"#{1074235}"); // Owner: ~1_val~ } private static bool CheckCombat(Mobile m, TimeSpan time) @@ -966,11 +964,11 @@ namespace Server.Items set { } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); - list.Add(1060584, m_UsesRemaining.ToString()); // uses remaining: ~1_val~ + list.Add(1060584, $"{m_UsesRemaining}"); // uses remaining: ~1_val~ } public override void Serialize(IGenericWriter writer) @@ -1094,7 +1092,7 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Special/Special Scrolls/PowerScroll.cs b/Projects/UOContent/Items/Special/Special Scrolls/PowerScroll.cs index 1dd35b8f3..e15007091 100644 --- a/Projects/UOContent/Items/Special/Special Scrolls/PowerScroll.cs +++ b/Projects/UOContent/Items/Special/Special Scrolls/PowerScroll.cs @@ -160,7 +160,7 @@ namespace Server.Items return new PowerScroll(skillName, 100 + Utility.RandomMinMax(min, max) * 5); } - public override void AddNameProperty(ObjectPropertyList list) + public override void AddNameProperty(IPropertyList list) { var level = (Value - 105.0) / 5.0; @@ -175,7 +175,7 @@ namespace Server.Items } else { - list.Add("a power scroll of {0} ({1} Skill)", GetName(), Value); + list.Add($"a power scroll of {GetName()} ({Value} Skill)"); } } @@ -189,7 +189,7 @@ namespace Server.Items } else { - LabelTo(from, "a power scroll of {0} ({1} Skill)", GetName(), Value); + LabelTo(from, $"a power scroll of {GetName()} ({Value} Skill)"); } } diff --git a/Projects/UOContent/Items/Special/Special Scrolls/ScrollofAlacrity.cs b/Projects/UOContent/Items/Special/Special Scrolls/ScrollofAlacrity.cs index d6b5453c6..39e346c7f 100644 --- a/Projects/UOContent/Items/Special/Special Scrolls/ScrollofAlacrity.cs +++ b/Projects/UOContent/Items/Special/Special Scrolls/ScrollofAlacrity.cs @@ -29,11 +29,11 @@ namespace Server.Items public override string DefaultTitle => "Scroll of Alacrity:"; - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); - list.Add(1071345, "{0} 15 Minutes", GetName()); // Skill: ~1_val~ + list.Add(1071345, $"{GetName()} 15 Minutes"); // Skill: ~1_val~ } public override bool CanUse(Mobile from) diff --git a/Projects/UOContent/Items/Special/Special Scrolls/ScrollofTranscendence.cs b/Projects/UOContent/Items/Special/Special Scrolls/ScrollofTranscendence.cs index 80f44cc3e..e013aa399 100644 --- a/Projects/UOContent/Items/Special/Special Scrolls/ScrollofTranscendence.cs +++ b/Projects/UOContent/Items/Special/Special Scrolls/ScrollofTranscendence.cs @@ -32,7 +32,7 @@ namespace Server.Items public static ScrollofTranscendence CreateRandom(int min, int max) => new(Utility.RandomSkill(), Utility.RandomMinMax(min, max) * 0.1); - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); list.Add(1076759, $"{GetName()}\t{Value:0.#} Skill Points"); diff --git a/Projects/UOContent/Items/Special/Special Scrolls/StatScroll.cs b/Projects/UOContent/Items/Special/Special Scrolls/StatScroll.cs index eabd749db..2b16cf501 100644 --- a/Projects/UOContent/Items/Special/Special Scrolls/StatScroll.cs +++ b/Projects/UOContent/Items/Special/Special Scrolls/StatScroll.cs @@ -43,7 +43,7 @@ namespace Server.Items public override string DefaultTitle => $"Power Scroll ({((int)Value - 225 >= 0 ? "+" : "")}{(int)Value - 225} Maximum Stats):"; - public override void AddNameProperty(ObjectPropertyList list) + public override void AddNameProperty(IPropertyList list) { var level = ((int)Value - 230) / 5; @@ -59,7 +59,8 @@ namespace Server.Items } else { - list.Add("a scroll of power ({0}{1} Maximum Stats)", Value - 225 >= 0 ? "+" : "", Value - 225); + var diff = Value - 225; + list.Add($"a scroll of power ({(diff >= 0 ? "+" : "")}{diff} Maximum Stats)"); } } @@ -73,7 +74,8 @@ namespace Server.Items } else { - LabelTo(from, "a scroll of power ({0}{1} Maximum Stats)", Value - 225 >= 0 ? "+" : "", Value - 225); + var diff = Value - 225; + LabelTo(from, $"a scroll of power ({(diff >= 0 ? "+" : "")}{diff} Maximum Stats)"); } } diff --git a/Projects/UOContent/Items/Special/Valentines/2007/ValentinesCard.cs b/Projects/UOContent/Items/Special/Valentines/2007/ValentinesCard.cs index 7e851da24..27dff00b5 100644 --- a/Projects/UOContent/Items/Special/Valentines/2007/ValentinesCard.cs +++ b/Projects/UOContent/Items/Special/Valentines/2007/ValentinesCard.cs @@ -52,7 +52,7 @@ namespace Server.Items * */ - public override void AddNameProperty(ObjectPropertyList list) + public override void AddNameProperty(IPropertyList list) { list.Add(m_LabelNumber, $"{m_To ?? Unsigned}\t{m_From ?? Unsigned}"); } diff --git a/Projects/UOContent/Items/Special/Veteran Rewards/AnkhOfSacrifice.cs b/Projects/UOContent/Items/Special/Veteran Rewards/AnkhOfSacrifice.cs index 1bd7ce1bc..ff7b6527a 100644 --- a/Projects/UOContent/Items/Special/Veteran Rewards/AnkhOfSacrifice.cs +++ b/Projects/UOContent/Items/Special/Veteran Rewards/AnkhOfSacrifice.cs @@ -338,7 +338,7 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Special/Veteran Rewards/Banner.cs b/Projects/UOContent/Items/Special/Veteran Rewards/Banner.cs index f102d7441..6cf4d1125 100644 --- a/Projects/UOContent/Items/Special/Veteran Rewards/Banner.cs +++ b/Projects/UOContent/Items/Special/Veteran Rewards/Banner.cs @@ -74,7 +74,7 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); @@ -155,7 +155,7 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Special/Veteran Rewards/BloodyPentagram.cs b/Projects/UOContent/Items/Special/Veteran Rewards/BloodyPentagram.cs index be9f47b1d..5d5e420db 100644 --- a/Projects/UOContent/Items/Special/Veteran Rewards/BloodyPentagram.cs +++ b/Projects/UOContent/Items/Special/Veteran Rewards/BloodyPentagram.cs @@ -168,7 +168,7 @@ namespace Server.Items base.OnDoubleClick(from); } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Special/Veteran Rewards/Brazier.cs b/Projects/UOContent/Items/Special/Veteran Rewards/Brazier.cs index ad6232377..31086b084 100644 --- a/Projects/UOContent/Items/Special/Veteran Rewards/Brazier.cs +++ b/Projects/UOContent/Items/Special/Veteran Rewards/Brazier.cs @@ -107,7 +107,7 @@ namespace Server.Items m_Fire?.MoveToWorld(new Point3D(X, Y, Z + ItemData.Height), Map); } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); @@ -184,7 +184,7 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Special/Veteran Rewards/Cannon.cs b/Projects/UOContent/Items/Special/Veteran Rewards/Cannon.cs index 4f55b12a1..50034e814 100644 --- a/Projects/UOContent/Items/Special/Veteran Rewards/Cannon.cs +++ b/Projects/UOContent/Items/Special/Veteran Rewards/Cannon.cs @@ -16,7 +16,7 @@ namespace Server.Items public override int LabelNumber => 1076157; // Decorative Cannon - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); @@ -27,7 +27,7 @@ namespace Server.Items list.Add(1076223); // 7th Year Veteran Reward } - list.Add(1076207, addon.Charges.ToString()); // Remaining Charges: ~1_val~ + list.Add(1076207, $"{addon.Charges}"); // Remaining Charges: ~1_val~ } } @@ -462,7 +462,7 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); @@ -471,7 +471,7 @@ namespace Server.Items list.Add(1076223); // 7th Year Veteran Reward } - list.Add(1076207, m_Charges.ToString()); // Remaining Charges: ~1_val~ + list.Add(1076207, $"{m_Charges}"); // Remaining Charges: ~1_val~ } public override void OnDoubleClick(Mobile from) diff --git a/Projects/UOContent/Items/Special/Veteran Rewards/CommodityDeedBox.cs b/Projects/UOContent/Items/Special/Veteran Rewards/CommodityDeedBox.cs index a9d99e5a0..8496a9ed4 100644 --- a/Projects/UOContent/Items/Special/Veteran Rewards/CommodityDeedBox.cs +++ b/Projects/UOContent/Items/Special/Veteran Rewards/CommodityDeedBox.cs @@ -32,7 +32,7 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Special/Veteran Rewards/ContestMiniHouse.cs b/Projects/UOContent/Items/Special/Veteran Rewards/ContestMiniHouse.cs index 753ae19ec..e978d9956 100644 --- a/Projects/UOContent/Items/Special/Veteran Rewards/ContestMiniHouse.cs +++ b/Projects/UOContent/Items/Special/Veteran Rewards/ContestMiniHouse.cs @@ -111,7 +111,7 @@ namespace Server.Items base.OnDoubleClick(from); } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Special/Veteran Rewards/DecorativeShield.cs b/Projects/UOContent/Items/Special/Veteran Rewards/DecorativeShield.cs index 71f5da8f8..dfebe6dfa 100644 --- a/Projects/UOContent/Items/Special/Veteran Rewards/DecorativeShield.cs +++ b/Projects/UOContent/Items/Special/Veteran Rewards/DecorativeShield.cs @@ -59,7 +59,7 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); @@ -140,7 +140,7 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Special/Veteran Rewards/FlamingHead.cs b/Projects/UOContent/Items/Special/Veteran Rewards/FlamingHead.cs index 5e1752e6a..fdc58513b 100644 --- a/Projects/UOContent/Items/Special/Veteran Rewards/FlamingHead.cs +++ b/Projects/UOContent/Items/Special/Veteran Rewards/FlamingHead.cs @@ -73,7 +73,7 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); @@ -154,7 +154,7 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Special/Veteran Rewards/HangingSkeleton.cs b/Projects/UOContent/Items/Special/Veteran Rewards/HangingSkeleton.cs index b46114ff2..b1f53b2ac 100644 --- a/Projects/UOContent/Items/Special/Veteran Rewards/HangingSkeleton.cs +++ b/Projects/UOContent/Items/Special/Veteran Rewards/HangingSkeleton.cs @@ -73,7 +73,7 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); @@ -154,7 +154,7 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Special/Veteran Rewards/MiningCart.cs b/Projects/UOContent/Items/Special/Veteran Rewards/MiningCart.cs index 0cb2917e8..116d7f54e 100644 --- a/Projects/UOContent/Items/Special/Veteran Rewards/MiningCart.cs +++ b/Projects/UOContent/Items/Special/Veteran Rewards/MiningCart.cs @@ -359,7 +359,7 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Special/Veteran Rewards/MinotaurStatue.cs b/Projects/UOContent/Items/Special/Veteran Rewards/MinotaurStatue.cs index 3e8129b20..9cf8086a0 100644 --- a/Projects/UOContent/Items/Special/Veteran Rewards/MinotaurStatue.cs +++ b/Projects/UOContent/Items/Special/Veteran Rewards/MinotaurStatue.cs @@ -160,7 +160,7 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Special/Veteran Rewards/PottedCactus.cs b/Projects/UOContent/Items/Special/Veteran Rewards/PottedCactus.cs index 80647576c..1c9ac09cb 100644 --- a/Projects/UOContent/Items/Special/Veteran Rewards/PottedCactus.cs +++ b/Projects/UOContent/Items/Special/Veteran Rewards/PottedCactus.cs @@ -102,7 +102,7 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Special/Veteran Rewards/StoneAnkh.cs b/Projects/UOContent/Items/Special/Veteran Rewards/StoneAnkh.cs index 33aa414b7..bde1d8e2f 100644 --- a/Projects/UOContent/Items/Special/Veteran Rewards/StoneAnkh.cs +++ b/Projects/UOContent/Items/Special/Veteran Rewards/StoneAnkh.cs @@ -15,7 +15,7 @@ namespace Server.Items public override bool ForceShowProperties => ObjectPropertyList.Enabled; - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); @@ -90,7 +90,7 @@ namespace Server.Items from.SendLocalizedMessage(500489); // You can't use an axe on that. } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); @@ -202,7 +202,7 @@ namespace Server.Items base.OnDoubleClick(m); } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Special/Veteran Rewards/TreeStump.cs b/Projects/UOContent/Items/Special/Veteran Rewards/TreeStump.cs index c9c32ede4..01bef3ce5 100644 --- a/Projects/UOContent/Items/Special/Veteran Rewards/TreeStump.cs +++ b/Projects/UOContent/Items/Special/Veteran Rewards/TreeStump.cs @@ -250,7 +250,7 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Special/Veteran Rewards/WallBanner.cs b/Projects/UOContent/Items/Special/Veteran Rewards/WallBanner.cs index cced8f9cb..132b9ae39 100644 --- a/Projects/UOContent/Items/Special/Veteran Rewards/WallBanner.cs +++ b/Projects/UOContent/Items/Special/Veteran Rewards/WallBanner.cs @@ -302,7 +302,7 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Items/Special/Veteran Rewards/WeaponEngravingTool.cs b/Projects/UOContent/Items/Special/Veteran Rewards/WeaponEngravingTool.cs index a9603d6af..14dacdb02 100644 --- a/Projects/UOContent/Items/Special/Veteran Rewards/WeaponEngravingTool.cs +++ b/Projects/UOContent/Items/Special/Veteran Rewards/WeaponEngravingTool.cs @@ -99,7 +99,7 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); @@ -110,7 +110,7 @@ namespace Server.Items if (ShowUsesRemaining) { - list.Add(1060584, m_UsesRemaining.ToString()); // uses remaining: ~1_val~ + list.Add(1060584, $"{m_UsesRemaining}"); // uses remaining: ~1_val~ } } diff --git a/Projects/UOContent/Items/Talismans/BaseTalisman.cs b/Projects/UOContent/Items/Talismans/BaseTalisman.cs index fe338037f..5b0ffe5b0 100644 --- a/Projects/UOContent/Items/Talismans/BaseTalisman.cs +++ b/Projects/UOContent/Items/Talismans/BaseTalisman.cs @@ -549,7 +549,7 @@ namespace Server.Items } } - public override void AddNameProperty(ObjectPropertyList list) + public override void AddNameProperty(IPropertyList list) { if (ForceShowName) { @@ -572,7 +572,7 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); @@ -595,7 +595,7 @@ namespace Server.Items { if (m_ChargeTime > 0) { - list.Add(1074884, m_ChargeTime.ToString()); // Charge time left: ~1_val~ + list.Add(1074884, $"{m_ChargeTime}"); // Charge time left: ~1_val~ } else { @@ -608,41 +608,33 @@ namespace Server.Items if (m_Killer?.IsEmpty == false && m_Killer.Amount > 0) { list.Add( - 1072388, - "{0}\t{1}", - m_Killer.Name?.ToString() ?? "Unknown", - m_Killer.Amount - ); // ~1_NAME~ Killer: +~2_val~% + 1072388, // ~1_NAME~ Killer: +~2_val~% + $"{m_Killer.Name ?? "Unknown"}\t{m_Killer.Amount}" + ); } if (m_Protection?.IsEmpty == false && m_Protection.Amount > 0) { list.Add( - 1072387, - "{0}\t{1}", - m_Protection.Name?.ToString() ?? "Unknown", - m_Protection.Amount - ); // ~1_NAME~ Protection: +~2_val~% + 1072387, // ~1_NAME~ Protection: +~2_val~% + $"{m_Protection.Name ?? "Unknown"}\t{m_Protection.Amount}" + ); } if (m_ExceptionalBonus != 0) { list.Add( - 1072395, - "#{0}\t{1}", - AosSkillBonuses.GetLabel(m_Skill), - m_ExceptionalBonus - ); // ~1_NAME~ Exceptional Bonus: ~2_val~% + 1072395, // ~1_NAME~ Exceptional Bonus: ~2_val~% + $"#{AosSkillBonuses.GetLabel(m_Skill)}\t{m_ExceptionalBonus}" + ); } if (m_SuccessBonus != 0) { list.Add( - 1072394, - "#{0}\t{1}", - AosSkillBonuses.GetLabel(m_Skill), - m_SuccessBonus - ); // ~1_NAME~ Bonus: ~2_val~% + 1072394, // ~1_NAME~ Bonus: ~2_val~% + $"#{AosSkillBonuses.GetLabel(m_Skill)}\t{m_SuccessBonus}" + ); } SkillBonuses.GetProperties(list); @@ -651,72 +643,72 @@ namespace Server.Items if ((prop = Attributes.WeaponDamage) != 0) { - list.Add(1060401, prop.ToString()); // damage increase ~1_val~% + list.Add(1060401, $"{prop}"); // damage increase ~1_val~% } if ((prop = Attributes.DefendChance) != 0) { - list.Add(1060408, prop.ToString()); // defense chance increase ~1_val~% + list.Add(1060408, $"{prop}"); // defense chance increase ~1_val~% } if ((prop = Attributes.BonusDex) != 0) { - list.Add(1060409, prop.ToString()); // dexterity bonus ~1_val~ + list.Add(1060409, $"{prop}"); // dexterity bonus ~1_val~ } if ((prop = Attributes.EnhancePotions) != 0) { - list.Add(1060411, prop.ToString()); // enhance potions ~1_val~% + list.Add(1060411, $"{prop}"); // enhance potions ~1_val~% } if ((prop = Attributes.CastRecovery) != 0) { - list.Add(1060412, prop.ToString()); // faster cast recovery ~1_val~ + list.Add(1060412, $"{prop}"); // faster cast recovery ~1_val~ } if ((prop = Attributes.CastSpeed) != 0) { - list.Add(1060413, prop.ToString()); // faster casting ~1_val~ + list.Add(1060413, $"{prop}"); // faster casting ~1_val~ } if ((prop = Attributes.AttackChance) != 0) { - list.Add(1060415, prop.ToString()); // hit chance increase ~1_val~% + list.Add(1060415, $"{prop}"); // hit chance increase ~1_val~% } if ((prop = Attributes.BonusHits) != 0) { - list.Add(1060431, prop.ToString()); // hit point increase ~1_val~ + list.Add(1060431, $"{prop}"); // hit point increase ~1_val~ } if ((prop = Attributes.BonusInt) != 0) { - list.Add(1060432, prop.ToString()); // intelligence bonus ~1_val~ + list.Add(1060432, $"{prop}"); // intelligence bonus ~1_val~ } if ((prop = Attributes.LowerManaCost) != 0) { - list.Add(1060433, prop.ToString()); // lower mana cost ~1_val~% + list.Add(1060433, $"{prop}"); // lower mana cost ~1_val~% } if ((prop = Attributes.LowerRegCost) != 0) { - list.Add(1060434, prop.ToString()); // lower reagent cost ~1_val~% + list.Add(1060434, $"{prop}"); // lower reagent cost ~1_val~% } if ((prop = Attributes.Luck) != 0) { - list.Add(1060436, prop.ToString()); // luck ~1_val~ + list.Add(1060436, $"{prop}"); // luck ~1_val~ } if ((prop = Attributes.BonusMana) != 0) { - list.Add(1060439, prop.ToString()); // mana increase ~1_val~ + list.Add(1060439, $"{prop}"); // mana increase ~1_val~ } if ((prop = Attributes.RegenMana) != 0) { - list.Add(1060440, prop.ToString()); // mana regeneration ~1_val~ + list.Add(1060440, $"{prop}"); // mana regeneration ~1_val~ } if (Attributes.NightSight != 0) @@ -726,17 +718,17 @@ namespace Server.Items if ((prop = Attributes.ReflectPhysical) != 0) { - list.Add(1060442, prop.ToString()); // reflect physical damage ~1_val~% + list.Add(1060442, $"{prop}"); // reflect physical damage ~1_val~% } if ((prop = Attributes.RegenStam) != 0) { - list.Add(1060443, prop.ToString()); // stamina regeneration ~1_val~ + list.Add(1060443, $"{prop}"); // stamina regeneration ~1_val~ } if ((prop = Attributes.RegenHits) != 0) { - list.Add(1060444, prop.ToString()); // hit point regeneration ~1_val~ + list.Add(1060444, $"{prop}"); // hit point regeneration ~1_val~ } if (Attributes.SpellChanneling != 0) @@ -746,32 +738,32 @@ namespace Server.Items if ((prop = Attributes.SpellDamage) != 0) { - list.Add(1060483, prop.ToString()); // spell damage increase ~1_val~% + list.Add(1060483, $"{prop}"); // spell damage increase ~1_val~% } if ((prop = Attributes.BonusStam) != 0) { - list.Add(1060484, prop.ToString()); // stamina increase ~1_val~ + list.Add(1060484, $"{prop}"); // stamina increase ~1_val~ } if ((prop = Attributes.BonusStr) != 0) { - list.Add(1060485, prop.ToString()); // strength bonus ~1_val~ + list.Add(1060485, $"{prop}"); // strength bonus ~1_val~ } if ((prop = Attributes.WeaponSpeed) != 0) { - list.Add(1060486, prop.ToString()); // swing speed increase ~1_val~% + list.Add(1060486, $"{prop}"); // swing speed increase ~1_val~% } if (Core.ML && (prop = Attributes.IncreasedKarmaLoss) != 0) { - list.Add(1075210, prop.ToString()); // Increased Karma Loss ~1val~% + list.Add(1075210, $"{prop}"); // Increased Karma Loss ~1val~% } if (m_MaxCharges > 0) { - list.Add(1060741, m_Charges.ToString()); // charges: ~1_val~ + list.Add(1060741, $"{m_Charges}"); // charges: ~1_val~ } if (m_Slayer != TalismanSlayerName.None) diff --git a/Projects/UOContent/Items/Wands/BaseWand.cs b/Projects/UOContent/Items/Wands/BaseWand.cs index 7d404413f..0549b7a6c 100644 --- a/Projects/UOContent/Items/Wands/BaseWand.cs +++ b/Projects/UOContent/Items/Wands/BaseWand.cs @@ -123,44 +123,44 @@ namespace Server.Items _charges = reader.ReadInt(); } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); switch (_wandEffect) { case WandEffect.Clumsiness: - list.Add(1017326, _charges.ToString()); + list.Add(1017326, $"{_charges}"); break; // clumsiness charges: ~1_val~ case WandEffect.Identification: - list.Add(1017350, _charges.ToString()); + list.Add(1017350, $"{_charges}"); break; // identification charges: ~1_val~ case WandEffect.Healing: - list.Add(1017329, _charges.ToString()); + list.Add(1017329, $"{_charges}"); break; // healing charges: ~1_val~ case WandEffect.Feeblemindedness: - list.Add(1017327, _charges.ToString()); + list.Add(1017327, $"{_charges}"); break; // feeblemind charges: ~1_val~ case WandEffect.Weakness: - list.Add(1017328, _charges.ToString()); + list.Add(1017328, $"{_charges}"); break; // weakness charges: ~1_val~ case WandEffect.MagicArrow: - list.Add(1060492, _charges.ToString()); + list.Add(1060492, $"{_charges}"); break; // magic arrow charges: ~1_val~ case WandEffect.Harming: - list.Add(1017334, _charges.ToString()); + list.Add(1017334, $"{_charges}"); break; // harm charges: ~1_val~ case WandEffect.Fireball: - list.Add(1060487, _charges.ToString()); + list.Add(1060487, $"{_charges}"); break; // fireball charges: ~1_val~ case WandEffect.GreaterHealing: - list.Add(1017330, _charges.ToString()); + list.Add(1017330, $"{_charges}"); break; // greater healing charges: ~1_val~ case WandEffect.Lightning: - list.Add(1060491, _charges.ToString()); + list.Add(1060491, $"{_charges}"); break; // lightning charges: ~1_val~ case WandEffect.ManaDraining: - list.Add(1017339, _charges.ToString()); + list.Add(1017339, $"{_charges}"); break; // mana drain charges: ~1_val~ } } diff --git a/Projects/UOContent/Items/Weapons/BaseWeapon.cs b/Projects/UOContent/Items/Weapons/BaseWeapon.cs index ad0bf9863..a89e8e7c0 100644 --- a/Projects/UOContent/Items/Weapons/BaseWeapon.cs +++ b/Projects/UOContent/Items/Weapons/BaseWeapon.cs @@ -2716,8 +2716,6 @@ namespace Server.Items from.Animate(action, 7, 1, true, false, 0); } - private string GetNameString() => Name ?? $"#{LabelNumber}"; - public int GetElementalDamageHue() { GetDamageTypes(null, out _, out var fire, out var cold, out var pois, out var nrgy, out _, out _); @@ -2752,7 +2750,7 @@ namespace Server.Items return hue; } - public override void AddNameProperty(ObjectPropertyList list) + public override void AddNameProperty(IPropertyList list) { var oreType = m_Resource switch { @@ -2776,17 +2774,19 @@ namespace Server.Items _ => 0 }; + var name = Name; + if (oreType != 0) { - list.Add(1053099, "#{0}\t{1}", oreType, GetNameString()); // ~1_oretype~ ~2_armortype~ + list.Add(1053099, name != null ? $"#{oreType}\t{name}" : $"#{oreType}\t#{LabelNumber}"); // ~1_oretype~ ~2_armortype~ } - else if (Name == null) + else if (name == null) { list.Add(LabelNumber); } else { - list.Add(Name); + list.Add(name); } /* @@ -2815,7 +2815,7 @@ namespace Server.Items public virtual int GetLuckBonus() => CraftResources.GetInfo(m_Resource)?.AttributeInfo?.WeaponLuck ?? 0; - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); @@ -2848,12 +2848,12 @@ namespace Server.Items if (ArtifactRarity > 0) { - list.Add(1061078, ArtifactRarity.ToString()); // artifact rarity ~1_val~ + list.Add(1061078, $"{ArtifactRarity}"); // artifact rarity ~1_val~ } if (this is IUsesRemaining usesRemaining && usesRemaining.ShowUsesRemaining) { - list.Add(1060584, usesRemaining.UsesRemaining.ToString()); // uses remaining: ~1_val~ + list.Add(1060584, $"{usesRemaining.UsesRemaining}"); // uses remaining: ~1_val~ } if (m_Poison != null && m_PoisonCharges > 0) @@ -2897,107 +2897,107 @@ namespace Server.Items if ((prop = GetDamageBonus() + Attributes.WeaponDamage) != 0) { - list.Add(1060401, prop.ToString()); // damage increase ~1_val~% + list.Add(1060401, $"{prop}"); // damage increase ~1_val~% } if ((prop = Attributes.DefendChance) != 0) { - list.Add(1060408, prop.ToString()); // defense chance increase ~1_val~% + list.Add(1060408, $"{prop}"); // defense chance increase ~1_val~% } if ((prop = Attributes.EnhancePotions) != 0) { - list.Add(1060411, prop.ToString()); // enhance potions ~1_val~% + list.Add(1060411, $"{prop}"); // enhance potions ~1_val~% } if ((prop = Attributes.CastRecovery) != 0) { - list.Add(1060412, prop.ToString()); // faster cast recovery ~1_val~ + list.Add(1060412, $"{prop}"); // faster cast recovery ~1_val~ } if ((prop = Attributes.CastSpeed) != 0) { - list.Add(1060413, prop.ToString()); // faster casting ~1_val~ + list.Add(1060413, $"{prop}"); // faster casting ~1_val~ } if ((prop = GetHitChanceBonus() + Attributes.AttackChance) != 0) { - list.Add(1060415, prop.ToString()); // hit chance increase ~1_val~% + list.Add(1060415, $"{prop}"); // hit chance increase ~1_val~% } if ((prop = WeaponAttributes.HitColdArea) != 0) { - list.Add(1060416, prop.ToString()); // hit cold area ~1_val~% + list.Add(1060416, $"{prop}"); // hit cold area ~1_val~% } if ((prop = WeaponAttributes.HitDispel) != 0) { - list.Add(1060417, prop.ToString()); // hit dispel ~1_val~% + list.Add(1060417, $"{prop}"); // hit dispel ~1_val~% } if ((prop = WeaponAttributes.HitEnergyArea) != 0) { - list.Add(1060418, prop.ToString()); // hit energy area ~1_val~% + list.Add(1060418, $"{prop}"); // hit energy area ~1_val~% } if ((prop = WeaponAttributes.HitFireArea) != 0) { - list.Add(1060419, prop.ToString()); // hit fire area ~1_val~% + list.Add(1060419, $"{prop}"); // hit fire area ~1_val~% } if ((prop = WeaponAttributes.HitFireball) != 0) { - list.Add(1060420, prop.ToString()); // hit fireball ~1_val~% + list.Add(1060420, $"{prop}"); // hit fireball ~1_val~% } if ((prop = WeaponAttributes.HitHarm) != 0) { - list.Add(1060421, prop.ToString()); // hit harm ~1_val~% + list.Add(1060421, $"{prop}"); // hit harm ~1_val~% } if ((prop = WeaponAttributes.HitLeechHits) != 0) { - list.Add(1060422, prop.ToString()); // hit life leech ~1_val~% + list.Add(1060422, $"{prop}"); // hit life leech ~1_val~% } if ((prop = WeaponAttributes.HitLightning) != 0) { - list.Add(1060423, prop.ToString()); // hit lightning ~1_val~% + list.Add(1060423, $"{prop}"); // hit lightning ~1_val~% } if ((prop = WeaponAttributes.HitLowerAttack) != 0) { - list.Add(1060424, prop.ToString()); // hit lower attack ~1_val~% + list.Add(1060424, $"{prop}"); // hit lower attack ~1_val~% } if ((prop = WeaponAttributes.HitLowerDefend) != 0) { - list.Add(1060425, prop.ToString()); // hit lower defense ~1_val~% + list.Add(1060425, $"{prop}"); // hit lower defense ~1_val~% } if ((prop = WeaponAttributes.HitMagicArrow) != 0) { - list.Add(1060426, prop.ToString()); // hit magic arrow ~1_val~% + list.Add(1060426, $"{prop}"); // hit magic arrow ~1_val~% } if ((prop = WeaponAttributes.HitLeechMana) != 0) { - list.Add(1060427, prop.ToString()); // hit mana leech ~1_val~% + list.Add(1060427, $"{prop}"); // hit mana leech ~1_val~% } if ((prop = WeaponAttributes.HitPhysicalArea) != 0) { - list.Add(1060428, prop.ToString()); // hit physical area ~1_val~% + list.Add(1060428, $"{prop}"); // hit physical area ~1_val~% } if ((prop = WeaponAttributes.HitPoisonArea) != 0) { - list.Add(1060429, prop.ToString()); // hit poison area ~1_val~% + list.Add(1060429, $"{prop}"); // hit poison area ~1_val~% } if ((prop = WeaponAttributes.HitLeechStam) != 0) { - list.Add(1060430, prop.ToString()); // hit stamina leech ~1_val~% + list.Add(1060430, $"{prop}"); // hit stamina leech ~1_val~% } if (ImmolatingWeaponSpell.IsImmolating(this)) @@ -3007,42 +3007,42 @@ namespace Server.Items if (Core.ML && (ranged?.Velocity ?? 0) != 0) { - list.Add(1072793, prop.ToString()); // Velocity ~1_val~% + list.Add(1072793, $"{prop}"); // Velocity ~1_val~% } if ((prop = Attributes.BonusDex) != 0) { - list.Add(1060409, prop.ToString()); // dexterity bonus ~1_val~ + list.Add(1060409, $"{prop}"); // dexterity bonus ~1_val~ } if ((prop = Attributes.BonusHits) != 0) { - list.Add(1060431, prop.ToString()); // hit point increase ~1_val~ + list.Add(1060431, $"{prop}"); // hit point increase ~1_val~ } if ((prop = Attributes.BonusInt) != 0) { - list.Add(1060432, prop.ToString()); // intelligence bonus ~1_val~ + list.Add(1060432, $"{prop}"); // intelligence bonus ~1_val~ } if ((prop = Attributes.LowerManaCost) != 0) { - list.Add(1060433, prop.ToString()); // lower mana cost ~1_val~% + list.Add(1060433, $"{prop}"); // lower mana cost ~1_val~% } if ((prop = Attributes.LowerRegCost) != 0) { - list.Add(1060434, prop.ToString()); // lower reagent cost ~1_val~% + list.Add(1060434, $"{prop}"); // lower reagent cost ~1_val~% } if ((prop = GetLowerStatReq()) != 0) { - list.Add(1060435, prop.ToString()); // lower requirements ~1_val~% + list.Add(1060435, $"{prop}"); // lower requirements ~1_val~% } if ((prop = GetLuckBonus() + Attributes.Luck) != 0) { - list.Add(1060436, prop.ToString()); // luck ~1_val~ + list.Add(1060436, $"{prop}"); // luck ~1_val~ } if ((prop = WeaponAttributes.MageWeapon) != 0) @@ -3052,12 +3052,12 @@ namespace Server.Items if ((prop = Attributes.BonusMana) != 0) { - list.Add(1060439, prop.ToString()); // mana increase ~1_val~ + list.Add(1060439, $"{prop}"); // mana increase ~1_val~ } if ((prop = Attributes.RegenMana) != 0) { - list.Add(1060440, prop.ToString()); // mana regeneration ~1_val~ + list.Add(1060440, $"{prop}"); // mana regeneration ~1_val~ } if (Attributes.NightSight != 0) @@ -3067,22 +3067,22 @@ namespace Server.Items if ((prop = Attributes.ReflectPhysical) != 0) { - list.Add(1060442, prop.ToString()); // reflect physical damage ~1_val~% + list.Add(1060442, $"{prop}"); // reflect physical damage ~1_val~% } if ((prop = Attributes.RegenStam) != 0) { - list.Add(1060443, prop.ToString()); // stamina regeneration ~1_val~ + list.Add(1060443, $"{prop}"); // stamina regeneration ~1_val~ } if ((prop = Attributes.RegenHits) != 0) { - list.Add(1060444, prop.ToString()); // hit point regeneration ~1_val~ + list.Add(1060444, $"{prop}"); // hit point regeneration ~1_val~ } if ((prop = WeaponAttributes.SelfRepair) != 0) { - list.Add(1060450, prop.ToString()); // self repair ~1_val~ + list.Add(1060450, $"{prop}"); // self repair ~1_val~ } if (Attributes.SpellChanneling != 0) @@ -3092,27 +3092,27 @@ namespace Server.Items if ((prop = Attributes.SpellDamage) != 0) { - list.Add(1060483, prop.ToString()); // spell damage increase ~1_val~% + list.Add(1060483, $"{prop}"); // spell damage increase ~1_val~% } if ((prop = Attributes.BonusStam) != 0) { - list.Add(1060484, prop.ToString()); // stamina increase ~1_val~ + list.Add(1060484, $"{prop}"); // stamina increase ~1_val~ } if ((prop = Attributes.BonusStr) != 0) { - list.Add(1060485, prop.ToString()); // strength bonus ~1_val~ + list.Add(1060485, $"{prop}"); // strength bonus ~1_val~ } if ((prop = Attributes.WeaponSpeed) != 0) { - list.Add(1060486, prop.ToString()); // swing speed increase ~1_val~% + list.Add(1060486, $"{prop}"); // swing speed increase ~1_val~% } if (Core.ML && (prop = Attributes.IncreasedKarmaLoss) != 0) { - list.Add(1075210, prop.ToString()); // Increased Karma Loss ~1val~% + list.Add(1075210, $"{prop}"); // Increased Karma Loss ~1val~% } GetDamageTypes( @@ -3128,40 +3128,40 @@ namespace Server.Items if (phys != 0) { - list.Add(1060403, phys.ToString()); // physical damage ~1_val~% + list.Add(1060403, $"{phys}"); // physical damage ~1_val~% } if (fire != 0) { - list.Add(1060405, fire.ToString()); // fire damage ~1_val~% + list.Add(1060405, $"{fire}"); // fire damage ~1_val~% } if (cold != 0) { - list.Add(1060404, cold.ToString()); // cold damage ~1_val~% + list.Add(1060404, $"{cold}"); // cold damage ~1_val~% } if (pois != 0) { - list.Add(1060406, pois.ToString()); // poison damage ~1_val~% + list.Add(1060406, $"{pois}"); // poison damage ~1_val~% } if (nrgy != 0) { - list.Add(1060407, nrgy.ToString()); // energy damage ~1_val + list.Add(1060407, $"{nrgy}"); // energy damage ~1_val } if (Core.ML && chaos != 0) { - list.Add(1072846, chaos.ToString()); // chaos damage ~1_val~% + list.Add(1072846, $"{chaos}"); // chaos damage ~1_val~% } if (Core.ML && direct != 0) { - list.Add(1079978, direct.ToString()); // Direct Damage: ~1_PERCENT~% + list.Add(1079978, $"{direct}"); // Direct Damage: ~1_PERCENT~% } - list.Add(1061168, "{0}\t{1}", MinDamage.ToString(), MaxDamage.ToString()); // weapon damage ~1_val~ - ~2_val~ + list.Add(1061168, $"{MinDamage}\t{MaxDamage}"); // weapon damage ~1_val~ - ~2_val~ if (Core.ML) { @@ -3169,19 +3169,19 @@ namespace Server.Items } else { - list.Add(1061167, Speed.ToString()); + list.Add(1061167, $"{Speed}"); } if (MaxRange > 1) { - list.Add(1061169, MaxRange.ToString()); // range ~1_val~ + list.Add(1061169, $"{MaxRange}"); // range ~1_val~ } var strReq = AOS.Scale(StrRequirement, 100 - GetLowerStatReq()); if (strReq > 0) { - list.Add(1061170, strReq.ToString()); // strength requirement ~1_val~ + list.Add(1061170, $"{strReq}"); // strength requirement ~1_val~ } if (Layer == Layer.TwoHanded) @@ -3222,7 +3222,7 @@ namespace Server.Items if (m_Hits >= 0 && m_MaxHits > 0) { - list.Add(1060639, "{0}\t{1}", m_Hits, m_MaxHits); // durability ~1_val~ / ~2_val~ + list.Add(1060639, $"{m_Hits}\t{m_MaxHits}"); // durability ~1_val~ / ~2_val~ } } diff --git a/Projects/UOContent/Items/Weapons/ML Weapons/ButchersWarCleaver.cs b/Projects/UOContent/Items/Weapons/ML Weapons/ButchersWarCleaver.cs index 30ccfb29b..13cb86c65 100644 --- a/Projects/UOContent/Items/Weapons/ML Weapons/ButchersWarCleaver.cs +++ b/Projects/UOContent/Items/Weapons/ML Weapons/ButchersWarCleaver.cs @@ -12,7 +12,7 @@ namespace Server.Items public override int LabelNumber => 1073526; // butcher's war cleaver - public override void AppendChildNameProperties(ObjectPropertyList list) + public override void AppendChildNameProperties(IPropertyList list) { base.AppendChildNameProperties(list); diff --git a/Projects/UOContent/Items/Weapons/Maces/FireworksWand.cs b/Projects/UOContent/Items/Weapons/Maces/FireworksWand.cs index 916a5a6be..c28b20f8f 100644 --- a/Projects/UOContent/Items/Weapons/Maces/FireworksWand.cs +++ b/Projects/UOContent/Items/Weapons/Maces/FireworksWand.cs @@ -20,11 +20,11 @@ namespace Server.Items public override int LabelNumber => 1041424; // a fireworks wand - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); - list.Add(1060741, _charges.ToString()); // charges: ~1_val~ + list.Add(1060741, $"{_charges}"); // charges: ~1_val~ } public override void OnDoubleClick(Mobile from) diff --git a/Projects/UOContent/Misc/AOS.cs b/Projects/UOContent/Misc/AOS.cs index 79e49c57b..527c46d8d 100644 --- a/Projects/UOContent/Misc/AOS.cs +++ b/Projects/UOContent/Misc/AOS.cs @@ -1035,13 +1035,13 @@ namespace Server set => SetSkill(4, value); } - public void GetProperties(ObjectPropertyList list) + public void GetProperties(IPropertyList list) { for (var i = 0; i < 5; ++i) { if (GetValues(i, out var skill, out var bonus)) { - list.Add(1060451 + i, "#{0}\t{1}", GetLabel(skill), bonus); + list.Add(1060451 + i, $"#{GetLabel(skill)}\t{bonus}"); } } } @@ -1459,7 +1459,7 @@ namespace Server } } - if (Owner.Parent is Mobile m) + if (Owner?.Parent is Mobile m) { m.CheckStatTimers(); m.UpdateResistances(); @@ -1475,7 +1475,7 @@ namespace Server } } - Owner.InvalidateProperties(); + Owner?.InvalidateProperties(); } private int GetIndex(uint mask) diff --git a/Projects/UOContent/Misc/Gifts/Winter2004/DecorativeTopiary.cs b/Projects/UOContent/Misc/Gifts/Winter2004/DecorativeTopiary.cs index 3e7f3c02b..22862e652 100644 --- a/Projects/UOContent/Misc/Gifts/Winter2004/DecorativeTopiary.cs +++ b/Projects/UOContent/Misc/Gifts/Winter2004/DecorativeTopiary.cs @@ -20,7 +20,7 @@ namespace Server.Items LabelTo(from, 1070880); // Winter 2004 } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Misc/Gifts/Winter2004/FestiveCactus.cs b/Projects/UOContent/Misc/Gifts/Winter2004/FestiveCactus.cs index e347b2ada..ff92515af 100644 --- a/Projects/UOContent/Misc/Gifts/Winter2004/FestiveCactus.cs +++ b/Projects/UOContent/Misc/Gifts/Winter2004/FestiveCactus.cs @@ -20,7 +20,7 @@ namespace Server.Items LabelTo(from, 1070880); // Winter 2004 } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Misc/Gifts/Winter2004/LightOfTheWinterSolstice.cs b/Projects/UOContent/Misc/Gifts/Winter2004/LightOfTheWinterSolstice.cs index 8103c7c00..c65cf69d4 100644 --- a/Projects/UOContent/Misc/Gifts/Winter2004/LightOfTheWinterSolstice.cs +++ b/Projects/UOContent/Misc/Gifts/Winter2004/LightOfTheWinterSolstice.cs @@ -49,7 +49,7 @@ namespace Server.Items LabelTo(from, 1070880); // Winter 2004 } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Misc/Gifts/Winter2004/Mistletoe.cs b/Projects/UOContent/Misc/Gifts/Winter2004/Mistletoe.cs index 004f2fb43..67645e105 100644 --- a/Projects/UOContent/Misc/Gifts/Winter2004/Mistletoe.cs +++ b/Projects/UOContent/Misc/Gifts/Winter2004/Mistletoe.cs @@ -202,7 +202,7 @@ namespace Server.Items LabelTo(from, 1070880); // Winter 2004 } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Misc/Gifts/Winter2004/PileOfGlacialSnow.cs b/Projects/UOContent/Misc/Gifts/Winter2004/PileOfGlacialSnow.cs index 69e09d85a..47335b9d5 100644 --- a/Projects/UOContent/Misc/Gifts/Winter2004/PileOfGlacialSnow.cs +++ b/Projects/UOContent/Misc/Gifts/Winter2004/PileOfGlacialSnow.cs @@ -47,7 +47,7 @@ namespace Server.Items LabelTo(from, 1070880); // Winter 2004 } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Misc/Gifts/Winter2004/SnowyTree.cs b/Projects/UOContent/Misc/Gifts/Winter2004/SnowyTree.cs index c9c038acc..329240a50 100644 --- a/Projects/UOContent/Misc/Gifts/Winter2004/SnowyTree.cs +++ b/Projects/UOContent/Misc/Gifts/Winter2004/SnowyTree.cs @@ -20,7 +20,7 @@ namespace Server.Items LabelTo(from, 1070880); // Winter 2004 } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Misc/TextDefinition.cs b/Projects/UOContent/Misc/TextDefinition.cs index 8fbb4407c..97d71507b 100644 --- a/Projects/UOContent/Misc/TextDefinition.cs +++ b/Projects/UOContent/Misc/TextDefinition.cs @@ -66,7 +66,7 @@ namespace Server }; } - public static void AddTo(ObjectPropertyList list, TextDefinition def) + public static void AddTo(IPropertyList list, TextDefinition def) { if (def == null) { diff --git a/Projects/UOContent/Mobiles/AI/BaseAI.cs b/Projects/UOContent/Mobiles/AI/BaseAI.cs index 4b8a4772a..d5a5b5466 100644 --- a/Projects/UOContent/Mobiles/AI/BaseAI.cs +++ b/Projects/UOContent/Mobiles/AI/BaseAI.cs @@ -2861,7 +2861,7 @@ namespace Server.Mobiles Delete(); } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/Ethereals.cs b/Projects/UOContent/Mobiles/Animals/Mounts/Ethereals.cs index 83edbf3e2..079736046 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/Ethereals.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/Ethereals.cs @@ -128,7 +128,7 @@ namespace Server.Mobiles [CommandProperty(AccessLevel.GameMaster)] public bool IsRewardItem { get; set; } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/SwampDragon.cs b/Projects/UOContent/Mobiles/Animals/Mounts/SwampDragon.cs index 64671c8d5..984e8bedf 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/SwampDragon.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/SwampDragon.cs @@ -152,7 +152,7 @@ namespace Server.Mobiles public override double GetControlChance(Mobile m, bool useBaseSkill = false) => 1.0; - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Mobiles/BaseCreature.cs b/Projects/UOContent/Mobiles/BaseCreature.cs index 602955362..f0d7a5c77 100644 --- a/Projects/UOContent/Mobiles/BaseCreature.cs +++ b/Projects/UOContent/Mobiles/BaseCreature.cs @@ -2784,7 +2784,7 @@ namespace Server.Mobiles base.OnDoubleClick(from); } - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); diff --git a/Projects/UOContent/Mobiles/Monsters/LBR/Meers/EnragedCreatures.cs b/Projects/UOContent/Mobiles/Monsters/LBR/Meers/EnragedCreatures.cs index 2a09bf7b9..3bf779bc5 100644 --- a/Projects/UOContent/Mobiles/Monsters/LBR/Meers/EnragedCreatures.cs +++ b/Projects/UOContent/Mobiles/Monsters/LBR/Meers/EnragedCreatures.cs @@ -219,7 +219,7 @@ namespace Server.Mobiles PrivateOverheadMessage(MessageType.Regular, 0x3B2, 1060768, from.NetState); // enraged } - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); list.Add(1060768); // enraged diff --git a/Projects/UOContent/Mobiles/PlayerMobile.cs b/Projects/UOContent/Mobiles/PlayerMobile.cs index c8f0e000c..02648f607 100644 --- a/Projects/UOContent/Mobiles/PlayerMobile.cs +++ b/Projects/UOContent/Mobiles/PlayerMobile.cs @@ -3511,7 +3511,7 @@ namespace Server.Mobiles DisguiseTimers.RemoveTimer(this); } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); @@ -3531,32 +3531,26 @@ namespace Server.Mobiles { list.Add( 1042734, - "{0}\t{1}", - pl.Sheriff.Definition.FriendlyName, - faction.Definition.PropName + $"{pl.Sheriff.Definition.FriendlyName}\t{faction.Definition.PropName}" ); // The Sheriff of ~1_CITY~, ~2_FACTION_NAME~ } else if (pl.Finance != null) { list.Add( - 1042735, - "{0}\t{1}", - pl.Finance.Definition.FriendlyName, - faction.Definition.PropName - ); // The Finance Minister of ~1_CITY~, ~2_FACTION_NAME~ + 1042735, // The Finance Minister of ~1_CITY~, ~2_FACTION_NAME~ + $"{pl.Finance.Definition.FriendlyName}\t{faction.Definition.PropName}" + ); } else if (pl.MerchantTitle != MerchantTitle.None) { list.Add( - 1060776, - "{0}\t{1}", - MerchantTitles.GetInfo(pl.MerchantTitle).Title, - faction.Definition.PropName - ); // ~1_val~, ~2_val~ + 1060776, // ~1_val~, ~2_val~ + $"{MerchantTitles.GetInfo(pl.MerchantTitle).Title}\t{faction.Definition.PropName}" + ); } else { - list.Add(1060776, "{0}\t{1}", pl.Rank.Title, faction.Definition.PropName); // ~1_val~, ~2_val~ + list.Add(1060776, $"{pl.Rank.Title}\t{faction.Definition.PropName}"); // ~1_val~, ~2_val~ } } } diff --git a/Projects/UOContent/Mobiles/Special/ServantOfSemidar.cs b/Projects/UOContent/Mobiles/Special/ServantOfSemidar.cs index 8aec98cf3..cf9836831 100644 --- a/Projects/UOContent/Mobiles/Special/ServantOfSemidar.cs +++ b/Projects/UOContent/Mobiles/Special/ServantOfSemidar.cs @@ -17,7 +17,7 @@ namespace Server.Mobiles public override bool CanBeDamaged() => false; - public override void AddNameProperties(ObjectPropertyList list) + public override void AddNameProperties(IPropertyList list) { base.AddNameProperties(list); diff --git a/Projects/UOContent/Mobiles/Vendors/BaseVendor.cs b/Projects/UOContent/Mobiles/Vendors/BaseVendor.cs index 0266aa7b0..f9e05c63a 100644 --- a/Projects/UOContent/Mobiles/Vendors/BaseVendor.cs +++ b/Projects/UOContent/Mobiles/Vendors/BaseVendor.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using Server.Collections; using Server.ContextMenus; using Server.Engines.BulkOrders; using Server.Factions; @@ -876,7 +877,7 @@ namespace Server.Mobiles var list = new List(buyInfo.Length); var cont = BuyPack; - var opls = EnableVendorBuyOPL ? new List(buyInfo.Length) : null; + using var opls = PooledRefQueue.Create(EnableVendorBuyOPL ? buyInfo.Length : 0); for (var idx = 0; idx < buyInfo.Length; idx++) { @@ -906,9 +907,9 @@ namespace Server.Mobiles ) ); - if (disp is IPropertyListObject obj) + if (disp is IObjectPropertyListEntity obj) { - opls?.Add(obj.PropertyList); + opls.Enqueue(obj.PropertyList); } } @@ -949,7 +950,7 @@ namespace Server.Mobiles if (name != null && list.Count < 250) { list.Add(new BuyItemState(name, cont.Serial, item.Serial, price, item.Amount, item.ItemID, item.Hue)); - opls?.Add(item.PropertyList); + opls.Enqueue(item.PropertyList); } } @@ -978,12 +979,9 @@ namespace Server.Mobiles from.NetState.SendDisplayBuyList(Serial); from.NetState.SendMobileStatus(from); // make sure their gold amount is sent - if (opls != null) + while (opls.Count > 0) { - for (var i = 0; i < opls.Count; ++i) - { - from.NetState?.Send(opls[i].Buffer); - } + from.NetState?.Send(opls.Dequeue().Buffer); } SayTo(from, 500186); // Greetings. Have a look around. diff --git a/Projects/UOContent/Mobiles/Vendors/PlayerVendor.cs b/Projects/UOContent/Mobiles/Vendors/PlayerVendor.cs index 11c3e340d..6bb78d9c5 100644 --- a/Projects/UOContent/Mobiles/Vendors/PlayerVendor.cs +++ b/Projects/UOContent/Mobiles/Vendors/PlayerVendor.cs @@ -155,7 +155,7 @@ namespace Server.Mobiles } } - public override void GetChildNameProperties(ObjectPropertyList list, Item item) + public override void GetChildNameProperties(IPropertyList list, Item item) { base.GetChildNameProperties(list, item); @@ -182,7 +182,7 @@ namespace Server.Mobiles } } - public override void GetChildProperties(ObjectPropertyList list, Item item) + public override void GetChildProperties(IPropertyList list, Item item) { base.GetChildProperties(list, item); @@ -735,7 +735,7 @@ namespace Server.Mobiles public override bool IsSnoop(Mobile from) => false; - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); @@ -1652,7 +1652,7 @@ namespace Server.Mobiles [CommandProperty(AccessLevel.GameMaster)] public PlayerVendor Vendor { get; private set; } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Multis/Boats/BaseDockedBoat.cs b/Projects/UOContent/Multis/Boats/BaseDockedBoat.cs index 6a7a86d85..f2b18daa5 100644 --- a/Projects/UOContent/Multis/Boats/BaseDockedBoat.cs +++ b/Projects/UOContent/Multis/Boats/BaseDockedBoat.cs @@ -102,7 +102,7 @@ namespace Server.Multis } } - public override void AddNameProperty(ObjectPropertyList list) + public override void AddNameProperty(IPropertyList list) { if (m_ShipName != null) { diff --git a/Projects/UOContent/Multis/Boats/TillerMan.cs b/Projects/UOContent/Multis/Boats/TillerMan.cs index be04517b2..cef485f9c 100644 --- a/Projects/UOContent/Multis/Boats/TillerMan.cs +++ b/Projects/UOContent/Multis/Boats/TillerMan.cs @@ -29,7 +29,7 @@ namespace Server.Items }; } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); @@ -46,7 +46,7 @@ namespace Server.Items PublicOverheadMessage(MessageType.Regular, 0x3B2, number, args); } - public override void AddNameProperty(ObjectPropertyList list) + public override void AddNameProperty(IPropertyList list) { if (m_Boat?.ShipName != null) { diff --git a/Projects/UOContent/Multis/Houses/BaseHouse.cs b/Projects/UOContent/Multis/Houses/BaseHouse.cs index 272bba2cf..dd480e427 100644 --- a/Projects/UOContent/Multis/Houses/BaseHouse.cs +++ b/Projects/UOContent/Multis/Houses/BaseHouse.cs @@ -3700,7 +3700,7 @@ namespace Server.Multis public override string DefaultName => "a house transfer contract"; - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Multis/Houses/HouseSign.cs b/Projects/UOContent/Multis/Houses/HouseSign.cs index 9341915e4..ab8a35180 100644 --- a/Projects/UOContent/Multis/Houses/HouseSign.cs +++ b/Projects/UOContent/Multis/Houses/HouseSign.cs @@ -52,12 +52,12 @@ namespace Server.Multis } } - public override void AddNameProperty(ObjectPropertyList list) + public override void AddNameProperty(IPropertyList list) { list.Add(1061638); // A House Sign } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); diff --git a/Projects/UOContent/Special Systems/Items/Stones/GamblingStone.cs b/Projects/UOContent/Special Systems/Items/Stones/GamblingStone.cs index 076ef0d77..f33a1197f 100644 --- a/Projects/UOContent/Special Systems/Items/Stones/GamblingStone.cs +++ b/Projects/UOContent/Special Systems/Items/Stones/GamblingStone.cs @@ -30,17 +30,17 @@ namespace Server.Items public override string DefaultName => "a gambling stone"; - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); - list.Add("Jackpot: {0}gp", m_GamblePot); + list.Add($"Jackpot: {m_GamblePot}gp"); } public override void OnSingleClick(Mobile from) { base.OnSingleClick(from); - LabelTo(from, "Jackpot: {0}gp", m_GamblePot); + LabelTo(from, $"Jackpot: {m_GamblePot}gp"); } public override void OnDoubleClick(Mobile from) diff --git a/Projects/UOContent/Spells/Spellweaving/Items/ArcaneFocus.cs b/Projects/UOContent/Spells/Spellweaving/Items/ArcaneFocus.cs index f38d180d2..44f987401 100644 --- a/Projects/UOContent/Spells/Spellweaving/Items/ArcaneFocus.cs +++ b/Projects/UOContent/Spells/Spellweaving/Items/ArcaneFocus.cs @@ -34,11 +34,11 @@ namespace Server.Items public override TextDefinition InvalidTransferMessage => 1073480; // Your arcane focus disappears. public override bool Nontransferable => true; - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); - list.Add(1060485, StrengthBonus.ToString()); // strength bonus ~1_val~ + list.Add(1060485, $"{StrengthBonus}"); // strength bonus ~1_val~ } public override void Serialize(IGenericWriter writer) diff --git a/Projects/UOContent/Spells/Spellweaving/Items/TransientItem.cs b/Projects/UOContent/Spells/Spellweaving/Items/TransientItem.cs index 49781eae5..4755e5ed1 100644 --- a/Projects/UOContent/Spells/Spellweaving/Items/TransientItem.cs +++ b/Projects/UOContent/Spells/Spellweaving/Items/TransientItem.cs @@ -76,13 +76,13 @@ namespace Server.Items } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties(IPropertyList list) { base.GetProperties(list); var remaining = CreationTime + LifeSpan - Core.Now; - list.Add(1072517, ((int)remaining.TotalSeconds).ToString()); // Lifespan: ~1_val~ seconds + list.Add(1072517, $"{(int)remaining.TotalSeconds}"); // Lifespan: ~1_val~ seconds } public override void Serialize(IGenericWriter writer) diff --git a/version.json b/version.json index ea27bd978..b5377358e 100644 --- a/version.json +++ b/version.json @@ -1,4 +1,4 @@ { "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", - "version": "0.9.1" + "version": "0.9.2" } From 5f00330a66dbce60856ee026209ab47c43fd5875 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sat, 4 Jun 2022 11:53:32 -0700 Subject: [PATCH 180/213] fix: Adds optimized formatter for clilocs (#1045) Adds an optimized formatter for localization. Example: ```cs string localizationText = Localization.Format(1050039, "enu", $"{m_Amount}\t{LabelNumber:#}"); ``` Fixes #1044 --- .../Tests/Buffers/STArrayPoolTests.cs | 3 +- .../Localization/LocalizationEntryTests.cs | 19 ++ .../Buffers/PooledArraySpanFormattable.cs | 20 +- Projects/Server/Buffers/STArrayPool.cs | 5 + Projects/Server/Localization/Localization.cs | 44 ++-- .../Server/Localization/LocalizationEntry.cs | 210 +++++++++++++++--- 6 files changed, 248 insertions(+), 53 deletions(-) create mode 100644 Projects/Server.Tests/Tests/Localization/LocalizationEntryTests.cs diff --git a/Projects/Server.Tests/Tests/Buffers/STArrayPoolTests.cs b/Projects/Server.Tests/Tests/Buffers/STArrayPoolTests.cs index 8b6ea0551..0b7ee8937 100644 --- a/Projects/Server.Tests/Tests/Buffers/STArrayPoolTests.cs +++ b/Projects/Server.Tests/Tests/Buffers/STArrayPoolTests.cs @@ -4,6 +4,7 @@ using Xunit; namespace Server.Tests.Tests.Buffers; +[Collection("Sequential Tests")] public class STArrayPoolTests { [Theory] @@ -48,7 +49,7 @@ public class STArrayPoolTests weakReferences1[i] = new WeakReference(arrays1[i]); arrays2[i] = STArrayPool.Shared.Rent(64); - weakReferences2[i] = new WeakReference(arrays1[i]); + weakReferences2[i] = new WeakReference(arrays2[i]); } for (var i = 0; i < arrays1.Length; i++) diff --git a/Projects/Server.Tests/Tests/Localization/LocalizationEntryTests.cs b/Projects/Server.Tests/Tests/Localization/LocalizationEntryTests.cs new file mode 100644 index 000000000..9b64535cd --- /dev/null +++ b/Projects/Server.Tests/Tests/Localization/LocalizationEntryTests.cs @@ -0,0 +1,19 @@ +using Xunit; + +namespace Server.Tests; + +public class LocalizationEntryTests +{ + [Fact] + public void TestClilocAsParameter() + { + Localization.Add("enu", 500002, "This tests ~1_NUMBER~ as parameters."); + Localization.Add("enu", 500003, "clilocs"); + + string numericFormatter = Localization.Format(500002, "enu", $"{500003:#}"); + string stringParam = Localization.Format(500002, "enu", $"{"#500003"}"); + + Assert.Equal("This tests clilocs as parameters", numericFormatter); + Assert.Equal("This tests clilocs as parameters", stringParam); + } +} diff --git a/Projects/Server/Buffers/PooledArraySpanFormattable.cs b/Projects/Server/Buffers/PooledArraySpanFormattable.cs index a210a7ff9..7290f250a 100644 --- a/Projects/Server/Buffers/PooledArraySpanFormattable.cs +++ b/Projects/Server/Buffers/PooledArraySpanFormattable.cs @@ -22,11 +22,13 @@ public struct PooledArraySpanFormattable : ISpanFormattable, IDisposable { private char[] _arrayToReturnToPool; private int _pos; + private string _value; public PooledArraySpanFormattable(char[] arrayToReturnToPool, int length) { _arrayToReturnToPool = arrayToReturnToPool; _pos = length; + _value = null; } public ReadOnlySpan Chars => _arrayToReturnToPool.AsSpan(.._pos); @@ -35,10 +37,12 @@ public struct PooledArraySpanFormattable : ISpanFormattable, IDisposable public string ToString(string? format = null, IFormatProvider formatProvider = null) { - var result = new string(_arrayToReturnToPool.AsSpan(0, _pos)); - Dispose(); + _value ??= new string(_arrayToReturnToPool.AsSpan(0, _pos)); - return result; + STArrayPool.Shared.Return(_arrayToReturnToPool); + _arrayToReturnToPool = null; + + return _value; } public bool TryFormat( @@ -53,18 +57,14 @@ public struct PooledArraySpanFormattable : ISpanFormattable, IDisposable } _arrayToReturnToPool.AsSpan(0, _pos).CopyTo(destination); - Dispose(); - charsWritten = _pos; return true; } public void Dispose() { - if (_arrayToReturnToPool != null) - { - STArrayPool.Shared.Return(_arrayToReturnToPool); - _arrayToReturnToPool = null; - } + STArrayPool.Shared.Return(_arrayToReturnToPool); + _arrayToReturnToPool = null; + this = default; // Defensive clear } } diff --git a/Projects/Server/Buffers/STArrayPool.cs b/Projects/Server/Buffers/STArrayPool.cs index 65e8a9d6c..a9ff65492 100644 --- a/Projects/Server/Buffers/STArrayPool.cs +++ b/Projects/Server/Buffers/STArrayPool.cs @@ -127,6 +127,11 @@ public class STArrayPool : ArrayPool buckets[i]?.Trim(ticks, pressure, GetMaxSizeForBucket(i)); } + if (_cacheBuckets == null) + { + return true; + } + // Under high pressure, release all cached buckets if (pressure == MemoryPressure.High) { diff --git a/Projects/Server/Localization/Localization.cs b/Projects/Server/Localization/Localization.cs index e178bbd95..ca92c06c2 100644 --- a/Projects/Server/Localization/Localization.cs +++ b/Projects/Server/Localization/Localization.cs @@ -42,6 +42,37 @@ public static class Localization } } + public static void Add(string lang, int number, string text) + { + var entry = new LocalizationEntry(lang, number, text); + if (!_localizations.TryGetValue(lang, out var entries)) + { + entries = new Dictionary(); + _localizations[lang] = entries; + if (lang == FallbackLanguage) + { + _fallbackEntries ??= entries; + } + } + + entries.Add(number, entry); + } + + public static bool Remove(string lang, int number) + { + if (!_localizations.TryGetValue(lang, out var entries) || !entries.Remove(number)) + { + return false; + } + + if (entries.Count == 0) + { + _localizations.Remove(lang); + } + + return true; + } + public static Dictionary LoadClilocs(string lang) => LoadClilocs(lang, Core.FindDataFile($"cliloc.{lang}", false)); @@ -96,19 +127,6 @@ public static class Localization public static string GetText(int number, string lang = FallbackLanguage) => TryGetLocalization(lang, number, out var entry) ? entry.Text : null; - /// - /// Creates a formatted string of the localization entry using the specified language. - /// Uses under the hood. - /// Note: This method is not recommended since it uses almost double the memory and 50% more processing. - /// Instead use Format with string interpolation. - /// - /// Localization number - /// Language in ISO 639-2 format - /// An object array containing zero or more objects to format - /// A copy of the localization text where the placeholder arguments have been replaced with string representations of the provided arguments - public static string Format(int number, string lang = FallbackLanguage, params object[] args) => - TryGetLocalization(lang, number, out var entry) ? entry.Format(args) : null; - /// /// Gets a localization entry using the . /// diff --git a/Projects/Server/Localization/LocalizationEntry.cs b/Projects/Server/Localization/LocalizationEntry.cs index f91bcbce0..a2efd2236 100644 --- a/Projects/Server/Localization/LocalizationEntry.cs +++ b/Projects/Server/Localization/LocalizationEntry.cs @@ -84,24 +84,6 @@ public class LocalizationEntry builder.Dispose(); } - public string Format(params object[] args) - { - if (args == null || args.Length == 0 || StringFormatter == null) - { - return Text; - } - - for (var i = 0; i < args.Length; i++) - { - if (args[i] is string s && s[0] == '#' && int.TryParse(s.AsSpan(1), out var number)) - { - args[i] = Localization.GetText(number, Language); - } - } - - return string.Format(StringFormatter, args); - } - /// /// Creates a formatted string of the localization entry. /// Uses string interpolation under the hood. This method is preferably relative to the object array method signature. @@ -256,13 +238,69 @@ public class LocalizationEntry } } - public void AppendFormatted(T value, string? format) + // Each numeric needs its own override + public void AppendFormatted(int value, string? format) { if (!ReadyToAppend()) { return; } + if (!TryAppendCliloc(value, format)) + { + AppendFormattedDirect(value, format); + } + } + + public void AppendFormatted(uint value, string? format) + { + if (!ReadyToAppend()) + { + return; + } + + if (!TryAppendCliloc((int)value, format)) + { + AppendFormattedDirect(value, format); + } + } + + public void AppendFormatted(long value, string? format) + { + if (!ReadyToAppend()) + { + return; + } + + if (!TryAppendCliloc((int)value, format)) + { + AppendFormattedDirect(value, format); + } + } + + public void AppendFormatted(ulong value, string? format) + { + if (!ReadyToAppend()) + { + return; + } + + if (!TryAppendCliloc((int)value, format)) + { + AppendFormattedDirect(value, format); + } + } + + public void AppendFormatted(T value, string? format) + { + if (ReadyToAppend()) + { + AppendFormattedDirect(value, format); + } + } + + private void AppendFormattedDirect(T value, string? format) + { string? s; if (value is IFormattable) { @@ -307,6 +345,95 @@ public class LocalizationEntry } } + // Each numeric needs its own override + public void AppendFormatted(int value, int alignment, string? format) + { + if (!ReadyToAppend()) + { + return; + } + + var startingPos = _pos; + if (TryAppendCliloc(value, format)) + { + AppendFormatted(value, format); + if (alignment != 0) + { + AppendOrInsertAlignmentIfNeeded(startingPos, alignment); + } + } + else + { + AppendFormattedDirect(value, alignment, format); + } + } + + public void AppendFormatted(uint value, int alignment, string? format) + { + if (!ReadyToAppend()) + { + return; + } + + var startingPos = _pos; + if (TryAppendCliloc((int)value, format)) + { + AppendFormatted(value, format); + if (alignment != 0) + { + AppendOrInsertAlignmentIfNeeded(startingPos, alignment); + } + } + else + { + AppendFormattedDirect(value, alignment, format); + } + } + + public void AppendFormatted(long value, int alignment, string? format) + { + if (!ReadyToAppend()) + { + return; + } + + var startingPos = _pos; + if (TryAppendCliloc((int)value, format)) + { + AppendFormatted(value, format); + if (alignment != 0) + { + AppendOrInsertAlignmentIfNeeded(startingPos, alignment); + } + } + else + { + AppendFormattedDirect(value, alignment, format); + } + } + + public void AppendFormatted(ulong value, int alignment, string? format) + { + if (!ReadyToAppend()) + { + return; + } + + var startingPos = _pos; + if (TryAppendCliloc((int)value, format)) + { + AppendFormatted(value, format); + if (alignment != 0) + { + AppendOrInsertAlignmentIfNeeded(startingPos, alignment); + } + } + else + { + AppendFormattedDirect(value, alignment, format); + } + } + public void AppendFormatted(T value, int alignment, string? format) { if (!ReadyToAppend()) @@ -314,6 +441,11 @@ public class LocalizationEntry return; } + AppendFormattedDirect(value, alignment, format); + } + + private void AppendFormattedDirect(T value, int alignment, string? format) + { var startingPos = _pos; AppendFormatted(value, format); if (alignment != 0) @@ -324,7 +456,7 @@ public class LocalizationEntry public void AppendFormatted(ReadOnlySpan value) { - if (!ReadyToAppend() || TryAppendClilocNumber(value)) + if (!ReadyToAppend() || TryAppendClilocByNumericString(value)) { return; } @@ -380,12 +512,33 @@ public class LocalizationEntry } } - public void AppendFormatted(object? value, int alignment = 0, string? format = null) => - AppendFormatted(value, alignment, format); + public void AppendFormatted(object? value, int alignment = 0, string? format = null) + { + if (value is int i) + { + AppendFormatted(i, alignment, format); + } + else if (value is uint ui) + { + AppendFormatted(ui, alignment, format); + } + else if (value is long l) + { + AppendFormatted(l, alignment, format); + } + else if (value is ulong ul) + { + AppendFormatted(ul, alignment, format); + } + else + { + AppendFormatted(value, alignment, format); + } + } public void AppendFormatted(string? value) { - if (!ReadyToAppend() || TryAppendClilocNumber(value)) + if (!ReadyToAppend() || TryAppendClilocByNumericString(value)) { return; } @@ -403,13 +556,9 @@ public class LocalizationEntry public void AppendFormatted(string? value, int alignment, string? format = null) => AppendFormatted(value, alignment, format); - private bool TryAppendClilocNumber(ReadOnlySpan value) + public bool TryAppendCliloc(int number, string? format) { - if ( - value[0] != '#' || - !int.TryParse(value[1..], out var number) || - !Localization.TryGetLocalization(_lang, number, out var entry) - ) + if (format != "#" || !Localization.TryGetLocalization(_lang, number, out var entry)) { return false; } @@ -428,6 +577,9 @@ public class LocalizationEntry return true; } + private bool TryAppendClilocByNumericString(ReadOnlySpan value) => + value[0] == '#' && long.TryParse(value[1..], out var number) && TryAppendCliloc((int)number, "#"); + private void AppendOrInsertAlignmentIfNeeded(int startingPos, int alignment) { var charsWritten = _pos - startingPos; From 78bb4f4bb2a50591003a14580039462b0b640ded Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sat, 4 Jun 2022 12:09:19 -0700 Subject: [PATCH 181/213] fix: Fixes localization test (#1046) --- .../Server.Tests/Tests/Localization/LocalizationEntryTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Projects/Server.Tests/Tests/Localization/LocalizationEntryTests.cs b/Projects/Server.Tests/Tests/Localization/LocalizationEntryTests.cs index 9b64535cd..d37046591 100644 --- a/Projects/Server.Tests/Tests/Localization/LocalizationEntryTests.cs +++ b/Projects/Server.Tests/Tests/Localization/LocalizationEntryTests.cs @@ -13,7 +13,7 @@ public class LocalizationEntryTests string numericFormatter = Localization.Format(500002, "enu", $"{500003:#}"); string stringParam = Localization.Format(500002, "enu", $"{"#500003"}"); - Assert.Equal("This tests clilocs as parameters", numericFormatter); - Assert.Equal("This tests clilocs as parameters", stringParam); + Assert.Equal("This tests clilocs as parameters.", numericFormatter); + Assert.Equal("This tests clilocs as parameters.", stringParam); } } From 6e69d25e3384dbf66b8664bc6d0ea827f3fc4d0a Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 5 Jun 2022 01:00:22 -0700 Subject: [PATCH 182/213] fix: Fixes structured logging (#1043) - [X] Fixes various bugs in logging. --- Projects/Server/Client/UOClient.cs | 7 ++-- .../Configuration/ServerConfiguration.cs | 2 +- Projects/Server/Maps/Map.cs | 12 +++---- Projects/Server/Maps/MapLoader.cs | 6 ++-- Projects/Server/Mobiles/Mobile.cs | 7 +++- Projects/Server/Network/NetState/NetState.cs | 19 ++--------- .../Packets/IncomingExtendedCommandPackets.cs | 3 +- .../Network/Packets/IncomingPlayerPackets.cs | 2 +- .../Network/Packets/OutgoingGumpPackets.cs | 2 +- Projects/Server/Network/TcpServer.cs | 10 +++--- Projects/Server/Regions/RegionLoader.cs | 6 ++-- Projects/Server/TileMatrix/TileMatrix.cs | 6 ++-- .../Server/TileMatrix/TileMatrixLoader.cs | 4 +-- Projects/Server/Timer/Timer.DelayCall.cs | 10 +++--- Projects/Server/Timer/Timer.Pool.cs | 7 ++-- Projects/Server/Timer/Timer.TimerWheel.cs | 8 ++--- Projects/Server/World/World.cs | 10 +++--- .../Accounting/AccessRestrictions.cs | 4 +-- .../UOContent/Accounting/AccountHandler.cs | 32 +++++++++---------- .../UOContent/Engines/Chat/ChatPackets.cs | 2 +- .../ML Quests/Objectives/DeliverObjective.cs | 2 +- .../Commands/GenerateSpawnersCommand.cs | 9 ++++-- Projects/UOContent/Misc/AccountPrompt.cs | 2 +- Projects/UOContent/Misc/CharacterCreation.cs | 2 +- Projects/UOContent/Misc/Cleanup.cs | 4 +-- Projects/UOContent/Misc/ServerAccess.cs | 8 ++--- Projects/UOContent/Misc/ServerList.cs | 2 +- .../UOContent/Multis/Houses/ContestHouses.cs | 4 +-- .../UOContent/Multis/Houses/HousePackets.cs | 2 +- .../UOContent/Network/ProtocolExtensions.cs | 2 +- Projects/UOContent/Regions/GuardedRegion.cs | 2 +- 31 files changed, 96 insertions(+), 102 deletions(-) diff --git a/Projects/Server/Client/UOClient.cs b/Projects/Server/Client/UOClient.cs index 583d3dc81..19e62b18c 100644 --- a/Projects/Server/Client/UOClient.cs +++ b/Projects/Server/Client/UOClient.cs @@ -54,13 +54,14 @@ public static class UOClient { logger.Information( CuoSettings?.ClientVersion == ServerClientVersion - ? $"Automatically detected client version {ServerClientVersion} from CUO settings." - : $"Automatically detected client version {ServerClientVersion}" + ? "Automatically detected client version {ServerClientVersion} from CUO settings." + : "Automatically detected client version {ServerClientVersion}", + ServerClientVersion ); return; } - logger.Information($"Manually configured to use client version {ServerClientVersion}"); + logger.Information("Manually configured to use client version {ServerClientVersion}", ServerClientVersion); } private static ClientVersion DetectCUOClient() diff --git a/Projects/Server/Configuration/ServerConfiguration.cs b/Projects/Server/Configuration/ServerConfiguration.cs index 5cb173e62..718540c23 100644 --- a/Projects/Server/Configuration/ServerConfiguration.cs +++ b/Projects/Server/Configuration/ServerConfiguration.cs @@ -217,7 +217,7 @@ public static class ServerConfiguration if (File.Exists(m_FilePath)) { - logger.Information($"Reading server configuration from {_relPath}..."); + logger.Information("Reading server configuration from {Path}...", _relPath); m_Settings = JsonConfig.Deserialize(m_FilePath); if (m_Settings == null) diff --git a/Projects/Server/Maps/Map.cs b/Projects/Server/Maps/Map.cs index 8f5239248..88ef42d10 100644 --- a/Projects/Server/Maps/Map.cs +++ b/Projects/Server/Maps/Map.cs @@ -320,8 +320,7 @@ public sealed class Map : IComparable public const int SectorShift = 4; public const int SectorActiveRange = 2; - private static ILogger _logger; - private static ILogger Logger => _logger ??= LogFactory.GetLogger(typeof(Map)); + private static ILogger logger = LogFactory.GetLogger(typeof(Map)); private readonly int m_FileIndex; private readonly Sector[][] m_Sectors; @@ -409,7 +408,7 @@ public sealed class Map : IComparable { if (this == Internal && m_Name != "Internal") { - Logger.Warning($"Internal map name was '{m_Name}'\n{new StackTrace()}"); + logger.Warning("Internal map name was '{Name}'\n{StackTrace}", m_Name, new StackTrace()); m_Name = "Internal"; } @@ -419,8 +418,7 @@ public sealed class Map : IComparable { if (this == Internal && value != "Internal") { - Logger.Warning($"Attempted to set internal map name to '{value}'\n{new StackTrace()}"); - + logger.Warning("Attempted to set internal map name to '{Value}'\n{StackTrace}", value, new StackTrace()); value = "Internal"; } @@ -1045,7 +1043,7 @@ public sealed class Map : IComparable if (Regions.ContainsKey(regName)) { - Logger.Warning($"Duplicate region name '{regName}' for map '{Name}'"); + logger.Warning("Duplicate region name '{RegionName}' for map '{MapName}'", regName, Name); } else { @@ -1101,7 +1099,7 @@ public sealed class Map : IComparable } else { - Logger.Warning($"Warning: Invalid object ({o}) in line of sight"); + logger.Warning("Warning: Invalid object ({Object}) in line of sight", o); p = Point3D.Zero; } diff --git a/Projects/Server/Maps/MapLoader.cs b/Projects/Server/Maps/MapLoader.cs index ca0ed6119..a335d5799 100644 --- a/Projects/Server/Maps/MapLoader.cs +++ b/Projects/Server/Maps/MapLoader.cs @@ -80,18 +80,18 @@ namespace Server if (failures.Count > 0) { logger.Warning( - "Map Definitions loaded with failures ({0} maps, {1} failures) ({2:F2} seconds)", + "Map Definitions loaded with failures ({Count} maps, {FailureCount} failures) ({Duration:F2} seconds)", count, failures.Count, stopwatch.Elapsed.TotalSeconds ); - logger.Warning(string.Join(Environment.NewLine, failures)); + logger.Warning("Map load failures: {Failure}", failures); } else { logger.Information( - "Map Definitions loaded successfully ({0} maps, {1} failures) ({2:F2} seconds)", + "Map Definitions loaded successfully ({Count} maps, {FailureCount} failures) ({Duration:F2} seconds)", count, failures.Count, stopwatch.Elapsed.TotalSeconds diff --git a/Projects/Server/Mobiles/Mobile.cs b/Projects/Server/Mobiles/Mobile.cs index 92f007906..fea0a9345 100644 --- a/Projects/Server/Mobiles/Mobile.cs +++ b/Projects/Server/Mobiles/Mobile.cs @@ -5190,7 +5190,12 @@ namespace Server if (oldAmount <= 0) { - logger.Error($"Item {item.GetType()} ({item.Serial}) has amount of {oldAmount}, but must be at least 1"); + logger.Error( + "Item {Type} ({Serial}) has amount of {OldAmount}, but must be at least 1", + item.GetType(), + item.Serial, + oldAmount + ); } else { diff --git a/Projects/Server/Network/NetState/NetState.cs b/Projects/Server/Network/NetState/NetState.cs index 1bd7cf40f..036f8f3a9 100755 --- a/Projects/Server/Network/NetState/NetState.cs +++ b/Projects/Server/Network/NetState/NetState.cs @@ -343,13 +343,7 @@ public partial class NetState : IComparable [MethodImpl(MethodImplOptions.AggressiveInlining)] public void LogInfo(string text) { - logger.Information("Client: {0}: {1}", this, text); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void LogInfo(string format, params object[] args) - { - LogInfo(string.Format(format, args)); + logger.Information("Client: {NetState}: {Message}", this, text); } public void AddMenu(IMenu menu) @@ -861,7 +855,7 @@ public partial class NetState : IComparable { if (ex.SocketErrorCode != SocketError.WouldBlock) { - logger.Debug(ex, "Disconnected due to socket exception"); + logger.Debug(ex, "Disconnected due to a socket exception"); Disconnect(string.Empty); } } @@ -1127,13 +1121,6 @@ public partial class NetState : IComparable var count = TcpServer.Instances.Count; - if (a != null) - { - LogInfo("Disconnected. [{0} Online] [{1}]", count, a); - } - else - { - LogInfo("Disconnected. [{0} Online]", count); - } + LogInfo(a != null ? $"Disconnected. [{count} Online] [{a}]" : $"Disconnected. [{count} Online]"); } } diff --git a/Projects/Server/Network/Packets/IncomingExtendedCommandPackets.cs b/Projects/Server/Network/Packets/IncomingExtendedCommandPackets.cs index bda5b3917..cd98b0bba 100644 --- a/Projects/Server/Network/Packets/IncomingExtendedCommandPackets.cs +++ b/Projects/Server/Network/Packets/IncomingExtendedCommandPackets.cs @@ -103,8 +103,7 @@ public static class IncomingExtendedCommandPackets if (state.Mobile == null) { state.LogInfo( - "Sent in-game packet (0xBFx{0:X2}) before having been attached to a mobile", - packetId + $"Sent in-game packet (0xBFx{packetId:X2}) before having been attached to a mobile" ); } diff --git a/Projects/Server/Network/Packets/IncomingPlayerPackets.cs b/Projects/Server/Network/Packets/IncomingPlayerPackets.cs index 0a6f18c97..7de69d681 100644 --- a/Projects/Server/Network/Packets/IncomingPlayerPackets.cs +++ b/Projects/Server/Network/Packets/IncomingPlayerPackets.cs @@ -202,7 +202,7 @@ public static class IncomingPlayerPackets } default: { - state.LogInfo("Unknown text-command type 0x{0:X2}: {1}", state, type, command); + state.LogInfo($"Unknown text-command type 0x{state:X2}: {type} ({command})"); break; } } diff --git a/Projects/Server/Network/Packets/OutgoingGumpPackets.cs b/Projects/Server/Network/Packets/OutgoingGumpPackets.cs index f8d3e9b29..f1eb61fa0 100644 --- a/Projects/Server/Network/Packets/OutgoingGumpPackets.cs +++ b/Projects/Server/Network/Packets/OutgoingGumpPackets.cs @@ -78,7 +78,7 @@ public static class OutgoingGumpPackets if (error != ZlibError.Okay) { - logger.Warning($"Gump compression failed {error}"); + logger.Warning("Gump compression failed: {Error}", error); writer.Write(4); writer.Write(0); diff --git a/Projects/Server/Network/TcpServer.cs b/Projects/Server/Network/TcpServer.cs index b78e67a41..c82a92537 100644 --- a/Projects/Server/Network/TcpServer.cs +++ b/Projects/Server/Network/TcpServer.cs @@ -77,7 +77,7 @@ namespace Server.Network foreach (var ipep in listeningAddresses) { - logger.Information("Listening: {0}:{1}", ipep.Address, ipep.Port); + logger.Information("Listening: {Address}:{Port}", ipep.Address, ipep.Port); } ListeningAddresses = listeningAddresses.ToArray(); @@ -119,12 +119,12 @@ namespace Server.Network // WSAEADDRINUSE if (se.ErrorCode == 10048) { - logger.Warning("Listener: {0}:{1}: Failed (In Use)", ipep.Address, ipep.Port); + logger.Warning("Listener: {Address}:{Port}: Failed (In Use)", ipep.Address, ipep.Port); } // WSAEADDRNOTAVAIL else if (se.ErrorCode == 10049) { - logger.Warning("Listener {0}:{1}: Failed (Unavailable)", ipep.Address, ipep.Port); + logger.Warning("Listener {Address}:{Port}: Failed (Unavailable)", ipep.Address, ipep.Port); } else { @@ -142,7 +142,7 @@ namespace Server.Network while (++count <= MaxConnectionsPerLoop && _connectedQueue.TryDequeue(out var ns)) { Instances.Add(ns); - ns.LogInfo("Connected. [{0} Online]", Instances.Count); + ns.LogInfo($"Connected. [{Instances.Count} Online]"); } } @@ -166,7 +166,7 @@ namespace Server.Network if (socket.RemoteEndPoint is IPEndPoint ipep) { var ip = ipep.Address.ToString(); - logger.Warning("Listener {0}: Failed (Maximum connections reached)", ip); + logger.Warning("Listener {Address}: Failed (Maximum connections reached)", ip); NetState.TraceDisconnect("Maximum connections reached.", ip); } diff --git a/Projects/Server/Regions/RegionLoader.cs b/Projects/Server/Regions/RegionLoader.cs index 73ec7a3c9..8570cb276 100644 --- a/Projects/Server/Regions/RegionLoader.cs +++ b/Projects/Server/Regions/RegionLoader.cs @@ -64,7 +64,7 @@ namespace Server if (failures.Count == 0) { logger.Information( - "Regions loaded ({0} regions, {1} failures) ({2:F2} seconds)", + "Regions loaded ({Count} regions, {FailureCount} failures) ({Duration:F2} seconds)", count, failures.Count, stopwatch.Elapsed.TotalSeconds @@ -73,13 +73,13 @@ namespace Server else { logger.Warning( - "Failed loading regions ({0} regions, {1} failures) ({2:F2} seconds)", + "Failed loading regions ({Count} regions, {FailureCount} failures) ({Duration:F2} seconds)", count, failures.Count, stopwatch.Elapsed.TotalSeconds ); - logger.Warning(string.Join(Environment.NewLine, failures)); + logger.Warning("{Failures}", failures); } } } diff --git a/Projects/Server/TileMatrix/TileMatrix.cs b/Projects/Server/TileMatrix/TileMatrix.cs index 03dfcb755..79f61bd3d 100644 --- a/Projects/Server/TileMatrix/TileMatrix.cs +++ b/Projects/Server/TileMatrix/TileMatrix.cs @@ -90,7 +90,7 @@ namespace Server } else { - logger.Warning($"map{mapFileIndex}.mul was not found."); + logger.Warning("{File} was not found.", $"map{mapFileIndex}.mul"); } } @@ -103,7 +103,7 @@ namespace Server } else { - logger.Warning($"staidx{mapFileIndex}.mul was not found."); + logger.Warning("{File} was not found.", $"staidx{mapFileIndex}.mul"); } var staticsPath = Core.FindDataFile($"statics{mapFileIndex}.mul", false); @@ -114,7 +114,7 @@ namespace Server } else { - logger.Warning($"statics{fileIndex}.mul was not found."); + logger.Warning("{File} was not found.", $"statics{fileIndex}.mul"); } } diff --git a/Projects/Server/TileMatrix/TileMatrixLoader.cs b/Projects/Server/TileMatrix/TileMatrixLoader.cs index 0d2e2563e..548024a88 100644 --- a/Projects/Server/TileMatrix/TileMatrixLoader.cs +++ b/Projects/Server/TileMatrix/TileMatrixLoader.cs @@ -46,11 +46,11 @@ namespace Server if (exception == null) { - logger.Information("Maps loaded ({0:F2} seconds)", stopwatch.Elapsed.TotalSeconds); + logger.Information("Maps loaded ({Duration:F2} seconds)", stopwatch.Elapsed.TotalSeconds); } else { - logger.Error(exception, "Loading maps failed ({0:F2} seconds)", stopwatch.Elapsed.TotalSeconds); + logger.Error(exception, "Loading maps failed ({Duration:F2} seconds)", stopwatch.Elapsed.TotalSeconds); throw exception; } } diff --git a/Projects/Server/Timer/Timer.DelayCall.cs b/Projects/Server/Timer/Timer.DelayCall.cs index 5d98180bb..dd2a75cd0 100644 --- a/Projects/Server/Timer/Timer.DelayCall.cs +++ b/Projects/Server/Timer/Timer.DelayCall.cs @@ -147,7 +147,7 @@ namespace Server { if (Running) { - logger.Error($"Timer is returned while still running!\n{new StackTrace()}"); + logger.Error("Timer is returned while still running!\n{StackTrace}", new StackTrace()); return; } @@ -163,7 +163,7 @@ namespace Server if (_poolCount >= _poolCapacity) { #if DEBUG_TIMERS - logger.Warning($"DelayCallTimer pool reached maximum of {_poolCapacity} timers"); + logger.Warning("DelayCallTimer pool reached maximum of {Capacity} timers", _poolCapacity); _allowFinalization = true; #endif return; @@ -181,7 +181,7 @@ namespace Server if (timer != null) { #if DEBUG_TIMERS - logger.Information($"Getting from pool: ({_poolCount} / {_poolCapacity})"); + logger.Information("Getting from pool: ({Count} / {Capacity})", _poolCount, _poolCapacity); #endif timer.Init(delay, interval, count); @@ -197,7 +197,7 @@ namespace Server _timerPoolDepletionAmount++; #if DEBUG_TIMERS - logger.Warning($"Timer pool depleted and timer was allocated.\n{new StackTrace()}"); + logger.Warning("Timer pool depleted and timer was allocated.\n{StackTrace}", new StackTrace()); #endif return new DelayCallTimer(delay, interval, count, callback); } @@ -211,7 +211,7 @@ namespace Server { if (!_allowFinalization) { - logger.Warning($"Pooled timer was not returned to the pool.\n{_stackTraces[GetHashCode()]}"); + logger.Warning("Pooled timer was not returned to the pool.\n{StackTrace}", _stackTraces[GetHashCode()]); } } #endif diff --git a/Projects/Server/Timer/Timer.Pool.cs b/Projects/Server/Timer/Timer.Pool.cs index cb92fc18f..fbdc0d91e 100644 --- a/Projects/Server/Timer/Timer.Pool.cs +++ b/Projects/Server/Timer/Timer.Pool.cs @@ -41,8 +41,9 @@ namespace Server var amountToRefill = Math.Min(_maxPoolCapacity, amountToGrow); var maximumHit = amountToGrow > amountToRefill ? " Maximum pool size has been reached." : ""; + var warningMessage = $"Timer pool depleted by {{Amount}}. Refilling with {{AmountRefill}}.{maximumHit}"; - logger.Warning($"Timer pool depleted by {_timerPoolDepletionAmount}. Refilling with {amountToRefill}.{maximumHit}"); + logger.Warning(warningMessage, _timerPoolDepletionAmount, amountToRefill); RefillPoolAsync(amountToRefill); _timerPoolDepletionAmount = 0; } @@ -62,7 +63,7 @@ namespace Server _poolHead = head; _poolCount += amount; #if DEBUG_TIMERS - logger.Information($"Returning to pool. ({_poolCount} / {_poolCapacity})"); + logger.Information("Returning to pool. ({Count} / {Capacity})", _poolCount, _poolCapacity); #endif } @@ -84,7 +85,7 @@ namespace Server internal static void RefillPool(int amount, out DelayCallTimer head, out DelayCallTimer tail) { #if DEBUG_TIMERS - logger.Information($"Filling pool with {amount} timers."); + logger.Information("Filling pool with {Amount} timers.", amount); #endif head = null; diff --git a/Projects/Server/Timer/Timer.TimerWheel.cs b/Projects/Server/Timer/Timer.TimerWheel.cs index e3dc9ae6c..8b0621b21 100644 --- a/Projects/Server/Timer/Timer.TimerWheel.cs +++ b/Projects/Server/Timer/Timer.TimerWheel.cs @@ -199,7 +199,7 @@ namespace Server // TODO: Handle timers > 17yrs #if DEBUG_TIMERS - logger.Error($"Timer is more than max duration. ({originalDelay})"); + logger.Error("Timer is more than max duration. ({Duration})", originalDelay); #endif } @@ -224,12 +224,12 @@ namespace Server while (t != null) { var name = t.ToString(); - + hash.TryGetValue(name, out var count); hash[name] = count + 1; - + total++; - + t = t?._nextTimer; } } diff --git a/Projects/Server/World/World.cs b/Projects/Server/World/World.cs index cb2606918..68b3fa7bf 100644 --- a/Projects/Server/World/World.cs +++ b/Projects/Server/World/World.cs @@ -284,11 +284,11 @@ namespace Server watch.Stop(); - logger.Information(string.Format("World loaded ({1} items, {2} mobiles) ({0:F2} seconds)", + logger.Information("World loaded ({ItemCount} items, {MobileCount} mobiles) ({Duration:F2} seconds)", watch.Elapsed.TotalSeconds, Items.Count, Mobiles.Count - )); + ); WorldState = WorldState.Running; } @@ -304,7 +304,7 @@ namespace Server { if (_pendingAdd.ContainsKey(entity.Serial)) { - logger.Warning("Entity {0} was both pending both deletion and addition after save", entity); + logger.Warning("Entity {Entity} was both pending both deletion and addition after save", entity); } RemoveEntity(entity); @@ -402,7 +402,7 @@ namespace Server watch.Stop(); - logger.Information("Writing world save snapshot done ({0:F2} seconds)", watch.Elapsed.TotalSeconds); + logger.Information("Writing world save snapshot done ({Duration:F2} seconds)", watch.Elapsed.TotalSeconds); } catch (Exception ex) { @@ -505,7 +505,7 @@ namespace Server if (exception == null) { var duration = watch.Elapsed.TotalSeconds; - logger.Information("World save completed ({0:F2} seconds)", duration); + logger.Information("World save completed ({Duration:F2} seconds)", duration); // Only broadcast if it took at least 150ms if (duration >= 0.15) diff --git a/Projects/UOContent/Accounting/AccessRestrictions.cs b/Projects/UOContent/Accounting/AccessRestrictions.cs index 08ad2484c..4522e558c 100644 --- a/Projects/UOContent/Accounting/AccessRestrictions.cs +++ b/Projects/UOContent/Accounting/AccessRestrictions.cs @@ -22,14 +22,14 @@ namespace Server if (Firewall.IsBlocked(ip)) { - logger.Information("Client: {0}: Firewall blocked connection attempt.", ip); + logger.Information("Client: {IP}: Firewall blocked connection attempt.", ip); e.AllowConnection = false; return; } if (IPLimiter.SocketBlock && !IPLimiter.Verify(ip)) { - logger.Warning("Client: {0}: Past IP limit threshold", ip); + logger.Warning("Client: {IP}: Past IP limit threshold", ip); using (var op = new StreamWriter("ipLimits.log", true)) { diff --git a/Projects/UOContent/Accounting/AccountHandler.cs b/Projects/UOContent/Accounting/AccountHandler.cs index 583091ed7..06df4cc68 100644 --- a/Projects/UOContent/Accounting/AccountHandler.cs +++ b/Projects/UOContent/Accounting/AccountHandler.cs @@ -255,7 +255,7 @@ namespace Server.Misc } else { - state.LogInfo("Deleting character {0} (0x{1:X})", index, m.Serial.Value); + state.LogInfo($"Deleting character {index} (0x{m.Serial.Value:X})"); acct.Comments.Add(new AccountComment("System", $"Character #{index + 1} {m} deleted by {state}")); @@ -314,16 +314,16 @@ namespace Server.Misc if (!CanCreate(state.Address)) { logger.Information( - "Login: {0}: Account '{1}' not created, ip already has {2} account{3}.", + $"Login: {{NetState}} Account '{{Username}}' not created, ip already has {{AccountCount}} account{(MaxAccountsPerIP == 1 ? "" : "s")}.", state, un, - MaxAccountsPerIP, - MaxAccountsPerIP == 1 ? "" : "s" + MaxAccountsPerIP ); + return null; } - logger.Information("Login: {0}: Creating new account '{1}'", state, un); + logger.Information("Login: {NetState}: Creating new account '{Username}'", state, un); var a = new Account(un, pw); @@ -337,7 +337,7 @@ namespace Server.Misc e.Accepted = false; e.RejectReason = ALRReason.InUse; - logger.Information("Login: {0}: Past IP limit threshold", e.State); + logger.Information("Login: {NetState}: Past IP limit threshold", e.State); using var op = new StreamWriter("ipLimits.log", true); op.WriteLine("{0}\tPast IP limit threshold\t{1}", e.State, Core.Now); @@ -365,28 +365,28 @@ namespace Server.Misc } else { - logger.Information("Login: {0}: Invalid username '{1}'", e.State, un); + logger.Information("Login: {NetState} Invalid username '{Username}'", e.State, un); e.RejectReason = ALRReason.Invalid; } } else if (!acct.HasAccess(e.State)) { - logger.Information("Login: {0}: Access denied for '{1}'", e.State, un); + logger.Information("Login: {NetState} Access denied for '{Username}'", e.State, un); e.RejectReason = LockdownLevel > AccessLevel.Player ? ALRReason.BadComm : ALRReason.BadPass; } else if (!acct.CheckPassword(pw)) { - logger.Information("Login: {0}: Invalid password for '{1}'", e.State, un); + logger.Information("Login: {NetState} Invalid password for '{Username}'", e.State, un); e.RejectReason = ALRReason.BadPass; } else if (acct.Banned) { - logger.Information("Login: {0}: Banned account '{1}'", e.State, un); + logger.Information("Login: {NetState} Banned account '{Username}'", e.State, un); e.RejectReason = ALRReason.Blocked; } else { - logger.Information("Login: {0}: Valid credentials for '{1}'", e.State, un); + logger.Information("Login: {NetState} Valid credentials for '{Username}'", e.State, un); e.State.Account = acct; e.Accepted = true; @@ -405,7 +405,7 @@ namespace Server.Misc { e.Accepted = false; - logger.Warning("Login: {0}: Past IP limit threshold", e.State); + logger.Warning("Login: {NetState} Past IP limit threshold", e.State); using var op = new StreamWriter("ipLimits.log", true); op.WriteLine("{0}\tPast IP limit threshold\t{1}", e.State, Core.Now); @@ -422,24 +422,24 @@ namespace Server.Misc } else if (!acct.HasAccess(e.State)) { - logger.Information("Login: {0}: Access denied for '{1}'", e.State, un); + logger.Information("Login: {NetState} Access denied for '{Username}'", e.State, un); e.Accepted = false; } else if (!acct.CheckPassword(pw)) { - logger.Information("Login: {0}: Invalid password for '{1}'", e.State, un); + logger.Information("Login: {NetState} Invalid password for '{Username}'", e.State, un); e.Accepted = false; } else if (acct.Banned) { - logger.Information("Login: {0}: Banned account '{1}'", e.State, un); + logger.Information("Login: {NetState} Banned account '{Username}'", e.State, un); e.Accepted = false; } else { acct.LogAccess(e.State); - logger.Information("Login: {0}: Account '{1}' at character list", e.State, un); + logger.Information("Login: {NetState} Account '{Username}' at character list", e.State, un); e.State.Account = acct; e.Accepted = true; e.CityInfo = StartingCities; diff --git a/Projects/UOContent/Engines/Chat/ChatPackets.cs b/Projects/UOContent/Engines/Chat/ChatPackets.cs index a74d63c0e..7eedb3abf 100644 --- a/Projects/UOContent/Engines/Chat/ChatPackets.cs +++ b/Projects/UOContent/Engines/Chat/ChatPackets.cs @@ -73,7 +73,7 @@ namespace Server.Engines.Chat if (handler == null) { - state.LogInfo("Unknown chat action 0x{0:X}: {1}", actionID, param); + state.LogInfo($"Unknown chat action 0x{actionID:X}: {param}"); return; } diff --git a/Projects/UOContent/Engines/ML Quests/Objectives/DeliverObjective.cs b/Projects/UOContent/Engines/ML Quests/Objectives/DeliverObjective.cs index 25e9ef729..87344e480 100644 --- a/Projects/UOContent/Engines/ML Quests/Objectives/DeliverObjective.cs +++ b/Projects/UOContent/Engines/ML Quests/Objectives/DeliverObjective.cs @@ -26,7 +26,7 @@ namespace Server.Engines.MLQuests.Objectives if (itemid is <= 0 or > 0x4000) { - logger.Warning("Cliloc {0} is likely giving the wrong item ID", name.Number); + logger.Warning("Cliloc {Number} is likely giving the wrong item ID", name.Number); } } } diff --git a/Projects/UOContent/Engines/Spawners/Commands/GenerateSpawnersCommand.cs b/Projects/UOContent/Engines/Spawners/Commands/GenerateSpawnersCommand.cs index 2292ce482..4c17ea231 100644 --- a/Projects/UOContent/Engines/Spawners/Commands/GenerateSpawnersCommand.cs +++ b/Projects/UOContent/Engines/Spawners/Commands/GenerateSpawnersCommand.cs @@ -107,13 +107,16 @@ namespace Server.Engines.Spawners watch.Stop(); - logger.Information("Generated {0} spawners ({1:F2} seconds, {2} failures)"); - from.SendMessage( - "GenerateSpawners: Generated {0} spawners ({1:F2} seconds, {2} failures)", + logger.Information( + "Generated {Count} spawners ({Duration:F2} seconds, {Failures} failures)", totalGenerated, watch.Elapsed.TotalSeconds, totalFailures ); + + from.SendMessage( + $"GenerateSpawners: Generated {totalGenerated} spawners ({watch.Elapsed.TotalSeconds:F2} seconds, {totalFailures} failures)" + ); } private static void ParseSpawnerList( diff --git a/Projects/UOContent/Misc/AccountPrompt.cs b/Projects/UOContent/Misc/AccountPrompt.cs index 0d4a22e06..28f6d08d0 100644 --- a/Projects/UOContent/Misc/AccountPrompt.cs +++ b/Projects/UOContent/Misc/AccountPrompt.cs @@ -31,7 +31,7 @@ public static class AccountPrompt AccessLevel = AccessLevel.Owner }; - logger.Information("Owner account created: {0}", username); + logger.Information("Owner account created: {Username}", username); ServerAccess.AddProtectedAccount(a, true); } else diff --git a/Projects/UOContent/Misc/CharacterCreation.cs b/Projects/UOContent/Misc/CharacterCreation.cs index da82bb8ec..3f20279ff 100644 --- a/Projects/UOContent/Misc/CharacterCreation.cs +++ b/Projects/UOContent/Misc/CharacterCreation.cs @@ -138,7 +138,7 @@ namespace Server.Misc if (newChar == null) { - logger.Information("Login: {0}: Character creation failed, account full", state); + logger.Information("Login: {NetState}: Character creation failed, account full", state); return; } diff --git a/Projects/UOContent/Misc/Cleanup.cs b/Projects/UOContent/Misc/Cleanup.cs index 5678ab851..176d92188 100644 --- a/Projects/UOContent/Misc/Cleanup.cs +++ b/Projects/UOContent/Misc/Cleanup.cs @@ -122,14 +122,14 @@ namespace Server.Misc if (boxes > 0) { logger.Information( - "Cleanup: Detected {0} inaccessible items, including {1} bank boxes, removing..", + "Cleanup: Detected {Count} inaccessible items, including {BankBoxes} bank boxes, removing..", items.Count, boxes ); } else { - logger.Information("Cleanup: Detected {0} inaccessible items, removing..", items.Count); + logger.Information("Cleanup: Detected {Count} inaccessible items, removing..", items.Count); } for (var i = 0; i < items.Count; ++i) diff --git a/Projects/UOContent/Misc/ServerAccess.cs b/Projects/UOContent/Misc/ServerAccess.cs index 357082c85..b5f86b9b7 100644 --- a/Projects/UOContent/Misc/ServerAccess.cs +++ b/Projects/UOContent/Misc/ServerAccess.cs @@ -25,7 +25,7 @@ public static class ServerAccess { var username = acct.Username.ToLower(); ServerAccessConfiguration.ProtectedAccounts.Add(username); - logger.Information("Protected account added: {0}", username); + logger.Information("Protected account added: {Username}", username); if (save) { @@ -37,7 +37,7 @@ public static class ServerAccess { var username = acct.Username.ToLower(); ServerAccessConfiguration.ProtectedAccounts.Remove(username); - logger.Information("Protected account removed: {0}", username); + logger.Information("Protected account removed: {Username}", username); if (save) { @@ -59,7 +59,7 @@ public static class ServerAccess if (ServerAccessConfiguration.ProtectedAccounts.Count > 0) { var protectedAccounts = string.Join(", ", ServerAccessConfiguration.ProtectedAccounts); - logger.Information("Protected accounts registered: {0}", protectedAccounts); + logger.Information("Protected accounts registered: {Count}", protectedAccounts); } } @@ -85,7 +85,7 @@ public static class ServerAccess acct.Banned = false; acct.AccessLevel = AccessLevel.Owner; - logger.Warning("Protected account \"{0}\" has been reset.", username); + logger.Warning("Protected account \"{Username}\" has been reset.", username); if (e.RejectReason is ALRReason.Blocked or ALRReason.BadPass or ALRReason.BadComm) { diff --git a/Projects/UOContent/Misc/ServerList.cs b/Projects/UOContent/Misc/ServerList.cs index d457a102a..7b20de027 100644 --- a/Projects/UOContent/Misc/ServerList.cs +++ b/Projects/UOContent/Misc/ServerList.cs @@ -104,7 +104,7 @@ namespace Server.Misc if (_publicAddress != null) { - logger.Information("Auto-detected public IP address ({0})", _publicAddress); + logger.Information("Auto-detected public IP address ({IPAddress})", _publicAddress); } else { diff --git a/Projects/UOContent/Multis/Houses/ContestHouses.cs b/Projects/UOContent/Multis/Houses/ContestHouses.cs index 18df0537e..06382205e 100644 --- a/Projects/UOContent/Multis/Houses/ContestHouses.cs +++ b/Projects/UOContent/Multis/Houses/ContestHouses.cs @@ -215,11 +215,11 @@ namespace Server.Multis { if (value.Count > 2) { - logger.Warning("More than 2 teleporters detected for {0:X}!", key); + logger.Warning("More than 2 teleporters detected for {ItemId:X}!", key); } else if (value.Count <= 1) { - logger.Warning("1 or less teleporters detected for {0:X}!", key); + logger.Warning("1 or less teleporters detected for {ItemId:X}!", key); continue; } diff --git a/Projects/UOContent/Multis/Houses/HousePackets.cs b/Projects/UOContent/Multis/Houses/HousePackets.cs index a84c9bc45..f8c41a47f 100644 --- a/Projects/UOContent/Multis/Houses/HousePackets.cs +++ b/Projects/UOContent/Multis/Houses/HousePackets.cs @@ -251,7 +251,7 @@ namespace Server.Multis if (ce != ZlibError.Okay) { - logger.Warning("ZLib error: {0} (#{1})", ce, (int)ce); + logger.Warning("ZLib error: {Error} (#{ErrorCode})", ce, (int)ce); length = 0; size = 0; } diff --git a/Projects/UOContent/Network/ProtocolExtensions.cs b/Projects/UOContent/Network/ProtocolExtensions.cs index 5c2be60ac..e8a034b3e 100644 --- a/Projects/UOContent/Network/ProtocolExtensions.cs +++ b/Projects/UOContent/Network/ProtocolExtensions.cs @@ -34,7 +34,7 @@ namespace Server.Network if (ph.Ingame && state.Mobile == null) { - state.LogInfo("Sent in-game packet (0x{0:X2}x{1:X2}) before having been attached to a mobile", packetId, cmd); + state.LogInfo($"Sent in-game packet (0x{packetId:X2}x{cmd:X2}) before having been attached to a mobile"); state.Disconnect("Sent in-game packet before being attached to a mobile."); } else if (ph.Ingame && state.Mobile.Deleted) diff --git a/Projects/UOContent/Regions/GuardedRegion.cs b/Projects/UOContent/Regions/GuardedRegion.cs index d714c1719..dc1879ab5 100644 --- a/Projects/UOContent/Regions/GuardedRegion.cs +++ b/Projects/UOContent/Regions/GuardedRegion.cs @@ -34,7 +34,7 @@ namespace Server.Regions if (!typeof(BaseGuard).IsAssignableFrom(m_GuardType)) { - logger.Warning("Invalid guard type for region '{0}'", this); + logger.Warning("Invalid guard type for region '{Region}'", this); m_GuardType = DefaultGuardType; } } From ff1b7aa9945ad13bfdefca728e1ee1ba7a2a05ed Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Mon, 6 Jun 2022 17:32:57 -0700 Subject: [PATCH 183/213] fix: Updates serialization generator to add serial support (#1047) --- .config/dotnet-tools.json | 2 +- Projects/Server/Server.csproj | 2 +- Projects/UOContent/UOContent.csproj | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 2074240b9..c0b05674e 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "modernuoschemagenerator": { - "version": "2.0.4", + "version": "2.0.5", "commands": [ "ModernUOSchemaGenerator" ] diff --git a/Projects/Server/Server.csproj b/Projects/Server/Server.csproj index 1c7cadb61..c1eaa1ceb 100755 --- a/Projects/Server/Server.csproj +++ b/Projects/Server/Server.csproj @@ -41,7 +41,7 @@ - + diff --git a/Projects/UOContent/UOContent.csproj b/Projects/UOContent/UOContent.csproj index cc056a51a..89015f409 100755 --- a/Projects/UOContent/UOContent.csproj +++ b/Projects/UOContent/UOContent.csproj @@ -46,7 +46,7 @@ - + From 12404ba6f67b594a4364d0dbabd5f0b1d17dd7f7 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 12 Jun 2022 09:59:23 -0700 Subject: [PATCH 184/213] fix: Fixes linux not enumerating directories, and wrong spelling for migration files (#1049) --- Projects/Server/Main.cs | 11 +++++++---- ...on => Server.Items.SpinningWheelEastAddon.v0.json} | 0 ...son => Server.Items.SpinningWheelEastDeed.v0.json} | 0 ...n => Server.Items.SpinningWheelSouthAddon.v0.json} | 0 ...on => Server.Items.SpinningWheelSouthDeed.v0.json} | 0 5 files changed, 7 insertions(+), 4 deletions(-) rename Projects/UOContent/Migrations/{Server.Items.SpinningwheelEastAddon.v0.json => Server.Items.SpinningWheelEastAddon.v0.json} (100%) rename Projects/UOContent/Migrations/{Server.Items.SpinningwheelEastDeed.v0.json => Server.Items.SpinningWheelEastDeed.v0.json} (100%) rename Projects/UOContent/Migrations/{Server.Items.SpinningwheelSouthAddon.v0.json => Server.Items.SpinningWheelSouthAddon.v0.json} (100%) rename Projects/UOContent/Migrations/{Server.Items.SpinningwheelSouthDeed.v0.json => Server.Items.SpinningWheelSouthDeed.v0.json} (100%) diff --git a/Projects/Server/Main.cs b/Projects/Server/Main.cs index c684e5fcf..f964a49b0 100644 --- a/Projects/Server/Main.cs +++ b/Projects/Server/Main.cs @@ -252,10 +252,13 @@ namespace Server if (IsLinux && !File.Exists(fullPath)) { var fi = new FileInfo(fullPath); - fullPath = fi.Directory!.EnumerateFiles( - fi.Name, - new EnumerationOptions { MatchCasing = MatchCasing.CaseInsensitive } - ).FirstOrDefault()?.FullName; + if (fi.Directory != null && Directory.Exists(fi.Directory.FullName)) + { + fullPath = fi.Directory.EnumerateFiles( + fi.Name, + new EnumerationOptions { MatchCasing = MatchCasing.CaseInsensitive } + ).FirstOrDefault()?.FullName; + } } if (File.Exists(fullPath)) diff --git a/Projects/UOContent/Migrations/Server.Items.SpinningwheelEastAddon.v0.json b/Projects/UOContent/Migrations/Server.Items.SpinningWheelEastAddon.v0.json similarity index 100% rename from Projects/UOContent/Migrations/Server.Items.SpinningwheelEastAddon.v0.json rename to Projects/UOContent/Migrations/Server.Items.SpinningWheelEastAddon.v0.json diff --git a/Projects/UOContent/Migrations/Server.Items.SpinningwheelEastDeed.v0.json b/Projects/UOContent/Migrations/Server.Items.SpinningWheelEastDeed.v0.json similarity index 100% rename from Projects/UOContent/Migrations/Server.Items.SpinningwheelEastDeed.v0.json rename to Projects/UOContent/Migrations/Server.Items.SpinningWheelEastDeed.v0.json diff --git a/Projects/UOContent/Migrations/Server.Items.SpinningwheelSouthAddon.v0.json b/Projects/UOContent/Migrations/Server.Items.SpinningWheelSouthAddon.v0.json similarity index 100% rename from Projects/UOContent/Migrations/Server.Items.SpinningwheelSouthAddon.v0.json rename to Projects/UOContent/Migrations/Server.Items.SpinningWheelSouthAddon.v0.json diff --git a/Projects/UOContent/Migrations/Server.Items.SpinningwheelSouthDeed.v0.json b/Projects/UOContent/Migrations/Server.Items.SpinningWheelSouthDeed.v0.json similarity index 100% rename from Projects/UOContent/Migrations/Server.Items.SpinningwheelSouthDeed.v0.json rename to Projects/UOContent/Migrations/Server.Items.SpinningWheelSouthDeed.v0.json From b74b47159f913dc4aa44429453f19c7185405968 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 12 Jun 2022 21:17:42 -0700 Subject: [PATCH 185/213] fix: Fixes localization corner cases with OPL (#1050) ## Changes - [X] Adds OPL convenience methods - `opl.Add(cliloc, value)` and `opl.Add(value)` - value as an integer or string works just like `opl.Add(cliloc, $"{value}")` - `opl.AddLocalized(cliloc, clilocValue)` - works the same as `opl.Add(cliloc, $"#{clilocValue}");` - [X] Simplifies basic `list.Add()` situations - [X] Changes cliloc as an argument so it works with custom IPropertyList implementations (HTML) - [X] Fixes plants so they support the old localization and new (changed in 7.0.12.0+) - [X] Exposes more methods to override for Item to make creating custom OPL possible. ## Important Notes * Using a ternary as an argument, like this `opl.Add(number, showType ? $"{type}\t{value}" : $"{value}");` _will not use the correct string interpolation_. This means if you use a custom PropertyList (for HTML or some other purpose), the property list won't be localized properly. * All localization values must be interpolated, even if they are literal strings, or integers. Example: `opl.Add(number, $"{"Charges"}\t{m_Charges}");` is correct. Using the following: `$"Charges\t{m_Charges}"` will not work for custom PropertyList implementations! --- Projects/Server/Client/ClientVersion.cs | 1 + Projects/Server/Items/Item.cs | 23 +- Projects/Server/Mobiles/Mobile.cs | 17 +- .../Network/Packets/IncomingEntityPackets.cs | 4 +- .../Packets/IncomingExtendedCommandPackets.cs | 4 +- Projects/Server/PropertyList/IPropertyList.cs | 18 +- .../Server/PropertyList/ObjectPropertyList.cs | 53 ++-- .../Bulk Orders/Books/BulkOrderBook.cs | 2 +- .../UOContent/Engines/Bulk Orders/LargeBOD.cs | 4 +- .../UOContent/Engines/Bulk Orders/SmallBOD.cs | 4 +- .../Engines/CannedEvil/ChampionSpawn.cs | 9 +- .../Items/Traps/FactionTrapRemovalKit.cs | 2 +- .../Mobiles/Guards/BaseFactionGuard.cs | 2 +- .../UOContent/Engines/Plants/PlantItem.cs | 230 +++++++++++++----- Projects/UOContent/Engines/Plants/Seed.cs | 34 ++- .../Quests/Collector/Items/PaintedImage.cs | 2 +- .../Quests/Core/Items/HornOfRetreat.cs | 2 +- .../Quests/Witch Apprentice/Objectives.cs | 7 +- .../UOContent/Engines/Spawners/BaseSpawner.cs | 12 +- .../Engines/Spawners/RegionSpawner.cs | 2 +- .../BasePigmentsOfTokuno.cs | 2 +- Projects/UOContent/Items/Aquarium/Aquarium.cs | 16 +- Projects/UOContent/Items/Aquarium/FishBowl.cs | 2 +- .../UOContent/Items/Aquarium/VacationWafer.cs | 2 +- Projects/UOContent/Items/Armor/BaseArmor.cs | 77 +++--- .../Items/Armor/Glasses/ElvenGlasses.cs | 30 +-- .../UOContent/Items/Clothing/BaseClothing.cs | 63 ++--- .../BaseDecorationArtifact.cs | 4 +- .../UOContent/Items/Deeds/CommodityDeed.cs | 32 ++- Projects/UOContent/Items/Jewels/BaseJewel.cs | 46 ++-- Projects/UOContent/Items/Misc/BankCheck.cs | 9 +- .../Items/Misc/CommunicationCrystals.cs | 4 +- .../UOContent/Items/Misc/PromotionalToken.cs | 12 +- Projects/UOContent/Items/Misc/Teleporter.cs | 16 +- .../UOContent/Items/Quivers/BaseQuiver.cs | 60 ++--- .../Items/Resources/Blacksmithing/Ingots.cs | 2 +- .../Items/Resources/Blacksmithing/Ore.cs | 2 +- .../UOContent/Items/Resources/Tailor/Hides.cs | 2 +- .../Items/Resources/Tailor/Leathers.cs | 2 +- .../Carpenter Items/TaxidermyKit.cs | 4 +- .../Fishing/Misc/ShipwreckedItem.cs | 2 +- .../Harvest Tools/BaseHarvestTool.cs | 2 +- .../Skill Items/Magical/Misc/RecallRune.cs | 6 +- .../Items/Skill Items/Magical/Spellbook.cs | 46 ++-- .../Items/Skill Items/Misc/RecipeScroll.cs | 9 +- .../Musical Instruments/BaseInstrument.cs | 2 +- .../Items/Skill Items/Ninjitsu/Fukiya.cs | 2 +- .../Items/Skill Items/Ninjitsu/FukiyaDarts.cs | 2 +- .../Skill Items/Ninjitsu/LeatherNinjaBelt.cs | 2 +- .../Items/Skill Items/Ninjitsu/Shuriken.cs | 2 +- .../Items/Skill Items/Tools/BaseTool.cs | 2 +- .../Items/Skill Items/Tools/RunicSewingKit.cs | 29 +-- .../Dawn's Music Box/DawnsMusicBox.cs | 6 +- .../8th Anniversary Items/FountainOfLife.cs | 2 +- .../8th Anniversary Items/Talismans.cs | 2 +- .../Blacksmithy/AncientSmithyHammer.cs | 2 +- .../Blacksmithy/GlovesOfMining.cs | 2 +- .../Blacksmithy/PowderOfTemperament.cs | 2 +- .../Items/Special/Gifts/RoseOfTrinsic.cs | 2 +- .../UOContent/Items/Special/HeritageToken.cs | 2 +- .../Special/House Raffle/HouseRaffleDeed.cs | 4 +- .../Special/House Raffle/HouseRaffleStone.cs | 4 +- .../Items/Special/Solen Items/BagOfSending.cs | 2 +- .../Special/Solen Items/BraceletOfBinding.cs | 10 +- Projects/UOContent/Items/Special/SoulStone.cs | 13 +- .../Items/Special/Veteran Rewards/Cannon.cs | 4 +- .../Veteran Rewards/WeaponEngravingTool.cs | 2 +- .../UOContent/Items/Talismans/BaseTalisman.cs | 67 ++--- .../UOContent/Items/Weapons/BaseWeapon.cs | 111 +++++---- Projects/UOContent/Misc/AOS.cs | 2 +- Projects/UOContent/Mobiles/PlayerMobile.cs | 7 +- Projects/UOContent/Multis/Houses/BaseHouse.cs | 13 +- Projects/UOContent/Multis/Houses/HouseSign.cs | 2 +- .../Spells/Spellweaving/Items/ArcaneFocus.cs | 2 +- .../Spellweaving/Items/TransientItem.cs | 4 +- 75 files changed, 715 insertions(+), 477 deletions(-) diff --git a/Projects/Server/Client/ClientVersion.cs b/Projects/Server/Client/ClientVersion.cs index 3c4eafe00..412eb53bd 100644 --- a/Projects/Server/Client/ClientVersion.cs +++ b/Projects/Server/Client/ClientVersion.cs @@ -39,6 +39,7 @@ public class ClientVersion : IComparable, IComparer /// Overridable. Sends the object property list to . /// - public virtual void SendPropertiesTo(Mobile from) + public virtual void SendPropertiesTo(NetState ns) { - from.NetState?.Send(PropertyList.Buffer); + ns?.Send(PropertyList.Buffer); } /// @@ -1829,7 +1828,7 @@ namespace Server } else { - list.Add(1050039, $"{m_Amount}\t#{LabelNumber}"); // ~1_NUMBER~ ~2_ITEMNAME~ + list.Add(1050039, $"{m_Amount}\t{LabelNumber:#}"); // ~1_NUMBER~ ~2_ITEMNAME~ } } else @@ -1874,35 +1873,35 @@ namespace Server if (v != 0) { - list.Add(1060448, $"{v}"); // physical resist ~1_val~% + list.Add(1060448, v); // physical resist ~1_val~% } v = FireResistance; if (v != 0) { - list.Add(1060447, $"{v}"); // fire resist ~1_val~% + list.Add(1060447, v); // fire resist ~1_val~% } v = ColdResistance; if (v != 0) { - list.Add(1060445, $"{v}"); // cold resist ~1_val~% + list.Add(1060445, v); // cold resist ~1_val~% } v = PoisonResistance; if (v != 0) { - list.Add(1060449, $"{v}"); // poison resist ~1_val~% + list.Add(1060449, v); // poison resist ~1_val~% } v = EnergyResistance; if (v != 0) { - list.Add(1060446, $"{v}"); // energy resist ~1_val~% + list.Add(1060446, v); // energy resist ~1_val~% } } @@ -2401,7 +2400,7 @@ namespace Server return list; } - public void ClearProperties() + public virtual void ClearProperties() { m_PropertyList = null; } @@ -3080,7 +3079,7 @@ namespace Server SendOPLPacketTo(ns, opl); } - public void SendOPLPacketTo(NetState ns, Span opl = default) + public virtual void SendOPLPacketTo(NetState ns, Span opl = default) { if (!ObjectPropertyList.Enabled) { diff --git a/Projects/Server/Mobiles/Mobile.cs b/Projects/Server/Mobiles/Mobile.cs index fea0a9345..76a307d15 100644 --- a/Projects/Server/Mobiles/Mobile.cs +++ b/Projects/Server/Mobiles/Mobile.cs @@ -3413,9 +3413,9 @@ namespace Server public int GetAOSStatus(int index) => AOSStatusHandler?.Invoke(this, index) ?? 0; - public virtual void SendPropertiesTo(Mobile from) + public virtual void SendPropertiesTo(NetState ns) { - from.NetState?.Send(PropertyList.Buffer); + ns?.Send(PropertyList.Buffer); } public virtual void OnAosSingleClick(Mobile from) @@ -3485,11 +3485,14 @@ namespace Server if (guildTitle.Length > 0) { - list.Add( - NewGuildDisplay - ? $"{Utility.FixHtml(guildTitle)}, {Utility.FixHtml(guild.Name)}" - : $"{Utility.FixHtml(guildTitle)}, {Utility.FixHtml(guild.Name)} Guild{type}" - ); + if (NewGuildDisplay) + { + list.Add($"{Utility.FixHtml(guildTitle)}, {Utility.FixHtml(guild.Name)}"); + } + else + { + list.Add($"{Utility.FixHtml(guildTitle)}, {Utility.FixHtml(guild.Name)} Guild{type}"); + } } else { diff --git a/Projects/Server/Network/Packets/IncomingEntityPackets.cs b/Projects/Server/Network/Packets/IncomingEntityPackets.cs index 40fe5a252..8ae998b03 100644 --- a/Projects/Server/Network/Packets/IncomingEntityPackets.cs +++ b/Projects/Server/Network/Packets/IncomingEntityPackets.cs @@ -175,7 +175,7 @@ public static class IncomingEntityPackets if (m != null && from.CanSee(m) && Utility.InUpdateRange(from.Location, m.Location)) { - m.SendPropertiesTo(from); + m.SendPropertiesTo(state); } } else if (s.IsItem) @@ -185,7 +185,7 @@ public static class IncomingEntityPackets if (item?.Deleted == false && from.CanSee(item) && Utility.InUpdateRange(from.Location, item.GetWorldLocation())) { - item.SendPropertiesTo(from); + item.SendPropertiesTo(state); } } } diff --git a/Projects/Server/Network/Packets/IncomingExtendedCommandPackets.cs b/Projects/Server/Network/Packets/IncomingExtendedCommandPackets.cs index cd98b0bba..0a8e399aa 100644 --- a/Projects/Server/Network/Packets/IncomingExtendedCommandPackets.cs +++ b/Projects/Server/Network/Packets/IncomingExtendedCommandPackets.cs @@ -330,7 +330,7 @@ public static class IncomingExtendedCommandPackets if (m != null && from.CanSee(m) && Utility.InUpdateRange(from.Location, m.Location)) { - m.SendPropertiesTo(from); + m.SendPropertiesTo(state); } } else if (s.IsItem) @@ -340,7 +340,7 @@ public static class IncomingExtendedCommandPackets if (item?.Deleted == false && from.CanSee(item) && Utility.InUpdateRange(from.Location, item.GetWorldLocation())) { - item.SendPropertiesTo(from); + item.SendPropertiesTo(state); } } } diff --git a/Projects/Server/PropertyList/IPropertyList.cs b/Projects/Server/PropertyList/IPropertyList.cs index 59d9a57d7..41b5fa845 100644 --- a/Projects/Server/PropertyList/IPropertyList.cs +++ b/Projects/Server/PropertyList/IPropertyList.cs @@ -22,9 +22,25 @@ public interface IPropertyList : ISelfInterpolatedStringHandler { public void Reset(); public void Terminate(); - public void Add(int number, string argument = null); + + public void Add(int number); + + /** Convenience method for $"{argument}". */ + public void Add(int number, string argument); + + /** Convenience method for $"{text}". */ public void Add(string text); + /** Convenience method for $"{value}". */ + public void Add(int number, int value); + + /** Convenience method for $"{value:#}". */ + public void AddLocalized(int value); + + /** Convenience method for $"{value:#}". */ + public void AddLocalized(int number, int value); + // String Interpolation + public void Add([InterpolatedStringHandlerArgument("")] ref InterpolatedStringHandler handler); public void Add(int number, [InterpolatedStringHandlerArgument("")] ref InterpolatedStringHandler handler); } diff --git a/Projects/Server/PropertyList/ObjectPropertyList.cs b/Projects/Server/PropertyList/ObjectPropertyList.cs index 834afffd8..fd147c65b 100644 --- a/Projects/Server/PropertyList/ObjectPropertyList.cs +++ b/Projects/Server/PropertyList/ObjectPropertyList.cs @@ -119,29 +119,22 @@ public sealed class ObjectPropertyList : IPropertyList, IDisposable _hash ^= (val >> 26) & 0x3F; } - public void Add(int number, string? arguments = null) + public void Add(int number) { if (number == 0) { return; } - arguments ??= ""; - if (Header == 0) { Header = number; - HeaderArgs = arguments; + HeaderArgs = ""; } AddHash(number); - if (arguments.Length > 0) - { - AddHash(arguments.GetHashCode(StringComparison.Ordinal)); - } - int strLength = arguments.Length * 2; - int length = _bufferPos + 6 + strLength; + int length = _bufferPos + 6; while (length > _buffer.Length) { Flush(); @@ -149,24 +142,31 @@ public sealed class ObjectPropertyList : IPropertyList, IDisposable var writer = new SpanWriter(_buffer.AsSpan(_bufferPos)); writer.Write(number); - writer.Write((ushort)strLength); - writer.WriteLittleUni(arguments); - - _bufferPos += writer.BytesWritten; - _pos = 0; + writer.Write((ushort)0); + _bufferPos += 6; } + public void Add(int number, string? arguments) => InternalAdd(number, $"{arguments}"); + public void Add(string argument) => InternalAdd(GetStringNumber(), $"{argument}"); + public void Add(int number, int value) => InternalAdd(number, $"{value}"); + public void AddLocalized(int value) => InternalAdd(GetStringNumber(), $"{value:#}"); + public void AddLocalized(int number, int value) => InternalAdd(number, $"{value:#}"); + private int GetStringNumber() => _stringNumbers[_stringNumbersIndex++ % _stringNumbers.Length]; - public void Add(string argument) => Add(GetStringNumber(), argument); - + // String Interpolation public void Add( [InterpolatedStringHandlerArgument("")] ref IPropertyList.InterpolatedStringHandler handler - ) => Add(GetStringNumber(), ref handler); + ) => InternalAdd(GetStringNumber(), ref handler); - // String Interpolation public void Add( + int number, + [InterpolatedStringHandlerArgument("")] + ref IPropertyList.InterpolatedStringHandler handler + ) => InternalAdd(number, ref handler); + + private void InternalAdd( int number, [InterpolatedStringHandlerArgument("")] ref IPropertyList.InterpolatedStringHandler handler) @@ -182,14 +182,10 @@ public sealed class ObjectPropertyList : IPropertyList, IDisposable { Header = number; HeaderArgs = chars.ToString(); - HeaderArgs.GetHashCode(StringComparison.Ordinal); } AddHash(number); - if (chars.Length > 0) - { - AddHash(string.GetHashCode(chars, StringComparison.Ordinal)); - } + AddHash(string.GetHashCode(chars, StringComparison.Ordinal)); int strLength = chars.Length * 2; int length = _bufferPos + 6 + strLength; @@ -253,7 +249,6 @@ public sealed class ObjectPropertyList : IPropertyList, IDisposable public void AppendFormatted(T value) { - string? s; if (value is IFormattable) { @@ -284,6 +279,14 @@ public sealed class ObjectPropertyList : IPropertyList, IDisposable public void AppendFormatted(T value, string? format) { + // We support localization '#' cliloc formatter for custom property lists + // This allows someone to build an IPropertyList that creates HTML using the same syntax as LocalizationInterpolationHandler + if (format == "#") + { + AppendLiteral("#"); + format = null; + } + string? s; if (value is IFormattable) { diff --git a/Projects/UOContent/Engines/Bulk Orders/Books/BulkOrderBook.cs b/Projects/UOContent/Engines/Bulk Orders/Books/BulkOrderBook.cs index b05ede58c..9766a698a 100644 --- a/Projects/UOContent/Engines/Bulk Orders/Books/BulkOrderBook.cs +++ b/Projects/UOContent/Engines/Bulk Orders/Books/BulkOrderBook.cs @@ -262,7 +262,7 @@ namespace Server.Engines.BulkOrders { base.GetProperties(list); - list.Add(1062344, $"{Entries.Count}"); // Deeds in book: ~1_val~ + list.Add(1062344, Entries.Count); // Deeds in book: ~1_val~ if (!string.IsNullOrEmpty(m_BookName)) { diff --git a/Projects/UOContent/Engines/Bulk Orders/LargeBOD.cs b/Projects/UOContent/Engines/Bulk Orders/LargeBOD.cs index d16cdc5c6..b918f3e79 100644 --- a/Projects/UOContent/Engines/Bulk Orders/LargeBOD.cs +++ b/Projects/UOContent/Engines/Bulk Orders/LargeBOD.cs @@ -54,12 +54,12 @@ namespace Server.Engines.BulkOrders list.Add(LargeBODGump.GetMaterialNumberFor(Material)); // All items must be made with x material. } - list.Add(1060656, $"{AmountMax}"); // amount to make: ~1_val~ + list.Add(1060656, AmountMax); // amount to make: ~1_val~ for (var i = 0; i < _entries.Length; ++i) { var entry = _entries[i]; - list.Add(1060658 + i, $"#{entry.Details.Number}\t{entry.Amount}"); // ~1_val~: ~2_val~ + list.Add(1060658 + i, $"{entry.Details.Number:#}\t{entry.Amount}"); // ~1_val~: ~2_val~ } } diff --git a/Projects/UOContent/Engines/Bulk Orders/SmallBOD.cs b/Projects/UOContent/Engines/Bulk Orders/SmallBOD.cs index 206a2d4e0..5d3d7c7a2 100644 --- a/Projects/UOContent/Engines/Bulk Orders/SmallBOD.cs +++ b/Projects/UOContent/Engines/Bulk Orders/SmallBOD.cs @@ -77,8 +77,8 @@ namespace Server.Engines.BulkOrders list.Add(SmallBODGump.GetMaterialNumberFor(Material)); // All items must be made with x material. } - list.Add(1060656, $"{AmountMax}"); // amount to make: ~1_val~ - list.Add(1060658, $"#{m_Number}\t{m_AmountCur}"); // ~1_val~: ~2_val~ + list.Add(1060656, AmountMax); // amount to make: ~1_val~ + list.Add(1060658, $"{m_Number:#}\t{m_AmountCur}"); // ~1_val~: ~2_val~ } public override void OnDoubleClick(Mobile from) diff --git a/Projects/UOContent/Engines/CannedEvil/ChampionSpawn.cs b/Projects/UOContent/Engines/CannedEvil/ChampionSpawn.cs index d98063e56..16d89198d 100755 --- a/Projects/UOContent/Engines/CannedEvil/ChampionSpawn.cs +++ b/Projects/UOContent/Engines/CannedEvil/ChampionSpawn.cs @@ -945,12 +945,11 @@ namespace Server.Engines.CannedEvil if (m_Active) { - list.Add(1060742); // active - list.Add(1060658, $"Type\t{m_Type}"); // ~1_val~: ~2_val~ - list.Add(1060659, $"Level\t{Level}"); // ~1_val~: ~2_val~ + list.Add(1060742); // active + list.Add(1060658, $"{"Type"}\t{m_Type}"); // ~1_val~: ~2_val~ + list.Add(1060659, $"{"Level"}\t{Level}"); // ~1_val~: ~2_val~ var killRatio = 100.0 * ((double)m_Kills / MaxKills); - list.Add(1060660, $"Kills\t{m_Kills} of {MaxKills} ({killRatio:F1}%)"); // ~1_val~: ~2_val~ - //list.Add(1060661, "Spawn Range\t{0}", m_SpawnRange); // ~1_val~: ~2_val~ + list.Add(1060660, $"{"Kills"}\t{m_Kills} of {MaxKills} ({killRatio:F1}%)"); // ~1_val~: ~2_val~ } else { diff --git a/Projects/UOContent/Engines/Factions/Items/Traps/FactionTrapRemovalKit.cs b/Projects/UOContent/Engines/Factions/Items/Traps/FactionTrapRemovalKit.cs index 364c98c3a..0ee8d8ebb 100644 --- a/Projects/UOContent/Engines/Factions/Items/Traps/FactionTrapRemovalKit.cs +++ b/Projects/UOContent/Engines/Factions/Items/Traps/FactionTrapRemovalKit.cs @@ -35,7 +35,7 @@ namespace Server.Factions base.GetProperties(list); // NOTE: OSI does not list uses remaining; intentional difference - list.Add(1060584, $"{Charges}"); // uses remaining: ~1_val~ + list.Add(1060584, Charges); // uses remaining: ~1_val~ } public override void Serialize(IGenericWriter writer) diff --git a/Projects/UOContent/Engines/Factions/Mobiles/Guards/BaseFactionGuard.cs b/Projects/UOContent/Engines/Factions/Mobiles/Guards/BaseFactionGuard.cs index c5fe00653..bffd70992 100644 --- a/Projects/UOContent/Engines/Factions/Mobiles/Guards/BaseFactionGuard.cs +++ b/Projects/UOContent/Engines/Factions/Mobiles/Guards/BaseFactionGuard.cs @@ -314,7 +314,7 @@ namespace Server.Factions if (m_Faction != null && Map == Faction.Facet) { - list.Add(1060846, m_Faction.Definition.PropName); // Guard: ~1_val~ + list.Add(1060846, $"{m_Faction.Definition.PropName}"); // Guard: ~1_val~ } } diff --git a/Projects/UOContent/Engines/Plants/PlantItem.cs b/Projects/UOContent/Engines/Plants/PlantItem.cs index 22061af38..ba71e6455 100644 --- a/Projects/UOContent/Engines/Plants/PlantItem.cs +++ b/Projects/UOContent/Engines/Plants/PlantItem.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using Server.ContextMenus; using Server.Gumps; @@ -30,17 +31,14 @@ namespace Server.Engines.Plants public class PlantItem : Item, ISecurable { - /* - * Clients 7.0.12.0+ expect a container type in the plant label. - * To support older (and only older) clients, change this to false. - */ - private static readonly bool ShowContainerType = true; private PlantHue m_PlantHue; - private PlantStatus m_PlantStatus; private PlantType m_PlantType; private bool m_ShowType; + // For clients older than 7.0.12.0 + private ObjectPropertyList _oldClientPropertyList; + [Constructible] public PlantItem(bool fertileDirt = false) : base(0x1602) { @@ -59,6 +57,9 @@ namespace Server.Engines.Plants public PlantSystem PlantSystem { get; private set; } + public ObjectPropertyList OldClientPropertyList => + _oldClientPropertyList ??= InitializePropertyList(_oldClientPropertyList); + public override bool ForceShowProperties => ObjectPropertyList.Enabled; [CommandProperty(AccessLevel.GameMaster)] @@ -248,80 +249,189 @@ namespace Server.Engines.Plants InvalidateProperties(); } - public override void AddNameProperty(IPropertyList list) + private ObjectPropertyList InitializePropertyList(ObjectPropertyList list) { - if (m_PlantStatus >= PlantStatus.DeadTwigs) - { - base.AddNameProperty(list); - } - else if (m_PlantStatus < PlantStatus.Seed) - { - string args; + GetProperties(list); + AppendChildProperties(list); + list.Terminate(); + return list; + } - if (ShowContainerType) + // Overridden to support new and old client localization + public override void SendOPLPacketTo(NetState ns, Span opl = default) + { + if (!ObjectPropertyList.Enabled) + { + return; + } + + if (ns.Version < ClientVersion.Version70120) + { + ns.SendOPLInfo(Serial, OldClientPropertyList.Hash); + return; + } + + ns.SendOPLInfo(this); + } + + public override void SendPropertiesTo(NetState ns) + { + if (ns?.Version < ClientVersion.Version70120) + { + ns?.Send(OldClientPropertyList.Buffer); + return; + } + + ns?.Send(PropertyList.Buffer); + } + + public override void ClearProperties() + { + base.ClearProperties(); + _oldClientPropertyList = null; + } + + public override void InvalidateProperties() + { + if (!ObjectPropertyList.Enabled) + { + return; + } + + base.InvalidateProperties(); + + if (Map != null && Map != Map.Internal && !World.Loading) + { + int? oldHash = _oldClientPropertyList?.Hash; + + if (oldHash != null) { - args = $"#{GetLocalizedContainerType()}\t#{PlantSystem.GetLocalizedDirtStatus()}"; + _oldClientPropertyList.Reset(); } else { - args = $"#{PlantSystem.GetLocalizedDirtStatus()}"; + _oldClientPropertyList = new ObjectPropertyList(this); } - list.Add(1060830, args); // a ~1_val~ of ~2_val~ dirt + InitializePropertyList(_oldClientPropertyList); + + if (oldHash != _oldClientPropertyList.Hash) + { + Delta(ItemDelta.Properties); + } } else { - var typeInfo = PlantTypeInfo.GetInfo(m_PlantType); - var hueInfo = PlantHueInfo.GetInfo(m_PlantHue); + ClearProperties(); + } + } - if (m_PlantStatus >= PlantStatus.DecorativePlant) + public override void OnAosSingleClick(Mobile from) + { + var ns = from?.NetState; + + if (ns == null) + { + return; + } + + var opl = ns.Version < ClientVersion.Version70120 ? OldClientPropertyList : PropertyList; + + if (opl.Header > 0) + { + from.NetState.SendMessageLocalized( + Serial, + ItemID, + MessageType.Label, + 0x3B2, + 3, + opl.Header, + Name, + opl.HeaderArgs + ); + } + } + + public override void GetProperties(IPropertyList list) + { + if (m_PlantStatus >= PlantStatus.DeadTwigs) + { + base.GetProperties(list); + return; + } + + var container = GetLocalizedContainerType(); + var dirt = PlantSystem.GetLocalizedDirtStatus(); + var health = PlantSystem.GetLocalizedHealth(); + var plantStatus = GetLocalizedPlantStatus(); + + if (m_PlantStatus < PlantStatus.Seed) + { + // Clients above 7.0.12.0 use the regular PropertyList + if (list != _oldClientPropertyList) { - list.Add(typeInfo.GetPlantLabelDecorative(hueInfo), $"#{hueInfo.Name}\t#{typeInfo.Name}"); + // a ~1_val~ of ~2_val~ dirt + list.Add(1060830, $"{container:#}\t{dirt:#}"); } - else if (m_PlantStatus >= PlantStatus.FullGrownPlant) + else + { + // a ~1_val~ of ~2_val~ dirt + list.Add(1060830, $"{dirt:#}"); + } + + return; + } + + var typeInfo = PlantTypeInfo.GetInfo(m_PlantType); + var hueInfo = PlantHueInfo.GetInfo(m_PlantHue); + + if (m_PlantStatus >= PlantStatus.DecorativePlant) + { + list.Add(typeInfo.GetPlantLabelDecorative(hueInfo), $"{hueInfo.Name:#}\t{typeInfo.Name:#}"); + return; + } + + if (m_PlantStatus >= PlantStatus.FullGrownPlant) + { + list.Add( + typeInfo.GetPlantLabelFullGrown(hueInfo), + $"{health:#}\t{hueInfo.Name:#}\t{typeInfo.Name:#}" + ); + return; + } + + if (m_ShowType) + { + var plantNumber = m_PlantStatus == PlantStatus.Plant + ? typeInfo.GetPlantLabelPlant(hueInfo) + : typeInfo.GetPlantLabelSeed(hueInfo); + + if (list != _oldClientPropertyList) { list.Add( - typeInfo.GetPlantLabelFullGrown(hueInfo), - $"#{PlantSystem.GetLocalizedHealth()}\t#{hueInfo.Name}\t#{typeInfo.Name}" + plantNumber, + $"{container:#}\t{dirt:#}\t{health:#}\t{hueInfo.Name:#}\t{typeInfo.Name:#}\t{plantStatus:#}" ); } else { - string args; - - if (ShowContainerType) - { - args = - $"#{GetLocalizedContainerType()}\t#{PlantSystem.GetLocalizedDirtStatus()}\t#{PlantSystem.GetLocalizedHealth()}"; - } - else - { - args = $"#{PlantSystem.GetLocalizedDirtStatus()}\t#{PlantSystem.GetLocalizedHealth()}"; - } - - if (m_ShowType) - { - args += $"\t#{hueInfo.Name}\t#{typeInfo.Name}\t#{GetLocalizedPlantStatus()}"; - - if (m_PlantStatus == PlantStatus.Plant) - { - list.Add(typeInfo.GetPlantLabelPlant(hueInfo), args); - } - else - { - list.Add(typeInfo.GetPlantLabelSeed(hueInfo), args); - } - } - else - { - args += - $"\t#{(typeInfo.PlantCategory == PlantCategory.Default ? hueInfo.Name : (int)typeInfo.PlantCategory)}\t#{GetLocalizedPlantStatus()}"; - - list.Add( - hueInfo.IsBright() ? 1060832 : 1060831, - args - ); // a ~1_val~ of ~2_val~ dirt with a ~3_val~ [bright] ~4_val~ ~5_val~ - } + list.Add( + plantNumber, + $"{dirt:#}\t{health:#}\t{hueInfo.Name:#}\t{typeInfo.Name:#}\t{plantStatus:#}" + ); + } + } + else + { + var category = typeInfo.PlantCategory == PlantCategory.Default ? hueInfo.Name : (int)typeInfo.PlantCategory; + var plantNumber = hueInfo.IsBright() ? 1060832 : 1060831; + if (list != _oldClientPropertyList) + { + list.Add(plantNumber, $"{container:#}\t{dirt:#}\t{health:#}\t{category:#}\t{plantStatus:#}"); + } + else + { + list.Add(plantNumber,$"{dirt:#}\t{health:#}\t{category:#}\t{plantStatus:#}"); } } } diff --git a/Projects/UOContent/Engines/Plants/Seed.cs b/Projects/UOContent/Engines/Plants/Seed.cs index ef05f343d..bee1228a8 100644 --- a/Projects/UOContent/Engines/Plants/Seed.cs +++ b/Projects/UOContent/Engines/Plants/Seed.cs @@ -126,7 +126,39 @@ namespace Server.Engines.Plants public override void AddNameProperty(IPropertyList list) { - list.Add(GetLabel(out var args), args); + var typeInfo = PlantTypeInfo.GetInfo(m_PlantType); + var hueInfo = PlantHueInfo.GetInfo(m_PlantHue); + + int title; + + if (m_ShowType || typeInfo.PlantCategory == PlantCategory.Default) + { + title = hueInfo.Name; + } + else + { + title = (int)typeInfo.PlantCategory; + } + + if (Amount == 1) + { + if (m_ShowType) + { + list.Add(typeInfo.GetSeedLabel(hueInfo), $"{title:#}\t{typeInfo.Name:#}"); + return; + } + + list.Add(hueInfo.IsBright() ? 1060839 : 1060838, $"{title:#}"); + return; + } + + if (m_ShowType) + { + list.Add(typeInfo.GetSeedLabelPlural(hueInfo), $"{Amount}\t{title:#}\t{typeInfo.Name:#}"); + return; + } + + list.Add(hueInfo.IsBright() ? 1113491 : 1113490, $"{Amount}\t{title:#}"); } public override void OnSingleClick(Mobile from) diff --git a/Projects/UOContent/Engines/Quests/Collector/Items/PaintedImage.cs b/Projects/UOContent/Engines/Quests/Collector/Items/PaintedImage.cs index 659036097..e1180f01c 100644 --- a/Projects/UOContent/Engines/Quests/Collector/Items/PaintedImage.cs +++ b/Projects/UOContent/Engines/Quests/Collector/Items/PaintedImage.cs @@ -34,7 +34,7 @@ namespace Server.Engines.Quests.Collector public override void AddNameProperty(IPropertyList list) { var info = ImageTypeInfo.Get(m_Image); - list.Add(1060847, $"#1055126\t#{info.Name}"); // a painted image of: + list.Add(1060847, $"{1055126:#}\t{info.Name:#}"); // a painted image of: } public override void OnSingleClick(Mobile from) diff --git a/Projects/UOContent/Engines/Quests/Core/Items/HornOfRetreat.cs b/Projects/UOContent/Engines/Quests/Core/Items/HornOfRetreat.cs index a16779d0f..bb4249616 100644 --- a/Projects/UOContent/Engines/Quests/Core/Items/HornOfRetreat.cs +++ b/Projects/UOContent/Engines/Quests/Core/Items/HornOfRetreat.cs @@ -47,7 +47,7 @@ namespace Server.Engines.Quests { base.GetProperties(list); - list.Add(1060741, $"{m_Charges}"); // charges: ~1_val~ + list.Add(1060741, m_Charges); // charges: ~1_val~ } public override void OnDoubleClick(Mobile from) diff --git a/Projects/UOContent/Engines/Quests/Witch Apprentice/Objectives.cs b/Projects/UOContent/Engines/Quests/Witch Apprentice/Objectives.cs index 59858d6fe..1da04cee4 100644 --- a/Projects/UOContent/Engines/Quests/Witch Apprentice/Objectives.cs +++ b/Projects/UOContent/Engines/Quests/Witch Apprentice/Objectives.cs @@ -391,13 +391,10 @@ namespace Server.Engines.Quests.Hag if (creature.GetType() == type) { - System.From.SendLocalizedMessage( - 1055043, - $"#{info.Name}" - ); // You gather a ~1_INGREDIENT_NAME~ from the corpse. + // You gather a ~1_INGREDIENT_NAME~ from the corpse. + System.From.SendLocalizedMessage(1055043, $"#{info.Name}"); CurProgress++; - break; } } diff --git a/Projects/UOContent/Engines/Spawners/BaseSpawner.cs b/Projects/UOContent/Engines/Spawners/BaseSpawner.cs index dd1d7a71f..ff0616b8e 100644 --- a/Projects/UOContent/Engines/Spawners/BaseSpawner.cs +++ b/Projects/UOContent/Engines/Spawners/BaseSpawner.cs @@ -365,12 +365,12 @@ namespace Server.Engines.Spawners { list.Add(1060742); // active - list.Add(1060656, $"{m_Count}"); // amount to make: ~1_val~ - list.Add(1061169, $"{m_HomeRange}"); // range ~1_val~ - list.Add(1050039, $"walking range:\t{m_WalkingRange}"); // ~1_NUMBER~ ~2_ITEMNAME~ - list.Add(1053099, $"group:\t{m_Group}"); // ~1_oretype~: ~2_armortype~ - list.Add(1060847, $"team:\t{m_Team}"); // ~1_val~ ~2_val~ - list.Add(1063483, $"delay:\t{m_MinDelay} to {m_MaxDelay}"); // ~1_MATERIAL~: ~2_ITEMNAME~ + list.Add(1060656, m_Count); // amount to make: ~1_val~ + list.Add(1061169, m_HomeRange); // range ~1_val~ + list.Add(1050039, $"{"walking range:"}\t{m_WalkingRange}"); // ~1_NUMBER~ ~2_ITEMNAME~ + list.Add(1053099, $"{"group:"}\t{m_Group}"); // ~1_oretype~: ~2_armortype~ + list.Add(1060847, $"{"team:"}\t{m_Team}"); // ~1_val~ ~2_val~ + list.Add(1063483, $"{"delay:"}\t{m_MinDelay} to {m_MaxDelay}"); // ~1_MATERIAL~: ~2_ITEMNAME~ GetSpawnerProperties(list); diff --git a/Projects/UOContent/Engines/Spawners/RegionSpawner.cs b/Projects/UOContent/Engines/Spawners/RegionSpawner.cs index f12a332fe..d3446e22a 100644 --- a/Projects/UOContent/Engines/Spawners/RegionSpawner.cs +++ b/Projects/UOContent/Engines/Spawners/RegionSpawner.cs @@ -94,7 +94,7 @@ namespace Server.Engines.Spawners if (Running && m_SpawnRegion != null) { - list.Add(1076228, $"region:\t{m_SpawnRegion.Name}"); // ~1_DUMMY~ ~2_DUMMY~ + list.Add(1076228, $"{"region:"}\t{m_SpawnRegion.Name}"); // ~1_DUMMY~ ~2_DUMMY~ } } diff --git a/Projects/UOContent/Engines/Treasures of Tokuno/BasePigmentsOfTokuno.cs b/Projects/UOContent/Engines/Treasures of Tokuno/BasePigmentsOfTokuno.cs index 8fbd3a1d6..f9745cb4c 100644 --- a/Projects/UOContent/Engines/Treasures of Tokuno/BasePigmentsOfTokuno.cs +++ b/Projects/UOContent/Engines/Treasures of Tokuno/BasePigmentsOfTokuno.cs @@ -122,7 +122,7 @@ namespace Server.Items TextDefinition.AddTo(list, m_Label); } - list.Add(1060584, $"{m_UsesRemaining}"); // uses remaining: ~1_val~ + list.Add(1060584, m_UsesRemaining); // uses remaining: ~1_val~ } public override void OnDoubleClick(Mobile from) diff --git a/Projects/UOContent/Items/Aquarium/Aquarium.cs b/Projects/UOContent/Items/Aquarium/Aquarium.cs index 1671139bd..165811484 100644 --- a/Projects/UOContent/Items/Aquarium/Aquarium.cs +++ b/Projects/UOContent/Items/Aquarium/Aquarium.cs @@ -389,18 +389,18 @@ namespace Server.Items if (dead > 0) { - list.Add(1074248, $"{dead}"); // Dead Creatures: ~1_NUM~ + list.Add(1074248, dead); // Dead Creatures: ~1_NUM~ } var decorations = Items.Count - LiveCreatures - dead; if (decorations > 0) { - list.Add(1074249, $"{decorations}"); // Decorations: ~1_NUM~ + list.Add(1074249, decorations); // Decorations: ~1_NUM~ } - list.Add(1074250, $"#{FoodNumber()}"); // Food state: ~1_STATE~ - list.Add(1074251, $"#{WaterNumber()}"); // Water state: ~1_STATE~ + list.AddLocalized(1074250, FoodNumber()); // Food state: ~1_STATE~ + list.AddLocalized(1074251, WaterNumber()); // Water state: ~1_STATE~ if (_food.State == (int)FoodState.Dead) { @@ -912,12 +912,8 @@ namespace Server.Items AddItem(item); - from?.SendLocalizedMessage( - 1073635, - item.LabelNumber != 0 - ? $"#{item.LabelNumber}" - : item.Name - ); // You add the following decoration to your aquarium: ~1_NAME~ + // You add the following decoration to your aquarium: ~1_NAME~ + from?.SendLocalizedMessage(1073635, item.LabelNumber != 0 ? $"#{item.LabelNumber}" : item.Name); InvalidateProperties(); return true; diff --git a/Projects/UOContent/Items/Aquarium/FishBowl.cs b/Projects/UOContent/Items/Aquarium/FishBowl.cs index 810078b3a..52f73788f 100644 --- a/Projects/UOContent/Items/Aquarium/FishBowl.cs +++ b/Projects/UOContent/Items/Aquarium/FishBowl.cs @@ -88,7 +88,7 @@ namespace Server.Items if (fish != null) { - list.Add(1074494, $"#{fish.LabelNumber}"); // Contains: ~1_CREATURE~ + list.AddLocalized(1074494, fish.LabelNumber); // Contains: ~1_CREATURE~ } } } diff --git a/Projects/UOContent/Items/Aquarium/VacationWafer.cs b/Projects/UOContent/Items/Aquarium/VacationWafer.cs index b12494255..f7ba9b7f2 100644 --- a/Projects/UOContent/Items/Aquarium/VacationWafer.cs +++ b/Projects/UOContent/Items/Aquarium/VacationWafer.cs @@ -18,7 +18,7 @@ namespace Server.Items { base.AddNameProperties(list); - list.Add(1074432, $"{VacationDays}"); // Vacation days: ~1_DAYS~ + list.AddLocalized(1074432, VacationDays); // Vacation days: ~1_DAYS~ } } } diff --git a/Projects/UOContent/Items/Armor/BaseArmor.cs b/Projects/UOContent/Items/Armor/BaseArmor.cs index 026eb0dc2..029403c30 100644 --- a/Projects/UOContent/Items/Armor/BaseArmor.cs +++ b/Projects/UOContent/Items/Armor/BaseArmor.cs @@ -1251,14 +1251,27 @@ namespace Server.Items if (oreType != 0) { - list.Add( - _quality == ArmorQuality.Exceptional ? 1053100 : 1053099, - name != null ? $"#{oreType}\t{Name}" : $"#{oreType}\t#{LabelNumber}" - ); + var qualityNumber = _quality == ArmorQuality.Exceptional ? 1053100 : 1053099; + + if (name != null) + { + list.Add(qualityNumber, $"{oreType:#}\t{Name}"); + } + else + { + list.Add(qualityNumber, $"{oreType:#}\t{LabelNumber:#}"); + } } else if (_quality == ArmorQuality.Exceptional) { - list.Add(1050040, name ?? $"#{LabelNumber}"); // exceptional ~1_ITEMNAME~ + if (name != null) + { + list.Add(1050040, name); // exceptional ~1_ITEMNAME~ + } + else + { + list.AddLocalized(1050040, LabelNumber); // exceptional ~1_ITEMNAME~ + } } else if (name == null) { @@ -1312,72 +1325,72 @@ namespace Server.Items if ((prop = ArtifactRarity) > 0) { - list.Add(1061078, $"{prop}"); // artifact rarity ~1_val~ + list.Add(1061078, prop); // artifact rarity ~1_val~ } if ((prop = Attributes.WeaponDamage) != 0) { - list.Add(1060401, $"{prop}"); // damage increase ~1_val~% + list.Add(1060401, prop); // damage increase ~1_val~% } if ((prop = Attributes.DefendChance) != 0) { - list.Add(1060408, $"{prop}"); // defense chance increase ~1_val~% + list.Add(1060408, prop); // defense chance increase ~1_val~% } if ((prop = Attributes.BonusDex) != 0) { - list.Add(1060409, $"{prop}"); // dexterity bonus ~1_val~ + list.Add(1060409, prop); // dexterity bonus ~1_val~ } if ((prop = Attributes.EnhancePotions) != 0) { - list.Add(1060411, $"{prop}"); // enhance potions ~1_val~% + list.Add(1060411, prop); // enhance potions ~1_val~% } if ((prop = Attributes.CastRecovery) != 0) { - list.Add(1060412, $"{prop}"); // faster cast recovery ~1_val~ + list.Add(1060412, prop); // faster cast recovery ~1_val~ } if ((prop = Attributes.CastSpeed) != 0) { - list.Add(1060413, $"{prop}"); // faster casting ~1_val~ + list.Add(1060413, prop); // faster casting ~1_val~ } if ((prop = Attributes.AttackChance) != 0) { - list.Add(1060415, $"{prop}"); // hit chance increase ~1_val~% + list.Add(1060415, prop); // hit chance increase ~1_val~% } if ((prop = Attributes.BonusHits) != 0) { - list.Add(1060431, $"{prop}"); // hit point increase ~1_val~ + list.Add(1060431, prop); // hit point increase ~1_val~ } if ((prop = Attributes.BonusInt) != 0) { - list.Add(1060432, $"{prop}"); // intelligence bonus ~1_val~ + list.Add(1060432, prop); // intelligence bonus ~1_val~ } if ((prop = Attributes.LowerManaCost) != 0) { - list.Add(1060433, $"{prop}"); // lower mana cost ~1_val~% + list.Add(1060433, prop); // lower mana cost ~1_val~% } if ((prop = Attributes.LowerRegCost) != 0) { - list.Add(1060434, $"{prop}"); // lower reagent cost ~1_val~% + list.Add(1060434, prop); // lower reagent cost ~1_val~% } if ((prop = GetLowerStatReq()) != 0) { - list.Add(1060435, $"{prop}"); // lower requirements ~1_val~% + list.Add(1060435, prop); // lower requirements ~1_val~% } if ((prop = GetLuckBonus() + Attributes.Luck) != 0) { - list.Add(1060436, $"{prop}"); // luck ~1_val~ + list.Add(1060436, prop); // luck ~1_val~ } if (ArmorAttributes.MageArmor != 0) @@ -1387,12 +1400,12 @@ namespace Server.Items if ((prop = Attributes.BonusMana) != 0) { - list.Add(1060439, $"{prop}"); // mana increase ~1_val~ + list.Add(1060439, prop); // mana increase ~1_val~ } if ((prop = Attributes.RegenMana) != 0) { - list.Add(1060440, $"{prop}"); // mana regeneration ~1_val~ + list.Add(1060440, prop); // mana regeneration ~1_val~ } if (Attributes.NightSight != 0) @@ -1402,22 +1415,22 @@ namespace Server.Items if ((prop = Attributes.ReflectPhysical) != 0) { - list.Add(1060442, $"{prop}"); // reflect physical damage ~1_val~% + list.Add(1060442, prop); // reflect physical damage ~1_val~% } if ((prop = Attributes.RegenStam) != 0) { - list.Add(1060443, $"{prop}"); // stamina regeneration ~1_val~ + list.Add(1060443, prop); // stamina regeneration ~1_val~ } if ((prop = Attributes.RegenHits) != 0) { - list.Add(1060444, $"{prop}"); // hit point regeneration ~1_val~ + list.Add(1060444, prop); // hit point regeneration ~1_val~ } if ((prop = ArmorAttributes.SelfRepair) != 0) { - list.Add(1060450, $"{prop}"); // self repair ~1_val~ + list.Add(1060450, prop); // self repair ~1_val~ } if (Attributes.SpellChanneling != 0) @@ -1427,39 +1440,39 @@ namespace Server.Items if ((prop = Attributes.SpellDamage) != 0) { - list.Add(1060483, $"{prop}"); // spell damage increase ~1_val~% + list.Add(1060483, prop); // spell damage increase ~1_val~% } if ((prop = Attributes.BonusStam) != 0) { - list.Add(1060484, $"{prop}"); // stamina increase ~1_val~ + list.Add(1060484, prop); // stamina increase ~1_val~ } if ((prop = Attributes.BonusStr) != 0) { - list.Add(1060485, $"{prop}"); // strength bonus ~1_val~ + list.Add(1060485, prop); // strength bonus ~1_val~ } if ((prop = Attributes.WeaponSpeed) != 0) { - list.Add(1060486, $"{prop}"); // swing speed increase ~1_val~% + list.Add(1060486, prop); // swing speed increase ~1_val~% } if (Core.ML && (prop = Attributes.IncreasedKarmaLoss) != 0) { - list.Add(1075210, $"{prop}"); // Increased Karma Loss ~1val~% + list.Add(1075210, prop); // Increased Karma Loss ~1val~% } AddResistanceProperties(list); if ((prop = GetDurabilityBonus()) > 0) { - list.Add(1060410, $"{prop}"); // durability ~1_val~% + list.Add(1060410, prop); // durability ~1_val~% } if ((prop = ComputeStatReq(StatType.Str)) > 0) { - list.Add(1061170, $"{prop}"); // strength requirement ~1_val~ + list.Add(1061170, prop); // strength requirement ~1_val~ } if (_hitPoints >= 0 && _maxHitPoints > 0) diff --git a/Projects/UOContent/Items/Armor/Glasses/ElvenGlasses.cs b/Projects/UOContent/Items/Armor/Glasses/ElvenGlasses.cs index 3469820c0..05c81c3c7 100644 --- a/Projects/UOContent/Items/Armor/Glasses/ElvenGlasses.cs +++ b/Projects/UOContent/Items/Armor/Glasses/ElvenGlasses.cs @@ -50,77 +50,77 @@ namespace Server.Items if ((prop = _weaponAttributes.HitColdArea) != 0) { - list.Add(1060416, $"{prop}"); // hit cold area ~1_val~% + list.Add(1060416, prop); // hit cold area ~1_val~% } if ((prop = _weaponAttributes.HitDispel) != 0) { - list.Add(1060417, $"{prop}"); // hit dispel ~1_val~% + list.Add(1060417, prop); // hit dispel ~1_val~% } if ((prop = _weaponAttributes.HitEnergyArea) != 0) { - list.Add(1060418, $"{prop}"); // hit energy area ~1_val~% + list.Add(1060418, prop); // hit energy area ~1_val~% } if ((prop = _weaponAttributes.HitFireArea) != 0) { - list.Add(1060419, $"{prop}"); // hit fire area ~1_val~% + list.Add(1060419, prop); // hit fire area ~1_val~% } if ((prop = _weaponAttributes.HitFireball) != 0) { - list.Add(1060420, $"{prop}"); // hit fireball ~1_val~% + list.Add(1060420, prop); // hit fireball ~1_val~% } if ((prop = _weaponAttributes.HitHarm) != 0) { - list.Add(1060421, $"{prop}"); // hit harm ~1_val~% + list.Add(1060421, prop); // hit harm ~1_val~% } if ((prop = _weaponAttributes.HitLeechHits) != 0) { - list.Add(1060422, $"{prop}"); // hit life leech ~1_val~% + list.Add(1060422, prop); // hit life leech ~1_val~% } if ((prop = _weaponAttributes.HitLightning) != 0) { - list.Add(1060423, $"{prop}"); // hit lightning ~1_val~% + list.Add(1060423, prop); // hit lightning ~1_val~% } if ((prop = _weaponAttributes.HitLowerAttack) != 0) { - list.Add(1060424, $"{prop}"); // hit lower attack ~1_val~% + list.Add(1060424, prop); // hit lower attack ~1_val~% } if ((prop = _weaponAttributes.HitLowerDefend) != 0) { - list.Add(1060425, $"{prop}"); // hit lower defense ~1_val~% + list.Add(1060425, prop); // hit lower defense ~1_val~% } if ((prop = _weaponAttributes.HitMagicArrow) != 0) { - list.Add(1060426, $"{prop}"); // hit magic arrow ~1_val~% + list.Add(1060426, prop); // hit magic arrow ~1_val~% } if ((prop = _weaponAttributes.HitLeechMana) != 0) { - list.Add(1060427, $"{prop}"); // hit mana leech ~1_val~% + list.Add(1060427, prop); // hit mana leech ~1_val~% } if ((prop = _weaponAttributes.HitPhysicalArea) != 0) { - list.Add(1060428, $"{prop}"); // hit physical area ~1_val~% + list.Add(1060428, prop); // hit physical area ~1_val~% } if ((prop = _weaponAttributes.HitPoisonArea) != 0) { - list.Add(1060429, $"{prop}"); // hit poison area ~1_val~% + list.Add(1060429, prop); // hit poison area ~1_val~% } if ((prop = _weaponAttributes.HitLeechStam) != 0) { - list.Add(1060430, $"{prop}"); // hit stamina leech ~1_val~% + list.Add(1060430, prop); // hit stamina leech ~1_val~% } } } diff --git a/Projects/UOContent/Items/Clothing/BaseClothing.cs b/Projects/UOContent/Items/Clothing/BaseClothing.cs index 0de3beadc..bacf44e70 100644 --- a/Projects/UOContent/Items/Clothing/BaseClothing.cs +++ b/Projects/UOContent/Items/Clothing/BaseClothing.cs @@ -690,7 +690,14 @@ namespace Server.Items if (oreType != 0) { - list.Add(1053099, name != null ? $"#{oreType}\t{name}" : $"#{oreType}\t#{LabelNumber}"); // ~1_oretype~ ~2_armortype~ + if (name != null) + { + list.Add(1053099, $"{oreType:#}\t{name}"); // ~1_oretype~ ~2_armortype~ + } + else + { + list.Add(1053099, $"{oreType:#}\t{LabelNumber:#}"); // ~1_oretype~ ~2_armortype~ + } } else if (name == null) { @@ -737,72 +744,72 @@ namespace Server.Items if ((prop = ArtifactRarity) > 0) { - list.Add(1061078, $"{prop}"); // artifact rarity ~1_val~ + list.Add(1061078, prop); // artifact rarity ~1_val~ } if ((prop = Attributes.WeaponDamage) != 0) { - list.Add(1060401, $"{prop}"); // damage increase ~1_val~% + list.Add(1060401, prop); // damage increase ~1_val~% } if ((prop = Attributes.DefendChance) != 0) { - list.Add(1060408, $"{prop}"); // defense chance increase ~1_val~% + list.Add(1060408, prop); // defense chance increase ~1_val~% } if ((prop = Attributes.BonusDex) != 0) { - list.Add(1060409, $"{prop}"); // dexterity bonus ~1_val~ + list.Add(1060409, prop); // dexterity bonus ~1_val~ } if ((prop = Attributes.EnhancePotions) != 0) { - list.Add(1060411, $"{prop}"); // enhance potions ~1_val~% + list.Add(1060411, prop); // enhance potions ~1_val~% } if ((prop = Attributes.CastRecovery) != 0) { - list.Add(1060412, $"{prop}"); // faster cast recovery ~1_val~ + list.Add(1060412, prop); // faster cast recovery ~1_val~ } if ((prop = Attributes.CastSpeed) != 0) { - list.Add(1060413, $"{prop}"); // faster casting ~1_val~ + list.Add(1060413, prop); // faster casting ~1_val~ } if ((prop = Attributes.AttackChance) != 0) { - list.Add(1060415, $"{prop}"); // hit chance increase ~1_val~% + list.Add(1060415, prop); // hit chance increase ~1_val~% } if ((prop = Attributes.BonusHits) != 0) { - list.Add(1060431, $"{prop}"); // hit point increase ~1_val~ + list.Add(1060431, prop); // hit point increase ~1_val~ } if ((prop = Attributes.BonusInt) != 0) { - list.Add(1060432, $"{prop}"); // intelligence bonus ~1_val~ + list.Add(1060432, prop); // intelligence bonus ~1_val~ } if ((prop = Attributes.LowerManaCost) != 0) { - list.Add(1060433, $"{prop}"); // lower mana cost ~1_val~% + list.Add(1060433, prop); // lower mana cost ~1_val~% } if ((prop = Attributes.LowerRegCost) != 0) { - list.Add(1060434, $"{prop}"); // lower reagent cost ~1_val~% + list.Add(1060434, prop); // lower reagent cost ~1_val~% } if ((prop = ClothingAttributes.LowerStatReq) != 0) { - list.Add(1060435, $"{prop}"); // lower requirements ~1_val~% + list.Add(1060435, prop); // lower requirements ~1_val~% } if ((prop = Attributes.Luck) != 0) { - list.Add(1060436, $"{prop}"); // luck ~1_val~ + list.Add(1060436, prop); // luck ~1_val~ } if (ClothingAttributes.MageArmor != 0) @@ -812,12 +819,12 @@ namespace Server.Items if ((prop = Attributes.BonusMana) != 0) { - list.Add(1060439, $"{prop}"); // mana increase ~1_val~ + list.Add(1060439, prop); // mana increase ~1_val~ } if ((prop = Attributes.RegenMana) != 0) { - list.Add(1060440, $"{prop}"); // mana regeneration ~1_val~ + list.Add(1060440, prop); // mana regeneration ~1_val~ } if (Attributes.NightSight != 0) @@ -827,22 +834,22 @@ namespace Server.Items if ((prop = Attributes.ReflectPhysical) != 0) { - list.Add(1060442, $"{prop}"); // reflect physical damage ~1_val~% + list.Add(1060442, prop); // reflect physical damage ~1_val~% } if ((prop = Attributes.RegenStam) != 0) { - list.Add(1060443, $"{prop}"); // stamina regeneration ~1_val~ + list.Add(1060443, prop); // stamina regeneration ~1_val~ } if ((prop = Attributes.RegenHits) != 0) { - list.Add(1060444, $"{prop}"); // hit point regeneration ~1_val~ + list.Add(1060444, prop); // hit point regeneration ~1_val~ } if ((prop = ClothingAttributes.SelfRepair) != 0) { - list.Add(1060450, $"{prop}"); // self repair ~1_val~ + list.Add(1060450, prop); // self repair ~1_val~ } if (Attributes.SpellChanneling != 0) @@ -852,39 +859,39 @@ namespace Server.Items if ((prop = Attributes.SpellDamage) != 0) { - list.Add(1060483, $"{prop}"); // spell damage increase ~1_val~% + list.Add(1060483, prop); // spell damage increase ~1_val~% } if ((prop = Attributes.BonusStam) != 0) { - list.Add(1060484, $"{prop}"); // stamina increase ~1_val~ + list.Add(1060484, prop); // stamina increase ~1_val~ } if ((prop = Attributes.BonusStr) != 0) { - list.Add(1060485, $"{prop}"); // strength bonus ~1_val~ + list.Add(1060485, prop); // strength bonus ~1_val~ } if ((prop = Attributes.WeaponSpeed) != 0) { - list.Add(1060486, $"{prop}"); // swing speed increase ~1_val~% + list.Add(1060486, prop); // swing speed increase ~1_val~% } if (Core.ML && (prop = Attributes.IncreasedKarmaLoss) != 0) { - list.Add(1075210, $"{prop}"); // Increased Karma Loss ~1val~% + list.Add(1075210, prop); // Increased Karma Loss ~1val~% } AddResistanceProperties(list); if ((prop = ClothingAttributes.DurabilityBonus) > 0) { - list.Add(1060410, $"{prop}"); // durability ~1_val~% + list.Add(1060410, prop); // durability ~1_val~% } if ((prop = ComputeStatReq(StatType.Str)) > 0) { - list.Add(1061170, $"{prop}"); // strength requirement ~1_val~ + list.Add(1061170, prop); // strength requirement ~1_val~ } if (_hitPoints >= 0 && _maxHitPoints > 0) diff --git a/Projects/UOContent/Items/Decoration Artifacts/BaseDecorationArtifact.cs b/Projects/UOContent/Items/Decoration Artifacts/BaseDecorationArtifact.cs index 69719ab90..366a256e7 100644 --- a/Projects/UOContent/Items/Decoration Artifacts/BaseDecorationArtifact.cs +++ b/Projects/UOContent/Items/Decoration Artifacts/BaseDecorationArtifact.cs @@ -15,7 +15,7 @@ public abstract partial class BaseDecorationArtifact : Item { base.GetProperties(list); - list.Add(1061078, $"{ArtifactRarity}"); // artifact rarity ~1_val~ + list.Add(1061078, ArtifactRarity); // artifact rarity ~1_val~ } } @@ -32,6 +32,6 @@ public abstract partial class BaseDecorationContainerArtifact : BaseContainer { base.AddNameProperties(list); - list.Add(1061078, $"{ArtifactRarity}"); // artifact rarity ~1_val~ + list.Add(1061078, ArtifactRarity); // artifact rarity ~1_val~ } } diff --git a/Projects/UOContent/Items/Deeds/CommodityDeed.cs b/Projects/UOContent/Items/Deeds/CommodityDeed.cs index 87772006a..f72b771f1 100644 --- a/Projects/UOContent/Items/Deeds/CommodityDeed.cs +++ b/Projects/UOContent/Items/Deeds/CommodityDeed.cs @@ -1,5 +1,6 @@ using ModernUO.Serialization; using Server.Targeting; +using Server.Text; namespace Server.Items; @@ -66,13 +67,20 @@ public partial class CommodityDeed : Item { base.GetProperties(list); - if (Commodity != null) + if (Commodity is ICommodity ic) { - var args = Commodity.Name == null - ? $"#{(Commodity as ICommodity)?.DescriptionNumber ?? Commodity.LabelNumber}\t{Commodity.Amount}" - : $"{Commodity.Name}\t{Commodity.Amount}"; - - list.Add(1060658, args); // ~1_val~: ~2_val~ + list.Add(1060658, $"{ic.DescriptionNumber:#}\t{Commodity.Amount}"); // ~1_val~: ~2_val~ + } + else if (Commodity != null) + { + if (Commodity.Name == null) + { + list.Add(1060658, $"{Commodity.LabelNumber:#}\t{Commodity.Amount}"); // ~1_val~: ~2_val~ + } + else + { + list.Add(1060658, $"{Commodity.Name}\t{Commodity.Amount}"); // ~1_val~: ~2_val~ + } } else { @@ -86,11 +94,13 @@ public partial class CommodityDeed : Item if (Commodity != null) { - var args = Commodity.Name == null - ? $"#{(Commodity as ICommodity)?.DescriptionNumber ?? Commodity.LabelNumber}\t{Commodity.Amount}" - : $"{Commodity.Name}\t{Commodity.Amount}"; - - LabelTo(from, 1060658, args); // ~1_val~: ~2_val~ + LabelTo( + from, + 1060658, // ~1_val~: ~2_val~ + Commodity.Name == null + ? $"#{(Commodity as ICommodity)?.DescriptionNumber ?? Commodity.LabelNumber}\t{Commodity.Amount}" + : $"{Commodity.Name}\t{Commodity.Amount}" + ); } } diff --git a/Projects/UOContent/Items/Jewels/BaseJewel.cs b/Projects/UOContent/Items/Jewels/BaseJewel.cs index cbce3546d..29e823124 100644 --- a/Projects/UOContent/Items/Jewels/BaseJewel.cs +++ b/Projects/UOContent/Items/Jewels/BaseJewel.cs @@ -265,77 +265,77 @@ namespace Server.Items if ((prop = ArtifactRarity) > 0) { - list.Add(1061078, $"{prop}"); // artifact rarity ~1_val~ + list.Add(1061078, prop); // artifact rarity ~1_val~ } if ((prop = Attributes.WeaponDamage) != 0) { - list.Add(1060401, $"{prop}"); // damage increase ~1_val~% + list.Add(1060401, prop); // damage increase ~1_val~% } if ((prop = Attributes.DefendChance) != 0) { - list.Add(1060408, $"{prop}"); // defense chance increase ~1_val~% + list.Add(1060408, prop); // defense chance increase ~1_val~% } if ((prop = Attributes.BonusDex) != 0) { - list.Add(1060409, $"{prop}"); // dexterity bonus ~1_val~ + list.Add(1060409, prop); // dexterity bonus ~1_val~ } if ((prop = Attributes.EnhancePotions) != 0) { - list.Add(1060411, $"{prop}"); // enhance potions ~1_val~% + list.Add(1060411, prop); // enhance potions ~1_val~% } if ((prop = Attributes.CastRecovery) != 0) { - list.Add(1060412, $"{prop}"); // faster cast recovery ~1_val~ + list.Add(1060412, prop); // faster cast recovery ~1_val~ } if ((prop = Attributes.CastSpeed) != 0) { - list.Add(1060413, $"{prop}"); // faster casting ~1_val~ + list.Add(1060413, prop); // faster casting ~1_val~ } if ((prop = Attributes.AttackChance) != 0) { - list.Add(1060415, $"{prop}"); // hit chance increase ~1_val~% + list.Add(1060415, prop); // hit chance increase ~1_val~% } if ((prop = Attributes.BonusHits) != 0) { - list.Add(1060431, $"{prop}"); // hit point increase ~1_val~ + list.Add(1060431, prop); // hit point increase ~1_val~ } if ((prop = Attributes.BonusInt) != 0) { - list.Add(1060432, $"{prop}"); // intelligence bonus ~1_val~ + list.Add(1060432, prop); // intelligence bonus ~1_val~ } if ((prop = Attributes.LowerManaCost) != 0) { - list.Add(1060433, $"{prop}"); // lower mana cost ~1_val~% + list.Add(1060433, prop); // lower mana cost ~1_val~% } if ((prop = Attributes.LowerRegCost) != 0) { - list.Add(1060434, $"{prop}"); // lower reagent cost ~1_val~% + list.Add(1060434, prop); // lower reagent cost ~1_val~% } if ((prop = Attributes.Luck) != 0) { - list.Add(1060436, $"{prop}"); // luck ~1_val~ + list.Add(1060436, prop); // luck ~1_val~ } if ((prop = Attributes.BonusMana) != 0) { - list.Add(1060439, $"{prop}"); // mana increase ~1_val~ + list.Add(1060439, prop); // mana increase ~1_val~ } if ((prop = Attributes.RegenMana) != 0) { - list.Add(1060440, $"{prop}"); // mana regeneration ~1_val~ + list.Add(1060440, prop); // mana regeneration ~1_val~ } if (Attributes.NightSight != 0) @@ -345,17 +345,17 @@ namespace Server.Items if ((prop = Attributes.ReflectPhysical) != 0) { - list.Add(1060442, $"{prop}"); // reflect physical damage ~1_val~% + list.Add(1060442, prop); // reflect physical damage ~1_val~% } if ((prop = Attributes.RegenStam) != 0) { - list.Add(1060443, $"{prop}"); // stamina regeneration ~1_val~ + list.Add(1060443, prop); // stamina regeneration ~1_val~ } if ((prop = Attributes.RegenHits) != 0) { - list.Add(1060444, $"{prop}"); // hit point regeneration ~1_val~ + list.Add(1060444, prop); // hit point regeneration ~1_val~ } if (Attributes.SpellChanneling != 0) @@ -365,27 +365,27 @@ namespace Server.Items if ((prop = Attributes.SpellDamage) != 0) { - list.Add(1060483, $"{prop}"); // spell damage increase ~1_val~% + list.Add(1060483, prop); // spell damage increase ~1_val~% } if ((prop = Attributes.BonusStam) != 0) { - list.Add(1060484, $"{prop}"); // stamina increase ~1_val~ + list.Add(1060484, prop); // stamina increase ~1_val~ } if ((prop = Attributes.BonusStr) != 0) { - list.Add(1060485, $"{prop}"); // strength bonus ~1_val~ + list.Add(1060485, prop); // strength bonus ~1_val~ } if ((prop = Attributes.WeaponSpeed) != 0) { - list.Add(1060486, $"{prop}"); // swing speed increase ~1_val~% + list.Add(1060486, prop); // swing speed increase ~1_val~% } if (Core.ML && (prop = Attributes.IncreasedKarmaLoss) != 0) { - list.Add(1075210, $"{prop}"); // Increased Karma Loss ~1val~% + list.Add(1075210, prop); // Increased Karma Loss ~1val~% } AddResistanceProperties(list); diff --git a/Projects/UOContent/Items/Misc/BankCheck.cs b/Projects/UOContent/Items/Misc/BankCheck.cs index db1517471..d7396374f 100644 --- a/Projects/UOContent/Items/Misc/BankCheck.cs +++ b/Projects/UOContent/Items/Misc/BankCheck.cs @@ -71,7 +71,14 @@ namespace Server.Items public override void GetProperties(IPropertyList list) { base.GetProperties(list); - list.Add(1060738, Core.ML ? $"{m_Worth:N0}" : m_Worth.ToString()); // value: ~1_val~) + if (Core.ML) + { + list.Add(1060738, $"{m_Worth:N0}"); // value: ~1_val~ + } + else + { + list.Add(1060738, m_Worth); // value: ~1_val~ + } } public override void OnAdded(IEntity parent) diff --git a/Projects/UOContent/Items/Misc/CommunicationCrystals.cs b/Projects/UOContent/Items/Misc/CommunicationCrystals.cs index 02997aa56..35955907d 100644 --- a/Projects/UOContent/Items/Misc/CommunicationCrystals.cs +++ b/Projects/UOContent/Items/Misc/CommunicationCrystals.cs @@ -97,11 +97,11 @@ namespace Server.Items list.Add(Active ? 1060742 : 1060743); // active / inactive list.Add(1060745); // broadcast - list.Add(1060741, $"{Charges}"); // charges: ~1_val~ + list.Add(1060741, Charges); // charges: ~1_val~ if (Receivers.Count > 0) { - list.Add(1060746, $"{Receivers.Count}"); // links: ~1_val~ + list.Add(1060746, Receivers.Count); // links: ~1_val~ } } diff --git a/Projects/UOContent/Items/Misc/PromotionalToken.cs b/Projects/UOContent/Items/Misc/PromotionalToken.cs index 857e7548b..d38bff9c9 100644 --- a/Projects/UOContent/Items/Misc/PromotionalToken.cs +++ b/Projects/UOContent/Items/Misc/PromotionalToken.cs @@ -27,7 +27,17 @@ namespace Server.Items { base.GetProperties(list); - list.Add(1070998, $"{ItemName}"); // Use this to redeem
your ~1_PROMO~ + if (ItemName != null) + { + if (ItemName.Number > 0) + { + list.Add(1070998, ItemName.Number); // Use this to redeem
your ~1_PROMO~ + } + else + { + list.Add(1070998, ItemName.String); // Use this to redeem
your ~1_PROMO~ + } + } } public override void OnDoubleClick(Mobile from) diff --git a/Projects/UOContent/Items/Misc/Teleporter.cs b/Projects/UOContent/Items/Misc/Teleporter.cs index ec505662d..07dcb6af0 100644 --- a/Projects/UOContent/Items/Misc/Teleporter.cs +++ b/Projects/UOContent/Items/Misc/Teleporter.cs @@ -168,15 +168,15 @@ namespace Server.Items if (m_MapDest != null) { - list.Add(1060658, $"Map\t{m_MapDest}"); + list.Add(1060658, $"{"Map"}\t{m_MapDest}"); } if (m_PointDest != Point3D.Zero) { - list.Add(1060659, $"Coords\t{m_PointDest}"); + list.Add(1060659, $"{"Coords"}\t{m_PointDest}"); } - list.Add(1060660, $"Creatures\t{(m_Creatures ? "Yes" : "No")}"); + list.Add(1060660, $"{"Creatures"}\t{(m_Creatures ? "Yes" : "No")}"); } public override void OnSingleClick(Mobile from) @@ -483,11 +483,11 @@ namespace Server.Items if (m_MessageString != null) { - list.Add(1060662, $"Message\t{m_MessageString}"); + list.Add(1060662, $"{"Message"}\t{m_MessageString}"); } else if (m_MessageNumber != 0) { - list.Add(1060662, $"Message\t#{m_MessageNumber}"); + list.Add(1060662, $"{"Message"}\t{m_MessageNumber:#}"); } } @@ -625,16 +625,16 @@ namespace Server.Items { base.GetProperties(list); - list.Add(1060661, $"Range\t{m_Range}"); + list.Add(1060661, $"{"Range"}\t{m_Range}"); if (m_Keyword >= 0) { - list.Add(1060662, $"Keyword\t{m_Keyword}"); + list.Add(1060662, $"{"Keyword"}\t{m_Keyword}"); } if (m_Substring != null) { - list.Add(1060663, $"Substring\t{m_Substring}"); + list.Add(1060663, $"{"Substring"}\t{m_Substring}"); } } diff --git a/Projects/UOContent/Items/Quivers/BaseQuiver.cs b/Projects/UOContent/Items/Quivers/BaseQuiver.cs index ca0c191b9..7acc0b426 100644 --- a/Projects/UOContent/Items/Quivers/BaseQuiver.cs +++ b/Projects/UOContent/Items/Quivers/BaseQuiver.cs @@ -272,7 +272,7 @@ namespace Server.Items if ((prop = m_DamageIncrease) != 0) { - list.Add(1074762, $"{prop}"); // Damage modifier: ~1_PERCENT~% + list.Add(1074762, prop); // Damage modifier: ~1_PERCENT~% } int phys = 0, fire = 0, cold = 0, pois = 0, nrgy = 0, chaos = 0, direct = 0; @@ -281,104 +281,104 @@ namespace Server.Items if (phys != 0) { - list.Add(1060403, $"{phys}"); // physical damage ~1_val~% + list.Add(1060403, phys); // physical damage ~1_val~% } if (fire != 0) { - list.Add(1060405, $"{fire}"); // fire damage ~1_val~% + list.Add(1060405, fire); // fire damage ~1_val~% } if (cold != 0) { - list.Add(1060404, $"{cold}"); // cold damage ~1_val~% + list.Add(1060404, cold); // cold damage ~1_val~% } if (pois != 0) { - list.Add(1060406, $"{pois}"); // poison damage ~1_val~% + list.Add(1060406, pois); // poison damage ~1_val~% } if (nrgy != 0) { - list.Add(1060407, $"{nrgy}"); // energy damage ~1_val + list.Add(1060407, nrgy); // energy damage ~1_val } if (chaos != 0) { - list.Add(1072846, $"{chaos}"); // chaos damage ~1_val~% + list.Add(1072846, chaos); // chaos damage ~1_val~% } if (direct != 0) { - list.Add(1079978, $"{direct}"); // Direct Damage: ~1_PERCENT~% + list.Add(1079978, direct); // Direct Damage: ~1_PERCENT~% } list.Add(1075085); // Requirement: Mondain's Legacy if ((prop = Attributes.DefendChance) != 0) { - list.Add(1060408, $"{prop}"); // defense chance increase ~1_val~% + list.Add(1060408, prop); // defense chance increase ~1_val~% } if ((prop = Attributes.BonusDex) != 0) { - list.Add(1060409, $"{prop}"); // dexterity bonus ~1_val~ + list.Add(1060409, prop); // dexterity bonus ~1_val~ } if ((prop = Attributes.EnhancePotions) != 0) { - list.Add(1060411, $"{prop}"); // enhance potions ~1_val~% + list.Add(1060411, prop); // enhance potions ~1_val~% } if ((prop = Attributes.CastRecovery) != 0) { - list.Add(1060412, $"{prop}"); // faster cast recovery ~1_val~ + list.Add(1060412, prop); // faster cast recovery ~1_val~ } if ((prop = Attributes.CastSpeed) != 0) { - list.Add(1060413, $"{prop}"); // faster casting ~1_val~ + list.Add(1060413, prop); // faster casting ~1_val~ } if ((prop = Attributes.AttackChance) != 0) { - list.Add(1060415, $"{prop}"); // hit chance increase ~1_val~% + list.Add(1060415, prop); // hit chance increase ~1_val~% } if ((prop = Attributes.BonusHits) != 0) { - list.Add(1060431, $"{prop}"); // hit point increase ~1_val~ + list.Add(1060431, prop); // hit point increase ~1_val~ } if ((prop = Attributes.BonusInt) != 0) { - list.Add(1060432, $"{prop}"); // intelligence bonus ~1_val~ + list.Add(1060432, prop); // intelligence bonus ~1_val~ } if ((prop = Attributes.LowerManaCost) != 0) { - list.Add(1060433, $"{prop}"); // lower mana cost ~1_val~% + list.Add(1060433, prop); // lower mana cost ~1_val~% } if ((prop = Attributes.LowerRegCost) != 0) { - list.Add(1060434, $"{prop}"); // lower reagent cost ~1_val~% + list.Add(1060434, prop); // lower reagent cost ~1_val~% } if ((prop = Attributes.Luck) != 0) { - list.Add(1060436, $"{prop}"); // luck ~1_val~ + list.Add(1060436, prop); // luck ~1_val~ } if ((prop = Attributes.BonusMana) != 0) { - list.Add(1060439, $"{prop}"); // mana increase ~1_val~ + list.Add(1060439, prop); // mana increase ~1_val~ } if ((prop = Attributes.RegenMana) != 0) { - list.Add(1060440, $"{prop}"); // mana regeneration ~1_val~ + list.Add(1060440, prop); // mana regeneration ~1_val~ } if (Attributes.NightSight != 0) @@ -388,42 +388,42 @@ namespace Server.Items if ((prop = Attributes.ReflectPhysical) != 0) { - list.Add(1060442, $"{prop}"); // reflect physical damage ~1_val~% + list.Add(1060442, prop); // reflect physical damage ~1_val~% } if ((prop = Attributes.RegenStam) != 0) { - list.Add(1060443, $"{prop}"); // stamina regeneration ~1_val~ + list.Add(1060443, prop); // stamina regeneration ~1_val~ } if ((prop = Attributes.RegenHits) != 0) { - list.Add(1060444, $"{prop}"); // hit point regeneration ~1_val~ + list.Add(1060444, prop); // hit point regeneration ~1_val~ } if ((prop = Attributes.SpellDamage) != 0) { - list.Add(1060483, $"{prop}"); // spell damage increase ~1_val~% + list.Add(1060483, prop); // spell damage increase ~1_val~% } if ((prop = Attributes.BonusStam) != 0) { - list.Add(1060484, $"{prop}"); // stamina increase ~1_val~ + list.Add(1060484, prop); // stamina increase ~1_val~ } if ((prop = Attributes.BonusStr) != 0) { - list.Add(1060485, $"{prop}"); // strength bonus ~1_val~ + list.Add(1060485, prop); // strength bonus ~1_val~ } if ((prop = Attributes.WeaponSpeed) != 0) { - list.Add(1060486, $"{prop}"); // swing speed increase ~1_val~% + list.Add(1060486, prop); // swing speed increase ~1_val~% } if ((prop = m_LowerAmmoCost) > 0) { - list.Add(1075208, $"{prop}"); // Lower Ammo Cost ~1_Percentage~% + list.Add(1075208, prop); // Lower Ammo Cost ~1_Percentage~% } var weight = ammo != null ? ammo.Weight + ammo.Amount : 0; @@ -435,7 +435,7 @@ namespace Server.Items if ((prop = m_WeightReduction) != 0) { - list.Add(1072210, $"{prop}"); // Weight reduction: ~1_PERCENTAGE~% + list.Add(1072210, prop); // Weight reduction: ~1_PERCENTAGE~% } } diff --git a/Projects/UOContent/Items/Resources/Blacksmithing/Ingots.cs b/Projects/UOContent/Items/Resources/Blacksmithing/Ingots.cs index bcf624f90..acffef1db 100644 --- a/Projects/UOContent/Items/Resources/Blacksmithing/Ingots.cs +++ b/Projects/UOContent/Items/Resources/Blacksmithing/Ingots.cs @@ -72,7 +72,7 @@ namespace Server.Items { if (Amount > 1) { - list.Add(1050039, $"{Amount}\t#{1027154}"); // ~1_NUMBER~ ~2_ITEMNAME~ + list.Add(1050039, $"{Amount}\t{1027154:#}"); // ~1_NUMBER~ ~2_ITEMNAME~ } else { diff --git a/Projects/UOContent/Items/Resources/Blacksmithing/Ore.cs b/Projects/UOContent/Items/Resources/Blacksmithing/Ore.cs index 093d30d25..b1c0b9ce7 100644 --- a/Projects/UOContent/Items/Resources/Blacksmithing/Ore.cs +++ b/Projects/UOContent/Items/Resources/Blacksmithing/Ore.cs @@ -87,7 +87,7 @@ namespace Server.Items { if (Amount > 1) { - list.Add(1050039, $"{Amount}\t#{1026583}"); // ~1_NUMBER~ ~2_ITEMNAME~ + list.Add(1050039, $"{Amount}\t{1026583:#}"); // ~1_NUMBER~ ~2_ITEMNAME~ } else { diff --git a/Projects/UOContent/Items/Resources/Tailor/Hides.cs b/Projects/UOContent/Items/Resources/Tailor/Hides.cs index 6c28ac235..e9dbc9cda 100644 --- a/Projects/UOContent/Items/Resources/Tailor/Hides.cs +++ b/Projects/UOContent/Items/Resources/Tailor/Hides.cs @@ -59,7 +59,7 @@ namespace Server.Items { if (Amount > 1) { - list.Add(1050039, $"{Amount}\t#1024216"); // ~1_NUMBER~ ~2_ITEMNAME~ + list.Add(1050039, $"{Amount}\t{1024216:#}"); // ~1_NUMBER~ ~2_ITEMNAME~ } else { diff --git a/Projects/UOContent/Items/Resources/Tailor/Leathers.cs b/Projects/UOContent/Items/Resources/Tailor/Leathers.cs index 1d44a86ea..2431b26a7 100644 --- a/Projects/UOContent/Items/Resources/Tailor/Leathers.cs +++ b/Projects/UOContent/Items/Resources/Tailor/Leathers.cs @@ -59,7 +59,7 @@ namespace Server.Items { if (Amount > 1) { - list.Add(1050039, $"{Amount}\t#1024199"); // ~1_NUMBER~ ~2_ITEMNAME~ + list.Add(1050039, $"{Amount}\t{1024199:#}"); // ~1_NUMBER~ ~2_ITEMNAME~ } else { diff --git a/Projects/UOContent/Items/Skill Items/Carpenter Items/TaxidermyKit.cs b/Projects/UOContent/Items/Skill Items/Carpenter Items/TaxidermyKit.cs index 82c2a2aca..80b7713e4 100644 --- a/Projects/UOContent/Items/Skill Items/Carpenter Items/TaxidermyKit.cs +++ b/Projects/UOContent/Items/Skill Items/Carpenter Items/TaxidermyKit.cs @@ -264,7 +264,7 @@ namespace Server.Items list.Add(1070857, m_Hunter.Name); // Caught by ~1_fisherman~ } - list.Add(1070858, $"{m_AnimalWeight}"); // ~1_weight~ stones + list.Add(1070858, m_AnimalWeight); // ~1_weight~ stones } } @@ -439,7 +439,7 @@ namespace Server.Items list.Add(1070857, m_Hunter.Name); // Caught by ~1_fisherman~ } - list.Add(1070858, $"{m_AnimalWeight}"); // ~1_weight~ stones + list.Add(1070858, m_AnimalWeight); // ~1_weight~ stones } } diff --git a/Projects/UOContent/Items/Skill Items/Fishing/Misc/ShipwreckedItem.cs b/Projects/UOContent/Items/Skill Items/Fishing/Misc/ShipwreckedItem.cs index 6643e1507..641b457c5 100644 --- a/Projects/UOContent/Items/Skill Items/Fishing/Misc/ShipwreckedItem.cs +++ b/Projects/UOContent/Items/Skill Items/Fishing/Misc/ShipwreckedItem.cs @@ -48,7 +48,7 @@ namespace Server.Items public override void OnSingleClick(Mobile from) { - LabelTo(from, 1050039, $"#{LabelNumber}\t#1041645"); + LabelTo(from, 1050039, $"{LabelNumber:#}\t{1041645:#}"); } public override void AddNameProperties(IPropertyList list) diff --git a/Projects/UOContent/Items/Skill Items/Harvest Tools/BaseHarvestTool.cs b/Projects/UOContent/Items/Skill Items/Harvest Tools/BaseHarvestTool.cs index cb79d1891..2a948b96d 100644 --- a/Projects/UOContent/Items/Skill Items/Harvest Tools/BaseHarvestTool.cs +++ b/Projects/UOContent/Items/Skill Items/Harvest Tools/BaseHarvestTool.cs @@ -122,7 +122,7 @@ namespace Server.Items list.Add(1060636); // exceptional } - list.Add(1060584, $"{m_UsesRemaining}"); // uses remaining: ~1_val~ + list.Add(1060584, m_UsesRemaining); // uses remaining: ~1_val~ } public virtual void DisplayDurabilityTo(Mobile m) diff --git a/Projects/UOContent/Items/Skill Items/Magical/Misc/RecallRune.cs b/Projects/UOContent/Items/Skill Items/Magical/Misc/RecallRune.cs index e04e97d16..033f6ca8b 100644 --- a/Projects/UOContent/Items/Skill Items/Magical/Misc/RecallRune.cs +++ b/Projects/UOContent/Items/Skill Items/Magical/Misc/RecallRune.cs @@ -246,9 +246,13 @@ namespace Server.Items { list.Add(House != null ? 1062453 : 1060806, $"a recall rune for {desc}"); // ~1_val~ (Trammel)[(House)] } + else if (House != null) + { + list.Add($"a recall rune for {desc} ({m_TargetMap})(House)"); + } else { - list.Add(House != null ? $"a recall rune for {desc} ({m_TargetMap})(House)" : $"a recall rune for {desc} ({m_TargetMap})"); + list.Add($"a recall rune for {desc} ({m_TargetMap})"); } } } diff --git a/Projects/UOContent/Items/Skill Items/Magical/Spellbook.cs b/Projects/UOContent/Items/Skill Items/Magical/Spellbook.cs index b8b6ef6be..c15bd699d 100644 --- a/Projects/UOContent/Items/Skill Items/Magical/Spellbook.cs +++ b/Projects/UOContent/Items/Skill Items/Magical/Spellbook.cs @@ -738,72 +738,72 @@ namespace Server.Items if ((prop = Attributes.WeaponDamage) != 0) { - list.Add(1060401, $"{prop}"); // damage increase ~1_val~% + list.Add(1060401, prop); // damage increase ~1_val~% } if ((prop = Attributes.DefendChance) != 0) { - list.Add(1060408, $"{prop}"); // defense chance increase ~1_val~% + list.Add(1060408, prop); // defense chance increase ~1_val~% } if ((prop = Attributes.BonusDex) != 0) { - list.Add(1060409, $"{prop}"); // dexterity bonus ~1_val~ + list.Add(1060409, prop); // dexterity bonus ~1_val~ } if ((prop = Attributes.EnhancePotions) != 0) { - list.Add(1060411, $"{prop}"); // enhance potions ~1_val~% + list.Add(1060411, prop); // enhance potions ~1_val~% } if ((prop = Attributes.CastRecovery) != 0) { - list.Add(1060412, $"{prop}"); // faster cast recovery ~1_val~ + list.Add(1060412, prop); // faster cast recovery ~1_val~ } if ((prop = Attributes.CastSpeed) != 0) { - list.Add(1060413, $"{prop}"); // faster casting ~1_val~ + list.Add(1060413, prop); // faster casting ~1_val~ } if ((prop = Attributes.AttackChance) != 0) { - list.Add(1060415, $"{prop}"); // hit chance increase ~1_val~% + list.Add(1060415, prop); // hit chance increase ~1_val~% } if ((prop = Attributes.BonusHits) != 0) { - list.Add(1060431, $"{prop}"); // hit point increase ~1_val~ + list.Add(1060431, prop); // hit point increase ~1_val~ } if ((prop = Attributes.BonusInt) != 0) { - list.Add(1060432, $"{prop}"); // intelligence bonus ~1_val~ + list.Add(1060432, prop); // intelligence bonus ~1_val~ } if ((prop = Attributes.LowerManaCost) != 0) { - list.Add(1060433, $"{prop}"); // lower mana cost ~1_val~% + list.Add(1060433, prop); // lower mana cost ~1_val~% } if ((prop = Attributes.LowerRegCost) != 0) { - list.Add(1060434, $"{prop}"); // lower reagent cost ~1_val~% + list.Add(1060434, prop); // lower reagent cost ~1_val~% } if ((prop = Attributes.Luck) != 0) { - list.Add(1060436, $"{prop}"); // luck ~1_val~ + list.Add(1060436, prop); // luck ~1_val~ } if ((prop = Attributes.BonusMana) != 0) { - list.Add(1060439, $"{prop}"); // mana increase ~1_val~ + list.Add(1060439, prop); // mana increase ~1_val~ } if ((prop = Attributes.RegenMana) != 0) { - list.Add(1060440, $"{prop}"); // mana regeneration ~1_val~ + list.Add(1060440, prop); // mana regeneration ~1_val~ } if (Attributes.NightSight != 0) @@ -813,17 +813,17 @@ namespace Server.Items if ((prop = Attributes.ReflectPhysical) != 0) { - list.Add(1060442, $"{prop}"); // reflect physical damage ~1_val~% + list.Add(1060442, prop); // reflect physical damage ~1_val~% } if ((prop = Attributes.RegenStam) != 0) { - list.Add(1060443, $"{prop}"); // stamina regeneration ~1_val~ + list.Add(1060443, prop); // stamina regeneration ~1_val~ } if ((prop = Attributes.RegenHits) != 0) { - list.Add(1060444, $"{prop}"); // hit point regeneration ~1_val~ + list.Add(1060444, prop); // hit point regeneration ~1_val~ } if (Attributes.SpellChanneling != 0) @@ -833,30 +833,30 @@ namespace Server.Items if ((prop = Attributes.SpellDamage) != 0) { - list.Add(1060483, $"{prop}"); // spell damage increase ~1_val~% + list.Add(1060483, prop); // spell damage increase ~1_val~% } if ((prop = Attributes.BonusStam) != 0) { - list.Add(1060484, $"{prop}"); // stamina increase ~1_val~ + list.Add(1060484, prop); // stamina increase ~1_val~ } if ((prop = Attributes.BonusStr) != 0) { - list.Add(1060485, $"{prop}"); // strength bonus ~1_val~ + list.Add(1060485, prop); // strength bonus ~1_val~ } if ((prop = Attributes.WeaponSpeed) != 0) { - list.Add(1060486, $"{prop}"); // swing speed increase ~1_val~% + list.Add(1060486, prop); // swing speed increase ~1_val~% } if (Core.ML && (prop = Attributes.IncreasedKarmaLoss) != 0) { - list.Add(1075210, $"{prop}"); // Increased Karma Loss ~1val~% + list.Add(1075210, prop); // Increased Karma Loss ~1val~% } - list.Add(1042886, $"{SpellCount}"); // ~1_NUMBERS_OF_SPELLS~ Spells + list.Add(1042886, SpellCount); // ~1_NUMBERS_OF_SPELLS~ Spells } public override void OnSingleClick(Mobile from) diff --git a/Projects/UOContent/Items/Skill Items/Misc/RecipeScroll.cs b/Projects/UOContent/Items/Skill Items/Misc/RecipeScroll.cs index 13673cedc..e9a5125e3 100644 --- a/Projects/UOContent/Items/Skill Items/Misc/RecipeScroll.cs +++ b/Projects/UOContent/Items/Skill Items/Misc/RecipeScroll.cs @@ -50,7 +50,14 @@ namespace Server.Items if (r != null) { - list.Add(1049644, $"{r.TextDefinition}"); // [~1_stuff~] + if (r.TextDefinition.Number > 0) + { + list.Add(1049644, r.TextDefinition.Number); // [~1_stuff~] + } + else + { + list.Add(1049644, r.TextDefinition.String); // [~1_stuff~] + } } } diff --git a/Projects/UOContent/Items/Skill Items/Musical Instruments/BaseInstrument.cs b/Projects/UOContent/Items/Skill Items/Musical Instruments/BaseInstrument.cs index ce7a15a73..86e97b7f0 100644 --- a/Projects/UOContent/Items/Skill Items/Musical Instruments/BaseInstrument.cs +++ b/Projects/UOContent/Items/Skill Items/Musical Instruments/BaseInstrument.cs @@ -376,7 +376,7 @@ namespace Server.Items list.Add(1060636); // exceptional } - list.Add(1060584, $"{m_UsesRemaining}"); // uses remaining: ~1_val~ + list.Add(1060584, m_UsesRemaining); // uses remaining: ~1_val~ if (m_ReplenishesCharges) { diff --git a/Projects/UOContent/Items/Skill Items/Ninjitsu/Fukiya.cs b/Projects/UOContent/Items/Skill Items/Ninjitsu/Fukiya.cs index 9411c8efe..a565fce0b 100644 --- a/Projects/UOContent/Items/Skill Items/Ninjitsu/Fukiya.cs +++ b/Projects/UOContent/Items/Skill Items/Ninjitsu/Fukiya.cs @@ -91,7 +91,7 @@ namespace Server.Items { base.GetProperties(list); - list.Add(1060584, $"{m_UsesRemaining}"); // uses remaining: ~1_val~ + list.Add(1060584, m_UsesRemaining); // uses remaining: ~1_val~ if (m_Poison != null && m_PoisonCharges > 0) { diff --git a/Projects/UOContent/Items/Skill Items/Ninjitsu/FukiyaDarts.cs b/Projects/UOContent/Items/Skill Items/Ninjitsu/FukiyaDarts.cs index 3bdd5ca95..429b1b5bc 100644 --- a/Projects/UOContent/Items/Skill Items/Ninjitsu/FukiyaDarts.cs +++ b/Projects/UOContent/Items/Skill Items/Ninjitsu/FukiyaDarts.cs @@ -77,7 +77,7 @@ namespace Server.Items { base.GetProperties(list); - list.Add(1060584, $"{m_UsesRemaining}"); // uses remaining: ~1_val~ + list.Add(1060584, m_UsesRemaining); // uses remaining: ~1_val~ if (m_Poison != null && m_PoisonCharges > 0) { diff --git a/Projects/UOContent/Items/Skill Items/Ninjitsu/LeatherNinjaBelt.cs b/Projects/UOContent/Items/Skill Items/Ninjitsu/LeatherNinjaBelt.cs index 2f26f70bf..61a2b45cb 100644 --- a/Projects/UOContent/Items/Skill Items/Ninjitsu/LeatherNinjaBelt.cs +++ b/Projects/UOContent/Items/Skill Items/Ninjitsu/LeatherNinjaBelt.cs @@ -93,7 +93,7 @@ namespace Server.Items { base.GetProperties(list); - list.Add(1060584, $"{m_UsesRemaining}"); // uses remaining: ~1_val~ + list.Add(1060584, m_UsesRemaining); // uses remaining: ~1_val~ if (m_Poison != null && m_PoisonCharges > 0) { diff --git a/Projects/UOContent/Items/Skill Items/Ninjitsu/Shuriken.cs b/Projects/UOContent/Items/Skill Items/Ninjitsu/Shuriken.cs index 8e800e9cd..9a033b1db 100644 --- a/Projects/UOContent/Items/Skill Items/Ninjitsu/Shuriken.cs +++ b/Projects/UOContent/Items/Skill Items/Ninjitsu/Shuriken.cs @@ -78,7 +78,7 @@ namespace Server.Items { base.GetProperties(list); - list.Add(1060584, $"{m_UsesRemaining}"); // uses remaining: ~1_val~ + list.Add(1060584, m_UsesRemaining); // uses remaining: ~1_val~ if (m_Poison != null && m_PoisonCharges > 0) { diff --git a/Projects/UOContent/Items/Skill Items/Tools/BaseTool.cs b/Projects/UOContent/Items/Skill Items/Tools/BaseTool.cs index 5565c1cf7..5ef23c441 100644 --- a/Projects/UOContent/Items/Skill Items/Tools/BaseTool.cs +++ b/Projects/UOContent/Items/Skill Items/Tools/BaseTool.cs @@ -127,7 +127,7 @@ namespace Server.Items list.Add(1060636); // exceptional } - list.Add(1060584, $"{m_UsesRemaining}"); // uses remaining: ~1_val~ + list.Add(1060584, m_UsesRemaining); // uses remaining: ~1_val~ } public virtual void DisplayDurabilityTo(Mobile m) diff --git a/Projects/UOContent/Items/Skill Items/Tools/RunicSewingKit.cs b/Projects/UOContent/Items/Skill Items/Tools/RunicSewingKit.cs index 16a2d49b2..edf868a4d 100644 --- a/Projects/UOContent/Items/Skill Items/Tools/RunicSewingKit.cs +++ b/Projects/UOContent/Items/Skill Items/Tools/RunicSewingKit.cs @@ -26,23 +26,24 @@ namespace Server.Items public override void AddNameProperty(IPropertyList list) { - var v = " "; - - if (!CraftResources.IsStandard(Resource)) + if (CraftResources.IsStandard(Resource)) { - var num = CraftResources.GetLocalizationNumber(Resource); - - if (num > 0) - { - v = $"#{num}"; - } - else - { - v = CraftResources.GetName(Resource); - } + list.Add(1061119, " "); // ~1_LEATHER_TYPE~ runic sewing kit + return; } - list.Add(1061119, v); // ~1_LEATHER_TYPE~ runic sewing kit + var num = CraftResources.GetLocalizationNumber(Resource); + + if (num > 0) + { + // ~1_LEATHER_TYPE~ runic sewing kit + list.Add(1061119, $"#{num}"); + } + else + { + // ~1_LEATHER_TYPE~ runic sewing kit + list.Add(1061119, CraftResources.GetName(Resource)); + } } public override void OnSingleClick(Mobile from) diff --git a/Projects/UOContent/Items/Special/8th Anniversary Items/Dawn's Music Box/DawnsMusicBox.cs b/Projects/UOContent/Items/Special/8th Anniversary Items/Dawn's Music Box/DawnsMusicBox.cs index 206712650..8f85838fc 100644 --- a/Projects/UOContent/Items/Special/8th Anniversary Items/Dawn's Music Box/DawnsMusicBox.cs +++ b/Projects/UOContent/Items/Special/8th Anniversary Items/Dawn's Music Box/DawnsMusicBox.cs @@ -169,17 +169,17 @@ namespace Server.Items if (commonSongs > 0) { - list.Add(1075234, $"{commonSongs}"); // ~1_NUMBER~ Common Tracks + list.Add(1075234, commonSongs); // ~1_NUMBER~ Common Tracks } if (uncommonSongs > 0) { - list.Add(1075235, $"{uncommonSongs}"); // ~1_NUMBER~ Uncommon Tracks + list.Add(1075235, uncommonSongs); // ~1_NUMBER~ Uncommon Tracks } if (rareSongs > 0) { - list.Add(1075236, $"{rareSongs}"); // ~1_NUMBER~ Rare Tracks + list.Add(1075236, rareSongs); // ~1_NUMBER~ Rare Tracks } } diff --git a/Projects/UOContent/Items/Special/8th Anniversary Items/FountainOfLife.cs b/Projects/UOContent/Items/Special/8th Anniversary Items/FountainOfLife.cs index 8ffa9aaf1..887503411 100644 --- a/Projects/UOContent/Items/Special/8th Anniversary Items/FountainOfLife.cs +++ b/Projects/UOContent/Items/Special/8th Anniversary Items/FountainOfLife.cs @@ -125,7 +125,7 @@ namespace Server.Items { base.AddNameProperties(list); - list.Add(1075217, $"{m_Charges}"); // ~1_val~ charges remaining + list.Add(1075217, m_Charges); // ~1_val~ charges remaining } public override void OnDelete() diff --git a/Projects/UOContent/Items/Special/8th Anniversary Items/Talismans.cs b/Projects/UOContent/Items/Special/8th Anniversary Items/Talismans.cs index 7c8e49129..bb203b645 100644 --- a/Projects/UOContent/Items/Special/8th Anniversary Items/Talismans.cs +++ b/Projects/UOContent/Items/Special/8th Anniversary Items/Talismans.cs @@ -29,7 +29,7 @@ namespace Server.Items public override void AddNameProperty(IPropertyList list) { - list.Add(1075200, $"#{(int)Form}"); + list.Add(1075200, $"{(int)Form:#}"); } public override void Serialize(IGenericWriter writer) diff --git a/Projects/UOContent/Items/Special/Bulk Order Rewards/Blacksmithy/AncientSmithyHammer.cs b/Projects/UOContent/Items/Special/Bulk Order Rewards/Blacksmithy/AncientSmithyHammer.cs index b30e7b83d..fb5795e02 100644 --- a/Projects/UOContent/Items/Special/Bulk Order Rewards/Blacksmithy/AncientSmithyHammer.cs +++ b/Projects/UOContent/Items/Special/Bulk Order Rewards/Blacksmithy/AncientSmithyHammer.cs @@ -79,7 +79,7 @@ namespace Server.Items if (m_Bonus != 0) { - list.Add(1060451, $"#1042354\t{m_Bonus}"); // ~1_skillname~ +~2_val~ + list.Add(1060451, $"{1042354:#}\t{m_Bonus}"); // ~1_skillname~ +~2_val~ } } diff --git a/Projects/UOContent/Items/Special/Bulk Order Rewards/Blacksmithy/GlovesOfMining.cs b/Projects/UOContent/Items/Special/Bulk Order Rewards/Blacksmithy/GlovesOfMining.cs index 959aeca8c..8fe83deaa 100644 --- a/Projects/UOContent/Items/Special/Bulk Order Rewards/Blacksmithy/GlovesOfMining.cs +++ b/Projects/UOContent/Items/Special/Bulk Order Rewards/Blacksmithy/GlovesOfMining.cs @@ -202,7 +202,7 @@ namespace Server.Items if (m_Bonus != 0) { - list.Add(1062005, $"{m_Bonus}"); // mining bonus +~1_val~ + list.Add(1062005, m_Bonus); // mining bonus +~1_val~ } } diff --git a/Projects/UOContent/Items/Special/Bulk Order Rewards/Blacksmithy/PowderOfTemperament.cs b/Projects/UOContent/Items/Special/Bulk Order Rewards/Blacksmithy/PowderOfTemperament.cs index c08ed66ae..209da9950 100644 --- a/Projects/UOContent/Items/Special/Bulk Order Rewards/Blacksmithy/PowderOfTemperament.cs +++ b/Projects/UOContent/Items/Special/Bulk Order Rewards/Blacksmithy/PowderOfTemperament.cs @@ -66,7 +66,7 @@ namespace Server.Items { base.GetProperties(list); - list.Add(1060584, $"{m_UsesRemaining}"); // uses remaining: ~1_val~ + list.Add(1060584, m_UsesRemaining); // uses remaining: ~1_val~ } public virtual void DisplayDurabilityTo(Mobile m) diff --git a/Projects/UOContent/Items/Special/Gifts/RoseOfTrinsic.cs b/Projects/UOContent/Items/Special/Gifts/RoseOfTrinsic.cs index 1fe6f266d..4d73c97a9 100644 --- a/Projects/UOContent/Items/Special/Gifts/RoseOfTrinsic.cs +++ b/Projects/UOContent/Items/Special/Gifts/RoseOfTrinsic.cs @@ -69,7 +69,7 @@ namespace Server.Items { base.GetProperties(list); - list.Add(1062925, $"{Petals}"); // Petals: ~1_COUNT~ + list.Add(1062925, Petals); // Petals: ~1_COUNT~ } public override void GetContextMenuEntries(Mobile from, List list) diff --git a/Projects/UOContent/Items/Special/HeritageToken.cs b/Projects/UOContent/Items/Special/HeritageToken.cs index bf3273dc2..b08a07409 100644 --- a/Projects/UOContent/Items/Special/HeritageToken.cs +++ b/Projects/UOContent/Items/Special/HeritageToken.cs @@ -34,7 +34,7 @@ namespace Server.Items { base.GetProperties(list); - list.Add(1070998, $"#{1076595}"); // Use this to redeem
Your Heritage Items + list.AddLocalized(1070998, 1076595); // Use this to redeem
Your Heritage Items } public override void Serialize(IGenericWriter writer) diff --git a/Projects/UOContent/Items/Special/House Raffle/HouseRaffleDeed.cs b/Projects/UOContent/Items/Special/House Raffle/HouseRaffleDeed.cs index 5d9ccd8dd..29054bfcc 100644 --- a/Projects/UOContent/Items/Special/House Raffle/HouseRaffleDeed.cs +++ b/Projects/UOContent/Items/Special/House Raffle/HouseRaffleDeed.cs @@ -93,9 +93,9 @@ namespace Server.Items { list.Add( 1060658, // ~1_val~: ~2_val~ - $"location\t{HouseRaffleStone.FormatLocation(m_PlotLocation, m_Facet, false)}" + $"{"location"}\t{HouseRaffleStone.FormatLocation(m_PlotLocation, m_Facet, false)}" ); - list.Add(1060659, $"facet\t{m_Facet}"); // ~1_val~: ~2_val~ + list.Add(1060659, $"{"facet"}\t{m_Facet}"); // ~1_val~: ~2_val~ list.Add(1150486); // [Marked Item] } diff --git a/Projects/UOContent/Items/Special/House Raffle/HouseRaffleStone.cs b/Projects/UOContent/Items/Special/House Raffle/HouseRaffleStone.cs index 57f76efa7..6ce07cbeb 100644 --- a/Projects/UOContent/Items/Special/House Raffle/HouseRaffleStone.cs +++ b/Projects/UOContent/Items/Special/House Raffle/HouseRaffleStone.cs @@ -411,8 +411,8 @@ namespace Server.Items { case HouseRaffleState.Active: { - list.Add(1060658, $"ticket price\t{FormatPrice()}"); // ~1_val~: ~2_val~ - list.Add(1060659, $"ends\t{m_Started + m_Duration}"); // ~1_val~: ~2_val~ + list.Add(1060658, $"{"ticket price"}\t{FormatPrice()}"); // ~1_val~: ~2_val~ + list.Add(1060659, $"{"ends"}\t{m_Started + m_Duration}"); // ~1_val~: ~2_val~ break; } case HouseRaffleState.Completed: diff --git a/Projects/UOContent/Items/Special/Solen Items/BagOfSending.cs b/Projects/UOContent/Items/Special/Solen Items/BagOfSending.cs index 710c31b94..faf151f2d 100644 --- a/Projects/UOContent/Items/Special/Solen Items/BagOfSending.cs +++ b/Projects/UOContent/Items/Special/Solen Items/BagOfSending.cs @@ -106,7 +106,7 @@ namespace Server.Items { base.GetProperties(list); - list.Add(1060741, $"{m_Charges}"); // charges: ~1_val~ + list.Add(1060741, m_Charges); // charges: ~1_val~ } public override void OnSingleClick(Mobile from) diff --git a/Projects/UOContent/Items/Special/Solen Items/BraceletOfBinding.cs b/Projects/UOContent/Items/Special/Solen Items/BraceletOfBinding.cs index 8bec81198..b116ca657 100644 --- a/Projects/UOContent/Items/Special/Solen Items/BraceletOfBinding.cs +++ b/Projects/UOContent/Items/Special/Solen Items/BraceletOfBinding.cs @@ -91,19 +91,17 @@ namespace Server.Items public override void AddNameProperty(IPropertyList list) { - list.Add( - 1054000, - $"{m_Charges}\t{m_Inscription.DefaultIfNullOrEmpty(" ")}" - ); // a bracelet of binding : ~1_val~ ~2_val~ + // a bracelet of binding : ~1_val~ ~2_val~ + list.Add(1054000, $"{m_Charges}\t{m_Inscription.DefaultIfNullOrEmpty(" ")}"); } public override void OnSingleClick(Mobile from) { LabelTo( from, - 1054000, + 1054000, // a bracelet of binding : ~1_val~ ~2_val~ $"{m_Charges}\t{m_Inscription.DefaultIfNullOrEmpty(" ")}" - ); // a bracelet of binding : ~1_val~ ~2_val~ + ); } public override void GetContextMenuEntries(Mobile from, List list) diff --git a/Projects/UOContent/Items/Special/SoulStone.cs b/Projects/UOContent/Items/Special/SoulStone.cs index 08c1dabb3..f924e21b2 100644 --- a/Projects/UOContent/Items/Special/SoulStone.cs +++ b/Projects/UOContent/Items/Special/SoulStone.cs @@ -129,11 +129,18 @@ namespace Server.Items { list.Add( 1070721, // Skill stored: ~1_skillname~ ~2_skillamount~ - $"#{AosSkillBonuses.GetLabel(Skill)}\t{SkillValue:F1}" + $"{AosSkillBonuses.GetLabel(Skill):#}\t{SkillValue:F1}" ); } - list.Add(1041602, LastUserName ?? $"#{1074235}"); // Owner: ~1_val~ + if (LastUserName != null) + { + list.Add(1041602, LastUserName); // Owner: ~1_val~ + } + else + { + list.AddLocalized(1041602, 1074235); // Owner: ~1_val~ + } } private static bool CheckCombat(Mobile m, TimeSpan time) @@ -968,7 +975,7 @@ namespace Server.Items { base.GetProperties(list); - list.Add(1060584, $"{m_UsesRemaining}"); // uses remaining: ~1_val~ + list.Add(1060584, m_UsesRemaining); // uses remaining: ~1_val~ } public override void Serialize(IGenericWriter writer) diff --git a/Projects/UOContent/Items/Special/Veteran Rewards/Cannon.cs b/Projects/UOContent/Items/Special/Veteran Rewards/Cannon.cs index 50034e814..3fb9a131e 100644 --- a/Projects/UOContent/Items/Special/Veteran Rewards/Cannon.cs +++ b/Projects/UOContent/Items/Special/Veteran Rewards/Cannon.cs @@ -27,7 +27,7 @@ namespace Server.Items list.Add(1076223); // 7th Year Veteran Reward } - list.Add(1076207, $"{addon.Charges}"); // Remaining Charges: ~1_val~ + list.Add(1076207, addon.Charges); // Remaining Charges: ~1_val~ } } @@ -471,7 +471,7 @@ namespace Server.Items list.Add(1076223); // 7th Year Veteran Reward } - list.Add(1076207, $"{m_Charges}"); // Remaining Charges: ~1_val~ + list.Add(1076207, m_Charges); // Remaining Charges: ~1_val~ } public override void OnDoubleClick(Mobile from) diff --git a/Projects/UOContent/Items/Special/Veteran Rewards/WeaponEngravingTool.cs b/Projects/UOContent/Items/Special/Veteran Rewards/WeaponEngravingTool.cs index 14dacdb02..ffd7b759a 100644 --- a/Projects/UOContent/Items/Special/Veteran Rewards/WeaponEngravingTool.cs +++ b/Projects/UOContent/Items/Special/Veteran Rewards/WeaponEngravingTool.cs @@ -110,7 +110,7 @@ namespace Server.Items if (ShowUsesRemaining) { - list.Add(1060584, $"{m_UsesRemaining}"); // uses remaining: ~1_val~ + list.Add(1060584, m_UsesRemaining); // uses remaining: ~1_val~ } } diff --git a/Projects/UOContent/Items/Talismans/BaseTalisman.cs b/Projects/UOContent/Items/Talismans/BaseTalisman.cs index 5b0ffe5b0..42a8efcb9 100644 --- a/Projects/UOContent/Items/Talismans/BaseTalisman.cs +++ b/Projects/UOContent/Items/Talismans/BaseTalisman.cs @@ -557,14 +557,19 @@ namespace Server.Items } else if (m_Summoner?.IsEmpty == false) { - list.Add( - 1072400, - m_Summoner?.Name ?? "Unknown" - ); // Talisman of ~1_name~ Summoning + var name = m_Summoner?.Name; + if (name?.Number > 0) + { + list.Add(1072400, name.Number); // Talisman of ~1_name~ Summoning + } + else + { + list.Add(1072400, name?.String ?? "Unknown"); // Talisman of ~1_name~ Summoning + } } else if (m_Removal != TalismanRemoval.None) { - list.Add(1072389, $"#{1072000 + (int)m_Removal}"); // Talisman of ~1_name~ + list.AddLocalized(1072389, 1072000 + (int)m_Removal); // Talisman of ~1_name~ } else { @@ -595,7 +600,7 @@ namespace Server.Items { if (m_ChargeTime > 0) { - list.Add(1074884, $"{m_ChargeTime}"); // Charge time left: ~1_val~ + list.Add(1074884, m_ChargeTime); // Charge time left: ~1_val~ } else { @@ -625,7 +630,7 @@ namespace Server.Items { list.Add( 1072395, // ~1_NAME~ Exceptional Bonus: ~2_val~% - $"#{AosSkillBonuses.GetLabel(m_Skill)}\t{m_ExceptionalBonus}" + $"{AosSkillBonuses.GetLabel(m_Skill):#}\t{m_ExceptionalBonus}" ); } @@ -633,7 +638,7 @@ namespace Server.Items { list.Add( 1072394, // ~1_NAME~ Bonus: ~2_val~% - $"#{AosSkillBonuses.GetLabel(m_Skill)}\t{m_SuccessBonus}" + $"{AosSkillBonuses.GetLabel(m_Skill):#}\t{m_SuccessBonus}" ); } @@ -643,72 +648,72 @@ namespace Server.Items if ((prop = Attributes.WeaponDamage) != 0) { - list.Add(1060401, $"{prop}"); // damage increase ~1_val~% + list.Add(1060401, prop); // damage increase ~1_val~% } if ((prop = Attributes.DefendChance) != 0) { - list.Add(1060408, $"{prop}"); // defense chance increase ~1_val~% + list.Add(1060408, prop); // defense chance increase ~1_val~% } if ((prop = Attributes.BonusDex) != 0) { - list.Add(1060409, $"{prop}"); // dexterity bonus ~1_val~ + list.Add(1060409, prop); // dexterity bonus ~1_val~ } if ((prop = Attributes.EnhancePotions) != 0) { - list.Add(1060411, $"{prop}"); // enhance potions ~1_val~% + list.Add(1060411, prop); // enhance potions ~1_val~% } if ((prop = Attributes.CastRecovery) != 0) { - list.Add(1060412, $"{prop}"); // faster cast recovery ~1_val~ + list.Add(1060412, prop); // faster cast recovery ~1_val~ } if ((prop = Attributes.CastSpeed) != 0) { - list.Add(1060413, $"{prop}"); // faster casting ~1_val~ + list.Add(1060413, prop); // faster casting ~1_val~ } if ((prop = Attributes.AttackChance) != 0) { - list.Add(1060415, $"{prop}"); // hit chance increase ~1_val~% + list.Add(1060415, prop); // hit chance increase ~1_val~% } if ((prop = Attributes.BonusHits) != 0) { - list.Add(1060431, $"{prop}"); // hit point increase ~1_val~ + list.Add(1060431, prop); // hit point increase ~1_val~ } if ((prop = Attributes.BonusInt) != 0) { - list.Add(1060432, $"{prop}"); // intelligence bonus ~1_val~ + list.Add(1060432, prop); // intelligence bonus ~1_val~ } if ((prop = Attributes.LowerManaCost) != 0) { - list.Add(1060433, $"{prop}"); // lower mana cost ~1_val~% + list.Add(1060433, prop); // lower mana cost ~1_val~% } if ((prop = Attributes.LowerRegCost) != 0) { - list.Add(1060434, $"{prop}"); // lower reagent cost ~1_val~% + list.Add(1060434, prop); // lower reagent cost ~1_val~% } if ((prop = Attributes.Luck) != 0) { - list.Add(1060436, $"{prop}"); // luck ~1_val~ + list.Add(1060436, prop); // luck ~1_val~ } if ((prop = Attributes.BonusMana) != 0) { - list.Add(1060439, $"{prop}"); // mana increase ~1_val~ + list.Add(1060439, prop); // mana increase ~1_val~ } if ((prop = Attributes.RegenMana) != 0) { - list.Add(1060440, $"{prop}"); // mana regeneration ~1_val~ + list.Add(1060440, prop); // mana regeneration ~1_val~ } if (Attributes.NightSight != 0) @@ -718,17 +723,17 @@ namespace Server.Items if ((prop = Attributes.ReflectPhysical) != 0) { - list.Add(1060442, $"{prop}"); // reflect physical damage ~1_val~% + list.Add(1060442, prop); // reflect physical damage ~1_val~% } if ((prop = Attributes.RegenStam) != 0) { - list.Add(1060443, $"{prop}"); // stamina regeneration ~1_val~ + list.Add(1060443, prop); // stamina regeneration ~1_val~ } if ((prop = Attributes.RegenHits) != 0) { - list.Add(1060444, $"{prop}"); // hit point regeneration ~1_val~ + list.Add(1060444, prop); // hit point regeneration ~1_val~ } if (Attributes.SpellChanneling != 0) @@ -738,32 +743,32 @@ namespace Server.Items if ((prop = Attributes.SpellDamage) != 0) { - list.Add(1060483, $"{prop}"); // spell damage increase ~1_val~% + list.Add(1060483, prop); // spell damage increase ~1_val~% } if ((prop = Attributes.BonusStam) != 0) { - list.Add(1060484, $"{prop}"); // stamina increase ~1_val~ + list.Add(1060484, prop); // stamina increase ~1_val~ } if ((prop = Attributes.BonusStr) != 0) { - list.Add(1060485, $"{prop}"); // strength bonus ~1_val~ + list.Add(1060485, prop); // strength bonus ~1_val~ } if ((prop = Attributes.WeaponSpeed) != 0) { - list.Add(1060486, $"{prop}"); // swing speed increase ~1_val~% + list.Add(1060486, prop); // swing speed increase ~1_val~% } if (Core.ML && (prop = Attributes.IncreasedKarmaLoss) != 0) { - list.Add(1075210, $"{prop}"); // Increased Karma Loss ~1val~% + list.Add(1075210, prop); // Increased Karma Loss ~1val~% } if (m_MaxCharges > 0) { - list.Add(1060741, $"{m_Charges}"); // charges: ~1_val~ + list.Add(1060741, m_Charges); // charges: ~1_val~ } if (m_Slayer != TalismanSlayerName.None) diff --git a/Projects/UOContent/Items/Weapons/BaseWeapon.cs b/Projects/UOContent/Items/Weapons/BaseWeapon.cs index a89e8e7c0..9e560bcf2 100644 --- a/Projects/UOContent/Items/Weapons/BaseWeapon.cs +++ b/Projects/UOContent/Items/Weapons/BaseWeapon.cs @@ -2778,7 +2778,14 @@ namespace Server.Items if (oreType != 0) { - list.Add(1053099, name != null ? $"#{oreType}\t{name}" : $"#{oreType}\t#{LabelNumber}"); // ~1_oretype~ ~2_armortype~ + if (name != null) + { + list.Add(1053099, $"{oreType:#}\t{name}"); // ~1_oretype~ ~2_armortype~ + } + else + { + list.Add(1053099, $"{oreType:#}\t{LabelNumber:#}"); // ~1_oretype~ ~2_armortype~ + } } else if (name == null) { @@ -2848,12 +2855,12 @@ namespace Server.Items if (ArtifactRarity > 0) { - list.Add(1061078, $"{ArtifactRarity}"); // artifact rarity ~1_val~ + list.Add(1061078, ArtifactRarity); // artifact rarity ~1_val~ } if (this is IUsesRemaining usesRemaining && usesRemaining.ShowUsesRemaining) { - list.Add(1060584, $"{usesRemaining.UsesRemaining}"); // uses remaining: ~1_val~ + list.Add(1060584, usesRemaining.UsesRemaining); // uses remaining: ~1_val~ } if (m_Poison != null && m_PoisonCharges > 0) @@ -2897,107 +2904,107 @@ namespace Server.Items if ((prop = GetDamageBonus() + Attributes.WeaponDamage) != 0) { - list.Add(1060401, $"{prop}"); // damage increase ~1_val~% + list.Add(1060401, prop); // damage increase ~1_val~% } if ((prop = Attributes.DefendChance) != 0) { - list.Add(1060408, $"{prop}"); // defense chance increase ~1_val~% + list.Add(1060408, prop); // defense chance increase ~1_val~% } if ((prop = Attributes.EnhancePotions) != 0) { - list.Add(1060411, $"{prop}"); // enhance potions ~1_val~% + list.Add(1060411, prop); // enhance potions ~1_val~% } if ((prop = Attributes.CastRecovery) != 0) { - list.Add(1060412, $"{prop}"); // faster cast recovery ~1_val~ + list.Add(1060412, prop); // faster cast recovery ~1_val~ } if ((prop = Attributes.CastSpeed) != 0) { - list.Add(1060413, $"{prop}"); // faster casting ~1_val~ + list.Add(1060413, prop); // faster casting ~1_val~ } if ((prop = GetHitChanceBonus() + Attributes.AttackChance) != 0) { - list.Add(1060415, $"{prop}"); // hit chance increase ~1_val~% + list.Add(1060415, prop); // hit chance increase ~1_val~% } if ((prop = WeaponAttributes.HitColdArea) != 0) { - list.Add(1060416, $"{prop}"); // hit cold area ~1_val~% + list.Add(1060416, prop); // hit cold area ~1_val~% } if ((prop = WeaponAttributes.HitDispel) != 0) { - list.Add(1060417, $"{prop}"); // hit dispel ~1_val~% + list.Add(1060417, prop); // hit dispel ~1_val~% } if ((prop = WeaponAttributes.HitEnergyArea) != 0) { - list.Add(1060418, $"{prop}"); // hit energy area ~1_val~% + list.Add(1060418, prop); // hit energy area ~1_val~% } if ((prop = WeaponAttributes.HitFireArea) != 0) { - list.Add(1060419, $"{prop}"); // hit fire area ~1_val~% + list.Add(1060419, prop); // hit fire area ~1_val~% } if ((prop = WeaponAttributes.HitFireball) != 0) { - list.Add(1060420, $"{prop}"); // hit fireball ~1_val~% + list.Add(1060420, prop); // hit fireball ~1_val~% } if ((prop = WeaponAttributes.HitHarm) != 0) { - list.Add(1060421, $"{prop}"); // hit harm ~1_val~% + list.Add(1060421, prop); // hit harm ~1_val~% } if ((prop = WeaponAttributes.HitLeechHits) != 0) { - list.Add(1060422, $"{prop}"); // hit life leech ~1_val~% + list.Add(1060422, prop); // hit life leech ~1_val~% } if ((prop = WeaponAttributes.HitLightning) != 0) { - list.Add(1060423, $"{prop}"); // hit lightning ~1_val~% + list.Add(1060423, prop); // hit lightning ~1_val~% } if ((prop = WeaponAttributes.HitLowerAttack) != 0) { - list.Add(1060424, $"{prop}"); // hit lower attack ~1_val~% + list.Add(1060424, prop); // hit lower attack ~1_val~% } if ((prop = WeaponAttributes.HitLowerDefend) != 0) { - list.Add(1060425, $"{prop}"); // hit lower defense ~1_val~% + list.Add(1060425, prop); // hit lower defense ~1_val~% } if ((prop = WeaponAttributes.HitMagicArrow) != 0) { - list.Add(1060426, $"{prop}"); // hit magic arrow ~1_val~% + list.Add(1060426, prop); // hit magic arrow ~1_val~% } if ((prop = WeaponAttributes.HitLeechMana) != 0) { - list.Add(1060427, $"{prop}"); // hit mana leech ~1_val~% + list.Add(1060427, prop); // hit mana leech ~1_val~% } if ((prop = WeaponAttributes.HitPhysicalArea) != 0) { - list.Add(1060428, $"{prop}"); // hit physical area ~1_val~% + list.Add(1060428, prop); // hit physical area ~1_val~% } if ((prop = WeaponAttributes.HitPoisonArea) != 0) { - list.Add(1060429, $"{prop}"); // hit poison area ~1_val~% + list.Add(1060429, prop); // hit poison area ~1_val~% } if ((prop = WeaponAttributes.HitLeechStam) != 0) { - list.Add(1060430, $"{prop}"); // hit stamina leech ~1_val~% + list.Add(1060430, prop); // hit stamina leech ~1_val~% } if (ImmolatingWeaponSpell.IsImmolating(this)) @@ -3007,42 +3014,42 @@ namespace Server.Items if (Core.ML && (ranged?.Velocity ?? 0) != 0) { - list.Add(1072793, $"{prop}"); // Velocity ~1_val~% + list.Add(1072793, prop); // Velocity ~1_val~% } if ((prop = Attributes.BonusDex) != 0) { - list.Add(1060409, $"{prop}"); // dexterity bonus ~1_val~ + list.Add(1060409, prop); // dexterity bonus ~1_val~ } if ((prop = Attributes.BonusHits) != 0) { - list.Add(1060431, $"{prop}"); // hit point increase ~1_val~ + list.Add(1060431, prop); // hit point increase ~1_val~ } if ((prop = Attributes.BonusInt) != 0) { - list.Add(1060432, $"{prop}"); // intelligence bonus ~1_val~ + list.Add(1060432, prop); // intelligence bonus ~1_val~ } if ((prop = Attributes.LowerManaCost) != 0) { - list.Add(1060433, $"{prop}"); // lower mana cost ~1_val~% + list.Add(1060433, prop); // lower mana cost ~1_val~% } if ((prop = Attributes.LowerRegCost) != 0) { - list.Add(1060434, $"{prop}"); // lower reagent cost ~1_val~% + list.Add(1060434, prop); // lower reagent cost ~1_val~% } if ((prop = GetLowerStatReq()) != 0) { - list.Add(1060435, $"{prop}"); // lower requirements ~1_val~% + list.Add(1060435, prop); // lower requirements ~1_val~% } if ((prop = GetLuckBonus() + Attributes.Luck) != 0) { - list.Add(1060436, $"{prop}"); // luck ~1_val~ + list.Add(1060436, prop); // luck ~1_val~ } if ((prop = WeaponAttributes.MageWeapon) != 0) @@ -3052,12 +3059,12 @@ namespace Server.Items if ((prop = Attributes.BonusMana) != 0) { - list.Add(1060439, $"{prop}"); // mana increase ~1_val~ + list.Add(1060439, prop); // mana increase ~1_val~ } if ((prop = Attributes.RegenMana) != 0) { - list.Add(1060440, $"{prop}"); // mana regeneration ~1_val~ + list.Add(1060440, prop); // mana regeneration ~1_val~ } if (Attributes.NightSight != 0) @@ -3067,22 +3074,22 @@ namespace Server.Items if ((prop = Attributes.ReflectPhysical) != 0) { - list.Add(1060442, $"{prop}"); // reflect physical damage ~1_val~% + list.Add(1060442, prop); // reflect physical damage ~1_val~% } if ((prop = Attributes.RegenStam) != 0) { - list.Add(1060443, $"{prop}"); // stamina regeneration ~1_val~ + list.Add(1060443, prop); // stamina regeneration ~1_val~ } if ((prop = Attributes.RegenHits) != 0) { - list.Add(1060444, $"{prop}"); // hit point regeneration ~1_val~ + list.Add(1060444, prop); // hit point regeneration ~1_val~ } if ((prop = WeaponAttributes.SelfRepair) != 0) { - list.Add(1060450, $"{prop}"); // self repair ~1_val~ + list.Add(1060450, prop); // self repair ~1_val~ } if (Attributes.SpellChanneling != 0) @@ -3092,27 +3099,27 @@ namespace Server.Items if ((prop = Attributes.SpellDamage) != 0) { - list.Add(1060483, $"{prop}"); // spell damage increase ~1_val~% + list.Add(1060483, prop); // spell damage increase ~1_val~% } if ((prop = Attributes.BonusStam) != 0) { - list.Add(1060484, $"{prop}"); // stamina increase ~1_val~ + list.Add(1060484, prop); // stamina increase ~1_val~ } if ((prop = Attributes.BonusStr) != 0) { - list.Add(1060485, $"{prop}"); // strength bonus ~1_val~ + list.Add(1060485, prop); // strength bonus ~1_val~ } if ((prop = Attributes.WeaponSpeed) != 0) { - list.Add(1060486, $"{prop}"); // swing speed increase ~1_val~% + list.Add(1060486, prop); // swing speed increase ~1_val~% } if (Core.ML && (prop = Attributes.IncreasedKarmaLoss) != 0) { - list.Add(1075210, $"{prop}"); // Increased Karma Loss ~1val~% + list.Add(1075210, prop); // Increased Karma Loss ~1val~% } GetDamageTypes( @@ -3128,37 +3135,37 @@ namespace Server.Items if (phys != 0) { - list.Add(1060403, $"{phys}"); // physical damage ~1_val~% + list.Add(1060403, phys); // physical damage ~1_val~% } if (fire != 0) { - list.Add(1060405, $"{fire}"); // fire damage ~1_val~% + list.Add(1060405, fire); // fire damage ~1_val~% } if (cold != 0) { - list.Add(1060404, $"{cold}"); // cold damage ~1_val~% + list.Add(1060404, cold); // cold damage ~1_val~% } if (pois != 0) { - list.Add(1060406, $"{pois}"); // poison damage ~1_val~% + list.Add(1060406, pois); // poison damage ~1_val~% } if (nrgy != 0) { - list.Add(1060407, $"{nrgy}"); // energy damage ~1_val + list.Add(1060407, nrgy); // energy damage ~1_val } if (Core.ML && chaos != 0) { - list.Add(1072846, $"{chaos}"); // chaos damage ~1_val~% + list.Add(1072846, chaos); // chaos damage ~1_val~% } if (Core.ML && direct != 0) { - list.Add(1079978, $"{direct}"); // Direct Damage: ~1_PERCENT~% + list.Add(1079978, direct); // Direct Damage: ~1_PERCENT~% } list.Add(1061168, $"{MinDamage}\t{MaxDamage}"); // weapon damage ~1_val~ - ~2_val~ @@ -3174,14 +3181,14 @@ namespace Server.Items if (MaxRange > 1) { - list.Add(1061169, $"{MaxRange}"); // range ~1_val~ + list.Add(1061169, MaxRange); // range ~1_val~ } var strReq = AOS.Scale(StrRequirement, 100 - GetLowerStatReq()); if (strReq > 0) { - list.Add(1061170, $"{strReq}"); // strength requirement ~1_val~ + list.Add(1061170, strReq); // strength requirement ~1_val~ } if (Layer == Layer.TwoHanded) diff --git a/Projects/UOContent/Misc/AOS.cs b/Projects/UOContent/Misc/AOS.cs index 527c46d8d..02ca10b8d 100644 --- a/Projects/UOContent/Misc/AOS.cs +++ b/Projects/UOContent/Misc/AOS.cs @@ -1041,7 +1041,7 @@ namespace Server { if (GetValues(i, out var skill, out var bonus)) { - list.Add(1060451 + i, $"#{GetLabel(skill)}\t{bonus}"); + list.Add(1060451 + i, $"{GetLabel(skill):#}\t{bonus}"); } } } diff --git a/Projects/UOContent/Mobiles/PlayerMobile.cs b/Projects/UOContent/Mobiles/PlayerMobile.cs index 02648f607..f5a01f8ab 100644 --- a/Projects/UOContent/Mobiles/PlayerMobile.cs +++ b/Projects/UOContent/Mobiles/PlayerMobile.cs @@ -3525,14 +3525,15 @@ namespace Server.Mobiles if (faction.Commander == this) { - list.Add(1042733, faction.Definition.PropName); // Commanding Lord of the ~1_FACTION_NAME~ + // Commanding Lord of the ~1_FACTION_NAME~ + list.Add(1042733, $"{faction.Definition.PropName}"); } else if (pl.Sheriff != null) { list.Add( - 1042734, + 1042734, // The Sheriff of ~1_CITY~, ~2_FACTION_NAME~ $"{pl.Sheriff.Definition.FriendlyName}\t{faction.Definition.PropName}" - ); // The Sheriff of ~1_CITY~, ~2_FACTION_NAME~ + ); } else if (pl.Finance != null) { diff --git a/Projects/UOContent/Multis/Houses/BaseHouse.cs b/Projects/UOContent/Multis/Houses/BaseHouse.cs index dd480e427..b11216e86 100644 --- a/Projects/UOContent/Multis/Houses/BaseHouse.cs +++ b/Projects/UOContent/Multis/Houses/BaseHouse.cs @@ -3721,12 +3721,17 @@ namespace Server.Multis ref ySouth ); - var location = - valid ? $"{yLat}° {yMins}'{(ySouth ? "S" : "N")}, {xLong}° {xMins}'{(xEast ? "E" : "W")}" : "unknown"; - list.Add(1061112, Utility.FixHtml(houseName)); // House Name: ~1_val~ list.Add(1061113, owner); // Owner: ~1_val~ - list.Add(1061114, location); // Location: ~1_val~ + if (valid) + { + // Location: ~1_val~ + list.Add(1061114, $"{yLat}° {yMins}'{(ySouth ? "S" : "N")}, {xLong}° {xMins}'{(xEast ? "E" : "W")}"); + } + else + { + list.Add(1061114, "unknown"); // Location: ~1_val~ + } } public override void Serialize(IGenericWriter writer) diff --git a/Projects/UOContent/Multis/Houses/HouseSign.cs b/Projects/UOContent/Multis/Houses/HouseSign.cs index ab8a35180..2df270fb8 100644 --- a/Projects/UOContent/Multis/Houses/HouseSign.cs +++ b/Projects/UOContent/Multis/Houses/HouseSign.cs @@ -83,7 +83,7 @@ namespace Server.Multis level = DecayLevel.IDOC; } - list.Add(1062028, $"#{1043009 + (int)level}"); // Condition: This structure is ... + list.AddLocalized(1062028, 1043009 + (int)level); // Condition: This structure is ... } } } diff --git a/Projects/UOContent/Spells/Spellweaving/Items/ArcaneFocus.cs b/Projects/UOContent/Spells/Spellweaving/Items/ArcaneFocus.cs index 44f987401..56676d627 100644 --- a/Projects/UOContent/Spells/Spellweaving/Items/ArcaneFocus.cs +++ b/Projects/UOContent/Spells/Spellweaving/Items/ArcaneFocus.cs @@ -38,7 +38,7 @@ namespace Server.Items { base.GetProperties(list); - list.Add(1060485, $"{StrengthBonus}"); // strength bonus ~1_val~ + list.Add(1060485, StrengthBonus); // strength bonus ~1_val~ } public override void Serialize(IGenericWriter writer) diff --git a/Projects/UOContent/Spells/Spellweaving/Items/TransientItem.cs b/Projects/UOContent/Spells/Spellweaving/Items/TransientItem.cs index 4755e5ed1..8f5bec909 100644 --- a/Projects/UOContent/Spells/Spellweaving/Items/TransientItem.cs +++ b/Projects/UOContent/Spells/Spellweaving/Items/TransientItem.cs @@ -53,9 +53,9 @@ namespace Server.Items public virtual void SendTimeRemainingMessage(Mobile to) { to.SendLocalizedMessage( - 1072516, + 1072516, // ~1_name~ will expire in ~2_val~ seconds! $"{Name ?? $"#{LabelNumber}"}\t{(int)LifeSpan.TotalSeconds}" - ); // ~1_name~ will expire in ~2_val~ seconds! + ); } public override void OnDelete() From db207227114a7051d8addaa4d282600119330c28 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 12 Jun 2022 21:27:16 -0700 Subject: [PATCH 186/213] fix: Simplifies OPL (#1051) --- Projects/Server/Items/Item.cs | 24 ++++++------------- Projects/Server/Mobiles/Mobile.cs | 11 ++------- .../UOContent/Engines/Plants/PlantItem.cs | 2 +- .../UOContent/Items/Misc/Corpses/Corpse.cs | 4 ++-- .../Multis/Houses/HouseFoundation.cs | 4 ++-- 5 files changed, 14 insertions(+), 31 deletions(-) diff --git a/Projects/Server/Items/Item.cs b/Projects/Server/Items/Item.cs index 9a657dc21..027ce41ba 100644 --- a/Projects/Server/Items/Item.cs +++ b/Projects/Server/Items/Item.cs @@ -1123,7 +1123,6 @@ namespace Server Span oldWorldItem = stackalloc byte[OutgoingEntityPackets.MaxWorldEntityPacketLength].InitializePacket(); Span saWorldItem = stackalloc byte[OutgoingEntityPackets.MaxWorldEntityPacketLength].InitializePacket(); Span hsWorldItem = stackalloc byte[OutgoingEntityPackets.MaxWorldEntityPacketLength].InitializePacket(); - Span opl = ObjectPropertyList.Enabled ? stackalloc byte[OutgoingEntityPackets.OPLPacketLength].InitializePacket() : null; var eable = m_Map.GetClientsInRange(m_Location, GetMaxUpdateRange()); @@ -1141,7 +1140,7 @@ namespace Server hsWorldItem = hsWorldItem[..length]; } - SendInfoTo(state, hsWorldItem, opl); + SendInfoTo(state, hsWorldItem); } else if (state.StygianAbyss) { @@ -1151,7 +1150,7 @@ namespace Server saWorldItem = saWorldItem[..length]; } - SendInfoTo(state, saWorldItem, opl); + SendInfoTo(state, saWorldItem); } else { @@ -1161,7 +1160,7 @@ namespace Server oldWorldItem = oldWorldItem[..length]; } - SendInfoTo(state, oldWorldItem, opl); + SendInfoTo(state, oldWorldItem); } } } @@ -3073,27 +3072,18 @@ namespace Server public virtual int GetUpdateRange(Mobile m) => 18; - public virtual void SendInfoTo(NetState ns, ReadOnlySpan world = default, Span opl = default) + public virtual void SendInfoTo(NetState ns, ReadOnlySpan world = default) { SendWorldPacketTo(ns, world); - SendOPLPacketTo(ns, opl); + SendOPLPacketTo(ns); } - public virtual void SendOPLPacketTo(NetState ns, Span opl = default) + public virtual void SendOPLPacketTo(NetState ns) { - if (!ObjectPropertyList.Enabled) - { - return; - } - - if (opl == null) + if (ObjectPropertyList.Enabled) { ns.SendOPLInfo(this); - return; } - - OutgoingEntityPackets.CreateOPLInfo(opl, this); - ns.Send(opl); } public virtual void SendWorldPacketTo(NetState ns, ReadOnlySpan world = default) diff --git a/Projects/Server/Mobiles/Mobile.cs b/Projects/Server/Mobiles/Mobile.cs index 76a307d15..7fb9e0a77 100644 --- a/Projects/Server/Mobiles/Mobile.cs +++ b/Projects/Server/Mobiles/Mobile.cs @@ -6892,21 +6892,14 @@ namespace Server eable.Free(); } - public void SendOPLPacketTo(NetState state) => SendOPLPacketTo(state, ObjectPropertyList.Enabled); - - protected virtual void SendOPLPacketTo(NetState ns, bool sendOplPacket) + public virtual void SendOPLPacketTo(NetState ns) { - if (sendOplPacket) + if (ObjectPropertyList.Enabled) { ns.SendOPLInfo(this); } } - public virtual void SendOPLPacketTo(NetState ns, ReadOnlySpan opl) - { - ns?.Send(opl); - } - public virtual void OnAccessLevelChanged(AccessLevel oldLevel) { } diff --git a/Projects/UOContent/Engines/Plants/PlantItem.cs b/Projects/UOContent/Engines/Plants/PlantItem.cs index ba71e6455..ef1bcdcb1 100644 --- a/Projects/UOContent/Engines/Plants/PlantItem.cs +++ b/Projects/UOContent/Engines/Plants/PlantItem.cs @@ -258,7 +258,7 @@ namespace Server.Engines.Plants } // Overridden to support new and old client localization - public override void SendOPLPacketTo(NetState ns, Span opl = default) + public override void SendOPLPacketTo(NetState ns) { if (!ObjectPropertyList.Enabled) { diff --git a/Projects/UOContent/Items/Misc/Corpses/Corpse.cs b/Projects/UOContent/Items/Misc/Corpses/Corpse.cs index 15eb2ca25..17f686976 100644 --- a/Projects/UOContent/Items/Misc/Corpses/Corpse.cs +++ b/Projects/UOContent/Items/Misc/Corpses/Corpse.cs @@ -799,9 +799,9 @@ namespace Server.Items return m_Devourer.Devour(this); // Devour the corpse if it hasn't } - public override void SendInfoTo(NetState ns, ReadOnlySpan world = default, Span opl = default) + public override void SendInfoTo(NetState ns, ReadOnlySpan world = default) { - base.SendInfoTo(ns, world, opl); + base.SendInfoTo(ns, world); if (((Body)Amount).IsHuman && ItemID == 0x2006) { diff --git a/Projects/UOContent/Multis/Houses/HouseFoundation.cs b/Projects/UOContent/Multis/Houses/HouseFoundation.cs index d8c1a7176..186952f38 100644 --- a/Projects/UOContent/Multis/Houses/HouseFoundation.cs +++ b/Projects/UOContent/Multis/Houses/HouseFoundation.cs @@ -878,9 +878,9 @@ namespace Server.Multis DesignState.SendDetailedInfoTo(ns); } - public override void SendInfoTo(NetState ns, ReadOnlySpan world = default, Span opl = default) + public override void SendInfoTo(NetState ns, ReadOnlySpan world = default) { - base.SendInfoTo(ns, world, opl); + base.SendInfoTo(ns, world); var stateToSend = DesignContext.Find(ns?.Mobile)?.Foundation == this ? DesignState : CurrentState; stateToSend.SendGeneralInfoTo(ns); From 59e1793c2d4ec438b385cef2a328c33ac4db4d23 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Mon, 13 Jun 2022 01:13:59 -0700 Subject: [PATCH 187/213] fix: Codegens fillable containers (#862) - [X] Fillable containers now relock/retrap after respawn. - [X] Optimized the lookup and serialization. --- .../Fillable Containers/FillableContainer.cs | 254 +++ .../Fillable Containers/FillableContainers.cs | 100 + .../FillableContent.ContentTypes.cs | 810 +++++++++ .../Fillable Containers/FillableContent.cs | 114 ++ .../Fillable Containers/FillableEntry.cs | 102 ++ .../Items/Containers/FillableContainers.cs | 1612 ----------------- .../Server.Items.FillableBarrel.v0.json | 4 + .../Server.Items.FillableContainer.v2.json | 19 + .../Server.Items.FillableLargeCrate.v0.json | 4 + .../Server.Items.FillableMetalBox.v0.json | 4 + .../Server.Items.FillableMetalChest.v0.json | 4 + ...ver.Items.FillableMetalGoldenChest.v0.json | 4 + .../Server.Items.FillableSmallCrate.v0.json | 4 + .../Server.Items.FillableWoodenBox.v0.json | 4 + .../Server.Items.FillableWoodenChest.v0.json | 4 + .../Server.Items.LibraryBookcase.v0.json | 4 + 16 files changed, 1435 insertions(+), 1612 deletions(-) create mode 100644 Projects/UOContent/Items/Containers/Fillable Containers/FillableContainer.cs create mode 100644 Projects/UOContent/Items/Containers/Fillable Containers/FillableContainers.cs create mode 100644 Projects/UOContent/Items/Containers/Fillable Containers/FillableContent.ContentTypes.cs create mode 100644 Projects/UOContent/Items/Containers/Fillable Containers/FillableContent.cs create mode 100644 Projects/UOContent/Items/Containers/Fillable Containers/FillableEntry.cs delete mode 100644 Projects/UOContent/Items/Containers/FillableContainers.cs create mode 100644 Projects/UOContent/Migrations/Server.Items.FillableBarrel.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.FillableContainer.v2.json create mode 100644 Projects/UOContent/Migrations/Server.Items.FillableLargeCrate.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.FillableMetalBox.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.FillableMetalChest.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.FillableMetalGoldenChest.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.FillableSmallCrate.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.FillableWoodenBox.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.FillableWoodenChest.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.LibraryBookcase.v0.json diff --git a/Projects/UOContent/Items/Containers/Fillable Containers/FillableContainer.cs b/Projects/UOContent/Items/Containers/Fillable Containers/FillableContainer.cs new file mode 100644 index 000000000..9f035a477 --- /dev/null +++ b/Projects/UOContent/Items/Containers/Fillable Containers/FillableContainer.cs @@ -0,0 +1,254 @@ +using System; +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(2, false)] +public abstract partial class FillableContainer : LockableContainer +{ + [SerializableField(0)] + protected FillableContentType _rawContentType; + + [TimerDrift] + [SerializableField(1)] + private Timer _respawnTimer; + + [DeserializeTimerField(1)] + private void DeserializeRespawnTimer(TimeSpan delay) + { + if (delay > TimeSpan.MinValue) + { + _respawnTimer = Timer.DelayCall(delay, Respawn); + } + } + + public FillableContainer(int itemID) : base(itemID) => Movable = false; + + public virtual int MinRespawnMinutes => 60; + public virtual int MaxRespawnMinutes => 90; + + public virtual bool IsLockable => true; + public virtual bool IsTrappable => IsLockable; + + public virtual int SpawnThreshold => 2; + + [CommandProperty(AccessLevel.GameMaster)] + public DateTime NextRespawnTime => _respawnTimer?.Next ?? DateTime.MinValue; + + [CommandProperty(AccessLevel.GameMaster)] + public FillableContentType ContentType + { + get => _rawContentType; + set + { + if (_rawContentType == value) + { + return; + } + + ClearContents(); + _rawContentType = value; + Respawn(); + } + } + + protected void ClearContents() + { + for (var i = Items.Count - 1; i >= 0; --i) + { + if (i < Items.Count) + { + Items[i].Delete(); + } + } + } + + public override void OnMapChange() + { + base.OnMapChange(); + AcquireContent(); + } + + public override void OnLocationChange(Point3D oldLocation) + { + base.OnLocationChange(oldLocation); + AcquireContent(); + } + + public virtual void AcquireContent() + { + if (_rawContentType != FillableContentType.None) + { + return; + } + + RawContentType = FillableContent.Acquire(GetWorldLocation(), Map); + + if (_rawContentType != FillableContentType.None) + { + Respawn(); + } + } + + public override void OnItemRemoved(Item item) + { + CheckRespawn(); + } + + public override void OnAfterDelete() + { + base.OnAfterDelete(); + + _respawnTimer?.Stop(); + _respawnTimer = null; + } + + public int GetItemsCount() + { + var count = 0; + + foreach (var item in Items) + { + count += item.Amount; + } + + return count; + } + + public void CheckRespawn() + { + var canSpawn = + _rawContentType != FillableContentType.None && + !Deleted && !Movable && Parent == null && !IsLockedDown && !IsSecure && + ( + GetItemsCount() <= SpawnThreshold || + IsLockable && !Locked || + IsTrappable && TrapType == TrapType.None + ); + + if (canSpawn) + { + if (_respawnTimer?.Running != true) + { + var mins = Utility.RandomMinMax(MinRespawnMinutes, MaxRespawnMinutes); + var delay = TimeSpan.FromMinutes(mins); + _respawnTimer = Timer.DelayCall(delay, Respawn); + } + } + else + { + _respawnTimer?.Stop(); + _respawnTimer = null; + } + } + + public void Respawn() + { + _respawnTimer?.Stop(); + _respawnTimer = null; + + if (_rawContentType == FillableContentType.None || Deleted) + { + return; + } + + GenerateContent(); + + var level = FillableContent.Lookup(_rawContentType).Level; + + if (IsLockable) + { + Locked = true; + + var difficulty = (level - 1) * 30; + + LockLevel = difficulty - 10; + MaxLockLevel = difficulty + 30; + RequiredSkill = difficulty; + } + + if (IsTrappable && (level > 1 || Utility.Random(5) < 4)) + { + TrapType = level > Utility.Random(5) ? TrapType.PoisonTrap : TrapType.ExplosionTrap; + TrapPower = level * Utility.RandomMinMax(10, 30); + TrapLevel = level; + } + else + { + TrapType = TrapType.None; + TrapPower = 0; + TrapLevel = 0; + } + + CheckRespawn(); + } + + protected virtual int GetSpawnCount() + { + var itemsCount = GetItemsCount(); + + if (itemsCount > SpawnThreshold) + { + return 0; + } + + var maxSpawnCount = (1 + SpawnThreshold - itemsCount) * 2; + + return Utility.RandomMinMax(0, maxSpawnCount); + } + + public virtual void GenerateContent() + { + if (_rawContentType == FillableContentType.None || Deleted) + { + return; + } + + var content = FillableContent.Lookup(_rawContentType); + + var toSpawn = GetSpawnCount(); + + for (var i = 0; i < toSpawn; ++i) + { + var item = content.Construct(); + + if (item == null) + { + continue; + } + + var list = Items; + + for (var j = 0; j < list.Count; ++j) + { + var subItem = list[j]; + + if (subItem is not Container && subItem.StackWith(null, item, false)) + { + break; + } + } + + if (!item.Deleted) + { + DropItem(item); + } + } + } + + private void Deserialize(IGenericReader reader, int version) + { + _rawContentType = (FillableContentType)reader.ReadInt(); + var respawnTimerNext = reader.ReadDeltaTime(); + DeserializeRespawnTimer(respawnTimerNext == DateTime.MinValue ? TimeSpan.MinValue : respawnTimerNext - Core.Now); + } + + [AfterDeserialization] + private void AfterDeserialization() + { + if (_respawnTimer?.Running != true) + { + CheckRespawn(); + } + } +} diff --git a/Projects/UOContent/Items/Containers/Fillable Containers/FillableContainers.cs b/Projects/UOContent/Items/Containers/Fillable Containers/FillableContainers.cs new file mode 100644 index 000000000..0c3afc853 --- /dev/null +++ b/Projects/UOContent/Items/Containers/Fillable Containers/FillableContainers.cs @@ -0,0 +1,100 @@ +using ModernUO.Serialization; + +namespace Server.Items; + +[Flippable(0xA97, 0xA99, 0xA98, 0xA9A, 0xA9B, 0xA9C)] +[SerializationGenerator(0)] +public partial class LibraryBookcase : FillableContainer +{ + [Constructible] + public LibraryBookcase() : base(0xA97) => Weight = 1.0; + + public override bool IsLockable => false; + public override int SpawnThreshold => 5; + + protected override int GetSpawnCount() => 5 - GetItemsCount(); + + public override void AcquireContent() + { + if (_rawContentType != FillableContentType.None) + { + return; + } + + RawContentType = FillableContentType.Library; + Respawn(); + } +} + +[Flippable(0xE3D, 0xE3C)] +[SerializationGenerator(0)] +public partial class FillableLargeCrate : FillableContainer +{ + [Constructible] + public FillableLargeCrate() : base(0xE3D) => Weight = 1.0; +} + +[Flippable(0x9A9, 0xE7E)] +[SerializationGenerator(0)] +public partial class FillableSmallCrate : FillableContainer +{ + [Constructible] + public FillableSmallCrate() : base(0x9A9) => Weight = 1.0; +} + +[Flippable(0x9AA, 0xE7D)] +[SerializationGenerator(0)] +public partial class FillableWoodenBox : FillableContainer +{ + [Constructible] + public FillableWoodenBox() : base(0x9AA) => Weight = 4.0; +} + +[Flippable(0x9A8, 0xE80)] +[SerializationGenerator(0)] +public partial class FillableMetalBox : FillableContainer +{ + [Constructible] + public FillableMetalBox() : base(0x9A8) + { + } +} + +[SerializationGenerator(0)] +public partial class FillableBarrel : FillableContainer +{ + [Constructible] + public FillableBarrel() : base(0xE77) + { + } +} + +[Flippable(0x9AB, 0xE7C)] +[SerializationGenerator(0, false)] +public partial class FillableMetalChest : FillableContainer +{ + [Constructible] + public FillableMetalChest() : base(0x9AB) + { + } +} + +[Flippable(0xE41, 0xE40)] +[SerializationGenerator(0, false)] +public partial class FillableMetalGoldenChest : FillableContainer +{ + [Constructible] + public FillableMetalGoldenChest() : base(0xE41) + { + } +} + +[Flippable(0xE43, 0xE42)] +[SerializationGenerator(0, false)] +public partial class FillableWoodenChest : FillableContainer +{ + [Constructible] + public FillableWoodenChest() : base(0xE43) + { + } +} diff --git a/Projects/UOContent/Items/Containers/Fillable Containers/FillableContent.ContentTypes.cs b/Projects/UOContent/Items/Containers/Fillable Containers/FillableContent.ContentTypes.cs new file mode 100644 index 000000000..55a7b2ab1 --- /dev/null +++ b/Projects/UOContent/Items/Containers/Fillable Containers/FillableContent.ContentTypes.cs @@ -0,0 +1,810 @@ +using System; +using System.Collections.Generic; +using Server.Mobiles; + +namespace Server.Items; + +public enum FillableContentType +{ + None = -1, + Weaponsmith, + Provisioner, + Mage, + Alchemist, + Armorer, + ArtisanGuild, + Baker, + Bard, + Blacksmith, + Bowyer, + Butcher, + Carpenter, + Clothier, + Cobbler, + Docks, + Farm, + FighterGuild, + Guard, + Healer, + Herbalist, + Inn, + Jeweler, + Library, + Merchant, + Mill, + Mine, + Observatory, + Painter, + Ranger, + Stables, + Tanner, + Tavern, + ThiefGuild, + Tinker, + Veterinarian +} + +public partial class FillableContent +{ + private static readonly FillableContent Alchemist = new( + 1, + new[] + { + typeof(Alchemist) + }, + new[] + { + new FillableEntry(typeof(NightSightPotion)), + new FillableEntry(typeof(LesserCurePotion)), + new FillableEntry(typeof(AgilityPotion)), + new FillableEntry(typeof(StrengthPotion)), + new FillableEntry(typeof(LesserPoisonPotion)), + new FillableEntry(typeof(RefreshPotion)), + new FillableEntry(typeof(LesserHealPotion)), + new FillableEntry(typeof(LesserExplosionPotion)), + new FillableEntry(typeof(MortarPestle)) + } + ); + + private static readonly FillableContent Armorer = new( + 2, + new[] + { + typeof(Armorer) + }, + new[] + { + new FillableEntry(2, typeof(ChainCoif)), + new FillableEntry(1, typeof(PlateGorget)), + new FillableEntry(1, typeof(BronzeShield)), + new FillableEntry(1, typeof(Buckler)), + new FillableEntry(2, typeof(MetalKiteShield)), + new FillableEntry(2, typeof(HeaterShield)), + new FillableEntry(1, typeof(WoodenShield)), + new FillableEntry(1, typeof(MetalShield)) + } + ); + + private static readonly FillableContent ArtisanGuild = new( + 1, + Array.Empty(), + new[] + { + new FillableEntry(1, typeof(PaintsAndBrush)), + new FillableEntry(1, typeof(SledgeHammer)), + new FillableEntry(2, typeof(SmithHammer)), + new FillableEntry(2, typeof(Tongs)), + new FillableEntry(4, typeof(Lockpick)), + new FillableEntry(4, typeof(TinkerTools)), + new FillableEntry(1, typeof(MalletAndChisel)), + new FillableEntry(1, typeof(StatueEast2)), + new FillableEntry(1, typeof(StatueSouth)), + new FillableEntry(1, typeof(StatueSouthEast)), + new FillableEntry(1, typeof(StatueWest)), + new FillableEntry(1, typeof(StatueNorth)), + new FillableEntry(1, typeof(StatueEast)), + new FillableEntry(1, typeof(BustEast)), + new FillableEntry(1, typeof(BustSouth)), + new FillableEntry(1, typeof(BearMask)), + new FillableEntry(1, typeof(DeerMask)), + new FillableEntry(4, typeof(OrcHelm)), + new FillableEntry(1, typeof(TribalMask)), + new FillableEntry(1, typeof(HornedTribalMask)) + } + ); + + private static readonly FillableContent Baker = new( + 1, + new[] + { + typeof(Baker) + }, + new[] + { + new FillableEntry(1, typeof(RollingPin)), + new FillableEntry(2, typeof(SackFlour)), + new FillableEntry(2, typeof(BreadLoaf)), + new FillableEntry(1, typeof(FrenchBread)) + } + ); + + private static readonly FillableContent Bard = new( + 1, + new[] + { + typeof(Bard), + typeof(BardGuildmaster) + }, + new[] + { + new FillableEntry(1, typeof(LapHarp)), + new FillableEntry(2, typeof(Lute)), + new FillableEntry(1, typeof(Drums)), + new FillableEntry(1, typeof(Tambourine)), + new FillableEntry(1, typeof(TambourineTassel)) + } + ); + + private static readonly FillableContent Blacksmith = new( + 2, + new[] + { + typeof(Blacksmith), + typeof(BlacksmithGuildmaster) + }, + new[] + { + new FillableEntry(8, typeof(SmithHammer)), + new FillableEntry(8, typeof(Tongs)), + new FillableEntry(8, typeof(SledgeHammer)), + // new FillableEntry( 8, typeof( IronOre ) ), TODO: Smaller ore + new FillableEntry(8, typeof(IronIngot)), + new FillableEntry(1, typeof(IronWire)), + new FillableEntry(1, typeof(SilverWire)), + new FillableEntry(1, typeof(GoldWire)), + new FillableEntry(1, typeof(CopperWire)), + new FillableEntry(1, typeof(HorseShoes)), + new FillableEntry(1, typeof(ForgedMetal)) + } + ); + + private static readonly FillableContent Bowyer = new( + 2, + new[] + { + typeof(Bowyer) + }, + new[] + { + new FillableEntry(2, typeof(Bow)), + new FillableEntry(2, typeof(Crossbow)), + new FillableEntry(1, typeof(Arrow)) + } + ); + + private static readonly FillableContent Butcher = new( + 1, + new[] + { + typeof(Butcher) + }, + new[] + { + new FillableEntry(2, typeof(Cleaver)), + new FillableEntry(2, typeof(SlabOfBacon)), + new FillableEntry(2, typeof(Bacon)), + new FillableEntry(1, typeof(RawFishSteak)), + new FillableEntry(1, typeof(FishSteak)), + new FillableEntry(2, typeof(CookedBird)), + new FillableEntry(2, typeof(RawBird)), + new FillableEntry(2, typeof(Ham)), + new FillableEntry(1, typeof(RawLambLeg)), + new FillableEntry(1, typeof(LambLeg)), + new FillableEntry(1, typeof(Ribs)), + new FillableEntry(1, typeof(RawRibs)), + new FillableEntry(2, typeof(Sausage)), + new FillableEntry(1, typeof(RawChickenLeg)), + new FillableEntry(1, typeof(ChickenLeg)) + } + ); + + private static readonly FillableContent Carpenter = new( + 1, + new[] + { + typeof(Carpenter), + typeof(Architect), + typeof(RealEstateBroker) + }, + new[] + { + new FillableEntry(1, typeof(ChiselsNorth)), + new FillableEntry(1, typeof(ChiselsWest)), + new FillableEntry(2, typeof(DovetailSaw)), + new FillableEntry(2, typeof(Hammer)), + new FillableEntry(2, typeof(MouldingPlane)), + new FillableEntry(2, typeof(Nails)), + new FillableEntry(2, typeof(JointingPlane)), + new FillableEntry(2, typeof(SmoothingPlane)), + new FillableEntry(2, typeof(Saw)), + new FillableEntry(2, typeof(DrawKnife)), + new FillableEntry(1, typeof(Log)), + new FillableEntry(1, typeof(Froe)), + new FillableEntry(1, typeof(Inshave)), + new FillableEntry(1, typeof(Scorp)) + } + ); + + private static readonly FillableContent Clothier = new( + 1, + new[] + { + typeof(Tailor), + typeof(Weaver), + typeof(TailorGuildmaster) + }, + new[] + { + new FillableEntry(1, typeof(Cotton)), + new FillableEntry(1, typeof(Wool)), + new FillableEntry(1, typeof(DarkYarn)), + new FillableEntry(1, typeof(LightYarn)), + new FillableEntry(1, typeof(LightYarnUnraveled)), + new FillableEntry(1, typeof(SpoolOfThread)), + // Four different types + // new FillableEntry( 1, typeof( FoldedCloth ) ), + // new FillableEntry( 1, typeof( FoldedCloth ) ), + // new FillableEntry( 1, typeof( FoldedCloth ) ), + // new FillableEntry( 1, typeof( FoldedCloth ) ), + new FillableEntry(1, typeof(Dyes)), + new FillableEntry(2, typeof(Leather)) + } + ); + + private static readonly FillableContent Cobbler = new( + 1, + new[] + { + typeof(Cobbler) + }, + new[] + { + new FillableEntry(1, typeof(Boots)), + new FillableEntry(2, typeof(Shoes)), + new FillableEntry(2, typeof(Sandals)), + new FillableEntry(1, typeof(ThighBoots)) + } + ); + + private static readonly FillableContent Docks = new( + 1, + new[] + { + typeof(Fisherman), + typeof(FisherGuildmaster) + }, + new[] + { + new FillableEntry(1, typeof(FishingPole)), + // Two different types + // new FillableEntry( 1, typeof( SmallFish ) ), + // new FillableEntry( 1, typeof( SmallFish ) ), + new FillableEntry(4, typeof(Fish)) + } + ); + + private static readonly FillableContent Farm = new( + 1, + new[] + { + typeof(Farmer), + typeof(Rancher) + }, + new[] + { + new FillableEntry(1, typeof(Shirt)), + new FillableEntry(1, typeof(ShortPants)), + new FillableEntry(1, typeof(Skirt)), + new FillableEntry(1, typeof(PlainDress)), + new FillableEntry(1, typeof(Cap)), + new FillableEntry(2, typeof(Sandals)), + new FillableEntry(2, typeof(GnarledStaff)), + new FillableEntry(2, typeof(Pitchfork)), + new FillableEntry(1, typeof(Bag)), + new FillableEntry(1, typeof(Kindling)), + new FillableEntry(1, typeof(Lettuce)), + new FillableEntry(1, typeof(Onion)), + new FillableEntry(1, typeof(Turnip)), + new FillableEntry(1, typeof(Ham)), + new FillableEntry(1, typeof(Bacon)), + new FillableEntry(1, typeof(RawLambLeg)), + new FillableEntry(1, typeof(SheafOfHay)), + new FillableBvrge(1, typeof(Pitcher), BeverageType.Milk) + } + ); + + private static readonly FillableContent FighterGuild = new( + 3, + new[] + { + typeof(WarriorGuildmaster) + }, + new[] + { + new FillableEntry(12, Loot.ArmorTypes), + new FillableEntry(8, Loot.WeaponTypes), + new FillableEntry(3, Loot.ShieldTypes), + new FillableEntry(1, typeof(Arrow)) + } + ); + + private static readonly FillableContent Guard = new( + 3, + Array.Empty(), + new[] + { + new FillableEntry(12, Loot.ArmorTypes), + new FillableEntry(8, Loot.WeaponTypes), + new FillableEntry(3, Loot.ShieldTypes), + new FillableEntry(1, typeof(Arrow)) + } + ); + + private static readonly FillableContent Healer = new( + 1, + new[] + { + typeof(Healer), + typeof(HealerGuildmaster) + }, + new[] + { + new FillableEntry(1, typeof(Bandage)), + new FillableEntry(1, typeof(MortarPestle)), + new FillableEntry(1, typeof(LesserHealPotion)) + } + ); + + private static readonly FillableContent Herbalist = new( + 1, + new[] + { + typeof(Herbalist) + }, + new[] + { + new FillableEntry(10, typeof(Garlic)), + new FillableEntry(10, typeof(Ginseng)), + new FillableEntry(10, typeof(MandrakeRoot)), + new FillableEntry(1, typeof(DeadWood)), + new FillableEntry(1, typeof(WhiteDriedFlowers)), + new FillableEntry(1, typeof(GreenDriedFlowers)), + new FillableEntry(1, typeof(DriedOnions)), + new FillableEntry(1, typeof(DriedHerbs)) + } + ); + + private static readonly FillableContent Inn = new( + 1, + Array.Empty(), + new[] + { + new FillableEntry(1, typeof(Candle)), + new FillableEntry(1, typeof(Torch)), + new FillableEntry(1, typeof(Lantern)) + } + ); + + private static readonly FillableContent Jeweler = new( + 2, + new[] + { + typeof(Jeweler) + }, + new[] + { + new FillableEntry(1, typeof(GoldRing)), + new FillableEntry(1, typeof(GoldBracelet)), + new FillableEntry(1, typeof(GoldEarrings)), + new FillableEntry(1, typeof(GoldNecklace)), + new FillableEntry(1, typeof(GoldBeadNecklace)), + new FillableEntry(1, typeof(Necklace)), + new FillableEntry(1, typeof(Beads)), + new FillableEntry(9, Loot.GemTypes) + } + ); + + private static readonly FillableContent Library = new( + 1, + new[] + { + typeof(Scribe) + }, + new[] + { + new FillableEntry(8, Loot.LibraryBookTypes), + new FillableEntry(1, typeof(RedBook)), + new FillableEntry(1, typeof(BlueBook)) + } + ); + + private static readonly FillableContent Mage = new( + 2, + new[] + { + typeof(Mage), + typeof(HolyMage), + typeof(MageGuildmaster) + }, + new[] + { + new FillableEntry(16, typeof(BlankScroll)), + new FillableEntry(14, typeof(Spellbook)), + new FillableEntry(12, Loot.RegularScrollTypes, 0, 8), + new FillableEntry(11, Loot.RegularScrollTypes, 8, 8), + new FillableEntry(10, Loot.RegularScrollTypes, 16, 8), + new FillableEntry(9, Loot.RegularScrollTypes, 24, 8), + new FillableEntry(8, Loot.RegularScrollTypes, 32, 8), + new FillableEntry(7, Loot.RegularScrollTypes, 40, 8), + new FillableEntry(6, Loot.RegularScrollTypes, 48, 8), + new FillableEntry(5, Loot.RegularScrollTypes, 56, 8) + } + ); + + private static readonly FillableContent Merchant = new( + 1, + new[] + { + typeof(MerchantGuildmaster) + }, + new[] + { + new FillableEntry(1, typeof(CheeseWheel)), + new FillableEntry(1, typeof(CheeseWedge)), + new FillableEntry(1, typeof(CheeseSlice)), + new FillableEntry(1, typeof(Eggs)), + new FillableEntry(4, typeof(Fish)), + new FillableEntry(2, typeof(RawFishSteak)), + new FillableEntry(2, typeof(FishSteak)), + new FillableEntry(1, typeof(Apple)), + new FillableEntry(2, typeof(Banana)), + new FillableEntry(2, typeof(Bananas)), + new FillableEntry(2, typeof(OpenCoconut)), + new FillableEntry(1, typeof(SplitCoconut)), + new FillableEntry(1, typeof(Coconut)), + new FillableEntry(1, typeof(Dates)), + new FillableEntry(1, typeof(Grapes)), + new FillableEntry(1, typeof(Lemon)), + new FillableEntry(1, typeof(Lemons)), + new FillableEntry(1, typeof(Lime)), + new FillableEntry(1, typeof(Limes)), + new FillableEntry(1, typeof(Peach)), + new FillableEntry(1, typeof(Pear)), + new FillableEntry(2, typeof(SlabOfBacon)), + new FillableEntry(2, typeof(Bacon)), + new FillableEntry(2, typeof(CookedBird)), + new FillableEntry(2, typeof(RawBird)), + new FillableEntry(2, typeof(Ham)), + new FillableEntry(1, typeof(RawLambLeg)), + new FillableEntry(1, typeof(LambLeg)), + new FillableEntry(1, typeof(Ribs)), + new FillableEntry(1, typeof(RawRibs)), + new FillableEntry(2, typeof(Sausage)), + new FillableEntry(1, typeof(RawChickenLeg)), + new FillableEntry(1, typeof(ChickenLeg)), + new FillableEntry(1, typeof(Watermelon)), + new FillableEntry(1, typeof(SmallWatermelon)), + new FillableEntry(3, typeof(Turnip)), + new FillableEntry(2, typeof(YellowGourd)), + new FillableEntry(2, typeof(GreenGourd)), + new FillableEntry(2, typeof(Pumpkin)), + new FillableEntry(1, typeof(SmallPumpkin)), + new FillableEntry(2, typeof(Onion)), + new FillableEntry(2, typeof(Lettuce)), + new FillableEntry(2, typeof(Squash)), + new FillableEntry(2, typeof(HoneydewMelon)), + new FillableEntry(1, typeof(Carrot)), + new FillableEntry(2, typeof(Cantaloupe)), + new FillableEntry(2, typeof(Cabbage)), + new FillableEntry(4, typeof(EarOfCorn)) + } + ); + + private static readonly FillableContent Mill = new( + 1, + Array.Empty(), + new[] + { + new FillableEntry(1, typeof(SackFlour)) + } + ); + + private static readonly FillableContent Mine = new( + 1, + new[] + { + typeof(Miner) + }, + new[] + { + new FillableEntry(2, typeof(Pickaxe)), + new FillableEntry(2, typeof(Shovel)), + new FillableEntry(2, typeof(IronIngot)), + // new FillableEntry( 2, typeof( IronOre ) ), TODO: Smaller Ore + new FillableEntry(1, typeof(ForgedMetal)) + } + ); + + private static readonly FillableContent Observatory = new( + 1, + Array.Empty(), + new[] + { + new FillableEntry(2, typeof(Sextant)), + new FillableEntry(2, typeof(Clock)), + new FillableEntry(1, typeof(Spyglass)) + } + ); + + private static readonly FillableContent Painter = new( + 1, + Array.Empty(), + new[] + { + new FillableEntry(1, typeof(PaintsAndBrush)), + new FillableEntry(2, typeof(PenAndInk)) + } + ); + + private static readonly FillableContent Provisioner = new( + 1, + new[] + { + typeof(Provisioner) + }, + new[] + { + new FillableEntry(1, typeof(CheeseWheel)), + new FillableEntry(1, typeof(CheeseWedge)), + new FillableEntry(1, typeof(CheeseSlice)), + new FillableEntry(1, typeof(Eggs)), + new FillableEntry(4, typeof(Fish)), + new FillableEntry(1, typeof(DirtyFrypan)), + new FillableEntry(1, typeof(DirtyPan)), + new FillableEntry(1, typeof(DirtyKettle)), + new FillableEntry(1, typeof(DirtySmallRoundPot)), + new FillableEntry(1, typeof(DirtyRoundPot)), + new FillableEntry(1, typeof(DirtySmallPot)), + new FillableEntry(1, typeof(DirtyPot)), + new FillableEntry(1, typeof(Apple)), + new FillableEntry(2, typeof(Banana)), + new FillableEntry(2, typeof(Bananas)), + new FillableEntry(2, typeof(OpenCoconut)), + new FillableEntry(1, typeof(SplitCoconut)), + new FillableEntry(1, typeof(Coconut)), + new FillableEntry(1, typeof(Dates)), + new FillableEntry(1, typeof(Grapes)), + new FillableEntry(1, typeof(Lemon)), + new FillableEntry(1, typeof(Lemons)), + new FillableEntry(1, typeof(Lime)), + new FillableEntry(1, typeof(Limes)), + new FillableEntry(1, typeof(Peach)), + new FillableEntry(1, typeof(Pear)), + new FillableEntry(2, typeof(SlabOfBacon)), + new FillableEntry(2, typeof(Bacon)), + new FillableEntry(1, typeof(RawFishSteak)), + new FillableEntry(1, typeof(FishSteak)), + new FillableEntry(2, typeof(CookedBird)), + new FillableEntry(2, typeof(RawBird)), + new FillableEntry(2, typeof(Ham)), + new FillableEntry(1, typeof(RawLambLeg)), + new FillableEntry(1, typeof(LambLeg)), + new FillableEntry(1, typeof(Ribs)), + new FillableEntry(1, typeof(RawRibs)), + new FillableEntry(2, typeof(Sausage)), + new FillableEntry(1, typeof(RawChickenLeg)), + new FillableEntry(1, typeof(ChickenLeg)), + new FillableEntry(1, typeof(Watermelon)), + new FillableEntry(1, typeof(SmallWatermelon)), + new FillableEntry(3, typeof(Turnip)), + new FillableEntry(2, typeof(YellowGourd)), + new FillableEntry(2, typeof(GreenGourd)), + new FillableEntry(2, typeof(Pumpkin)), + new FillableEntry(1, typeof(SmallPumpkin)), + new FillableEntry(2, typeof(Onion)), + new FillableEntry(2, typeof(Lettuce)), + new FillableEntry(2, typeof(Squash)), + new FillableEntry(2, typeof(HoneydewMelon)), + new FillableEntry(1, typeof(Carrot)), + new FillableEntry(2, typeof(Cantaloupe)), + new FillableEntry(2, typeof(Cabbage)), + new FillableEntry(4, typeof(EarOfCorn)) + } + ); + + private static readonly FillableContent Ranger = new( + 2, + new[] + { + typeof(Ranger), + typeof(RangerGuildmaster) + }, + new[] + { + new FillableEntry(2, typeof(StuddedChest)), + new FillableEntry(2, typeof(StuddedLegs)), + new FillableEntry(2, typeof(StuddedArms)), + new FillableEntry(2, typeof(StuddedGloves)), + new FillableEntry(1, typeof(StuddedGorget)), + + new FillableEntry(2, typeof(LeatherChest)), + new FillableEntry(2, typeof(LeatherLegs)), + new FillableEntry(2, typeof(LeatherArms)), + new FillableEntry(2, typeof(LeatherGloves)), + new FillableEntry(1, typeof(LeatherGorget)), + + new FillableEntry(2, typeof(FeatheredHat)), + new FillableEntry(1, typeof(CloseHelm)), + new FillableEntry(1, typeof(TallStrawHat)), + new FillableEntry(1, typeof(Bandana)), + new FillableEntry(1, typeof(Cloak)), + new FillableEntry(2, typeof(Boots)), + new FillableEntry(2, typeof(ThighBoots)), + + new FillableEntry(2, typeof(GnarledStaff)), + new FillableEntry(1, typeof(Whip)), + + new FillableEntry(2, typeof(Bow)), + new FillableEntry(2, typeof(Crossbow)), + new FillableEntry(2, typeof(HeavyCrossbow)), + new FillableEntry(4, typeof(Arrow)) + } + ); + + private static readonly FillableContent Stables = new( + 1, + new[] + { + typeof(AnimalTrainer), + typeof(GypsyAnimalTrainer) + }, + new[] + { + // new FillableEntry( 1, typeof( Wheat ) ), + new FillableEntry(1, typeof(Carrot)) + } + ); + + private static readonly FillableContent Tanner = new( + 2, + new[] + { + typeof(Tanner), + typeof(LeatherWorker), + typeof(Furtrader) + }, + new[] + { + new FillableEntry(1, typeof(FeatheredHat)), + new FillableEntry(1, typeof(LeatherArms)), + new FillableEntry(2, typeof(LeatherLegs)), + new FillableEntry(2, typeof(LeatherChest)), + new FillableEntry(2, typeof(LeatherGloves)), + new FillableEntry(1, typeof(LeatherGorget)), + new FillableEntry(2, typeof(Leather)) + } + ); + + private static readonly FillableContent Tavern = new( + 1, + new[] + { + typeof(TavernKeeper), + typeof(Barkeeper), + typeof(Waiter), + typeof(Cook) + }, + new FillableEntry[] + { + new FillableBvrge(1, typeof(BeverageBottle), BeverageType.Ale), + new FillableBvrge(1, typeof(BeverageBottle), BeverageType.Wine), + new FillableBvrge(1, typeof(BeverageBottle), BeverageType.Liquor), + new FillableBvrge(1, typeof(Jug), BeverageType.Cider) + } + ); + + private static readonly FillableContent ThiefGuild = new( + 1, + new[] + { + typeof(Thief), + typeof(ThiefGuildmaster) + }, + new[] + { + new FillableEntry(1, typeof(Lockpick)), + new FillableEntry(1, typeof(BearMask)), + new FillableEntry(1, typeof(DeerMask)), + new FillableEntry(1, typeof(TribalMask)), + new FillableEntry(1, typeof(HornedTribalMask)), + new FillableEntry(4, typeof(OrcHelm)) + } + ); + + private static readonly FillableContent Tinker = new( + 1, + new[] + { + typeof(Tinker), + typeof(TinkerGuildmaster) + }, + new[] + { + new FillableEntry(1, typeof(Lockpick)), + // new FillableEntry( 1, typeof( KeyRing ) ), + new FillableEntry(2, typeof(Clock)), + new FillableEntry(2, typeof(ClockParts)), + new FillableEntry(2, typeof(AxleGears)), + new FillableEntry(2, typeof(Gears)), + new FillableEntry(2, typeof(Hinge)), + // new FillableEntry( 1, typeof( ArrowShafts ) ), + new FillableEntry(2, typeof(Sextant)), + new FillableEntry(2, typeof(SextantParts)), + new FillableEntry(2, typeof(Axle)), + new FillableEntry(2, typeof(Springs)), + new FillableEntry(5, typeof(TinkerTools)), + new FillableEntry(4, typeof(Key)), + new FillableEntry(1, typeof(DecoArrowShafts)), + new FillableEntry(1, typeof(Lockpicks)), + new FillableEntry(1, typeof(ToolKit)) + } + ); + + private static readonly FillableContent Veterinarian = new( + 1, + new[] + { + typeof(Veterinarian) + }, + new[] + { + new FillableEntry(1, typeof(Bandage)), + new FillableEntry(1, typeof(MortarPestle)), + new FillableEntry(1, typeof(LesserHealPotion)), + // new FillableEntry( 1, typeof( Wheat ) ), + new FillableEntry(1, typeof(Carrot)) + } + ); + + private static readonly FillableContent Weaponsmith = new( + 2, + new[] + { + typeof(Weaponsmith) + }, + new[] + { + new FillableEntry(8, Loot.WeaponTypes), + new FillableEntry(1, typeof(Arrow)) + } + ); + + private static Dictionary _acquireTable; + + // This should match the FillableContentType enum + private static readonly FillableContent[] ContentTypes = + { + Weaponsmith, Provisioner, Mage, + Alchemist, Armorer, ArtisanGuild, + Baker, Bard, Blacksmith, + Bowyer, Butcher, Carpenter, + Clothier, Cobbler, Docks, + Farm, FighterGuild, Guard, + Healer, Herbalist, Inn, + Jeweler, Library, Merchant, + Mill, Mine, Observatory, + Painter, Ranger, Stables, + Tanner, Tavern, ThiefGuild, + Tinker, Veterinarian + }; +} diff --git a/Projects/UOContent/Items/Containers/Fillable Containers/FillableContent.cs b/Projects/UOContent/Items/Containers/Fillable Containers/FillableContent.cs new file mode 100644 index 000000000..f9752d9b7 --- /dev/null +++ b/Projects/UOContent/Items/Containers/Fillable Containers/FillableContent.cs @@ -0,0 +1,114 @@ +using System; +using System.Collections.Generic; + +namespace Server.Items; + +public partial class FillableContent +{ + private readonly FillableEntry[] _entries; + private readonly int _weight; + + public FillableContent(int level, Type[] vendors, FillableEntry[] entries) + { + Level = level; + Vendors = vendors; + _entries = entries; + + for (var i = 0; i < entries.Length; ++i) + { + _weight += entries[i].Weight; + } + } + + public int Level { get; } + + public Type[] Vendors { get; } + + public FillableContentType TypeID => Lookup(this); + + public virtual Item Construct() + { + var index = Utility.Random(_weight); + + for (var i = 0; i < _entries.Length; ++i) + { + var entry = _entries[i]; + + if (index < entry.Weight) + { + return entry.Construct(); + } + + index -= entry.Weight; + } + + return null; + } + + public static FillableContent Lookup(FillableContentType type) + { + var v = (int)type; + + if (v >= 0 && v < ContentTypes.Length) + { + return ContentTypes[v]; + } + + return null; + } + + public static FillableContentType Lookup(FillableContent content) + { + if (content == null) + { + return FillableContentType.None; + } + + return (FillableContentType)Array.IndexOf(ContentTypes, content); + } + + public static FillableContentType Acquire(Point3D loc, Map map) + { + FillableContentType content = FillableContentType.None; + + if (map == null || map == Map.Internal) + { + return content; + } + + if (_acquireTable == null) + { + _acquireTable = new Dictionary(); + + for (var i = 0; i < ContentTypes.Length; ++i) + { + var fill = ContentTypes[i]; + + for (var j = 0; j < fill.Vendors.Length; ++j) + { + _acquireTable[fill.Vendors[j]] = fill.TypeID; + } + } + } + + Mobile nearest = null; + + // TODO: Replace with vendor shop regions and a fallback override. + foreach (var mob in map.GetMobilesInRange(loc, 20)) + { + if (nearest != null && mob.GetDistanceToSqrt(loc) > nearest.GetDistanceToSqrt(loc) && + !(nearest is Mobiles.Cobbler && mob is Mobiles.Provisioner)) + { + continue; + } + + if (_acquireTable.TryGetValue(mob.GetType(), out var check)) + { + nearest = mob; + content = check; + } + } + + return content; + } +} diff --git a/Projects/UOContent/Items/Containers/Fillable Containers/FillableEntry.cs b/Projects/UOContent/Items/Containers/Fillable Containers/FillableEntry.cs new file mode 100644 index 000000000..ee7ca724a --- /dev/null +++ b/Projects/UOContent/Items/Containers/Fillable Containers/FillableEntry.cs @@ -0,0 +1,102 @@ +using System; + +namespace Server.Items; + +public class FillableEntry +{ + protected Type[] _types; + protected int _weight; + + public FillableEntry(Type type) : this(1, new[] { type }) + { + } + + public FillableEntry(int weight, Type type) : this(weight, new[] { type }) + { + } + + public FillableEntry(Type[] types) : this(1, types) + { + } + + public FillableEntry(int weight, Type[] types) + { + _weight = weight; + _types = types; + } + + public FillableEntry(int weight, Type[] types, int offset, int count) + { + _weight = weight; + _types = new Type[count]; + Array.Copy(types, offset, _types, 0, count); + } + + public Type[] Types => _types; + public int Weight => _weight; + + public virtual Item Construct() + { + var item = Loot.Construct(_types); + + if (item is Key key) + { + key.ItemID = Utility.RandomList( + (int)KeyType.Copper, + (int)KeyType.Gold, + (int)KeyType.Iron, + (int)KeyType.Rusty + ); + } + else if (item is Arrow or Bolt) + { + item.Amount = Utility.RandomMinMax(2, 6); + } + else if (item is Bandage or Lockpick) + { + item.Amount = Utility.RandomMinMax(1, 3); + } + + return item; + } +} + +public class FillableBvrge : FillableEntry +{ + public FillableBvrge(Type type, BeverageType content) : this(1, type, content) + { + } + + public FillableBvrge(int weight, Type type, BeverageType content) : base(weight, type) => + Content = content; + + public BeverageType Content { get; } + + public override Item Construct() + { + Item item; + + var index = Utility.Random(_types.Length); + + if (_types[index] == typeof(BeverageBottle)) + { + item = new BeverageBottle(Content); + } + else if (_types[index] == typeof(Jug)) + { + item = new Jug(Content); + } + else + { + item = base.Construct(); + + if (item is BaseBeverage bev) + { + bev.Content = Content; + bev.Quantity = bev.MaxQuantity; + } + } + + return item; + } +} diff --git a/Projects/UOContent/Items/Containers/FillableContainers.cs b/Projects/UOContent/Items/Containers/FillableContainers.cs deleted file mode 100644 index 54ccdd410..000000000 --- a/Projects/UOContent/Items/Containers/FillableContainers.cs +++ /dev/null @@ -1,1612 +0,0 @@ -using System; -using System.Collections.Generic; -using Server.Mobiles; - -namespace Server.Items -{ - public abstract class FillableContainer : LockableContainer - { - protected FillableContent m_Content; - - protected DateTime m_NextRespawnTime; - protected Timer _respawnTimer; - - public FillableContainer(int itemID) : base(itemID) => Movable = false; - - public FillableContainer(Serial serial) - : base(serial) - { - } - - public virtual int MinRespawnMinutes => 60; - public virtual int MaxRespawnMinutes => 90; - - public virtual bool IsLockable => true; - public virtual bool IsTrappable => IsLockable; - - public virtual int SpawnThreshold => 2; - - [CommandProperty(AccessLevel.GameMaster)] - public DateTime NextRespawnTime => m_NextRespawnTime; - - [CommandProperty(AccessLevel.GameMaster)] - public FillableContentType ContentType - { - get => FillableContent.Lookup(m_Content); - set => Content = FillableContent.Lookup(value); - } - - public FillableContent Content - { - get => m_Content; - set - { - if (m_Content == value) - { - return; - } - - m_Content = value; - - for (var i = Items.Count - 1; i >= 0; --i) - { - if (i < Items.Count) - { - Items[i].Delete(); - } - } - - Respawn(); - } - } - - public override void OnMapChange() - { - base.OnMapChange(); - AcquireContent(); - } - - public override void OnLocationChange(Point3D oldLocation) - { - base.OnLocationChange(oldLocation); - AcquireContent(); - } - - public virtual void AcquireContent() - { - if (m_Content != null) - { - return; - } - - m_Content = FillableContent.Acquire(GetWorldLocation(), Map); - - if (m_Content != null) - { - Respawn(); - } - } - - public override void OnItemRemoved(Item item) - { - CheckRespawn(); - } - - public override void OnAfterDelete() - { - base.OnAfterDelete(); - - _respawnTimer?.Stop(); - _respawnTimer = null; - } - - public int GetItemsCount() - { - var count = 0; - - foreach (var item in Items) - { - count += item.Amount; - } - - return count; - } - - public void CheckRespawn() - { - var canSpawn = m_Content != null && !Deleted && GetItemsCount() <= SpawnThreshold && !Movable && - Parent == null && !IsLockedDown && !IsSecure; - - if (canSpawn) - { - if (_respawnTimer?.Running != true) - { - var mins = Utility.RandomMinMax(MinRespawnMinutes, MaxRespawnMinutes); - var delay = TimeSpan.FromMinutes(mins); - - m_NextRespawnTime = Core.Now + delay; - _respawnTimer = Timer.DelayCall(delay, Respawn); - } - } - else - { - _respawnTimer?.Stop(); - _respawnTimer = null; - } - } - - public void Respawn() - { - _respawnTimer?.Stop(); - _respawnTimer = null; - - if (m_Content == null || Deleted) - { - return; - } - - GenerateContent(); - - if (IsLockable) - { - Locked = true; - - var difficulty = (m_Content.Level - 1) * 30; - - LockLevel = difficulty - 10; - MaxLockLevel = difficulty + 30; - RequiredSkill = difficulty; - } - - if (IsTrappable && (m_Content.Level > 1 || Utility.Random(5) < 4)) - { - if (m_Content.Level > Utility.Random(5)) - { - TrapType = TrapType.PoisonTrap; - } - else - { - TrapType = TrapType.ExplosionTrap; - } - - TrapPower = m_Content.Level * Utility.RandomMinMax(10, 30); - TrapLevel = m_Content.Level; - } - else - { - TrapType = TrapType.None; - TrapPower = 0; - TrapLevel = 0; - } - - CheckRespawn(); - } - - protected virtual int GetSpawnCount() - { - var itemsCount = GetItemsCount(); - - if (itemsCount > SpawnThreshold) - { - return 0; - } - - var maxSpawnCount = (1 + SpawnThreshold - itemsCount) * 2; - - return Utility.RandomMinMax(0, maxSpawnCount); - } - - public virtual void GenerateContent() - { - if (m_Content == null || Deleted) - { - return; - } - - var toSpawn = GetSpawnCount(); - - for (var i = 0; i < toSpawn; ++i) - { - var item = m_Content.Construct(); - - if (item == null) - { - continue; - } - - var list = Items; - - for (var j = 0; j < list.Count; ++j) - { - var subItem = list[j]; - - if (subItem is not Container && subItem.StackWith(null, item, false)) - { - break; - } - } - - if (!item.Deleted) - { - DropItem(item); - } - } - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(1); // version - - writer.Write((int)ContentType); - - if (_respawnTimer?.Running == true) - { - writer.Write(true); - writer.WriteDeltaTime(m_NextRespawnTime); - } - else - { - writer.Write(false); - } - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - - switch (version) - { - case 1: - { - m_Content = FillableContent.Lookup((FillableContentType)reader.ReadInt()); - goto case 0; - } - case 0: - { - if (reader.ReadBool()) - { - m_NextRespawnTime = reader.ReadDeltaTime(); - - var delay = m_NextRespawnTime - Core.Now; - Timer.DelayCall(delay, Respawn); - } - else - { - CheckRespawn(); - } - - break; - } - } - } - } - - [Flippable(0xA97, 0xA99, 0xA98, 0xA9A, 0xA9B, 0xA9C)] - public class LibraryBookcase : FillableContainer - { - [Constructible] - public LibraryBookcase() - : base(0xA97) => - Weight = 1.0; - - public LibraryBookcase(Serial serial) - : base(serial) - { - } - - public override bool IsLockable => false; - public override int SpawnThreshold => 5; - - protected override int GetSpawnCount() => 5 - GetItemsCount(); - - public override void AcquireContent() - { - if (m_Content != null) - { - return; - } - - m_Content = FillableContent.Library; - - if (m_Content != null) - { - Respawn(); - } - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(1); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - - if (version == 0 && m_Content == null) - { - Timer.StartTimer(AcquireContent); - } - } - } - - [Flippable(0xE3D, 0xE3C)] - public class FillableLargeCrate : FillableContainer - { - [Constructible] - public FillableLargeCrate() - : base(0xE3D) => - Weight = 1.0; - - public FillableLargeCrate(Serial serial) - : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } - - [Flippable(0x9A9, 0xE7E)] - public class FillableSmallCrate : FillableContainer - { - [Constructible] - public FillableSmallCrate() - : base(0x9A9) => - Weight = 1.0; - - public FillableSmallCrate(Serial serial) - : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } - - [Flippable(0x9AA, 0xE7D)] - public class FillableWoodenBox : FillableContainer - { - [Constructible] - public FillableWoodenBox() - : base(0x9AA) => - Weight = 4.0; - - public FillableWoodenBox(Serial serial) - : base(serial) - { - } - - 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(); - } - } - - [Flippable(0x9A8, 0xE80)] - public class FillableMetalBox : FillableContainer - { - [Constructible] - public FillableMetalBox() - : base(0x9A8) - { - } - - public FillableMetalBox(Serial serial) - : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - - if (version == 0 && Weight == 3) - { - Weight = -1; - } - } - } - - public class FillableBarrel : FillableContainer - { - [Constructible] - public FillableBarrel() - : base(0xE77) - { - } - - public FillableBarrel(Serial serial) - : base(serial) - { - } - - public override bool IsLockable => false; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(1); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - - if (version == 0 && Weight == 25) - { - Weight = -1; - } - } - } - - [Flippable(0x9AB, 0xE7C)] - public class FillableMetalChest : FillableContainer - { - [Constructible] - public FillableMetalChest() - : base(0x9AB) - { - } - - public FillableMetalChest(Serial serial) - : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(1); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - if (version == 0 && Weight == 25) - { - Weight = -1; - } - } - } - - [Flippable(0xE41, 0xE40)] - public class FillableMetalGoldenChest : FillableContainer - { - [Constructible] - public FillableMetalGoldenChest() - : base(0xE41) - { - } - - public FillableMetalGoldenChest(Serial serial) - : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(1); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - if (version == 0 && Weight == 25) - { - Weight = -1; - } - } - } - - [Flippable(0xE43, 0xE42)] - public class FillableWoodenChest : FillableContainer - { - [Constructible] - public FillableWoodenChest() - : base(0xE43) - { - } - - public FillableWoodenChest(Serial serial) - : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(1); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - if (version == 0 && Weight == 2) - { - Weight = -1; - } - } - } - - public class FillableEntry - { - protected Type[] m_Types; - protected int m_Weight; - - public FillableEntry(Type type) - : this(1, new[] { type }) - { - } - - public FillableEntry(int weight, Type type) - : this(weight, new[] { type }) - { - } - - public FillableEntry(Type[] types) - : this(1, types) - { - } - - public FillableEntry(int weight, Type[] types) - { - m_Weight = weight; - m_Types = types; - } - - public FillableEntry(int weight, Type[] types, int offset, int count) - { - m_Weight = weight; - m_Types = new Type[count]; - - for (var i = 0; i < m_Types.Length; ++i) - { - m_Types[i] = types[offset + i]; - } - } - - public Type[] Types => m_Types; - public int Weight => m_Weight; - - public virtual Item Construct() - { - var item = Loot.Construct(m_Types); - - if (item is Key key) - { - key.ItemID = Utility.RandomList( - (int)KeyType.Copper, - (int)KeyType.Gold, - (int)KeyType.Iron, - (int)KeyType.Rusty - ); - } - else if (item is Arrow or Bolt) - { - item.Amount = Utility.RandomMinMax(2, 6); - } - else if (item is Bandage or Lockpick) - { - item.Amount = Utility.RandomMinMax(1, 3); - } - - return item; - } - } - - public class FillableBvrge : FillableEntry - { - public FillableBvrge(Type type, BeverageType content) - : this(1, type, content) - { - } - - public FillableBvrge(int weight, Type type, BeverageType content) - : base(weight, type) => - Content = content; - - public BeverageType Content { get; } - - public override Item Construct() - { - Item item; - - var index = Utility.Random(m_Types.Length); - - if (m_Types[index] == typeof(BeverageBottle)) - { - item = new BeverageBottle(Content); - } - else if (m_Types[index] == typeof(Jug)) - { - item = new Jug(Content); - } - else - { - item = base.Construct(); - - if (item is BaseBeverage bev) - { - bev.Content = Content; - bev.Quantity = bev.MaxQuantity; - } - } - - return item; - } - } - - public enum FillableContentType - { - None = -1, - Weaponsmith, - Provisioner, - Mage, - Alchemist, - Armorer, - ArtisanGuild, - Baker, - Bard, - Blacksmith, - Bowyer, - Butcher, - Carpenter, - Clothier, - Cobbler, - Docks, - Farm, - FighterGuild, - Guard, - Healer, - Herbalist, - Inn, - Jeweler, - Library, - Merchant, - Mill, - Mine, - Observatory, - Painter, - Ranger, - Stables, - Tanner, - Tavern, - ThiefGuild, - Tinker, - Veterinarian - } - - public class FillableContent - { - public static FillableContent Alchemist = new( - 1, - new[] - { - typeof(Alchemist) - }, - new[] - { - new FillableEntry(typeof(NightSightPotion)), - new FillableEntry(typeof(LesserCurePotion)), - new FillableEntry(typeof(AgilityPotion)), - new FillableEntry(typeof(StrengthPotion)), - new FillableEntry(typeof(LesserPoisonPotion)), - new FillableEntry(typeof(RefreshPotion)), - new FillableEntry(typeof(LesserHealPotion)), - new FillableEntry(typeof(LesserExplosionPotion)), - new FillableEntry(typeof(MortarPestle)) - } - ); - - public static FillableContent Armorer = new( - 2, - new[] - { - typeof(Armorer) - }, - new[] - { - new FillableEntry(2, typeof(ChainCoif)), - new FillableEntry(1, typeof(PlateGorget)), - new FillableEntry(1, typeof(BronzeShield)), - new FillableEntry(1, typeof(Buckler)), - new FillableEntry(2, typeof(MetalKiteShield)), - new FillableEntry(2, typeof(HeaterShield)), - new FillableEntry(1, typeof(WoodenShield)), - new FillableEntry(1, typeof(MetalShield)) - } - ); - - public static FillableContent ArtisanGuild = new( - 1, - Array.Empty(), - new[] - { - new FillableEntry(1, typeof(PaintsAndBrush)), - new FillableEntry(1, typeof(SledgeHammer)), - new FillableEntry(2, typeof(SmithHammer)), - new FillableEntry(2, typeof(Tongs)), - new FillableEntry(4, typeof(Lockpick)), - new FillableEntry(4, typeof(TinkerTools)), - new FillableEntry(1, typeof(MalletAndChisel)), - new FillableEntry(1, typeof(StatueEast2)), - new FillableEntry(1, typeof(StatueSouth)), - new FillableEntry(1, typeof(StatueSouthEast)), - new FillableEntry(1, typeof(StatueWest)), - new FillableEntry(1, typeof(StatueNorth)), - new FillableEntry(1, typeof(StatueEast)), - new FillableEntry(1, typeof(BustEast)), - new FillableEntry(1, typeof(BustSouth)), - new FillableEntry(1, typeof(BearMask)), - new FillableEntry(1, typeof(DeerMask)), - new FillableEntry(4, typeof(OrcHelm)), - new FillableEntry(1, typeof(TribalMask)), - new FillableEntry(1, typeof(HornedTribalMask)) - } - ); - - public static FillableContent Baker = new( - 1, - new[] - { - typeof(Baker) - }, - new[] - { - new FillableEntry(1, typeof(RollingPin)), - new FillableEntry(2, typeof(SackFlour)), - new FillableEntry(2, typeof(BreadLoaf)), - new FillableEntry(1, typeof(FrenchBread)) - } - ); - - public static FillableContent Bard = new( - 1, - new[] - { - typeof(Bard), - typeof(BardGuildmaster) - }, - new[] - { - new FillableEntry(1, typeof(LapHarp)), - new FillableEntry(2, typeof(Lute)), - new FillableEntry(1, typeof(Drums)), - new FillableEntry(1, typeof(Tambourine)), - new FillableEntry(1, typeof(TambourineTassel)) - } - ); - - public static FillableContent Blacksmith = new( - 2, - new[] - { - typeof(Blacksmith), - typeof(BlacksmithGuildmaster) - }, - new[] - { - new FillableEntry(8, typeof(SmithHammer)), - new FillableEntry(8, typeof(Tongs)), - new FillableEntry(8, typeof(SledgeHammer)), - // new FillableEntry( 8, typeof( IronOre ) ), TODO: Smaller ore - new FillableEntry(8, typeof(IronIngot)), - new FillableEntry(1, typeof(IronWire)), - new FillableEntry(1, typeof(SilverWire)), - new FillableEntry(1, typeof(GoldWire)), - new FillableEntry(1, typeof(CopperWire)), - new FillableEntry(1, typeof(HorseShoes)), - new FillableEntry(1, typeof(ForgedMetal)) - } - ); - - public static FillableContent Bowyer = new( - 2, - new[] - { - typeof(Bowyer) - }, - new[] - { - new FillableEntry(2, typeof(Bow)), - new FillableEntry(2, typeof(Crossbow)), - new FillableEntry(1, typeof(Arrow)) - } - ); - - public static FillableContent Butcher = new( - 1, - new[] - { - typeof(Butcher) - }, - new[] - { - new FillableEntry(2, typeof(Cleaver)), - new FillableEntry(2, typeof(SlabOfBacon)), - new FillableEntry(2, typeof(Bacon)), - new FillableEntry(1, typeof(RawFishSteak)), - new FillableEntry(1, typeof(FishSteak)), - new FillableEntry(2, typeof(CookedBird)), - new FillableEntry(2, typeof(RawBird)), - new FillableEntry(2, typeof(Ham)), - new FillableEntry(1, typeof(RawLambLeg)), - new FillableEntry(1, typeof(LambLeg)), - new FillableEntry(1, typeof(Ribs)), - new FillableEntry(1, typeof(RawRibs)), - new FillableEntry(2, typeof(Sausage)), - new FillableEntry(1, typeof(RawChickenLeg)), - new FillableEntry(1, typeof(ChickenLeg)) - } - ); - - public static FillableContent Carpenter = new( - 1, - new[] - { - typeof(Carpenter), - typeof(Architect), - typeof(RealEstateBroker) - }, - new[] - { - new FillableEntry(1, typeof(ChiselsNorth)), - new FillableEntry(1, typeof(ChiselsWest)), - new FillableEntry(2, typeof(DovetailSaw)), - new FillableEntry(2, typeof(Hammer)), - new FillableEntry(2, typeof(MouldingPlane)), - new FillableEntry(2, typeof(Nails)), - new FillableEntry(2, typeof(JointingPlane)), - new FillableEntry(2, typeof(SmoothingPlane)), - new FillableEntry(2, typeof(Saw)), - new FillableEntry(2, typeof(DrawKnife)), - new FillableEntry(1, typeof(Log)), - new FillableEntry(1, typeof(Froe)), - new FillableEntry(1, typeof(Inshave)), - new FillableEntry(1, typeof(Scorp)) - } - ); - - public static FillableContent Clothier = new( - 1, - new[] - { - typeof(Tailor), - typeof(Weaver), - typeof(TailorGuildmaster) - }, - new[] - { - new FillableEntry(1, typeof(Cotton)), - new FillableEntry(1, typeof(Wool)), - new FillableEntry(1, typeof(DarkYarn)), - new FillableEntry(1, typeof(LightYarn)), - new FillableEntry(1, typeof(LightYarnUnraveled)), - new FillableEntry(1, typeof(SpoolOfThread)), - // Four different types - // new FillableEntry( 1, typeof( FoldedCloth ) ), - // new FillableEntry( 1, typeof( FoldedCloth ) ), - // new FillableEntry( 1, typeof( FoldedCloth ) ), - // new FillableEntry( 1, typeof( FoldedCloth ) ), - new FillableEntry(1, typeof(Dyes)), - new FillableEntry(2, typeof(Leather)) - } - ); - - public static FillableContent Cobbler = new( - 1, - new[] - { - typeof(Cobbler) - }, - new[] - { - new FillableEntry(1, typeof(Boots)), - new FillableEntry(2, typeof(Shoes)), - new FillableEntry(2, typeof(Sandals)), - new FillableEntry(1, typeof(ThighBoots)) - } - ); - - public static FillableContent Docks = new( - 1, - new[] - { - typeof(Fisherman), - typeof(FisherGuildmaster) - }, - new[] - { - new FillableEntry(1, typeof(FishingPole)), - // Two different types - // new FillableEntry( 1, typeof( SmallFish ) ), - // new FillableEntry( 1, typeof( SmallFish ) ), - new FillableEntry(4, typeof(Fish)) - } - ); - - public static FillableContent Farm = new( - 1, - new[] - { - typeof(Farmer), - typeof(Rancher) - }, - new[] - { - new FillableEntry(1, typeof(Shirt)), - new FillableEntry(1, typeof(ShortPants)), - new FillableEntry(1, typeof(Skirt)), - new FillableEntry(1, typeof(PlainDress)), - new FillableEntry(1, typeof(Cap)), - new FillableEntry(2, typeof(Sandals)), - new FillableEntry(2, typeof(GnarledStaff)), - new FillableEntry(2, typeof(Pitchfork)), - new FillableEntry(1, typeof(Bag)), - new FillableEntry(1, typeof(Kindling)), - new FillableEntry(1, typeof(Lettuce)), - new FillableEntry(1, typeof(Onion)), - new FillableEntry(1, typeof(Turnip)), - new FillableEntry(1, typeof(Ham)), - new FillableEntry(1, typeof(Bacon)), - new FillableEntry(1, typeof(RawLambLeg)), - new FillableEntry(1, typeof(SheafOfHay)), - new FillableBvrge(1, typeof(Pitcher), BeverageType.Milk) - } - ); - - public static FillableContent FighterGuild = new( - 3, - new[] - { - typeof(WarriorGuildmaster) - }, - new[] - { - new FillableEntry(12, Loot.ArmorTypes), - new FillableEntry(8, Loot.WeaponTypes), - new FillableEntry(3, Loot.ShieldTypes), - new FillableEntry(1, typeof(Arrow)) - } - ); - - public static FillableContent Guard = new( - 3, - Array.Empty(), - new[] - { - new FillableEntry(12, Loot.ArmorTypes), - new FillableEntry(8, Loot.WeaponTypes), - new FillableEntry(3, Loot.ShieldTypes), - new FillableEntry(1, typeof(Arrow)) - } - ); - - public static FillableContent Healer = new( - 1, - new[] - { - typeof(Healer), - typeof(HealerGuildmaster) - }, - new[] - { - new FillableEntry(1, typeof(Bandage)), - new FillableEntry(1, typeof(MortarPestle)), - new FillableEntry(1, typeof(LesserHealPotion)) - } - ); - - public static FillableContent Herbalist = new( - 1, - new[] - { - typeof(Herbalist) - }, - new[] - { - new FillableEntry(10, typeof(Garlic)), - new FillableEntry(10, typeof(Ginseng)), - new FillableEntry(10, typeof(MandrakeRoot)), - new FillableEntry(1, typeof(DeadWood)), - new FillableEntry(1, typeof(WhiteDriedFlowers)), - new FillableEntry(1, typeof(GreenDriedFlowers)), - new FillableEntry(1, typeof(DriedOnions)), - new FillableEntry(1, typeof(DriedHerbs)) - } - ); - - public static FillableContent Inn = new( - 1, - Array.Empty(), - new[] - { - new FillableEntry(1, typeof(Candle)), - new FillableEntry(1, typeof(Torch)), - new FillableEntry(1, typeof(Lantern)) - } - ); - - public static FillableContent Jeweler = new( - 2, - new[] - { - typeof(Jeweler) - }, - new[] - { - new FillableEntry(1, typeof(GoldRing)), - new FillableEntry(1, typeof(GoldBracelet)), - new FillableEntry(1, typeof(GoldEarrings)), - new FillableEntry(1, typeof(GoldNecklace)), - new FillableEntry(1, typeof(GoldBeadNecklace)), - new FillableEntry(1, typeof(Necklace)), - new FillableEntry(1, typeof(Beads)), - new FillableEntry(9, Loot.GemTypes) - } - ); - - public static FillableContent Library = new( - 1, - new[] - { - typeof(Scribe) - }, - new[] - { - new FillableEntry(8, Loot.LibraryBookTypes), - new FillableEntry(1, typeof(RedBook)), - new FillableEntry(1, typeof(BlueBook)) - } - ); - - public static FillableContent Mage = new( - 2, - new[] - { - typeof(Mage), - typeof(HolyMage), - typeof(MageGuildmaster) - }, - new[] - { - new FillableEntry(16, typeof(BlankScroll)), - new FillableEntry(14, typeof(Spellbook)), - new FillableEntry(12, Loot.RegularScrollTypes, 0, 8), - new FillableEntry(11, Loot.RegularScrollTypes, 8, 8), - new FillableEntry(10, Loot.RegularScrollTypes, 16, 8), - new FillableEntry(9, Loot.RegularScrollTypes, 24, 8), - new FillableEntry(8, Loot.RegularScrollTypes, 32, 8), - new FillableEntry(7, Loot.RegularScrollTypes, 40, 8), - new FillableEntry(6, Loot.RegularScrollTypes, 48, 8), - new FillableEntry(5, Loot.RegularScrollTypes, 56, 8) - } - ); - - public static FillableContent Merchant = new( - 1, - new[] - { - typeof(MerchantGuildmaster) - }, - new[] - { - new FillableEntry(1, typeof(CheeseWheel)), - new FillableEntry(1, typeof(CheeseWedge)), - new FillableEntry(1, typeof(CheeseSlice)), - new FillableEntry(1, typeof(Eggs)), - new FillableEntry(4, typeof(Fish)), - new FillableEntry(2, typeof(RawFishSteak)), - new FillableEntry(2, typeof(FishSteak)), - new FillableEntry(1, typeof(Apple)), - new FillableEntry(2, typeof(Banana)), - new FillableEntry(2, typeof(Bananas)), - new FillableEntry(2, typeof(OpenCoconut)), - new FillableEntry(1, typeof(SplitCoconut)), - new FillableEntry(1, typeof(Coconut)), - new FillableEntry(1, typeof(Dates)), - new FillableEntry(1, typeof(Grapes)), - new FillableEntry(1, typeof(Lemon)), - new FillableEntry(1, typeof(Lemons)), - new FillableEntry(1, typeof(Lime)), - new FillableEntry(1, typeof(Limes)), - new FillableEntry(1, typeof(Peach)), - new FillableEntry(1, typeof(Pear)), - new FillableEntry(2, typeof(SlabOfBacon)), - new FillableEntry(2, typeof(Bacon)), - new FillableEntry(2, typeof(CookedBird)), - new FillableEntry(2, typeof(RawBird)), - new FillableEntry(2, typeof(Ham)), - new FillableEntry(1, typeof(RawLambLeg)), - new FillableEntry(1, typeof(LambLeg)), - new FillableEntry(1, typeof(Ribs)), - new FillableEntry(1, typeof(RawRibs)), - new FillableEntry(2, typeof(Sausage)), - new FillableEntry(1, typeof(RawChickenLeg)), - new FillableEntry(1, typeof(ChickenLeg)), - new FillableEntry(1, typeof(Watermelon)), - new FillableEntry(1, typeof(SmallWatermelon)), - new FillableEntry(3, typeof(Turnip)), - new FillableEntry(2, typeof(YellowGourd)), - new FillableEntry(2, typeof(GreenGourd)), - new FillableEntry(2, typeof(Pumpkin)), - new FillableEntry(1, typeof(SmallPumpkin)), - new FillableEntry(2, typeof(Onion)), - new FillableEntry(2, typeof(Lettuce)), - new FillableEntry(2, typeof(Squash)), - new FillableEntry(2, typeof(HoneydewMelon)), - new FillableEntry(1, typeof(Carrot)), - new FillableEntry(2, typeof(Cantaloupe)), - new FillableEntry(2, typeof(Cabbage)), - new FillableEntry(4, typeof(EarOfCorn)) - } - ); - - public static FillableContent Mill = new( - 1, - Array.Empty(), - new[] - { - new FillableEntry(1, typeof(SackFlour)) - } - ); - - public static FillableContent Mine = new( - 1, - new[] - { - typeof(Miner) - }, - new[] - { - new FillableEntry(2, typeof(Pickaxe)), - new FillableEntry(2, typeof(Shovel)), - new FillableEntry(2, typeof(IronIngot)), - // new FillableEntry( 2, typeof( IronOre ) ), TODO: Smaller Ore - new FillableEntry(1, typeof(ForgedMetal)) - } - ); - - public static FillableContent Observatory = new( - 1, - Array.Empty(), - new[] - { - new FillableEntry(2, typeof(Sextant)), - new FillableEntry(2, typeof(Clock)), - new FillableEntry(1, typeof(Spyglass)) - } - ); - - public static FillableContent Painter = new( - 1, - Array.Empty(), - new[] - { - new FillableEntry(1, typeof(PaintsAndBrush)), - new FillableEntry(2, typeof(PenAndInk)) - } - ); - - public static FillableContent Provisioner = new( - 1, - new[] - { - typeof(Provisioner) - }, - new[] - { - new FillableEntry(1, typeof(CheeseWheel)), - new FillableEntry(1, typeof(CheeseWedge)), - new FillableEntry(1, typeof(CheeseSlice)), - new FillableEntry(1, typeof(Eggs)), - new FillableEntry(4, typeof(Fish)), - new FillableEntry(1, typeof(DirtyFrypan)), - new FillableEntry(1, typeof(DirtyPan)), - new FillableEntry(1, typeof(DirtyKettle)), - new FillableEntry(1, typeof(DirtySmallRoundPot)), - new FillableEntry(1, typeof(DirtyRoundPot)), - new FillableEntry(1, typeof(DirtySmallPot)), - new FillableEntry(1, typeof(DirtyPot)), - new FillableEntry(1, typeof(Apple)), - new FillableEntry(2, typeof(Banana)), - new FillableEntry(2, typeof(Bananas)), - new FillableEntry(2, typeof(OpenCoconut)), - new FillableEntry(1, typeof(SplitCoconut)), - new FillableEntry(1, typeof(Coconut)), - new FillableEntry(1, typeof(Dates)), - new FillableEntry(1, typeof(Grapes)), - new FillableEntry(1, typeof(Lemon)), - new FillableEntry(1, typeof(Lemons)), - new FillableEntry(1, typeof(Lime)), - new FillableEntry(1, typeof(Limes)), - new FillableEntry(1, typeof(Peach)), - new FillableEntry(1, typeof(Pear)), - new FillableEntry(2, typeof(SlabOfBacon)), - new FillableEntry(2, typeof(Bacon)), - new FillableEntry(1, typeof(RawFishSteak)), - new FillableEntry(1, typeof(FishSteak)), - new FillableEntry(2, typeof(CookedBird)), - new FillableEntry(2, typeof(RawBird)), - new FillableEntry(2, typeof(Ham)), - new FillableEntry(1, typeof(RawLambLeg)), - new FillableEntry(1, typeof(LambLeg)), - new FillableEntry(1, typeof(Ribs)), - new FillableEntry(1, typeof(RawRibs)), - new FillableEntry(2, typeof(Sausage)), - new FillableEntry(1, typeof(RawChickenLeg)), - new FillableEntry(1, typeof(ChickenLeg)), - new FillableEntry(1, typeof(Watermelon)), - new FillableEntry(1, typeof(SmallWatermelon)), - new FillableEntry(3, typeof(Turnip)), - new FillableEntry(2, typeof(YellowGourd)), - new FillableEntry(2, typeof(GreenGourd)), - new FillableEntry(2, typeof(Pumpkin)), - new FillableEntry(1, typeof(SmallPumpkin)), - new FillableEntry(2, typeof(Onion)), - new FillableEntry(2, typeof(Lettuce)), - new FillableEntry(2, typeof(Squash)), - new FillableEntry(2, typeof(HoneydewMelon)), - new FillableEntry(1, typeof(Carrot)), - new FillableEntry(2, typeof(Cantaloupe)), - new FillableEntry(2, typeof(Cabbage)), - new FillableEntry(4, typeof(EarOfCorn)) - } - ); - - public static FillableContent Ranger = new( - 2, - new[] - { - typeof(Ranger), - typeof(RangerGuildmaster) - }, - new[] - { - new FillableEntry(2, typeof(StuddedChest)), - new FillableEntry(2, typeof(StuddedLegs)), - new FillableEntry(2, typeof(StuddedArms)), - new FillableEntry(2, typeof(StuddedGloves)), - new FillableEntry(1, typeof(StuddedGorget)), - - new FillableEntry(2, typeof(LeatherChest)), - new FillableEntry(2, typeof(LeatherLegs)), - new FillableEntry(2, typeof(LeatherArms)), - new FillableEntry(2, typeof(LeatherGloves)), - new FillableEntry(1, typeof(LeatherGorget)), - - new FillableEntry(2, typeof(FeatheredHat)), - new FillableEntry(1, typeof(CloseHelm)), - new FillableEntry(1, typeof(TallStrawHat)), - new FillableEntry(1, typeof(Bandana)), - new FillableEntry(1, typeof(Cloak)), - new FillableEntry(2, typeof(Boots)), - new FillableEntry(2, typeof(ThighBoots)), - - new FillableEntry(2, typeof(GnarledStaff)), - new FillableEntry(1, typeof(Whip)), - - new FillableEntry(2, typeof(Bow)), - new FillableEntry(2, typeof(Crossbow)), - new FillableEntry(2, typeof(HeavyCrossbow)), - new FillableEntry(4, typeof(Arrow)) - } - ); - - public static FillableContent Stables = new( - 1, - new[] - { - typeof(AnimalTrainer), - typeof(GypsyAnimalTrainer) - }, - new[] - { - // new FillableEntry( 1, typeof( Wheat ) ), - new FillableEntry(1, typeof(Carrot)) - } - ); - - public static FillableContent Tanner = new( - 2, - new[] - { - typeof(Tanner), - typeof(LeatherWorker), - typeof(Furtrader) - }, - new[] - { - new FillableEntry(1, typeof(FeatheredHat)), - new FillableEntry(1, typeof(LeatherArms)), - new FillableEntry(2, typeof(LeatherLegs)), - new FillableEntry(2, typeof(LeatherChest)), - new FillableEntry(2, typeof(LeatherGloves)), - new FillableEntry(1, typeof(LeatherGorget)), - new FillableEntry(2, typeof(Leather)) - } - ); - - public static FillableContent Tavern = new( - 1, - new[] - { - typeof(TavernKeeper), - typeof(Barkeeper), - typeof(Waiter), - typeof(Cook) - }, - new FillableEntry[] - { - new FillableBvrge(1, typeof(BeverageBottle), BeverageType.Ale), - new FillableBvrge(1, typeof(BeverageBottle), BeverageType.Wine), - new FillableBvrge(1, typeof(BeverageBottle), BeverageType.Liquor), - new FillableBvrge(1, typeof(Jug), BeverageType.Cider) - } - ); - - public static FillableContent ThiefGuild = new( - 1, - new[] - { - typeof(Thief), - typeof(ThiefGuildmaster) - }, - new[] - { - new FillableEntry(1, typeof(Lockpick)), - new FillableEntry(1, typeof(BearMask)), - new FillableEntry(1, typeof(DeerMask)), - new FillableEntry(1, typeof(TribalMask)), - new FillableEntry(1, typeof(HornedTribalMask)), - new FillableEntry(4, typeof(OrcHelm)) - } - ); - - public static FillableContent Tinker = new( - 1, - new[] - { - typeof(Tinker), - typeof(TinkerGuildmaster) - }, - new[] - { - new FillableEntry(1, typeof(Lockpick)), - // new FillableEntry( 1, typeof( KeyRing ) ), - new FillableEntry(2, typeof(Clock)), - new FillableEntry(2, typeof(ClockParts)), - new FillableEntry(2, typeof(AxleGears)), - new FillableEntry(2, typeof(Gears)), - new FillableEntry(2, typeof(Hinge)), - // new FillableEntry( 1, typeof( ArrowShafts ) ), - new FillableEntry(2, typeof(Sextant)), - new FillableEntry(2, typeof(SextantParts)), - new FillableEntry(2, typeof(Axle)), - new FillableEntry(2, typeof(Springs)), - new FillableEntry(5, typeof(TinkerTools)), - new FillableEntry(4, typeof(Key)), - new FillableEntry(1, typeof(DecoArrowShafts)), - new FillableEntry(1, typeof(Lockpicks)), - new FillableEntry(1, typeof(ToolKit)) - } - ); - - public static FillableContent Veterinarian = new( - 1, - new[] - { - typeof(Veterinarian) - }, - new[] - { - new FillableEntry(1, typeof(Bandage)), - new FillableEntry(1, typeof(MortarPestle)), - new FillableEntry(1, typeof(LesserHealPotion)), - // new FillableEntry( 1, typeof( Wheat ) ), - new FillableEntry(1, typeof(Carrot)) - } - ); - - public static FillableContent Weaponsmith = new( - 2, - new[] - { - typeof(Weaponsmith) - }, - new[] - { - new FillableEntry(8, Loot.WeaponTypes), - new FillableEntry(1, typeof(Arrow)) - } - ); - - private static Dictionary m_AcquireTable; - - private static readonly FillableContent[] m_ContentTypes = - { - Weaponsmith, Provisioner, Mage, - Alchemist, Armorer, ArtisanGuild, - Baker, Bard, Blacksmith, - Bowyer, Butcher, Carpenter, - Clothier, Cobbler, Docks, - Farm, FighterGuild, Guard, - Healer, Herbalist, Inn, - Jeweler, Library, Merchant, - Mill, Mine, Observatory, - Painter, Ranger, Stables, - Tanner, Tavern, ThiefGuild, - Tinker, Veterinarian - }; - - private readonly FillableEntry[] m_Entries; - private readonly int m_Weight; - - public FillableContent(int level, Type[] vendors, FillableEntry[] entries) - { - Level = level; - Vendors = vendors; - m_Entries = entries; - - for (var i = 0; i < entries.Length; ++i) - { - m_Weight += entries[i].Weight; - } - } - - public int Level { get; } - - public Type[] Vendors { get; } - - public FillableContentType TypeID => Lookup(this); - - public virtual Item Construct() - { - var index = Utility.Random(m_Weight); - - for (var i = 0; i < m_Entries.Length; ++i) - { - var entry = m_Entries[i]; - - if (index < entry.Weight) - { - return entry.Construct(); - } - - index -= entry.Weight; - } - - return null; - } - - public static FillableContent Lookup(FillableContentType type) - { - var v = (int)type; - - if (v >= 0 && v < m_ContentTypes.Length) - { - return m_ContentTypes[v]; - } - - return null; - } - - public static FillableContentType Lookup(FillableContent content) - { - if (content == null) - { - return FillableContentType.None; - } - - return (FillableContentType)Array.IndexOf(m_ContentTypes, content); - } - - public static FillableContent Acquire(Point3D loc, Map map) - { - if (map == null || map == Map.Internal) - { - return null; - } - - if (m_AcquireTable == null) - { - m_AcquireTable = new Dictionary(); - - for (var i = 0; i < m_ContentTypes.Length; ++i) - { - var fill = m_ContentTypes[i]; - - for (var j = 0; j < fill.Vendors.Length; ++j) - { - m_AcquireTable[fill.Vendors[j]] = fill; - } - } - } - - Mobile nearest = null; - FillableContent content = null; - - foreach (var mob in map.GetMobilesInRange(loc, 20)) - { - if (nearest != null && mob.GetDistanceToSqrt(loc) > nearest.GetDistanceToSqrt(loc) && - !(nearest is Cobbler && mob is Provisioner)) - { - continue; - } - - if (m_AcquireTable.TryGetValue(mob.GetType(), out var check)) - { - nearest = mob; - content = check; - } - } - - return content; - } - } -} diff --git a/Projects/UOContent/Migrations/Server.Items.FillableBarrel.v0.json b/Projects/UOContent/Migrations/Server.Items.FillableBarrel.v0.json new file mode 100644 index 000000000..755fca3f0 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.FillableBarrel.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.FillableBarrel" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.FillableContainer.v2.json b/Projects/UOContent/Migrations/Server.Items.FillableContainer.v2.json new file mode 100644 index 000000000..bb0c8c156 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.FillableContainer.v2.json @@ -0,0 +1,19 @@ +{ + "version": 2, + "type": "Server.Items.FillableContainer", + "properties": [ + { + "name": "RawContentType", + "type": "Server.Items.FillableContentType", + "rule": "EnumMigrationRule" + }, + { + "name": "RespawnTimer", + "type": "Server.Timer", + "rule": "TimerMigrationRule", + "ruleArguments": [ + "@TimerDrift" + ] + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.FillableLargeCrate.v0.json b/Projects/UOContent/Migrations/Server.Items.FillableLargeCrate.v0.json new file mode 100644 index 000000000..55a56b0dc --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.FillableLargeCrate.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.FillableLargeCrate" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.FillableMetalBox.v0.json b/Projects/UOContent/Migrations/Server.Items.FillableMetalBox.v0.json new file mode 100644 index 000000000..7a1fc83d4 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.FillableMetalBox.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.FillableMetalBox" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.FillableMetalChest.v0.json b/Projects/UOContent/Migrations/Server.Items.FillableMetalChest.v0.json new file mode 100644 index 000000000..43282f2ba --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.FillableMetalChest.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.FillableMetalChest" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.FillableMetalGoldenChest.v0.json b/Projects/UOContent/Migrations/Server.Items.FillableMetalGoldenChest.v0.json new file mode 100644 index 000000000..c96422f5f --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.FillableMetalGoldenChest.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.FillableMetalGoldenChest" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.FillableSmallCrate.v0.json b/Projects/UOContent/Migrations/Server.Items.FillableSmallCrate.v0.json new file mode 100644 index 000000000..ad9907a95 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.FillableSmallCrate.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.FillableSmallCrate" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.FillableWoodenBox.v0.json b/Projects/UOContent/Migrations/Server.Items.FillableWoodenBox.v0.json new file mode 100644 index 000000000..c81a4abf8 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.FillableWoodenBox.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.FillableWoodenBox" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.FillableWoodenChest.v0.json b/Projects/UOContent/Migrations/Server.Items.FillableWoodenChest.v0.json new file mode 100644 index 000000000..ec2d74b8d --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.FillableWoodenChest.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.FillableWoodenChest" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.LibraryBookcase.v0.json b/Projects/UOContent/Migrations/Server.Items.LibraryBookcase.v0.json new file mode 100644 index 000000000..3c1812b6f --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.LibraryBookcase.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.LibraryBookcase" +} \ No newline at end of file From 864440a05e57da1b09d72ce53acacebc455f147a Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Mon, 13 Jun 2022 01:48:27 -0700 Subject: [PATCH 188/213] fix: Source generates food. (#1054) --- .../UOContent/Items/Food/BeverageEmpty.cs | 65 +- Projects/UOContent/Items/Food/Bowls.cs | 806 +++------ .../UOContent/Items/Food/Chocolatiering.cs | 367 ++-- Projects/UOContent/Items/Food/CookableFood.cs | 966 +++------- Projects/UOContent/Items/Food/Cooking.cs | 631 ++----- Projects/UOContent/Items/Food/Food.cs | 1577 +++++------------ Projects/UOContent/Items/Food/Fruits.cs | 771 +++----- Projects/UOContent/Items/Food/Vegetables.cs | 254 +-- .../Migrations/Server.Items.Apple.v0.json | 4 + .../Migrations/Server.Items.ApplePie.v0.json | 4 + .../Migrations/Server.Items.Bacon.v0.json | 4 + .../Migrations/Server.Items.Banana.v0.json | 4 + .../Migrations/Server.Items.Bananas.v0.json | 4 + .../Migrations/Server.Items.BowlFlour.v0.json | 4 + .../Migrations/Server.Items.BreadLoaf.v0.json | 4 + .../Server.Items.BrightlyColoredEggs.v0.json | 4 + .../Migrations/Server.Items.Cabbage.v0.json | 4 + .../Migrations/Server.Items.Cake.v0.json | 4 + .../Migrations/Server.Items.CakeMix.v0.json | 4 + .../Server.Items.Cantaloupe.v0.json | 4 + .../Migrations/Server.Items.Carrot.v0.json | 4 + .../Server.Items.CheesePizza.v0.json | 4 + .../Server.Items.CheeseSlice.v0.json | 4 + .../Server.Items.CheeseWedge.v0.json | 4 + .../Server.Items.CheeseWheel.v0.json | 4 + .../Server.Items.ChickenLeg.v0.json | 4 + .../Server.Items.CocoaButter.v0.json | 4 + .../Server.Items.CocoaLiquor.v0.json | 4 + .../Migrations/Server.Items.CocoaPulp.v0.json | 4 + .../Migrations/Server.Items.Coconut.v0.json | 4 + .../Server.Items.CookableFood.v0.json | 14 + .../Server.Items.CookedBird.v0.json | 4 + .../Migrations/Server.Items.CookieMix.v0.json | 4 + .../Migrations/Server.Items.Cookies.v0.json | 4 + .../Server.Items.DarkChocolate.v0.json | 4 + .../Migrations/Server.Items.Dates.v0.json | 4 + .../Migrations/Server.Items.Dough.v0.json | 4 + .../Migrations/Server.Items.EarOfCorn.v0.json | 4 + .../Server.Items.EasterEggs.v0.json | 4 + .../Migrations/Server.Items.Eggs.v0.json | 4 + .../Migrations/Server.Items.Eggshells.v0.json | 4 + .../Server.Items.EmptyPewterBowl.v0.json | 4 + .../Server.Items.EmptyPewterTub.v0.json | 4 + .../Server.Items.EmptyWoodenBowl.v0.json | 4 + .../Server.Items.EmptyWoodenTub.v0.json | 4 + .../Migrations/Server.Items.FishSteak.v0.json | 4 + .../Migrations/Server.Items.Food.v0.json | 27 + .../Server.Items.FrenchBread.v0.json | 4 + .../Migrations/Server.Items.FriedEggs.v0.json | 4 + .../Server.Items.FruitBasket.v0.json | 4 + .../Migrations/Server.Items.FruitPie.v0.json | 4 + .../Migrations/Server.Items.Glass.v0.json | 4 + .../Server.Items.GlassBottle.v0.json | 4 + .../Migrations/Server.Items.Grapes.v0.json | 4 + .../Server.Items.GreenGourd.v0.json | 4 + .../Migrations/Server.Items.Ham.v0.json | 4 + .../Server.Items.HoneydewMelon.v0.json | 4 + .../Migrations/Server.Items.JarHoney.v0.json | 4 + .../Migrations/Server.Items.LambLeg.v0.json | 4 + .../Migrations/Server.Items.Lemon.v0.json | 4 + .../Migrations/Server.Items.Lemons.v0.json | 4 + .../Migrations/Server.Items.Lettuce.v0.json | 4 + .../Migrations/Server.Items.Lime.v0.json | 4 + .../Migrations/Server.Items.Limes.v0.json | 4 + .../Migrations/Server.Items.MeatPie.v0.json | 4 + .../Server.Items.MilkChocolate.v0.json | 4 + .../Migrations/Server.Items.Muffins.v0.json | 4 + .../Migrations/Server.Items.Onion.v0.json | 4 + .../Server.Items.OpenCoconut.v0.json | 4 + .../Migrations/Server.Items.Peach.v0.json | 4 + .../Server.Items.PeachCobbler.v0.json | 4 + .../Migrations/Server.Items.Pear.v0.json | 4 + .../Server.Items.PewterBowlOfCarrots.v0.json | 4 + .../Server.Items.PewterBowlOfCorn.v0.json | 4 + .../Server.Items.PewterBowlOfLettuce.v0.json | 4 + .../Server.Items.PewterBowlOfPeas.v0.json | 4 + .../Server.Items.PewterBowlOfPotatos.v0.json | 4 + .../Migrations/Server.Items.Pumpkin.v0.json | 4 + .../Server.Items.PumpkinPie.v0.json | 4 + .../Migrations/Server.Items.Quiche.v0.json | 4 + .../Migrations/Server.Items.RawBird.v0.json | 4 + .../Server.Items.RawChickenLeg.v0.json | 4 + .../Server.Items.RawFishSteak.v0.json | 4 + .../Server.Items.RawLambLeg.v0.json | 4 + .../Migrations/Server.Items.RawRibs.v0.json | 4 + .../Migrations/Server.Items.Ribs.v0.json | 4 + .../Migrations/Server.Items.RoastPig.v0.json | 4 + .../Migrations/Server.Items.SackFlour.v0.json | 14 + .../Server.Items.SackOfSugar.v0.json | 4 + .../Migrations/Server.Items.Sausage.v0.json | 4 + .../Server.Items.SausagePizza.v0.json | 4 + .../Server.Items.SheafOfHay.v0.json | 4 + .../Server.Items.SlabOfBacon.v0.json | 4 + .../Server.Items.SmallPumpkin.v0.json | 4 + .../Server.Items.SmallWatermelon.v0.json | 4 + .../Server.Items.SplitCoconut.v0.json | 4 + .../Migrations/Server.Items.Squash.v0.json | 4 + .../Server.Items.SweetDough.v0.json | 4 + .../Migrations/Server.Items.Turnip.v0.json | 4 + .../Server.Items.UnbakedApplePie.v0.json | 4 + .../Server.Items.UnbakedFruitPie.v0.json | 4 + .../Server.Items.UnbakedMeatPie.v0.json | 4 + .../Server.Items.UnbakedPeachCobbler.v0.json | 4 + .../Server.Items.UnbakedPumpkinPie.v0.json | 4 + .../Server.Items.UnbakedQuiche.v0.json | 4 + .../Server.Items.UncookedCheesePizza.v0.json | 4 + .../Server.Items.UncookedSausagePizza.v0.json | 4 + .../Migrations/Server.Items.Vanilla.v0.json | 4 + .../Server.Items.Watermelon.v0.json | 4 + .../Server.Items.WheatSheaf.v0.json | 4 + .../Server.Items.WhiteChocolate.v0.json | 4 + .../Server.Items.WoodenBowl.v0.json | 4 + .../Server.Items.WoodenBowlOfCarrots.v0.json | 4 + .../Server.Items.WoodenBowlOfCorn.v0.json | 4 + .../Server.Items.WoodenBowlOfLettuce.v0.json | 4 + .../Server.Items.WoodenBowlOfPeas.v0.json | 4 + .../Server.Items.WoodenBowlOfStew.v0.json | 4 + ...erver.Items.WoodenBowlOfTomatoSoup.v0.json | 4 + .../Server.Items.YellowGourd.v0.json | 4 + 119 files changed, 2034 insertions(+), 3890 deletions(-) create mode 100644 Projects/UOContent/Migrations/Server.Items.Apple.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.ApplePie.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Bacon.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Banana.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Bananas.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.BowlFlour.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.BreadLoaf.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.BrightlyColoredEggs.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Cabbage.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Cake.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.CakeMix.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Cantaloupe.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Carrot.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.CheesePizza.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.CheeseSlice.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.CheeseWedge.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.CheeseWheel.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.ChickenLeg.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.CocoaButter.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.CocoaLiquor.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.CocoaPulp.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Coconut.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.CookableFood.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.CookedBird.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.CookieMix.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Cookies.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.DarkChocolate.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Dates.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Dough.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.EarOfCorn.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.EasterEggs.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Eggs.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Eggshells.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.EmptyPewterBowl.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.EmptyPewterTub.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.EmptyWoodenBowl.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.EmptyWoodenTub.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.FishSteak.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Food.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.FrenchBread.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.FriedEggs.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.FruitBasket.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.FruitPie.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Glass.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.GlassBottle.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Grapes.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.GreenGourd.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Ham.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.HoneydewMelon.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.JarHoney.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.LambLeg.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Lemon.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Lemons.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Lettuce.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Lime.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Limes.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.MeatPie.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.MilkChocolate.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Muffins.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Onion.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.OpenCoconut.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Peach.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.PeachCobbler.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Pear.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.PewterBowlOfCarrots.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.PewterBowlOfCorn.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.PewterBowlOfLettuce.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.PewterBowlOfPeas.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.PewterBowlOfPotatos.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Pumpkin.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.PumpkinPie.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Quiche.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.RawBird.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.RawChickenLeg.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.RawFishSteak.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.RawLambLeg.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.RawRibs.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Ribs.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.RoastPig.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.SackFlour.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.SackOfSugar.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Sausage.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.SausagePizza.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.SheafOfHay.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.SlabOfBacon.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.SmallPumpkin.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.SmallWatermelon.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.SplitCoconut.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Squash.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.SweetDough.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Turnip.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.UnbakedApplePie.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.UnbakedFruitPie.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.UnbakedMeatPie.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.UnbakedPeachCobbler.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.UnbakedPumpkinPie.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.UnbakedQuiche.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.UncookedCheesePizza.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.UncookedSausagePizza.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Vanilla.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Watermelon.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.WheatSheaf.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.WhiteChocolate.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.WoodenBowl.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.WoodenBowlOfCarrots.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.WoodenBowlOfCorn.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.WoodenBowlOfLettuce.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.WoodenBowlOfPeas.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.WoodenBowlOfStew.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.WoodenBowlOfTomatoSoup.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.YellowGourd.v0.json diff --git a/Projects/UOContent/Items/Food/BeverageEmpty.cs b/Projects/UOContent/Items/Food/BeverageEmpty.cs index fb75dad41..317635af0 100644 --- a/Projects/UOContent/Items/Food/BeverageEmpty.cs +++ b/Projects/UOContent/Items/Food/BeverageEmpty.cs @@ -1,51 +1,18 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[Flippable(0x1f81, 0x1f82, 0x1f83, 0x1f84)] +[SerializationGenerator(0, false)] +public partial class Glass : Item { - [Flippable(0x1f81, 0x1f82, 0x1f83, 0x1f84)] - public class Glass : Item - { - [Constructible] - public Glass() : base(0x1f81) => Weight = 0.1; - - public Glass(Serial serial) : base(serial) - { - } - - 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 GlassBottle : Item - { - [Constructible] - public GlassBottle() : base(0xe2b) => Weight = 0.3; - - public GlassBottle(Serial serial) : base(serial) - { - } - - 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(); - } - } + [Constructible] + public Glass() : base(0x1f81) => Weight = 0.1; +} + +[SerializationGenerator(0, false)] +public partial class GlassBottle : Item +{ + [Constructible] + public GlassBottle() : base(0xe2b) => Weight = 0.3; } diff --git a/Projects/UOContent/Items/Food/Bowls.cs b/Projects/UOContent/Items/Food/Bowls.cs index b5b98522a..f080b6d62 100644 --- a/Projects/UOContent/Items/Food/Bowls.cs +++ b/Projects/UOContent/Items/Food/Bowls.cs @@ -1,540 +1,286 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class EmptyWoodenBowl : Item { - public class EmptyWoodenBowl : Item + [Constructible] + public EmptyWoodenBowl() : base(0x15F8) => Weight = 1.0; +} + +[SerializationGenerator(0, false)] +public partial class EmptyPewterBowl : Item +{ + [Constructible] + public EmptyPewterBowl() : base(0x15FD) => Weight = 1.0; +} + +[SerializationGenerator(0, false)] +public partial class WoodenBowlOfCarrots : Food +{ + [Constructible] + public WoodenBowlOfCarrots() : base(0x15F9) { - [Constructible] - public EmptyWoodenBowl() : base(0x15F8) => Weight = 1.0; - - public EmptyWoodenBowl(Serial serial) : base(serial) - { - } - - 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(); - } + Stackable = false; + Weight = 1.0; + FillFactor = 2; } - public class EmptyPewterBowl : Item + public override bool Eat(Mobile from) { - [Constructible] - public EmptyPewterBowl() : base(0x15FD) => Weight = 1.0; - - public EmptyPewterBowl(Serial serial) : base(serial) + if (!base.Eat(from)) { + return false; } - 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 WoodenBowlOfCarrots : Food - { - [Constructible] - public WoodenBowlOfCarrots() : base(0x15F9) - { - Stackable = false; - Weight = 1.0; - FillFactor = 2; - } - - public WoodenBowlOfCarrots(Serial serial) : base(serial) - { - } - - public override bool Eat(Mobile from) - { - if (!base.Eat(from)) - { - return false; - } - - from.AddToBackpack(new EmptyWoodenBowl()); - return 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 WoodenBowlOfCorn : Food - { - [Constructible] - public WoodenBowlOfCorn() : base(0x15FA) - { - Stackable = false; - Weight = 1.0; - FillFactor = 2; - } - - public WoodenBowlOfCorn(Serial serial) : base(serial) - { - } - - public override bool Eat(Mobile from) - { - if (!base.Eat(from)) - { - return false; - } - - from.AddToBackpack(new EmptyWoodenBowl()); - return 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 WoodenBowlOfLettuce : Food - { - [Constructible] - public WoodenBowlOfLettuce() : base(0x15FB) - { - Stackable = false; - Weight = 1.0; - FillFactor = 2; - } - - public WoodenBowlOfLettuce(Serial serial) : base(serial) - { - } - - public override bool Eat(Mobile from) - { - if (!base.Eat(from)) - { - return false; - } - - from.AddToBackpack(new EmptyWoodenBowl()); - return 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 WoodenBowlOfPeas : Food - { - [Constructible] - public WoodenBowlOfPeas() : base(0x15FC) - { - Stackable = false; - Weight = 1.0; - FillFactor = 2; - } - - public WoodenBowlOfPeas(Serial serial) : base(serial) - { - } - - public override bool Eat(Mobile from) - { - if (!base.Eat(from)) - { - return false; - } - - from.AddToBackpack(new EmptyWoodenBowl()); - return 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 PewterBowlOfCarrots : Food - { - [Constructible] - public PewterBowlOfCarrots() : base(0x15FE) - { - Stackable = false; - Weight = 1.0; - FillFactor = 2; - } - - public PewterBowlOfCarrots(Serial serial) : base(serial) - { - } - - public override bool Eat(Mobile from) - { - if (!base.Eat(from)) - { - return false; - } - - from.AddToBackpack(new EmptyPewterBowl()); - return 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 PewterBowlOfCorn : Food - { - [Constructible] - public PewterBowlOfCorn() : base(0x15FF) - { - Stackable = false; - Weight = 1.0; - FillFactor = 2; - } - - public PewterBowlOfCorn(Serial serial) : base(serial) - { - } - - public override bool Eat(Mobile from) - { - if (!base.Eat(from)) - { - return false; - } - - from.AddToBackpack(new EmptyPewterBowl()); - return 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 PewterBowlOfLettuce : Food - { - [Constructible] - public PewterBowlOfLettuce() : base(0x1600) - { - Stackable = false; - Weight = 1.0; - FillFactor = 2; - } - - public PewterBowlOfLettuce(Serial serial) : base(serial) - { - } - - public override bool Eat(Mobile from) - { - if (!base.Eat(from)) - { - return false; - } - - from.AddToBackpack(new EmptyPewterBowl()); - return 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 PewterBowlOfPeas : Food - { - [Constructible] - public PewterBowlOfPeas() : base(0x1601) - { - Stackable = false; - Weight = 1.0; - FillFactor = 2; - } - - public PewterBowlOfPeas(Serial serial) : base(serial) - { - } - - public override bool Eat(Mobile from) - { - if (!base.Eat(from)) - { - return false; - } - - from.AddToBackpack(new EmptyPewterBowl()); - return 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 PewterBowlOfPotatos : Food - { - [Constructible] - public PewterBowlOfPotatos() : base(0x1602) - { - Stackable = false; - Weight = 1.0; - FillFactor = 2; - } - - public PewterBowlOfPotatos(Serial serial) : base(serial) - { - } - - public override bool Eat(Mobile from) - { - if (!base.Eat(from)) - { - return false; - } - - from.AddToBackpack(new EmptyPewterBowl()); - return 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(); - } - } - - [TypeAlias("Server.Items.EmptyLargeWoodenBowl")] - public class EmptyWoodenTub : Item - { - [Constructible] - public EmptyWoodenTub() : base(0x1605) => Weight = 2.0; - - public EmptyWoodenTub(Serial serial) : base(serial) - { - } - - 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(); - } - } - - [TypeAlias("Server.Items.EmptyLargePewterBowl")] - public class EmptyPewterTub : Item - { - [Constructible] - public EmptyPewterTub() : base(0x1603) => Weight = 2.0; - - public EmptyPewterTub(Serial serial) : base(serial) - { - } - - 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 WoodenBowlOfStew : Food - { - [Constructible] - public WoodenBowlOfStew() : base(0x1604) - { - Stackable = false; - Weight = 2.0; - FillFactor = 2; - } - - public WoodenBowlOfStew(Serial serial) : base(serial) - { - } - - public override bool Eat(Mobile from) - { - if (!base.Eat(from)) - { - return false; - } - - from.AddToBackpack(new EmptyWoodenTub()); - return 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 WoodenBowlOfTomatoSoup : Food - { - [Constructible] - public WoodenBowlOfTomatoSoup() : base(0x1606) - { - Stackable = false; - Weight = 2.0; - FillFactor = 2; - } - - public WoodenBowlOfTomatoSoup(Serial serial) : base(serial) - { - } - - public override bool Eat(Mobile from) - { - if (!base.Eat(from)) - { - return false; - } - - from.AddToBackpack(new EmptyWoodenTub()); - return 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(); - } + from.AddToBackpack(new EmptyWoodenBowl()); + return true; + } +} + +[SerializationGenerator(0, false)] +public partial class WoodenBowlOfCorn : Food +{ + [Constructible] + public WoodenBowlOfCorn() : base(0x15FA) + { + Stackable = false; + Weight = 1.0; + FillFactor = 2; + } + + public override bool Eat(Mobile from) + { + if (!base.Eat(from)) + { + return false; + } + + from.AddToBackpack(new EmptyWoodenBowl()); + return true; + } +} + +[SerializationGenerator(0, false)] +public partial class WoodenBowlOfLettuce : Food +{ + [Constructible] + public WoodenBowlOfLettuce() : base(0x15FB) + { + Stackable = false; + Weight = 1.0; + FillFactor = 2; + } + + public override bool Eat(Mobile from) + { + if (!base.Eat(from)) + { + return false; + } + + from.AddToBackpack(new EmptyWoodenBowl()); + return true; + } +} + +[SerializationGenerator(0, false)] +public partial class WoodenBowlOfPeas : Food +{ + [Constructible] + public WoodenBowlOfPeas() : base(0x15FC) + { + Stackable = false; + Weight = 1.0; + FillFactor = 2; + } + + public override bool Eat(Mobile from) + { + if (!base.Eat(from)) + { + return false; + } + + from.AddToBackpack(new EmptyWoodenBowl()); + return true; + } +} + +[SerializationGenerator(0, false)] +public partial class PewterBowlOfCarrots : Food +{ + [Constructible] + public PewterBowlOfCarrots() : base(0x15FE) + { + Stackable = false; + Weight = 1.0; + FillFactor = 2; + } + + public override bool Eat(Mobile from) + { + if (!base.Eat(from)) + { + return false; + } + + from.AddToBackpack(new EmptyPewterBowl()); + return true; + } +} + +[SerializationGenerator(0, false)] +public partial class PewterBowlOfCorn : Food +{ + [Constructible] + public PewterBowlOfCorn() : base(0x15FF) + { + Stackable = false; + Weight = 1.0; + FillFactor = 2; + } + + public override bool Eat(Mobile from) + { + if (!base.Eat(from)) + { + return false; + } + + from.AddToBackpack(new EmptyPewterBowl()); + return true; + } +} + +[SerializationGenerator(0, false)] +public partial class PewterBowlOfLettuce : Food +{ + [Constructible] + public PewterBowlOfLettuce() : base(0x1600) + { + Stackable = false; + Weight = 1.0; + FillFactor = 2; + } + + public override bool Eat(Mobile from) + { + if (!base.Eat(from)) + { + return false; + } + + from.AddToBackpack(new EmptyPewterBowl()); + return true; + } +} + +[SerializationGenerator(0, false)] +public partial class PewterBowlOfPeas : Food +{ + [Constructible] + public PewterBowlOfPeas() : base(0x1601) + { + Stackable = false; + Weight = 1.0; + FillFactor = 2; + } + + public override bool Eat(Mobile from) + { + if (!base.Eat(from)) + { + return false; + } + + from.AddToBackpack(new EmptyPewterBowl()); + return true; + } +} + +[SerializationGenerator(0, false)] +public partial class PewterBowlOfPotatos : Food +{ + [Constructible] + public PewterBowlOfPotatos() : base(0x1602) + { + Stackable = false; + Weight = 1.0; + FillFactor = 2; + } + + public override bool Eat(Mobile from) + { + if (!base.Eat(from)) + { + return false; + } + + from.AddToBackpack(new EmptyPewterBowl()); + return true; + } +} + +[TypeAlias("Server.Items.EmptyLargeWoodenBowl")] +[SerializationGenerator(0, false)] +public partial class EmptyWoodenTub : Item +{ + [Constructible] + public EmptyWoodenTub() : base(0x1605) => Weight = 2.0; +} + +[TypeAlias("Server.Items.EmptyLargePewterBowl")] +[SerializationGenerator(0, false)] +public partial class EmptyPewterTub : Item +{ + [Constructible] + public EmptyPewterTub() : base(0x1603) => Weight = 2.0; +} + +[SerializationGenerator(0, false)] +public partial class WoodenBowlOfStew : Food +{ + [Constructible] + public WoodenBowlOfStew() : base(0x1604) + { + Stackable = false; + Weight = 2.0; + FillFactor = 2; + } + + public override bool Eat(Mobile from) + { + if (!base.Eat(from)) + { + return false; + } + + from.AddToBackpack(new EmptyWoodenTub()); + return true; + } +} + +[SerializationGenerator(0, false)] +public partial class WoodenBowlOfTomatoSoup : Food +{ + [Constructible] + public WoodenBowlOfTomatoSoup() : base(0x1606) + { + Stackable = false; + Weight = 2.0; + FillFactor = 2; + } + + public override bool Eat(Mobile from) + { + if (!base.Eat(from)) + { + return false; + } + + from.AddToBackpack(new EmptyWoodenTub()); + return true; } } diff --git a/Projects/UOContent/Items/Food/Chocolatiering.cs b/Projects/UOContent/Items/Food/Chocolatiering.cs index 90dd2b640..af588e5a7 100644 --- a/Projects/UOContent/Items/Food/Chocolatiering.cs +++ b/Projects/UOContent/Items/Food/Chocolatiering.cs @@ -1,263 +1,110 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class CocoaLiquor : Item { - public class CocoaLiquor : Item - { - [Constructible] - public CocoaLiquor() - : base(0x103F) => - Hue = 0x46A; + [Constructible] + public CocoaLiquor() : base(0x103F) => Hue = 0x46A; - public CocoaLiquor(Serial serial) - : base(serial) - { - } - - public override int LabelNumber => 1080007; // Cocoa liquor - public override double DefaultWeight => 1.0; - - 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 SackOfSugar : Item - { - [Constructible] - public SackOfSugar(int amount = 1) - : base(0x1039) - { - Hue = 0x461; - Stackable = true; - Amount = amount; - } - - public SackOfSugar(Serial serial) - : base(serial) - { - } - - public override int LabelNumber => 1080003; // Sack of sugar - public override double DefaultWeight => 1.0; - - 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 CocoaButter : Item - { - [Constructible] - public CocoaButter() - : base(0x1044) => - Hue = 0x457; - - public CocoaButter(Serial serial) - : base(serial) - { - } - - public override int LabelNumber => 1080005; // Cocoa butter - public override double DefaultWeight => 1.0; - - 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 Vanilla : Item - { - [Constructible] - public Vanilla(int amount = 1) - : base(0xE2A) - { - Hue = 0x462; - Stackable = true; - Amount = amount; - } - - public Vanilla(Serial serial) - : base(serial) - { - } - - public override int LabelNumber => 1080009; // Vanilla - public override double DefaultWeight => 1.0; - - 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 CocoaPulp : Item - { - [Constructible] - public CocoaPulp(int amount = 1) - : base(0xF7C) - { - Hue = 0x219; - Stackable = true; - Amount = amount; - } - - public CocoaPulp(Serial serial) - : base(serial) - { - } - - public override int LabelNumber => 1080530; // cocoa pulp - public override double DefaultWeight => 1.0; - - 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 DarkChocolate : CandyCane - { - [Constructible] - public DarkChocolate() - : base(0xF10) - { - Hue = 0x465; - LootType = LootType.Regular; - } - - public DarkChocolate(Serial serial) - : base(serial) - { - } - - public override int LabelNumber => 1079994; // Dark chocolate - public override double DefaultWeight => 1.0; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } - - public class MilkChocolate : CandyCane - { - [Constructible] - public MilkChocolate() - : base(0xF18) - { - Hue = 0x461; - LootType = LootType.Regular; - } - - public MilkChocolate(Serial serial) - : base(serial) - { - } - - public override int LabelNumber => 1079995; // Milk chocolate - public override double DefaultWeight => 1.0; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } - - public class WhiteChocolate : CandyCane - { - [Constructible] - public WhiteChocolate() - : base(0xF11) - { - Hue = 0x47E; - LootType = LootType.Regular; - } - - public WhiteChocolate(Serial serial) - : base(serial) - { - } - - public override int LabelNumber => 1079996; // White chocolate - public override double DefaultWeight => 1.0; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } + public override int LabelNumber => 1080007; // Cocoa liquor + public override double DefaultWeight => 1.0; +} + +[SerializationGenerator(0, false)] +public partial class SackOfSugar : Item +{ + [Constructible] + public SackOfSugar(int amount = 1) : base(0x1039) + { + Hue = 0x461; + Stackable = true; + Amount = amount; + } + + public override int LabelNumber => 1080003; // Sack of sugar + public override double DefaultWeight => 1.0; +} + +[SerializationGenerator(0, false)] +public partial class CocoaButter : Item +{ + [Constructible] + public CocoaButter() : base(0x1044) => Hue = 0x457; + + public override int LabelNumber => 1080005; // Cocoa butter + public override double DefaultWeight => 1.0; +} + +[SerializationGenerator(0, false)] +public partial class Vanilla : Item +{ + [Constructible] + public Vanilla(int amount = 1) : base(0xE2A) + { + Hue = 0x462; + Stackable = true; + Amount = amount; + } + + public override int LabelNumber => 1080009; // Vanilla + public override double DefaultWeight => 1.0; +} + +[SerializationGenerator(0, false)] +public partial class CocoaPulp : Item +{ + [Constructible] + public CocoaPulp(int amount = 1) : base(0xF7C) + { + Hue = 0x219; + Stackable = true; + Amount = amount; + } + + public override int LabelNumber => 1080530; // cocoa pulp + public override double DefaultWeight => 1.0; +} + +[SerializationGenerator(0, false)] +public partial class DarkChocolate : CandyCane +{ + [Constructible] + public DarkChocolate() : base(0xF10) + { + Hue = 0x465; + LootType = LootType.Regular; + } + + public override int LabelNumber => 1079994; // Dark chocolate + public override double DefaultWeight => 1.0; +} + +[SerializationGenerator(0, false)] +public partial class MilkChocolate : CandyCane +{ + [Constructible] + public MilkChocolate() : base(0xF18) + { + Hue = 0x461; + LootType = LootType.Regular; + } + + public override int LabelNumber => 1079995; // Milk chocolate + public override double DefaultWeight => 1.0; +} + +[SerializationGenerator(0, false)] +public partial class WhiteChocolate : CandyCane +{ + [Constructible] + public WhiteChocolate() : base(0xF11) + { + Hue = 0x47E; + LootType = LootType.Regular; + } + + public override int LabelNumber => 1079996; // White chocolate + public override double DefaultWeight => 1.0; } diff --git a/Projects/UOContent/Items/Food/CookableFood.cs b/Projects/UOContent/Items/Food/CookableFood.cs index 0582491b9..d7711abfb 100644 --- a/Projects/UOContent/Items/Food/CookableFood.cs +++ b/Projects/UOContent/Items/Food/CookableFood.cs @@ -1,745 +1,293 @@ -using System; +using ModernUO.Serialization; using Server.Targeting; -namespace Server.Items +namespace Server.Items; + +[SerializationGenerator(0, false)] +public abstract partial class CookableFood : Item { - public abstract class CookableFood : Item + [SerializableField(0)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private int _cookingLevel; + + public CookableFood(int itemID, int cookingLevel) : base(itemID) => _cookingLevel = cookingLevel; + + public abstract Food Cook(); + + public static bool IsHeatSource(object targeted) { - public CookableFood(int itemID, int cookingLevel) : base(itemID) => CookingLevel = cookingLevel; + int itemID; - public CookableFood(Serial serial) : base(serial) + if (targeted is Item item) { + itemID = item.ItemID; } - - [CommandProperty(AccessLevel.GameMaster)] - public int CookingLevel { get; set; } - - public abstract Food Cook(); - - public override void Serialize(IGenericWriter writer) + else if (targeted is StaticTarget target) { - base.Serialize(writer); - - writer.Write(1); // version - // Version 1 - writer.Write(CookingLevel); + itemID = target.ItemID; } - - public override void Deserialize(IGenericReader reader) + else { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - switch (version) - { - case 1: - { - CookingLevel = reader.ReadInt(); - - break; - } - } - } - - public static bool IsHeatSource(object targeted) - { - int itemID; - - if (targeted is Item item) - { - itemID = item.ItemID; - } - else if (targeted is StaticTarget target) - { - itemID = target.ItemID; - } - else - { - return false; - } - - if (itemID >= 0xDE3 && itemID <= 0xDE9) - { - return true; // Campfire - } - - if (itemID >= 0x461 && itemID <= 0x48E) - { - return true; // Sandstone oven/fireplace - } - - if (itemID >= 0x92B && itemID <= 0x96C) - { - return true; // Stone oven/fireplace - } - - if (itemID == 0xFAC) - { - return true; // Firepit - } - - if (itemID >= 0x184A && itemID <= 0x184C) - { - return true; // Heating stand (left) - } - - if (itemID >= 0x184E && itemID <= 0x1850) - { - return true; // Heating stand (right) - } - - if (itemID >= 0x398C && itemID <= 0x399F) - { - return true; // Fire field - } - return false; } - private class InternalTarget : Target + if (itemID >= 0xDE3 && itemID <= 0xDE9) { - private readonly CookableFood m_Item; - - public InternalTarget(CookableFood item) : base(1, false, TargetFlags.None) => m_Item = item; - - protected override void OnTarget(Mobile from, object targeted) - { - if (m_Item.Deleted) - { - return; - } - - if (IsHeatSource(targeted)) - { - if (from.BeginAction()) - { - from.PlaySound(0x225); - - m_Item.Consume(); - - var t = new InternalTimer(from, targeted as IPoint3D, from.Map, m_Item); - t.Start(); - } - else - { - from.SendLocalizedMessage(500119); // You must wait to perform another action - } - } - } - - private class InternalTimer : Timer - { - private readonly CookableFood m_CookableFood; - private readonly Mobile m_From; - private readonly Map m_Map; - private readonly IPoint3D m_Point; - - public InternalTimer(Mobile from, IPoint3D p, Map map, CookableFood cookableFood) : base( - TimeSpan.FromSeconds(5.0) - ) - { - m_From = from; - m_Point = p; - m_Map = map; - m_CookableFood = cookableFood; - } - - protected override void OnTick() - { - m_From.EndAction(); - - if (m_From.Map != m_Map || m_Point != null && m_From.GetDistanceToSqrt(m_Point) > 3) - { - m_From.SendLocalizedMessage(500686); // You burn the food to a crisp! It's ruined. - return; - } - - if (m_From.CheckSkill(SkillName.Cooking, m_CookableFood.CookingLevel, 100)) - { - var cookedFood = m_CookableFood.Cook(); - - if (m_From.AddToBackpack(cookedFood)) - { - m_From.PlaySound(0x57); - } - } - else - { - m_From.SendLocalizedMessage(500686); // You burn the food to a crisp! It's ruined. - } - } - } - } - } - - // ********** RawRibs ********** - public class RawRibs : CookableFood - { - [Constructible] - public RawRibs(int amount = 1) : base(0x9F1, 10) - { - Weight = 1.0; - Stackable = true; - Amount = amount; + return true; // Campfire } - public RawRibs(Serial serial) : base(serial) + if (itemID >= 0x461 && itemID <= 0x48E) { + return true; // Sandstone oven/fireplace } - public override void Serialize(IGenericWriter writer) + if (itemID >= 0x92B && itemID <= 0x96C) { - base.Serialize(writer); - - writer.Write(0); // version + return true; // Stone oven/fireplace } - public override void Deserialize(IGenericReader reader) + if (itemID == 0xFAC) { - base.Deserialize(reader); - - var version = reader.ReadInt(); + return true; // Firepit } - public override Food Cook() => new Ribs(); - } - - // ********** RawLambLeg ********** - public class RawLambLeg : CookableFood - { - [Constructible] - public RawLambLeg(int amount = 1) : base(0x1609, 10) + if (itemID >= 0x184A && itemID <= 0x184C) { - Stackable = true; - Amount = amount; + return true; // Heating stand (left) } - public RawLambLeg(Serial serial) : base(serial) + if (itemID >= 0x184E && itemID <= 0x1850) { + return true; // Heating stand (right) } - public override void Serialize(IGenericWriter writer) + if (itemID >= 0x398C && itemID <= 0x399F) { - base.Serialize(writer); - - writer.Write(1); // version + return true; // Fire field } - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - if (version == 0 && Weight == 1) - { - Weight = -1; - } - } - - public override Food Cook() => new LambLeg(); - } - - // ********** RawChickenLeg ********** - public class RawChickenLeg : CookableFood - { - [Constructible] - public RawChickenLeg() : base(0x1607, 10) - { - Weight = 1.0; - Stackable = true; - } - - public RawChickenLeg(Serial serial) : base(serial) - { - } - - 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 override Food Cook() => new ChickenLeg(); - } - - // ********** RawBird ********** - public class RawBird : CookableFood - { - [Constructible] - public RawBird(int amount = 1) : base(0x9B9, 10) - { - Weight = 1.0; - Stackable = true; - Amount = amount; - } - - public RawBird(Serial serial) : base(serial) - { - } - - 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 override Food Cook() => new CookedBird(); - } - - // ********** UnbakedPeachCobbler ********** - public class UnbakedPeachCobbler : CookableFood - { - [Constructible] - public UnbakedPeachCobbler() : base(0x1042, 25) => Weight = 1.0; - - public UnbakedPeachCobbler(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1041335; // unbaked peach cobbler - - 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 override Food Cook() => new PeachCobbler(); - } - - // ********** UnbakedFruitPie ********** - public class UnbakedFruitPie : CookableFood - { - [Constructible] - public UnbakedFruitPie() : base(0x1042, 25) => Weight = 1.0; - - public UnbakedFruitPie(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1041334; // unbaked fruit pie - - 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 override Food Cook() => new FruitPie(); - } - - // ********** UnbakedMeatPie ********** - public class UnbakedMeatPie : CookableFood - { - [Constructible] - public UnbakedMeatPie() : base(0x1042, 25) => Weight = 1.0; - - public UnbakedMeatPie(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1041338; // unbaked meat pie - - 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 override Food Cook() => new MeatPie(); - } - - // ********** UnbakedPumpkinPie ********** - public class UnbakedPumpkinPie : CookableFood - { - [Constructible] - public UnbakedPumpkinPie() : base(0x1042, 25) => Weight = 1.0; - - public UnbakedPumpkinPie(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1041342; // unbaked pumpkin pie - - 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 override Food Cook() => new PumpkinPie(); - } - - // ********** UnbakedApplePie ********** - public class UnbakedApplePie : CookableFood - { - [Constructible] - public UnbakedApplePie() : base(0x1042, 25) => Weight = 1.0; - - public UnbakedApplePie(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1041336; // unbaked apple pie - - 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 override Food Cook() => new ApplePie(); - } - - // ********** UncookedCheesePizza ********** - [TypeAlias("Server.Items.UncookedPizza")] - public class UncookedCheesePizza : CookableFood - { - [Constructible] - public UncookedCheesePizza() : base(0x1083, 20) => Weight = 1.0; - - public UncookedCheesePizza(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1041341; // uncooked cheese pizza - - 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(); - - if (ItemID == 0x1040) - { - ItemID = 0x1083; - } - - if (Hue == 51) - { - Hue = 0; - } - } - - public override Food Cook() => new CheesePizza(); - } - - // ********** UncookedSausagePizza ********** - public class UncookedSausagePizza : CookableFood - { - [Constructible] - public UncookedSausagePizza() : base(0x1083, 20) => Weight = 1.0; - - public UncookedSausagePizza(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1041337; // uncooked sausage pizza - - 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 override Food Cook() => new SausagePizza(); - } - - // ********** UnbakedQuiche ********** - public class UnbakedQuiche : CookableFood - { - [Constructible] - public UnbakedQuiche() : base(0x1042, 25) => Weight = 1.0; - - public UnbakedQuiche(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1041339; // unbaked quiche - - 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 override Food Cook() => new Quiche(); - } - - // ********** Eggs ********** - public class Eggs : CookableFood - { - [Constructible] - public Eggs(int amount = 1) : base(0x9B5, 15) - { - Weight = 1.0; - Stackable = true; - Amount = amount; - } - - public Eggs(Serial serial) : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(1); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - if (version < 1) - { - Stackable = true; - - if (Weight == 0.5) - { - Weight = 1.0; - } - } - } - - public override Food Cook() => new FriedEggs(); - } - - // ********** BrightlyColoredEggs ********** - public class BrightlyColoredEggs : CookableFood - { - [Constructible] - public BrightlyColoredEggs() : base(0x9B5, 15) - { - Weight = 0.5; - Hue = 3 + Utility.Random(20) * 5; - } - - public BrightlyColoredEggs(Serial serial) : base(serial) - { - } - - public override string DefaultName => "brightly colored eggs"; - - 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 override Food Cook() => new FriedEggs(); - } - - // ********** EasterEggs ********** - public class EasterEggs : CookableFood - { - [Constructible] - public EasterEggs() : base(0x9B5, 15) - { - Weight = 0.5; - Hue = 3 + Utility.Random(20) * 5; - } - - public EasterEggs(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1016105; // Easter Eggs - - 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 override Food Cook() => new FriedEggs(); - } - - // ********** CookieMix ********** - public class CookieMix : CookableFood - { - [Constructible] - public CookieMix() : base(0x103F, 20) => Weight = 1.0; - - public CookieMix(Serial serial) : base(serial) - { - } - - 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 override Food Cook() => new Cookies(); - } - - // ********** CakeMix ********** - public class CakeMix : CookableFood - { - [Constructible] - public CakeMix() : base(0x103F, 40) => Weight = 1.0; - - public CakeMix(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1041002; // cake mix - - 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 override Food Cook() => new Cake(); - } - - public class RawFishSteak : CookableFood - { - [Constructible] - public RawFishSteak(int amount = 1) : base(0x097A, 10) - { - Stackable = true; - Amount = amount; - } - - public RawFishSteak(Serial serial) : base(serial) - { - } - - public override double DefaultWeight => 0.1; - - public override Food Cook() => new FishSteak(); - - 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(); - } + return false; } } + +[SerializationGenerator(0, false)] +public partial class RawRibs : CookableFood +{ + [Constructible] + public RawRibs(int amount = 1) : base(0x9F1, 10) + { + Weight = 1.0; + Stackable = true; + Amount = amount; + } + + public override Food Cook() => new Ribs(); +} + +[SerializationGenerator(0, false)] +public partial class RawLambLeg : CookableFood +{ + [Constructible] + public RawLambLeg(int amount = 1) : base(0x1609, 10) + { + Stackable = true; + Amount = amount; + } + + public override Food Cook() => new LambLeg(); +} + +[SerializationGenerator(0, false)] +public partial class RawChickenLeg : CookableFood +{ + [Constructible] + public RawChickenLeg() : base(0x1607, 10) + { + Weight = 1.0; + Stackable = true; + } + + public override Food Cook() => new ChickenLeg(); +} + +[SerializationGenerator(0, false)] +public partial class RawBird : CookableFood +{ + [Constructible] + public RawBird(int amount = 1) : base(0x9B9, 10) + { + Weight = 1.0; + Stackable = true; + Amount = amount; + } + + public override Food Cook() => new CookedBird(); +} + +[SerializationGenerator(0, false)] +public partial class UnbakedPeachCobbler : CookableFood +{ + [Constructible] + public UnbakedPeachCobbler() : base(0x1042, 25) => Weight = 1.0; + + public override int LabelNumber => 1041335; // unbaked peach cobbler + + public override Food Cook() => new PeachCobbler(); +} + +[SerializationGenerator(0, false)] +public partial class UnbakedFruitPie : CookableFood +{ + [Constructible] + public UnbakedFruitPie() : base(0x1042, 25) => Weight = 1.0; + + public override int LabelNumber => 1041334; // unbaked fruit pie + + public override Food Cook() => new FruitPie(); +} + +[SerializationGenerator(0, false)] +public partial class UnbakedMeatPie : CookableFood +{ + [Constructible] + public UnbakedMeatPie() : base(0x1042, 25) => Weight = 1.0; + + public override int LabelNumber => 1041338; // unbaked meat pie + + public override Food Cook() => new MeatPie(); +} + +[SerializationGenerator(0, false)] +public partial class UnbakedPumpkinPie : CookableFood +{ + [Constructible] + public UnbakedPumpkinPie() : base(0x1042, 25) => Weight = 1.0; + + public override int LabelNumber => 1041342; // unbaked pumpkin pie + + public override Food Cook() => new PumpkinPie(); +} + +[SerializationGenerator(0, false)] +public partial class UnbakedApplePie : CookableFood +{ + [Constructible] + public UnbakedApplePie() : base(0x1042, 25) => Weight = 1.0; + + public override int LabelNumber => 1041336; // unbaked apple pie + + public override Food Cook() => new ApplePie(); +} + +[TypeAlias("Server.Items.UncookedPizza")] +[SerializationGenerator(0, false)] +public partial class UncookedCheesePizza : CookableFood +{ + [Constructible] + public UncookedCheesePizza() : base(0x1083, 20) => Weight = 1.0; + + public override int LabelNumber => 1041341; // uncooked cheese pizza + + public override Food Cook() => new CheesePizza(); +} + +[SerializationGenerator(0, false)] +public partial class UncookedSausagePizza : CookableFood +{ + [Constructible] + public UncookedSausagePizza() : base(0x1083, 20) => Weight = 1.0; + + public override int LabelNumber => 1041337; // uncooked sausage pizza + + public override Food Cook() => new SausagePizza(); +} + +[SerializationGenerator(0, false)] +public partial class UnbakedQuiche : CookableFood +{ + [Constructible] + public UnbakedQuiche() : base(0x1042, 25) => Weight = 1.0; + + public override int LabelNumber => 1041339; // unbaked quiche + + public override Food Cook() => new Quiche(); +} + +[SerializationGenerator(0, false)] +public partial class Eggs : CookableFood +{ + [Constructible] + public Eggs(int amount = 1) : base(0x9B5, 15) + { + Weight = 1.0; + Stackable = true; + Amount = amount; + } + + public override Food Cook() => new FriedEggs(); +} + +[SerializationGenerator(0, false)] +public partial class BrightlyColoredEggs : CookableFood +{ + [Constructible] + public BrightlyColoredEggs() : base(0x9B5, 15) + { + Weight = 0.5; + Hue = 3 + Utility.Random(20) * 5; + } + + public override string DefaultName => "brightly colored eggs"; + + public override Food Cook() => new FriedEggs(); +} + +[SerializationGenerator(0, false)] +public partial class EasterEggs : CookableFood +{ + [Constructible] + public EasterEggs() : base(0x9B5, 15) + { + Weight = 0.5; + Hue = 3 + Utility.Random(20) * 5; + } + + public override int LabelNumber => 1016105; // Easter Eggs + + public override Food Cook() => new FriedEggs(); +} + +[SerializationGenerator(0, false)] +public partial class CookieMix : CookableFood +{ + [Constructible] + public CookieMix() : base(0x103F, 20) => Weight = 1.0; + + public override Food Cook() => new Cookies(); +} + +[SerializationGenerator(0, false)] +public partial class CakeMix : CookableFood +{ + [Constructible] + public CakeMix() : base(0x103F, 40) => Weight = 1.0; + + public override int LabelNumber => 1041002; // cake mix + + public override Food Cook() => new Cake(); +} + +[SerializationGenerator(0, false)] +public partial class RawFishSteak : CookableFood +{ + [Constructible] + public RawFishSteak(int amount = 1) : base(0x097A, 10) + { + Stackable = true; + Amount = amount; + } + + public override double DefaultWeight => 0.1; + + public override Food Cook() => new FishSteak(); +} diff --git a/Projects/UOContent/Items/Food/Cooking.cs b/Projects/UOContent/Items/Food/Cooking.cs index 1d74d028c..787a8334f 100644 --- a/Projects/UOContent/Items/Food/Cooking.cs +++ b/Projects/UOContent/Items/Food/Cooking.cs @@ -1,534 +1,147 @@ using System; +using ModernUO.Serialization; using Server.Targeting; -namespace Server.Items +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class Dough : Item { - // ********** Dough ********** - public class Dough : Item + [Constructible] + public Dough() : base(0x103d) { - [Constructible] - public Dough() : base(0x103d) - { - Stackable = Core.ML; - Weight = 1.0; - } - - public Dough(Serial serial) : base(serial) - { - } - - 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(); - } - - private class InternalTarget : Target - { - private readonly Dough m_Item; - - public InternalTarget(Dough item) : base(1, false, TargetFlags.None) => m_Item = item; - - protected override void OnTarget(Mobile from, object targeted) - { - if (m_Item.Deleted) - { - return; - } - - if (targeted is not Item targetItem || targetItem.Deleted) - { - return; - } - - m_Item.Consume(); - - if (targeted is Eggs) - { - from.AddToBackpack(new UnbakedQuiche()); - from.AddToBackpack(new Eggshells()); - } - else if (targeted is CheeseWheel) - { - from.AddToBackpack(new CheesePizza()); - } - else if (targeted is Sausage) - { - from.AddToBackpack(new SausagePizza()); - } - else if (targeted is Apple) - { - from.AddToBackpack(new UnbakedApplePie()); - } - else if (targeted is Peach) - { - from.AddToBackpack(new UnbakedPeachCobbler()); - } - else - { - return; - } - - targetItem.Consume(); - } - } - } - - // ********** SweetDough ********** - public class SweetDough : Item - { - [Constructible] - public SweetDough() : base(0x103d) - { - Stackable = Core.ML; - Weight = 1.0; - Hue = 150; - } - - public SweetDough(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1041340; // sweet dough - - 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(); - - if (Hue == 51) - { - Hue = 150; - } - } - - private class InternalTarget : Target - { - private readonly SweetDough m_Item; - - public InternalTarget(SweetDough item) : base(1, false, TargetFlags.None) => m_Item = item; - - protected override void OnTarget(Mobile from, object targeted) - { - if (m_Item.Deleted) - { - return; - } - - m_Item.Consume(); - - if (targeted is BowlFlour flour) - { - flour.Delete(); - - from.AddToBackpack(new CakeMix()); - } - else if (targeted is Campfire campfire) - { - from.PlaySound(0x225); - var t = new InternalTimer(from, campfire); - t.Start(); - } - } - - private class InternalTimer : Timer - { - private readonly Campfire m_Campfire; - private readonly Mobile m_From; - - public InternalTimer(Mobile from, Campfire campfire) : base(TimeSpan.FromSeconds(5.0)) - { - m_From = from; - m_Campfire = campfire; - } - - protected override void OnTick() - { - if (m_From.GetDistanceToSqrt(m_Campfire) > 3) - { - m_From.SendLocalizedMessage(500686); // You burn the food to a crisp! It's ruined. - return; - } - - if (m_From.CheckSkill(SkillName.Cooking, 0, 10)) - { - if (m_From.AddToBackpack(new Muffins())) - { - m_From.PlaySound(0x57); - } - } - else - { - m_From.SendLocalizedMessage(500686); // You burn the food to a crisp! It's ruined. - } - } - } - } - } - - // ********** JarHoney ********** - public class JarHoney : Item - { - [Constructible] - public JarHoney() : base(0x9ec) - { - Weight = 1.0; - Stackable = true; - } - - public JarHoney(Serial serial) : base(serial) - { - } - - 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(); - Stackable = true; - } - - /*public override void OnDoubleClick( Mobile from ) - { - if (!Movable) - return; - - from.Target = new InternalTarget( this ); - }*/ - - private class InternalTarget : Target - { - private readonly JarHoney m_Item; - - public InternalTarget(JarHoney item) : base(1, false, TargetFlags.None) => m_Item = item; - - protected override void OnTarget(Mobile from, object targeted) - { - if (m_Item.Deleted) - { - return; - } - - m_Item.Consume(); - - if (targeted is Dough dough) - { - dough.Consume(); - - from.AddToBackpack(new SweetDough()); - } - - if (targeted is BowlFlour flour) - { - flour.Delete(); - - from.AddToBackpack(new CookieMix()); - } - } - } - } - - // ********** BowlFlour ********** - public class BowlFlour : Item - { - [Constructible] - public BowlFlour() : base(0xa1e) => Weight = 1.0; - - public BowlFlour(Serial serial) : base(serial) - { - } - - 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(); - } - } - - // ********** WoodenBowl ********** - public class WoodenBowl : Item - { - [Constructible] - public WoodenBowl() : base(0x15f8) => Weight = 1.0; - - public WoodenBowl(Serial serial) : base(serial) - { - } - - 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(); - } - } - - // ********** PitcherWater ********** - /*public class PitcherWater : Item - { - [Constructible] - public PitcherWater() : base(Utility.Random( 0x1f9d, 2 )) - { + Stackable = Core.ML; Weight = 1.0; - } + } +} - public PitcherWater( Serial serial ) : base( serial ) - { - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize( writer ); - - writer.Write( (int) 0 ); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize( reader ); - - int version = reader.ReadInt(); - } - - public override void OnDoubleClick( Mobile from ) - { - if (!Movable) - return; - - from.Target = new InternalTarget( this ); - } - - private class InternalTarget : Target - { - private PitcherWater m_Item; - - public InternalTarget( PitcherWater item ) : base( 1, false, TargetFlags.None ) - { - m_Item = item; - } - - protected override void OnTarget( Mobile from, object targeted ) - { - if (m_Item.Deleted ) return; - - if (targeted is BowlFlour) - { - m_Item.Delete(); - ((BowlFlour)targeted).Delete(); - - from.AddToBackpack( new Dough() ); - from.AddToBackpack( new WoodenBowl() ); - } - } - } - }*/ - - // ********** SackFlour ********** - [TypeAlias("Server.Items.SackFlourOpen")] - public class SackFlour : Item, IHasQuantity +[SerializationGenerator(0, false)] +public partial class SweetDough : Item +{ + [Constructible] + public SweetDough() : base(0x103d) { - private int m_Quantity; + Stackable = Core.ML; + Weight = 1.0; + Hue = 150; + } - [Constructible] - public SackFlour() : base(0x1039) - { - Weight = 5.0; - m_Quantity = 20; - } + public override int LabelNumber => 1041340; // sweet dough +} - public SackFlour(Serial serial) : base(serial) - { - } +[SerializationGenerator(0, false)] +public partial class JarHoney : Item +{ + [Constructible] + public JarHoney() : base(0x9ec) + { + Weight = 1.0; + Stackable = true; + } +} - [CommandProperty(AccessLevel.GameMaster)] - public int Quantity +[SerializationGenerator(0, false)] +public partial class BowlFlour : Item +{ + [Constructible] + public BowlFlour() : base(0xa1e) => Weight = 1.0; +} + +[SerializationGenerator(0, false)] +public partial class WoodenBowl : Item +{ + [Constructible] + public WoodenBowl() : base(0x15f8) => Weight = 1.0; +} + +[TypeAlias("Server.Items.SackFlourOpen")] +[SerializationGenerator(0, false)] +public partial class SackFlour : Item, IHasQuantity +{ + private int _quantity; + + [Constructible] + public SackFlour() : base(0x1039) + { + Weight = 5.0; + _quantity = 20; + } + + [CommandProperty(AccessLevel.GameMaster)] + [SerializableField(1)] + public int Quantity + { + get => _quantity; + set { - get => m_Quantity; - set + _quantity = Math.Min(20, Math.Max(0, value)); + + if (_quantity == 0) { - m_Quantity = Math.Min(20, Math.Max(0, value)); - - if (m_Quantity == 0) - { - Delete(); - } - else if (m_Quantity < 20 && ItemID is 0x1039 or 0x1045) - { - ++ItemID; - } + Delete(); } - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(2); // version - - writer.Write(m_Quantity); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - switch (version) - { - case 2: - case 1: - { - m_Quantity = reader.ReadInt(); - break; - } - case 0: - { - m_Quantity = 20; - break; - } - } - - if (version < 2 && Weight == 1.0) - { - Weight = 5.0; - } - } - - public override void OnDoubleClick(Mobile from) - { - if (!Movable) - { - return; - } - - if (ItemID is 0x1039 or 0x1045) + else if (_quantity < 20 && ItemID is 0x1039 or 0x1045) { ++ItemID; } + + this.MarkDirty(); } } - // ********** Eggshells ********** - public class Eggshells : Item + public override void OnDoubleClick(Mobile from) { - [Constructible] - public Eggshells() : base(0x9b4) => Weight = 0.5; - - public Eggshells(Serial serial) : base(serial) + if (Movable && ItemID is 0x1039 or 0x1045) { - } - - 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 WheatSheaf : Item - { - [Constructible] - public WheatSheaf(int amount = 1) : base(7869) - { - Weight = 1.0; - Stackable = true; - Amount = amount; - } - - public WheatSheaf(Serial serial) : base(serial) - { - } - - public override void OnDoubleClick(Mobile from) - { - if (!Movable) - { - return; - } - - from.BeginTarget(4, false, TargetFlags.None, OnTarget); - } - - public virtual void OnTarget(Mobile from, object obj) - { - if (obj is AddonComponent addon) - { - obj = addon.Addon; - } - - if (obj is IFlourMill mill) - { - var needs = mill.MaxFlour - mill.CurFlour; - - if (needs > Amount) - { - needs = Amount; - } - - mill.CurFlour += needs; - Consume(needs); - } - } - - 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(); + ++ItemID; + } + } +} + +[SerializationGenerator(0, false)] +public partial class Eggshells : Item +{ + [Constructible] + public Eggshells() : base(0x9b4) => Weight = 0.5; +} + +[SerializationGenerator(0, false)] +public partial class WheatSheaf : Item +{ + [Constructible] + public WheatSheaf(int amount = 1) : base(7869) + { + Weight = 1.0; + Stackable = true; + Amount = amount; + } + + public override void OnDoubleClick(Mobile from) + { + if (Movable) + { + from.BeginTarget(4, false, TargetFlags.None, OnTarget); + } + } + + public virtual void OnTarget(Mobile from, object obj) + { + if (obj is AddonComponent addon) + { + obj = addon.Addon; + } + + if (obj is IFlourMill mill) + { + var needs = mill.MaxFlour - mill.CurFlour; + + if (needs > Amount) + { + needs = Amount; + } + + mill.CurFlour += needs; + Consume(needs); } } } diff --git a/Projects/UOContent/Items/Food/Food.cs b/Projects/UOContent/Items/Food/Food.cs index b976c8e6f..42afe10e4 100644 --- a/Projects/UOContent/Items/Food/Food.cs +++ b/Projects/UOContent/Items/Food/Food.cs @@ -1,1134 +1,519 @@ using System.Collections.Generic; +using ModernUO.Serialization; using Server.ContextMenus; -namespace Server.Items +namespace Server.Items; + +[SerializationGenerator(0, false)] +public abstract partial class Food : Item { - public abstract class Food : Item + [SerializableField(0)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private Mobile _poisoner; + + [SerializableField(1)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private Poison _poison; + + [SerializableField(2)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private int _fillFactor; + + public Food(int itemID, int amount = 1) : base(itemID) { - public Food(int itemID, int amount = 1) : base(itemID) + Stackable = true; + Amount = amount; + FillFactor = 1; + } + + public override void GetContextMenuEntries(Mobile from, List list) + { + base.GetContextMenuEntries(from, list); + + if (from.Alive) { - Stackable = true; - Amount = amount; - FillFactor = 1; + list.Add(new EatEntry(from, this)); + } + } + + public override void OnDoubleClick(Mobile from) + { + if (!Movable) + { + return; } - public Food(Serial serial) : base(serial) + if (from.InRange(GetWorldLocation(), 1)) { + Eat(from); } + } - [CommandProperty(AccessLevel.GameMaster)] - public Mobile Poisoner { get; set; } - - [CommandProperty(AccessLevel.GameMaster)] - public Poison Poison { get; set; } - - [CommandProperty(AccessLevel.GameMaster)] - public int FillFactor { get; set; } - - public override void GetContextMenuEntries(Mobile from, List list) + public override bool CanStackWith(Item dropped) + { + if (dropped is Food food) { - base.GetContextMenuEntries(from, list); - - if (from.Alive) + if (Poison != food.Poison || Poisoner != food.Poisoner) { - list.Add(new EatEntry(from, this)); - } - } - - public override void OnDoubleClick(Mobile from) - { - if (!Movable) - { - return; - } - - if (from.InRange(GetWorldLocation(), 1)) - { - Eat(from); - } - } - - public override bool CanStackWith(Item dropped) - { - if (dropped is Food food) - { - if (Poison != food.Poison || Poisoner != food.Poisoner) - { - return false; - } - } - return base.CanStackWith(dropped); - } - - - public virtual bool Eat(Mobile from) - { - // Fill the Mobile with FillFactor - if (CheckHunger(from)) - { - // Play a random "eat" sound - from.PlaySound(Utility.Random(0x3A, 3)); - - if (from.Body.IsHuman && !from.Mounted) - { - from.Animate(34, 5, 1, true, false, 0); - } - - if (Poison != null) - { - from.ApplyPoison(Poisoner, Poison); - } - - Consume(); - - return true; - } - - return false; - } - - public virtual bool CheckHunger(Mobile from) => FillHunger(from, FillFactor); - - public static bool FillHunger(Mobile from, int fillFactor) - { - if (from.Hunger >= 20) - { - from.SendLocalizedMessage(500867); // You are simply too full to eat any more! return false; } + } + return base.CanStackWith(dropped); + } - var iHunger = from.Hunger + fillFactor; - if (from.Stam < from.StamMax) + public virtual bool Eat(Mobile from) + { + // Fill the Mobile with FillFactor + if (CheckHunger(from)) + { + // Play a random "eat" sound + from.PlaySound(Utility.Random(0x3A, 3)); + + if (from.Body.IsHuman && !from.Mounted) { - from.Stam += Utility.Random(6, 3) + fillFactor / 5; + from.Animate(34, 5, 1, true, false, 0); } - if (iHunger >= 20) + if (Poison != null) { - from.Hunger = 20; - from.SendLocalizedMessage(500872); // You manage to eat the food, but you are stuffed! - } - else - { - from.Hunger = iHunger; - - if (iHunger < 5) - { - from.SendLocalizedMessage(500868); // You eat the food, but are still extremely hungry. - } - else if (iHunger < 10) - { - from.SendLocalizedMessage(500869); // You eat the food, and begin to feel more satiated. - } - else if (iHunger < 15) - { - from.SendLocalizedMessage(500870); // After eating the food, you feel much less hungry. - } - else - { - from.SendLocalizedMessage(500871); // You feel quite full after consuming the food. - } + from.ApplyPoison(Poisoner, Poison); } + Consume(); return true; } - public override void Serialize(IGenericWriter writer) + return false; + } + + public virtual bool CheckHunger(Mobile from) => FillHunger(from, FillFactor); + + public static bool FillHunger(Mobile from, int fillFactor) + { + if (from.Hunger >= 20) { - base.Serialize(writer); - - writer.Write(4); // version - - writer.Write(Poisoner); - - writer.Write(Poison); - writer.Write(FillFactor); + from.SendLocalizedMessage(500867); // You are simply too full to eat any more! + return false; } - public override void Deserialize(IGenericReader reader) + var iHunger = from.Hunger + fillFactor; + + if (from.Stam < from.StamMax) { - base.Deserialize(reader); + from.Stam += Utility.Random(6, 3) + fillFactor / 5; + } - var version = reader.ReadInt(); + if (iHunger >= 20) + { + from.Hunger = 20; + from.SendLocalizedMessage(500872); // You manage to eat the food, but you are stuffed! + } + else + { + from.Hunger = iHunger; - switch (version) + if (iHunger < 5) { - case 1: - { - Poison = reader.ReadInt() switch - { - 0 => null, - 1 => Poison.Lesser, - 2 => Poison.Regular, - 3 => Poison.Greater, - 4 => Poison.Deadly, - _ => Poison - }; - - break; - } - case 2: - { - Poison = reader.ReadPoison(); - break; - } - case 3: - { - Poison = reader.ReadPoison(); - FillFactor = reader.ReadInt(); - break; - } - case 4: - { - Poisoner = reader.ReadEntity(); - goto case 3; - } + from.SendLocalizedMessage(500868); // You eat the food, but are still extremely hungry. + } + else if (iHunger < 10) + { + from.SendLocalizedMessage(500869); // You eat the food, and begin to feel more satiated. + } + else if (iHunger < 15) + { + from.SendLocalizedMessage(500870); // After eating the food, you feel much less hungry. + } + else + { + from.SendLocalizedMessage(500871); // You feel quite full after consuming the food. } } - } - public class BreadLoaf : Food - { - [Constructible] - public BreadLoaf(int amount = 1) : base(0x103B, amount) - { - Weight = 1.0; - FillFactor = 3; - } - - public BreadLoaf(Serial serial) : base(serial) - { - } - - 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 Bacon : Food - { - [Constructible] - public Bacon(int amount = 1) : base(0x979, amount) - { - Weight = 1.0; - FillFactor = 1; - } - - public Bacon(Serial serial) : base(serial) - { - } - - 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 SlabOfBacon : Food - { - [Constructible] - public SlabOfBacon(int amount = 1) : base(0x976, amount) - { - Weight = 1.0; - FillFactor = 3; - } - - public SlabOfBacon(Serial serial) : base(serial) - { - } - - 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 FishSteak : Food - { - [Constructible] - public FishSteak(int amount = 1) : base(0x97B, amount) => FillFactor = 3; - - public FishSteak(Serial serial) : base(serial) - { - } - - public override double DefaultWeight => 0.1; - - 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 CheeseWheel : Food - { - [Constructible] - public CheeseWheel(int amount = 1) : base(0x97E, amount) => FillFactor = 3; - - public CheeseWheel(Serial serial) : base(serial) - { - } - - public override double DefaultWeight => 0.1; - - 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 CheeseWedge : Food - { - [Constructible] - public CheeseWedge(int amount = 1) : base(0x97D, amount) => FillFactor = 3; - - public CheeseWedge(Serial serial) : base(serial) - { - } - - public override double DefaultWeight => 0.1; - - 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 CheeseSlice : Food - { - [Constructible] - public CheeseSlice(int amount = 1) : base(0x97C, amount) => FillFactor = 1; - - public CheeseSlice(Serial serial) : base(serial) - { - } - - public override double DefaultWeight => 0.1; - - 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 FrenchBread : Food - { - [Constructible] - public FrenchBread(int amount = 1) : base(0x98C, amount) - { - Weight = 2.0; - FillFactor = 3; - } - - public FrenchBread(Serial serial) : base(serial) - { - } - - 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 FriedEggs : Food - { - [Constructible] - public FriedEggs(int amount = 1) : base(0x9B6, amount) - { - Weight = 1.0; - FillFactor = 4; - } - - public FriedEggs(Serial serial) : base(serial) - { - } - - 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 CookedBird : Food - { - [Constructible] - public CookedBird(int amount = 1) : base(0x9B7, amount) - { - Weight = 1.0; - FillFactor = 5; - } - - public CookedBird(Serial serial) : base(serial) - { - } - - 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 RoastPig : Food - { - [Constructible] - public RoastPig(int amount = 1) : base(0x9BB, amount) - { - Weight = 45.0; - FillFactor = 20; - } - - public RoastPig(Serial serial) : base(serial) - { - } - - 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 Sausage : Food - { - [Constructible] - public Sausage(int amount = 1) : base(0x9C0, amount) - { - Weight = 1.0; - FillFactor = 4; - } - - public Sausage(Serial serial) : base(serial) - { - } - - 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 Ham : Food - { - [Constructible] - public Ham(int amount = 1) : base(0x9C9, amount) - { - Weight = 1.0; - FillFactor = 5; - } - - public Ham(Serial serial) : base(serial) - { - } - - 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 Cake : Food - { - [Constructible] - public Cake() : base(0x9E9) - { - Stackable = false; - Weight = 1.0; - FillFactor = 10; - } - - public Cake(Serial serial) : base(serial) - { - } - - 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 Ribs : Food - { - [Constructible] - public Ribs(int amount = 1) : base(0x9F2, amount) - { - Weight = 1.0; - FillFactor = 5; - } - - public Ribs(Serial serial) : base(serial) - { - } - - 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 Cookies : Food - { - [Constructible] - public Cookies() : base(0x160b) - { - Stackable = Core.ML; - Weight = 1.0; - FillFactor = 4; - } - - public Cookies(Serial serial) : base(serial) - { - } - - 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 Muffins : Food - { - [Constructible] - public Muffins() : base(0x9eb) - { - Stackable = false; - Weight = 1.0; - FillFactor = 4; - } - - public Muffins(Serial serial) : base(serial) - { - } - - 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(); - } - } - - [TypeAlias("Server.Items.Pizza")] - public class CheesePizza : Food - { - [Constructible] - public CheesePizza() : base(0x1040) - { - Stackable = false; - Weight = 1.0; - FillFactor = 6; - } - - public CheesePizza(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1044516; // cheese pizza - - 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 SausagePizza : Food - { - [Constructible] - public SausagePizza() : base(0x1040) - { - Stackable = false; - Weight = 1.0; - FillFactor = 6; - } - - public SausagePizza(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1044517; // sausage pizza - - 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 FruitPie : Food - { - [Constructible] - public FruitPie() : base(0x1041) - { - Stackable = false; - Weight = 1.0; - FillFactor = 5; - } - - public FruitPie(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1041346; // baked fruit pie - - 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 MeatPie : Food - { - [Constructible] - public MeatPie() : base(0x1041) - { - Stackable = false; - Weight = 1.0; - FillFactor = 5; - } - - public MeatPie(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1041347; // baked meat pie - - 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 PumpkinPie : Food - { - [Constructible] - public PumpkinPie() : base(0x1041) - { - Stackable = false; - Weight = 1.0; - FillFactor = 5; - } - - public PumpkinPie(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1041348; // baked pumpkin pie - - 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 ApplePie : Food - { - [Constructible] - public ApplePie() : base(0x1041) - { - Stackable = false; - Weight = 1.0; - FillFactor = 5; - } - - public ApplePie(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1041343; // baked apple pie - - 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 PeachCobbler : Food - { - [Constructible] - public PeachCobbler() : base(0x1041) - { - Stackable = false; - Weight = 1.0; - FillFactor = 5; - } - - public PeachCobbler(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1041344; // baked peach cobbler - - 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 Quiche : Food - { - [Constructible] - public Quiche() : base(0x1041) - { - Stackable = Core.ML; - Weight = 1.0; - FillFactor = 5; - } - - public Quiche(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1041345; // baked quiche - - 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 LambLeg : Food - { - [Constructible] - public LambLeg(int amount = 1) : base(0x160a, amount) - { - Weight = 2.0; - FillFactor = 5; - } - - public LambLeg(Serial serial) : base(serial) - { - } - - 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 ChickenLeg : Food - { - [Constructible] - public ChickenLeg(int amount = 1) : base(0x1608, amount) - { - Weight = 1.0; - FillFactor = 4; - } - - public ChickenLeg(Serial serial) : base(serial) - { - } - - 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(); - } - } - - [Flippable(0xC74, 0xC75)] - public class HoneydewMelon : Food - { - [Constructible] - public HoneydewMelon(int amount = 1) : base(0xC74, amount) - { - Weight = 1.0; - FillFactor = 1; - } - - public HoneydewMelon(Serial serial) : base(serial) - { - } - - 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(); - } - } - - [Flippable(0xC64, 0xC65)] - public class YellowGourd : Food - { - [Constructible] - public YellowGourd(int amount = 1) : base(0xC64, amount) - { - Weight = 1.0; - FillFactor = 1; - } - - public YellowGourd(Serial serial) : base(serial) - { - } - - 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(); - } - } - - [Flippable(0xC66, 0xC67)] - public class GreenGourd : Food - { - [Constructible] - public GreenGourd(int amount = 1) : base(0xC66, amount) - { - Weight = 1.0; - FillFactor = 1; - } - - public GreenGourd(Serial serial) : base(serial) - { - } - - 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(); - } - } - - [Flippable(0xC7F, 0xC81)] - public class EarOfCorn : Food - { - [Constructible] - public EarOfCorn(int amount = 1) : base(0xC81, amount) - { - Weight = 1.0; - FillFactor = 1; - } - - public EarOfCorn(Serial serial) : base(serial) - { - } - - 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 Turnip : Food - { - [Constructible] - public Turnip(int amount = 1) : base(0xD3A, amount) - { - Weight = 1.0; - FillFactor = 1; - } - - public Turnip(Serial serial) : base(serial) - { - } - - 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 SheafOfHay : Item - { - [Constructible] - public SheafOfHay() : base(0xF36) => Weight = 10.0; - - public SheafOfHay(Serial serial) : base(serial) - { - } - - 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(); - } + return true; } } + +[SerializationGenerator(0, false)] +public partial class BreadLoaf : Food +{ + [Constructible] + public BreadLoaf(int amount = 1) : base(0x103B, amount) + { + Weight = 1.0; + FillFactor = 3; + } +} + +[SerializationGenerator(0, false)] +public partial class Bacon : Food +{ + [Constructible] + public Bacon(int amount = 1) : base(0x979, amount) + { + Weight = 1.0; + FillFactor = 1; + } +} + +[SerializationGenerator(0, false)] +public partial class SlabOfBacon : Food +{ + [Constructible] + public SlabOfBacon(int amount = 1) : base(0x976, amount) + { + Weight = 1.0; + FillFactor = 3; + } +} + +[SerializationGenerator(0, false)] +public partial class FishSteak : Food +{ + [Constructible] + public FishSteak(int amount = 1) : base(0x97B, amount) => FillFactor = 3; + + public override double DefaultWeight => 0.1; +} + +[SerializationGenerator(0, false)] +public partial class CheeseWheel : Food +{ + [Constructible] + public CheeseWheel(int amount = 1) : base(0x97E, amount) => FillFactor = 3; + + public override double DefaultWeight => 0.1; +} + +[SerializationGenerator(0, false)] +public partial class CheeseWedge : Food +{ + [Constructible] + public CheeseWedge(int amount = 1) : base(0x97D, amount) => FillFactor = 3; + + public override double DefaultWeight => 0.1; +} + +[SerializationGenerator(0, false)] +public partial class CheeseSlice : Food +{ + [Constructible] + public CheeseSlice(int amount = 1) : base(0x97C, amount) => FillFactor = 1; + + public override double DefaultWeight => 0.1; +} + +[SerializationGenerator(0, false)] +public partial class FrenchBread : Food +{ + [Constructible] + public FrenchBread(int amount = 1) : base(0x98C, amount) + { + Weight = 2.0; + FillFactor = 3; + } +} + +[SerializationGenerator(0, false)] +public partial class FriedEggs : Food +{ + [Constructible] + public FriedEggs(int amount = 1) : base(0x9B6, amount) + { + Weight = 1.0; + FillFactor = 4; + } +} + +[SerializationGenerator(0, false)] +public partial class CookedBird : Food +{ + [Constructible] + public CookedBird(int amount = 1) : base(0x9B7, amount) + { + Weight = 1.0; + FillFactor = 5; + } +} + +[SerializationGenerator(0, false)] +public partial class RoastPig : Food +{ + [Constructible] + public RoastPig(int amount = 1) : base(0x9BB, amount) + { + Weight = 45.0; + FillFactor = 20; + } +} + +[SerializationGenerator(0, false)] +public partial class Sausage : Food +{ + [Constructible] + public Sausage(int amount = 1) : base(0x9C0, amount) + { + Weight = 1.0; + FillFactor = 4; + } +} + +[SerializationGenerator(0, false)] +public partial class Ham : Food +{ + [Constructible] + public Ham(int amount = 1) : base(0x9C9, amount) + { + Weight = 1.0; + FillFactor = 5; + } +} + +[SerializationGenerator(0, false)] +public partial class Cake : Food +{ + [Constructible] + public Cake() : base(0x9E9) + { + Stackable = false; + Weight = 1.0; + FillFactor = 10; + } +} + +[SerializationGenerator(0, false)] +public partial class Ribs : Food +{ + [Constructible] + public Ribs(int amount = 1) : base(0x9F2, amount) + { + Weight = 1.0; + FillFactor = 5; + } +} + +[SerializationGenerator(0, false)] +public partial class Cookies : Food +{ + [Constructible] + public Cookies() : base(0x160b) + { + Stackable = Core.ML; + Weight = 1.0; + FillFactor = 4; + } +} + +[SerializationGenerator(0, false)] +public partial class Muffins : Food +{ + [Constructible] + public Muffins() : base(0x9eb) + { + Stackable = false; + Weight = 1.0; + FillFactor = 4; + } +} + +[TypeAlias("Server.Items.Pizza")] +[SerializationGenerator(0, false)] +public partial class CheesePizza : Food +{ + [Constructible] + public CheesePizza() : base(0x1040) + { + Stackable = false; + Weight = 1.0; + FillFactor = 6; + } + + public override int LabelNumber => 1044516; // cheese pizza +} + +[SerializationGenerator(0, false)] +public partial class SausagePizza : Food +{ + [Constructible] + public SausagePizza() : base(0x1040) + { + Stackable = false; + Weight = 1.0; + FillFactor = 6; + } + + public override int LabelNumber => 1044517; // sausage pizza +} + +[SerializationGenerator(0, false)] +public partial class FruitPie : Food +{ + [Constructible] + public FruitPie() : base(0x1041) + { + Stackable = false; + Weight = 1.0; + FillFactor = 5; + } + + public override int LabelNumber => 1041346; // baked fruit pie +} + +[SerializationGenerator(0, false)] +public partial class MeatPie : Food +{ + [Constructible] + public MeatPie() : base(0x1041) + { + Stackable = false; + Weight = 1.0; + FillFactor = 5; + } + + public override int LabelNumber => 1041347; // baked meat pie +} + +[SerializationGenerator(0, false)] +public partial class PumpkinPie : Food +{ + [Constructible] + public PumpkinPie() : base(0x1041) + { + Stackable = false; + Weight = 1.0; + FillFactor = 5; + } + + public override int LabelNumber => 1041348; // baked pumpkin pie +} + +[SerializationGenerator(0, false)] +public partial class ApplePie : Food +{ + [Constructible] + public ApplePie() : base(0x1041) + { + Stackable = false; + Weight = 1.0; + FillFactor = 5; + } + + public override int LabelNumber => 1041343; // baked apple pie +} + +[SerializationGenerator(0, false)] +public partial class PeachCobbler : Food +{ + [Constructible] + public PeachCobbler() : base(0x1041) + { + Stackable = false; + Weight = 1.0; + FillFactor = 5; + } + + public override int LabelNumber => 1041344; // baked peach cobbler +} + +[SerializationGenerator(0, false)] +public partial class Quiche : Food +{ + [Constructible] + public Quiche() : base(0x1041) + { + Stackable = Core.ML; + Weight = 1.0; + FillFactor = 5; + } + + public override int LabelNumber => 1041345; // baked quiche +} + +[SerializationGenerator(0, false)] +public partial class LambLeg : Food +{ + [Constructible] + public LambLeg(int amount = 1) : base(0x160a, amount) + { + Weight = 2.0; + FillFactor = 5; + } +} + +[SerializationGenerator(0, false)] +public partial class ChickenLeg : Food +{ + [Constructible] + public ChickenLeg(int amount = 1) : base(0x1608, amount) + { + Weight = 1.0; + FillFactor = 4; + } +} + +[Flippable(0xC74, 0xC75)] +[SerializationGenerator(0, false)] +public partial class HoneydewMelon : Food +{ + [Constructible] + public HoneydewMelon(int amount = 1) : base(0xC74, amount) + { + Weight = 1.0; + FillFactor = 1; + } +} + +[Flippable(0xC64, 0xC65)] +[SerializationGenerator(0, false)] +public partial class YellowGourd : Food +{ + [Constructible] + public YellowGourd(int amount = 1) : base(0xC64, amount) + { + Weight = 1.0; + FillFactor = 1; + } +} + +[Flippable(0xC66, 0xC67)] +[SerializationGenerator(0, false)] +public partial class GreenGourd : Food +{ + [Constructible] + public GreenGourd(int amount = 1) : base(0xC66, amount) + { + Weight = 1.0; + FillFactor = 1; + } +} + +[Flippable(0xC7F, 0xC81)] +[SerializationGenerator(0, false)] +public partial class EarOfCorn : Food +{ + [Constructible] + public EarOfCorn(int amount = 1) : base(0xC81, amount) + { + Weight = 1.0; + FillFactor = 1; + } +} + +[SerializationGenerator(0, false)] +public partial class Turnip : Food +{ + [Constructible] + public Turnip(int amount = 1) : base(0xD3A, amount) + { + Weight = 1.0; + FillFactor = 1; + } +} + +[SerializationGenerator(0, false)] +public partial class SheafOfHay : Item +{ + [Constructible] + public SheafOfHay() : base(0xF36) => Weight = 10.0; +} diff --git a/Projects/UOContent/Items/Food/Fruits.cs b/Projects/UOContent/Items/Food/Fruits.cs index 90ec2b3bf..9971f1d62 100644 --- a/Projects/UOContent/Items/Food/Fruits.cs +++ b/Projects/UOContent/Items/Food/Fruits.cs @@ -1,563 +1,228 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class FruitBasket : Food { - public class FruitBasket : Food + [Constructible] + public FruitBasket() : base(0x993) { - [Constructible] - public FruitBasket() : base(0x993) - { - Weight = 2.0; - FillFactor = 5; - Stackable = false; - } - - public FruitBasket(Serial serial) : base(serial) - { - } - - public override bool Eat(Mobile from) - { - if (!base.Eat(from)) - { - return false; - } - - from.AddToBackpack(new Basket()); - return 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(); - } + Weight = 2.0; + FillFactor = 5; + Stackable = false; } - [Flippable(0x171f, 0x1720)] - public class Banana : Food + public override bool Eat(Mobile from) { - [Constructible] - public Banana(int amount = 1) : base(0x171f, amount) + if (!base.Eat(from)) { - Weight = 1.0; - FillFactor = 1; + return false; } - public Banana(Serial serial) : base(serial) - { - } - - 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(); - } - } - - [Flippable(0x1721, 0x1722)] - public class Bananas : Food - { - [Constructible] - public Bananas(int amount = 1) : base(0x1721, amount) - { - Weight = 1.0; - FillFactor = 1; - } - - public Bananas(Serial serial) : base(serial) - { - } - - 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 SplitCoconut : Food - { - [Constructible] - public SplitCoconut(int amount = 1) : base(0x1725, amount) - { - Weight = 1.0; - FillFactor = 1; - } - - public SplitCoconut(Serial serial) : base(serial) - { - } - - 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 Lemon : Food - { - [Constructible] - public Lemon(int amount = 1) : base(0x1728, amount) - { - Weight = 1.0; - FillFactor = 1; - } - - public Lemon(Serial serial) : base(serial) - { - } - - 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 Lemons : Food - { - [Constructible] - public Lemons(int amount = 1) : base(0x1729, amount) - { - Weight = 1.0; - FillFactor = 1; - } - - public Lemons(Serial serial) : base(serial) - { - } - - 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 Lime : Food - { - [Constructible] - public Lime(int amount = 1) : base(0x172a, amount) - { - Weight = 1.0; - FillFactor = 1; - } - - public Lime(Serial serial) : base(serial) - { - } - - 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 Limes : Food - { - [Constructible] - public Limes(int amount = 1) : base(0x172B, amount) - { - Weight = 1.0; - FillFactor = 1; - } - - public Limes(Serial serial) : base(serial) - { - } - - 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 Coconut : Food - { - [Constructible] - public Coconut(int amount = 1) : base(0x1726, amount) - { - Weight = 1.0; - FillFactor = 1; - } - - public Coconut(Serial serial) : base(serial) - { - } - - 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 OpenCoconut : Food - { - [Constructible] - public OpenCoconut(int amount = 1) : base(0x1723, amount) - { - Weight = 1.0; - FillFactor = 1; - } - - public OpenCoconut(Serial serial) : base(serial) - { - } - - 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 Dates : Food - { - [Constructible] - public Dates(int amount = 1) : base(0x1727, amount) - { - Weight = 1.0; - FillFactor = 1; - } - - public Dates(Serial serial) : base(serial) - { - } - - 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 Grapes : Food - { - [Constructible] - public Grapes(int amount = 1) : base(0x9D1, amount) - { - Weight = 1.0; - FillFactor = 1; - } - - public Grapes(Serial serial) : base(serial) - { - } - - 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 Peach : Food - { - [Constructible] - public Peach(int amount = 1) : base(0x9D2, amount) - { - Weight = 1.0; - FillFactor = 1; - } - - public Peach(Serial serial) : base(serial) - { - } - - 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 Pear : Food - { - [Constructible] - public Pear(int amount = 1) : base(0x994, amount) - { - Weight = 1.0; - FillFactor = 1; - } - - public Pear(Serial serial) : base(serial) - { - } - - 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 Apple : Food - { - [Constructible] - public Apple(int amount = 1) : base(0x9D0, amount) - { - Weight = 1.0; - FillFactor = 1; - } - - public Apple(Serial serial) : base(serial) - { - } - - 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 Watermelon : Food - { - [Constructible] - public Watermelon(int amount = 1) : base(0xC5C, amount) - { - Weight = 5.0; - FillFactor = 5; - } - - public Watermelon(Serial serial) : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(1); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - if (version < 1) - { - if (FillFactor == 2) - { - FillFactor = 5; - } - - if (Weight == 2.0) - { - Weight = 5.0; - } - } - } - } - - public class SmallWatermelon : Food - { - [Constructible] - public SmallWatermelon(int amount = 1) : base(0xC5D, amount) - { - Weight = 5.0; - FillFactor = 5; - } - - public SmallWatermelon(Serial serial) : base(serial) - { - } - - 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(); - } - } - - [Flippable(0xc72, 0xc73)] - public class Squash : Food - { - [Constructible] - public Squash(int amount = 1) : base(0xc72, amount) - { - Weight = 1.0; - FillFactor = 1; - } - - public Squash(Serial serial) : base(serial) - { - } - - 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(); - } - } - - [Flippable(0xc79, 0xc7a)] - public class Cantaloupe : Food - { - [Constructible] - public Cantaloupe(int amount = 1) : base(0xc79, amount) - { - Weight = 1.0; - FillFactor = 1; - } - - public Cantaloupe(Serial serial) : base(serial) - { - } - - 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(); - } + from.AddToBackpack(new Basket()); + return true; + } +} + +[Flippable(0x171f, 0x1720)] +[SerializationGenerator(0, false)] +public partial class Banana : Food +{ + [Constructible] + public Banana(int amount = 1) : base(0x171f, amount) + { + Weight = 1.0; + FillFactor = 1; + } +} + +[Flippable(0x1721, 0x1722)] +[SerializationGenerator(0, false)] +public partial class Bananas : Food +{ + [Constructible] + public Bananas(int amount = 1) : base(0x1721, amount) + { + Weight = 1.0; + FillFactor = 1; + } +} + +[SerializationGenerator(0, false)] +public partial class SplitCoconut : Food +{ + [Constructible] + public SplitCoconut(int amount = 1) : base(0x1725, amount) + { + Weight = 1.0; + FillFactor = 1; + } +} + +[SerializationGenerator(0, false)] +public partial class Lemon : Food +{ + [Constructible] + public Lemon(int amount = 1) : base(0x1728, amount) + { + Weight = 1.0; + FillFactor = 1; + } +} + +[SerializationGenerator(0, false)] +public partial class Lemons : Food +{ + [Constructible] + public Lemons(int amount = 1) : base(0x1729, amount) + { + Weight = 1.0; + FillFactor = 1; + } +} + +[SerializationGenerator(0, false)] +public partial class Lime : Food +{ + [Constructible] + public Lime(int amount = 1) : base(0x172a, amount) + { + Weight = 1.0; + FillFactor = 1; + } +} + +[SerializationGenerator(0, false)] +public partial class Limes : Food +{ + [Constructible] + public Limes(int amount = 1) : base(0x172B, amount) + { + Weight = 1.0; + FillFactor = 1; + } +} + +[SerializationGenerator(0, false)] +public partial class Coconut : Food +{ + [Constructible] + public Coconut(int amount = 1) : base(0x1726, amount) + { + Weight = 1.0; + FillFactor = 1; + } +} + +[SerializationGenerator(0, false)] +public partial class OpenCoconut : Food +{ + [Constructible] + public OpenCoconut(int amount = 1) : base(0x1723, amount) + { + Weight = 1.0; + FillFactor = 1; + } +} + +[SerializationGenerator(0, false)] +public partial class Dates : Food +{ + [Constructible] + public Dates(int amount = 1) : base(0x1727, amount) + { + Weight = 1.0; + FillFactor = 1; + } +} + +[SerializationGenerator(0, false)] +public partial class Grapes : Food +{ + [Constructible] + public Grapes(int amount = 1) : base(0x9D1, amount) + { + Weight = 1.0; + FillFactor = 1; + } +} + +[SerializationGenerator(0, false)] +public partial class Peach : Food +{ + [Constructible] + public Peach(int amount = 1) : base(0x9D2, amount) + { + Weight = 1.0; + FillFactor = 1; + } +} + +[SerializationGenerator(0, false)] +public partial class Pear : Food +{ + [Constructible] + public Pear(int amount = 1) : base(0x994, amount) + { + Weight = 1.0; + FillFactor = 1; + } +} + +[SerializationGenerator(0, false)] +public partial class Apple : Food +{ + [Constructible] + public Apple(int amount = 1) : base(0x9D0, amount) + { + Weight = 1.0; + FillFactor = 1; + } +} + +[SerializationGenerator(0, false)] +public partial class Watermelon : Food +{ + [Constructible] + public Watermelon(int amount = 1) : base(0xC5C, amount) + { + Weight = 5.0; + FillFactor = 5; + } +} + +[SerializationGenerator(0, false)] +public partial class SmallWatermelon : Food +{ + [Constructible] + public SmallWatermelon(int amount = 1) : base(0xC5D, amount) + { + Weight = 5.0; + FillFactor = 5; + } +} + +[Flippable(0xc72, 0xc73)] +[SerializationGenerator(0, false)] +public partial class Squash : Food +{ + [Constructible] + public Squash(int amount = 1) : base(0xc72, amount) + { + Weight = 1.0; + FillFactor = 1; + } +} + +[Flippable(0xc79, 0xc7a)] +[SerializationGenerator(0, false)] +public partial class Cantaloupe : Food +{ + [Constructible] + public Cantaloupe(int amount = 1) : base(0xc79, amount) + { + Weight = 1.0; + FillFactor = 1; } } diff --git a/Projects/UOContent/Items/Food/Vegetables.cs b/Projects/UOContent/Items/Food/Vegetables.cs index 3c45febff..9824d23b3 100644 --- a/Projects/UOContent/Items/Food/Vegetables.cs +++ b/Projects/UOContent/Items/Food/Vegetables.cs @@ -1,188 +1,74 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[Flippable(0xc77, 0xc78)] +[SerializationGenerator(0, false)] +public partial class Carrot : Food { - [Flippable(0xc77, 0xc78)] - public class Carrot : Food + [Constructible] + public Carrot(int amount = 1) : base(0xc78, amount) { - [Constructible] - public Carrot(int amount = 1) : base(0xc78, amount) - { - Weight = 1.0; - FillFactor = 1; - } - - public Carrot(Serial serial) : base(serial) - { - } - - 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(); - } - } - - [Flippable(0xc7b, 0xc7c)] - public class Cabbage : Food - { - [Constructible] - public Cabbage(int amount = 1) : base(0xc7b, amount) - { - Weight = 1.0; - FillFactor = 1; - } - - public Cabbage(Serial serial) : base(serial) - { - } - - 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(); - } - } - - [Flippable(0xc6d, 0xc6e)] - public class Onion : Food - { - [Constructible] - public Onion(int amount = 1) : base(0xc6d, amount) - { - Weight = 1.0; - FillFactor = 1; - } - - public Onion(Serial serial) : base(serial) - { - } - - 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(); - } - } - - [Flippable(0xc70, 0xc71)] - public class Lettuce : Food - { - [Constructible] - public Lettuce(int amount = 1) : base(0xc70, amount) - { - Weight = 1.0; - FillFactor = 1; - } - - public Lettuce(Serial serial) : base(serial) - { - } - - 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(); - } - } - - [Flippable(0xC6A, 0xC6B)] - public class Pumpkin : Food - { - [Constructible] - public Pumpkin(int amount = 1) : base(0xC6A, amount) - { - Weight = 1.0; - FillFactor = 8; - } - - public Pumpkin(Serial serial) : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(1); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - if (version < 1) - { - if (FillFactor == 4) - { - FillFactor = 8; - } - - if (Weight == 5.0) - { - Weight = 1.0; - } - } - } - } - - public class SmallPumpkin : Food - { - [Constructible] - public SmallPumpkin(int amount = 1) : base(0xC6C, amount) - { - Weight = 1.0; - FillFactor = 8; - } - - public SmallPumpkin(Serial serial) : base(serial) - { - } - - 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(); - } + Weight = 1.0; + FillFactor = 1; + } +} + +[Flippable(0xc7b, 0xc7c)] +[SerializationGenerator(0, false)] +public partial class Cabbage : Food +{ + [Constructible] + public Cabbage(int amount = 1) : base(0xc7b, amount) + { + Weight = 1.0; + FillFactor = 1; + } +} + +[Flippable(0xc6d, 0xc6e)] +[SerializationGenerator(0, false)] +public partial class Onion : Food +{ + [Constructible] + public Onion(int amount = 1) : base(0xc6d, amount) + { + Weight = 1.0; + FillFactor = 1; + } +} + +[Flippable(0xc70, 0xc71)] +[SerializationGenerator(0, false)] +public partial class Lettuce : Food +{ + [Constructible] + public Lettuce(int amount = 1) : base(0xc70, amount) + { + Weight = 1.0; + FillFactor = 1; + } +} + +[Flippable(0xC6A, 0xC6B)] +[SerializationGenerator(0, false)] +public partial class Pumpkin : Food +{ + [Constructible] + public Pumpkin(int amount = 1) : base(0xC6A, amount) + { + Weight = 1.0; + FillFactor = 8; + } +} + +[SerializationGenerator(0, false)] +public partial class SmallPumpkin : Food +{ + [Constructible] + public SmallPumpkin(int amount = 1) : base(0xC6C, amount) + { + Weight = 1.0; + FillFactor = 8; } } diff --git a/Projects/UOContent/Migrations/Server.Items.Apple.v0.json b/Projects/UOContent/Migrations/Server.Items.Apple.v0.json new file mode 100644 index 000000000..f2cc1aebb --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Apple.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Apple" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.ApplePie.v0.json b/Projects/UOContent/Migrations/Server.Items.ApplePie.v0.json new file mode 100644 index 000000000..bd427f8e9 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.ApplePie.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.ApplePie" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Bacon.v0.json b/Projects/UOContent/Migrations/Server.Items.Bacon.v0.json new file mode 100644 index 000000000..c0dc41202 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Bacon.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Bacon" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Banana.v0.json b/Projects/UOContent/Migrations/Server.Items.Banana.v0.json new file mode 100644 index 000000000..2e0f8209b --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Banana.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Banana" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Bananas.v0.json b/Projects/UOContent/Migrations/Server.Items.Bananas.v0.json new file mode 100644 index 000000000..614b49ed1 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Bananas.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Bananas" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.BowlFlour.v0.json b/Projects/UOContent/Migrations/Server.Items.BowlFlour.v0.json new file mode 100644 index 000000000..3113a0733 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.BowlFlour.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.BowlFlour" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.BreadLoaf.v0.json b/Projects/UOContent/Migrations/Server.Items.BreadLoaf.v0.json new file mode 100644 index 000000000..486f50047 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.BreadLoaf.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.BreadLoaf" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.BrightlyColoredEggs.v0.json b/Projects/UOContent/Migrations/Server.Items.BrightlyColoredEggs.v0.json new file mode 100644 index 000000000..41968f6bd --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.BrightlyColoredEggs.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.BrightlyColoredEggs" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Cabbage.v0.json b/Projects/UOContent/Migrations/Server.Items.Cabbage.v0.json new file mode 100644 index 000000000..323d3658e --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Cabbage.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Cabbage" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Cake.v0.json b/Projects/UOContent/Migrations/Server.Items.Cake.v0.json new file mode 100644 index 000000000..f9a5fc948 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Cake.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Cake" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.CakeMix.v0.json b/Projects/UOContent/Migrations/Server.Items.CakeMix.v0.json new file mode 100644 index 000000000..bbf0e5c55 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.CakeMix.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.CakeMix" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Cantaloupe.v0.json b/Projects/UOContent/Migrations/Server.Items.Cantaloupe.v0.json new file mode 100644 index 000000000..5c61cf30e --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Cantaloupe.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Cantaloupe" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Carrot.v0.json b/Projects/UOContent/Migrations/Server.Items.Carrot.v0.json new file mode 100644 index 000000000..d07a22b5b --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Carrot.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Carrot" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.CheesePizza.v0.json b/Projects/UOContent/Migrations/Server.Items.CheesePizza.v0.json new file mode 100644 index 000000000..cb9acacf2 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.CheesePizza.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.CheesePizza" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.CheeseSlice.v0.json b/Projects/UOContent/Migrations/Server.Items.CheeseSlice.v0.json new file mode 100644 index 000000000..21e32b26c --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.CheeseSlice.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.CheeseSlice" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.CheeseWedge.v0.json b/Projects/UOContent/Migrations/Server.Items.CheeseWedge.v0.json new file mode 100644 index 000000000..9cc68c9e1 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.CheeseWedge.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.CheeseWedge" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.CheeseWheel.v0.json b/Projects/UOContent/Migrations/Server.Items.CheeseWheel.v0.json new file mode 100644 index 000000000..2e3eb9711 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.CheeseWheel.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.CheeseWheel" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.ChickenLeg.v0.json b/Projects/UOContent/Migrations/Server.Items.ChickenLeg.v0.json new file mode 100644 index 000000000..439dabe7c --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.ChickenLeg.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.ChickenLeg" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.CocoaButter.v0.json b/Projects/UOContent/Migrations/Server.Items.CocoaButter.v0.json new file mode 100644 index 000000000..b1c97f5cc --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.CocoaButter.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.CocoaButter" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.CocoaLiquor.v0.json b/Projects/UOContent/Migrations/Server.Items.CocoaLiquor.v0.json new file mode 100644 index 000000000..3e4c2ef1f --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.CocoaLiquor.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.CocoaLiquor" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.CocoaPulp.v0.json b/Projects/UOContent/Migrations/Server.Items.CocoaPulp.v0.json new file mode 100644 index 000000000..546e3c7d8 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.CocoaPulp.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.CocoaPulp" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Coconut.v0.json b/Projects/UOContent/Migrations/Server.Items.Coconut.v0.json new file mode 100644 index 000000000..6cbf6ca7b --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Coconut.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Coconut" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.CookableFood.v0.json b/Projects/UOContent/Migrations/Server.Items.CookableFood.v0.json new file mode 100644 index 000000000..907780a22 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.CookableFood.v0.json @@ -0,0 +1,14 @@ +{ + "version": 0, + "type": "Server.Items.CookableFood", + "properties": [ + { + "name": "CookingLevel", + "type": "int", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.CookedBird.v0.json b/Projects/UOContent/Migrations/Server.Items.CookedBird.v0.json new file mode 100644 index 000000000..2ed0f1a62 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.CookedBird.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.CookedBird" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.CookieMix.v0.json b/Projects/UOContent/Migrations/Server.Items.CookieMix.v0.json new file mode 100644 index 000000000..6c1840ceb --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.CookieMix.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.CookieMix" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Cookies.v0.json b/Projects/UOContent/Migrations/Server.Items.Cookies.v0.json new file mode 100644 index 000000000..f333fa730 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Cookies.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Cookies" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.DarkChocolate.v0.json b/Projects/UOContent/Migrations/Server.Items.DarkChocolate.v0.json new file mode 100644 index 000000000..c183912db --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.DarkChocolate.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.DarkChocolate" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Dates.v0.json b/Projects/UOContent/Migrations/Server.Items.Dates.v0.json new file mode 100644 index 000000000..741bf29d1 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Dates.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Dates" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Dough.v0.json b/Projects/UOContent/Migrations/Server.Items.Dough.v0.json new file mode 100644 index 000000000..c8b57c124 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Dough.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Dough" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.EarOfCorn.v0.json b/Projects/UOContent/Migrations/Server.Items.EarOfCorn.v0.json new file mode 100644 index 000000000..90b01e2a8 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.EarOfCorn.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.EarOfCorn" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.EasterEggs.v0.json b/Projects/UOContent/Migrations/Server.Items.EasterEggs.v0.json new file mode 100644 index 000000000..72b6c24ce --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.EasterEggs.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.EasterEggs" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Eggs.v0.json b/Projects/UOContent/Migrations/Server.Items.Eggs.v0.json new file mode 100644 index 000000000..f966b68f1 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Eggs.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Eggs" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Eggshells.v0.json b/Projects/UOContent/Migrations/Server.Items.Eggshells.v0.json new file mode 100644 index 000000000..511f677ff --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Eggshells.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Eggshells" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.EmptyPewterBowl.v0.json b/Projects/UOContent/Migrations/Server.Items.EmptyPewterBowl.v0.json new file mode 100644 index 000000000..2d1cb7d46 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.EmptyPewterBowl.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.EmptyPewterBowl" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.EmptyPewterTub.v0.json b/Projects/UOContent/Migrations/Server.Items.EmptyPewterTub.v0.json new file mode 100644 index 000000000..9c2461867 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.EmptyPewterTub.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.EmptyPewterTub" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.EmptyWoodenBowl.v0.json b/Projects/UOContent/Migrations/Server.Items.EmptyWoodenBowl.v0.json new file mode 100644 index 000000000..9942586dd --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.EmptyWoodenBowl.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.EmptyWoodenBowl" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.EmptyWoodenTub.v0.json b/Projects/UOContent/Migrations/Server.Items.EmptyWoodenTub.v0.json new file mode 100644 index 000000000..e9147d03c --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.EmptyWoodenTub.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.EmptyWoodenTub" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.FishSteak.v0.json b/Projects/UOContent/Migrations/Server.Items.FishSteak.v0.json new file mode 100644 index 000000000..a2cedd4a2 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.FishSteak.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.FishSteak" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Food.v0.json b/Projects/UOContent/Migrations/Server.Items.Food.v0.json new file mode 100644 index 000000000..aa86b5b37 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Food.v0.json @@ -0,0 +1,27 @@ +{ + "version": 0, + "type": "Server.Items.Food", + "properties": [ + { + "name": "Poisoner", + "type": "Server.Mobile", + "rule": "SerializableInterfaceMigrationRule" + }, + { + "name": "Poison", + "type": "Server.Poison", + "rule": "PrimitiveUOTypeMigrationRule", + "ruleArguments": [ + "Poison" + ] + }, + { + "name": "FillFactor", + "type": "int", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.FrenchBread.v0.json b/Projects/UOContent/Migrations/Server.Items.FrenchBread.v0.json new file mode 100644 index 000000000..cb57f7afc --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.FrenchBread.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.FrenchBread" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.FriedEggs.v0.json b/Projects/UOContent/Migrations/Server.Items.FriedEggs.v0.json new file mode 100644 index 000000000..aa8d9edbc --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.FriedEggs.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.FriedEggs" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.FruitBasket.v0.json b/Projects/UOContent/Migrations/Server.Items.FruitBasket.v0.json new file mode 100644 index 000000000..84b1609dc --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.FruitBasket.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.FruitBasket" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.FruitPie.v0.json b/Projects/UOContent/Migrations/Server.Items.FruitPie.v0.json new file mode 100644 index 000000000..75f15878a --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.FruitPie.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.FruitPie" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Glass.v0.json b/Projects/UOContent/Migrations/Server.Items.Glass.v0.json new file mode 100644 index 000000000..a201a73f1 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Glass.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Glass" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.GlassBottle.v0.json b/Projects/UOContent/Migrations/Server.Items.GlassBottle.v0.json new file mode 100644 index 000000000..f9ae5cd0b --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.GlassBottle.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.GlassBottle" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Grapes.v0.json b/Projects/UOContent/Migrations/Server.Items.Grapes.v0.json new file mode 100644 index 000000000..76923e20b --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Grapes.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Grapes" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.GreenGourd.v0.json b/Projects/UOContent/Migrations/Server.Items.GreenGourd.v0.json new file mode 100644 index 000000000..cece83700 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.GreenGourd.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.GreenGourd" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Ham.v0.json b/Projects/UOContent/Migrations/Server.Items.Ham.v0.json new file mode 100644 index 000000000..b5f398a4e --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Ham.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Ham" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.HoneydewMelon.v0.json b/Projects/UOContent/Migrations/Server.Items.HoneydewMelon.v0.json new file mode 100644 index 000000000..337082e0f --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.HoneydewMelon.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.HoneydewMelon" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.JarHoney.v0.json b/Projects/UOContent/Migrations/Server.Items.JarHoney.v0.json new file mode 100644 index 000000000..9dc72d1ed --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.JarHoney.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.JarHoney" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.LambLeg.v0.json b/Projects/UOContent/Migrations/Server.Items.LambLeg.v0.json new file mode 100644 index 000000000..0b14762e0 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.LambLeg.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.LambLeg" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Lemon.v0.json b/Projects/UOContent/Migrations/Server.Items.Lemon.v0.json new file mode 100644 index 000000000..00ec5e31a --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Lemon.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Lemon" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Lemons.v0.json b/Projects/UOContent/Migrations/Server.Items.Lemons.v0.json new file mode 100644 index 000000000..8feb21f2e --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Lemons.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Lemons" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Lettuce.v0.json b/Projects/UOContent/Migrations/Server.Items.Lettuce.v0.json new file mode 100644 index 000000000..6bccdabeb --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Lettuce.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Lettuce" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Lime.v0.json b/Projects/UOContent/Migrations/Server.Items.Lime.v0.json new file mode 100644 index 000000000..a4f943752 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Lime.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Lime" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Limes.v0.json b/Projects/UOContent/Migrations/Server.Items.Limes.v0.json new file mode 100644 index 000000000..a9d505b98 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Limes.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Limes" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.MeatPie.v0.json b/Projects/UOContent/Migrations/Server.Items.MeatPie.v0.json new file mode 100644 index 000000000..9e1994934 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.MeatPie.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.MeatPie" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.MilkChocolate.v0.json b/Projects/UOContent/Migrations/Server.Items.MilkChocolate.v0.json new file mode 100644 index 000000000..3358354cf --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.MilkChocolate.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.MilkChocolate" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Muffins.v0.json b/Projects/UOContent/Migrations/Server.Items.Muffins.v0.json new file mode 100644 index 000000000..9c7d8a9ff --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Muffins.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Muffins" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Onion.v0.json b/Projects/UOContent/Migrations/Server.Items.Onion.v0.json new file mode 100644 index 000000000..b5130b863 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Onion.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Onion" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.OpenCoconut.v0.json b/Projects/UOContent/Migrations/Server.Items.OpenCoconut.v0.json new file mode 100644 index 000000000..94cd7d532 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.OpenCoconut.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.OpenCoconut" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Peach.v0.json b/Projects/UOContent/Migrations/Server.Items.Peach.v0.json new file mode 100644 index 000000000..5d6e4a7ba --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Peach.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Peach" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.PeachCobbler.v0.json b/Projects/UOContent/Migrations/Server.Items.PeachCobbler.v0.json new file mode 100644 index 000000000..1263c061f --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.PeachCobbler.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.PeachCobbler" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Pear.v0.json b/Projects/UOContent/Migrations/Server.Items.Pear.v0.json new file mode 100644 index 000000000..38e7e73aa --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Pear.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Pear" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.PewterBowlOfCarrots.v0.json b/Projects/UOContent/Migrations/Server.Items.PewterBowlOfCarrots.v0.json new file mode 100644 index 000000000..f04bcf6c0 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.PewterBowlOfCarrots.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.PewterBowlOfCarrots" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.PewterBowlOfCorn.v0.json b/Projects/UOContent/Migrations/Server.Items.PewterBowlOfCorn.v0.json new file mode 100644 index 000000000..7d7af90d0 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.PewterBowlOfCorn.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.PewterBowlOfCorn" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.PewterBowlOfLettuce.v0.json b/Projects/UOContent/Migrations/Server.Items.PewterBowlOfLettuce.v0.json new file mode 100644 index 000000000..20b28ba7a --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.PewterBowlOfLettuce.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.PewterBowlOfLettuce" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.PewterBowlOfPeas.v0.json b/Projects/UOContent/Migrations/Server.Items.PewterBowlOfPeas.v0.json new file mode 100644 index 000000000..14a8225ba --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.PewterBowlOfPeas.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.PewterBowlOfPeas" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.PewterBowlOfPotatos.v0.json b/Projects/UOContent/Migrations/Server.Items.PewterBowlOfPotatos.v0.json new file mode 100644 index 000000000..fa7f89157 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.PewterBowlOfPotatos.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.PewterBowlOfPotatos" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Pumpkin.v0.json b/Projects/UOContent/Migrations/Server.Items.Pumpkin.v0.json new file mode 100644 index 000000000..83ab02724 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Pumpkin.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Pumpkin" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.PumpkinPie.v0.json b/Projects/UOContent/Migrations/Server.Items.PumpkinPie.v0.json new file mode 100644 index 000000000..72f3a3155 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.PumpkinPie.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.PumpkinPie" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Quiche.v0.json b/Projects/UOContent/Migrations/Server.Items.Quiche.v0.json new file mode 100644 index 000000000..c130ac70b --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Quiche.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Quiche" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.RawBird.v0.json b/Projects/UOContent/Migrations/Server.Items.RawBird.v0.json new file mode 100644 index 000000000..0475acb12 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.RawBird.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.RawBird" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.RawChickenLeg.v0.json b/Projects/UOContent/Migrations/Server.Items.RawChickenLeg.v0.json new file mode 100644 index 000000000..280168865 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.RawChickenLeg.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.RawChickenLeg" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.RawFishSteak.v0.json b/Projects/UOContent/Migrations/Server.Items.RawFishSteak.v0.json new file mode 100644 index 000000000..375f1cd89 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.RawFishSteak.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.RawFishSteak" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.RawLambLeg.v0.json b/Projects/UOContent/Migrations/Server.Items.RawLambLeg.v0.json new file mode 100644 index 000000000..5b126e759 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.RawLambLeg.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.RawLambLeg" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.RawRibs.v0.json b/Projects/UOContent/Migrations/Server.Items.RawRibs.v0.json new file mode 100644 index 000000000..d622b8be9 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.RawRibs.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.RawRibs" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Ribs.v0.json b/Projects/UOContent/Migrations/Server.Items.Ribs.v0.json new file mode 100644 index 000000000..de0182bcf --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Ribs.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Ribs" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.RoastPig.v0.json b/Projects/UOContent/Migrations/Server.Items.RoastPig.v0.json new file mode 100644 index 000000000..b7b4d04c2 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.RoastPig.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.RoastPig" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.SackFlour.v0.json b/Projects/UOContent/Migrations/Server.Items.SackFlour.v0.json new file mode 100644 index 000000000..8087f39fc --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.SackFlour.v0.json @@ -0,0 +1,14 @@ +{ + "version": 0, + "type": "Server.Items.SackFlour", + "properties": [ + { + "name": "Quantity", + "type": "int", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.SackOfSugar.v0.json b/Projects/UOContent/Migrations/Server.Items.SackOfSugar.v0.json new file mode 100644 index 000000000..8e0a647eb --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.SackOfSugar.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.SackOfSugar" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Sausage.v0.json b/Projects/UOContent/Migrations/Server.Items.Sausage.v0.json new file mode 100644 index 000000000..d803d2258 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Sausage.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Sausage" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.SausagePizza.v0.json b/Projects/UOContent/Migrations/Server.Items.SausagePizza.v0.json new file mode 100644 index 000000000..ec0ee27cf --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.SausagePizza.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.SausagePizza" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.SheafOfHay.v0.json b/Projects/UOContent/Migrations/Server.Items.SheafOfHay.v0.json new file mode 100644 index 000000000..d3d763d6c --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.SheafOfHay.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.SheafOfHay" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.SlabOfBacon.v0.json b/Projects/UOContent/Migrations/Server.Items.SlabOfBacon.v0.json new file mode 100644 index 000000000..347f27ab9 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.SlabOfBacon.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.SlabOfBacon" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.SmallPumpkin.v0.json b/Projects/UOContent/Migrations/Server.Items.SmallPumpkin.v0.json new file mode 100644 index 000000000..3af9f9d9f --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.SmallPumpkin.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.SmallPumpkin" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.SmallWatermelon.v0.json b/Projects/UOContent/Migrations/Server.Items.SmallWatermelon.v0.json new file mode 100644 index 000000000..fb49115bc --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.SmallWatermelon.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.SmallWatermelon" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.SplitCoconut.v0.json b/Projects/UOContent/Migrations/Server.Items.SplitCoconut.v0.json new file mode 100644 index 000000000..b2997c010 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.SplitCoconut.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.SplitCoconut" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Squash.v0.json b/Projects/UOContent/Migrations/Server.Items.Squash.v0.json new file mode 100644 index 000000000..0d6182f02 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Squash.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Squash" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.SweetDough.v0.json b/Projects/UOContent/Migrations/Server.Items.SweetDough.v0.json new file mode 100644 index 000000000..cca6c99ca --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.SweetDough.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.SweetDough" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Turnip.v0.json b/Projects/UOContent/Migrations/Server.Items.Turnip.v0.json new file mode 100644 index 000000000..f8f0c302e --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Turnip.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Turnip" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.UnbakedApplePie.v0.json b/Projects/UOContent/Migrations/Server.Items.UnbakedApplePie.v0.json new file mode 100644 index 000000000..99f050908 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.UnbakedApplePie.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.UnbakedApplePie" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.UnbakedFruitPie.v0.json b/Projects/UOContent/Migrations/Server.Items.UnbakedFruitPie.v0.json new file mode 100644 index 000000000..54548d26b --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.UnbakedFruitPie.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.UnbakedFruitPie" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.UnbakedMeatPie.v0.json b/Projects/UOContent/Migrations/Server.Items.UnbakedMeatPie.v0.json new file mode 100644 index 000000000..142fd4044 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.UnbakedMeatPie.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.UnbakedMeatPie" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.UnbakedPeachCobbler.v0.json b/Projects/UOContent/Migrations/Server.Items.UnbakedPeachCobbler.v0.json new file mode 100644 index 000000000..6d2b12e77 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.UnbakedPeachCobbler.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.UnbakedPeachCobbler" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.UnbakedPumpkinPie.v0.json b/Projects/UOContent/Migrations/Server.Items.UnbakedPumpkinPie.v0.json new file mode 100644 index 000000000..2d5ac5cc6 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.UnbakedPumpkinPie.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.UnbakedPumpkinPie" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.UnbakedQuiche.v0.json b/Projects/UOContent/Migrations/Server.Items.UnbakedQuiche.v0.json new file mode 100644 index 000000000..71633b3ad --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.UnbakedQuiche.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.UnbakedQuiche" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.UncookedCheesePizza.v0.json b/Projects/UOContent/Migrations/Server.Items.UncookedCheesePizza.v0.json new file mode 100644 index 000000000..37913c49f --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.UncookedCheesePizza.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.UncookedCheesePizza" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.UncookedSausagePizza.v0.json b/Projects/UOContent/Migrations/Server.Items.UncookedSausagePizza.v0.json new file mode 100644 index 000000000..c65c92a89 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.UncookedSausagePizza.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.UncookedSausagePizza" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Vanilla.v0.json b/Projects/UOContent/Migrations/Server.Items.Vanilla.v0.json new file mode 100644 index 000000000..b8b2b8a7b --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Vanilla.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Vanilla" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Watermelon.v0.json b/Projects/UOContent/Migrations/Server.Items.Watermelon.v0.json new file mode 100644 index 000000000..5fed967d8 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Watermelon.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Watermelon" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.WheatSheaf.v0.json b/Projects/UOContent/Migrations/Server.Items.WheatSheaf.v0.json new file mode 100644 index 000000000..f989c6934 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.WheatSheaf.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.WheatSheaf" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.WhiteChocolate.v0.json b/Projects/UOContent/Migrations/Server.Items.WhiteChocolate.v0.json new file mode 100644 index 000000000..a59371f31 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.WhiteChocolate.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.WhiteChocolate" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.WoodenBowl.v0.json b/Projects/UOContent/Migrations/Server.Items.WoodenBowl.v0.json new file mode 100644 index 000000000..09282000b --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.WoodenBowl.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.WoodenBowl" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.WoodenBowlOfCarrots.v0.json b/Projects/UOContent/Migrations/Server.Items.WoodenBowlOfCarrots.v0.json new file mode 100644 index 000000000..262bf8b3a --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.WoodenBowlOfCarrots.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.WoodenBowlOfCarrots" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.WoodenBowlOfCorn.v0.json b/Projects/UOContent/Migrations/Server.Items.WoodenBowlOfCorn.v0.json new file mode 100644 index 000000000..d28cf0b4e --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.WoodenBowlOfCorn.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.WoodenBowlOfCorn" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.WoodenBowlOfLettuce.v0.json b/Projects/UOContent/Migrations/Server.Items.WoodenBowlOfLettuce.v0.json new file mode 100644 index 000000000..655bc2d84 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.WoodenBowlOfLettuce.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.WoodenBowlOfLettuce" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.WoodenBowlOfPeas.v0.json b/Projects/UOContent/Migrations/Server.Items.WoodenBowlOfPeas.v0.json new file mode 100644 index 000000000..5704fe63c --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.WoodenBowlOfPeas.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.WoodenBowlOfPeas" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.WoodenBowlOfStew.v0.json b/Projects/UOContent/Migrations/Server.Items.WoodenBowlOfStew.v0.json new file mode 100644 index 000000000..45b7da55a --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.WoodenBowlOfStew.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.WoodenBowlOfStew" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.WoodenBowlOfTomatoSoup.v0.json b/Projects/UOContent/Migrations/Server.Items.WoodenBowlOfTomatoSoup.v0.json new file mode 100644 index 000000000..97ce4c1da --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.WoodenBowlOfTomatoSoup.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.WoodenBowlOfTomatoSoup" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.YellowGourd.v0.json b/Projects/UOContent/Migrations/Server.Items.YellowGourd.v0.json new file mode 100644 index 000000000..c3123d6fa --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.YellowGourd.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.YellowGourd" +} \ No newline at end of file From 5d6be05ad16e92f51dd80cdab0204cb011b12d77 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Mon, 13 Jun 2022 12:18:00 -0700 Subject: [PATCH 189/213] chore: Fixes CI build/test for Fedora (#1056) --- README.md | 2 +- azure-pipelines.yml | 7 ++----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index b7a0230e7..5f0a68612 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ Rider 2021.3+           & - `linuxmint.17`, `linuxmint.18`, `linuxmint.19` - Linux Mint - `debian.10`, `debian.11` - Debian - `centos.7`, `centos.8` - CentOS - - `fedora.32`, `fedora.33`, `fedora.34` - Fedora + - `fedora.32`, `fedora.33`, `fedora.34`, `fedora.35`, `fedora.36` - Fedora - `rhel.7`, `rhel.8` - Redhat - If blank, the operating system running the build is used. Linux Mint 20 is not supported directly yet, so build explicitly against `ubuntu.20.04` instead. diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 51ad8fce0..9820ec29a 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -40,15 +40,12 @@ jobs: 'Ubuntu 20': containerImage: mcr.microsoft.com/dotnet/sdk:6.0-focal os: ubuntu.20.04 - 'Fedora 34': - containerImage: fedora:34 - os: fedora.34 'Fedora 35': containerImage: fedora:35 - os: fedora.34 + os: fedora.35 'Fedora 36': containerImage: fedora:36 - os: fedora.34 + os: fedora.36 displayName: Linux From 5b488430458512d2d98eed5688d263d82bf05304 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Mon, 13 Jun 2022 14:03:18 -0700 Subject: [PATCH 190/213] fix: Adds beta MacOS 12 CI/CD support (#1057) --- .github/workflows/build-test.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index c3f71086e..119e2e0bc 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -18,6 +18,8 @@ jobs: name: MacOS 10 - os: macos-11 name: MacOS 11 + - os: macos-12 + name: MacOS 12 steps: - uses: actions/checkout@v2 From 368160144bec3985a8710cab85677ff6f86dd6b9 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Mon, 13 Jun 2022 17:31:56 -0700 Subject: [PATCH 191/213] fix: Codegens games (#1058) --- Projects/UOContent/Items/Games/Backgammon.cs | 64 ++- Projects/UOContent/Items/Games/BaseBoard.cs | 218 +++++---- Projects/UOContent/Items/Games/BasePiece.cs | 144 +++--- .../UOContent/Items/Games/CheckerBoard.cs | 52 +-- .../UOContent/Items/Games/CheckersPieces.cs | 65 +-- Projects/UOContent/Items/Games/ChessPieces.cs | 415 +++++------------- Projects/UOContent/Items/Games/Chessboard.cs | 90 ++-- Projects/UOContent/Items/Games/Dices.cs | 71 ++- .../Server.Items.Backgammon.v0.json | 4 + .../Migrations/Server.Items.BaseBoard.v2.json | 11 + .../Migrations/Server.Items.BasePiece.v0.json | 11 + .../Server.Items.CheckerBoard.v0.json | 4 + .../Server.Items.Chessboard.v0.json | 4 + .../Migrations/Server.Items.Dices.v0.json | 4 + .../Server.Items.PieceBlackBishop.v0.json | 4 + .../Server.Items.PieceBlackChecker.v0.json | 4 + .../Server.Items.PieceBlackKing.v0.json | 4 + .../Server.Items.PieceBlackKnight.v0.json | 4 + .../Server.Items.PieceBlackPawn.v0.json | 4 + .../Server.Items.PieceBlackQueen.v0.json | 4 + .../Server.Items.PieceBlackRook.v0.json | 4 + .../Server.Items.PieceWhiteBishop.v0.json | 4 + .../Server.Items.PieceWhiteChecker.v0.json | 4 + .../Server.Items.PieceWhiteKing.v0.json | 4 + .../Server.Items.PieceWhiteKnight.v0.json | 4 + .../Server.Items.PieceWhitePawn.v0.json | 4 + .../Server.Items.PieceWhiteQueen.v0.json | 4 + .../Server.Items.PieceWhiteRook.v0.json | 4 + 28 files changed, 502 insertions(+), 711 deletions(-) create mode 100644 Projects/UOContent/Migrations/Server.Items.Backgammon.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.BaseBoard.v2.json create mode 100644 Projects/UOContent/Migrations/Server.Items.BasePiece.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.CheckerBoard.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Chessboard.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Dices.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.PieceBlackBishop.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.PieceBlackChecker.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.PieceBlackKing.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.PieceBlackKnight.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.PieceBlackPawn.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.PieceBlackQueen.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.PieceBlackRook.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.PieceWhiteBishop.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.PieceWhiteChecker.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.PieceWhiteKing.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.PieceWhiteKnight.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.PieceWhitePawn.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.PieceWhiteQueen.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.PieceWhiteRook.v0.json diff --git a/Projects/UOContent/Items/Games/Backgammon.cs b/Projects/UOContent/Items/Games/Backgammon.cs index 836a62786..5b6a71b77 100644 --- a/Projects/UOContent/Items/Games/Backgammon.cs +++ b/Projects/UOContent/Items/Games/Backgammon.cs @@ -1,51 +1,37 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[Flippable(0xE1C, 0xFAD)] +[SerializationGenerator(0, false)] +public partial class Backgammon : BaseBoard { - [Flippable(0xE1C, 0xFAD)] - public class Backgammon : BaseBoard + [Constructible] + public Backgammon() : base(0xE1C) { - [Constructible] - public Backgammon() : base(0xE1C) + } + + public override void CreatePieces() + { + for (var i = 0; i < 5; i++) { + CreatePiece(new PieceWhiteChecker(this), 42, 17 * i + 6); + CreatePiece(new PieceBlackChecker(this), 42, 17 * i + 119); + + CreatePiece(new PieceBlackChecker(this), 142, 17 * i + 6); + CreatePiece(new PieceWhiteChecker(this), 142, 17 * i + 119); } - public Backgammon(Serial serial) : base(serial) + for (var i = 0; i < 3; i++) { + CreatePiece(new PieceBlackChecker(this), 108, 17 * i + 6); + CreatePiece(new PieceWhiteChecker(this), 108, 17 * i + 153); } - public override void CreatePieces() + for (var i = 0; i < 2; i++) { - for (var i = 0; i < 5; i++) - { - CreatePiece(new PieceWhiteChecker(this), 42, 17 * i + 6); - CreatePiece(new PieceBlackChecker(this), 42, 17 * i + 119); - - CreatePiece(new PieceBlackChecker(this), 142, 17 * i + 6); - CreatePiece(new PieceWhiteChecker(this), 142, 17 * i + 119); - } - - for (var i = 0; i < 3; i++) - { - CreatePiece(new PieceBlackChecker(this), 108, 17 * i + 6); - CreatePiece(new PieceWhiteChecker(this), 108, 17 * i + 153); - } - - for (var i = 0; i < 2; i++) - { - CreatePiece(new PieceWhiteChecker(this), 223, 17 * i + 6); - CreatePiece(new PieceBlackChecker(this), 223, 17 * i + 170); - } - } - - 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(); + CreatePiece(new PieceWhiteChecker(this), 223, 17 * i + 6); + CreatePiece(new PieceBlackChecker(this), 223, 17 * i + 170); } } } diff --git a/Projects/UOContent/Items/Games/BaseBoard.cs b/Projects/UOContent/Items/Games/BaseBoard.cs index 8426bcb84..869402f70 100644 --- a/Projects/UOContent/Items/Games/BaseBoard.cs +++ b/Projects/UOContent/Items/Games/BaseBoard.cs @@ -1,145 +1,129 @@ using System; using System.Collections.Generic; +using ModernUO.Serialization; using Server.ContextMenus; using Server.Gumps; using Server.Multis; using Server.Network; -namespace Server.Items +namespace Server.Items; + +[SerializationGenerator(2, false)] +public abstract partial class BaseBoard : Container, ISecurable { - public abstract class BaseBoard : Container, ISecurable + [SerializableField(0)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private SecureLevel _level; + + public BaseBoard(int itemID) : base(itemID) { - public BaseBoard(int itemID) : base(itemID) + CreatePieces(); + + Weight = 5.0; + } + + public override bool DisplaysContent => false; // Do not display (x items, y stones) + + public override bool IsDecoContainer => false; + + public override TimeSpan DecayTime => TimeSpan.FromDays(1.0); + + public abstract void CreatePieces(); + + public void Reset() + { + for (var i = Items.Count - 1; i >= 0; --i) { - CreatePieces(); - - Weight = 5.0; - } - - public BaseBoard(Serial serial) : base(serial) - { - } - - public override bool DisplaysContent => false; // Do not display (x items, y stones) - - public override bool IsDecoContainer => false; - - public override TimeSpan DecayTime => TimeSpan.FromDays(1.0); - - [CommandProperty(AccessLevel.GameMaster)] - public SecureLevel Level { get; set; } - - public abstract void CreatePieces(); - - public void Reset() - { - for (var i = Items.Count - 1; i >= 0; --i) + if (i < Items.Count) { - if (i < Items.Count) + Items[i].Delete(); + } + } + + CreatePieces(); + } + + public void CreatePiece(BasePiece piece, int x, int y) + { + AddItem(piece); + piece.Location = new Point3D(x, y, 0); + } + + private void Deserialize(IGenericReader reader, int version) + { + base.Deserialize(reader); + + if (version == 1) + { + Level = (SecureLevel)reader.ReadInt(); + } + } + + public override bool OnDragDrop(Mobile from, Item dropped) => + dropped is BasePiece piece && piece.Board == this && base.OnDragDrop(from, dropped); + + public override bool OnDragDropInto(Mobile from, Item dropped, Point3D point) + { + if (dropped is BasePiece piece && piece.Board == this && base.OnDragDropInto(from, dropped, point)) + { + if (RootParent == from) + { + from.SendSound(0x127, GetWorldLocation()); + } + else + { + Span buffer = stackalloc byte[OutgoingEffectPackets.SoundPacketLength].InitializePacket(); + + foreach (var state in GetClientsInRange(2)) { - Items[i].Delete(); + OutgoingEffectPackets.CreateSoundEffect(buffer, 0x127, GetWorldLocation()); + state.Send(buffer); } } - CreatePieces(); + return true; } - public void CreatePiece(BasePiece piece, int x, int y) + return false; + } + + public override void GetContextMenuEntries(Mobile from, List list) + { + base.GetContextMenuEntries(from, list); + + if (ValidateDefault(from, this)) { - AddItem(piece); - piece.Location = new Point3D(x, y, 0); + list.Add(new DefaultEntry(from, this)); } - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(1); // version + SetSecureLevelEntry.AddTo(from, this, list); + } - writer.Write((int)Level); + public static bool ValidateDefault(Mobile from, BaseBoard board) => + !board.Deleted && (from.AccessLevel >= AccessLevel.GameMaster || from.Alive && + (board.IsChildOf(from.Backpack) || board.RootParent is not Mobile && + board.Map == from.Map && from.InRange(board.GetWorldLocation(), 1) && + BaseHouse.FindHouseAt(board)?.IsOwner(from) == true)); + + public class DefaultEntry : ContextMenuEntry + { + private readonly BaseBoard m_Board; + private readonly Mobile m_From; + + public DefaultEntry(Mobile from, BaseBoard board) : base( + 6162, + from.AccessLevel >= AccessLevel.GameMaster ? -1 : 1 + ) + { + m_From = from; + m_Board = board; } - public override void Deserialize(IGenericReader reader) + public override void OnClick() { - base.Deserialize(reader); - var version = reader.ReadInt(); - - if (version == 1) + if (ValidateDefault(m_From, m_Board)) { - Level = (SecureLevel)reader.ReadInt(); - } - - if (Weight == 1.0) - { - Weight = 5.0; - } - } - - public override bool OnDragDrop(Mobile from, Item dropped) => - dropped is BasePiece piece && piece.Board == this && base.OnDragDrop(from, dropped); - - public override bool OnDragDropInto(Mobile from, Item dropped, Point3D point) - { - if (dropped is BasePiece piece && piece.Board == this && base.OnDragDropInto(from, dropped, point)) - { - if (RootParent == from) - { - from.SendSound(0x127, GetWorldLocation()); - } - else - { - Span buffer = stackalloc byte[OutgoingEffectPackets.SoundPacketLength].InitializePacket(); - - foreach (var state in GetClientsInRange(2)) - { - OutgoingEffectPackets.CreateSoundEffect(buffer, 0x127, GetWorldLocation()); - state.Send(buffer); - } - } - - return true; - } - - return false; - } - - public override void GetContextMenuEntries(Mobile from, List list) - { - base.GetContextMenuEntries(from, list); - - if (ValidateDefault(from, this)) - { - list.Add(new DefaultEntry(from, this)); - } - - SetSecureLevelEntry.AddTo(from, this, list); - } - - public static bool ValidateDefault(Mobile from, BaseBoard board) => - !board.Deleted && (from.AccessLevel >= AccessLevel.GameMaster || from.Alive && - (board.IsChildOf(from.Backpack) || board.RootParent is not Mobile && - board.Map == from.Map && from.InRange(board.GetWorldLocation(), 1) && - BaseHouse.FindHouseAt(board)?.IsOwner(from) == true)); - - public class DefaultEntry : ContextMenuEntry - { - private readonly BaseBoard m_Board; - private readonly Mobile m_From; - - public DefaultEntry(Mobile from, BaseBoard board) : base( - 6162, - from.AccessLevel >= AccessLevel.GameMaster ? -1 : 1 - ) - { - m_From = from; - m_Board = board; - } - - public override void OnClick() - { - if (ValidateDefault(m_From, m_Board)) - { - m_Board.Reset(); - } + m_Board.Reset(); } } } diff --git a/Projects/UOContent/Items/Games/BasePiece.cs b/Projects/UOContent/Items/Games/BasePiece.cs index a1ef5347a..f80234898 100644 --- a/Projects/UOContent/Items/Games/BasePiece.cs +++ b/Projects/UOContent/Items/Games/BasePiece.cs @@ -1,89 +1,67 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class BasePiece : Item { - public class BasePiece : Item + [SerializableField(0)] + private BaseBoard _board; + + public BasePiece(int itemID, BaseBoard board) : base(itemID) => _board = board; + + public override bool IsVirtualItem => true; + + public override bool CanTarget => false; + + [AfterDeserialization(false)] + private void AfterDeserialization() { - public BasePiece(int itemID, BaseBoard board) : base(itemID) => Board = board; - - public BasePiece(Serial serial) : base(serial) + if (Board == null || Parent == null) { + Delete(); } - - public BaseBoard Board { get; set; } - - public override bool IsVirtualItem => true; - - public override bool CanTarget => false; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); - writer.Write(Board); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - switch (version) - { - case 0: - { - Board = (BaseBoard)reader.ReadEntity(); - - if (Board == null || Parent == null) - { - Delete(); - } - - break; - } - } - } - - public override void OnSingleClick(Mobile from) - { - if (Board?.Deleted != false) - { - Delete(); - } - else if (!IsChildOf(Board)) - { - Board.DropItem(this); - } - else - { - base.OnSingleClick(from); - } - } - - public override bool OnDragLift(Mobile from) - { - if (Board?.Deleted != false) - { - Delete(); - return false; - } - - if (!IsChildOf(Board)) - { - Board.DropItem(this); - return false; - } - - return true; - } - - public override bool DropToMobile(Mobile from, Mobile target, Point3D p) => false; - - public override bool DropToItem(Mobile from, Item target, Point3D p) => - target == Board && p.X != -1 && p.Y != -1 && base.DropToItem(from, target, p); - - public override bool DropToWorld(Mobile from, Point3D p) => false; - - public override int GetLiftSound(Mobile from) => -1; } + + public override void OnSingleClick(Mobile from) + { + if (Board?.Deleted != false) + { + Delete(); + } + else if (!IsChildOf(Board)) + { + Board.DropItem(this); + } + else + { + base.OnSingleClick(from); + } + } + + public override bool OnDragLift(Mobile from) + { + if (Board?.Deleted != false) + { + Delete(); + return false; + } + + if (!IsChildOf(Board)) + { + Board.DropItem(this); + return false; + } + + return true; + } + + public override bool DropToMobile(Mobile from, Mobile target, Point3D p) => false; + + public override bool DropToItem(Mobile from, Item target, Point3D p) => + target == Board && p.X != -1 && p.Y != -1 && base.DropToItem(from, target, p); + + public override bool DropToWorld(Mobile from, Point3D p) => false; + + public override int GetLiftSound(Mobile from) => -1; } diff --git a/Projects/UOContent/Items/Games/CheckerBoard.cs b/Projects/UOContent/Items/Games/CheckerBoard.cs index 815666784..84b4a5daa 100644 --- a/Projects/UOContent/Items/Games/CheckerBoard.cs +++ b/Projects/UOContent/Items/Games/CheckerBoard.cs @@ -1,41 +1,27 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class CheckerBoard : BaseBoard { - public class CheckerBoard : BaseBoard + [Constructible] + public CheckerBoard() : base(0xFA6) { - [Constructible] - public CheckerBoard() : base(0xFA6) - { - } + } - public CheckerBoard(Serial serial) : base(serial) - { - } + public override int LabelNumber => 1016449; // a checker board - public override int LabelNumber => 1016449; // a checker board - - public override void CreatePieces() + public override void CreatePieces() + { + for (var i = 0; i < 4; i++) { - for (var i = 0; i < 4; i++) - { - CreatePiece(new PieceWhiteChecker(this), 50 * i + 45, 25); - CreatePiece(new PieceWhiteChecker(this), 50 * i + 70, 50); - CreatePiece(new PieceWhiteChecker(this), 50 * i + 45, 75); - CreatePiece(new PieceBlackChecker(this), 50 * i + 70, 150); - CreatePiece(new PieceBlackChecker(this), 50 * i + 45, 175); - CreatePiece(new PieceBlackChecker(this), 50 * i + 70, 200); - } - } - - 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(); + CreatePiece(new PieceWhiteChecker(this), 50 * i + 45, 25); + CreatePiece(new PieceWhiteChecker(this), 50 * i + 70, 50); + CreatePiece(new PieceWhiteChecker(this), 50 * i + 45, 75); + CreatePiece(new PieceBlackChecker(this), 50 * i + 70, 150); + CreatePiece(new PieceBlackChecker(this), 50 * i + 45, 175); + CreatePiece(new PieceBlackChecker(this), 50 * i + 70, 200); } } } diff --git a/Projects/UOContent/Items/Games/CheckersPieces.cs b/Projects/UOContent/Items/Games/CheckersPieces.cs index 1030b60c8..288d65517 100644 --- a/Projects/UOContent/Items/Games/CheckersPieces.cs +++ b/Projects/UOContent/Items/Games/CheckersPieces.cs @@ -1,52 +1,23 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class PieceWhiteChecker : BasePiece { - public class PieceWhiteChecker : BasePiece + public PieceWhiteChecker(BaseBoard board) : base(0x3584, board) { - public PieceWhiteChecker(BaseBoard board) : base(0x3584, board) - { - } - - public PieceWhiteChecker(Serial serial) : base(serial) - { - } - - public override string DefaultName => "white checker"; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } } - public class PieceBlackChecker : BasePiece - { - public PieceBlackChecker(BaseBoard board) : base(0x358B, board) - { - } - - public PieceBlackChecker(Serial serial) : base(serial) - { - } - - public override string DefaultName => "black checker"; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } - } + public override string DefaultName => "white checker"; +} + +[SerializationGenerator(0, false)] +public partial class PieceBlackChecker : BasePiece +{ + public PieceBlackChecker(BaseBoard board) : base(0x358B, board) + { + } + + public override string DefaultName => "black checker"; } diff --git a/Projects/UOContent/Items/Games/ChessPieces.cs b/Projects/UOContent/Items/Games/ChessPieces.cs index 01b76c21e..6da1afde2 100644 --- a/Projects/UOContent/Items/Games/ChessPieces.cs +++ b/Projects/UOContent/Items/Games/ChessPieces.cs @@ -1,302 +1,123 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class PieceWhiteKing : BasePiece { - public class PieceWhiteKing : BasePiece + public PieceWhiteKing(BaseBoard board) : base(0x3587, board) { - public PieceWhiteKing(BaseBoard board) : base(0x3587, board) - { - } - - public PieceWhiteKing(Serial serial) : base(serial) - { - } - - public override string DefaultName => "white king"; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } } - public class PieceBlackKing : BasePiece - { - public PieceBlackKing(BaseBoard board) : base(0x358E, board) - { - } - - public PieceBlackKing(Serial serial) : base(serial) - { - } - - public override string DefaultName => "black king"; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } - } - - public class PieceWhiteQueen : BasePiece - { - public PieceWhiteQueen(BaseBoard board) : base(0x358A, board) - { - } - - public PieceWhiteQueen(Serial serial) : base(serial) - { - } - - public override string DefaultName => "white queen"; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } - } - - public class PieceBlackQueen : BasePiece - { - public PieceBlackQueen(BaseBoard board) : base(0x3591, board) - { - } - - public PieceBlackQueen(Serial serial) : base(serial) - { - } - - public override string DefaultName => "black queen"; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } - } - - public class PieceWhiteRook : BasePiece - { - public PieceWhiteRook(BaseBoard board) : base(0x3586, board) - { - } - - public PieceWhiteRook(Serial serial) : base(serial) - { - } - - public override string DefaultName => "white rook"; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } - } - - public class PieceBlackRook : BasePiece - { - public PieceBlackRook(BaseBoard board) : base(0x358D, board) - { - } - - public PieceBlackRook(Serial serial) : base(serial) - { - } - - public override string DefaultName => "black rook"; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } - } - - public class PieceWhiteBishop : BasePiece - { - public PieceWhiteBishop(BaseBoard board) : base(0x3585, board) - { - } - - public PieceWhiteBishop(Serial serial) : base(serial) - { - } - - public override string DefaultName => "white bishop"; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } - } - - public class PieceBlackBishop : BasePiece - { - public PieceBlackBishop(BaseBoard board) : base(0x358C, board) - { - } - - public PieceBlackBishop(Serial serial) : base(serial) - { - } - - public override string DefaultName => "black bishop"; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } - } - - public class PieceWhiteKnight : BasePiece - { - public PieceWhiteKnight(BaseBoard board) : base(0x3588, board) - { - } - - public PieceWhiteKnight(Serial serial) : base(serial) - { - } - - public override string DefaultName => "white knight"; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } - } - - public class PieceBlackKnight : BasePiece - { - public PieceBlackKnight(BaseBoard board) : base(0x358F, board) - { - } - - public PieceBlackKnight(Serial serial) : base(serial) - { - } - - public override string DefaultName => "black knight"; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } - } - - public class PieceWhitePawn : BasePiece - { - public PieceWhitePawn(BaseBoard board) : base(0x3589, board) - { - } - - public PieceWhitePawn(Serial serial) : base(serial) - { - } - - public override string DefaultName => "white pawn"; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } - } - - public class PieceBlackPawn : BasePiece - { - public PieceBlackPawn(BaseBoard board) : base(0x3590, board) - { - } - - public PieceBlackPawn(Serial serial) : base(serial) - { - } - - public override string DefaultName => "black pawn"; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } - } + public override string DefaultName => "white king"; +} + +[SerializationGenerator(0, false)] +public partial class PieceBlackKing : BasePiece +{ + public PieceBlackKing(BaseBoard board) : base(0x358E, board) + { + } + + public override string DefaultName => "black king"; +} + +[SerializationGenerator(0, false)] +public partial class PieceWhiteQueen : BasePiece +{ + public PieceWhiteQueen(BaseBoard board) : base(0x358A, board) + { + } + + public override string DefaultName => "white queen"; +} + +[SerializationGenerator(0, false)] +public partial class PieceBlackQueen : BasePiece +{ + public PieceBlackQueen(BaseBoard board) : base(0x3591, board) + { + } + + public override string DefaultName => "black queen"; +} + +[SerializationGenerator(0, false)] +public partial class PieceWhiteRook : BasePiece +{ + public PieceWhiteRook(BaseBoard board) : base(0x3586, board) + { + } + + public override string DefaultName => "white rook"; +} + +[SerializationGenerator(0, false)] +public partial class PieceBlackRook : BasePiece +{ + public PieceBlackRook(BaseBoard board) : base(0x358D, board) + { + } + + public override string DefaultName => "black rook"; +} + +[SerializationGenerator(0, false)] +public partial class PieceWhiteBishop : BasePiece +{ + public PieceWhiteBishop(BaseBoard board) : base(0x3585, board) + { + } + + public override string DefaultName => "white bishop"; +} + +[SerializationGenerator(0, false)] +public partial class PieceBlackBishop : BasePiece +{ + public PieceBlackBishop(BaseBoard board) : base(0x358C, board) + { + } + + public override string DefaultName => "black bishop"; +} + +[SerializationGenerator(0, false)] +public partial class PieceWhiteKnight : BasePiece +{ + public PieceWhiteKnight(BaseBoard board) : base(0x3588, board) + { + } + + public override string DefaultName => "white knight"; +} + +[SerializationGenerator(0, false)] +public partial class PieceBlackKnight : BasePiece +{ + public PieceBlackKnight(BaseBoard board) : base(0x358F, board) + { + } + + public override string DefaultName => "black knight"; +} + +[SerializationGenerator(0, false)] +public partial class PieceWhitePawn : BasePiece +{ + public PieceWhitePawn(BaseBoard board) : base(0x3589, board) + { + } + + public override string DefaultName => "white pawn"; +} + +[SerializationGenerator(0, false)] +public partial class PieceBlackPawn : BasePiece +{ + public PieceBlackPawn(BaseBoard board) : base(0x3590, board) + { + } + + public override string DefaultName => "black pawn"; } diff --git a/Projects/UOContent/Items/Games/Chessboard.cs b/Projects/UOContent/Items/Games/Chessboard.cs index 5ac9e4141..b09f89ee6 100644 --- a/Projects/UOContent/Items/Games/Chessboard.cs +++ b/Projects/UOContent/Items/Games/Chessboard.cs @@ -1,66 +1,52 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class Chessboard : BaseBoard { - public class Chessboard : BaseBoard + [Constructible] + public Chessboard() : base(0xFA6) { - [Constructible] - public Chessboard() : base(0xFA6) + } + + public override int LabelNumber => 1016450; // a chessboard + + public override void CreatePieces() + { + for (var i = 0; i < 8; i++) { + CreatePiece(new PieceBlackPawn(this), 67, 25 * i + 17); + CreatePiece(new PieceWhitePawn(this), 192, 25 * i + 17); } - public Chessboard(Serial serial) : base(serial) - { - } + // Rook + CreatePiece(new PieceBlackRook(this), 42, 5); + CreatePiece(new PieceBlackRook(this), 42, 180); - public override int LabelNumber => 1016450; // a chessboard + CreatePiece(new PieceWhiteRook(this), 216, 5); + CreatePiece(new PieceWhiteRook(this), 216, 180); - public override void CreatePieces() - { - for (var i = 0; i < 8; i++) - { - CreatePiece(new PieceBlackPawn(this), 67, 25 * i + 17); - CreatePiece(new PieceWhitePawn(this), 192, 25 * i + 17); - } + // Knight + CreatePiece(new PieceBlackKnight(this), 42, 30); + CreatePiece(new PieceBlackKnight(this), 42, 155); - // Rook - CreatePiece(new PieceBlackRook(this), 42, 5); - CreatePiece(new PieceBlackRook(this), 42, 180); + CreatePiece(new PieceWhiteKnight(this), 216, 30); + CreatePiece(new PieceWhiteKnight(this), 216, 155); - CreatePiece(new PieceWhiteRook(this), 216, 5); - CreatePiece(new PieceWhiteRook(this), 216, 180); + // Bishop + CreatePiece(new PieceBlackBishop(this), 42, 55); + CreatePiece(new PieceBlackBishop(this), 42, 130); - // Knight - CreatePiece(new PieceBlackKnight(this), 42, 30); - CreatePiece(new PieceBlackKnight(this), 42, 155); + CreatePiece(new PieceWhiteBishop(this), 216, 55); + CreatePiece(new PieceWhiteBishop(this), 216, 130); - CreatePiece(new PieceWhiteKnight(this), 216, 30); - CreatePiece(new PieceWhiteKnight(this), 216, 155); + // Queen + CreatePiece(new PieceBlackQueen(this), 42, 105); + CreatePiece(new PieceWhiteQueen(this), 216, 105); - // Bishop - CreatePiece(new PieceBlackBishop(this), 42, 55); - CreatePiece(new PieceBlackBishop(this), 42, 130); - - CreatePiece(new PieceWhiteBishop(this), 216, 55); - CreatePiece(new PieceWhiteBishop(this), 216, 130); - - // Queen - CreatePiece(new PieceBlackQueen(this), 42, 105); - CreatePiece(new PieceWhiteQueen(this), 216, 105); - - // King - CreatePiece(new PieceBlackKing(this), 42, 80); - CreatePiece(new PieceWhiteKing(this), 216, 80); - } - - 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(); - } + // King + CreatePiece(new PieceBlackKing(this), 42, 80); + CreatePiece(new PieceWhiteKing(this), 216, 80); } } diff --git a/Projects/UOContent/Items/Games/Dices.cs b/Projects/UOContent/Items/Games/Dices.cs index e277a8e54..0cd9cf22e 100644 --- a/Projects/UOContent/Items/Games/Dices.cs +++ b/Projects/UOContent/Items/Games/Dices.cs @@ -1,54 +1,39 @@ +using ModernUO.Serialization; using Server.Network; -namespace Server.Items +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class Dices : Item, ITelekinesisable { - public class Dices : Item, ITelekinesisable + [Constructible] + public Dices() : base(0xFA7) => Weight = 1.0; + + public void OnTelekinesis(Mobile from) { - [Constructible] - public Dices() : base(0xFA7) => Weight = 1.0; + Effects.SendLocationParticles(EffectItem.Create(Location, Map, EffectItem.DefaultDuration), 0x376A, 9, 32, 5022); + Effects.PlaySound(Location, Map, 0x1F5); - public Dices(Serial serial) : base(serial) + Roll(from); + } + + public override void OnDoubleClick(Mobile from) + { + if (!from.InRange(GetWorldLocation(), 2)) { + return; } - public void OnTelekinesis(Mobile from) - { - Effects.SendLocationParticles(EffectItem.Create(Location, Map, EffectItem.DefaultDuration), 0x376A, 9, 32, 5022); - Effects.PlaySound(Location, Map, 0x1F5); + Roll(from); + } - Roll(from); - } - - public override void OnDoubleClick(Mobile from) - { - if (!from.InRange(GetWorldLocation(), 2)) - { - return; - } - - Roll(from); - } - - public void Roll(Mobile from) - { - PublicOverheadMessage( - MessageType.Regular, - 0, - false, - $"*{from.Name} rolls {Utility.Random(1, 6)}, {Utility.Random(1, 6)}*" - ); - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } + public void Roll(Mobile from) + { + PublicOverheadMessage( + MessageType.Regular, + 0, + false, + $"*{from.Name} rolls {Utility.Random(1, 6)}, {Utility.Random(1, 6)}*" + ); } } diff --git a/Projects/UOContent/Migrations/Server.Items.Backgammon.v0.json b/Projects/UOContent/Migrations/Server.Items.Backgammon.v0.json new file mode 100644 index 000000000..b5b6599dd --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Backgammon.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Backgammon" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.BaseBoard.v2.json b/Projects/UOContent/Migrations/Server.Items.BaseBoard.v2.json new file mode 100644 index 000000000..75c01eb01 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.BaseBoard.v2.json @@ -0,0 +1,11 @@ +{ + "version": 2, + "type": "Server.Items.BaseBoard", + "properties": [ + { + "name": "Level", + "type": "Server.Multis.SecureLevel", + "rule": "EnumMigrationRule" + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.BasePiece.v0.json b/Projects/UOContent/Migrations/Server.Items.BasePiece.v0.json new file mode 100644 index 000000000..25ebbe0f5 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.BasePiece.v0.json @@ -0,0 +1,11 @@ +{ + "version": 0, + "type": "Server.Items.BasePiece", + "properties": [ + { + "name": "Board", + "type": "Server.Items.BaseBoard", + "rule": "SerializableInterfaceMigrationRule" + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.CheckerBoard.v0.json b/Projects/UOContent/Migrations/Server.Items.CheckerBoard.v0.json new file mode 100644 index 000000000..be1070419 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.CheckerBoard.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.CheckerBoard" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Chessboard.v0.json b/Projects/UOContent/Migrations/Server.Items.Chessboard.v0.json new file mode 100644 index 000000000..3956ffa9e --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Chessboard.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Chessboard" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Dices.v0.json b/Projects/UOContent/Migrations/Server.Items.Dices.v0.json new file mode 100644 index 000000000..3097cfff5 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Dices.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Dices" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.PieceBlackBishop.v0.json b/Projects/UOContent/Migrations/Server.Items.PieceBlackBishop.v0.json new file mode 100644 index 000000000..5f8df22fe --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.PieceBlackBishop.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.PieceBlackBishop" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.PieceBlackChecker.v0.json b/Projects/UOContent/Migrations/Server.Items.PieceBlackChecker.v0.json new file mode 100644 index 000000000..5179c0e65 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.PieceBlackChecker.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.PieceBlackChecker" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.PieceBlackKing.v0.json b/Projects/UOContent/Migrations/Server.Items.PieceBlackKing.v0.json new file mode 100644 index 000000000..1c595a4ce --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.PieceBlackKing.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.PieceBlackKing" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.PieceBlackKnight.v0.json b/Projects/UOContent/Migrations/Server.Items.PieceBlackKnight.v0.json new file mode 100644 index 000000000..12c0c2b30 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.PieceBlackKnight.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.PieceBlackKnight" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.PieceBlackPawn.v0.json b/Projects/UOContent/Migrations/Server.Items.PieceBlackPawn.v0.json new file mode 100644 index 000000000..e875fddd4 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.PieceBlackPawn.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.PieceBlackPawn" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.PieceBlackQueen.v0.json b/Projects/UOContent/Migrations/Server.Items.PieceBlackQueen.v0.json new file mode 100644 index 000000000..bbde0e9e7 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.PieceBlackQueen.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.PieceBlackQueen" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.PieceBlackRook.v0.json b/Projects/UOContent/Migrations/Server.Items.PieceBlackRook.v0.json new file mode 100644 index 000000000..8f34dceb3 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.PieceBlackRook.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.PieceBlackRook" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.PieceWhiteBishop.v0.json b/Projects/UOContent/Migrations/Server.Items.PieceWhiteBishop.v0.json new file mode 100644 index 000000000..28de1dca9 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.PieceWhiteBishop.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.PieceWhiteBishop" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.PieceWhiteChecker.v0.json b/Projects/UOContent/Migrations/Server.Items.PieceWhiteChecker.v0.json new file mode 100644 index 000000000..0d0049e99 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.PieceWhiteChecker.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.PieceWhiteChecker" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.PieceWhiteKing.v0.json b/Projects/UOContent/Migrations/Server.Items.PieceWhiteKing.v0.json new file mode 100644 index 000000000..e26819c8c --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.PieceWhiteKing.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.PieceWhiteKing" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.PieceWhiteKnight.v0.json b/Projects/UOContent/Migrations/Server.Items.PieceWhiteKnight.v0.json new file mode 100644 index 000000000..d550344f1 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.PieceWhiteKnight.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.PieceWhiteKnight" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.PieceWhitePawn.v0.json b/Projects/UOContent/Migrations/Server.Items.PieceWhitePawn.v0.json new file mode 100644 index 000000000..f3921fda1 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.PieceWhitePawn.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.PieceWhitePawn" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.PieceWhiteQueen.v0.json b/Projects/UOContent/Migrations/Server.Items.PieceWhiteQueen.v0.json new file mode 100644 index 000000000..2e8b7aa57 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.PieceWhiteQueen.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.PieceWhiteQueen" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.PieceWhiteRook.v0.json b/Projects/UOContent/Migrations/Server.Items.PieceWhiteRook.v0.json new file mode 100644 index 000000000..807f09712 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.PieceWhiteRook.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.PieceWhiteRook" +} \ No newline at end of file From a07c42fc853d2a65fc24bd82eda11b3ccac06ec7 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Mon, 13 Jun 2022 17:38:46 -0700 Subject: [PATCH 192/213] fix: Codegens gems (#1059) --- Projects/UOContent/Items/Gems/Amber.cs | 40 ++++++------------- Projects/UOContent/Items/Gems/Amethyst.cs | 40 ++++++------------- Projects/UOContent/Items/Gems/Citrine.cs | 40 ++++++------------- Projects/UOContent/Items/Gems/Diamond.cs | 40 ++++++------------- Projects/UOContent/Items/Gems/Emerald.cs | 40 ++++++------------- Projects/UOContent/Items/Gems/Ruby.cs | 40 ++++++------------- Projects/UOContent/Items/Gems/Sapphire.cs | 40 ++++++------------- Projects/UOContent/Items/Gems/StarSapphire.cs | 40 ++++++------------- Projects/UOContent/Items/Gems/Tourmaline.cs | 40 ++++++------------- .../Migrations/Server.Items.Amber.v0.json | 4 ++ .../Migrations/Server.Items.Amethyst.v0.json | 4 ++ .../Migrations/Server.Items.Citrine.v0.json | 4 ++ .../Migrations/Server.Items.Diamond.v0.json | 4 ++ .../Migrations/Server.Items.Emerald.v0.json | 4 ++ .../Migrations/Server.Items.Ruby.v0.json | 4 ++ .../Migrations/Server.Items.Sapphire.v0.json | 4 ++ .../Server.Items.StarSapphire.v0.json | 4 ++ .../Server.Items.Tourmaline.v0.json | 4 ++ 18 files changed, 144 insertions(+), 252 deletions(-) create mode 100644 Projects/UOContent/Migrations/Server.Items.Amber.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Amethyst.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Citrine.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Diamond.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Emerald.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Ruby.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Sapphire.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.StarSapphire.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Tourmaline.v0.json diff --git a/Projects/UOContent/Items/Gems/Amber.cs b/Projects/UOContent/Items/Gems/Amber.cs index d811421cf..99760ef19 100644 --- a/Projects/UOContent/Items/Gems/Amber.cs +++ b/Projects/UOContent/Items/Gems/Amber.cs @@ -1,32 +1,16 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class Amber : Item { - public class Amber : Item + [Constructible] + public Amber(int amount = 1) : base(0xF25) { - [Constructible] - public Amber(int amount = 1) : base(0xF25) - { - Stackable = true; - Amount = amount; - } - - public Amber(Serial serial) : base(serial) - { - } - - public override double DefaultWeight => 0.1; - - 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(); - } + Stackable = true; + Amount = amount; } + + public override double DefaultWeight => 0.1; } diff --git a/Projects/UOContent/Items/Gems/Amethyst.cs b/Projects/UOContent/Items/Gems/Amethyst.cs index 99f684cc7..4e1cefd0d 100644 --- a/Projects/UOContent/Items/Gems/Amethyst.cs +++ b/Projects/UOContent/Items/Gems/Amethyst.cs @@ -1,32 +1,16 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class Amethyst : Item { - public class Amethyst : Item + [Constructible] + public Amethyst(int amount = 1) : base(0xF16) { - [Constructible] - public Amethyst(int amount = 1) : base(0xF16) - { - Stackable = true; - Amount = amount; - } - - public Amethyst(Serial serial) : base(serial) - { - } - - public override double DefaultWeight => 0.1; - - 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(); - } + Stackable = true; + Amount = amount; } + + public override double DefaultWeight => 0.1; } diff --git a/Projects/UOContent/Items/Gems/Citrine.cs b/Projects/UOContent/Items/Gems/Citrine.cs index 2f87a0462..cd06a3713 100644 --- a/Projects/UOContent/Items/Gems/Citrine.cs +++ b/Projects/UOContent/Items/Gems/Citrine.cs @@ -1,32 +1,16 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class Citrine : Item { - public class Citrine : Item + [Constructible] + public Citrine(int amount = 1) : base(0xF15) { - [Constructible] - public Citrine(int amount = 1) : base(0xF15) - { - Stackable = true; - Amount = amount; - } - - public Citrine(Serial serial) : base(serial) - { - } - - public override double DefaultWeight => 0.1; - - 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(); - } + Stackable = true; + Amount = amount; } + + public override double DefaultWeight => 0.1; } diff --git a/Projects/UOContent/Items/Gems/Diamond.cs b/Projects/UOContent/Items/Gems/Diamond.cs index 22802ba8e..22194b60c 100644 --- a/Projects/UOContent/Items/Gems/Diamond.cs +++ b/Projects/UOContent/Items/Gems/Diamond.cs @@ -1,32 +1,16 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class Diamond : Item { - public class Diamond : Item + [Constructible] + public Diamond(int amount = 1) : base(0xF26) { - [Constructible] - public Diamond(int amount = 1) : base(0xF26) - { - Stackable = true; - Amount = amount; - } - - public Diamond(Serial serial) : base(serial) - { - } - - public override double DefaultWeight => 0.1; - - 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(); - } + Stackable = true; + Amount = amount; } + + public override double DefaultWeight => 0.1; } diff --git a/Projects/UOContent/Items/Gems/Emerald.cs b/Projects/UOContent/Items/Gems/Emerald.cs index 90bde6ffc..de02a09dd 100644 --- a/Projects/UOContent/Items/Gems/Emerald.cs +++ b/Projects/UOContent/Items/Gems/Emerald.cs @@ -1,32 +1,16 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class Emerald : Item { - public class Emerald : Item + [Constructible] + public Emerald(int amount = 1) : base(0xF10) { - [Constructible] - public Emerald(int amount = 1) : base(0xF10) - { - Stackable = true; - Amount = amount; - } - - public Emerald(Serial serial) : base(serial) - { - } - - public override double DefaultWeight => 0.1; - - 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(); - } + Stackable = true; + Amount = amount; } + + public override double DefaultWeight => 0.1; } diff --git a/Projects/UOContent/Items/Gems/Ruby.cs b/Projects/UOContent/Items/Gems/Ruby.cs index 536f2a06b..9d2712818 100644 --- a/Projects/UOContent/Items/Gems/Ruby.cs +++ b/Projects/UOContent/Items/Gems/Ruby.cs @@ -1,32 +1,16 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class Ruby : Item { - public class Ruby : Item + [Constructible] + public Ruby(int amount = 1) : base(0xF13) { - [Constructible] - public Ruby(int amount = 1) : base(0xF13) - { - Stackable = true; - Amount = amount; - } - - public Ruby(Serial serial) : base(serial) - { - } - - public override double DefaultWeight => 0.1; - - 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(); - } + Stackable = true; + Amount = amount; } + + public override double DefaultWeight => 0.1; } diff --git a/Projects/UOContent/Items/Gems/Sapphire.cs b/Projects/UOContent/Items/Gems/Sapphire.cs index a43a7b7f5..870e4346a 100644 --- a/Projects/UOContent/Items/Gems/Sapphire.cs +++ b/Projects/UOContent/Items/Gems/Sapphire.cs @@ -1,32 +1,16 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class Sapphire : Item { - public class Sapphire : Item + [Constructible] + public Sapphire(int amount = 1) : base(0xF19) { - [Constructible] - public Sapphire(int amount = 1) : base(0xF19) - { - Stackable = true; - Amount = amount; - } - - public Sapphire(Serial serial) : base(serial) - { - } - - public override double DefaultWeight => 0.1; - - 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(); - } + Stackable = true; + Amount = amount; } + + public override double DefaultWeight => 0.1; } diff --git a/Projects/UOContent/Items/Gems/StarSapphire.cs b/Projects/UOContent/Items/Gems/StarSapphire.cs index 04f2aa463..06e464600 100644 --- a/Projects/UOContent/Items/Gems/StarSapphire.cs +++ b/Projects/UOContent/Items/Gems/StarSapphire.cs @@ -1,32 +1,16 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class StarSapphire : Item { - public class StarSapphire : Item + [Constructible] + public StarSapphire(int amount = 1) : base(0xF21) { - [Constructible] - public StarSapphire(int amount = 1) : base(0xF21) - { - Stackable = true; - Amount = amount; - } - - public StarSapphire(Serial serial) : base(serial) - { - } - - public override double DefaultWeight => 0.1; - - 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(); - } + Stackable = true; + Amount = amount; } + + public override double DefaultWeight => 0.1; } diff --git a/Projects/UOContent/Items/Gems/Tourmaline.cs b/Projects/UOContent/Items/Gems/Tourmaline.cs index c17503f80..8ead4268e 100644 --- a/Projects/UOContent/Items/Gems/Tourmaline.cs +++ b/Projects/UOContent/Items/Gems/Tourmaline.cs @@ -1,32 +1,16 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class Tourmaline : Item { - public class Tourmaline : Item + [Constructible] + public Tourmaline(int amount = 1) : base(0xF2D) { - [Constructible] - public Tourmaline(int amount = 1) : base(0xF2D) - { - Stackable = true; - Amount = amount; - } - - public Tourmaline(Serial serial) : base(serial) - { - } - - public override double DefaultWeight => 0.1; - - 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(); - } + Stackable = true; + Amount = amount; } + + public override double DefaultWeight => 0.1; } diff --git a/Projects/UOContent/Migrations/Server.Items.Amber.v0.json b/Projects/UOContent/Migrations/Server.Items.Amber.v0.json new file mode 100644 index 000000000..9d44ba15c --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Amber.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Amber" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Amethyst.v0.json b/Projects/UOContent/Migrations/Server.Items.Amethyst.v0.json new file mode 100644 index 000000000..af9bad81e --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Amethyst.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Amethyst" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Citrine.v0.json b/Projects/UOContent/Migrations/Server.Items.Citrine.v0.json new file mode 100644 index 000000000..8afa812e6 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Citrine.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Citrine" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Diamond.v0.json b/Projects/UOContent/Migrations/Server.Items.Diamond.v0.json new file mode 100644 index 000000000..16cfb07fe --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Diamond.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Diamond" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Emerald.v0.json b/Projects/UOContent/Migrations/Server.Items.Emerald.v0.json new file mode 100644 index 000000000..84c2f40e9 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Emerald.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Emerald" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Ruby.v0.json b/Projects/UOContent/Migrations/Server.Items.Ruby.v0.json new file mode 100644 index 000000000..d98101a7c --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Ruby.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Ruby" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Sapphire.v0.json b/Projects/UOContent/Migrations/Server.Items.Sapphire.v0.json new file mode 100644 index 000000000..a12b238df --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Sapphire.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Sapphire" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.StarSapphire.v0.json b/Projects/UOContent/Migrations/Server.Items.StarSapphire.v0.json new file mode 100644 index 000000000..a72f1d8d8 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.StarSapphire.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.StarSapphire" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Tourmaline.v0.json b/Projects/UOContent/Migrations/Server.Items.Tourmaline.v0.json new file mode 100644 index 000000000..56572c492 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Tourmaline.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Tourmaline" +} \ No newline at end of file From fd2d47cd75db94b94f9b21b5fbd80e94f5adb86d Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Mon, 13 Jun 2022 17:39:43 -0700 Subject: [PATCH 193/213] chore: Removes MacOS 10 from CI/CD (#1060) --- .github/workflows/build-test.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 119e2e0bc..bfc63eaa8 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -14,8 +14,6 @@ jobs: fail-fast: false matrix: include: - - os: macos-latest - name: MacOS 10 - os: macos-11 name: MacOS 11 - os: macos-12 From 3594e97109060c2cc8f70d4bbe11a5685c1512fe Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Mon, 13 Jun 2022 23:28:33 -0700 Subject: [PATCH 194/213] fix: Updates serialization generator (#1062) Updates the serialization and schema generators to a considerably more optimized version. --- .config/dotnet-tools.json | 2 +- Directory.Build.props | 2 +- Projects/Server/Server.csproj | 2 +- Projects/UOContent/UOContent.csproj | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index c0b05674e..daaf31f85 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "modernuoschemagenerator": { - "version": "2.0.5", + "version": "2.1.0", "commands": [ "ModernUOSchemaGenerator" ] diff --git a/Directory.Build.props b/Directory.Build.props index c0a882066..5b23e4a72 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -59,7 +59,7 @@ - 3.5.104 + 3.5.107 all diff --git a/Projects/Server/Server.csproj b/Projects/Server/Server.csproj index c1eaa1ceb..a90755287 100755 --- a/Projects/Server/Server.csproj +++ b/Projects/Server/Server.csproj @@ -41,7 +41,7 @@ - + diff --git a/Projects/UOContent/UOContent.csproj b/Projects/UOContent/UOContent.csproj index 89015f409..40165f53b 100755 --- a/Projects/UOContent/UOContent.csproj +++ b/Projects/UOContent/UOContent.csproj @@ -38,7 +38,7 @@ false - + @@ -46,7 +46,7 @@ - + From c1cc1308a5a35f76140b929a081677d7f9ae8e60 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Tue, 14 Jun 2022 08:29:00 -0700 Subject: [PATCH 195/213] fix: Codegens guildstone and jewelery (#1061) --- Projects/UOContent/Items/Games/BaseBoard.cs | 2 - Projects/UOContent/Items/Guilds/GuildDeed.cs | 152 ++- .../UOContent/Items/Guilds/GuildTeleporter.cs | 124 +-- Projects/UOContent/Items/Guilds/Guildstone.cs | 689 ++++++-------- .../Jewels/Artifacts/BraceletOfHealth.cs | 44 +- .../Artifacts/Craftable/EssenceOfBattle.cs | 44 +- .../Artifacts/Craftable/PendantOfTheMagi.cs | 48 +- .../Artifacts/Craftable/ResillientBracer.cs | 50 +- .../Jewels/Artifacts/OrnamentOfTheMagician.cs | 55 +- .../Jewels/Artifacts/RingOfTheElements.cs | 50 +- .../Items/Jewels/Artifacts/RingOfTheVile.cs | 53 +- Projects/UOContent/Items/Jewels/BaseJewel.cs | 885 ++++++++---------- Projects/UOContent/Items/Jewels/Beads.cs | 30 +- Projects/UOContent/Items/Jewels/Bracelet.cs | 94 +- Projects/UOContent/Items/Jewels/Earrings.cs | 94 +- Projects/UOContent/Items/Jewels/Necklace.cs | 187 +--- Projects/UOContent/Items/Jewels/Ring.cs | 94 +- .../Server.Items.BaseBracelet.v0.json | 4 + .../Server.Items.BaseEarrings.v0.json | 4 + .../Migrations/Server.Items.BaseJewel.v4.json | 56 ++ .../Server.Items.BaseNecklace.v0.json | 4 + .../Migrations/Server.Items.BaseRing.v0.json | 4 + .../Migrations/Server.Items.Beads.v0.json | 4 + .../Server.Items.BraceletOfHealth.v0.json | 4 + .../Server.Items.EssenceOfBattle.v0.json | 4 + .../Server.Items.GoldBeadNecklace.v0.json | 4 + .../Server.Items.GoldBracelet.v0.json | 4 + .../Server.Items.GoldEarrings.v0.json | 4 + .../Server.Items.GoldNecklace.v0.json | 4 + .../Migrations/Server.Items.GoldRing.v0.json | 4 + .../Migrations/Server.Items.GuildDeed.v0.json | 4 + .../Server.Items.GuildTeleporter.v0.json | 11 + .../Server.Items.Guildstone.v4.json | 27 + .../Server.Items.GuildstoneDeed.v0.json | 27 + .../Migrations/Server.Items.Necklace.v0.json | 4 + ...Server.Items.OrnamentOfTheMagician.v0.json | 4 + .../Server.Items.PendantOfTheMagi.v0.json | 4 + .../Server.Items.ResilientBracer.v0.json | 4 + .../Server.Items.RingOfTheElements.v0.json | 4 + .../Server.Items.RingOfTheVile.v0.json | 4 + .../Server.Items.SilverBeadNecklace.v0.json | 4 + .../Server.Items.SilverBracelet.v0.json | 4 + .../Server.Items.SilverEarrings.v0.json | 4 + .../Server.Items.SilverNecklace.v0.json | 4 + .../Server.Items.SilverRing.v0.json | 4 + 45 files changed, 1239 insertions(+), 1673 deletions(-) create mode 100644 Projects/UOContent/Migrations/Server.Items.BaseBracelet.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.BaseEarrings.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.BaseJewel.v4.json create mode 100644 Projects/UOContent/Migrations/Server.Items.BaseNecklace.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.BaseRing.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Beads.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.BraceletOfHealth.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.EssenceOfBattle.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.GoldBeadNecklace.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.GoldBracelet.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.GoldEarrings.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.GoldNecklace.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.GoldRing.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.GuildDeed.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.GuildTeleporter.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Guildstone.v4.json create mode 100644 Projects/UOContent/Migrations/Server.Items.GuildstoneDeed.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Necklace.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.OrnamentOfTheMagician.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.PendantOfTheMagi.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.ResilientBracer.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.RingOfTheElements.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.RingOfTheVile.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.SilverBeadNecklace.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.SilverBracelet.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.SilverEarrings.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.SilverNecklace.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.SilverRing.v0.json diff --git a/Projects/UOContent/Items/Games/BaseBoard.cs b/Projects/UOContent/Items/Games/BaseBoard.cs index 869402f70..be9194b7a 100644 --- a/Projects/UOContent/Items/Games/BaseBoard.cs +++ b/Projects/UOContent/Items/Games/BaseBoard.cs @@ -51,8 +51,6 @@ public abstract partial class BaseBoard : Container, ISecurable private void Deserialize(IGenericReader reader, int version) { - base.Deserialize(reader); - if (version == 1) { Level = (SecureLevel)reader.ReadInt(); diff --git a/Projects/UOContent/Items/Guilds/GuildDeed.cs b/Projects/UOContent/Items/Guilds/GuildDeed.cs index 4413b4bbc..ac0869a71 100644 --- a/Projects/UOContent/Items/Guilds/GuildDeed.cs +++ b/Projects/UOContent/Items/Guilds/GuildDeed.cs @@ -1,47 +1,71 @@ +using ModernUO.Serialization; using Server.Guilds; using Server.Multis; using Server.Prompts; -namespace Server.Items +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class GuildDeed : Item { - public class GuildDeed : Item + [Constructible] + public GuildDeed() : base(0x14F0) => Weight = 1.0; + + public override int LabelNumber => 1041055; // a guild deed + + public override void OnDoubleClick(Mobile from) { - [Constructible] - public GuildDeed() : base(0x14F0) => Weight = 1.0; - - public GuildDeed(Serial serial) : base(serial) + if (Guild.NewGuildSystem) { + return; } - public override int LabelNumber => 1041055; // a guild deed - - public override void Serialize(IGenericWriter writer) + if (!IsChildOf(from.Backpack)) { - base.Serialize(writer); - - writer.Write(0); // version + from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it. } - - public override void Deserialize(IGenericReader reader) + else if (from.Guild != null) { - base.Deserialize(reader); + from.SendLocalizedMessage(501137); // You must resign from your current guild before founding another! + } + else + { + var house = BaseHouse.FindHouseAt(from); - var version = reader.ReadInt(); - - if (Weight == 0.0) + if (house == null) { - Weight = 1.0; + from.SendLocalizedMessage(501138); // You can only place a guildstone in a house. + } + else if (house.FindGuildstone() != null) + { + from.SendLocalizedMessage(501142); // Only one guildstone may reside in a given house. + } + else if (!house.IsOwner(from)) + { + from.SendLocalizedMessage(501141); // You can only place a guildstone in a house you own! + } + else + { + from.SendLocalizedMessage(1013060); // Enter new guild name (40 characters max): + from.Prompt = new InternalPrompt(this); } } + } - public override void OnDoubleClick(Mobile from) + private class InternalPrompt : Prompt + { + private readonly GuildDeed m_Deed; + + public InternalPrompt(GuildDeed deed) => m_Deed = deed; + + public override void OnResponse(Mobile from, string text) { - if (Guild.NewGuildSystem) + if (m_Deed.Deleted) { return; } - if (!IsChildOf(from.Backpack)) + if (!m_Deed.IsChildOf(from.Backpack)) { from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it. } @@ -67,76 +91,30 @@ namespace Server.Items } else { - from.SendLocalizedMessage(1013060); // Enter new guild name (40 characters max): - from.Prompt = new InternalPrompt(this); + m_Deed.Delete(); + + if (text.Length > 40) + { + text = text[..40]; + } + + var guild = new Guild(from, text, "none"); + + from.Guild = guild; + from.GuildTitle = "Guildmaster"; + + var stone = new Guildstone(guild); + + stone.MoveToWorld(from.Location, from.Map); + + guild.Guildstone = stone; } } } - private class InternalPrompt : Prompt + public override void OnCancel(Mobile from) { - private readonly GuildDeed m_Deed; - - public InternalPrompt(GuildDeed deed) => m_Deed = deed; - - public override void OnResponse(Mobile from, string text) - { - if (m_Deed.Deleted) - { - return; - } - - if (!m_Deed.IsChildOf(from.Backpack)) - { - from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it. - } - else if (from.Guild != null) - { - from.SendLocalizedMessage(501137); // You must resign from your current guild before founding another! - } - else - { - var house = BaseHouse.FindHouseAt(from); - - if (house == null) - { - from.SendLocalizedMessage(501138); // You can only place a guildstone in a house. - } - else if (house.FindGuildstone() != null) - { - from.SendLocalizedMessage(501142); // Only one guildstone may reside in a given house. - } - else if (!house.IsOwner(from)) - { - from.SendLocalizedMessage(501141); // You can only place a guildstone in a house you own! - } - else - { - m_Deed.Delete(); - - if (text.Length > 40) - { - text = text[..40]; - } - - var guild = new Guild(from, text, "none"); - - from.Guild = guild; - from.GuildTitle = "Guildmaster"; - - var stone = new Guildstone(guild); - - stone.MoveToWorld(from.Location, from.Map); - - guild.Guildstone = stone; - } - } - } - - public override void OnCancel(Mobile from) - { - from.SendLocalizedMessage(501145); // Placement of guildstone cancelled. - } + from.SendLocalizedMessage(501145); // Placement of guildstone cancelled. } } } diff --git a/Projects/UOContent/Items/Guilds/GuildTeleporter.cs b/Projects/UOContent/Items/Guilds/GuildTeleporter.cs index 8e2d0555f..81d7efa12 100644 --- a/Projects/UOContent/Items/Guilds/GuildTeleporter.cs +++ b/Projects/UOContent/Items/Guilds/GuildTeleporter.cs @@ -1,101 +1,65 @@ +using ModernUO.Serialization; using Server.Guilds; using Server.Multis; -namespace Server.Items +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class GuildTeleporter : Item { - public class GuildTeleporter : Item + [SerializableField(0)] + private Item _stone; + + [Constructible] + public GuildTeleporter(Item stone = null) : base(0x1869) { - private Item m_Stone; + Weight = 1.0; + LootType = LootType.Blessed; + _stone = stone; + } - [Constructible] - public GuildTeleporter(Item stone = null) : base(0x1869) + public override int LabelNumber => 1041054; // guildstone teleporter + + public override bool DisplayLootType => false; + + public override void OnDoubleClick(Mobile from) + { + if (Guild.NewGuildSystem) { - Weight = 1.0; - LootType = LootType.Blessed; - - m_Stone = stone; + return; } - public GuildTeleporter(Serial serial) : base(serial) + if (!IsChildOf(from.Backpack)) { + from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it. + return; } - public override int LabelNumber => 1041054; // guildstone teleporter - - public override bool DisplayLootType => false; - - public override void Serialize(IGenericWriter writer) + if (_stone is not Guildstone gs || gs.Deleted || gs.Guild?.Teleporter != this) { - base.Serialize(writer); - - writer.Write(0); // version - - writer.Write(m_Stone); + from.SendLocalizedMessage(501197); // This teleporting object can not determine what guildstone to teleport + return; } - public override void Deserialize(IGenericReader reader) + var house = BaseHouse.FindHouseAt(from); + + if (house == null) { - base.Deserialize(reader); - LootType = LootType.Blessed; - - var version = reader.ReadInt(); - - switch (version) - { - case 0: - { - m_Stone = reader.ReadEntity(); - - break; - } - } - - if (Weight == 0.0) - { - Weight = 1.0; - } + from.SendLocalizedMessage(501138); // You can only place a guildstone in a house. } - - public override void OnDoubleClick(Mobile from) + else if (!house.IsOwner(from)) { - if (Guild.NewGuildSystem) - { - return; - } - - var stone = m_Stone as Guildstone; - - if (!IsChildOf(from.Backpack)) - { - from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it. - } - else if (stone?.Deleted != false || stone.Guild?.Teleporter != this) - { - from.SendLocalizedMessage(501197); // This teleporting object can not determine what guildstone to teleport - } - else - { - var house = BaseHouse.FindHouseAt(from); - - if (house == null) - { - from.SendLocalizedMessage(501138); // You can only place a guildstone in a house. - } - else if (!house.IsOwner(from)) - { - from.SendLocalizedMessage(501141); // You can only place a guildstone in a house you own! - } - else if (house.FindGuildstone() != null) - { - from.SendLocalizedMessage(501142); // Only one guildstone may reside in a given house. - } - else - { - m_Stone.MoveToWorld(from.Location, from.Map); - Delete(); - stone.Guild.Teleporter = null; - } - } + from.SendLocalizedMessage(501141); // You can only place a guildstone in a house you own! + } + else if (house.FindGuildstone() != null) + { + from.SendLocalizedMessage(501142); // Only one guildstone may reside in a given house. + } + else + { + gs.MoveToWorld(from.Location, from.Map); + Delete(); + gs.Guild.Teleporter = null; } } } diff --git a/Projects/UOContent/Items/Guilds/Guildstone.cs b/Projects/UOContent/Items/Guilds/Guildstone.cs index 89a53b6c6..adce68a6c 100644 --- a/Projects/UOContent/Items/Guilds/Guildstone.cs +++ b/Projects/UOContent/Items/Guilds/Guildstone.cs @@ -1,3 +1,4 @@ +using ModernUO.Serialization; using Server.Factions; using Server.Guilds; using Server.Gumps; @@ -5,461 +6,311 @@ using Server.Multis; using Server.Network; using Server.Targeting; -namespace Server.Items +namespace Server.Items; + +[SerializationGenerator(4, false)] +public partial class Guildstone : Item, IAddon, IChoppable { - public class Guildstone : Item, IAddon, IChoppable + [InvalidateProperties] + [SerializableField(0)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private string _guildName; + + [InvalidateProperties] + [SerializableField(1)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private string _guildAbbrev; + + [InvalidateProperties] + [SerializableField(2, setter: "private")] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private Guild _guild; + + public Guildstone(Guild g) : this(g, g.Name, g.Abbreviation) { - private bool m_BeforeChangeover; - private string m_GuildAbbrev; - private string m_GuildName; + } - public Guildstone(Guild g) : this(g, g.Name, g.Abbreviation) + public Guildstone(Guild g, string guildName, string abbrev) : base(Guild.NewGuildSystem ? 0xED6 : 0xED4) + { + _guild = g; + _guildName = guildName; + _guildAbbrev = abbrev; + + Movable = false; + } + + public override int LabelNumber => 1041429; // a guildstone + + public Item Deed => new GuildstoneDeed(Guild, _guildName, _guildAbbrev); + + public bool CouldFit(IPoint3D p, Map map) => map.CanFit(p.X, p.Y, p.Z, ItemData.Height); + + public void OnChop(Mobile from) + { + if (!Guild.NewGuildSystem) { + return; } - public Guildstone(Guild g, string guildName, string abbrev) : base(Guild.NewGuildSystem ? 0xED6 : 0xED4) + var house = BaseHouse.FindHouseAt(this); + + if (house?.IsOwner(from) == true && house.Addons.Contains(this)) { - Guild = g; - m_GuildName = guildName; - m_GuildAbbrev = abbrev; + Effects.PlaySound(GetWorldLocation(), Map, 0x3B3); + from.SendLocalizedMessage(500461); // You destroy the item. - Movable = false; - } + Delete(); - public Guildstone(Serial serial) : base(serial) - { - } + house.Addons.Remove(this); - [CommandProperty(AccessLevel.GameMaster)] - public string GuildName - { - get => m_GuildName; - set + var deed = Deed; + + if (deed != null) { - m_GuildName = value; - InvalidateProperties(); - } - } - - [CommandProperty(AccessLevel.GameMaster)] - public string GuildAbbrev - { - get => m_GuildAbbrev; - set - { - m_GuildAbbrev = value; - InvalidateProperties(); - } - } - - [CommandProperty(AccessLevel.GameMaster)] - public Guild Guild { get; private set; } - - public override int LabelNumber => 1041429; // a guildstone - - public Item Deed => new GuildstoneDeed(Guild, m_GuildName, m_GuildAbbrev); - - public bool CouldFit(IPoint3D p, Map map) => map.CanFit(p.X, p.Y, p.Z, ItemData.Height); - - public void OnChop(Mobile from) - { - if (!Guild.NewGuildSystem) - { - return; - } - - var house = BaseHouse.FindHouseAt(this); - - var contains = false; - - if (house == null && m_BeforeChangeover || - house?.IsOwner(from) == true && (contains = house.Addons.Contains(this))) - { - Effects.PlaySound(GetWorldLocation(), Map, 0x3B3); - from.SendLocalizedMessage(500461); // You destroy the item. - - Delete(); - - if (contains) - { - house.Addons.Remove(this); - } - - var deed = Deed; - - if (deed != null) - { - from.AddToBackpack(deed); - } - } - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - if (Guild?.Disbanded == false) - { - m_GuildName = Guild.Name; - m_GuildAbbrev = Guild.Abbreviation; - } - - writer.Write(3); // version - - writer.Write(m_BeforeChangeover); - - writer.Write(m_GuildName); - writer.Write(m_GuildAbbrev); - - writer.Write(Guild); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - switch (version) - { - case 3: - { - m_BeforeChangeover = reader.ReadBool(); - goto case 2; - } - case 2: - { - m_GuildName = reader.ReadString(); - m_GuildAbbrev = reader.ReadString(); - - goto case 1; - } - case 1: - { - Guild = reader.ReadEntity(); - - goto case 0; - } - case 0: - { - break; - } - } - - if (Guild.NewGuildSystem && ItemID == 0xED4) - { - ItemID = 0xED6; - } - - if (version <= 2) - { - m_BeforeChangeover = true; - } - - if (Guild.NewGuildSystem && m_BeforeChangeover) - { - Timer.StartTimer(AddToHouse); - } - - if (!Guild.NewGuildSystem && Guild == null) - { - Delete(); - } - } - - private void AddToHouse() - { - var house = BaseHouse.FindHouseAt(this); - - if (Guild.NewGuildSystem && m_BeforeChangeover && house?.Addons.Contains(this) == false) - { - house.Addons.Add(this); - m_BeforeChangeover = false; - } - } - - public override void GetProperties(IPropertyList list) - { - base.GetProperties(list); - - if (Guild?.Disbanded == false) - { - string name; - string abbr; - - if ((name = Guild.Name) == null || (name = name.Trim()).Length <= 0) - { - name = "(unnamed)"; - } - - if ((abbr = Guild.Abbreviation) == null || (abbr = abbr.Trim()).Length <= 0) - { - abbr = ""; - } - - // list.Add( 1060802, Utility.FixHtml( name ) ); // Guild name: ~1_val~ - list.Add(1060802, $"{Utility.FixHtml(name)} [{Utility.FixHtml(abbr)}]"); - } - else if (m_GuildName != null && m_GuildAbbrev != null) - { - list.Add(1060802, $"{Utility.FixHtml(m_GuildName)} [{Utility.FixHtml(m_GuildAbbrev)}]"); - } - } - - public override void OnSingleClick(Mobile from) - { - base.OnSingleClick(from); - - if (Guild?.Disbanded == false) - { - string name; - - if ((name = Guild.Name) == null || (name = name.Trim()).Length <= 0) - { - name = "(unnamed)"; - } - - LabelTo(from, name); - } - else if (m_GuildName != null) - { - LabelTo(from, m_GuildName); - } - } - - public override void OnAfterDelete() - { - if (!Guild.NewGuildSystem && Guild?.Disbanded == false) - { - Guild.Disband(); - } - } - - public override void OnDoubleClick(Mobile from) - { - if (Guild.NewGuildSystem) - { - return; - } - - if (Guild?.Disbanded != false) - { - Delete(); - } - else if (!from.InRange(GetWorldLocation(), 2)) - { - from.SendLocalizedMessage(500446); // That is too far away. - } - else if (Guild.Accepted.Contains(from)) - { - var guildState = PlayerState.Find(Guild.Leader); - var targetState = PlayerState.Find(from); - - var guildFaction = guildState?.Faction; - var targetFaction = targetState?.Faction; - - if (guildFaction != targetFaction || targetState?.IsLeaving == true) - { - return; - } - - if (guildState != null && targetState != null) - { - targetState.Leaving = guildState.Leaving; - } - - Guild.Accepted.Remove(from); - Guild.AddMember(from); - - GuildGump.EnsureClosed(from); - from.SendGump(new GuildGump(from, Guild)); - } - else if (from.AccessLevel < AccessLevel.GameMaster && !Guild.IsMember(from)) - { - from.NetState.SendMessageLocalized( - Serial, - ItemID, - MessageType.Regular, - 0x3B2, - 3, - 501158 - ); // You are not a member ... - } - else - { - GuildGump.EnsureClosed(from); - from.SendGump(new GuildGump(from, Guild)); + from.AddToBackpack(deed); } } } - [Flippable(0x14F0, 0x14EF)] - public class GuildstoneDeed : Item + private void Deserialize(IGenericReader reader, int version) { - private string m_GuildAbbrev; + reader.ReadBool(); // Before Change Over + _guildName = reader.ReadString(); + _guildAbbrev = reader.ReadString(); + _guild = reader.ReadEntity(); + } - private string m_GuildName; - - [Constructible] - public GuildstoneDeed(Guild g = null, string guildName = null, string abbrev = null) : base(0x14F0) + [AfterDeserialization(false)] + private void AfterDeserialization() + { + if (Guild.NewGuildSystem && ItemID == 0xED4) { - Guild = g; - m_GuildName = guildName; - m_GuildAbbrev = abbrev; - - Weight = 1.0; + ItemID = 0xED6; } - public GuildstoneDeed(Serial serial) : base(serial) + if (!Guild.NewGuildSystem && Guild == null) { + Delete(); + } + } + + public override void GetProperties(IPropertyList list) + { + base.GetProperties(list); + + if (_guild?.Disbanded == false) + { + string name; + string abbr; + + if ((name = _guild.Name) == null || (name = name.Trim()).Length <= 0) + { + name = "(unnamed)"; + } + + if ((abbr = _guild.Abbreviation) == null || (abbr = abbr.Trim()).Length <= 0) + { + abbr = ""; + } + + // list.Add( 1060802, Utility.FixHtml( name ) ); // Guild name: ~1_val~ + list.Add(1060802, $"{Utility.FixHtml(name)} [{Utility.FixHtml(abbr)}]"); + } + else if (_guildName != null && _guildAbbrev != null) + { + list.Add(1060802, $"{Utility.FixHtml(_guildName)} [{Utility.FixHtml(_guildAbbrev)}]"); + } + } + + public override void OnSingleClick(Mobile from) + { + base.OnSingleClick(from); + + if (_guild?.Disbanded == false) + { + string name; + + if ((name = _guild.Name) == null || (name = name.Trim()).Length <= 0) + { + name = "(unnamed)"; + } + + LabelTo(from, name); + } + else if (_guildName != null) + { + LabelTo(from, _guildName); + } + } + + public override void OnAfterDelete() + { + if (!Guild.NewGuildSystem && _guild?.Disbanded == false) + { + _guild.Disband(); + } + } + + public override void OnDoubleClick(Mobile from) + { + if (Guild.NewGuildSystem) + { + return; } - public override int LabelNumber => 1041233; // deed to a guildstone - - [CommandProperty(AccessLevel.GameMaster)] - public string GuildName + if (_guild?.Disbanded != false) { - get => m_GuildName; - set - { - m_GuildName = value; - InvalidateProperties(); - } + Delete(); } - - [CommandProperty(AccessLevel.GameMaster)] - public string GuildAbbrev + else if (!from.InRange(GetWorldLocation(), 2)) { - get => m_GuildAbbrev; - set - { - m_GuildAbbrev = value; - InvalidateProperties(); - } + from.SendLocalizedMessage(500446); // That is too far away. } - - [CommandProperty(AccessLevel.GameMaster)] - public Guild Guild { get; private set; } - - public override void Serialize(IGenericWriter writer) + else if (_guild.Accepted.Contains(from)) { - base.Serialize(writer); + var guildState = PlayerState.Find(_guild.Leader); + var targetState = PlayerState.Find(from); - if (Guild?.Disbanded == false) - { - m_GuildName = Guild.Name; - m_GuildAbbrev = Guild.Abbreviation; - } + var guildFaction = guildState?.Faction; + var targetFaction = targetState?.Faction; - writer.Write(1); // version - - writer.Write(m_GuildName); - writer.Write(m_GuildAbbrev); - - writer.Write(Guild); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - switch (version) - { - case 1: - { - m_GuildName = reader.ReadString(); - m_GuildAbbrev = reader.ReadString(); - - Guild = reader.ReadEntity(); - - break; - } - } - } - - public override void GetProperties(IPropertyList list) - { - base.GetProperties(list); - - if (Guild?.Disbanded == false) - { - string name; - string abbr; - - if ((name = Guild.Name) == null || (name = name.Trim()).Length <= 0) - { - name = "(unnamed)"; - } - - if ((abbr = Guild.Abbreviation) == null || (abbr = abbr.Trim()).Length <= 0) - { - abbr = ""; - } - - // list.Add( 1060802, Utility.FixHtml( name ) ); // Guild name: ~1_val~ - list.Add(1060802, $"{Utility.FixHtml(name)} [{Utility.FixHtml(abbr)}]"); - } - else if (m_GuildName != null && m_GuildAbbrev != null) - { - list.Add(1060802, $"{Utility.FixHtml(m_GuildName)} [{Utility.FixHtml(m_GuildAbbrev)}]"); - } - } - - public override void OnDoubleClick(Mobile from) - { - if (IsChildOf(from.Backpack)) - { - var house = BaseHouse.FindHouseAt(from); - - if (house?.IsOwner(from) == true) - { - from.SendLocalizedMessage(1062838); // Where would you like to place this decoration? - from.BeginTarget(-1, true, TargetFlags.None, Placement_OnTarget); - } - else - { - from.SendLocalizedMessage(502092); // You must be in your house to do this. - } - } - else - { - from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it. - } - } - - public void Placement_OnTarget(Mobile from, object targeted) - { - if (targeted is not IPoint3D p || Deleted) + if (guildFaction != targetFaction || targetState?.IsLeaving == true) { return; } - var loc = new Point3D(p); - - var house = BaseHouse.FindHouseAt(loc, from.Map, 16); - - if (IsChildOf(from.Backpack)) + if (guildState != null && targetState != null) { - if (house?.IsOwner(from) == true) - { - Item addon = new Guildstone(Guild, m_GuildName, m_GuildAbbrev); - - addon.MoveToWorld(loc, from.Map); - - house.Addons.Add(addon); - Delete(); - } - else - { - from.SendLocalizedMessage(1042036); // That location is not in your house. - } - } - else - { - from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it. + targetState.Leaving = guildState.Leaving; } + + _guild.Remove(_guild.Accepted, from); + _guild.AddMember(from); + + GuildGump.EnsureClosed(from); + from.SendGump(new GuildGump(from, Guild)); + } + else if (from.AccessLevel < AccessLevel.GameMaster && !_guild.IsMember(from)) + { + // You are not a member ... + from.NetState.SendMessageLocalized(Serial, ItemID, MessageType.Regular, 0x3B2, 3, 501158); + } + else + { + GuildGump.EnsureClosed(from); + from.SendGump(new GuildGump(from, _guild)); + } + } +} + +[Flippable(0x14F0, 0x14EF)] +[SerializationGenerator(0, false)] +public partial class GuildstoneDeed : Item +{ + [InvalidateProperties] + [SerializableField(0)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private string _guildName; + + [InvalidateProperties] + [SerializableField(1)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private string _guildAbbrev; + + [InvalidateProperties] + [SerializableField(2, setter: "private")] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private Guild _guild; + + [Constructible] + public GuildstoneDeed(Guild g = null, string guildName = null, string abbrev = null) : base(0x14F0) + { + _guild = g; + _guildName = guildName; + _guildAbbrev = abbrev; + + Weight = 1.0; + } + + public override int LabelNumber => 1041233; // deed to a guildstone + + public override void GetProperties(IPropertyList list) + { + base.GetProperties(list); + + if (_guild?.Disbanded == false) + { + string name; + string abbr; + + if ((name = _guild.Name) == null || (name = name.Trim()).Length <= 0) + { + name = "(unnamed)"; + } + + if ((abbr = _guild.Abbreviation) == null || (abbr = abbr.Trim()).Length <= 0) + { + abbr = ""; + } + + // list.Add( 1060802, Utility.FixHtml( name ) ); // Guild name: ~1_val~ + list.Add(1060802, $"{Utility.FixHtml(name)} [{Utility.FixHtml(abbr)}]"); + } + else if (_guildName != null && _guildAbbrev != null) + { + list.Add(1060802, $"{Utility.FixHtml(_guildName)} [{Utility.FixHtml(_guildAbbrev)}]"); + } + } + + public override void OnDoubleClick(Mobile from) + { + if (!IsChildOf(from.Backpack)) + { + from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it. + return; + } + + var house = BaseHouse.FindHouseAt(from); + + if (house?.IsOwner(from) == true) + { + from.SendLocalizedMessage(1062838); // Where would you like to place this decoration? + from.BeginTarget(-1, true, TargetFlags.None, Placement_OnTarget); + } + else + { + from.SendLocalizedMessage(502092); // You must be in your house to do this. + } + } + + public void Placement_OnTarget(Mobile from, object targeted) + { + if (targeted is not IPoint3D p || Deleted) + { + return; + } + + if (!IsChildOf(from.Backpack)) + { + from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it. + return; + } + + var loc = new Point3D(p); + + var house = BaseHouse.FindHouseAt(loc, from.Map, 16); + if (house?.IsOwner(from) == true) + { + Item addon = new Guildstone(_guild, _guildName, _guildAbbrev); + + addon.MoveToWorld(loc, from.Map); + + house.Add(house.Addons, addon); + Delete(); + } + else + { + from.SendLocalizedMessage(1042036); // That location is not in your house. } } } diff --git a/Projects/UOContent/Items/Jewels/Artifacts/BraceletOfHealth.cs b/Projects/UOContent/Items/Jewels/Artifacts/BraceletOfHealth.cs index 6aaf3a314..249e6b333 100644 --- a/Projects/UOContent/Items/Jewels/Artifacts/BraceletOfHealth.cs +++ b/Projects/UOContent/Items/Jewels/Artifacts/BraceletOfHealth.cs @@ -1,34 +1,18 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class BraceletOfHealth : GoldBracelet { - public class BraceletOfHealth : GoldBracelet + [Constructible] + public BraceletOfHealth() { - [Constructible] - public BraceletOfHealth() - { - Hue = 0x21; - Attributes.BonusHits = 5; - Attributes.RegenHits = 10; - } - - public BraceletOfHealth(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1061103; // Bracelet of Health - public override int ArtifactRarity => 11; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } + Hue = 0x21; + Attributes.BonusHits = 5; + Attributes.RegenHits = 10; } + + public override int LabelNumber => 1061103; // Bracelet of Health + public override int ArtifactRarity => 11; } diff --git a/Projects/UOContent/Items/Jewels/Artifacts/Craftable/EssenceOfBattle.cs b/Projects/UOContent/Items/Jewels/Artifacts/Craftable/EssenceOfBattle.cs index 779ba556e..f089442a0 100644 --- a/Projects/UOContent/Items/Jewels/Artifacts/Craftable/EssenceOfBattle.cs +++ b/Projects/UOContent/Items/Jewels/Artifacts/Craftable/EssenceOfBattle.cs @@ -1,34 +1,18 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0)] +public partial class EssenceOfBattle : GoldRing { - public class EssenceOfBattle : GoldRing + [Constructible] + public EssenceOfBattle() { - [Constructible] - public EssenceOfBattle() - { - Hue = 0x550; - Attributes.BonusDex = 7; - Attributes.BonusStr = 7; - Attributes.WeaponDamage = 30; - } - - public EssenceOfBattle(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1072935; // Essence of Battle - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } + Hue = 0x550; + Attributes.BonusDex = 7; + Attributes.BonusStr = 7; + Attributes.WeaponDamage = 30; } + + public override int LabelNumber => 1072935; // Essence of Battle } diff --git a/Projects/UOContent/Items/Jewels/Artifacts/Craftable/PendantOfTheMagi.cs b/Projects/UOContent/Items/Jewels/Artifacts/Craftable/PendantOfTheMagi.cs index 180930246..e32120647 100644 --- a/Projects/UOContent/Items/Jewels/Artifacts/Craftable/PendantOfTheMagi.cs +++ b/Projects/UOContent/Items/Jewels/Artifacts/Craftable/PendantOfTheMagi.cs @@ -1,36 +1,20 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0)] +public partial class PendantOfTheMagi : GoldNecklace { - public class PendantOfTheMagi : GoldNecklace + [Constructible] + public PendantOfTheMagi() { - [Constructible] - public PendantOfTheMagi() - { - Hue = 0x48D; - Attributes.BonusInt = 10; - Attributes.RegenMana = 3; - Attributes.SpellDamage = 5; - Attributes.LowerManaCost = 10; - Attributes.LowerRegCost = 30; - } - - public PendantOfTheMagi(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1072937; // Pendant of the Magi - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } + Hue = 0x48D; + Attributes.BonusInt = 10; + Attributes.RegenMana = 3; + Attributes.SpellDamage = 5; + Attributes.LowerManaCost = 10; + Attributes.LowerRegCost = 30; } + + public override int LabelNumber => 1072937; // Pendant of the Magi } diff --git a/Projects/UOContent/Items/Jewels/Artifacts/Craftable/ResillientBracer.cs b/Projects/UOContent/Items/Jewels/Artifacts/Craftable/ResillientBracer.cs index 7e0edd560..907ac1e7d 100644 --- a/Projects/UOContent/Items/Jewels/Artifacts/Craftable/ResillientBracer.cs +++ b/Projects/UOContent/Items/Jewels/Artifacts/Craftable/ResillientBracer.cs @@ -1,39 +1,23 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0)] +public partial class ResilientBracer : GoldBracelet { - public class ResilientBracer : GoldBracelet + [Constructible] + public ResilientBracer() { - [Constructible] - public ResilientBracer() - { - Hue = 0x488; + Hue = 0x488; - SkillBonuses.SetValues(0, SkillName.MagicResist, 15.0); + SkillBonuses.SetValues(0, SkillName.MagicResist, 15.0); - Attributes.BonusHits = 5; - Attributes.RegenHits = 2; - Attributes.DefendChance = 10; - } - - public ResilientBracer(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1072933; // Resillient Bracer - - public override int PhysicalResistance => 20; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } + Attributes.BonusHits = 5; + Attributes.RegenHits = 2; + Attributes.DefendChance = 10; } + + public override int LabelNumber => 1072933; // Resillient Bracer + + public override int PhysicalResistance => 20; } diff --git a/Projects/UOContent/Items/Jewels/Artifacts/OrnamentOfTheMagician.cs b/Projects/UOContent/Items/Jewels/Artifacts/OrnamentOfTheMagician.cs index 623f99815..88f6afd7b 100644 --- a/Projects/UOContent/Items/Jewels/Artifacts/OrnamentOfTheMagician.cs +++ b/Projects/UOContent/Items/Jewels/Artifacts/OrnamentOfTheMagician.cs @@ -1,42 +1,21 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class OrnamentOfTheMagician : GoldBracelet { - public class OrnamentOfTheMagician : GoldBracelet + [Constructible] + public OrnamentOfTheMagician() { - [Constructible] - public OrnamentOfTheMagician() - { - Hue = 0x554; - Attributes.CastRecovery = 3; - Attributes.CastSpeed = 2; - Attributes.LowerManaCost = 10; - Attributes.LowerRegCost = 20; - Resistances.Energy = 15; - } - - public OrnamentOfTheMagician(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1061105; // Ornament of the Magician - public override int ArtifactRarity => 11; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - if (Hue == 0x12B) - { - Hue = 0x554; - } - } + Hue = 0x554; + Attributes.CastRecovery = 3; + Attributes.CastSpeed = 2; + Attributes.LowerManaCost = 10; + Attributes.LowerRegCost = 20; + Resistances.Energy = 15; } + + public override int LabelNumber => 1061105; // Ornament of the Magician + public override int ArtifactRarity => 11; } diff --git a/Projects/UOContent/Items/Jewels/Artifacts/RingOfTheElements.cs b/Projects/UOContent/Items/Jewels/Artifacts/RingOfTheElements.cs index 25ffd9f83..6bd99bf4b 100644 --- a/Projects/UOContent/Items/Jewels/Artifacts/RingOfTheElements.cs +++ b/Projects/UOContent/Items/Jewels/Artifacts/RingOfTheElements.cs @@ -1,37 +1,21 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class RingOfTheElements : GoldRing { - public class RingOfTheElements : GoldRing + [Constructible] + public RingOfTheElements() { - [Constructible] - public RingOfTheElements() - { - Hue = 0x4E9; - Attributes.Luck = 100; - Resistances.Fire = 16; - Resistances.Cold = 16; - Resistances.Poison = 16; - Resistances.Energy = 16; - } - - public RingOfTheElements(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1061104; // Ring of the Elements - public override int ArtifactRarity => 11; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } + Hue = 0x4E9; + Attributes.Luck = 100; + Resistances.Fire = 16; + Resistances.Cold = 16; + Resistances.Poison = 16; + Resistances.Energy = 16; } + + public override int LabelNumber => 1061104; // Ring of the Elements + public override int ArtifactRarity => 11; } diff --git a/Projects/UOContent/Items/Jewels/Artifacts/RingOfTheVile.cs b/Projects/UOContent/Items/Jewels/Artifacts/RingOfTheVile.cs index 4a361064b..3a3613777 100644 --- a/Projects/UOContent/Items/Jewels/Artifacts/RingOfTheVile.cs +++ b/Projects/UOContent/Items/Jewels/Artifacts/RingOfTheVile.cs @@ -1,41 +1,20 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class RingOfTheVile : GoldRing { - public class RingOfTheVile : GoldRing + [Constructible] + public RingOfTheVile() { - [Constructible] - public RingOfTheVile() - { - Hue = 0x4F7; - Attributes.BonusDex = 8; - Attributes.RegenStam = 6; - Attributes.AttackChance = 15; - Resistances.Poison = 20; - } - - public RingOfTheVile(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1061102; // Ring of the Vile - public override int ArtifactRarity => 11; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - if (Hue == 0x4F4) - { - Hue = 0x4F7; - } - } + Hue = 0x4F7; + Attributes.BonusDex = 8; + Attributes.RegenStam = 6; + Attributes.AttackChance = 15; + Resistances.Poison = 20; } + + public override int LabelNumber => 1061102; // Ring of the Vile + public override int ArtifactRarity => 11; } diff --git a/Projects/UOContent/Items/Jewels/BaseJewel.cs b/Projects/UOContent/Items/Jewels/BaseJewel.cs index 29e823124..a7c74ea85 100644 --- a/Projects/UOContent/Items/Jewels/BaseJewel.cs +++ b/Projects/UOContent/Items/Jewels/BaseJewel.cs @@ -1,499 +1,444 @@ using System; +using ModernUO.Serialization; using Server.Engines.Craft; -namespace Server.Items +namespace Server.Items; + +public enum GemType { - public enum GemType + None, + StarSapphire, + Emerald, + Sapphire, + Ruby, + Citrine, + Amethyst, + Tourmaline, + Amber, + Diamond +} + +[SerializationGenerator(4, false)] +public abstract partial class BaseJewel : Item, ICraftable +{ + [EncodedInt] + [InvalidateProperties] + [SerializableField(0)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private int _maxHitPoints; + + // Field 1 + private int _hitPoints; + + [SerializableField(2, "private", "private")] + private CraftResource _rawResource; + + [SerializableField(3)] + [InvalidateProperties] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private GemType _gemType; + + [SerializableField(4, setter: "private")] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster, canModify: true)]")] + private AosAttributes _attributes; + + [SerializableField(5, setter: "private")] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster, canModify: true)]")] + private AosElementAttributes _resistances; + + [SerializableField(6, setter: "private")] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster, canModify: true)]")] + private AosSkillBonuses _skillBonuses; + + public BaseJewel(int itemID, Layer layer) : base(itemID) { - None, - StarSapphire, - Emerald, - Sapphire, - Ruby, - Citrine, - Amethyst, - Tourmaline, - Amber, - Diamond + _attributes = new AosAttributes(this); + _resistances = new AosElementAttributes(this); + _skillBonuses = new AosSkillBonuses(this); + _rawResource = CraftResource.Iron; + Hue = CraftResources.GetHue(_rawResource); + _gemType = GemType.None; + + Layer = layer; + + _hitPoints = _maxHitPoints = Utility.RandomMinMax(InitMinHits, InitMaxHits); } - public abstract class BaseJewel : Item, ICraftable + [EncodedInt] + [SerializableField(1)] + [CommandProperty(AccessLevel.GameMaster)] + public int HitPoints { - private GemType m_GemType; - private int m_HitPoints; - private int m_MaxHitPoints; - private CraftResource m_Resource; - - public BaseJewel(int itemID, Layer layer) : base(itemID) + get => _hitPoints; + set { - Attributes = new AosAttributes(this); - Resistances = new AosElementAttributes(this); - SkillBonuses = new AosSkillBonuses(this); - m_Resource = CraftResource.Iron; - m_GemType = GemType.None; - - Layer = layer; - - m_HitPoints = m_MaxHitPoints = Utility.RandomMinMax(InitMinHits, InitMaxHits); - } - - public BaseJewel(Serial serial) : base(serial) - { - } - - [CommandProperty(AccessLevel.GameMaster)] - public int MaxHitPoints - { - get => m_MaxHitPoints; - set + if (value != _hitPoints && _maxHitPoints > 0) { - m_MaxHitPoints = value; + _hitPoints = value; + + if (_hitPoints < 0) + { + Delete(); + } + else if (_hitPoints > _maxHitPoints) + { + _hitPoints = _maxHitPoints; + } + InvalidateProperties(); + this.MarkDirty(); + } + } + } + + [CommandProperty(AccessLevel.GameMaster)] + public CraftResource Resource + { + get => _rawResource; + set + { + _rawResource = value; + Hue = CraftResources.GetHue(_rawResource); + } + } + + public override int PhysicalResistance => Resistances.Physical; + public override int FireResistance => Resistances.Fire; + public override int ColdResistance => Resistances.Cold; + public override int PoisonResistance => Resistances.Poison; + public override int EnergyResistance => Resistances.Energy; + public virtual int BaseGemTypeNumber => 0; + + public virtual int InitMinHits => 0; + public virtual int InitMaxHits => 0; + + public override int LabelNumber + { + get + { + if (_gemType == GemType.None) + { + return base.LabelNumber; + } + + return BaseGemTypeNumber + (int)_gemType - 1; + } + } + + public virtual int ArtifactRarity => 0; + + public int OnCraft( + int quality, bool makersMark, Mobile from, CraftSystem craftSystem, Type typeRes, BaseTool tool, + CraftItem craftItem, int resHue + ) + { + var resourceType = typeRes ?? craftItem.Resources[0].ItemType; + + Resource = CraftResources.GetFromType(resourceType); + + var context = craftSystem.GetContext(from); + + if (context?.DoNotColor == true) + { + Hue = 0; + } + + if (craftItem.Resources.Count > 1) + { + resourceType = craftItem.Resources[1].ItemType; + + if (resourceType == typeof(StarSapphire)) + { + GemType = GemType.StarSapphire; + } + else if (resourceType == typeof(Emerald)) + { + GemType = GemType.Emerald; + } + else if (resourceType == typeof(Sapphire)) + { + GemType = GemType.Sapphire; + } + else if (resourceType == typeof(Ruby)) + { + GemType = GemType.Ruby; + } + else if (resourceType == typeof(Citrine)) + { + GemType = GemType.Citrine; + } + else if (resourceType == typeof(Amethyst)) + { + GemType = GemType.Amethyst; + } + else if (resourceType == typeof(Tourmaline)) + { + GemType = GemType.Tourmaline; + } + else if (resourceType == typeof(Amber)) + { + GemType = GemType.Amber; + } + else if (resourceType == typeof(Diamond)) + { + GemType = GemType.Diamond; } } - [CommandProperty(AccessLevel.GameMaster)] - public int HitPoints + return 1; + } + + public override void OnAfterDuped(Item newItem) + { + if (newItem is not BaseJewel jewel) { - get => m_HitPoints; - set - { - if (value != m_HitPoints && MaxHitPoints > 0) - { - m_HitPoints = value; - - if (m_HitPoints < 0) - { - Delete(); - } - else if (m_HitPoints > MaxHitPoints) - { - m_HitPoints = MaxHitPoints; - } - - InvalidateProperties(); - } - } + return; } - [CommandProperty(AccessLevel.GameMaster, canModify: true)] - public AosAttributes Attributes { get; private set; } + jewel.Attributes = new AosAttributes(newItem, Attributes); + jewel.Resistances = new AosElementAttributes(newItem, Resistances); + jewel.SkillBonuses = new AosSkillBonuses(newItem, SkillBonuses); + } - [CommandProperty(AccessLevel.GameMaster, canModify: true)] - public AosElementAttributes Resistances { get; private set; } - - [CommandProperty(AccessLevel.GameMaster, canModify: true)] - public AosSkillBonuses SkillBonuses { get; private set; } - - [CommandProperty(AccessLevel.GameMaster)] - public CraftResource Resource + public override void OnAdded(IEntity parent) + { + if (Core.AOS && parent is Mobile from) { - get => m_Resource; - set + SkillBonuses.AddTo(from); + + var strBonus = Attributes.BonusStr; + var dexBonus = Attributes.BonusDex; + var intBonus = Attributes.BonusInt; + + if (strBonus != 0 || dexBonus != 0 || intBonus != 0) { - m_Resource = value; - Hue = CraftResources.GetHue(m_Resource); - } - } - - [CommandProperty(AccessLevel.GameMaster)] - public GemType GemType - { - get => m_GemType; - set - { - m_GemType = value; - InvalidateProperties(); - } - } - - public override int PhysicalResistance => Resistances.Physical; - public override int FireResistance => Resistances.Fire; - public override int ColdResistance => Resistances.Cold; - public override int PoisonResistance => Resistances.Poison; - public override int EnergyResistance => Resistances.Energy; - public virtual int BaseGemTypeNumber => 0; - - public virtual int InitMinHits => 0; - public virtual int InitMaxHits => 0; - - public override int LabelNumber - { - get - { - if (m_GemType == GemType.None) - { - return base.LabelNumber; - } - - return BaseGemTypeNumber + (int)m_GemType - 1; - } - } - - public virtual int ArtifactRarity => 0; - - public int OnCraft( - int quality, bool makersMark, Mobile from, CraftSystem craftSystem, Type typeRes, BaseTool tool, - CraftItem craftItem, int resHue - ) - { - var resourceType = typeRes ?? craftItem.Resources[0].ItemType; - - Resource = CraftResources.GetFromType(resourceType); - - var context = craftSystem.GetContext(from); - - if (context?.DoNotColor == true) - { - Hue = 0; - } - - if (craftItem.Resources.Count > 1) - { - resourceType = craftItem.Resources[1].ItemType; - - if (resourceType == typeof(StarSapphire)) - { - GemType = GemType.StarSapphire; - } - else if (resourceType == typeof(Emerald)) - { - GemType = GemType.Emerald; - } - else if (resourceType == typeof(Sapphire)) - { - GemType = GemType.Sapphire; - } - else if (resourceType == typeof(Ruby)) - { - GemType = GemType.Ruby; - } - else if (resourceType == typeof(Citrine)) - { - GemType = GemType.Citrine; - } - else if (resourceType == typeof(Amethyst)) - { - GemType = GemType.Amethyst; - } - else if (resourceType == typeof(Tourmaline)) - { - GemType = GemType.Tourmaline; - } - else if (resourceType == typeof(Amber)) - { - GemType = GemType.Amber; - } - else if (resourceType == typeof(Diamond)) - { - GemType = GemType.Diamond; - } - } - - return 1; - } - - public override void OnAfterDuped(Item newItem) - { - if (newItem is not BaseJewel jewel) - { - return; - } - - jewel.Attributes = new AosAttributes(newItem, Attributes); - jewel.Resistances = new AosElementAttributes(newItem, Resistances); - jewel.SkillBonuses = new AosSkillBonuses(newItem, SkillBonuses); - } - - public override void OnAdded(IEntity parent) - { - if (Core.AOS && parent is Mobile from) - { - SkillBonuses.AddTo(from); - - var strBonus = Attributes.BonusStr; - var dexBonus = Attributes.BonusDex; - var intBonus = Attributes.BonusInt; - - if (strBonus != 0 || dexBonus != 0 || intBonus != 0) - { - var modName = Serial.ToString(); - - if (strBonus != 0) - { - from.AddStatMod(new StatMod(StatType.Str, $"{modName}Str", strBonus, TimeSpan.Zero)); - } - - if (dexBonus != 0) - { - from.AddStatMod(new StatMod(StatType.Dex, $"{modName}Dex", dexBonus, TimeSpan.Zero)); - } - - if (intBonus != 0) - { - from.AddStatMod(new StatMod(StatType.Int, $"{modName}Int", intBonus, TimeSpan.Zero)); - } - } - - from.CheckStatTimers(); - } - } - - public override void OnRemoved(IEntity parent) - { - if (Core.AOS && parent is Mobile from) - { - SkillBonuses.Remove(); - var modName = Serial.ToString(); - from.RemoveStatMod($"{modName}Str"); - from.RemoveStatMod($"{modName}Dex"); - from.RemoveStatMod($"{modName}Int"); + if (strBonus != 0) + { + from.AddStatMod(new StatMod(StatType.Str, $"{modName}Str", strBonus, TimeSpan.Zero)); + } - from.CheckStatTimers(); - } - } + if (dexBonus != 0) + { + from.AddStatMod(new StatMod(StatType.Dex, $"{modName}Dex", dexBonus, TimeSpan.Zero)); + } - public override void GetProperties(IPropertyList list) - { - base.GetProperties(list); - - SkillBonuses.GetProperties(list); - - int prop; - - if ((prop = ArtifactRarity) > 0) - { - list.Add(1061078, prop); // artifact rarity ~1_val~ + if (intBonus != 0) + { + from.AddStatMod(new StatMod(StatType.Int, $"{modName}Int", intBonus, TimeSpan.Zero)); + } } - if ((prop = Attributes.WeaponDamage) != 0) - { - list.Add(1060401, prop); // damage increase ~1_val~% - } - - if ((prop = Attributes.DefendChance) != 0) - { - list.Add(1060408, prop); // defense chance increase ~1_val~% - } - - if ((prop = Attributes.BonusDex) != 0) - { - list.Add(1060409, prop); // dexterity bonus ~1_val~ - } - - if ((prop = Attributes.EnhancePotions) != 0) - { - list.Add(1060411, prop); // enhance potions ~1_val~% - } - - if ((prop = Attributes.CastRecovery) != 0) - { - list.Add(1060412, prop); // faster cast recovery ~1_val~ - } - - if ((prop = Attributes.CastSpeed) != 0) - { - list.Add(1060413, prop); // faster casting ~1_val~ - } - - if ((prop = Attributes.AttackChance) != 0) - { - list.Add(1060415, prop); // hit chance increase ~1_val~% - } - - if ((prop = Attributes.BonusHits) != 0) - { - list.Add(1060431, prop); // hit point increase ~1_val~ - } - - if ((prop = Attributes.BonusInt) != 0) - { - list.Add(1060432, prop); // intelligence bonus ~1_val~ - } - - if ((prop = Attributes.LowerManaCost) != 0) - { - list.Add(1060433, prop); // lower mana cost ~1_val~% - } - - if ((prop = Attributes.LowerRegCost) != 0) - { - list.Add(1060434, prop); // lower reagent cost ~1_val~% - } - - if ((prop = Attributes.Luck) != 0) - { - list.Add(1060436, prop); // luck ~1_val~ - } - - if ((prop = Attributes.BonusMana) != 0) - { - list.Add(1060439, prop); // mana increase ~1_val~ - } - - if ((prop = Attributes.RegenMana) != 0) - { - list.Add(1060440, prop); // mana regeneration ~1_val~ - } - - if (Attributes.NightSight != 0) - { - list.Add(1060441); // night sight - } - - if ((prop = Attributes.ReflectPhysical) != 0) - { - list.Add(1060442, prop); // reflect physical damage ~1_val~% - } - - if ((prop = Attributes.RegenStam) != 0) - { - list.Add(1060443, prop); // stamina regeneration ~1_val~ - } - - if ((prop = Attributes.RegenHits) != 0) - { - list.Add(1060444, prop); // hit point regeneration ~1_val~ - } - - if (Attributes.SpellChanneling != 0) - { - list.Add(1060482); // spell channeling - } - - if ((prop = Attributes.SpellDamage) != 0) - { - list.Add(1060483, prop); // spell damage increase ~1_val~% - } - - if ((prop = Attributes.BonusStam) != 0) - { - list.Add(1060484, prop); // stamina increase ~1_val~ - } - - if ((prop = Attributes.BonusStr) != 0) - { - list.Add(1060485, prop); // strength bonus ~1_val~ - } - - if ((prop = Attributes.WeaponSpeed) != 0) - { - list.Add(1060486, prop); // swing speed increase ~1_val~% - } - - if (Core.ML && (prop = Attributes.IncreasedKarmaLoss) != 0) - { - list.Add(1075210, prop); // Increased Karma Loss ~1val~% - } - - AddResistanceProperties(list); - - if (m_HitPoints >= 0 && m_MaxHitPoints > 0) - { - list.Add(1060639, $"{m_HitPoints}\t{m_MaxHitPoints}"); // durability ~1_val~ / ~2_val~ - } - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(3); // version - - writer.WriteEncodedInt(m_MaxHitPoints); - writer.WriteEncodedInt(m_HitPoints); - - writer.WriteEncodedInt((int)m_Resource); - writer.WriteEncodedInt((int)m_GemType); - - Attributes.Serialize(writer); - Resistances.Serialize(writer); - SkillBonuses.Serialize(writer); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - switch (version) - { - case 3: - { - m_MaxHitPoints = reader.ReadEncodedInt(); - m_HitPoints = reader.ReadEncodedInt(); - - goto case 2; - } - case 2: - { - m_Resource = (CraftResource)reader.ReadEncodedInt(); - m_GemType = (GemType)reader.ReadEncodedInt(); - - goto case 1; - } - case 1: - { - Attributes = new AosAttributes(this); - Attributes.Deserialize(reader); - Resistances = new AosElementAttributes(this); - Resistances.Deserialize(reader); - SkillBonuses = new AosSkillBonuses(this); - SkillBonuses.Deserialize(reader); - - var m = Parent as Mobile; - - if (Core.AOS && m != null) - { - SkillBonuses.AddTo(m); - } - - var strBonus = Attributes.BonusStr; - var dexBonus = Attributes.BonusDex; - var intBonus = Attributes.BonusInt; - - if (m != null && (strBonus != 0 || dexBonus != 0 || intBonus != 0)) - { - var modName = Serial.ToString(); - - if (strBonus != 0) - { - m.AddStatMod(new StatMod(StatType.Str, $"{modName}Str", strBonus, TimeSpan.Zero)); - } - - if (dexBonus != 0) - { - m.AddStatMod(new StatMod(StatType.Dex, $"{modName}Dex", dexBonus, TimeSpan.Zero)); - } - - if (intBonus != 0) - { - m.AddStatMod(new StatMod(StatType.Int, $"{modName}Int", intBonus, TimeSpan.Zero)); - } - } - - m?.CheckStatTimers(); - - break; - } - case 0: - { - Attributes = new AosAttributes(this); - Resistances = new AosElementAttributes(this); - SkillBonuses = new AosSkillBonuses(this); - - break; - } - } - - if (version < 2) - { - m_Resource = CraftResource.Iron; - m_GemType = GemType.None; - } + from.CheckStatTimers(); } } + + public override void OnRemoved(IEntity parent) + { + if (Core.AOS && parent is Mobile from) + { + SkillBonuses.Remove(); + + var modName = Serial.ToString(); + + from.RemoveStatMod($"{modName}Str"); + from.RemoveStatMod($"{modName}Dex"); + from.RemoveStatMod($"{modName}Int"); + + from.CheckStatTimers(); + } + } + + public override void GetProperties(IPropertyList list) + { + base.GetProperties(list); + + SkillBonuses.GetProperties(list); + + int prop; + + if ((prop = ArtifactRarity) > 0) + { + list.Add(1061078, prop); // artifact rarity ~1_val~ + } + + if ((prop = Attributes.WeaponDamage) != 0) + { + list.Add(1060401, prop); // damage increase ~1_val~% + } + + if ((prop = Attributes.DefendChance) != 0) + { + list.Add(1060408, prop); // defense chance increase ~1_val~% + } + + if ((prop = Attributes.BonusDex) != 0) + { + list.Add(1060409, prop); // dexterity bonus ~1_val~ + } + + if ((prop = Attributes.EnhancePotions) != 0) + { + list.Add(1060411, prop); // enhance potions ~1_val~% + } + + if ((prop = Attributes.CastRecovery) != 0) + { + list.Add(1060412, prop); // faster cast recovery ~1_val~ + } + + if ((prop = Attributes.CastSpeed) != 0) + { + list.Add(1060413, prop); // faster casting ~1_val~ + } + + if ((prop = Attributes.AttackChance) != 0) + { + list.Add(1060415, prop); // hit chance increase ~1_val~% + } + + if ((prop = Attributes.BonusHits) != 0) + { + list.Add(1060431, prop); // hit point increase ~1_val~ + } + + if ((prop = Attributes.BonusInt) != 0) + { + list.Add(1060432, prop); // intelligence bonus ~1_val~ + } + + if ((prop = Attributes.LowerManaCost) != 0) + { + list.Add(1060433, prop); // lower mana cost ~1_val~% + } + + if ((prop = Attributes.LowerRegCost) != 0) + { + list.Add(1060434, prop); // lower reagent cost ~1_val~% + } + + if ((prop = Attributes.Luck) != 0) + { + list.Add(1060436, prop); // luck ~1_val~ + } + + if ((prop = Attributes.BonusMana) != 0) + { + list.Add(1060439, prop); // mana increase ~1_val~ + } + + if ((prop = Attributes.RegenMana) != 0) + { + list.Add(1060440, prop); // mana regeneration ~1_val~ + } + + if (Attributes.NightSight != 0) + { + list.Add(1060441); // night sight + } + + if ((prop = Attributes.ReflectPhysical) != 0) + { + list.Add(1060442, prop); // reflect physical damage ~1_val~% + } + + if ((prop = Attributes.RegenStam) != 0) + { + list.Add(1060443, prop); // stamina regeneration ~1_val~ + } + + if ((prop = Attributes.RegenHits) != 0) + { + list.Add(1060444, prop); // hit point regeneration ~1_val~ + } + + if (Attributes.SpellChanneling != 0) + { + list.Add(1060482); // spell channeling + } + + if ((prop = Attributes.SpellDamage) != 0) + { + list.Add(1060483, prop); // spell damage increase ~1_val~% + } + + if ((prop = Attributes.BonusStam) != 0) + { + list.Add(1060484, prop); // stamina increase ~1_val~ + } + + if ((prop = Attributes.BonusStr) != 0) + { + list.Add(1060485, prop); // strength bonus ~1_val~ + } + + if ((prop = Attributes.WeaponSpeed) != 0) + { + list.Add(1060486, prop); // swing speed increase ~1_val~% + } + + if (Core.ML && (prop = Attributes.IncreasedKarmaLoss) != 0) + { + list.Add(1075210, prop); // Increased Karma Loss ~1val~% + } + + AddResistanceProperties(list); + + if (_hitPoints >= 0 && _maxHitPoints > 0) + { + list.Add(1060639, $"{_hitPoints}\t{_maxHitPoints}"); // durability ~1_val~ / ~2_val~ + } + } + + private void Deserialize(IGenericReader reader, int version) + { + _maxHitPoints = reader.ReadEncodedInt(); + _hitPoints = reader.ReadEncodedInt(); + _rawResource = (CraftResource)reader.ReadEncodedInt(); + _gemType = (GemType)reader.ReadEncodedInt(); + _attributes = new AosAttributes(this); + _attributes.Deserialize(reader); + _resistances = new AosElementAttributes(this); + _resistances.Deserialize(reader); + _skillBonuses = new AosSkillBonuses(this); + _skillBonuses.Deserialize(reader); + } + + [AfterDeserialization] + private void AfterDeserialization() + { + var m = Parent as Mobile; + + if (Core.AOS && m != null) + { + SkillBonuses.AddTo(m); + } + + var strBonus = Attributes.BonusStr; + var dexBonus = Attributes.BonusDex; + var intBonus = Attributes.BonusInt; + + if (m != null && (strBonus != 0 || dexBonus != 0 || intBonus != 0)) + { + var modName = Serial.ToString(); + + if (strBonus != 0) + { + m.AddStatMod(new StatMod(StatType.Str, $"{modName}Str", strBonus, TimeSpan.Zero)); + } + + if (dexBonus != 0) + { + m.AddStatMod(new StatMod(StatType.Dex, $"{modName}Dex", dexBonus, TimeSpan.Zero)); + } + + if (intBonus != 0) + { + m.AddStatMod(new StatMod(StatType.Int, $"{modName}Int", intBonus, TimeSpan.Zero)); + } + } + + m?.CheckStatTimers(); + } } diff --git a/Projects/UOContent/Items/Jewels/Beads.cs b/Projects/UOContent/Items/Jewels/Beads.cs index da34bfca4..e60572be2 100644 --- a/Projects/UOContent/Items/Jewels/Beads.cs +++ b/Projects/UOContent/Items/Jewels/Beads.cs @@ -1,24 +1,10 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class Beads : Item { - public class Beads : Item - { - [Constructible] - public Beads() : base(0x108B) => Weight = 1.0; - - public Beads(Serial serial) : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } - } + [Constructible] + public Beads() : base(0x108B) => Weight = 1.0; } diff --git a/Projects/UOContent/Items/Jewels/Bracelet.cs b/Projects/UOContent/Items/Jewels/Bracelet.cs index f300bd582..7a5aa44f8 100644 --- a/Projects/UOContent/Items/Jewels/Bracelet.cs +++ b/Projects/UOContent/Items/Jewels/Bracelet.cs @@ -1,77 +1,27 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0, false)] +public abstract partial class BaseBracelet : BaseJewel { - public abstract class BaseBracelet : BaseJewel + public BaseBracelet(int itemID) : base(itemID, Layer.Bracelet) { - public BaseBracelet(int itemID) : base(itemID, Layer.Bracelet) - { - } - - public BaseBracelet(Serial serial) : base(serial) - { - } - - public override int BaseGemTypeNumber => 1044221; // star sapphire bracelet - - 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 GoldBracelet : BaseBracelet - { - [Constructible] - public GoldBracelet() : base(0x1086) => Weight = 0.1; - - public GoldBracelet(Serial serial) : base(serial) - { - } - - 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 SilverBracelet : BaseBracelet - { - [Constructible] - public SilverBracelet() : base(0x1F06) => Weight = 0.1; - - public SilverBracelet(Serial serial) : base(serial) - { - } - - 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 override int BaseGemTypeNumber => 1044221; // star sapphire bracelet +} + +[SerializationGenerator(0, false)] +public partial class GoldBracelet : BaseBracelet +{ + [Constructible] + public GoldBracelet() : base(0x1086) => Weight = 0.1; +} + +[SerializationGenerator(0, false)] +public partial class SilverBracelet : BaseBracelet +{ + [Constructible] + public SilverBracelet() : base(0x1F06) => Weight = 0.1; } diff --git a/Projects/UOContent/Items/Jewels/Earrings.cs b/Projects/UOContent/Items/Jewels/Earrings.cs index f99ae91dd..73a6ccd09 100644 --- a/Projects/UOContent/Items/Jewels/Earrings.cs +++ b/Projects/UOContent/Items/Jewels/Earrings.cs @@ -1,77 +1,27 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0, false)] +public abstract partial class BaseEarrings : BaseJewel { - public abstract class BaseEarrings : BaseJewel + public BaseEarrings(int itemID) : base(itemID, Layer.Earrings) { - public BaseEarrings(int itemID) : base(itemID, Layer.Earrings) - { - } - - public BaseEarrings(Serial serial) : base(serial) - { - } - - public override int BaseGemTypeNumber => 1044203; // star sapphire earrings - - 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 GoldEarrings : BaseEarrings - { - [Constructible] - public GoldEarrings() : base(0x1087) => Weight = 0.1; - - public GoldEarrings(Serial serial) : base(serial) - { - } - - 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 SilverEarrings : BaseEarrings - { - [Constructible] - public SilverEarrings() : base(0x1F07) => Weight = 0.1; - - public SilverEarrings(Serial serial) : base(serial) - { - } - - 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 override int BaseGemTypeNumber => 1044203; // star sapphire earrings +} + +[SerializationGenerator(0, false)] +public partial class GoldEarrings : BaseEarrings +{ + [Constructible] + public GoldEarrings() : base(0x1087) => Weight = 0.1; +} + +[SerializationGenerator(0, false)] +public partial class SilverEarrings : BaseEarrings +{ + [Constructible] + public SilverEarrings() : base(0x1F07) => Weight = 0.1; } diff --git a/Projects/UOContent/Items/Jewels/Necklace.cs b/Projects/UOContent/Items/Jewels/Necklace.cs index baa9cc827..d4cd1eb9e 100644 --- a/Projects/UOContent/Items/Jewels/Necklace.cs +++ b/Projects/UOContent/Items/Jewels/Necklace.cs @@ -1,149 +1,48 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0, false)] +public abstract partial class BaseNecklace : BaseJewel { - public abstract class BaseNecklace : BaseJewel + public BaseNecklace(int itemID) : base(itemID, Layer.Neck) { - public BaseNecklace(int itemID) : base(itemID, Layer.Neck) - { - } - - public BaseNecklace(Serial serial) : base(serial) - { - } - - public override int BaseGemTypeNumber => 1044241; // star sapphire necklace - - 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 Necklace : BaseNecklace - { - [Constructible] - public Necklace() : base(0x1085) => Weight = 0.1; - - public Necklace(Serial serial) : base(serial) - { - } - - 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 GoldNecklace : BaseNecklace - { - [Constructible] - public GoldNecklace() : base(0x1088) => Weight = 0.1; - - public GoldNecklace(Serial serial) : base(serial) - { - } - - 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 GoldBeadNecklace : BaseNecklace - { - [Constructible] - public GoldBeadNecklace() : base(0x1089) => Weight = 0.1; - - public GoldBeadNecklace(Serial serial) : base(serial) - { - } - - 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 SilverNecklace : BaseNecklace - { - [Constructible] - public SilverNecklace() : base(0x1F08) => Weight = 0.1; - - public SilverNecklace(Serial serial) : base(serial) - { - } - - 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 SilverBeadNecklace : BaseNecklace - { - [Constructible] - public SilverBeadNecklace() : base(0x1F05) => Weight = 0.1; - - public SilverBeadNecklace(Serial serial) : base(serial) - { - } - - 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 override int BaseGemTypeNumber => 1044241; // star sapphire necklace +} + +[SerializationGenerator(0, false)] +public partial class Necklace : BaseNecklace +{ + [Constructible] + public Necklace() : base(0x1085) => Weight = 0.1; +} + +[SerializationGenerator(0, false)] +public partial class GoldNecklace : BaseNecklace +{ + [Constructible] + public GoldNecklace() : base(0x1088) => Weight = 0.1; +} + +[SerializationGenerator(0, false)] +public partial class GoldBeadNecklace : BaseNecklace +{ + [Constructible] + public GoldBeadNecklace() : base(0x1089) => Weight = 0.1; +} + +[SerializationGenerator(0, false)] +public partial class SilverNecklace : BaseNecklace +{ + [Constructible] + public SilverNecklace() : base(0x1F08) => Weight = 0.1; +} + +[SerializationGenerator(0, false)] +public partial class SilverBeadNecklace : BaseNecklace +{ + [Constructible] + public SilverBeadNecklace() : base(0x1F05) => Weight = 0.1; } diff --git a/Projects/UOContent/Items/Jewels/Ring.cs b/Projects/UOContent/Items/Jewels/Ring.cs index 140840ace..9c142f099 100644 --- a/Projects/UOContent/Items/Jewels/Ring.cs +++ b/Projects/UOContent/Items/Jewels/Ring.cs @@ -1,77 +1,27 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0, false)] +public abstract partial class BaseRing : BaseJewel { - public abstract class BaseRing : BaseJewel + public BaseRing(int itemID) : base(itemID, Layer.Ring) { - public BaseRing(int itemID) : base(itemID, Layer.Ring) - { - } - - public BaseRing(Serial serial) : base(serial) - { - } - - public override int BaseGemTypeNumber => 1044176; // star sapphire ring - - 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 GoldRing : BaseRing - { - [Constructible] - public GoldRing() : base(0x108a) => Weight = 0.1; - - public GoldRing(Serial serial) : base(serial) - { - } - - 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 SilverRing : BaseRing - { - [Constructible] - public SilverRing() : base(0x1F09) => Weight = 0.1; - - public SilverRing(Serial serial) : base(serial) - { - } - - 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 override int BaseGemTypeNumber => 1044176; // star sapphire ring +} + +[SerializationGenerator(0, false)] +public partial class GoldRing : BaseRing +{ + [Constructible] + public GoldRing() : base(0x108a) => Weight = 0.1; +} + +[SerializationGenerator(0, false)] +public partial class SilverRing : BaseRing +{ + [Constructible] + public SilverRing() : base(0x1F09) => Weight = 0.1; } diff --git a/Projects/UOContent/Migrations/Server.Items.BaseBracelet.v0.json b/Projects/UOContent/Migrations/Server.Items.BaseBracelet.v0.json new file mode 100644 index 000000000..d7ac49c34 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.BaseBracelet.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.BaseBracelet" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.BaseEarrings.v0.json b/Projects/UOContent/Migrations/Server.Items.BaseEarrings.v0.json new file mode 100644 index 000000000..0b065bf39 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.BaseEarrings.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.BaseEarrings" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.BaseJewel.v4.json b/Projects/UOContent/Migrations/Server.Items.BaseJewel.v4.json new file mode 100644 index 000000000..6573d187d --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.BaseJewel.v4.json @@ -0,0 +1,56 @@ +{ + "version": 4, + "type": "Server.Items.BaseJewel", + "properties": [ + { + "name": "MaxHitPoints", + "type": "int", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "EncodedInt" + ] + }, + { + "name": "HitPoints", + "type": "int", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "EncodedInt" + ] + }, + { + "name": "RawResource", + "type": "Server.Items.CraftResource", + "rule": "EnumMigrationRule" + }, + { + "name": "GemType", + "type": "Server.Items.GemType", + "rule": "EnumMigrationRule" + }, + { + "name": "Attributes", + "type": "Server.AosAttributes", + "rule": "RawSerializableMigrationRule", + "ruleArguments": [ + "DeserializationRequiresParent" + ] + }, + { + "name": "Resistances", + "type": "Server.AosElementAttributes", + "rule": "RawSerializableMigrationRule", + "ruleArguments": [ + "DeserializationRequiresParent" + ] + }, + { + "name": "SkillBonuses", + "type": "Server.AosSkillBonuses", + "rule": "RawSerializableMigrationRule", + "ruleArguments": [ + "DeserializationRequiresParent" + ] + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.BaseNecklace.v0.json b/Projects/UOContent/Migrations/Server.Items.BaseNecklace.v0.json new file mode 100644 index 000000000..d2fbc8ad8 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.BaseNecklace.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.BaseNecklace" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.BaseRing.v0.json b/Projects/UOContent/Migrations/Server.Items.BaseRing.v0.json new file mode 100644 index 000000000..e44e47d14 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.BaseRing.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.BaseRing" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Beads.v0.json b/Projects/UOContent/Migrations/Server.Items.Beads.v0.json new file mode 100644 index 000000000..ecb966df9 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Beads.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Beads" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.BraceletOfHealth.v0.json b/Projects/UOContent/Migrations/Server.Items.BraceletOfHealth.v0.json new file mode 100644 index 000000000..88c85671f --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.BraceletOfHealth.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.BraceletOfHealth" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.EssenceOfBattle.v0.json b/Projects/UOContent/Migrations/Server.Items.EssenceOfBattle.v0.json new file mode 100644 index 000000000..a5a69e5be --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.EssenceOfBattle.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.EssenceOfBattle" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.GoldBeadNecklace.v0.json b/Projects/UOContent/Migrations/Server.Items.GoldBeadNecklace.v0.json new file mode 100644 index 000000000..9e9ccb739 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.GoldBeadNecklace.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.GoldBeadNecklace" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.GoldBracelet.v0.json b/Projects/UOContent/Migrations/Server.Items.GoldBracelet.v0.json new file mode 100644 index 000000000..a4039aaeb --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.GoldBracelet.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.GoldBracelet" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.GoldEarrings.v0.json b/Projects/UOContent/Migrations/Server.Items.GoldEarrings.v0.json new file mode 100644 index 000000000..57d9f6e78 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.GoldEarrings.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.GoldEarrings" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.GoldNecklace.v0.json b/Projects/UOContent/Migrations/Server.Items.GoldNecklace.v0.json new file mode 100644 index 000000000..0ae334871 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.GoldNecklace.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.GoldNecklace" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.GoldRing.v0.json b/Projects/UOContent/Migrations/Server.Items.GoldRing.v0.json new file mode 100644 index 000000000..06714ef02 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.GoldRing.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.GoldRing" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.GuildDeed.v0.json b/Projects/UOContent/Migrations/Server.Items.GuildDeed.v0.json new file mode 100644 index 000000000..eac6a29ae --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.GuildDeed.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.GuildDeed" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.GuildTeleporter.v0.json b/Projects/UOContent/Migrations/Server.Items.GuildTeleporter.v0.json new file mode 100644 index 000000000..f30d94e3a --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.GuildTeleporter.v0.json @@ -0,0 +1,11 @@ +{ + "version": 0, + "type": "Server.Items.GuildTeleporter", + "properties": [ + { + "name": "Stone", + "type": "Server.Item", + "rule": "SerializableInterfaceMigrationRule" + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Guildstone.v4.json b/Projects/UOContent/Migrations/Server.Items.Guildstone.v4.json new file mode 100644 index 000000000..13c23724f --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Guildstone.v4.json @@ -0,0 +1,27 @@ +{ + "version": 4, + "type": "Server.Items.Guildstone", + "properties": [ + { + "name": "GuildName", + "type": "string", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "GuildAbbrev", + "type": "string", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "Guild", + "type": "Server.Guilds.Guild", + "rule": "SerializableInterfaceMigrationRule" + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.GuildstoneDeed.v0.json b/Projects/UOContent/Migrations/Server.Items.GuildstoneDeed.v0.json new file mode 100644 index 000000000..70f822f09 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.GuildstoneDeed.v0.json @@ -0,0 +1,27 @@ +{ + "version": 0, + "type": "Server.Items.GuildstoneDeed", + "properties": [ + { + "name": "GuildName", + "type": "string", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "GuildAbbrev", + "type": "string", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "Guild", + "type": "Server.Guilds.Guild", + "rule": "SerializableInterfaceMigrationRule" + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Necklace.v0.json b/Projects/UOContent/Migrations/Server.Items.Necklace.v0.json new file mode 100644 index 000000000..3404812bf --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Necklace.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Necklace" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.OrnamentOfTheMagician.v0.json b/Projects/UOContent/Migrations/Server.Items.OrnamentOfTheMagician.v0.json new file mode 100644 index 000000000..e76794585 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.OrnamentOfTheMagician.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.OrnamentOfTheMagician" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.PendantOfTheMagi.v0.json b/Projects/UOContent/Migrations/Server.Items.PendantOfTheMagi.v0.json new file mode 100644 index 000000000..cc7a26f04 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.PendantOfTheMagi.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.PendantOfTheMagi" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.ResilientBracer.v0.json b/Projects/UOContent/Migrations/Server.Items.ResilientBracer.v0.json new file mode 100644 index 000000000..0e8deb175 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.ResilientBracer.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.ResilientBracer" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.RingOfTheElements.v0.json b/Projects/UOContent/Migrations/Server.Items.RingOfTheElements.v0.json new file mode 100644 index 000000000..bcc0992cc --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.RingOfTheElements.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.RingOfTheElements" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.RingOfTheVile.v0.json b/Projects/UOContent/Migrations/Server.Items.RingOfTheVile.v0.json new file mode 100644 index 000000000..0cc53f9a3 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.RingOfTheVile.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.RingOfTheVile" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.SilverBeadNecklace.v0.json b/Projects/UOContent/Migrations/Server.Items.SilverBeadNecklace.v0.json new file mode 100644 index 000000000..e97248aa8 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.SilverBeadNecklace.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.SilverBeadNecklace" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.SilverBracelet.v0.json b/Projects/UOContent/Migrations/Server.Items.SilverBracelet.v0.json new file mode 100644 index 000000000..a329f03f6 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.SilverBracelet.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.SilverBracelet" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.SilverEarrings.v0.json b/Projects/UOContent/Migrations/Server.Items.SilverEarrings.v0.json new file mode 100644 index 000000000..ee60c9a3b --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.SilverEarrings.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.SilverEarrings" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.SilverNecklace.v0.json b/Projects/UOContent/Migrations/Server.Items.SilverNecklace.v0.json new file mode 100644 index 000000000..1be9db682 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.SilverNecklace.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.SilverNecklace" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.SilverRing.v0.json b/Projects/UOContent/Migrations/Server.Items.SilverRing.v0.json new file mode 100644 index 000000000..2e0338653 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.SilverRing.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.SilverRing" +} \ No newline at end of file From 4b2b7e22772b8898eea7046e13281bed5cbadb8a Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Tue, 14 Jun 2022 16:44:50 -0700 Subject: [PATCH 196/213] fix: Fixes old RunUO bug with skill mod owners (#1064) --- Projects/Server/Mobiles/Mobile.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/Projects/Server/Mobiles/Mobile.cs b/Projects/Server/Mobiles/Mobile.cs index 7fb9e0a77..9db78424b 100644 --- a/Projects/Server/Mobiles/Mobile.cs +++ b/Projects/Server/Mobiles/Mobile.cs @@ -103,13 +103,8 @@ namespace Server if (m_Owner != value) { m_Owner?.RemoveSkillMod(this); - m_Owner = value; - - if (m_Owner != value) - { - m_Owner.AddSkillMod(this); - } + m_Owner?.AddSkillMod(this); } } } From b779d7737f53be2f3b0eb611906cbe0b6da7bddb Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Tue, 14 Jun 2022 18:39:46 -0700 Subject: [PATCH 197/213] fix: Adds ISpanFormattable support to Serial (#1065) --- Projects/Server.Tests/Tests/SerialTests.cs | 37 +++ Projects/Server/Guild.cs | 2 +- Projects/Server/Items/Item.cs | 14 +- Projects/Server/Mobiles/Mobile.cs | 6 +- Projects/Server/Serial.cs | 252 ++++++++++-------- .../UOContent/Accounting/AccountHandler.cs | 2 +- .../Commands/Generic/Commands/Interface.cs | 4 +- Projects/UOContent/Commands/Logging.cs | 2 +- .../UOContent/Commands/Object Creation/Add.cs | 12 +- Projects/UOContent/Gumps/ClientGump.cs | 2 +- Projects/UOContent/Gumps/Props/PropsGump.cs | 10 +- Projects/UOContent/Items/Armor/BaseArmor.cs | 24 +- .../UOContent/Items/Clothing/BaseClothing.cs | 16 +- Projects/UOContent/Items/Jewels/BaseJewel.cs | 24 +- .../Items/Skill Items/Magical/Spellbook.cs | 24 +- .../UOContent/Items/Weapons/BaseWeapon.cs | 24 +- Projects/UOContent/Misc/AOS.cs | 16 +- Projects/UOContent/Misc/CrashGuard.cs | 2 +- 18 files changed, 269 insertions(+), 204 deletions(-) create mode 100644 Projects/Server.Tests/Tests/SerialTests.cs diff --git a/Projects/Server.Tests/Tests/SerialTests.cs b/Projects/Server.Tests/Tests/SerialTests.cs new file mode 100644 index 000000000..60ff3d370 --- /dev/null +++ b/Projects/Server.Tests/Tests/SerialTests.cs @@ -0,0 +1,37 @@ +using System; +using Xunit; + +namespace Server.Tests; + +public class SerialTests +{ + [Fact] + public void TestSerialTryFormatDefault() + { + var serial = (Serial)0xABCD1234u; + const string serialStr = "0xABCD1234"; + Span buffer = stackalloc char[serialStr.Length]; + var result = serial.TryFormat(buffer, out var charsWritten, null, null); + Assert.True(result); + Assert.Equal(serialStr.Length, charsWritten); + Assert.Equal(serialStr, buffer.ToString()); + + var interpolated = $"{serial}"; + Assert.Equal(serialStr, interpolated); + } + + [Fact] + public void TestSerialTryFormatCustom() + { + var serial = (Serial)0xABCD1234u; + const string serialStr = "2882343476"; + Span buffer = stackalloc char[serialStr.Length]; + var result = serial.TryFormat(buffer, out var charsWritten, "##", null); + Assert.True(result); + Assert.Equal(serialStr.Length, charsWritten); + Assert.Equal(serialStr, buffer.ToString()); + + var interpolated = $"{serial:##}"; + Assert.Equal(serialStr, interpolated); + } +} diff --git a/Projects/Server/Guild.cs b/Projects/Server/Guild.cs index 5ff38abd9..27fb2015b 100644 --- a/Projects/Server/Guild.cs +++ b/Projects/Server/Guild.cs @@ -135,6 +135,6 @@ namespace Server.Guilds return results; } - public override string ToString() => $"0x{Serial.Value:X} \"{Name} [{Abbreviation}]\""; + public override string ToString() => $"{Serial} \"{Name} [{Abbreviation}]\""; } } diff --git a/Projects/Server/Items/Item.cs b/Projects/Server/Items/Item.cs index 027ce41ba..d6d5d0d07 100644 --- a/Projects/Server/Items/Item.cs +++ b/Projects/Server/Items/Item.cs @@ -3165,10 +3165,10 @@ namespace Server if (item == this) { Console.WriteLine( - "Warning: Adding item to itself: [0x{0:X} {1}].AddItem( [0x{2:X} {3}] )", - Serial.Value, + "Warning: Adding item to itself: [0x{0} {1}].AddItem( [0x{2} {3}] )", + Serial, GetType().Name, - item.Serial.Value, + item.Serial, item.GetType().Name ); Console.WriteLine(new StackTrace()); @@ -3178,10 +3178,10 @@ namespace Server if (IsChildOf(item)) { Console.WriteLine( - "Warning: Adding parent item to child: [0x{0:X} {1}].AddItem( [0x{2:X} {3}] )", - Serial.Value, + "Warning: Adding parent item to child: [0x{0} {1}].AddItem( [0x{2} {3}] )", + Serial, GetType().Name, - item.Serial.Value, + item.Serial, item.GetType().Name ); Console.WriteLine(new StackTrace()); @@ -4245,7 +4245,7 @@ namespace Server public virtual bool IsStandardLoot() => (!Mobile.InsuranceEnabled || !Insured) && BlessedFor == null && m_LootType == LootType.Regular; - public override string ToString() => $"0x{Serial.Value:X} \"{GetType().Name}\""; + public override string ToString() => $"{Serial} \"{GetType().Name}\""; public virtual void OnSectorActivate() { diff --git a/Projects/Server/Mobiles/Mobile.cs b/Projects/Server/Mobiles/Mobile.cs index 9db78424b..f6c9055a8 100644 --- a/Projects/Server/Mobiles/Mobile.cs +++ b/Projects/Server/Mobiles/Mobile.cs @@ -3790,7 +3790,7 @@ namespace Server } } - public override string ToString() => $"0x{Serial.Value:X} \"{Name}\""; + public override string ToString() => $"{Serial} \"{Name}\""; public virtual void SendSkillMessage() { @@ -5311,8 +5311,8 @@ namespace Server catch { Console.WriteLine( - "Warning: 0x{0:X}: Item must have a zero parameter constructor to be separated from a stack. '{1}'.", - oldItem.Serial.Value, + "Warning: {0}: Item must have a zero parameter constructor to be separated from a stack. '{1}'.", + oldItem.Serial, oldItem.GetType().Name ); return null; diff --git a/Projects/Server/Serial.cs b/Projects/Server/Serial.cs index 3f90dbb21..7a83163fa 100644 --- a/Projects/Server/Serial.cs +++ b/Projects/Server/Serial.cs @@ -16,120 +16,148 @@ using System; using System.Runtime.CompilerServices; -namespace Server +namespace Server; + +public readonly struct Serial : IComparable, IComparable, IEquatable, ISpanFormattable { - public readonly struct Serial : IComparable, IComparable, IEquatable + public static readonly Serial MinusOne = new(0xFFFFFFFF); + public static readonly Serial Zero = new(0); + + private Serial(uint serial) => Value = serial; + + public uint Value { get; } + + public bool IsMobile { - public static readonly Serial MinusOne = new(0xFFFFFFFF); - public static readonly Serial Zero = new(0); - - private Serial(uint serial) => Value = serial; - - public uint Value { get; } - - public bool IsMobile - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Value > 0 && Value < World.ItemOffset; - } - - public bool IsItem - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Value >= World.ItemOffset && Value < World.MaxItemSerial; - } - - public bool IsValid - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Value > 0; - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override int GetHashCode() => Value.GetHashCode(); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public int CompareTo(Serial other) => Value.CompareTo(other.Value); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public int CompareTo(uint other) => Value.CompareTo(other); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override bool Equals(object obj) => - obj switch - { - Serial serial => this == serial, - uint u => Value == u, - _ => false - }; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator ==(Serial l, Serial r) => l.Value == r.Value; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator ==(Serial l, uint r) => l.Value == r; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator !=(Serial l, Serial r) => l.Value != r.Value; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator !=(Serial l, uint r) => l.Value != r; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator >(Serial l, Serial r) => l.Value > r.Value; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator >(Serial l, uint r) => l.Value > r; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator <(Serial l, Serial r) => l.Value < r.Value; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator <(Serial l, uint r) => l.Value < r; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator >=(Serial l, Serial r) => l.Value >= r.Value; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator >=(Serial l, uint r) => l.Value >= r; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator <=(Serial l, Serial r) => l.Value <= r.Value; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator <=(Serial l, uint r) => l.Value <= r; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Serial operator +(Serial l, Serial r) => (Serial)(l.Value + r.Value); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Serial operator +(Serial l, uint r) => (Serial)(l.Value + r); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Serial operator ++(Serial l) => (Serial)(l.Value + 1); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Serial operator -(Serial l, Serial r) => (Serial)(l.Value - r.Value); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Serial operator -(Serial l, uint r) => (Serial)(l.Value - r); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Serial operator --(Serial l) => (Serial)(l.Value - 1); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override string ToString() => $"0x{Value:X8}"; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static explicit operator uint(Serial a) => a.Value; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static explicit operator Serial(uint a) => new(a); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(Serial other) => Value == other.Value; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public int ToInt32() => (int)Value; + get => Value > 0 && Value < World.ItemOffset; } + + public bool IsItem + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => Value >= World.ItemOffset && Value < World.MaxItemSerial; + } + + public bool IsValid + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => Value > 0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override int GetHashCode() => Value.GetHashCode(); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int CompareTo(Serial other) => Value.CompareTo(other.Value); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int CompareTo(uint other) => Value.CompareTo(other); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override bool Equals(object obj) => + obj switch + { + Serial serial => this == serial, + uint u => Value == u, + _ => false + }; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool operator ==(Serial l, Serial r) => l.Value == r.Value; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool operator ==(Serial l, uint r) => l.Value == r; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool operator !=(Serial l, Serial r) => l.Value != r.Value; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool operator !=(Serial l, uint r) => l.Value != r; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool operator >(Serial l, Serial r) => l.Value > r.Value; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool operator >(Serial l, uint r) => l.Value > r; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool operator <(Serial l, Serial r) => l.Value < r.Value; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool operator <(Serial l, uint r) => l.Value < r; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool operator >=(Serial l, Serial r) => l.Value >= r.Value; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool operator >=(Serial l, uint r) => l.Value >= r; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool operator <=(Serial l, Serial r) => l.Value <= r.Value; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool operator <=(Serial l, uint r) => l.Value <= r; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Serial operator +(Serial l, Serial r) => (Serial)(l.Value + r.Value); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Serial operator +(Serial l, uint r) => (Serial)(l.Value + r); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Serial operator ++(Serial l) => (Serial)(l.Value + 1); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Serial operator -(Serial l, Serial r) => (Serial)(l.Value - r.Value); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Serial operator -(Serial l, uint r) => (Serial)(l.Value - r); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Serial operator --(Serial l) => (Serial)(l.Value - 1); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override string ToString() => $"0x{Value:X8}"; + + public string ToString(string format, IFormatProvider formatProvider) => ToString(); + + public bool TryFormat( + Span destination, out int charsWritten, ReadOnlySpan format, IFormatProvider provider + ) + { + if (format != null) + { + return Value.TryFormat(destination, out charsWritten, format, provider); + } + + if (destination.Length < 10) + { + charsWritten = 0; + return false; + } + + destination[0] = '0'; + destination[1] = 'x'; + + var result = Value.TryFormat(destination[2..], out charsWritten, "X8", provider); + if (result) + { + charsWritten += 2; + } + + return result; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static explicit operator uint(Serial a) => a.Value; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static explicit operator Serial(uint a) => new(a); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Equals(Serial other) => Value == other.Value; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int ToInt32() => (int)Value; } diff --git a/Projects/UOContent/Accounting/AccountHandler.cs b/Projects/UOContent/Accounting/AccountHandler.cs index 06df4cc68..6594fc667 100644 --- a/Projects/UOContent/Accounting/AccountHandler.cs +++ b/Projects/UOContent/Accounting/AccountHandler.cs @@ -255,7 +255,7 @@ namespace Server.Misc } else { - state.LogInfo($"Deleting character {index} (0x{m.Serial.Value:X})"); + state.LogInfo($"Deleting character {index} ({m.Serial})"); acct.Comments.Add(new AccountComment("System", $"Character #{index + 1} {m} deleted by {state}")); diff --git a/Projects/UOContent/Commands/Generic/Commands/Interface.cs b/Projects/UOContent/Commands/Generic/Commands/Interface.cs index b8c4b91e0..b9af25440 100644 --- a/Projects/UOContent/Commands/Generic/Commands/Interface.cs +++ b/Projects/UOContent/Commands/Generic/Commands/Interface.cs @@ -394,7 +394,7 @@ namespace Server.Commands.Generic case 4: // Go there { m_From.SendGump(new InterfaceItemGump(m_From, m_Columns, m_List, m_Page, m_Item)); - InvokeCommand($"Go {m_Item.Serial.Value}"); + InvokeCommand($"Go {m_Item.Serial}"); break; } case 5: // Move to target @@ -567,7 +567,7 @@ namespace Server.Commands.Generic case 4: // Go there { m_From.SendGump(new InterfaceMobileGump(m_From, m_Columns, m_List, m_Page, m_Mobile)); - InvokeCommand($"Go {m_Mobile.Serial.Value}"); + InvokeCommand($"Go {m_Mobile.Serial}"); break; } case 5: // Bring them here diff --git a/Projects/UOContent/Commands/Logging.cs b/Projects/UOContent/Commands/Logging.cs index 1ba8401d8..6fcfa65e3 100644 --- a/Projects/UOContent/Commands/Logging.cs +++ b/Projects/UOContent/Commands/Logging.cs @@ -46,7 +46,7 @@ namespace Server.Commands o switch { Mobile m => m.Account == null ? $"{m} (no account)" : $"{m} ('{m.Account.Username}')", - Item item => $"0x{item.Serial.Value:X} ({item.GetType().Name})", + Item item => $"{item.Serial} ({item.GetType().Name})", _ => o }; diff --git a/Projects/UOContent/Commands/Object Creation/Add.cs b/Projects/UOContent/Commands/Object Creation/Add.cs index a54c84e94..69aee68fd 100644 --- a/Projects/UOContent/Commands/Object Creation/Add.cs +++ b/Projects/UOContent/Commands/Object Creation/Add.cs @@ -35,22 +35,22 @@ namespace Server.Commands { var sb = new StringBuilder(); - sb.AppendFormat("{0} {1} building ", from.AccessLevel, CommandLogging.Format(from)); + sb.Append($"{from.AccessLevel} {CommandLogging.Format(from)} building "); if (start == end) { - sb.AppendFormat("at {0} in {1}", start, from.Map); + sb.Append($"at {start} in {from.Map}"); } else { - sb.AppendFormat("from {0} to {1} in {2}", start, end, from.Map); + sb.Append($"from {start} to {end} in {from.Map}"); } sb.Append(':'); for (var i = 0; i < args.Length; ++i) { - sb.AppendFormat(" \"{0}\"", args[i]); + sb.Append($" \"{args[i]}\""); } CommandLogging.WriteLine(from, sb.ToString()); @@ -321,7 +321,7 @@ namespace Server.Commands { var built = Build(from, ctor, values, props, realProps, ref sendError); - sb.AppendFormat("0x{0:X}; ", built.Serial.Value); + sb.Append($"{built.Serial}; "); if (built is Item item) { @@ -353,7 +353,7 @@ namespace Server.Commands var built = Build(from, ctor, values, props, realProps, ref sendError); - sb.AppendFormat("0x{0:X}; ", built.Serial.Value); + sb.Append($"{built.Serial}; "); if (built is Item item) { diff --git a/Projects/UOContent/Gumps/ClientGump.cs b/Projects/UOContent/Gumps/ClientGump.cs index 4d10f2405..408870f0f 100644 --- a/Projects/UOContent/Gumps/ClientGump.cs +++ b/Projects/UOContent/Gumps/ClientGump.cs @@ -66,7 +66,7 @@ namespace Server.Gumps if (m != null) { AddHtml(14, 36 + line * 20, 200, 20, Color("Mobile:", LabelColor32)); - AddHtml(70, 36 + line++ * 20, 200, 20, Color($"{m.Name} (0x{m.Serial.Value:X})", LabelColor32)); + AddHtml(70, 36 + line++ * 20, 200, 20, Color($"{m.Name} ({m.Serial})", LabelColor32)); AddHtml(14, 36 + line * 20, 200, 20, Color("Location:", LabelColor32)); AddHtml(70, 36 + line++ * 20, 200, 20, Color($"{m.Location} [{m.Map}]", LabelColor32)); diff --git a/Projects/UOContent/Gumps/Props/PropsGump.cs b/Projects/UOContent/Gumps/Props/PropsGump.cs index e7b43f0fc..7eb76c502 100644 --- a/Projects/UOContent/Gumps/Props/PropsGump.cs +++ b/Projects/UOContent/Gumps/Props/PropsGump.cs @@ -511,16 +511,16 @@ namespace Server.Gumps { if (serial.IsItem) { - return $"(I) 0x{serial.Value:X}"; + return $"(I) {serial}"; } if (serial.IsMobile) { - return $"(M) 0x{serial.Value:X}"; + return $"(M) {serial}"; } } - return $"(?) 0x{serial.Value:X}"; + return $"(?) {serial}"; } if (o is byte or sbyte or short or ushort or int or uint or long or ulong) @@ -530,12 +530,12 @@ namespace Server.Gumps if (o is Mobile mobile) { - return $"(M) 0x{mobile.Serial.Value:X} \"{mobile.Name}\""; + return $"(M) {mobile.Serial} \"{mobile.Name}\""; } if (o is Item item) { - return $"(I) 0x{item.Serial.Value:X}"; + return $"(I) {item.Serial}"; } if (o is Type type) diff --git a/Projects/UOContent/Items/Armor/BaseArmor.cs b/Projects/UOContent/Items/Armor/BaseArmor.cs index 029403c30..2cb758847 100644 --- a/Projects/UOContent/Items/Armor/BaseArmor.cs +++ b/Projects/UOContent/Items/Armor/BaseArmor.cs @@ -1056,21 +1056,21 @@ namespace Server.Items if (m != null && (strBonus != 0 || dexBonus != 0 || intBonus != 0)) { - var modName = Serial.ToString(); + var serial = Serial; if (strBonus != 0) { - m.AddStatMod(new StatMod(StatType.Str, $"{modName}Str", strBonus, TimeSpan.Zero)); + m.AddStatMod(new StatMod(StatType.Str, $"{serial}Str", strBonus, TimeSpan.Zero)); } if (dexBonus != 0) { - m.AddStatMod(new StatMod(StatType.Dex, $"{modName}Dex", dexBonus, TimeSpan.Zero)); + m.AddStatMod(new StatMod(StatType.Dex, $"{serial}Dex", dexBonus, TimeSpan.Zero)); } if (intBonus != 0) { - m.AddStatMod(new StatMod(StatType.Int, $"{modName}Int", intBonus, TimeSpan.Zero)); + m.AddStatMod(new StatMod(StatType.Int, $"{serial}Int", intBonus, TimeSpan.Zero)); } } @@ -1180,21 +1180,21 @@ namespace Server.Items if (strBonus != 0 || dexBonus != 0 || intBonus != 0) { - var modName = Serial.ToString(); + var serial = Serial; if (strBonus != 0) { - from.AddStatMod(new StatMod(StatType.Str, $"{modName}Str", strBonus, TimeSpan.Zero)); + from.AddStatMod(new StatMod(StatType.Str, $"{serial}Str", strBonus, TimeSpan.Zero)); } if (dexBonus != 0) { - from.AddStatMod(new StatMod(StatType.Dex, $"{modName}Dex", dexBonus, TimeSpan.Zero)); + from.AddStatMod(new StatMod(StatType.Dex, $"{serial}Dex", dexBonus, TimeSpan.Zero)); } if (intBonus != 0) { - from.AddStatMod(new StatMod(StatType.Int, $"{modName}Int", intBonus, TimeSpan.Zero)); + from.AddStatMod(new StatMod(StatType.Int, $"{serial}Int", intBonus, TimeSpan.Zero)); } } @@ -1205,11 +1205,11 @@ namespace Server.Items { if (parent is Mobile m) { - var modName = Serial.ToString(); + var serial = Serial; - m.RemoveStatMod($"{modName}Str"); - m.RemoveStatMod($"{modName}Dex"); - m.RemoveStatMod($"{modName}Int"); + m.RemoveStatMod($"{serial}Str"); + m.RemoveStatMod($"{serial}Dex"); + m.RemoveStatMod($"{serial}Int"); if (Core.AOS) { diff --git a/Projects/UOContent/Items/Clothing/BaseClothing.cs b/Projects/UOContent/Items/Clothing/BaseClothing.cs index bacf44e70..11dd69859 100644 --- a/Projects/UOContent/Items/Clothing/BaseClothing.cs +++ b/Projects/UOContent/Items/Clothing/BaseClothing.cs @@ -518,21 +518,21 @@ namespace Server.Items return; } - var modName = Serial.ToString(); + var serial = Serial; if (strBonus != 0) { - parent.AddStatMod(new StatMod(StatType.Str, $"{modName}Str", strBonus, TimeSpan.Zero)); + parent.AddStatMod(new StatMod(StatType.Str, $"{serial}Str", strBonus, TimeSpan.Zero)); } if (dexBonus != 0) { - parent.AddStatMod(new StatMod(StatType.Dex, $"{modName}Dex", dexBonus, TimeSpan.Zero)); + parent.AddStatMod(new StatMod(StatType.Dex, $"{serial}Dex", dexBonus, TimeSpan.Zero)); } if (intBonus != 0) { - parent.AddStatMod(new StatMod(StatType.Int, $"{modName}Int", intBonus, TimeSpan.Zero)); + parent.AddStatMod(new StatMod(StatType.Int, $"{serial}Int", intBonus, TimeSpan.Zero)); } } @@ -619,11 +619,11 @@ namespace Server.Items SkillBonuses.Remove(); } - var modName = Serial.ToString(); + var serial = Serial; - mob.RemoveStatMod($"{modName}Str"); - mob.RemoveStatMod($"{modName}Dex"); - mob.RemoveStatMod($"{modName}Int"); + mob.RemoveStatMod($"{serial}Str"); + mob.RemoveStatMod($"{serial}Dex"); + mob.RemoveStatMod($"{serial}Int"); mob.CheckStatTimers(); } diff --git a/Projects/UOContent/Items/Jewels/BaseJewel.cs b/Projects/UOContent/Items/Jewels/BaseJewel.cs index a7c74ea85..c15c2d6e0 100644 --- a/Projects/UOContent/Items/Jewels/BaseJewel.cs +++ b/Projects/UOContent/Items/Jewels/BaseJewel.cs @@ -212,21 +212,21 @@ public abstract partial class BaseJewel : Item, ICraftable if (strBonus != 0 || dexBonus != 0 || intBonus != 0) { - var modName = Serial.ToString(); + var serial = Serial; if (strBonus != 0) { - from.AddStatMod(new StatMod(StatType.Str, $"{modName}Str", strBonus, TimeSpan.Zero)); + from.AddStatMod(new StatMod(StatType.Str, $"{serial}Str", strBonus, TimeSpan.Zero)); } if (dexBonus != 0) { - from.AddStatMod(new StatMod(StatType.Dex, $"{modName}Dex", dexBonus, TimeSpan.Zero)); + from.AddStatMod(new StatMod(StatType.Dex, $"{serial}Dex", dexBonus, TimeSpan.Zero)); } if (intBonus != 0) { - from.AddStatMod(new StatMod(StatType.Int, $"{modName}Int", intBonus, TimeSpan.Zero)); + from.AddStatMod(new StatMod(StatType.Int, $"{serial}Int", intBonus, TimeSpan.Zero)); } } @@ -240,11 +240,11 @@ public abstract partial class BaseJewel : Item, ICraftable { SkillBonuses.Remove(); - var modName = Serial.ToString(); + var serial = Serial; - from.RemoveStatMod($"{modName}Str"); - from.RemoveStatMod($"{modName}Dex"); - from.RemoveStatMod($"{modName}Int"); + from.RemoveStatMod($"{serial}Str"); + from.RemoveStatMod($"{serial}Dex"); + from.RemoveStatMod($"{serial}Int"); from.CheckStatTimers(); } @@ -421,21 +421,21 @@ public abstract partial class BaseJewel : Item, ICraftable if (m != null && (strBonus != 0 || dexBonus != 0 || intBonus != 0)) { - var modName = Serial.ToString(); + var serial = Serial; if (strBonus != 0) { - m.AddStatMod(new StatMod(StatType.Str, $"{modName}Str", strBonus, TimeSpan.Zero)); + m.AddStatMod(new StatMod(StatType.Str, $"{serial}Str", strBonus, TimeSpan.Zero)); } if (dexBonus != 0) { - m.AddStatMod(new StatMod(StatType.Dex, $"{modName}Dex", dexBonus, TimeSpan.Zero)); + m.AddStatMod(new StatMod(StatType.Dex, $"{serial}Dex", dexBonus, TimeSpan.Zero)); } if (intBonus != 0) { - m.AddStatMod(new StatMod(StatType.Int, $"{modName}Int", intBonus, TimeSpan.Zero)); + m.AddStatMod(new StatMod(StatType.Int, $"{serial}Int", intBonus, TimeSpan.Zero)); } } diff --git a/Projects/UOContent/Items/Skill Items/Magical/Spellbook.cs b/Projects/UOContent/Items/Skill Items/Magical/Spellbook.cs index c15bd699d..9de8c67d2 100644 --- a/Projects/UOContent/Items/Skill Items/Magical/Spellbook.cs +++ b/Projects/UOContent/Items/Skill Items/Magical/Spellbook.cs @@ -623,21 +623,21 @@ namespace Server.Items if (strBonus != 0 || dexBonus != 0 || intBonus != 0) { - var modName = Serial.ToString(); + var serial = Serial; if (strBonus != 0) { - from.AddStatMod(new StatMod(StatType.Str, $"{modName}Str", strBonus, TimeSpan.Zero)); + from.AddStatMod(new StatMod(StatType.Str, $"{serial}Str", strBonus, TimeSpan.Zero)); } if (dexBonus != 0) { - from.AddStatMod(new StatMod(StatType.Dex, $"{modName}Dex", dexBonus, TimeSpan.Zero)); + from.AddStatMod(new StatMod(StatType.Dex, $"{serial}Dex", dexBonus, TimeSpan.Zero)); } if (intBonus != 0) { - from.AddStatMod(new StatMod(StatType.Int, $"{modName}Int", intBonus, TimeSpan.Zero)); + from.AddStatMod(new StatMod(StatType.Int, $"{serial}Int", intBonus, TimeSpan.Zero)); } } @@ -651,11 +651,11 @@ namespace Server.Items { SkillBonuses.Remove(); - var modName = Serial.ToString(); + var serial = Serial; - from.RemoveStatMod($"{modName}Str"); - from.RemoveStatMod($"{modName}Dex"); - from.RemoveStatMod($"{modName}Int"); + from.RemoveStatMod($"{serial}Str"); + from.RemoveStatMod($"{serial}Dex"); + from.RemoveStatMod($"{serial}Int"); from.CheckStatTimers(); } @@ -974,21 +974,21 @@ namespace Server.Items { if (strBonus != 0 || dexBonus != 0 || intBonus != 0) { - var modName = Serial.ToString(); + var serial = Serial; if (strBonus != 0) { - m.AddStatMod(new StatMod(StatType.Str, $"{modName}Str", strBonus, TimeSpan.Zero)); + m.AddStatMod(new StatMod(StatType.Str, $"{serial}Str", strBonus, TimeSpan.Zero)); } if (dexBonus != 0) { - m.AddStatMod(new StatMod(StatType.Dex, $"{modName}Dex", dexBonus, TimeSpan.Zero)); + m.AddStatMod(new StatMod(StatType.Dex, $"{serial}Dex", dexBonus, TimeSpan.Zero)); } if (intBonus != 0) { - m.AddStatMod(new StatMod(StatType.Int, $"{modName}Int", intBonus, TimeSpan.Zero)); + m.AddStatMod(new StatMod(StatType.Int, $"{serial}Int", intBonus, TimeSpan.Zero)); } } diff --git a/Projects/UOContent/Items/Weapons/BaseWeapon.cs b/Projects/UOContent/Items/Weapons/BaseWeapon.cs index 9e560bcf2..0ae416987 100644 --- a/Projects/UOContent/Items/Weapons/BaseWeapon.cs +++ b/Projects/UOContent/Items/Weapons/BaseWeapon.cs @@ -939,21 +939,21 @@ namespace Server.Items { var m = from; - var modName = Serial.ToString(); + var serial = Serial; if (strBonus != 0) { - m.AddStatMod(new StatMod(StatType.Str, $"{modName}Str", strBonus, TimeSpan.Zero)); + m.AddStatMod(new StatMod(StatType.Str, $"{serial}Str", strBonus, TimeSpan.Zero)); } if (dexBonus != 0) { - m.AddStatMod(new StatMod(StatType.Dex, $"{modName}Dex", dexBonus, TimeSpan.Zero)); + m.AddStatMod(new StatMod(StatType.Dex, $"{serial}Dex", dexBonus, TimeSpan.Zero)); } if (intBonus != 0) { - m.AddStatMod(new StatMod(StatType.Int, $"{modName}Int", intBonus, TimeSpan.Zero)); + m.AddStatMod(new StatMod(StatType.Int, $"{serial}Int", intBonus, TimeSpan.Zero)); } } @@ -1004,11 +1004,11 @@ namespace Server.Items return; } - var modName = Serial.ToString(); + var serial = Serial; - m.RemoveStatMod($"{modName}Str"); - m.RemoveStatMod($"{modName}Dex"); - m.RemoveStatMod($"{modName}Int"); + m.RemoveStatMod($"{serial}Str"); + m.RemoveStatMod($"{serial}Dex"); + m.RemoveStatMod($"{serial}Int"); if (!_enableInstaHit && m.Weapon is BaseWeapon weapon) { @@ -4148,21 +4148,21 @@ namespace Server.Items if (parentMobile != null && (strBonus != 0 || dexBonus != 0 || intBonus != 0)) { - var modName = Serial.ToString(); + var serial = Serial; if (strBonus != 0) { - parentMobile.AddStatMod(new StatMod(StatType.Str, $"{modName}Str", strBonus, TimeSpan.Zero)); + parentMobile.AddStatMod(new StatMod(StatType.Str, $"{serial}Str", strBonus, TimeSpan.Zero)); } if (dexBonus != 0) { - parentMobile.AddStatMod(new StatMod(StatType.Dex, $"{modName}Dex", dexBonus, TimeSpan.Zero)); + parentMobile.AddStatMod(new StatMod(StatType.Dex, $"{serial}Dex", dexBonus, TimeSpan.Zero)); } if (intBonus != 0) { - parentMobile.AddStatMod(new StatMod(StatType.Int, $"{modName}Int", intBonus, TimeSpan.Zero)); + parentMobile.AddStatMod(new StatMod(StatType.Int, $"{serial}Int", intBonus, TimeSpan.Zero)); } } diff --git a/Projects/UOContent/Misc/AOS.cs b/Projects/UOContent/Misc/AOS.cs index 02ca10b8d..18f7f3210 100644 --- a/Projects/UOContent/Misc/AOS.cs +++ b/Projects/UOContent/Misc/AOS.cs @@ -566,21 +566,21 @@ namespace Server if (strBonus != 0 || dexBonus != 0 || intBonus != 0) { - var modName = Owner.Serial.ToString(); + var serial = Owner.Serial; if (strBonus != 0) { - to.AddStatMod(new StatMod(StatType.Str, $"{modName}Str", strBonus, TimeSpan.Zero)); + to.AddStatMod(new StatMod(StatType.Str, $"{serial}Str", strBonus, TimeSpan.Zero)); } if (dexBonus != 0) { - to.AddStatMod(new StatMod(StatType.Dex, $"{modName}Dex", dexBonus, TimeSpan.Zero)); + to.AddStatMod(new StatMod(StatType.Dex, $"{serial}Dex", dexBonus, TimeSpan.Zero)); } if (intBonus != 0) { - to.AddStatMod(new StatMod(StatType.Int, $"{modName}Int", intBonus, TimeSpan.Zero)); + to.AddStatMod(new StatMod(StatType.Int, $"{serial}Int", intBonus, TimeSpan.Zero)); } } @@ -589,11 +589,11 @@ namespace Server public void RemoveStatBonuses(Mobile from) { - var modName = Owner.Serial.ToString(); + var serial = Owner.Serial; - from.RemoveStatMod($"{modName}Str"); - from.RemoveStatMod($"{modName}Dex"); - from.RemoveStatMod($"{modName}Int"); + from.RemoveStatMod($"{serial}Str"); + from.RemoveStatMod($"{serial}Dex"); + from.RemoveStatMod($"{serial}Int"); from.CheckStatTimers(); } diff --git a/Projects/UOContent/Misc/CrashGuard.cs b/Projects/UOContent/Misc/CrashGuard.cs index c41b213fa..a6a695c89 100644 --- a/Projects/UOContent/Misc/CrashGuard.cs +++ b/Projects/UOContent/Misc/CrashGuard.cs @@ -195,7 +195,7 @@ namespace Server.Misc if (m != null) { - op.Write($" (mobile = 0x{m.Serial.Value:X} '{m.Name}')"); + op.Write($" (mobile = {m.Serial} '{m.Name}')"); } op.WriteLine(); From f24b98f8e238256585c776253040b9e93f85a2f1 Mon Sep 17 00:00:00 2001 From: Stefano Merotta <97297186+stefanomerotta@users.noreply.github.com> Date: Wed, 15 Jun 2022 21:48:43 +0200 Subject: [PATCH 198/213] fix: Replaces throttlers and packet callbacks with function pointers (#1063) Replaces multi-cast delegates with function pointers to gain 25% in performance and lower allocations. --- .../Network/ContainerGridPacketHandler.cs | 5 +- Projects/Server/Network/NetState/NetState.cs | 4 +- Projects/Server/Network/PacketHandler.cs | 14 ++-- .../Network/Packets/IncomingAccountPackets.cs | 28 ++++---- .../Network/Packets/IncomingEntityPackets.cs | 10 +-- .../Packets/IncomingExtendedCommandPackets.cs | 47 +++++++------- .../Network/Packets/IncomingHousePackets.cs | 4 +- .../Network/Packets/IncomingItemPackets.cs | 12 ++-- .../Network/Packets/IncomingMessagePackets.cs | 6 +- .../Network/Packets/IncomingMobilePackets.cs | 10 +-- .../Packets/IncomingMovementPackets.cs | 4 +- .../Server/Network/Packets/IncomingPackets.cs | 5 +- .../Network/Packets/IncomingPlayerPackets.cs | 46 ++++++------- .../Packets/IncomingTargetingPackets.cs | 4 +- .../Network/Packets/IncomingVendorPackets.cs | 6 +- .../Accounting/AccountAttackLimiter.cs | 8 +-- .../UOContent/Engines/Chat/ChatPackets.cs | 6 +- .../Engines/ML Quests/Gumps/RaceChangeGump.cs | 4 +- .../Engines/UltimaStore/UltimaStorePackets.cs | 4 +- Projects/UOContent/Items/Books/BookPackets.cs | 8 +-- .../Bulletin Boards/BulletinBoardPackets.cs | 4 +- .../Items/Games/Mahjong/MahjongPackets.cs | 4 +- .../UOContent/Items/Maps/MapItemPackets.cs | 4 +- Projects/UOContent/Misc/HardwareInfo.cs | 4 +- Projects/UOContent/Misc/PacketThrottles.cs | 8 +-- .../Multis/Houses/HouseFoundation.cs | 4 +- .../UOContent/Network/FreeshardProtocol.cs | 9 ++- Projects/UOContent/Network/MapUO.cs | 15 +++-- .../UOContent/Network/ProtocolExtensions.cs | 64 +++++++++++-------- Projects/UOContent/Network/UOGateway.cs | 6 +- .../UOContent/Skills/Tracking/Tracking.cs | 4 +- 31 files changed, 189 insertions(+), 172 deletions(-) diff --git a/Projects/Server/Network/ContainerGridPacketHandler.cs b/Projects/Server/Network/ContainerGridPacketHandler.cs index ccbf94603..0907a3d43 100644 --- a/Projects/Server/Network/ContainerGridPacketHandler.cs +++ b/Projects/Server/Network/ContainerGridPacketHandler.cs @@ -15,9 +15,10 @@ namespace Server.Network; -public class ContainerGridPacketHandler : PacketHandler +public unsafe class ContainerGridPacketHandler : PacketHandler { - public ContainerGridPacketHandler(int packetID, int length, bool ingame, OnPacketReceive onReceive) + public ContainerGridPacketHandler(int packetID, int length, bool ingame, + delegate* onReceive) : base(packetID, length, ingame, onReceive) { } diff --git a/Projects/Server/Network/NetState/NetState.cs b/Projects/Server/Network/NetState/NetState.cs index 036f8f3a9..fad1ffe5e 100755 --- a/Projects/Server/Network/NetState/NetState.cs +++ b/Projects/Server/Network/NetState/NetState.cs @@ -745,7 +745,7 @@ public partial class NetState : IComparable * length is the total buffer length. We might be able to use packetReader.Capacity() instead. * packetLength is the length of the packet that this function actually found. */ - private ParserState HandlePacket(CircularBufferReader packetReader, byte packetId, out int packetLength) + private unsafe ParserState HandlePacket(CircularBufferReader packetReader, byte packetId, out int packetLength) { PacketHandler handler = IncomingPackets.GetHandler(packetId); int length = packetReader.Length; @@ -793,7 +793,7 @@ public partial class NetState : IComparable } } - ThrottlePacketCallback throttler = handler.ThrottleCallback; + var throttler = handler.ThrottleCallback; if (throttler != null) { if (!throttler(packetId, this, out bool drop)) diff --git a/Projects/Server/Network/PacketHandler.cs b/Projects/Server/Network/PacketHandler.cs index fdf13b589..8ee6ff7df 100644 --- a/Projects/Server/Network/PacketHandler.cs +++ b/Projects/Server/Network/PacketHandler.cs @@ -15,15 +15,11 @@ namespace Server.Network; -public delegate void OnPacketReceive(NetState state, CircularBufferReader reader, int packetLength); - -public delegate bool ThrottlePacketCallback(int packetId, NetState state, out bool drop); - -public class PacketHandler +public unsafe class PacketHandler { - private int _length; + private readonly int _length; - public PacketHandler(int packetID, int length, bool ingame, OnPacketReceive onReceive) + public PacketHandler(int packetID, int length, bool ingame, delegate* onReceive) { _length = length; PacketID = packetID; @@ -35,9 +31,9 @@ public class PacketHandler public virtual int GetLength(NetState ns) => _length; - public OnPacketReceive OnReceive { get; } + public delegate* OnReceive { get; } - public ThrottlePacketCallback ThrottleCallback { get; set; } + public delegate* ThrottleCallback { get; set; } public bool Ingame { get; } } diff --git a/Projects/Server/Network/Packets/IncomingAccountPackets.cs b/Projects/Server/Network/Packets/IncomingAccountPackets.cs index a29d6157c..33cb6117b 100644 --- a/Projects/Server/Network/Packets/IncomingAccountPackets.cs +++ b/Projects/Server/Network/Packets/IncomingAccountPackets.cs @@ -38,21 +38,21 @@ public static class IncomingAccountPackets } } - public static void Configure() + public static unsafe void Configure() { - IncomingPackets.Register(0x00, 104, false, CreateCharacter); - IncomingPackets.Register(0x5D, 73, false, PlayCharacter); - IncomingPackets.Register(0x80, 62, false, AccountLogin); - IncomingPackets.Register(0x83, 39, false, DeleteCharacter); - IncomingPackets.Register(0x91, 65, false, GameLogin); - IncomingPackets.Register(0xA0, 3, false, PlayServer); - IncomingPackets.Register(0xBB, 9, false, AccountID); - IncomingPackets.Register(0xBD, 0, false, ClientVersion); - IncomingPackets.Register(0xBE, 0, true, AssistVersion); - IncomingPackets.Register(0xCF, 0, false, AccountLogin); - IncomingPackets.Register(0xE1, 0, false, ClientType); - IncomingPackets.Register(0xEF, 21, false, LoginServerSeed); - IncomingPackets.Register(0xF8, 106, false, CreateCharacter); + IncomingPackets.Register(0x00, 104, false, &CreateCharacter); + IncomingPackets.Register(0x5D, 73, false, &PlayCharacter); + IncomingPackets.Register(0x80, 62, false, &AccountLogin); + IncomingPackets.Register(0x83, 39, false, &DeleteCharacter); + IncomingPackets.Register(0x91, 65, false, &GameLogin); + IncomingPackets.Register(0xA0, 3, false, &PlayServer); + IncomingPackets.Register(0xBB, 9, false, &AccountID); + IncomingPackets.Register(0xBD, 0, false, &ClientVersion); + IncomingPackets.Register(0xBE, 0, true, &AssistVersion); + IncomingPackets.Register(0xCF, 0, false, &AccountLogin); + IncomingPackets.Register(0xE1, 0, false, &ClientType); + IncomingPackets.Register(0xEF, 21, false, &LoginServerSeed); + IncomingPackets.Register(0xF8, 106, false, &CreateCharacter); } public static void CreateCharacter(NetState state, CircularBufferReader reader, int packetLength) diff --git a/Projects/Server/Network/Packets/IncomingEntityPackets.cs b/Projects/Server/Network/Packets/IncomingEntityPackets.cs index 8ae998b03..30f56b7ef 100644 --- a/Projects/Server/Network/Packets/IncomingEntityPackets.cs +++ b/Projects/Server/Network/Packets/IncomingEntityPackets.cs @@ -19,12 +19,12 @@ public static class IncomingEntityPackets { public static bool SingleClickProps { get; set; } - public static void Configure() + public static unsafe void Configure() { - IncomingPackets.Register(0x06, 5, true, UseReq); - IncomingPackets.Register(0x09, 5, true, LookReq); - IncomingPackets.Register(0xB6, 9, true, ObjectHelpRequest); - IncomingPackets.Register(0xD6, 0, true, BatchQueryProperties); + IncomingPackets.Register(0x06, 5, true, &UseReq); + IncomingPackets.Register(0x09, 5, true, &LookReq); + IncomingPackets.Register(0xB6, 9, true, &ObjectHelpRequest); + IncomingPackets.Register(0xD6, 0, true, &BatchQueryProperties); } public static void ObjectHelpRequest(NetState state, CircularBufferReader reader, int packetLength) diff --git a/Projects/Server/Network/Packets/IncomingExtendedCommandPackets.cs b/Projects/Server/Network/Packets/IncomingExtendedCommandPackets.cs index 0a8e399aa..a9b15cfbf 100644 --- a/Projects/Server/Network/Packets/IncomingExtendedCommandPackets.cs +++ b/Projects/Server/Network/Packets/IncomingExtendedCommandPackets.cs @@ -34,29 +34,29 @@ public static class IncomingExtendedCommandPackets 125, 126, 127, 128 }; - public static void Configure() + public static unsafe void Configure() { - IncomingPackets.Register(0xBF, 0, true, ExtendedCommand); + IncomingPackets.Register(0xBF, 0, true, &ExtendedCommand); - RegisterExtended(0x05, false, ScreenSize); - RegisterExtended(0x06, true, PartyMessage); - RegisterExtended(0x09, true, DisarmRequest); - RegisterExtended(0x0A, true, StunRequest); - RegisterExtended(0x0B, false, Language); - RegisterExtended(0x0C, true, CloseStatus); - RegisterExtended(0x0E, true, Animate); - RegisterExtended(0x0F, false, Empty); // What's this? - RegisterExtended(0x10, true, QueryProperties); - RegisterExtended(0x13, true, ContextMenuRequest); - RegisterExtended(0x15, true, ContextMenuResponse); - RegisterExtended(0x1A, true, StatLockChange); - RegisterExtended(0x1C, true, CastSpell); - RegisterExtended(0x24, false, UnhandledBF); - RegisterExtended(0x2C, true, BandageTarget); - RegisterExtended(0x2D, true, TargetedSpell); - RegisterExtended(0x2E, true, TargetedSkillUse); - RegisterExtended(0x30, true, TargetByResourceMacro); - RegisterExtended(0x32, true, ToggleFlying); + RegisterExtended(0x05, false, &ScreenSize); + RegisterExtended(0x06, true, &PartyMessage); + RegisterExtended(0x09, true, &DisarmRequest); + RegisterExtended(0x0A, true, &StunRequest); + RegisterExtended(0x0B, false, &Language); + RegisterExtended(0x0C, true, &CloseStatus); + RegisterExtended(0x0E, true, &Animate); + RegisterExtended(0x0F, false, &Empty); // What's this? + RegisterExtended(0x10, true, &QueryProperties); + RegisterExtended(0x13, true, &ContextMenuRequest); + RegisterExtended(0x15, true, &ContextMenuResponse); + RegisterExtended(0x1A, true, &StatLockChange); + RegisterExtended(0x1C, true, &CastSpell); + RegisterExtended(0x24, false, &UnhandledBF); + RegisterExtended(0x2C, true, &BandageTarget); + RegisterExtended(0x2D, true, &TargetedSpell); + RegisterExtended(0x2E, true, &TargetedSkillUse); + RegisterExtended(0x30, true, &TargetByResourceMacro); + RegisterExtended(0x32, true, &ToggleFlying); } private static void UnhandledBF(NetState state, CircularBufferReader reader, int packetLength) @@ -67,7 +67,8 @@ public static class IncomingExtendedCommandPackets { } - public static void RegisterExtended(int packetID, bool ingame, OnPacketReceive onReceive) + public static unsafe void RegisterExtended(int packetID, bool ingame, + delegate* onReceive) { if (packetID is >= 0 and < 0x100) { @@ -86,7 +87,7 @@ public static class IncomingExtendedCommandPackets } } - public static void ExtendedCommand(NetState state, CircularBufferReader reader, int packetLength) + public static unsafe void ExtendedCommand(NetState state, CircularBufferReader reader, int packetLength) { int packetId = reader.ReadUInt16(); diff --git a/Projects/Server/Network/Packets/IncomingHousePackets.cs b/Projects/Server/Network/Packets/IncomingHousePackets.cs index 1d9925537..a1ba476ab 100644 --- a/Projects/Server/Network/Packets/IncomingHousePackets.cs +++ b/Projects/Server/Network/Packets/IncomingHousePackets.cs @@ -17,9 +17,9 @@ namespace Server.Network; public static class IncomingHousePackets { - public static void Configure() + public static unsafe void Configure() { - IncomingPackets.Register(0xFB, 2, false, ShowPublicHouseContent); + IncomingPackets.Register(0xFB, 2, false, &ShowPublicHouseContent); } public static void ShowPublicHouseContent(NetState state, CircularBufferReader reader, int packetLength) diff --git a/Projects/Server/Network/Packets/IncomingItemPackets.cs b/Projects/Server/Network/Packets/IncomingItemPackets.cs index 0b9059d19..beb58b189 100644 --- a/Projects/Server/Network/Packets/IncomingItemPackets.cs +++ b/Projects/Server/Network/Packets/IncomingItemPackets.cs @@ -21,13 +21,13 @@ namespace Server.Network; public static class IncomingItemPackets { - public static void Configure() + public static unsafe void Configure() { - IncomingPackets.Register(0x07, 7, true, LiftReq); - IncomingPackets.Register(new ContainerGridPacketHandler(0x08, 14, true, DropReq)); - IncomingPackets.Register(0x13, 10, true, EquipReq); - IncomingPackets.Register(0xEC, 0, false, EquipMacro); - IncomingPackets.Register(0xED, 0, false, UnequipMacro); + IncomingPackets.Register(0x07, 7, true, &LiftReq); + IncomingPackets.Register(new ContainerGridPacketHandler(0x08, 14, true, &DropReq)); + IncomingPackets.Register(0x13, 10, true, &EquipReq); + IncomingPackets.Register(0xEC, 0, false, &EquipMacro); + IncomingPackets.Register(0xED, 0, false, &UnequipMacro); } public static void LiftReq(NetState state, CircularBufferReader reader, int packetLength) diff --git a/Projects/Server/Network/Packets/IncomingMessagePackets.cs b/Projects/Server/Network/Packets/IncomingMessagePackets.cs index 8bea6bb45..5404bc2ed 100644 --- a/Projects/Server/Network/Packets/IncomingMessagePackets.cs +++ b/Projects/Server/Network/Packets/IncomingMessagePackets.cs @@ -40,10 +40,10 @@ public static class IncomingMessagePackets { private static readonly KeywordList m_KeywordList = new(); - public static void Configure() + public static unsafe void Configure() { - IncomingPackets.Register(0x03, 0, true, AsciiSpeech); - IncomingPackets.Register(0xAD, 0, true, UnicodeSpeech); + IncomingPackets.Register(0x03, 0, true, &AsciiSpeech); + IncomingPackets.Register(0xAD, 0, true, &UnicodeSpeech); } public static void AsciiSpeech(NetState state, CircularBufferReader reader, int packetLength) diff --git a/Projects/Server/Network/Packets/IncomingMobilePackets.cs b/Projects/Server/Network/Packets/IncomingMobilePackets.cs index a612e4ea1..1cdcb7c62 100644 --- a/Projects/Server/Network/Packets/IncomingMobilePackets.cs +++ b/Projects/Server/Network/Packets/IncomingMobilePackets.cs @@ -19,12 +19,12 @@ namespace Server.Network; public static class IncomingMobilePackets { - public static void Configure() + public static unsafe void Configure() { - IncomingPackets.Register(0x75, 35, true, RenameRequest); - IncomingPackets.Register(0x98, 0, true, MobileNameRequest); - IncomingPackets.Register(0xB8, 0, true, ProfileReq); - IncomingPackets.Register(0x6F, 0, true, SecureTrade); + IncomingPackets.Register(0x75, 35, true, &RenameRequest); + IncomingPackets.Register(0x98, 0, true, &MobileNameRequest); + IncomingPackets.Register(0xB8, 0, true, &ProfileReq); + IncomingPackets.Register(0x6F, 0, true, &SecureTrade); } public static void RenameRequest(NetState state, CircularBufferReader reader, int packetLength) diff --git a/Projects/Server/Network/Packets/IncomingMovementPackets.cs b/Projects/Server/Network/Packets/IncomingMovementPackets.cs index 9a361bfa2..9fc1bb0a3 100644 --- a/Projects/Server/Network/Packets/IncomingMovementPackets.cs +++ b/Projects/Server/Network/Packets/IncomingMovementPackets.cs @@ -17,9 +17,9 @@ namespace Server.Network; public static class IncomingMovementPackets { - public static void Configure() + public static unsafe void Configure() { - IncomingPackets.Register(0x02, 7, true, MovementReq); + IncomingPackets.Register(0x02, 7, true, &MovementReq); // Not used by OSI, and interferes with ClassicUO/Razor protocol extensions // IncomingPackets.Register(0xF0, 0, true, NewMovementReq); // IncomingPackets.Register(0xF1, 9, true, TimeSyncReq); diff --git a/Projects/Server/Network/Packets/IncomingPackets.cs b/Projects/Server/Network/Packets/IncomingPackets.cs index 3aa6e2597..23012d7ae 100644 --- a/Projects/Server/Network/Packets/IncomingPackets.cs +++ b/Projects/Server/Network/Packets/IncomingPackets.cs @@ -24,7 +24,8 @@ public static class IncomingPackets public static PacketHandler[] Handlers { get; } = new PacketHandler[0x100]; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Register(int packetID, int length, bool ingame, OnPacketReceive onReceive) => + public static unsafe void Register(int packetID, int length, bool ingame, + delegate* onReceive) => Register(new PacketHandler(packetID, length, ingame, onReceive)); public static void Register(PacketHandler packetHandler) @@ -53,7 +54,7 @@ public static class IncomingPackets } } - public static void RegisterThrottler(int packetID, ThrottlePacketCallback t) + public static unsafe void RegisterThrottler(int packetID, delegate* t) { var ph = GetHandler(packetID); diff --git a/Projects/Server/Network/Packets/IncomingPlayerPackets.cs b/Projects/Server/Network/Packets/IncomingPlayerPackets.cs index 7de69d681..e409e3edd 100644 --- a/Projects/Server/Network/Packets/IncomingPlayerPackets.cs +++ b/Projects/Server/Network/Packets/IncomingPlayerPackets.cs @@ -23,30 +23,30 @@ namespace Server.Network; public static class IncomingPlayerPackets { - public static void Configure() + public static unsafe void Configure() { - IncomingPackets.Register(0x01, 5, false, Disconnect); - IncomingPackets.Register(0x05, 5, true, AttackReq); - IncomingPackets.Register(0x12, 0, true, TextCommand); - IncomingPackets.Register(0x22, 3, true, Resynchronize); - IncomingPackets.Register(0x2C, 2, true, DeathStatusResponse); - IncomingPackets.Register(0x34, 10, true, MobileQuery); - IncomingPackets.Register(0x3A, 0, true, ChangeSkillLock); - IncomingPackets.Register(0x72, 5, true, SetWarMode); - IncomingPackets.Register(0x73, 2, false, PingReq); - IncomingPackets.Register(0x7D, 13, true, MenuResponse); - IncomingPackets.Register(0x95, 9, true, HuePickerResponse); - IncomingPackets.Register(0x9A, 0, true, AsciiPromptResponse); - IncomingPackets.Register(0x9B, 258, true, HelpRequest); - IncomingPackets.Register(0xA4, 149, false, SystemInfo); - IncomingPackets.Register(0xA7, 4, true, RequestScrollWindow); - IncomingPackets.Register(0xB1, 0, true, DisplayGumpResponse); - IncomingPackets.Register(0xC2, 0, true, UnicodePromptResponse); - IncomingPackets.Register(0xC8, 2, true, SetUpdateRange); - IncomingPackets.Register(0xD0, 0, true, ConfigurationFile); - IncomingPackets.Register(0xD1, 2, true, LogoutReq); - IncomingPackets.Register(0xD7, 0, true, EncodedCommand); - IncomingPackets.Register(0xF4, 0, false, CrashReport); + IncomingPackets.Register(0x01, 5, false, &Disconnect); + IncomingPackets.Register(0x05, 5, true, &AttackReq); + IncomingPackets.Register(0x12, 0, true, &TextCommand); + IncomingPackets.Register(0x22, 3, true, &Resynchronize); + IncomingPackets.Register(0x2C, 2, true, &DeathStatusResponse); + IncomingPackets.Register(0x34, 10, true, &MobileQuery); + IncomingPackets.Register(0x3A, 0, true, &ChangeSkillLock); + IncomingPackets.Register(0x72, 5, true, &SetWarMode); + IncomingPackets.Register(0x73, 2, false, &PingReq); + IncomingPackets.Register(0x7D, 13, true, &MenuResponse); + IncomingPackets.Register(0x95, 9, true, &HuePickerResponse); + IncomingPackets.Register(0x9A, 0, true, &AsciiPromptResponse); + IncomingPackets.Register(0x9B, 258, true, &HelpRequest); + IncomingPackets.Register(0xA4, 149, false, &SystemInfo); + IncomingPackets.Register(0xA7, 4, true, &RequestScrollWindow); + IncomingPackets.Register(0xB1, 0, true, &DisplayGumpResponse); + IncomingPackets.Register(0xC2, 0, true, &UnicodePromptResponse); + IncomingPackets.Register(0xC8, 2, true, &SetUpdateRange); + IncomingPackets.Register(0xD0, 0, true, &ConfigurationFile); + IncomingPackets.Register(0xD1, 2, true, &LogoutReq); + IncomingPackets.Register(0xD7, 0, true, &EncodedCommand); + IncomingPackets.Register(0xF4, 0, false, &CrashReport); IncomingPackets.RegisterEncoded(0x28, true, GuildGumpRequest); IncomingPackets.RegisterEncoded(0x32, true, QuestGumpRequest); diff --git a/Projects/Server/Network/Packets/IncomingTargetingPackets.cs b/Projects/Server/Network/Packets/IncomingTargetingPackets.cs index e4bcd7342..b4efa9e81 100644 --- a/Projects/Server/Network/Packets/IncomingTargetingPackets.cs +++ b/Projects/Server/Network/Packets/IncomingTargetingPackets.cs @@ -20,9 +20,9 @@ namespace Server.Network; public static class IncomingTargetingPackets { - public static void Configure() + public static unsafe void Configure() { - IncomingPackets.Register(0x6C, 19, true, TargetResponse); + IncomingPackets.Register(0x6C, 19, true, &TargetResponse); } public static void TargetResponse(NetState state, CircularBufferReader reader, int packetLength) diff --git a/Projects/Server/Network/Packets/IncomingVendorPackets.cs b/Projects/Server/Network/Packets/IncomingVendorPackets.cs index 7328639c7..2f11b20e4 100644 --- a/Projects/Server/Network/Packets/IncomingVendorPackets.cs +++ b/Projects/Server/Network/Packets/IncomingVendorPackets.cs @@ -19,10 +19,10 @@ namespace Server.Network; public static class IncomingVendorPackets { - public static void Configure() + public static unsafe void Configure() { - IncomingPackets.Register(0x3B, 0, true, VendorBuyReply); - IncomingPackets.Register(0x9F, 0, true, VendorSellReply); + IncomingPackets.Register(0x3B, 0, true, &VendorBuyReply); + IncomingPackets.Register(0x9F, 0, true, &VendorSellReply); } public static void VendorBuyReply(NetState state, CircularBufferReader reader, int packetLength) diff --git a/Projects/UOContent/Accounting/AccountAttackLimiter.cs b/Projects/UOContent/Accounting/AccountAttackLimiter.cs index 97bbc90df..53143327b 100644 --- a/Projects/UOContent/Accounting/AccountAttackLimiter.cs +++ b/Projects/UOContent/Accounting/AccountAttackLimiter.cs @@ -17,16 +17,16 @@ namespace Server.Accounting Enabled = ServerConfiguration.GetOrUpdateSetting("accountAttackLimiter.enable", true); } - public static void Initialize() + public static unsafe void Initialize() { if (!Enabled) { return; } - IncomingPackets.RegisterThrottler(0x80, Throttle); - IncomingPackets.RegisterThrottler(0x91, Throttle); - IncomingPackets.RegisterThrottler(0xCF, Throttle); + IncomingPackets.RegisterThrottler(0x80, &Throttle); + IncomingPackets.RegisterThrottler(0x91, &Throttle); + IncomingPackets.RegisterThrottler(0xCF, &Throttle); } public static bool Throttle(int packetId, NetState ns, out bool drop) diff --git a/Projects/UOContent/Engines/Chat/ChatPackets.cs b/Projects/UOContent/Engines/Chat/ChatPackets.cs index 7eedb3abf..31c63bdb6 100644 --- a/Projects/UOContent/Engines/Chat/ChatPackets.cs +++ b/Projects/UOContent/Engines/Chat/ChatPackets.cs @@ -21,10 +21,10 @@ namespace Server.Engines.Chat { public static class ChatPackets { - public static void Configure() + public static unsafe void Configure() { - IncomingPackets.Register(0xB5, 0x40, true, OpenChatWindowRequest); - IncomingPackets.Register(0xB3, 0, true, ChatAction); + IncomingPackets.Register(0xB5, 0x40, true, &OpenChatWindowRequest); + IncomingPackets.Register(0xB3, 0, true, &ChatAction); } public static void OpenChatWindowRequest(NetState state, CircularBufferReader reader, int packetLength) diff --git a/Projects/UOContent/Engines/ML Quests/Gumps/RaceChangeGump.cs b/Projects/UOContent/Engines/ML Quests/Gumps/RaceChangeGump.cs index d19425fa8..abc739166 100644 --- a/Projects/UOContent/Engines/ML Quests/Gumps/RaceChangeGump.cs +++ b/Projects/UOContent/Engines/ML Quests/Gumps/RaceChangeGump.cs @@ -76,11 +76,11 @@ namespace Server.Engines.MLQuests.Gumps } } - public static void Initialize() + public static unsafe void Initialize() { m_Pending = new Dictionary(); - IncomingExtendedCommandPackets.RegisterExtended(0x2A, true, RaceChangeReply); + IncomingExtendedCommandPackets.RegisterExtended(0x2A, true, &RaceChangeReply); } public static bool IsPending(NetState state) => state != null && m_Pending.ContainsKey(state); diff --git a/Projects/UOContent/Engines/UltimaStore/UltimaStorePackets.cs b/Projects/UOContent/Engines/UltimaStore/UltimaStorePackets.cs index 24a3ba797..bb4b1698b 100644 --- a/Projects/UOContent/Engines/UltimaStore/UltimaStorePackets.cs +++ b/Projects/UOContent/Engines/UltimaStore/UltimaStorePackets.cs @@ -4,9 +4,9 @@ namespace Server.Engines.UltimaStore { public static class UltimaStorePackets { - public static void Configure() + public static unsafe void Configure() { - IncomingPackets.Register(0xFA, 1, true, UltimaStoreOpenRequest); + IncomingPackets.Register(0xFA, 1, true, &UltimaStoreOpenRequest); } public static void UltimaStoreOpenRequest(NetState state, CircularBufferReader reader, int packetLength) diff --git a/Projects/UOContent/Items/Books/BookPackets.cs b/Projects/UOContent/Items/Books/BookPackets.cs index 5eb43d5a1..8e9c6d257 100644 --- a/Projects/UOContent/Items/Books/BookPackets.cs +++ b/Projects/UOContent/Items/Books/BookPackets.cs @@ -22,11 +22,11 @@ namespace Server.Items { public static class BookPackets { - public static void Configure() + public static unsafe void Configure() { - IncomingPackets.Register(0xD4, 0, true, HeaderChange); - IncomingPackets.Register(0x66, 0, true, ContentChange); - IncomingPackets.Register(0x93, 99, true, OldHeaderChange); + IncomingPackets.Register(0xD4, 0, true, &HeaderChange); + IncomingPackets.Register(0x66, 0, true, &ContentChange); + IncomingPackets.Register(0x93, 99, true, &OldHeaderChange); } public static void OldHeaderChange(NetState state, CircularBufferReader reader, int packetLength) diff --git a/Projects/UOContent/Items/Bulletin Boards/BulletinBoardPackets.cs b/Projects/UOContent/Items/Bulletin Boards/BulletinBoardPackets.cs index 2cca09634..53086b70f 100644 --- a/Projects/UOContent/Items/Bulletin Boards/BulletinBoardPackets.cs +++ b/Projects/UOContent/Items/Bulletin Boards/BulletinBoardPackets.cs @@ -24,9 +24,9 @@ namespace Server.Network { public static class BulletinBoardPackets { - public static void Configure() + public static unsafe void Configure() { - IncomingPackets.Register(0x71, 0, true, BBClientRequest); + IncomingPackets.Register(0x71, 0, true, &BBClientRequest); } public static string FormatTS(TimeSpan ts) diff --git a/Projects/UOContent/Items/Games/Mahjong/MahjongPackets.cs b/Projects/UOContent/Items/Games/Mahjong/MahjongPackets.cs index fa958623e..8d6dfe42e 100644 --- a/Projects/UOContent/Items/Games/Mahjong/MahjongPackets.cs +++ b/Projects/UOContent/Items/Games/Mahjong/MahjongPackets.cs @@ -43,9 +43,9 @@ namespace Server.Engines.Mahjong return null; } - public static void Configure() + public static unsafe void Configure() { - IncomingPackets.Register(0xDA, 0, true, OnPacket); + IncomingPackets.Register(0xDA, 0, true, &OnPacket); RegisterSubCommand(0x6, ExitGame); RegisterSubCommand(0xA, GivePoints); diff --git a/Projects/UOContent/Items/Maps/MapItemPackets.cs b/Projects/UOContent/Items/Maps/MapItemPackets.cs index c98e34812..935331792 100644 --- a/Projects/UOContent/Items/Maps/MapItemPackets.cs +++ b/Projects/UOContent/Items/Maps/MapItemPackets.cs @@ -20,9 +20,9 @@ namespace Server.Network { public static class MapItemPackets { - public static void Configure() + public static unsafe void Configure() { - IncomingPackets.Register(0x56, 11, true, OnMapCommand); + IncomingPackets.Register(0x56, 11, true, &OnMapCommand); } private static void OnMapCommand(NetState state, CircularBufferReader reader, int packetLength) diff --git a/Projects/UOContent/Misc/HardwareInfo.cs b/Projects/UOContent/Misc/HardwareInfo.cs index 20ef94ddc..eeaff8304 100644 --- a/Projects/UOContent/Misc/HardwareInfo.cs +++ b/Projects/UOContent/Misc/HardwareInfo.cs @@ -87,9 +87,9 @@ namespace Server [CommandProperty(AccessLevel.GameMaster)] public DateTime TimeReceived { get; private set; } - public static void Configure() + public static unsafe void Configure() { - IncomingPackets.Register(0xD9, 0x10C, false, OnReceive); + IncomingPackets.Register(0xD9, 0x10C, false, &OnReceive); CommandSystem.Register("HWInfo", AccessLevel.GameMaster, HWInfo_OnCommand); } diff --git a/Projects/UOContent/Misc/PacketThrottles.cs b/Projects/UOContent/Misc/PacketThrottles.cs index a49f62aca..33ef421c7 100644 --- a/Projects/UOContent/Misc/PacketThrottles.cs +++ b/Projects/UOContent/Misc/PacketThrottles.cs @@ -12,7 +12,7 @@ namespace Server.Network private static readonly int[] Delays = new int[0x100]; private const string ThrottlesConfiguration = "Configuration/throttles.json"; - public static void Initialize() + public static unsafe void Initialize() { CommandSystem.Register("GetThrottle", AccessLevel.Administrator, GetThrottle); CommandSystem.Register("SetThrottle", AccessLevel.Administrator, SetThrottle); @@ -47,7 +47,7 @@ namespace Server.Network { if (Delays[i] > 0) { - IncomingPackets.RegisterThrottler(i, Throttle); + IncomingPackets.RegisterThrottler(i, &Throttle); } } @@ -77,7 +77,7 @@ namespace Server.Network [Usage("SetThrottle ")] [Description("Sets a throttle for the given packet.")] - public static void SetThrottle(CommandEventArgs e) + public static unsafe void SetThrottle(CommandEventArgs e) { if (e.Length != 2) { @@ -104,7 +104,7 @@ namespace Server.Network if (oldDelay == 0 && delay > 0) { - IncomingPackets.RegisterThrottler(packetID, Throttle); + IncomingPackets.RegisterThrottler(packetID, &Throttle); } else if (oldDelay > 0 && delay == 0) { diff --git a/Projects/UOContent/Multis/Houses/HouseFoundation.cs b/Projects/UOContent/Multis/Houses/HouseFoundation.cs index 186952f38..a994c5e2b 100644 --- a/Projects/UOContent/Multis/Houses/HouseFoundation.cs +++ b/Projects/UOContent/Multis/Houses/HouseFoundation.cs @@ -972,9 +972,9 @@ namespace Server.Multis public bool IsHiddenToCustomizer(Item item) => item == Signpost || item == SignHanger || item == Sign || IsFixture(item); - public static void Initialize() + public static unsafe void Initialize() { - IncomingExtendedCommandPackets.RegisterExtended(0x1E, true, QueryDesignDetails); + IncomingExtendedCommandPackets.RegisterExtended(0x1E, true, &QueryDesignDetails); IncomingPackets.RegisterEncoded(0x02, true, Designer_Backup); IncomingPackets.RegisterEncoded(0x03, true, Designer_Restore); diff --git a/Projects/UOContent/Network/FreeshardProtocol.cs b/Projects/UOContent/Network/FreeshardProtocol.cs index 93b6a49b3..62efd6abd 100644 --- a/Projects/UOContent/Network/FreeshardProtocol.cs +++ b/Projects/UOContent/Network/FreeshardProtocol.cs @@ -22,10 +22,15 @@ namespace Server.Network [CallPriority(10)] public static void Configure() { - _handlers = ProtocolExtensions.Register(0xF1); + _handlers = ProtocolExtensions.Register(new FreeshardProtocolInfo()); } - public static void Register(int cmd, bool ingame, OnPacketReceive onReceive) => + public static unsafe void Register(int cmd, bool ingame, delegate* onReceive) => _handlers[cmd] = new PacketHandler(cmd, 0, ingame, onReceive); + + private struct FreeshardProtocolInfo : IProtocolExtensionsInfo + { + public int PacketId => 0xF1; + } } } diff --git a/Projects/UOContent/Network/MapUO.cs b/Projects/UOContent/Network/MapUO.cs index 92769f92b..11f7305ea 100644 --- a/Projects/UOContent/Network/MapUO.cs +++ b/Projects/UOContent/Network/MapUO.cs @@ -25,15 +25,15 @@ namespace Server.Network { private static PacketHandler[] _handlers; - public static void Configure() + public static unsafe void Configure() { - _handlers = ProtocolExtensions.Register(0xF0); + _handlers = ProtocolExtensions.Register(new MapUOProtocolInfo()); - Register(0x00, true, QueryPartyMemberLocations); - Register(0x01, true, QueryGuildMemberLocations); + Register(0x00, true, &QueryPartyMemberLocations); + Register(0x01, true, &QueryGuildMemberLocations); } - public static void Register(int cmd, bool ingame, OnPacketReceive onReceive) => + public static unsafe void Register(int cmd, bool ingame, delegate* onReceive) => _handlers[cmd] = new PacketHandler(cmd, 0, ingame, onReceive); public static void QueryGuildMemberLocations(NetState state, CircularBufferReader reader, int packetLength) @@ -160,5 +160,10 @@ namespace Server.Network writer.WritePacketLength(); ns.Send(writer.Span); } + + private struct MapUOProtocolInfo : IProtocolExtensionsInfo + { + public int PacketId => 0xF0; + } } } diff --git a/Projects/UOContent/Network/ProtocolExtensions.cs b/Projects/UOContent/Network/ProtocolExtensions.cs index e8a034b3e..6df2a6a8b 100644 --- a/Projects/UOContent/Network/ProtocolExtensions.cs +++ b/Projects/UOContent/Network/ProtocolExtensions.cs @@ -15,40 +15,48 @@ namespace Server.Network { - public static class ProtocolExtensions + public interface IProtocolExtensionsInfo { - public static PacketHandler[] Register(byte packetId) + public int PacketId { get; } + } + + public static class ProtocolExtensions where T : struct, IProtocolExtensionsInfo + { + private static readonly PacketHandler[] packetHandlers = new PacketHandler[0x100]; + private static int packetId; + + public static unsafe PacketHandler[] Register(T info) { - var packetHandlers = new PacketHandler[0x100]; + packetId = info.PacketId; + IncomingPackets.Register(packetId, 0, false, &DecodeBundledPacket); - void DecodeBundledPacket(NetState state, CircularBufferReader reader, int packetLength) + return packetHandlers; + } + + private static unsafe void DecodeBundledPacket(NetState state, CircularBufferReader reader, int packetLength) + { + int cmd = reader.ReadByte(); + + PacketHandler ph = packetHandlers[cmd]; + + if (ph == null) { - int cmd = reader.ReadByte(); - - PacketHandler ph = packetHandlers[cmd]; - - if (ph == null) - { - return; - } - - if (ph.Ingame && state.Mobile == null) - { - state.LogInfo($"Sent in-game packet (0x{packetId:X2}x{cmd:X2}) before having been attached to a mobile"); - state.Disconnect("Sent in-game packet before being attached to a mobile."); - } - else if (ph.Ingame && state.Mobile.Deleted) - { - state.Disconnect(string.Empty); - } - else - { - ph.OnReceive(state, reader, packetLength); - } + return; } - IncomingPackets.Register(packetId, 0, false, DecodeBundledPacket); - return packetHandlers; + if (ph.Ingame && state.Mobile == null) + { + state.LogInfo($"Sent in-game packet (0x{packetId:X2}x{cmd:X2}) before having been attached to a mobile"); + state.Disconnect("Sent in-game packet before being attached to a mobile."); + } + else if (ph.Ingame && state.Mobile.Deleted) + { + state.Disconnect(string.Empty); + } + else + { + ph.OnReceive(state, reader, packetLength); + } } } } diff --git a/Projects/UOContent/Network/UOGateway.cs b/Projects/UOContent/Network/UOGateway.cs index 3d9721f37..b3b3bdcc4 100644 --- a/Projects/UOContent/Network/UOGateway.cs +++ b/Projects/UOContent/Network/UOGateway.cs @@ -22,14 +22,14 @@ namespace Server.Network { public static class UOGateway { - public static void Configure() + public static unsafe void Configure() { var enabled = ServerConfiguration.GetOrUpdateSetting("uogateway.enabled", true); if (enabled) { - FreeshardProtocol.Register(0xFE, false, QueryCompactShardStats); - FreeshardProtocol.Register(0xFF, false, QueryExtendedShardStats); + FreeshardProtocol.Register(0xFE, false, &QueryCompactShardStats); + FreeshardProtocol.Register(0xFF, false, &QueryExtendedShardStats); } } diff --git a/Projects/UOContent/Skills/Tracking/Tracking.cs b/Projects/UOContent/Skills/Tracking/Tracking.cs index 4cd3f52ad..ad62def69 100644 --- a/Projects/UOContent/Skills/Tracking/Tracking.cs +++ b/Projects/UOContent/Skills/Tracking/Tracking.cs @@ -12,9 +12,9 @@ namespace Server.SkillHandlers { private static readonly Dictionary m_Table = new(); - public static void Configure() + public static unsafe void Configure() { - IncomingExtendedCommandPackets.RegisterExtended(0x07, true, QuestArrow); + IncomingExtendedCommandPackets.RegisterExtended(0x07, true, &QuestArrow); SkillInfo.Table[(int)SkillName.Tracking].Callback = OnUse; } From 057cf87e607baca4ec4446ceff97176a8370f911 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Wed, 15 Jun 2022 17:20:36 -0700 Subject: [PATCH 199/213] fix: Updates encoded packet handler to use function pointers (#1066) --- .../Server/Network/EncodedPacketHandler.cs | 44 ++++++++++------- Projects/Server/Network/EncodedReader.cs | 47 ++++++++++++------- .../Server/Network/Packets/IncomingPackets.cs | 4 +- .../Network/Packets/IncomingPlayerPackets.cs | 6 +-- .../Weapons/Abilities/WeaponAbilityPackets.cs | 6 +-- .../Multis/Houses/HouseFoundation.cs | 26 +++++----- 6 files changed, 79 insertions(+), 54 deletions(-) diff --git a/Projects/Server/Network/EncodedPacketHandler.cs b/Projects/Server/Network/EncodedPacketHandler.cs index 3b417f9f4..33499beaf 100644 --- a/Projects/Server/Network/EncodedPacketHandler.cs +++ b/Projects/Server/Network/EncodedPacketHandler.cs @@ -1,20 +1,32 @@ -namespace Server.Network +/************************************************************************* + * ModernUO * + * Copyright 2019-2022 - ModernUO Development Team * + * Email: hi@modernuo.com * + * File: EncodedPacketHandler.cs * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + +namespace Server.Network; + +public unsafe class EncodedPacketHandler { - public delegate void OnEncodedPacketReceive(NetState state, IEntity ent, EncodedReader reader); - - public class EncodedPacketHandler + public EncodedPacketHandler(int packetID, bool ingame, delegate* onReceive) { - public EncodedPacketHandler(int packetID, bool ingame, OnEncodedPacketReceive onReceive) - { - PacketID = packetID; - Ingame = ingame; - OnReceive = onReceive; - } - - public int PacketID { get; } - - public OnEncodedPacketReceive OnReceive { get; } - - public bool Ingame { get; } + PacketID = packetID; + Ingame = ingame; + OnReceive = onReceive; } + + public int PacketID { get; } + + public delegate* OnReceive { get; } + + public bool Ingame { get; } } diff --git a/Projects/Server/Network/EncodedReader.cs b/Projects/Server/Network/EncodedReader.cs index 9c2ecf5cb..c7b6ce7d0 100644 --- a/Projects/Server/Network/EncodedReader.cs +++ b/Projects/Server/Network/EncodedReader.cs @@ -1,26 +1,37 @@ -namespace Server.Network +/************************************************************************* + * ModernUO * + * Copyright 2019-2022 - ModernUO Development Team * + * Email: hi@modernuo.com * + * File: EncodedReader.cs * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + +namespace Server.Network; + +public ref struct EncodedReader { - public ref struct EncodedReader - { - private CircularBufferReader m_Reader; + private CircularBufferReader _reader; - public EncodedReader(CircularBufferReader reader) => m_Reader = reader; + public EncodedReader(CircularBufferReader reader) => _reader = reader; - public void Trace(NetState state) - { - m_Reader.Trace(state); - } + public void Trace(NetState state) => _reader.Trace(state); - public int ReadInt32() => m_Reader.ReadByte() != 0 ? 0 : m_Reader.ReadInt32(); + public int ReadInt32() => _reader.ReadByte() != 0 ? 0 : _reader.ReadInt32(); - public Point3D ReadPoint3D() => m_Reader.ReadByte() != 3 - ? Point3D.Zero - : new Point3D(m_Reader.ReadInt16(), m_Reader.ReadInt16(), m_Reader.ReadByte()); + public Point3D ReadPoint3D() => _reader.ReadByte() != 3 + ? Point3D.Zero + : new Point3D(_reader.ReadInt16(), _reader.ReadInt16(), _reader.ReadByte()); - public string ReadUnicodeStringSafe() => - m_Reader.ReadByte() != 2 ? string.Empty : m_Reader.ReadBigUniSafe(m_Reader.ReadUInt16()); + public string ReadUnicodeStringSafe() => + _reader.ReadByte() != 2 ? string.Empty : _reader.ReadBigUniSafe(_reader.ReadUInt16()); - public string ReadUnicodeString() => - m_Reader.ReadByte() != 2 ? string.Empty : m_Reader.ReadBigUni(m_Reader.ReadUInt16()); - } + public string ReadUnicodeString() => + _reader.ReadByte() != 2 ? string.Empty : _reader.ReadBigUni(_reader.ReadUInt16()); } diff --git a/Projects/Server/Network/Packets/IncomingPackets.cs b/Projects/Server/Network/Packets/IncomingPackets.cs index 23012d7ae..cb963dde5 100644 --- a/Projects/Server/Network/Packets/IncomingPackets.cs +++ b/Projects/Server/Network/Packets/IncomingPackets.cs @@ -35,7 +35,9 @@ public static class IncomingPackets public static PacketHandler GetHandler(int packetID) => Handlers[packetID]; - public static void RegisterEncoded(int packetID, bool ingame, OnEncodedPacketReceive onReceive) + public static unsafe void RegisterEncoded( + int packetID, bool ingame, delegate* onReceive + ) { if (packetID is >= 0 and < 0x100) { diff --git a/Projects/Server/Network/Packets/IncomingPlayerPackets.cs b/Projects/Server/Network/Packets/IncomingPlayerPackets.cs index e409e3edd..d49b3107c 100644 --- a/Projects/Server/Network/Packets/IncomingPlayerPackets.cs +++ b/Projects/Server/Network/Packets/IncomingPlayerPackets.cs @@ -48,8 +48,8 @@ public static class IncomingPlayerPackets IncomingPackets.Register(0xD7, 0, true, &EncodedCommand); IncomingPackets.Register(0xF4, 0, false, &CrashReport); - IncomingPackets.RegisterEncoded(0x28, true, GuildGumpRequest); - IncomingPackets.RegisterEncoded(0x32, true, QuestGumpRequest); + IncomingPackets.RegisterEncoded(0x28, true, &GuildGumpRequest); + IncomingPackets.RegisterEncoded(0x32, true, &QuestGumpRequest); } public static void DeathStatusResponse(NetState state, CircularBufferReader reader, int packetLength) @@ -593,7 +593,7 @@ public static class IncomingPlayerPackets EventSink.InvokeQuestGumpRequest(state.Mobile); } - public static void EncodedCommand(NetState state, CircularBufferReader reader, int packetLength) + public static unsafe void EncodedCommand(NetState state, CircularBufferReader reader, int packetLength) { var e = World.FindEntity((Serial)reader.ReadUInt32()); int packetId = reader.ReadUInt16(); diff --git a/Projects/UOContent/Items/Weapons/Abilities/WeaponAbilityPackets.cs b/Projects/UOContent/Items/Weapons/Abilities/WeaponAbilityPackets.cs index 744995544..78da5a8a4 100644 --- a/Projects/UOContent/Items/Weapons/Abilities/WeaponAbilityPackets.cs +++ b/Projects/UOContent/Items/Weapons/Abilities/WeaponAbilityPackets.cs @@ -6,12 +6,12 @@ namespace Server.Items { public static class WeaponAbilityPackets { - public static void Configure() + public static unsafe void Configure() { - IncomingPackets.RegisterEncoded(0x19, true, SetAbility); + IncomingPackets.RegisterEncoded(0x19, true, &SetAbility); } - public static void SetAbility(NetState state, IEntity e, EncodedReader reader) + public static unsafe void SetAbility(NetState state, IEntity e, EncodedReader reader) { var m = state.Mobile; var index = reader.ReadInt32(); diff --git a/Projects/UOContent/Multis/Houses/HouseFoundation.cs b/Projects/UOContent/Multis/Houses/HouseFoundation.cs index a994c5e2b..f8b114e5c 100644 --- a/Projects/UOContent/Multis/Houses/HouseFoundation.cs +++ b/Projects/UOContent/Multis/Houses/HouseFoundation.cs @@ -976,21 +976,21 @@ namespace Server.Multis { IncomingExtendedCommandPackets.RegisterExtended(0x1E, true, &QueryDesignDetails); - IncomingPackets.RegisterEncoded(0x02, true, Designer_Backup); - IncomingPackets.RegisterEncoded(0x03, true, Designer_Restore); - IncomingPackets.RegisterEncoded(0x04, true, Designer_Commit); - IncomingPackets.RegisterEncoded(0x05, true, Designer_Delete); - IncomingPackets.RegisterEncoded(0x06, true, Designer_Build); - IncomingPackets.RegisterEncoded(0x0C, true, Designer_Close); - IncomingPackets.RegisterEncoded(0x0D, true, Designer_Stairs); - IncomingPackets.RegisterEncoded(0x0E, true, Designer_Sync); - IncomingPackets.RegisterEncoded(0x10, true, Designer_Clear); - IncomingPackets.RegisterEncoded(0x12, true, Designer_Level); + IncomingPackets.RegisterEncoded(0x02, true, &Designer_Backup); + IncomingPackets.RegisterEncoded(0x03, true, &Designer_Restore); + IncomingPackets.RegisterEncoded(0x04, true, &Designer_Commit); + IncomingPackets.RegisterEncoded(0x05, true, &Designer_Delete); + IncomingPackets.RegisterEncoded(0x06, true, &Designer_Build); + IncomingPackets.RegisterEncoded(0x0C, true, &Designer_Close); + IncomingPackets.RegisterEncoded(0x0D, true, &Designer_Stairs); + IncomingPackets.RegisterEncoded(0x0E, true, &Designer_Sync); + IncomingPackets.RegisterEncoded(0x10, true, &Designer_Clear); + IncomingPackets.RegisterEncoded(0x12, true, &Designer_Level); - IncomingPackets.RegisterEncoded(0x13, true, Designer_Roof); // Samurai Empire roof - IncomingPackets.RegisterEncoded(0x14, true, Designer_RoofDelete); // Samurai Empire roof + IncomingPackets.RegisterEncoded(0x13, true, &Designer_Roof); // Samurai Empire roof + IncomingPackets.RegisterEncoded(0x14, true, &Designer_RoofDelete); // Samurai Empire roof - IncomingPackets.RegisterEncoded(0x1A, true, Designer_Revert); + IncomingPackets.RegisterEncoded(0x1A, true, &Designer_Revert); EventSink.Speech += EventSink_Speech; } From 4a057bf5acaf2451a0ea74749ad41543cf28edc1 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Wed, 15 Jun 2022 19:11:52 -0700 Subject: [PATCH 200/213] fix: Fixes poison charge OPL (#1068) --- Projects/UOContent/Items/Skill Items/Ninjitsu/Fukiya.cs | 2 +- Projects/UOContent/Items/Skill Items/Ninjitsu/FukiyaDarts.cs | 2 +- .../UOContent/Items/Skill Items/Ninjitsu/LeatherNinjaBelt.cs | 2 +- Projects/UOContent/Items/Skill Items/Ninjitsu/Shuriken.cs | 2 +- Projects/UOContent/Items/Weapons/BaseWeapon.cs | 4 ++-- Projects/UOContent/Mobiles/BaseCreature.cs | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Projects/UOContent/Items/Skill Items/Ninjitsu/Fukiya.cs b/Projects/UOContent/Items/Skill Items/Ninjitsu/Fukiya.cs index a565fce0b..73a46bebc 100644 --- a/Projects/UOContent/Items/Skill Items/Ninjitsu/Fukiya.cs +++ b/Projects/UOContent/Items/Skill Items/Ninjitsu/Fukiya.cs @@ -95,7 +95,7 @@ namespace Server.Items if (m_Poison != null && m_PoisonCharges > 0) { - list.Add(1062412 + m_Poison.Level, m_PoisonCharges.ToString()); + list.Add(1062412 + m_Poison.Level, m_PoisonCharges); } } diff --git a/Projects/UOContent/Items/Skill Items/Ninjitsu/FukiyaDarts.cs b/Projects/UOContent/Items/Skill Items/Ninjitsu/FukiyaDarts.cs index 429b1b5bc..e01b718f3 100644 --- a/Projects/UOContent/Items/Skill Items/Ninjitsu/FukiyaDarts.cs +++ b/Projects/UOContent/Items/Skill Items/Ninjitsu/FukiyaDarts.cs @@ -81,7 +81,7 @@ namespace Server.Items if (m_Poison != null && m_PoisonCharges > 0) { - list.Add(1062412 + m_Poison.Level, m_PoisonCharges.ToString()); + list.Add(1062412 + m_Poison.Level, m_PoisonCharges); } } diff --git a/Projects/UOContent/Items/Skill Items/Ninjitsu/LeatherNinjaBelt.cs b/Projects/UOContent/Items/Skill Items/Ninjitsu/LeatherNinjaBelt.cs index 61a2b45cb..acfebce0c 100644 --- a/Projects/UOContent/Items/Skill Items/Ninjitsu/LeatherNinjaBelt.cs +++ b/Projects/UOContent/Items/Skill Items/Ninjitsu/LeatherNinjaBelt.cs @@ -97,7 +97,7 @@ namespace Server.Items if (m_Poison != null && m_PoisonCharges > 0) { - list.Add(1062412 + m_Poison.Level, m_PoisonCharges.ToString()); + list.Add(1062412 + m_Poison.Level, m_PoisonCharges); } } diff --git a/Projects/UOContent/Items/Skill Items/Ninjitsu/Shuriken.cs b/Projects/UOContent/Items/Skill Items/Ninjitsu/Shuriken.cs index 9a033b1db..3dfd81b6e 100644 --- a/Projects/UOContent/Items/Skill Items/Ninjitsu/Shuriken.cs +++ b/Projects/UOContent/Items/Skill Items/Ninjitsu/Shuriken.cs @@ -82,7 +82,7 @@ namespace Server.Items if (m_Poison != null && m_PoisonCharges > 0) { - list.Add(1062412 + m_Poison.Level, m_PoisonCharges.ToString()); + list.Add(1062412 + m_Poison.Level, m_PoisonCharges); } } diff --git a/Projects/UOContent/Items/Weapons/BaseWeapon.cs b/Projects/UOContent/Items/Weapons/BaseWeapon.cs index 0ae416987..7f2a8296e 100644 --- a/Projects/UOContent/Items/Weapons/BaseWeapon.cs +++ b/Projects/UOContent/Items/Weapons/BaseWeapon.cs @@ -2865,7 +2865,7 @@ namespace Server.Items if (m_Poison != null && m_PoisonCharges > 0) { - list.Add(1062412 + m_Poison.Level, m_PoisonCharges.ToString()); + list.Add(1062412 + m_Poison.Level, m_PoisonCharges); } if (m_Slayer != SlayerName.None) @@ -3054,7 +3054,7 @@ namespace Server.Items if ((prop = WeaponAttributes.MageWeapon) != 0) { - list.Add(1060438, (30 - prop).ToString()); // mage weapon -~1_val~ skill + list.Add(1060438, 30 - prop); // mage weapon -~1_val~ skill } if ((prop = Attributes.BonusMana) != 0) diff --git a/Projects/UOContent/Mobiles/BaseCreature.cs b/Projects/UOContent/Mobiles/BaseCreature.cs index f0d7a5c77..d5127a6ab 100644 --- a/Projects/UOContent/Mobiles/BaseCreature.cs +++ b/Projects/UOContent/Mobiles/BaseCreature.cs @@ -2797,7 +2797,7 @@ namespace Server.Mobiles { if (DisplayWeight) { - list.Add(TotalWeight == 1 ? 1072788 : 1072789, TotalWeight.ToString()); // Weight: ~1_WEIGHT~ stones + list.Add(TotalWeight == 1 ? 1072788 : 1072789, TotalWeight); // Weight: ~1_WEIGHT~ stones } if (m_ControlOrder == OrderType.Guard) From 2fb660040bb7e5619fee4bab1085610c765f8b62 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Wed, 15 Jun 2022 19:52:23 -0700 Subject: [PATCH 201/213] fix: Cleans up namespaces (#1069) --- Projects/Server/Buffers/SpanWriter.cs | 2 -- Projects/Server/Localization/LocalizationEntry.cs | 1 - Projects/Server/Regions/RegionLoader.cs | 1 - Projects/UOContent/Engines/Plants/PlantItem.cs | 1 - Projects/UOContent/Items/Deeds/CommodityDeed.cs | 1 - Projects/UOContent/Mobiles/AI/BaseAI.cs | 1 - Projects/UOContent/Mobiles/PlayerMobile.cs | 1 - 7 files changed, 8 deletions(-) diff --git a/Projects/Server/Buffers/SpanWriter.cs b/Projects/Server/Buffers/SpanWriter.cs index aaf7b17f3..937db1c3e 100644 --- a/Projects/Server/Buffers/SpanWriter.cs +++ b/Projects/Server/Buffers/SpanWriter.cs @@ -14,9 +14,7 @@ *************************************************************************/ using System.Buffers.Binary; -using System.Data; using System.Diagnostics; -using System.Globalization; using System.IO; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/Projects/Server/Localization/LocalizationEntry.cs b/Projects/Server/Localization/LocalizationEntry.cs index a2efd2236..ae4747569 100644 --- a/Projects/Server/Localization/LocalizationEntry.cs +++ b/Projects/Server/Localization/LocalizationEntry.cs @@ -14,7 +14,6 @@ *************************************************************************/ using System; -using System.Buffers; using System.Runtime.CompilerServices; using System.Text.RegularExpressions; using Server.Buffers; diff --git a/Projects/Server/Regions/RegionLoader.cs b/Projects/Server/Regions/RegionLoader.cs index 8570cb276..15fe2a9b1 100644 --- a/Projects/Server/Regions/RegionLoader.cs +++ b/Projects/Server/Regions/RegionLoader.cs @@ -13,7 +13,6 @@ * along with this program. If not, see . * *************************************************************************/ -using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; diff --git a/Projects/UOContent/Engines/Plants/PlantItem.cs b/Projects/UOContent/Engines/Plants/PlantItem.cs index ef1bcdcb1..21aaabc1a 100644 --- a/Projects/UOContent/Engines/Plants/PlantItem.cs +++ b/Projects/UOContent/Engines/Plants/PlantItem.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using Server.ContextMenus; using Server.Gumps; diff --git a/Projects/UOContent/Items/Deeds/CommodityDeed.cs b/Projects/UOContent/Items/Deeds/CommodityDeed.cs index f72b771f1..459a45b93 100644 --- a/Projects/UOContent/Items/Deeds/CommodityDeed.cs +++ b/Projects/UOContent/Items/Deeds/CommodityDeed.cs @@ -1,6 +1,5 @@ using ModernUO.Serialization; using Server.Targeting; -using Server.Text; namespace Server.Items; diff --git a/Projects/UOContent/Mobiles/AI/BaseAI.cs b/Projects/UOContent/Mobiles/AI/BaseAI.cs index d5a5b5466..d6d735d57 100644 --- a/Projects/UOContent/Mobiles/AI/BaseAI.cs +++ b/Projects/UOContent/Mobiles/AI/BaseAI.cs @@ -7,7 +7,6 @@ using Server.Engines.Spawners; using Server.Factions; using Server.Gumps; using Server.Items; -using Server.Logging; using Server.Network; using Server.Spells; using Server.Spells.Spellweaving; diff --git a/Projects/UOContent/Mobiles/PlayerMobile.cs b/Projects/UOContent/Mobiles/PlayerMobile.cs index f5a01f8ab..9db9e7d14 100644 --- a/Projects/UOContent/Mobiles/PlayerMobile.cs +++ b/Projects/UOContent/Mobiles/PlayerMobile.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Runtime.CompilerServices; using Server.Accounting; using Server.ContextMenus; using Server.Engines.BulkOrders; From 800f8643350a28f945697b209b2be0e6432b786d Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Thu, 16 Jun 2022 09:31:09 -0700 Subject: [PATCH 202/213] fix: Updates serialization generator to fix crashing from duplicate fields (#1071) --- .config/dotnet-tools.json | 2 +- Projects/Server/Server.csproj | 2 +- Projects/UOContent/UOContent.csproj | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index daaf31f85..fbd46b62c 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "modernuoschemagenerator": { - "version": "2.1.0", + "version": "2.1.1", "commands": [ "ModernUOSchemaGenerator" ] diff --git a/Projects/Server/Server.csproj b/Projects/Server/Server.csproj index a90755287..bde115202 100755 --- a/Projects/Server/Server.csproj +++ b/Projects/Server/Server.csproj @@ -41,7 +41,7 @@ - + diff --git a/Projects/UOContent/UOContent.csproj b/Projects/UOContent/UOContent.csproj index 40165f53b..3e1296051 100755 --- a/Projects/UOContent/UOContent.csproj +++ b/Projects/UOContent/UOContent.csproj @@ -46,7 +46,7 @@ - + From 6edccfe2aa04d90352c1c0913c1bcd47157babbd Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Thu, 16 Jun 2022 10:19:49 -0700 Subject: [PATCH 203/213] fix: Codegens mahjong (#1070) --- .../Games/Mahjong/MahjongDealerIndicator.cs | 113 +-- .../Items/Games/Mahjong/MahjongDices.cs | 77 +- .../Items/Games/Mahjong/MahjongEnums.cs | 107 +- .../Items/Games/Mahjong/MahjongGame.cs | 583 ++++++----- .../Items/Games/Mahjong/MahjongPieceDim.cs | 75 +- .../Items/Games/Mahjong/MahjongPlayers.cs | 931 +++++++++--------- .../Items/Games/Mahjong/MahjongTile.cs | 163 ++- .../Games/Mahjong/MahjongTileTypeGenerator.cs | 43 +- .../Mahjong/MahjongWallBreakIndicator.cs | 72 +- ...nes.Mahjong.MahjongDealerIndicator.v1.json | 24 + ...erver.Engines.Mahjong.MahjongDices.v0.json | 22 + ...Server.Engines.Mahjong.MahjongGame.v1.json | 69 ++ ...ver.Engines.Mahjong.MahjongPlayers.v1.json | 53 + ...Server.Engines.Mahjong.MahjongTile.v1.json | 48 + ....Mahjong.MahjongWallBreakIndicator.v0.json | 14 + 15 files changed, 1272 insertions(+), 1122 deletions(-) create mode 100644 Projects/UOContent/Migrations/Server.Engines.Mahjong.MahjongDealerIndicator.v1.json create mode 100644 Projects/UOContent/Migrations/Server.Engines.Mahjong.MahjongDices.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Engines.Mahjong.MahjongGame.v1.json create mode 100644 Projects/UOContent/Migrations/Server.Engines.Mahjong.MahjongPlayers.v1.json create mode 100644 Projects/UOContent/Migrations/Server.Engines.Mahjong.MahjongTile.v1.json create mode 100644 Projects/UOContent/Migrations/Server.Engines.Mahjong.MahjongWallBreakIndicator.v0.json diff --git a/Projects/UOContent/Items/Games/Mahjong/MahjongDealerIndicator.cs b/Projects/UOContent/Items/Games/Mahjong/MahjongDealerIndicator.cs index 2d9d694be..3b2309e83 100644 --- a/Projects/UOContent/Items/Games/Mahjong/MahjongDealerIndicator.cs +++ b/Projects/UOContent/Items/Games/Mahjong/MahjongDealerIndicator.cs @@ -1,69 +1,62 @@ -namespace Server.Engines.Mahjong +using ModernUO.Serialization; + +namespace Server.Engines.Mahjong; + +[SerializationGenerator(1, false)] +public partial class MahjongDealerIndicator { - public class MahjongDealerIndicator + [DirtyTrackingEntity] + private readonly MahjongGame _game; + + [SerializableField(0, setter: "private")] + private Point2D _position; + + [SerializableField(1, setter: "private")] + private MahjongPieceDirection _direction; + + [SerializableField(2, setter: "private")] + private MahjongWind _wind; + + public MahjongDealerIndicator(MahjongGame game) { - public MahjongDealerIndicator(MahjongGame game, Point2D position, MahjongPieceDirection direction, MahjongWind wind) + _game = game; + } + + public MahjongDealerIndicator(MahjongGame game, Point2D position, MahjongPieceDirection direction, MahjongWind wind) + { + _game = game; + _position = position; + _direction = direction; + _wind = wind; + } + + public MahjongPieceDim Dimensions => GetDimensions(_position, _direction); + + public static MahjongPieceDim GetDimensions(Point2D position, MahjongPieceDirection direction) => + direction is MahjongPieceDirection.Up or MahjongPieceDirection.Down + ? new MahjongPieceDim(position, 40, 20) + : new MahjongPieceDim(position, 20, 40); + + public void Move(Point2D position, MahjongPieceDirection direction, MahjongWind wind) + { + var dim = GetDimensions(position, direction); + + if (!dim.IsValid()) { - Game = game; - Position = position; - Direction = direction; - Wind = wind; + return; } - public MahjongDealerIndicator(MahjongGame game, IGenericReader reader) - { - Game = game; + _position = position; + _direction = direction; + _wind = wind; - var version = reader.ReadInt(); + _game.Players.SendGeneralPacket(true, true); + } - Position = reader.ReadPoint2D(); - Direction = (MahjongPieceDirection)reader.ReadInt(); - Wind = (MahjongWind)reader.ReadInt(); - } - - public MahjongGame Game { get; } - - public Point2D Position { get; private set; } - - public MahjongPieceDirection Direction { get; private set; } - - public MahjongWind Wind { get; private set; } - - public MahjongPieceDim Dimensions => GetDimensions(Position, Direction); - - public static MahjongPieceDim GetDimensions(Point2D position, MahjongPieceDirection direction) - { - if (direction is MahjongPieceDirection.Up or MahjongPieceDirection.Down) - { - return new MahjongPieceDim(position, 40, 20); - } - - return new MahjongPieceDim(position, 20, 40); - } - - public void Move(Point2D position, MahjongPieceDirection direction, MahjongWind wind) - { - var dim = GetDimensions(position, direction); - - if (!dim.IsValid()) - { - return; - } - - Position = position; - Direction = direction; - Wind = wind; - - Game.Players.SendGeneralPacket(true, true); - } - - public void Save(IGenericWriter writer) - { - writer.Write(0); // version - - writer.Write(Position); - writer.Write((int)Direction); - writer.Write((int)Wind); - } + private void Deserialize(IGenericReader reader, int version) + { + _position = reader.ReadPoint2D(); + _direction = (MahjongPieceDirection)reader.ReadInt(); + _wind = (MahjongWind)reader.ReadInt(); } } diff --git a/Projects/UOContent/Items/Games/Mahjong/MahjongDices.cs b/Projects/UOContent/Items/Games/Mahjong/MahjongDices.cs index 41666961c..80ca47512 100644 --- a/Projects/UOContent/Items/Games/Mahjong/MahjongDices.cs +++ b/Projects/UOContent/Items/Games/Mahjong/MahjongDices.cs @@ -1,52 +1,37 @@ -namespace Server.Engines.Mahjong +using ModernUO.Serialization; + +namespace Server.Engines.Mahjong; + +[SerializationGenerator(0, false)] +public partial class MahjongDices { - public class MahjongDices + [DirtyTrackingEntity] + private readonly MahjongGame _game; + + [SerializableField(0, setter: "private")] + private int _first; + + [SerializableField(1, setter: "private")] + private int _second; + + public MahjongDices(MahjongGame game) { - public MahjongDices(MahjongGame game) + _game = game; + _first = Utility.Random(1, 6); + _second = Utility.Random(1, 6); + } + + public void RollDices(Mobile from) + { + _first = Utility.Random(1, 6); + _second = Utility.Random(1, 6); + + _game.Players.SendGeneralPacket(true, true); + + if (from != null) { - Game = game; - First = Utility.Random(1, 6); - Second = Utility.Random(1, 6); - } - - public MahjongDices(MahjongGame game, IGenericReader reader) - { - Game = game; - - var version = reader.ReadInt(); - - First = reader.ReadInt(); - Second = reader.ReadInt(); - } - - public MahjongGame Game { get; } - - public int First { get; private set; } - - public int Second { get; private set; } - - public void RollDices(Mobile from) - { - First = Utility.Random(1, 6); - Second = Utility.Random(1, 6); - - Game.Players.SendGeneralPacket(true, true); - - if (from != null) - { - Game.Players.SendLocalizedMessage( - 1062695, - $"{from.Name}\t{First}\t{Second}" - ); // ~1_name~ rolls the dice and gets a ~2_number~ and a ~3_number~! - } - } - - public void Save(IGenericWriter writer) - { - writer.Write(0); // version - - writer.Write(First); - writer.Write(Second); + // ~1_name~ rolls the dice and gets a ~2_number~ and a ~3_number~! + _game.Players.SendLocalizedMessage(1062695, $"{from.Name}\t{_first}\t{_second}"); } } } diff --git a/Projects/UOContent/Items/Games/Mahjong/MahjongEnums.cs b/Projects/UOContent/Items/Games/Mahjong/MahjongEnums.cs index 4dd79a98d..32d6b3ad6 100644 --- a/Projects/UOContent/Items/Games/Mahjong/MahjongEnums.cs +++ b/Projects/UOContent/Items/Games/Mahjong/MahjongEnums.cs @@ -1,56 +1,55 @@ -namespace Server.Engines.Mahjong +namespace Server.Engines.Mahjong; + +public enum MahjongPieceDirection { - public enum MahjongPieceDirection - { - Up, - Left, - Down, - Right - } - - public enum MahjongWind - { - North, - East, - South, - West - } - - public enum MahjongTileType - { - Dagger1 = 1, - Dagger2, - Dagger3, - Dagger4, - Dagger5, - Dagger6, - Dagger7, - Dagger8, - Dagger9, - Gem1, - Gem2, - Gem3, - Gem4, - Gem5, - Gem6, - Gem7, - Gem8, - Gem9, - Number1, - Number2, - Number3, - Number4, - Number5, - Number6, - Number7, - Number8, - Number9, - North, - East, - South, - West, - Green, - Red, - White - } + Up, + Left, + Down, + Right +} + +public enum MahjongWind +{ + North, + East, + South, + West +} + +public enum MahjongTileType +{ + Dagger1 = 1, + Dagger2, + Dagger3, + Dagger4, + Dagger5, + Dagger6, + Dagger7, + Dagger8, + Dagger9, + Gem1, + Gem2, + Gem3, + Gem4, + Gem5, + Gem6, + Gem7, + Gem8, + Gem9, + Number1, + Number2, + Number3, + Number4, + Number5, + Number6, + Number7, + Number8, + Number9, + North, + East, + South, + West, + Green, + Red, + White } diff --git a/Projects/UOContent/Items/Games/Mahjong/MahjongGame.cs b/Projects/UOContent/Items/Games/Mahjong/MahjongGame.cs index 4bd778ee2..827b135cf 100644 --- a/Projects/UOContent/Items/Games/Mahjong/MahjongGame.cs +++ b/Projects/UOContent/Items/Games/Mahjong/MahjongGame.cs @@ -1,347 +1,316 @@ using System; using System.Collections.Generic; +using ModernUO.Serialization; using Server.ContextMenus; using Server.Gumps; using Server.Multis; -namespace Server.Engines.Mahjong +namespace Server.Engines.Mahjong; + +[SerializationGenerator(1, false)] +public partial class MahjongGame : Item, ISecurable { - public class MahjongGame : Item, ISecurable + public const int MaxPlayers = 4; + public const int BaseScore = 30000; + + [SerializableField(0)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private SecureLevel _level; + + [SerializableField(1, setter: "private")] + private MahjongTile[] _tiles; + + [SerializableField(2, setter: "private")] + private MahjongDealerIndicator _dealerIndicator; + + [SerializableField(3, setter: "private")] + private MahjongWallBreakIndicator _wallBreakIndicator; + + [SerializableField(4, setter: "private")] + private MahjongDices _dices; + + [SerializableField(5, setter: "private")] + private MahjongPlayers _players; + + // Field 6 + private bool _showScores; + + // Field 7 + private bool _spectatorVision; + + private DateTime _lastReset; + + [Constructible] + public MahjongGame() : base(0xFAA) { - public const int MaxPlayers = 4; - public const int BaseScore = 30000; - private DateTime m_LastReset; + Weight = 5.0; - private bool m_ShowScores; - private bool m_SpectatorVision; + BuildWalls(); + _dealerIndicator = + new MahjongDealerIndicator(this, new Point2D(300, 300), MahjongPieceDirection.Up, MahjongWind.North); + _wallBreakIndicator = new MahjongWallBreakIndicator(this, new Point2D(335, 335)); + _dices = new MahjongDices(this); + _players = new MahjongPlayers(this, MaxPlayers, BaseScore); + _lastReset = Core.Now; + _level = SecureLevel.CoOwners; + } - [Constructible] - public MahjongGame() : base(0xFAA) + [CommandProperty(AccessLevel.GameMaster)] + [SerializableField(6)] + public bool ShowScores + { + get => _showScores; + set { - Weight = 5.0; - - BuildWalls(); - DealerIndicator = - new MahjongDealerIndicator(this, new Point2D(300, 300), MahjongPieceDirection.Up, MahjongWind.North); - WallBreakIndicator = new MahjongWallBreakIndicator(this, new Point2D(335, 335)); - Dices = new MahjongDices(this); - Players = new MahjongPlayers(this, MaxPlayers, BaseScore); - m_LastReset = Core.Now; - Level = SecureLevel.CoOwners; - } - - public MahjongGame(Serial serial) : base(serial) - { - } - - public MahjongTile[] Tiles { get; private set; } - - public MahjongDealerIndicator DealerIndicator { get; private set; } - - public MahjongWallBreakIndicator WallBreakIndicator { get; private set; } - - public MahjongDices Dices { get; private set; } - - public MahjongPlayers Players { get; private set; } - - [CommandProperty(AccessLevel.GameMaster)] - public bool ShowScores - { - get => m_ShowScores; - set - { - if (m_ShowScores == value) - { - return; - } - - m_ShowScores = value; - - if (value) - { - Players.SendPlayersPacket(true, true); - } - - Players.SendGeneralPacket(true, true); - - Players.SendLocalizedMessage(value ? 1062777 : 1062778); // The dealer has enabled/disabled score display. - } - } - - [CommandProperty(AccessLevel.GameMaster)] - public bool SpectatorVision - { - get => m_SpectatorVision; - set - { - if (m_SpectatorVision == value) - { - return; - } - - m_SpectatorVision = value; - - if (Players.IsInGamePlayer(Players.DealerPosition)) - { - Players.Dealer.NetState.SendMahjongGeneralInfo(this); - } - - Players.SendTilesPacket(false, true); - - Players.SendLocalizedMessage(value ? 1062715 : 1062716); // The dealer has enabled/disabled Spectator Vision. - - InvalidateProperties(); - } - } - - [CommandProperty(AccessLevel.GameMaster)] - public SecureLevel Level { get; set; } - - private void BuildHorizontalWall( - ref int index, int x, int y, int stackLevel, MahjongPieceDirection direction, - MahjongTileTypeGenerator typeGenerator - ) - { - for (var i = 0; i < 17; i++) - { - var position = new Point2D(x + i * 20, y); - Tiles[index + i] = new MahjongTile( - this, - index + i, - typeGenerator.Next(), - position, - stackLevel, - direction, - false - ); - } - - index += 17; - } - - private void BuildVerticalWall( - ref int index, int x, int y, int stackLevel, MahjongPieceDirection direction, - MahjongTileTypeGenerator typeGenerator - ) - { - for (var i = 0; i < 17; i++) - { - var position = new Point2D(x, y + i * 20); - Tiles[index + i] = new MahjongTile( - this, - index + i, - typeGenerator.Next(), - position, - stackLevel, - direction, - false - ); - } - - index += 17; - } - - private void BuildWalls() - { - Tiles = new MahjongTile[136]; - - var typeGenerator = new MahjongTileTypeGenerator(); - - var i = 0; - - BuildHorizontalWall(ref i, 165, 110, 0, MahjongPieceDirection.Up, typeGenerator); - BuildHorizontalWall(ref i, 165, 115, 1, MahjongPieceDirection.Up, typeGenerator); - - BuildVerticalWall(ref i, 530, 165, 0, MahjongPieceDirection.Left, typeGenerator); - BuildVerticalWall(ref i, 525, 165, 1, MahjongPieceDirection.Left, typeGenerator); - - BuildHorizontalWall(ref i, 165, 530, 0, MahjongPieceDirection.Down, typeGenerator); - BuildHorizontalWall(ref i, 165, 525, 1, MahjongPieceDirection.Down, typeGenerator); - - BuildVerticalWall(ref i, 110, 165, 0, MahjongPieceDirection.Right, typeGenerator); - BuildVerticalWall(ref i, 115, 165, 1, MahjongPieceDirection.Right, typeGenerator); - } - - public override void GetProperties(IPropertyList list) - { - base.GetProperties(list); - - if (m_SpectatorVision) - { - list.Add(1062717); // Spectator Vision Enabled - } - else - { - list.Add(1062718); // Spectator Vision Disabled - } - } - - public override void GetContextMenuEntries(Mobile from, List list) - { - base.GetContextMenuEntries(from, list); - - Players.CheckPlayers(); - - if (from.Alive && IsAccessibleTo(from) && Players.GetInGameMobiles(true, false).Count == 0) - { - list.Add(new ResetGameEntry(this)); - } - - SetSecureLevelEntry.AddTo(from, this, list); - } - - public override void OnDoubleClick(Mobile from) - { - Players.CheckPlayers(); - - Players.Join(from); - } - - public void ResetGame(Mobile from) - { - if (Core.Now - m_LastReset < TimeSpan.FromSeconds(5.0)) + if (_showScores == value) { return; } - m_LastReset = Core.Now; + _showScores = value; - if (from != null) + if (value) { - Players.SendLocalizedMessage(1062771, from.Name); // ~1_name~ has reset the game. + _players.SendPlayersPacket(true, true); } - Players.SendRelievePacket(true, true); - - BuildWalls(); - DealerIndicator = - new MahjongDealerIndicator(this, new Point2D(300, 300), MahjongPieceDirection.Up, MahjongWind.North); - WallBreakIndicator = new MahjongWallBreakIndicator(this, new Point2D(335, 335)); - Players = new MahjongPlayers(this, MaxPlayers, BaseScore); + _players.SendGeneralPacket(true, true); + _players.SendLocalizedMessage(value ? 1062777 : 1062778); // The dealer has enabled/disabled score display. + this.MarkDirty(); } + } - public void ResetWalls(Mobile from) + [CommandProperty(AccessLevel.GameMaster)] + [SerializableField(7)] + public bool SpectatorVision + { + get => _spectatorVision; + set { - if (Core.Now - m_LastReset < TimeSpan.FromSeconds(5.0)) + if (_spectatorVision == value) { return; } - m_LastReset = Core.Now; + _spectatorVision = value; - BuildWalls(); - - Players.SendTilesPacket(true, true); - - if (from != null) + if (_players.IsInGamePlayer(_players.DealerPosition)) { - Players.SendLocalizedMessage(1062696); // The dealer rebuilds the wall. + _players.Dealer.NetState.SendMahjongGeneralInfo(this); + } + + _players.SendTilesPacket(false, true); + _players.SendLocalizedMessage(value ? 1062715 : 1062716); // The dealer has enabled/disabled Spectator Vision. + InvalidateProperties(); + this.MarkDirty(); + } + } + + private void BuildHorizontalWall( + ref int index, int x, int y, int stackLevel, MahjongPieceDirection direction, + MahjongTileTypeGenerator typeGenerator + ) + { + for (var i = 0; i < 17; i++) + { + var position = new Point2D(x + i * 20, y); + Tiles[index + i] = new MahjongTile( + this, + index + i, + typeGenerator.Next(), + position, + stackLevel, + direction, + false + ); + } + + index += 17; + this.MarkDirty(); + } + + private void BuildVerticalWall( + ref int index, int x, int y, int stackLevel, MahjongPieceDirection direction, + MahjongTileTypeGenerator typeGenerator + ) + { + for (var i = 0; i < 17; i++) + { + var position = new Point2D(x, y + i * 20); + Tiles[index + i] = new MahjongTile( + this, + index + i, + typeGenerator.Next(), + position, + stackLevel, + direction, + false + ); + } + + index += 17; + this.MarkDirty(); + } + + private void BuildWalls() + { + Tiles = new MahjongTile[136]; + + var typeGenerator = new MahjongTileTypeGenerator(); + + var i = 0; + + BuildHorizontalWall(ref i, 165, 110, 0, MahjongPieceDirection.Up, typeGenerator); + BuildHorizontalWall(ref i, 165, 115, 1, MahjongPieceDirection.Up, typeGenerator); + + BuildVerticalWall(ref i, 530, 165, 0, MahjongPieceDirection.Left, typeGenerator); + BuildVerticalWall(ref i, 525, 165, 1, MahjongPieceDirection.Left, typeGenerator); + + BuildHorizontalWall(ref i, 165, 530, 0, MahjongPieceDirection.Down, typeGenerator); + BuildHorizontalWall(ref i, 165, 525, 1, MahjongPieceDirection.Down, typeGenerator); + + BuildVerticalWall(ref i, 110, 165, 0, MahjongPieceDirection.Right, typeGenerator); + BuildVerticalWall(ref i, 115, 165, 1, MahjongPieceDirection.Right, typeGenerator); + } + + public override void GetProperties(IPropertyList list) + { + base.GetProperties(list); + + if (_spectatorVision) + { + list.Add(1062717); // Spectator Vision Enabled + } + else + { + list.Add(1062718); // Spectator Vision Disabled + } + } + + public override void GetContextMenuEntries(Mobile from, List list) + { + base.GetContextMenuEntries(from, list); + + _players.CheckPlayers(); + + if (from.Alive && IsAccessibleTo(from) && _players.GetInGameMobiles(true, false).Count == 0) + { + list.Add(new ResetGameEntry(this)); + } + + SetSecureLevelEntry.AddTo(from, this, list); + } + + public override void OnDoubleClick(Mobile from) + { + _players.CheckPlayers(); + _players.Join(from); + } + + public void ResetGame(Mobile from) + { + if (Core.Now - _lastReset < TimeSpan.FromSeconds(5.0)) + { + return; + } + + _lastReset = Core.Now; + + if (from != null) + { + _players.SendLocalizedMessage(1062771, from.Name); // ~1_name~ has reset the game. + } + + _players.SendRelievePacket(true, true); + + BuildWalls(); + DealerIndicator = + new MahjongDealerIndicator(this, new Point2D(300, 300), MahjongPieceDirection.Up, MahjongWind.North); + WallBreakIndicator = new MahjongWallBreakIndicator(this, new Point2D(335, 335)); + Players = new MahjongPlayers(this, MaxPlayers, BaseScore); + } + + public void ResetWalls(Mobile from) + { + if (Core.Now - _lastReset < TimeSpan.FromSeconds(5.0)) + { + return; + } + + _lastReset = Core.Now; + + BuildWalls(); + + _players.SendTilesPacket(true, true); + + if (from != null) + { + _players.SendLocalizedMessage(1062696); // The dealer rebuilds the wall. + } + } + + public int GetStackLevel(MahjongPieceDim dim) + { + var level = -1; + foreach (var tile in _tiles) + { + if (tile.StackLevel > level && dim.IsOverlapping(tile.Dimensions)) + { + level = tile.StackLevel; } } - public int GetStackLevel(MahjongPieceDim dim) - { - var level = -1; - foreach (var tile in Tiles) - { - if (tile.StackLevel > level && dim.IsOverlapping(tile.Dimensions)) - { - level = tile.StackLevel; - } - } + return level; + } - return level; + private void Deserialize(IGenericReader reader, int number) + { + _level = (SecureLevel)reader.ReadInt(); + var length = reader.ReadInt(); + _tiles = new MahjongTile[length]; + + for (var i = 0; i < length; i++) + { + var tile = _tiles[i] = new MahjongTile(this); + tile.Deserialize(reader); } - public override void Serialize(IGenericWriter writer) + _dealerIndicator = new MahjongDealerIndicator(this); + _dealerIndicator.Deserialize(reader); + + _wallBreakIndicator = new MahjongWallBreakIndicator(this); + _wallBreakIndicator.Deserialize(reader); + + _dices = new MahjongDices(this); + _dices.Deserialize(reader); + + _players = new MahjongPlayers(this); + _players.Deserialize(reader); + + _showScores = reader.ReadBool(); + _spectatorVision = reader.ReadBool(); + } + + [AfterDeserialization] + private void AfterDeserialization() + { + _lastReset = Core.Now; + } + + private class ResetGameEntry : ContextMenuEntry + { + private readonly MahjongGame _game; + + public ResetGameEntry(MahjongGame game) : base(6162) => _game = game; + + public override void OnClick() { - base.Serialize(writer); + var from = Owner.From; - writer.Write(1); // version - - writer.Write((int)Level); - - writer.Write(Tiles.Length); - - for (var i = 0; i < Tiles.Length; i++) + if (from.CheckAlive() && !_game.Deleted && _game.IsAccessibleTo(from) && + _game.Players.GetInGameMobiles(true, false).Count == 0) { - Tiles[i].Save(writer); - } - - DealerIndicator.Save(writer); - - WallBreakIndicator.Save(writer); - - Dices.Save(writer); - - Players.Save(writer); - - writer.Write(m_ShowScores); - writer.Write(m_SpectatorVision); - } - - 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.CoOwners; - } - - var length = reader.ReadInt(); - Tiles = new MahjongTile[length]; - - for (var i = 0; i < length; i++) - { - Tiles[i] = new MahjongTile(this, reader); - } - - DealerIndicator = new MahjongDealerIndicator(this, reader); - - WallBreakIndicator = new MahjongWallBreakIndicator(this, reader); - - Dices = new MahjongDices(this, reader); - - Players = new MahjongPlayers(this, reader); - - m_ShowScores = reader.ReadBool(); - m_SpectatorVision = reader.ReadBool(); - - m_LastReset = Core.Now; - - break; - } - } - } - - private class ResetGameEntry : ContextMenuEntry - { - private readonly MahjongGame m_Game; - - public ResetGameEntry(MahjongGame game) : base(6162) => m_Game = game; - - public override void OnClick() - { - var from = Owner.From; - - if (from.CheckAlive() && !m_Game.Deleted && m_Game.IsAccessibleTo(from) && - m_Game.Players.GetInGameMobiles(true, false).Count == 0) - { - m_Game.ResetGame(from); - } + _game.ResetGame(from); } } } diff --git a/Projects/UOContent/Items/Games/Mahjong/MahjongPieceDim.cs b/Projects/UOContent/Items/Games/Mahjong/MahjongPieceDim.cs index 932f941b3..d93df6372 100644 --- a/Projects/UOContent/Items/Games/Mahjong/MahjongPieceDim.cs +++ b/Projects/UOContent/Items/Games/Mahjong/MahjongPieceDim.cs @@ -1,50 +1,49 @@ -namespace Server.Engines.Mahjong +namespace Server.Engines.Mahjong; + +public struct MahjongPieceDim { - public struct MahjongPieceDim + public Point2D Position { get; } + + public int Width { get; } + + public int Height { get; } + + public MahjongPieceDim(Point2D position, int width, int height) { - public Point2D Position { get; } + Position = position; + Width = width; + Height = height; + } - public int Width { get; } + public bool IsValid() => + Position.X >= 0 && Position.Y >= 0 && Position.X + Width <= 670 && Position.Y + Height <= 670; - public int Height { get; } + public bool IsOverlapping(MahjongPieceDim dim) => + Position.X < dim.Position.X + dim.Width && Position.Y < dim.Position.Y + dim.Height && + Position.X + Width > dim.Position.X && Position.Y + Height > dim.Position.Y; - public MahjongPieceDim(Point2D position, int width, int height) + public int GetHandArea() + { + if (Position.X + Width > 150 && Position.X < 520 && Position.Y < 35) { - Position = position; - Width = width; - Height = height; + return 0; } - public bool IsValid() => - Position.X >= 0 && Position.Y >= 0 && Position.X + Width <= 670 && Position.Y + Height <= 670; - - public bool IsOverlapping(MahjongPieceDim dim) => - Position.X < dim.Position.X + dim.Width && Position.Y < dim.Position.Y + dim.Height && - Position.X + Width > dim.Position.X && Position.Y + Height > dim.Position.Y; - - public int GetHandArea() + if (Position.X + Width > 635 && Position.Y + Height > 150 && Position.Y < 520) { - if (Position.X + Width > 150 && Position.X < 520 && Position.Y < 35) - { - return 0; - } - - if (Position.X + Width > 635 && Position.Y + Height > 150 && Position.Y < 520) - { - return 1; - } - - if (Position.X + Width > 150 && Position.X < 520 && Position.Y + Height > 635) - { - return 2; - } - - if (Position.X < 35 && Position.Y + Height > 150 && Position.Y < 520) - { - return 3; - } - - return -1; + return 1; } + + if (Position.X + Width > 150 && Position.X < 520 && Position.Y + Height > 635) + { + return 2; + } + + if (Position.X < 35 && Position.Y + Height > 150 && Position.Y < 520) + { + return 3; + } + + return -1; } } diff --git a/Projects/UOContent/Items/Games/Mahjong/MahjongPlayers.cs b/Projects/UOContent/Items/Games/Mahjong/MahjongPlayers.cs index 898b64009..2627ec27e 100644 --- a/Projects/UOContent/Items/Games/Mahjong/MahjongPlayers.cs +++ b/Projects/UOContent/Items/Games/Mahjong/MahjongPlayers.cs @@ -1,607 +1,604 @@ using System; using System.Collections.Generic; +using ModernUO.Serialization; using Server.Network; -namespace Server.Engines.Mahjong +namespace Server.Engines.Mahjong; + +[SerializationGenerator(1, false)] +public partial class MahjongPlayers { - public class MahjongPlayers + [SerializableField(0, setter: "private")] + private Mobile[] _players; + + [SerializableField(1, setter: "private")] + private bool[] _inGame; + + [SerializableField(2, setter: "private")] + private bool[] _publicHand; + + [SerializableField(3, setter: "private")] + private int[] _scores; + + [SerializableField(4, setter: "private")] + private int _dealerPosition; + + private List _spectators; + + [DirtyTrackingEntity] + private readonly MahjongGame _game; + + public MahjongPlayers(MahjongGame game, int maxPlayers, int baseScore) { - private readonly bool[] m_InGame; - private readonly Mobile[] m_Players; - private readonly bool[] m_PublicHand; - private readonly int[] m_Scores; - private readonly List m_Spectators; + _game = game; + _spectators = new List(); - public MahjongPlayers(MahjongGame game, int maxPlayers, int baseScore) + _players = new Mobile[maxPlayers]; + _inGame = new bool[maxPlayers]; + _publicHand = new bool[maxPlayers]; + _scores = new int[maxPlayers]; + + for (var i = 0; i < _scores.Length; i++) { - Game = game; - m_Spectators = new List(); + _scores[i] = baseScore; + } + } - m_Players = new Mobile[maxPlayers]; - m_InGame = new bool[maxPlayers]; - m_PublicHand = new bool[maxPlayers]; - m_Scores = new int[maxPlayers]; + public MahjongPlayers(MahjongGame game) + { + _game = game; + _spectators = new List(); + } - for (var i = 0; i < m_Scores.Length; i++) + private void Deserialize(IGenericReader reader, int version) + { + var seats = reader.ReadInt(); + _players = new Mobile[seats]; + _inGame = new bool[seats]; + _publicHand = new bool[seats]; + _scores = new int[seats]; + + for (var i = 0; i < seats; i++) + { + _players[i] = reader.ReadEntity(); + _publicHand[i] = reader.ReadBool(); + _scores[i] = reader.ReadInt(); + } + + _dealerPosition = reader.ReadInt(); + } + + public int Seats => _players.Length; + public Mobile Dealer => _players[DealerPosition]; + + public Mobile GetPlayer(int index) + { + if (index < 0 || index >= _players.Length) + { + return null; + } + + return _players[index]; + } + + public int GetPlayerIndex(Mobile mobile) + { + for (var i = 0; i < _players.Length; i++) + { + if (_players[i] == mobile) { - m_Scores[i] = baseScore; + return i; } } - public MahjongPlayers(MahjongGame game, IGenericReader reader) + return -1; + } + + public bool IsInGameDealer(Mobile mobile) + { + if (Dealer != mobile) { - Game = game; - m_Spectators = new List(); - - var version = reader.ReadInt(); - - var seats = reader.ReadInt(); - m_Players = new Mobile[seats]; - m_InGame = new bool[seats]; - m_PublicHand = new bool[seats]; - m_Scores = new int[seats]; - - for (var i = 0; i < seats; i++) - { - m_Players[i] = reader.ReadEntity(); - m_PublicHand[i] = reader.ReadBool(); - m_Scores[i] = reader.ReadInt(); - } - - DealerPosition = reader.ReadInt(); + return false; } - public MahjongGame Game { get; } + return _inGame[DealerPosition]; + } - public int Seats => m_Players.Length; - public Mobile Dealer => m_Players[DealerPosition]; - public int DealerPosition { get; private set; } - - public Mobile GetPlayer(int index) + public bool IsInGamePlayer(int index) + { + if (index < 0 || index >= _players.Length || _players[index] == null) { - if (index < 0 || index >= m_Players.Length) - { - return null; - } - - return m_Players[index]; + return false; } - public int GetPlayerIndex(Mobile mobile) + return _inGame[index]; + } + + public bool IsInGamePlayer(Mobile mobile) + { + var index = GetPlayerIndex(mobile); + + return IsInGamePlayer(index); + } + + public bool IsSpectator(Mobile mobile) => _spectators.Contains(mobile); + + public int GetScore(int index) + { + if (index < 0 || index >= _scores.Length) { - for (var i = 0; i < m_Players.Length; i++) + return 0; + } + + return _scores[index]; + } + + public bool IsPublic(int index) + { + if (index < 0 || index >= _publicHand.Length) + { + return false; + } + + return _publicHand[index]; + } + + public void SetPublic(int index, bool value) + { + if (index < 0 || index >= _publicHand.Length || _publicHand[index] == value) + { + return; + } + + _publicHand[index] = value; + + SendTilesPacket(true, !_game.SpectatorVision); + + if (IsInGamePlayer(index)) + { + _players[index].SendLocalizedMessage(value ? 1062775 : 1062776); // Your hand is [not] publicly viewable. + } + } + + public List GetInGameMobiles(bool players, bool spectators) + { + var list = new List(); + + if (players) + { + for (var i = 0; i < _players.Length; i++) { - if (m_Players[i] == mobile) + if (IsInGamePlayer(i)) { - return i; + list.Add(_players[i]); } } - - return -1; } - public bool IsInGameDealer(Mobile mobile) + if (spectators) { - if (Dealer != mobile) + list.AddRange(_spectators); + } + + return list; + } + + public void CheckPlayers() + { + var removed = false; + + Span relievePacket = stackalloc byte[MahjongPackets.MahjongRelievePacketLength].InitializePacket(); + + for (var i = 0; i < _players.Length; i++) + { + var player = _players[i]; + + if (player == null) { - return false; + continue; } - return m_InGame[DealerPosition]; - } - - public bool IsInGamePlayer(int index) - { - if (index < 0 || index >= m_Players.Length || m_Players[index] == null) + if (player.Deleted) { - return false; + _players[i] = null; + + SendPlayerExitMessage(player); + UpdateDealer(true); + + removed = true; } - - return m_InGame[index]; - } - - public bool IsInGamePlayer(Mobile mobile) - { - var index = GetPlayerIndex(mobile); - - return IsInGamePlayer(index); - } - - public bool IsSpectator(Mobile mobile) => m_Spectators.Contains(mobile); - - public int GetScore(int index) - { - if (index < 0 || index >= m_Scores.Length) + else if (_inGame[i]) { - return 0; - } - - return m_Scores[index]; - } - - public bool IsPublic(int index) - { - if (index < 0 || index >= m_PublicHand.Length) - { - return false; - } - - return m_PublicHand[index]; - } - - public void SetPublic(int index, bool value) - { - if (index < 0 || index >= m_PublicHand.Length || m_PublicHand[index] == value) - { - return; - } - - m_PublicHand[index] = value; - - SendTilesPacket(true, !Game.SpectatorVision); - - if (IsInGamePlayer(index)) - { - m_Players[index].SendLocalizedMessage(value ? 1062775 : 1062776); // Your hand is [not] publicly viewable. - } - } - - public List GetInGameMobiles(bool players, bool spectators) - { - var list = new List(); - - if (players) - { - for (var i = 0; i < m_Players.Length; i++) + if (player.NetState == null) { - if (IsInGamePlayer(i)) - { - list.Add(m_Players[i]); - } - } - } - - if (spectators) - { - list.AddRange(m_Spectators); - } - - return list; - } - - public void CheckPlayers() - { - var removed = false; - - Span relievePacket = stackalloc byte[MahjongPackets.MahjongRelievePacketLength].InitializePacket(); - - for (var i = 0; i < m_Players.Length; i++) - { - var player = m_Players[i]; - - if (player == null) - { - continue; - } - - if (player.Deleted) - { - m_Players[i] = null; + _inGame[i] = false; SendPlayerExitMessage(player); UpdateDealer(true); removed = true; } - else if (m_InGame[i]) + else if (!_game.IsAccessibleTo(player) || player.Map != _game.Map || + !player.InRange(_game.GetWorldLocation(), 5)) { - if (player.NetState == null) - { - m_InGame[i] = false; + _inGame[i] = false; - SendPlayerExitMessage(player); - UpdateDealer(true); + MahjongPackets.CreateMahjongRelieve(relievePacket, _game.Serial); + player.NetState?.Send(relievePacket); - removed = true; - } - else if (!Game.IsAccessibleTo(player) || player.Map != Game.Map || - !player.InRange(Game.GetWorldLocation(), 5)) - { - m_InGame[i] = false; + SendPlayerExitMessage(player); + UpdateDealer(true); - MahjongPackets.CreateMahjongRelieve(relievePacket, Game.Serial); - player.NetState?.Send(relievePacket); - - SendPlayerExitMessage(player); - UpdateDealer(true); - - removed = true; - } + removed = true; } } - - for (var i = 0; i < m_Spectators.Count;) - { - var mobile = m_Spectators[i]; - - if (mobile.NetState == null || mobile.Deleted) - { - m_Spectators.RemoveAt(i); - } - else if (!Game.IsAccessibleTo(mobile) || mobile.Map != Game.Map || - !mobile.InRange(Game.GetWorldLocation(), 5)) - { - m_Spectators.RemoveAt(i); - - MahjongPackets.CreateMahjongRelieve(relievePacket, Game.Serial); - mobile.NetState?.Send(relievePacket); - } - else - { - i++; - } - } - - if (removed && !UpdateSpectators()) - { - SendPlayersPacket(true, true); - } } - private void UpdateDealer(bool message) + for (var i = 0; i < _spectators.Count;) { - if (IsInGamePlayer(DealerPosition)) + var mobile = _spectators[i]; + + if (mobile.NetState == null || mobile.Deleted) { + _spectators.RemoveAt(i); + } + else if (!_game.IsAccessibleTo(mobile) || mobile.Map != _game.Map || + !mobile.InRange(_game.GetWorldLocation(), 5)) + { + _spectators.RemoveAt(i); + + MahjongPackets.CreateMahjongRelieve(relievePacket, _game.Serial); + mobile.NetState?.Send(relievePacket); + } + else + { + i++; + } + } + + if (removed && !UpdateSpectators()) + { + SendPlayersPacket(true, true); + } + } + + private void UpdateDealer(bool message) + { + if (IsInGamePlayer(DealerPosition)) + { + return; + } + + for (var i = DealerPosition + 1; i < _players.Length; i++) + { + if (IsInGamePlayer(i)) + { + DealerPosition = i; + + if (message) + { + SendDealerChangedMessage(); + } + return; } + } - for (var i = DealerPosition + 1; i < m_Players.Length; i++) + for (var i = 0; i < DealerPosition; i++) + { + if (IsInGamePlayer(i)) { - if (IsInGamePlayer(i)) + DealerPosition = i; + + if (message) { - DealerPosition = i; - - if (message) - { - SendDealerChangedMessage(); - } - - return; + SendDealerChangedMessage(); } + + return; } + } + } - for (var i = 0; i < DealerPosition; i++) + private int GetNextSeat() + { + for (var i = DealerPosition; i < _players.Length; i++) + { + if (_players[i] == null) { - if (IsInGamePlayer(i)) - { - DealerPosition = i; - - if (message) - { - SendDealerChangedMessage(); - } - - return; - } + return i; } } - private int GetNextSeat() + for (var i = 0; i < DealerPosition; i++) { - for (var i = DealerPosition; i < m_Players.Length; i++) + if (_players[i] == null) { - if (m_Players[i] == null) - { - return i; - } + return i; } - - for (var i = 0; i < DealerPosition; i++) - { - if (m_Players[i] == null) - { - return i; - } - } - - return -1; } - private bool UpdateSpectators() + return -1; + } + + private bool UpdateSpectators() + { + if (_spectators.Count == 0) { - if (m_Spectators.Count == 0) - { - return false; - } - - var nextSeat = GetNextSeat(); - - if (nextSeat >= 0) - { - var newPlayer = m_Spectators[0]; - - m_Spectators.RemoveAt(0); - - AddPlayer(newPlayer, nextSeat, false); - - UpdateSpectators(); - - return true; - } - return false; } - private void AddPlayer(Mobile player, int index, bool sendJoinGame) + var nextSeat = GetNextSeat(); + + if (nextSeat >= 0) { - m_Players[index] = player; - m_InGame[index] = true; + var newPlayer = _spectators[0]; - UpdateDealer(false); + _spectators.RemoveAt(0); - if (sendJoinGame) - { - player.NetState.SendMahjongJoinGame(Game.Serial); - } + AddPlayer(newPlayer, nextSeat, false); - SendPlayersPacket(true, true); + UpdateSpectators(); - player.NetState.SendMahjongGeneralInfo(Game); - player.NetState.SendMahjongTilesInfo(Game, player); - - if (DealerPosition == index) - { - SendLocalizedMessage(1062773, player.Name); // ~1_name~ has entered the game as the dealer. - } - else - { - SendLocalizedMessage(1062772, player.Name); // ~1_name~ has entered the game as a player. - } + return true; } - private void AddSpectator(Mobile mobile) - { - if (!IsSpectator(mobile)) - { - m_Spectators.Add(mobile); - } + return false; + } - mobile.NetState.SendMahjongJoinGame(Game.Serial); - mobile.NetState.SendMahjongPlayersInfo(Game, mobile); - mobile.NetState.SendMahjongGeneralInfo(Game); - mobile.NetState.SendMahjongTilesInfo(Game, mobile); + private void AddPlayer(Mobile player, int index, bool sendJoinGame) + { + _players[index] = player; + _inGame[index] = true; + + UpdateDealer(false); + + if (sendJoinGame) + { + player.NetState.SendMahjongJoinGame(_game.Serial); } - public void Join(Mobile mobile) + SendPlayersPacket(true, true); + + player.NetState.SendMahjongGeneralInfo(_game); + player.NetState.SendMahjongTilesInfo(_game, player); + + if (DealerPosition == index) { - var index = GetPlayerIndex(mobile); + SendLocalizedMessage(1062773, player.Name); // ~1_name~ has entered the game as the dealer. + } + else + { + SendLocalizedMessage(1062772, player.Name); // ~1_name~ has entered the game as a player. + } + } - if (index >= 0) - { - AddPlayer(mobile, index, true); - return; - } - - var nextSeat = GetNextSeat(); - - if (nextSeat >= 0) - { - AddPlayer(mobile, nextSeat, true); - } - else - { - AddSpectator(mobile); - } + private void AddSpectator(Mobile mobile) + { + if (!IsSpectator(mobile)) + { + _spectators.Add(mobile); } - public void LeaveGame(Mobile player) + mobile.NetState.SendMahjongJoinGame(_game.Serial); + mobile.NetState.SendMahjongPlayersInfo(_game, mobile); + mobile.NetState.SendMahjongGeneralInfo(_game); + mobile.NetState.SendMahjongTilesInfo(_game, mobile); + } + + public void Join(Mobile mobile) + { + var index = GetPlayerIndex(mobile); + + if (index >= 0) { - var index = GetPlayerIndex(player); - if (index >= 0) - { - m_InGame[index] = false; - - SendPlayerExitMessage(player); - UpdateDealer(true); - - SendPlayersPacket(true, true); - } - else - { - m_Spectators.Remove(player); - } + AddPlayer(mobile, index, true); + return; } - public void ResetScores(int value) + var nextSeat = GetNextSeat(); + + if (nextSeat >= 0) { - for (var i = 0; i < m_Scores.Length; i++) - { - m_Scores[i] = value; - } - - SendPlayersPacket(true, Game.ShowScores); - - SendLocalizedMessage(1062697); // The dealer redistributes the score sticks evenly. + AddPlayer(mobile, nextSeat, true); } - - public void TransferScore(Mobile from, int toPosition, int amount) + else { - var fromPosition = GetPlayerIndex(from); - var to = GetPlayer(toPosition); - - if (fromPosition < 0 || to == null || m_Scores[fromPosition] < amount) - { - return; - } - - m_Scores[fromPosition] -= amount; - m_Scores[toPosition] += amount; - - if (Game.ShowScores) - { - SendPlayersPacket(true, true); - } - else - { - from.NetState.SendMahjongPlayersInfo(Game, from); - to.NetState.SendMahjongPlayersInfo(Game, to); - } - - // ~1_giver~ gives ~2_receiver~ ~3_number~ points. - SendLocalizedMessage(1062774, $"{from.Name}\t{to.Name}\t{amount}"); + AddSpectator(mobile); } + } - public void OpenSeat(int index) + public void LeaveGame(Mobile player) + { + var index = GetPlayerIndex(player); + if (index >= 0) { - var player = GetPlayer(index); - if (player == null) - { - return; - } - - if (m_InGame[index]) - { - player.NetState.SendMahjongRelieve(Game.Serial); - } - - m_Players[index] = null; - - SendLocalizedMessage(1062699, player.Name); // ~1_name~ is relieved from the game by the dealer. + _inGame[index] = false; + SendPlayerExitMessage(player); UpdateDealer(true); - if (!UpdateSpectators()) - { - SendPlayersPacket(true, true); - } + SendPlayersPacket(true, true); + } + else + { + _spectators.Remove(player); + } + } + + public void ResetScores(int value) + { + for (var i = 0; i < _scores.Length; i++) + { + _scores[i] = value; } - public void AssignDealer(int index) + SendPlayersPacket(true, _game.ShowScores); + + SendLocalizedMessage(1062697); // The dealer redistributes the score sticks evenly. + } + + public void TransferScore(Mobile from, int toPosition, int amount) + { + var fromPosition = GetPlayerIndex(from); + var to = GetPlayer(toPosition); + + if (fromPosition < 0 || to == null || _scores[fromPosition] < amount) { - var to = GetPlayer(index); - - if (to == null || !m_InGame[index]) - { - return; - } - - var oldDealer = DealerPosition; - - DealerPosition = index; - - if (IsInGamePlayer(oldDealer)) - { - m_Players[oldDealer].NetState.SendMahjongPlayersInfo(Game, m_Players[oldDealer]); - } - - to.NetState.SendMahjongPlayersInfo(Game, to); - - SendDealerChangedMessage(); + return; } - private void SendDealerChangedMessage() + _scores[fromPosition] -= amount; + _scores[toPosition] += amount; + + if (_game.ShowScores) { - if (Dealer != null) - { - SendLocalizedMessage(1062698, Dealer.Name); // ~1_name~ is assigned the dealer. - } + SendPlayersPacket(true, true); + } + else + { + from.NetState.SendMahjongPlayersInfo(_game, from); + to.NetState.SendMahjongPlayersInfo(_game, to); } - private void SendPlayerExitMessage(Mobile who) + // ~1_giver~ gives ~2_receiver~ ~3_number~ points. + SendLocalizedMessage(1062774, $"{from.Name}\t{to.Name}\t{amount}"); + } + + public void OpenSeat(int index) + { + var player = GetPlayer(index); + if (player == null) { - SendLocalizedMessage(1062762, who.Name); // ~1_name~ has left the game. + return; } - public void SendPlayersPacket(bool players, bool spectators) + if (_inGame[index]) { - foreach (var mobile in GetInGameMobiles(players, spectators)) - { - mobile.NetState.SendMahjongPlayersInfo(Game, mobile); - } + player.NetState.SendMahjongRelieve(_game.Serial); } - public void SendGeneralPacket(bool players, bool spectators) + _players[index] = null; + + SendLocalizedMessage(1062699, player.Name); // ~1_name~ is relieved from the game by the dealer. + + UpdateDealer(true); + + if (!UpdateSpectators()) { - var mobiles = GetInGameMobiles(players, spectators); + SendPlayersPacket(true, true); + } + } - if (mobiles.Count == 0) - { - return; - } + public void AssignDealer(int index) + { + var to = GetPlayer(index); - Span generalInfo = stackalloc byte[MahjongPackets.MahjongGeneralInfoPacketLength].InitializePacket(); - - foreach (var mobile in mobiles) - { - MahjongPackets.CreateMahjongGeneralInfo(generalInfo, Game); - mobile.NetState?.Send(generalInfo); - } + if (to == null || !_inGame[index]) + { + return; } - public void SendTilesPacket(bool players, bool spectators) + var oldDealer = DealerPosition; + + DealerPosition = index; + + if (IsInGamePlayer(oldDealer)) { - foreach (var mobile in GetInGameMobiles(players, spectators)) - { - mobile.NetState.SendMahjongTilesInfo(Game, mobile); - } + _players[oldDealer].NetState.SendMahjongPlayersInfo(_game, _players[oldDealer]); } - public void SendTilePacket(MahjongTile tile, bool players, bool spectators) + to.NetState.SendMahjongPlayersInfo(_game, to); + + SendDealerChangedMessage(); + } + + private void SendDealerChangedMessage() + { + if (Dealer != null) { - foreach (var mobile in GetInGameMobiles(players, spectators)) - { - mobile.NetState.SendMahjongTileInfo(tile, mobile); - } + SendLocalizedMessage(1062698, Dealer.Name); // ~1_name~ is assigned the dealer. + } + } + + private void SendPlayerExitMessage(Mobile who) + { + SendLocalizedMessage(1062762, who.Name); // ~1_name~ has left the game. + } + + public void SendPlayersPacket(bool players, bool spectators) + { + foreach (var mobile in GetInGameMobiles(players, spectators)) + { + mobile.NetState.SendMahjongPlayersInfo(_game, mobile); + } + } + + public void SendGeneralPacket(bool players, bool spectators) + { + var mobiles = GetInGameMobiles(players, spectators); + + if (mobiles.Count == 0) + { + return; } - public void SendRelievePacket(bool players, bool spectators) + Span generalInfo = stackalloc byte[MahjongPackets.MahjongGeneralInfoPacketLength].InitializePacket(); + + foreach (var mobile in mobiles) { - var mobiles = GetInGameMobiles(players, spectators); + MahjongPackets.CreateMahjongGeneralInfo(generalInfo, _game); + mobile.NetState?.Send(generalInfo); + } + } - if (mobiles.Count == 0) - { - return; - } + public void SendTilesPacket(bool players, bool spectators) + { + foreach (var mobile in GetInGameMobiles(players, spectators)) + { + mobile.NetState.SendMahjongTilesInfo(_game, mobile); + } + } - Span relievePacket = stackalloc byte[MahjongPackets.MahjongRelievePacketLength].InitializePacket(); + public void SendTilePacket(MahjongTile tile, bool players, bool spectators) + { + foreach (var mobile in GetInGameMobiles(players, spectators)) + { + mobile.NetState.SendMahjongTileInfo(tile, mobile); + } + } - foreach (var mobile in mobiles) - { - MahjongPackets.CreateMahjongRelieve(relievePacket, Game.Serial); - mobile.NetState?.Send(relievePacket); - } + public void SendRelievePacket(bool players, bool spectators) + { + var mobiles = GetInGameMobiles(players, spectators); + + if (mobiles.Count == 0) + { + return; } - public void SendLocalizedMessage(int number) + Span relievePacket = stackalloc byte[MahjongPackets.MahjongRelievePacketLength].InitializePacket(); + + foreach (var mobile in mobiles) { - foreach (var mobile in GetInGameMobiles(true, true)) - { - mobile.SendLocalizedMessage(number); - } + MahjongPackets.CreateMahjongRelieve(relievePacket, _game.Serial); + mobile.NetState?.Send(relievePacket); } + } - public void SendLocalizedMessage(int number, string args) + public void SendLocalizedMessage(int number) + { + foreach (var mobile in GetInGameMobiles(true, true)) { - foreach (var mobile in GetInGameMobiles(true, true)) - { - mobile.SendLocalizedMessage(number, args); - } + mobile.SendLocalizedMessage(number); } + } - public void Save(IGenericWriter writer) + public void SendLocalizedMessage(int number, string args) + { + foreach (var mobile in GetInGameMobiles(true, true)) { - writer.Write(0); // version - - writer.Write(Seats); - - for (var i = 0; i < Seats; i++) - { - writer.Write(m_Players[i]); - writer.Write(m_PublicHand[i]); - writer.Write(m_Scores[i]); - } - - writer.Write(DealerPosition); + mobile.SendLocalizedMessage(number, args); } } } diff --git a/Projects/UOContent/Items/Games/Mahjong/MahjongTile.cs b/Projects/UOContent/Items/Games/Mahjong/MahjongTile.cs index e9d3bf628..61c684d17 100644 --- a/Projects/UOContent/Items/Games/Mahjong/MahjongTile.cs +++ b/Projects/UOContent/Items/Games/Mahjong/MahjongTile.cs @@ -1,95 +1,86 @@ -namespace Server.Engines.Mahjong +using ModernUO.Serialization; + +namespace Server.Engines.Mahjong; + +[SerializationGenerator(1, false)] +public partial class MahjongTile { - public class MahjongTile + [DirtyTrackingEntity] + private readonly MahjongGame _game; + + [SerializableField(0, setter: "private")] + private int _number; + + [SerializableField(1, setter: "private")] + private MahjongTileType _value; + + [SerializableField(2, setter: "private")] + private Point2D _position; + + [SerializableField(3, setter: "private")] + private int _stackLevel; + + [SerializableField(4, setter: "private")] + private MahjongPieceDirection _direction; + + [SerializableField(5, setter: "private")] + private bool _flipped; + + public MahjongTile(MahjongGame game) => _game = game; + + public MahjongTile( + MahjongGame game, int number, MahjongTileType value, Point2D position, int stackLevel, + MahjongPieceDirection direction, bool flipped + ) { - protected Point2D m_Position; + _game = game; + _number = number; + _value = value; + _position = position; + _stackLevel = stackLevel; + _direction = direction; + _flipped = flipped; + } - public MahjongTile( - MahjongGame game, int number, MahjongTileType value, Point2D position, int stackLevel, - MahjongPieceDirection direction, bool flipped - ) + public MahjongGame Game => _game; + + private void Deserialize(IGenericReader reader, int version) + { + _number = reader.ReadInt(); + _value = (MahjongTileType)reader.ReadInt(); + _position = reader.ReadPoint2D(); + _stackLevel = reader.ReadInt(); + _direction = (MahjongPieceDirection)reader.ReadInt(); + _flipped = reader.ReadBool(); + } + + public MahjongPieceDim Dimensions => GetDimensions(_position, _direction); + + public bool IsMovable => _game.GetStackLevel(Dimensions) <= _stackLevel; + + public static MahjongPieceDim GetDimensions(Point2D position, MahjongPieceDirection direction) => + direction is MahjongPieceDirection.Up or MahjongPieceDirection.Down + ? new MahjongPieceDim(position, 20, 30) + : new MahjongPieceDim(position, 30, 20); + + public void Move(Point2D position, MahjongPieceDirection direction, bool flip, int validHandArea) + { + var dim = GetDimensions(position, direction); + var curHandArea = Dimensions.GetHandArea(); + var newHandArea = dim.GetHandArea(); + + if (!IsMovable || !dim.IsValid() || validHandArea >= 0 && + (curHandArea >= 0 && curHandArea != validHandArea || newHandArea >= 0 && newHandArea != validHandArea)) { - Game = game; - Number = number; - Value = value; - m_Position = position; - StackLevel = stackLevel; - Direction = direction; - Flipped = flipped; + return; } - public MahjongTile(MahjongGame game, IGenericReader reader) - { - Game = game; + Position = position; + Direction = direction; + StackLevel = -1; // Avoid self interference + StackLevel = _game.GetStackLevel(dim) + 1; + Flipped = flip; - var version = reader.ReadInt(); - - Number = reader.ReadInt(); - Value = (MahjongTileType)reader.ReadInt(); - m_Position = reader.ReadPoint2D(); - StackLevel = reader.ReadInt(); - Direction = (MahjongPieceDirection)reader.ReadInt(); - Flipped = reader.ReadBool(); - } - - public MahjongGame Game { get; } - - public int Number { get; } - - public MahjongTileType Value { get; } - - public Point2D Position => m_Position; - public int StackLevel { get; private set; } - - public MahjongPieceDirection Direction { get; private set; } - - public bool Flipped { get; private set; } - - public MahjongPieceDim Dimensions => GetDimensions(m_Position, Direction); - - public bool IsMovable => Game.GetStackLevel(Dimensions) <= StackLevel; - - public static MahjongPieceDim GetDimensions(Point2D position, MahjongPieceDirection direction) - { - if (direction is MahjongPieceDirection.Up or MahjongPieceDirection.Down) - { - return new MahjongPieceDim(position, 20, 30); - } - - return new MahjongPieceDim(position, 30, 20); - } - - public void Move(Point2D position, MahjongPieceDirection direction, bool flip, int validHandArea) - { - var dim = GetDimensions(position, direction); - var curHandArea = Dimensions.GetHandArea(); - var newHandArea = dim.GetHandArea(); - - if (!IsMovable || !dim.IsValid() || validHandArea >= 0 && - (curHandArea >= 0 && curHandArea != validHandArea || newHandArea >= 0 && newHandArea != validHandArea)) - { - return; - } - - m_Position = position; - Direction = direction; - StackLevel = -1; // Avoid self interference - StackLevel = Game.GetStackLevel(dim) + 1; - Flipped = flip; - - Game.Players.SendTilePacket(this, true, true); - } - - public void Save(IGenericWriter writer) - { - writer.Write(0); // version - - writer.Write(Number); - writer.Write((int)Value); - writer.Write(m_Position); - writer.Write(StackLevel); - writer.Write((int)Direction); - writer.Write(Flipped); - } + _game.Players.SendTilePacket(this, true, true); } } diff --git a/Projects/UOContent/Items/Games/Mahjong/MahjongTileTypeGenerator.cs b/Projects/UOContent/Items/Games/Mahjong/MahjongTileTypeGenerator.cs index 099e3b610..90b260f43 100644 --- a/Projects/UOContent/Items/Games/Mahjong/MahjongTileTypeGenerator.cs +++ b/Projects/UOContent/Items/Games/Mahjong/MahjongTileTypeGenerator.cs @@ -1,31 +1,28 @@ -using System.Collections.Generic; +namespace Server.Engines.Mahjong; -namespace Server.Engines.Mahjong +public class MahjongTileTypeGenerator { - public class MahjongTileTypeGenerator + private MahjongTileType[] _leftTileTypes; + private int _nextTile; + + public MahjongTileTypeGenerator() { - public MahjongTileTypeGenerator() - { - LeftTileTypes = new List(136); + _leftTileTypes = new MahjongTileType[136]; - for (var i = 1; i <= 34; i++) - { - var tile = (MahjongTileType)i; - LeftTileTypes.Add(tile); - LeftTileTypes.Add(tile); - LeftTileTypes.Add(tile); - LeftTileTypes.Add(tile); - } + for (int i = 1, j = 0; i <= 34; i++) + { + var tile = (MahjongTileType)i; + _leftTileTypes[j++] = tile; + _leftTileTypes[j++] = tile; + _leftTileTypes[j++] = tile; + _leftTileTypes[j++] = tile; } - public List LeftTileTypes { get; } - - public MahjongTileType Next() - { - var next = LeftTileTypes.RandomElement(); - LeftTileTypes.Remove(next); - - return next; - } + _leftTileTypes.Shuffle(); + _leftTileTypes.Shuffle(); + _leftTileTypes.Shuffle(); + _leftTileTypes.Shuffle(); } + + public MahjongTileType Next() => _leftTileTypes[_nextTile++]; } diff --git a/Projects/UOContent/Items/Games/Mahjong/MahjongWallBreakIndicator.cs b/Projects/UOContent/Items/Games/Mahjong/MahjongWallBreakIndicator.cs index febd3c228..c73613aa9 100644 --- a/Projects/UOContent/Items/Games/Mahjong/MahjongWallBreakIndicator.cs +++ b/Projects/UOContent/Items/Games/Mahjong/MahjongWallBreakIndicator.cs @@ -1,49 +1,39 @@ -namespace Server.Engines.Mahjong +using ModernUO.Serialization; + +namespace Server.Engines.Mahjong; + +[SerializationGenerator(0, false)] +public partial class MahjongWallBreakIndicator { - public class MahjongWallBreakIndicator + [DirtyTrackingEntity] + private readonly MahjongGame _game; + + [SerializableField(0, setter: "private")] + private Point2D _position; + + public MahjongWallBreakIndicator(MahjongGame game) => _game = game; + + public MahjongWallBreakIndicator(MahjongGame game, Point2D position) { - public MahjongWallBreakIndicator(MahjongGame game, Point2D position) + _game = game; + _position = position; + } + + public MahjongPieceDim Dimensions => GetDimensions(_position); + + public static MahjongPieceDim GetDimensions(Point2D position) => new(position, 20, 20); + + public void Move(Point2D position) + { + var dim = GetDimensions(position); + + if (!dim.IsValid()) { - Game = game; - Position = position; + return; } - public MahjongWallBreakIndicator(MahjongGame game, IGenericReader reader) - { - Game = game; + _position = position; - var version = reader.ReadInt(); - - Position = reader.ReadPoint2D(); - } - - public MahjongGame Game { get; } - - public Point2D Position { get; private set; } - - public MahjongPieceDim Dimensions => GetDimensions(Position); - - public static MahjongPieceDim GetDimensions(Point2D position) => new(position, 20, 20); - - public void Move(Point2D position) - { - var dim = GetDimensions(position); - - if (!dim.IsValid()) - { - return; - } - - Position = position; - - Game.Players.SendGeneralPacket(true, true); - } - - public void Save(IGenericWriter writer) - { - writer.Write(0); // version - - writer.Write(Position); - } + _game.Players.SendGeneralPacket(true, true); } } diff --git a/Projects/UOContent/Migrations/Server.Engines.Mahjong.MahjongDealerIndicator.v1.json b/Projects/UOContent/Migrations/Server.Engines.Mahjong.MahjongDealerIndicator.v1.json new file mode 100644 index 000000000..967bc6e58 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Engines.Mahjong.MahjongDealerIndicator.v1.json @@ -0,0 +1,24 @@ +{ + "version": 1, + "type": "Server.Engines.Mahjong.MahjongDealerIndicator", + "properties": [ + { + "name": "Position", + "type": "Server.Point2D", + "rule": "PrimitiveUOTypeMigrationRule", + "ruleArguments": [ + "Point2D" + ] + }, + { + "name": "Direction", + "type": "Server.Engines.Mahjong.MahjongPieceDirection", + "rule": "EnumMigrationRule" + }, + { + "name": "Wind", + "type": "Server.Engines.Mahjong.MahjongWind", + "rule": "EnumMigrationRule" + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Engines.Mahjong.MahjongDices.v0.json b/Projects/UOContent/Migrations/Server.Engines.Mahjong.MahjongDices.v0.json new file mode 100644 index 000000000..2f5945ff3 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Engines.Mahjong.MahjongDices.v0.json @@ -0,0 +1,22 @@ +{ + "version": 0, + "type": "Server.Engines.Mahjong.MahjongDices", + "properties": [ + { + "name": "First", + "type": "int", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "Second", + "type": "int", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Engines.Mahjong.MahjongGame.v1.json b/Projects/UOContent/Migrations/Server.Engines.Mahjong.MahjongGame.v1.json new file mode 100644 index 000000000..9d4348506 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Engines.Mahjong.MahjongGame.v1.json @@ -0,0 +1,69 @@ +{ + "version": 1, + "type": "Server.Engines.Mahjong.MahjongGame", + "properties": [ + { + "name": "Level", + "type": "Server.Multis.SecureLevel", + "rule": "EnumMigrationRule" + }, + { + "name": "Tiles", + "type": "Server.Engines.Mahjong.MahjongTile[]", + "rule": "ArrayMigrationRule", + "ruleArguments": [ + "Server.Engines.Mahjong.MahjongTile", + "RawSerializableMigrationRule", + "DeserializationRequiresParent" + ] + }, + { + "name": "DealerIndicator", + "type": "Server.Engines.Mahjong.MahjongDealerIndicator", + "rule": "RawSerializableMigrationRule", + "ruleArguments": [ + "DeserializationRequiresParent" + ] + }, + { + "name": "WallBreakIndicator", + "type": "Server.Engines.Mahjong.MahjongWallBreakIndicator", + "rule": "RawSerializableMigrationRule", + "ruleArguments": [ + "DeserializationRequiresParent" + ] + }, + { + "name": "Dices", + "type": "Server.Engines.Mahjong.MahjongDices", + "rule": "RawSerializableMigrationRule", + "ruleArguments": [ + "DeserializationRequiresParent" + ] + }, + { + "name": "Players", + "type": "Server.Engines.Mahjong.MahjongPlayers", + "rule": "RawSerializableMigrationRule", + "ruleArguments": [ + "DeserializationRequiresParent" + ] + }, + { + "name": "ShowScores", + "type": "bool", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "SpectatorVision", + "type": "bool", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Engines.Mahjong.MahjongPlayers.v1.json b/Projects/UOContent/Migrations/Server.Engines.Mahjong.MahjongPlayers.v1.json new file mode 100644 index 000000000..696bd989e --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Engines.Mahjong.MahjongPlayers.v1.json @@ -0,0 +1,53 @@ +{ + "version": 1, + "type": "Server.Engines.Mahjong.MahjongPlayers", + "properties": [ + { + "name": "Players", + "type": "Server.Mobile[]", + "rule": "ArrayMigrationRule", + "ruleArguments": [ + "Server.Mobile", + "SerializableInterfaceMigrationRule" + ] + }, + { + "name": "InGame", + "type": "bool[]", + "rule": "ArrayMigrationRule", + "ruleArguments": [ + "bool", + "PrimitiveTypeMigrationRule", + "" + ] + }, + { + "name": "PublicHand", + "type": "bool[]", + "rule": "ArrayMigrationRule", + "ruleArguments": [ + "bool", + "PrimitiveTypeMigrationRule", + "" + ] + }, + { + "name": "Scores", + "type": "int[]", + "rule": "ArrayMigrationRule", + "ruleArguments": [ + "int", + "PrimitiveTypeMigrationRule", + "" + ] + }, + { + "name": "DealerPosition", + "type": "int", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Engines.Mahjong.MahjongTile.v1.json b/Projects/UOContent/Migrations/Server.Engines.Mahjong.MahjongTile.v1.json new file mode 100644 index 000000000..33d13b217 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Engines.Mahjong.MahjongTile.v1.json @@ -0,0 +1,48 @@ +{ + "version": 1, + "type": "Server.Engines.Mahjong.MahjongTile", + "properties": [ + { + "name": "Number", + "type": "int", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "Value", + "type": "Server.Engines.Mahjong.MahjongTileType", + "rule": "EnumMigrationRule" + }, + { + "name": "Position", + "type": "Server.Point2D", + "rule": "PrimitiveUOTypeMigrationRule", + "ruleArguments": [ + "Point2D" + ] + }, + { + "name": "StackLevel", + "type": "int", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "Direction", + "type": "Server.Engines.Mahjong.MahjongPieceDirection", + "rule": "EnumMigrationRule" + }, + { + "name": "Flipped", + "type": "bool", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Engines.Mahjong.MahjongWallBreakIndicator.v0.json b/Projects/UOContent/Migrations/Server.Engines.Mahjong.MahjongWallBreakIndicator.v0.json new file mode 100644 index 000000000..886f15a4d --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Engines.Mahjong.MahjongWallBreakIndicator.v0.json @@ -0,0 +1,14 @@ +{ + "version": 0, + "type": "Server.Engines.Mahjong.MahjongWallBreakIndicator", + "properties": [ + { + "name": "Position", + "type": "Server.Point2D", + "rule": "PrimitiveUOTypeMigrationRule", + "ruleArguments": [ + "Point2D" + ] + } + ] +} \ No newline at end of file From 17e33a65d2b0db0061862dd81d8b67870e54a474 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Thu, 16 Jun 2022 21:34:11 -0700 Subject: [PATCH 204/213] fix: Fixes source gen bugs (#1072) --- Projects/Server/Server.csproj | 2 +- Projects/UOContent/UOContent.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Projects/Server/Server.csproj b/Projects/Server/Server.csproj index bde115202..00c2d463a 100755 --- a/Projects/Server/Server.csproj +++ b/Projects/Server/Server.csproj @@ -41,7 +41,7 @@ - + diff --git a/Projects/UOContent/UOContent.csproj b/Projects/UOContent/UOContent.csproj index 3e1296051..2923b496b 100755 --- a/Projects/UOContent/UOContent.csproj +++ b/Projects/UOContent/UOContent.csproj @@ -46,7 +46,7 @@ - + From 57f81a0e12b8e73db801a12693ccca4781556761 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Thu, 16 Jun 2022 21:53:04 -0700 Subject: [PATCH 205/213] fix: Updates schema generator. (#1073) --- .config/dotnet-tools.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index fbd46b62c..c4a8cb63e 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "modernuoschemagenerator": { - "version": "2.1.1", + "version": "2.1.2", "commands": [ "ModernUOSchemaGenerator" ] From cf1d0374444588ce315b9534daab309612b54d94 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Thu, 16 Jun 2022 22:45:39 -0700 Subject: [PATCH 206/213] fix: Fixes serialization NPE when namespace is missing (#1074) --- .config/dotnet-tools.json | 2 +- Projects/Server/Server.csproj | 2 +- Projects/UOContent/UOContent.csproj | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index c4a8cb63e..9a1e358ec 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "modernuoschemagenerator": { - "version": "2.1.2", + "version": "2.1.3", "commands": [ "ModernUOSchemaGenerator" ] diff --git a/Projects/Server/Server.csproj b/Projects/Server/Server.csproj index 00c2d463a..1b00238b0 100755 --- a/Projects/Server/Server.csproj +++ b/Projects/Server/Server.csproj @@ -41,7 +41,7 @@ - + diff --git a/Projects/UOContent/UOContent.csproj b/Projects/UOContent/UOContent.csproj index 2923b496b..4bc001e19 100755 --- a/Projects/UOContent/UOContent.csproj +++ b/Projects/UOContent/UOContent.csproj @@ -46,7 +46,7 @@ - + From 9c8f73aaf85dd1872c9b269e300272d618921314 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Fri, 17 Jun 2022 01:48:25 -0700 Subject: [PATCH 207/213] chore: Updates minimum .net 6 version --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5f0a68612..c19bfc451 100644 --- a/README.md +++ b/README.md @@ -25,11 +25,11 @@ ModernUO [![Discord](https://img.shields.io/discord/751317910504603701?logo=disc [![RedHat 7/8](https://img.shields.io/badge/-8-BE0000?logo=red%20hat&logoColor=white)](https://access.redhat.com/downloads) #### Running the server -[![.NET](https://img.shields.io/badge/-6.0-5C2D91?logo=.NET)](https://dotnet.microsoft.com/download/dotnet/6.0) +[![.NET](https://img.shields.io/badge/-6.0.6-5C2D91?logo=.NET)](https://dotnet.microsoft.com/download/dotnet/6.0) #### Development [![git](https://img.shields.io/badge/-git-F05032?logo=git&logoColor=white)](https://git-scm.com/downloads) -[![.NET](https://img.shields.io/badge/-%206.0%20SDK-5C2D91?logo=.NET)](https://dotnet.microsoft.com/download/dotnet/6.0) +[![.NET](https://img.shields.io/badge/-%206.0.6%20SDK-5C2D91?logo=.NET)](https://dotnet.microsoft.com/download/dotnet/6.0) #### Supported IDEs     From 41efa69b566977d780f745e5b6bc624d559df737 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Fri, 17 Jun 2022 23:26:27 -0700 Subject: [PATCH 208/213] fix: Adds OSI candle/torch functionality, codegens lights (#1075) --- Projects/Server/Mobiles/Mobile.cs | 12 +- .../Items/Lights/BaseEquipableLight.cs | 109 ++++++ .../Items/Lights/BaseEquippableLight.cs | 62 --- Projects/UOContent/Items/Lights/BaseLight.cs | 368 +++++++++--------- Projects/UOContent/Items/Lights/Brazier.cs | 43 +- .../UOContent/Items/Lights/BrazierTall.cs | 43 +- Projects/UOContent/Items/Lights/Candelabra.cs | 91 ++--- .../UOContent/Items/Lights/CandelabraStand.cs | 43 +- Projects/UOContent/Items/Lights/Candle.cs | 12 +- .../UOContent/Items/Lights/CandleLarge.cs | 50 +-- Projects/UOContent/Items/Lights/CandleLong.cs | 50 +-- .../UOContent/Items/Lights/CandleShort.cs | 50 +-- .../UOContent/Items/Lights/CandleSkull.cs | 74 +--- Projects/UOContent/Items/Lights/DarkSource.cs | 34 +- .../UOContent/Items/Lights/HangingLantern.cs | 45 +-- .../UOContent/Items/Lights/HeatingStand.cs | 92 ++--- Projects/UOContent/Items/Lights/LampPost1.cs | 45 +-- Projects/UOContent/Items/Lights/LampPost2.cs | 45 +-- Projects/UOContent/Items/Lights/LampPost3.cs | 45 +-- Projects/UOContent/Items/Lights/Lantern.cs | 35 +- .../UOContent/Items/Lights/LightSource.cs | 34 +- .../UOContent/Items/Lights/PaperLantern.cs | 47 +-- .../Items/Lights/RedHangingLantern.cs | 97 ++--- .../Items/Lights/RoundPaperLantern.cs | 47 +-- .../UOContent/Items/Lights/ShojiLantern.cs | 47 +-- Projects/UOContent/Items/Lights/Torch.cs | 12 +- Projects/UOContent/Items/Lights/WallSconce.cs | 105 ++--- Projects/UOContent/Items/Lights/WallTorch.cs | 105 ++--- .../Items/Lights/WhiteHangingLantern.cs | 97 ++--- .../Server.Items.BaseEquipableLight.v0.json | 4 + .../Migrations/Server.Items.BaseLight.v1.json | 43 ++ .../Migrations/Server.Items.Brazier.v0.json | 4 + .../Server.Items.BrazierTall.v0.json | 4 + .../Server.Items.Candelabra.v0.json | 14 + .../Server.Items.CandelabraStand.v0.json | 4 + .../Server.Items.CandleLarge.v0.json | 4 + .../Server.Items.CandleLong.v0.json | 4 + .../Server.Items.CandleShort.v0.json | 4 + .../Server.Items.CandleSkull.v0.json | 4 + .../Server.Items.DarkSource.v0.json | 4 + .../Server.Items.HangingLantern.v0.json | 4 + .../Server.Items.HeatingStand.v0.json | 4 + .../Migrations/Server.Items.LampPost1.v0.json | 4 + .../Migrations/Server.Items.LampPost2.v0.json | 4 + .../Migrations/Server.Items.LampPost3.v0.json | 4 + .../Server.Items.LightSource.v0.json | 4 + .../Server.Items.PaperLantern.v0.json | 4 + .../Server.Items.RedHangingLantern.v0.json | 4 + .../Server.Items.RoundPaperLantern.v0.json | 4 + .../Server.Items.ShojiLantern.v0.json | 4 + .../Server.Items.WallSconce.v0.json | 4 + .../Migrations/Server.Items.WallTorch.v0.json | 4 + .../Server.Items.WhiteHangingLantern.v0.json | 4 + 53 files changed, 865 insertions(+), 1219 deletions(-) create mode 100644 Projects/UOContent/Items/Lights/BaseEquipableLight.cs delete mode 100644 Projects/UOContent/Items/Lights/BaseEquippableLight.cs create mode 100644 Projects/UOContent/Migrations/Server.Items.BaseEquipableLight.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.BaseLight.v1.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Brazier.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.BrazierTall.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Candelabra.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.CandelabraStand.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.CandleLarge.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.CandleLong.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.CandleShort.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.CandleSkull.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.DarkSource.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.HangingLantern.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.HeatingStand.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.LampPost1.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.LampPost2.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.LampPost3.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.LightSource.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.PaperLantern.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.RedHangingLantern.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.RoundPaperLantern.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.ShojiLantern.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.WallSconce.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.WallTorch.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.WhiteHangingLantern.v0.json diff --git a/Projects/Server/Mobiles/Mobile.cs b/Projects/Server/Mobiles/Mobile.cs index f6c9055a8..c811926af 100644 --- a/Projects/Server/Mobiles/Mobile.cs +++ b/Projects/Server/Mobiles/Mobile.cs @@ -5301,12 +5301,12 @@ namespace Server } } - public static Item LiftItemDupe(Item oldItem, int amount) + public static T LiftItemDupe(T oldItem, int amount) where T : Item { - Item item; + T item; try { - item = oldItem.GetType().CreateInstance(); + item = oldItem.GetType().CreateInstance(); } catch { @@ -5318,6 +5318,9 @@ namespace Server return null; } + var oldAmount = oldItem.Amount; + oldItem.Amount = amount; + item.Visible = oldItem.Visible; item.Movable = oldItem.Movable; item.LootType = oldItem.LootType; @@ -5329,10 +5332,9 @@ namespace Server item.Name = oldItem.Name; item.Weight = oldItem.Weight; - item.Amount = oldItem.Amount - amount; + item.Amount = oldAmount - amount; item.Map = oldItem.Map; - oldItem.Amount = amount; oldItem.OnAfterDuped(item); if (oldItem.Parent is Mobile parentMobile) diff --git a/Projects/UOContent/Items/Lights/BaseEquipableLight.cs b/Projects/UOContent/Items/Lights/BaseEquipableLight.cs new file mode 100644 index 000000000..8e0482cf9 --- /dev/null +++ b/Projects/UOContent/Items/Lights/BaseEquipableLight.cs @@ -0,0 +1,109 @@ +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0, false)] +public abstract partial class BaseEquipableLight : BaseLight +{ + [Constructible] + public BaseEquipableLight(int itemID) : base(itemID) => Layer = Layer.TwoHanded; + + private BaseEquipableLight SplitStack() + { + if (!Stackable || Amount < 2) + { + return null; + } + + var stack = Mobile.LiftItemDupe(this, 1); + stack.BurntOut = BurntOut; + stack.Duration = Duration; + stack.Light = Light; + stack.Protected = Protected; + + return stack; + } + + public override bool OnEquip(Mobile from) + { + if (!base.OnEquip(from)) + { + return false; + } + + var stack = SplitStack(); + if (stack != null && stack.Parent != from.Backpack) + { + if (from.AddToBackpack(stack)) + { + if (this is Candle) + { + from.SendLocalizedMessage(502967); // You put the remaining unlit candles into your backpack. + } + else if (this is Torch) + { + from.SendLocalizedMessage(502970); // You put the remaining unlit torches into your backpack. + } + } + else + { + stack.MoveToWorld(from.Location, from.Map); + } + } + + return true; + } + + public override void Ignite() + { + if (Parent is not Mobile && RootParent is Mobile holder) + { + if (holder.EquipItem(this)) + { + if (this is Candle) + { + holder.SendLocalizedMessage(502969); // You put the candle in your left hand. + } + else if (this is Torch) + { + holder.SendLocalizedMessage(502972); // You put the torch in your left hand. + } + + // No message for lanterns? + } + else + { + SplitStack(); + MoveToWorld(holder.Location, holder.Map); + + if (this is Candle) + { + holder.SendLocalizedMessage(502968); // You cannot hold the candle, so it has been placed at your feet. + } + else if (this is Torch) + { + // 502971 has the wrong message + holder.SendMessage("You cannot hold the torch, so it has been placed at your feet."); + } + + // No message for lanterns? + } + } + else + { + SplitStack(); + } + + base.Ignite(); + } + + public override void OnAdded(IEntity parent) + { + if (Burning && parent is Container) + { + Douse(); + } + + base.OnAdded(parent); + } +} diff --git a/Projects/UOContent/Items/Lights/BaseEquippableLight.cs b/Projects/UOContent/Items/Lights/BaseEquippableLight.cs deleted file mode 100644 index 5310b457c..000000000 --- a/Projects/UOContent/Items/Lights/BaseEquippableLight.cs +++ /dev/null @@ -1,62 +0,0 @@ -namespace Server.Items -{ - public abstract class BaseEquipableLight : BaseLight - { - [Constructible] - public BaseEquipableLight(int itemID) : base(itemID) => Layer = Layer.TwoHanded; - - public BaseEquipableLight(Serial serial) : base(serial) - { - } - - public override void Ignite() - { - if (Parent is not Mobile && RootParent is Mobile holder) - { - if (holder.EquipItem(this)) - { - if (this is Candle) - { - holder.SendLocalizedMessage(502969); // You put the candle in your left hand. - } - else if (this is Torch) - { - holder.SendLocalizedMessage(502971); // You put the torch in your left hand. - } - - base.Ignite(); - } - else - { - holder.SendLocalizedMessage(502449); // You cannot hold this item. - } - } - else - { - base.Ignite(); - } - } - - public override void OnAdded(IEntity parent) - { - if (Burning && parent is Container) - { - Douse(); - } - - base.OnAdded(parent); - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } - } -} diff --git a/Projects/UOContent/Items/Lights/BaseLight.cs b/Projects/UOContent/Items/Lights/BaseLight.cs index eb83b594b..7aa6742d4 100644 --- a/Projects/UOContent/Items/Lights/BaseLight.cs +++ b/Projects/UOContent/Items/Lights/BaseLight.cs @@ -1,233 +1,213 @@ using System; +using ModernUO.Serialization; -namespace Server.Items +namespace Server.Items; + +[SerializationGenerator(1, false)] +public abstract partial class BaseLight : Item { - public abstract class BaseLight : Item + public static readonly bool Burnout = false; + + [SerializableField(0)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private bool _burntOut; + + // Field 1 + private bool _burning; + + // Field 2 + private TimeSpan _duration = TimeSpan.Zero; + + [SerializableField(3)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private bool _protected; + + [TimerDrift] + [SerializableField(4, getter: "private", setter: "private")] + private Timer _burnTimer; + + [DeserializeTimerField(4)] + private void DeserializeTimer(TimeSpan delay) { - public static readonly bool Burnout = false; - private bool m_Burning; - private TimeSpan m_Duration = TimeSpan.Zero; - private DateTime m_End; - private Timer m_Timer; - - [Constructible] - public BaseLight(int itemID) : base(itemID) + if (_burning && _duration != TimeSpan.Zero) { + DoTimer(delay); } + } - public BaseLight(Serial serial) : base(serial) + [Constructible] + public BaseLight(int itemID) : base(itemID) + { + } + + public abstract int LitItemID { get; } + + public virtual int UnlitItemID => 0; + public virtual int BurntOutItemID => 0; + + public virtual int LitSound => 0x47; + public virtual int UnlitSound => 0x3be; + public virtual int BurntOutSound => 0x4b8; + + [SerializableField(1)] + [CommandProperty(AccessLevel.GameMaster)] + public bool Burning + { + get => _burning; + set { - } - - public abstract int LitItemID { get; } - - public virtual int UnlitItemID => 0; - public virtual int BurntOutItemID => 0; - - public virtual int LitSound => 0x47; - public virtual int UnlitSound => 0x3be; - public virtual int BurntOutSound => 0x4b8; - - [CommandProperty(AccessLevel.GameMaster)] - public bool Burning - { - get => m_Burning; - set + if (_burning != value) { - if (m_Burning != value) - { - m_Burning = true; - DoTimer(m_Duration); - } + _burning = true; + DoTimer(_duration); + this.MarkDirty(); } } + } - [CommandProperty(AccessLevel.GameMaster)] - public bool BurntOut { get; set; } - - [CommandProperty(AccessLevel.GameMaster)] - public bool Protected { get; set; } - - [CommandProperty(AccessLevel.GameMaster)] - public TimeSpan Duration + [SerializableField(2)] + [CommandProperty(AccessLevel.GameMaster)] + public TimeSpan Duration + { + get => _duration != TimeSpan.Zero && _burning && _burnTimer != null ? _burnTimer.Next - Core.Now : _duration; + set { - get => m_Duration != TimeSpan.Zero && m_Burning ? m_End - Core.Now : m_Duration; - set => m_Duration = value; + _duration = value; + this.MarkDirty(); + } + } + + public virtual void PlayLitSound() + { + if (LitSound != 0) + { + var loc = GetWorldLocation(); + Effects.PlaySound(loc, Map, LitSound); + } + } + + public virtual void PlayUnlitSound() + { + var sound = UnlitSound; + + if (BurntOut && BurntOutSound != 0) + { + sound = BurntOutSound; } - public virtual void PlayLitSound() + if (sound != 0) { - if (LitSound != 0) - { - var loc = GetWorldLocation(); - Effects.PlaySound(loc, Map, LitSound); - } + var loc = GetWorldLocation(); + Effects.PlaySound(loc, Map, sound); + } + } + + public virtual void Ignite() + { + if (!BurntOut) + { + PlayLitSound(); + + _burning = true; + ItemID = LitItemID; + DoTimer(_duration); + } + } + + public virtual void Douse() + { + _burning = false; + + ItemID = BurntOut && BurntOutItemID != 0 ? BurntOutItemID : UnlitItemID; + + if (BurntOut) + { + _duration = TimeSpan.Zero; + } + else if (_duration != TimeSpan.Zero) + { + _duration = _burnTimer.Next - Core.Now; } - public virtual void PlayUnlitSound() + _burnTimer?.Stop(); + this.MarkDirty(); + + PlayUnlitSound(); + } + + public virtual void Burn() + { + BurntOut = true; + Douse(); + } + + private void DoTimer(TimeSpan delay) + { + _duration = delay; + _burnTimer?.Stop(); + this.MarkDirty(); + + if (delay == TimeSpan.Zero) { - var sound = UnlitSound; - - if (BurntOut && BurntOutSound != 0) - { - sound = BurntOutSound; - } - - if (sound != 0) - { - var loc = GetWorldLocation(); - Effects.PlaySound(loc, Map, sound); - } + return; } - public virtual void Ignite() - { - if (!BurntOut) - { - PlayLitSound(); + _burnTimer = new InternalTimer(this, delay); + _burnTimer.Start(); + this.MarkDirty(); + } - m_Burning = true; - ItemID = LitItemID; - DoTimer(m_Duration); - } + public override void OnDoubleClick(Mobile from) + { + if (_burntOut) + { + return; } - public virtual void Douse() + if (_protected && from.AccessLevel == AccessLevel.Player) { - m_Burning = false; - - if (BurntOut && BurntOutItemID != 0) - { - ItemID = BurntOutItemID; - } - else - { - ItemID = UnlitItemID; - } - - if (BurntOut) - { - m_Duration = TimeSpan.Zero; - } - else if (m_Duration != TimeSpan.Zero) - { - m_Duration = m_End - Core.Now; - } - - m_Timer?.Stop(); - - PlayUnlitSound(); + return; } - public virtual void Burn() + if (!from.InRange(GetWorldLocation(), 2)) + { + return; + } + + if (!_burning) + { + Ignite(); + } + else if (UnlitItemID != 0) { - BurntOut = true; Douse(); } + } - private void DoTimer(TimeSpan delay) + private void Deserialize(IGenericReader reader, int version) + { + _burntOut = reader.ReadBool(); + _burning = reader.ReadBool(); + _duration = reader.ReadTimeSpan(); + _protected = reader.ReadBool(); + + if (_burning && _duration != TimeSpan.Zero) { - m_Duration = delay; - - m_Timer?.Stop(); - - if (delay == TimeSpan.Zero) - { - return; - } - - m_End = Core.Now + delay; - - m_Timer = new InternalTimer(this, delay); - m_Timer.Start(); + DoTimer(reader.ReadDeltaTime() - Core.Now); } + } - public override void OnDoubleClick(Mobile from) + private class InternalTimer : Timer + { + private readonly BaseLight m_Light; + + public InternalTimer(BaseLight light, TimeSpan delay) : base(delay) => m_Light = light; + + protected override void OnTick() { - if (BurntOut) + if (m_Light?.Deleted == false) { - return; - } - - if (Protected && from.AccessLevel == AccessLevel.Player) - { - return; - } - - if (!from.InRange(GetWorldLocation(), 2)) - { - return; - } - - if (m_Burning) - { - if (UnlitItemID != 0) - { - Douse(); - } - } - else - { - Ignite(); - } - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); - writer.Write(BurntOut); - writer.Write(m_Burning); - writer.Write(m_Duration); - writer.Write(Protected); - - if (m_Burning && m_Duration != TimeSpan.Zero) - { - writer.WriteDeltaTime(m_End); - } - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - switch (version) - { - case 0: - { - BurntOut = reader.ReadBool(); - m_Burning = reader.ReadBool(); - m_Duration = reader.ReadTimeSpan(); - Protected = reader.ReadBool(); - - if (m_Burning && m_Duration != TimeSpan.Zero) - { - DoTimer(reader.ReadDeltaTime() - Core.Now); - } - - break; - } - } - } - - private class InternalTimer : Timer - { - private readonly BaseLight m_Light; - - public InternalTimer(BaseLight light, TimeSpan delay) : base(delay) - { - m_Light = light; - } - - protected override void OnTick() - { - if (m_Light?.Deleted == false) - { - m_Light.Burn(); - } + m_Light.Burn(); } } } diff --git a/Projects/UOContent/Items/Lights/Brazier.cs b/Projects/UOContent/Items/Lights/Brazier.cs index 65b6f8066..56f834c3b 100644 --- a/Projects/UOContent/Items/Lights/Brazier.cs +++ b/Projects/UOContent/Items/Lights/Brazier.cs @@ -1,35 +1,20 @@ using System; +using ModernUO.Serialization; -namespace Server.Items +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class Brazier : BaseLight { - public class Brazier : BaseLight + [Constructible] + public Brazier() : base(0xE31) { - [Constructible] - public Brazier() : base(0xE31) - { - Movable = false; - Duration = TimeSpan.Zero; // Never burnt out - Burning = true; - Light = LightType.Circle225; - Weight = 20.0; - } - - public Brazier(Serial serial) : base(serial) - { - } - - public override int LitItemID => 0xE31; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } + Movable = false; + Duration = TimeSpan.Zero; // Never burnt out + Burning = true; + Light = LightType.Circle225; + Weight = 20.0; } + + public override int LitItemID => 0xE31; } diff --git a/Projects/UOContent/Items/Lights/BrazierTall.cs b/Projects/UOContent/Items/Lights/BrazierTall.cs index 0774217a8..c23945c50 100644 --- a/Projects/UOContent/Items/Lights/BrazierTall.cs +++ b/Projects/UOContent/Items/Lights/BrazierTall.cs @@ -1,35 +1,20 @@ using System; +using ModernUO.Serialization; -namespace Server.Items +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class BrazierTall : BaseLight { - public class BrazierTall : BaseLight + [Constructible] + public BrazierTall() : base(0x19AA) { - [Constructible] - public BrazierTall() : base(0x19AA) - { - Movable = false; - Duration = TimeSpan.Zero; // Never burnt out - Burning = true; - Light = LightType.Circle300; - Weight = 25.0; - } - - public BrazierTall(Serial serial) : base(serial) - { - } - - public override int LitItemID => 0x19AA; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } + Movable = false; + Duration = TimeSpan.Zero; // Never burnt out + Burning = true; + Light = LightType.Circle300; + Weight = 25.0; } + + public override int LitItemID => 0x19AA; } diff --git a/Projects/UOContent/Items/Lights/Candelabra.cs b/Projects/UOContent/Items/Lights/Candelabra.cs index 30d3b98e8..823313f2d 100644 --- a/Projects/UOContent/Items/Lights/Candelabra.cs +++ b/Projects/UOContent/Items/Lights/Candelabra.cs @@ -1,69 +1,44 @@ using System; +using ModernUO.Serialization; -namespace Server.Items +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class Candelabra : BaseLight, IShipwreckedItem { - public class Candelabra : BaseLight, IShipwreckedItem + [SerializableField(0)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private bool _isShipwreckedItem; + + [Constructible] + public Candelabra() : base(0xA27) { - [Constructible] - public Candelabra() : base(0xA27) + Duration = TimeSpan.Zero; // Never burnt out + Burning = false; + Light = LightType.Circle225; + Weight = 3.0; + } + + public override int LitItemID => 0xB1D; + public override int UnlitItemID => 0xA27; + + public override void AddNameProperties(IPropertyList list) + { + base.AddNameProperties(list); + + if (IsShipwreckedItem) { - Duration = TimeSpan.Zero; // Never burnt out - Burning = false; - Light = LightType.Circle225; - Weight = 3.0; + list.Add(1041645); // recovered from a shipwreck } + } - public Candelabra(Serial serial) : base(serial) + public override void OnSingleClick(Mobile from) + { + base.OnSingleClick(from); + + if (IsShipwreckedItem) { - } - - public override int LitItemID => 0xB1D; - public override int UnlitItemID => 0xA27; - - [CommandProperty(AccessLevel.GameMaster)] - public bool IsShipwreckedItem { get; set; } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(1); - - writer.Write(IsShipwreckedItem); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - - switch (version) - { - case 1: - { - IsShipwreckedItem = reader.ReadBool(); - break; - } - } - } - - public override void AddNameProperties(IPropertyList list) - { - base.AddNameProperties(list); - - if (IsShipwreckedItem) - { - list.Add(1041645); // recovered from a shipwreck - } - } - - public override void OnSingleClick(Mobile from) - { - base.OnSingleClick(from); - - if (IsShipwreckedItem) - { - LabelTo(from, 1041645); // recovered from a shipwreck - } + LabelTo(from, 1041645); // recovered from a shipwreck } } } diff --git a/Projects/UOContent/Items/Lights/CandelabraStand.cs b/Projects/UOContent/Items/Lights/CandelabraStand.cs index 4f32f5d39..00e49e521 100644 --- a/Projects/UOContent/Items/Lights/CandelabraStand.cs +++ b/Projects/UOContent/Items/Lights/CandelabraStand.cs @@ -1,35 +1,20 @@ using System; +using ModernUO.Serialization; -namespace Server.Items +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class CandelabraStand : BaseLight { - public class CandelabraStand : BaseLight + [Constructible] + public CandelabraStand() : base(0xA29) { - [Constructible] - public CandelabraStand() : base(0xA29) - { - Duration = TimeSpan.Zero; // Never burnt out - Burning = false; - Light = LightType.Circle225; - Weight = 20.0; - } - - public CandelabraStand(Serial serial) : base(serial) - { - } - - public override int LitItemID => 0xB26; - public override int UnlitItemID => 0xA29; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } + Duration = TimeSpan.Zero; // Never burnt out + Burning = false; + Light = LightType.Circle225; + Weight = 20.0; } + + public override int LitItemID => 0xB26; + public override int UnlitItemID => 0xA29; } diff --git a/Projects/UOContent/Items/Lights/Candle.cs b/Projects/UOContent/Items/Lights/Candle.cs index b38bcef4a..8ae12eb43 100644 --- a/Projects/UOContent/Items/Lights/Candle.cs +++ b/Projects/UOContent/Items/Lights/Candle.cs @@ -7,16 +7,10 @@ namespace Server.Items [Constructible] public Candle() : base(0xA28) { - if (Burnout) - { - Duration = TimeSpan.FromMinutes(20); - } - else - { - Duration = TimeSpan.Zero; - } - + Duration = Burnout ? TimeSpan.FromMinutes(20) : TimeSpan.Zero; Burning = false; + + Stackable = true; Light = LightType.Circle150; Weight = 1.0; } diff --git a/Projects/UOContent/Items/Lights/CandleLarge.cs b/Projects/UOContent/Items/Lights/CandleLarge.cs index 9cf17c014..12dfdf188 100644 --- a/Projects/UOContent/Items/Lights/CandleLarge.cs +++ b/Projects/UOContent/Items/Lights/CandleLarge.cs @@ -1,43 +1,21 @@ using System; +using ModernUO.Serialization; -namespace Server.Items +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class CandleLarge : BaseLight { - public class CandleLarge : BaseLight + [Constructible] + public CandleLarge() : base(0xA26) { - [Constructible] - public CandleLarge() : base(0xA26) - { - if (Burnout) - { - Duration = TimeSpan.FromMinutes(25); - } - else - { - Duration = TimeSpan.Zero; - } + Duration = Burnout ? TimeSpan.FromMinutes(25) : TimeSpan.Zero; - Burning = false; - Light = LightType.Circle150; - Weight = 2.0; - } - - public CandleLarge(Serial serial) : base(serial) - { - } - - public override int LitItemID => 0xB1A; - public override int UnlitItemID => 0xA26; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } + Burning = false; + Light = LightType.Circle150; + Weight = 2.0; } + + public override int LitItemID => 0xB1A; + public override int UnlitItemID => 0xA26; } diff --git a/Projects/UOContent/Items/Lights/CandleLong.cs b/Projects/UOContent/Items/Lights/CandleLong.cs index 540550be1..39daca623 100644 --- a/Projects/UOContent/Items/Lights/CandleLong.cs +++ b/Projects/UOContent/Items/Lights/CandleLong.cs @@ -1,43 +1,21 @@ using System; +using ModernUO.Serialization; -namespace Server.Items +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class CandleLong : BaseLight { - public class CandleLong : BaseLight + [Constructible] + public CandleLong() : base(0x1433) { - [Constructible] - public CandleLong() : base(0x1433) - { - if (Burnout) - { - Duration = TimeSpan.FromMinutes(30); - } - else - { - Duration = TimeSpan.Zero; - } + Duration = Burnout ? TimeSpan.FromMinutes(30) : TimeSpan.Zero; - Burning = false; - Light = LightType.Circle150; - Weight = 1.0; - } - - public CandleLong(Serial serial) : base(serial) - { - } - - public override int LitItemID => 0x1430; - public override int UnlitItemID => 0x1433; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } + Burning = false; + Light = LightType.Circle150; + Weight = 1.0; } + + public override int LitItemID => 0x1430; + public override int UnlitItemID => 0x1433; } diff --git a/Projects/UOContent/Items/Lights/CandleShort.cs b/Projects/UOContent/Items/Lights/CandleShort.cs index fd0826f5a..942478f35 100644 --- a/Projects/UOContent/Items/Lights/CandleShort.cs +++ b/Projects/UOContent/Items/Lights/CandleShort.cs @@ -1,43 +1,21 @@ using System; +using ModernUO.Serialization; -namespace Server.Items +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class CandleShort : BaseLight { - public class CandleShort : BaseLight + [Constructible] + public CandleShort() : base(0x142F) { - [Constructible] - public CandleShort() : base(0x142F) - { - if (Burnout) - { - Duration = TimeSpan.FromMinutes(25); - } - else - { - Duration = TimeSpan.Zero; - } + Duration = Burnout ? TimeSpan.FromMinutes(25) : TimeSpan.Zero; - Burning = false; - Light = LightType.Circle150; - Weight = 1.0; - } - - public CandleShort(Serial serial) : base(serial) - { - } - - public override int LitItemID => 0x142C; - public override int UnlitItemID => 0x142F; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } + Burning = false; + Light = LightType.Circle150; + Weight = 1.0; } + + public override int LitItemID => 0x142C; + public override int UnlitItemID => 0x142F; } diff --git a/Projects/UOContent/Items/Lights/CandleSkull.cs b/Projects/UOContent/Items/Lights/CandleSkull.cs index 049a426a3..8cd3a9f21 100644 --- a/Projects/UOContent/Items/Lights/CandleSkull.cs +++ b/Projects/UOContent/Items/Lights/CandleSkull.cs @@ -1,66 +1,22 @@ using System; +using ModernUO.Serialization; -namespace Server.Items +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class CandleSkull : BaseLight { - public class CandleSkull : BaseLight + [Constructible] + public CandleSkull() : base(0x1853) { - [Constructible] - public CandleSkull() : base(0x1853) - { - if (Burnout) - { - Duration = TimeSpan.FromMinutes(25); - } - else - { - Duration = TimeSpan.Zero; - } + Duration = Burnout ? TimeSpan.FromMinutes(25) : TimeSpan.Zero; - Burning = false; - Light = LightType.Circle150; - Weight = 5.0; - } - - public CandleSkull(Serial serial) : base(serial) - { - } - - public override int LitItemID - { - get - { - if (ItemID is 0x1583 or 0x1854) - { - return 0x1854; - } - - return 0x1858; - } - } - - public override int UnlitItemID - { - get - { - if (ItemID is 0x1853 or 0x1584) - { - return 0x1853; - } - - return 0x1857; - } - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } + Burning = false; + Light = LightType.Circle150; + Weight = 5.0; } + + public override int LitItemID => ItemID is 0x1583 or 0x1854 ? 0x1854 : 0x1858; + + public override int UnlitItemID => ItemID is 0x1853 or 0x1584 ? 0x1853 : 0x1857; } diff --git a/Projects/UOContent/Items/Lights/DarkSource.cs b/Projects/UOContent/Items/Lights/DarkSource.cs index 6cf443480..946a6bb12 100644 --- a/Projects/UOContent/Items/Lights/DarkSource.cs +++ b/Projects/UOContent/Items/Lights/DarkSource.cs @@ -1,28 +1,14 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class DarkSource : Item { - public class DarkSource : Item + [Constructible] + public DarkSource() : base(0x1646) { - [Constructible] - public DarkSource() : base(0x1646) - { - Layer = Layer.TwoHanded; - Movable = false; - } - - public DarkSource(Serial serial) : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } + Layer = Layer.TwoHanded; + Movable = false; } } diff --git a/Projects/UOContent/Items/Lights/HangingLantern.cs b/Projects/UOContent/Items/Lights/HangingLantern.cs index cf4e2fba1..1ae33dcf9 100644 --- a/Projects/UOContent/Items/Lights/HangingLantern.cs +++ b/Projects/UOContent/Items/Lights/HangingLantern.cs @@ -1,36 +1,21 @@ using System; +using ModernUO.Serialization; -namespace Server.Items +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class HangingLantern : BaseLight { - public class HangingLantern : BaseLight + [Constructible] + public HangingLantern() : base(0xA1D) { - [Constructible] - public HangingLantern() : base(0xA1D) - { - Movable = false; - Duration = TimeSpan.Zero; // Never burnt out - Burning = false; - Light = LightType.Circle300; - Weight = 40.0; - } - - public HangingLantern(Serial serial) : base(serial) - { - } - - public override int LitItemID => 0xA1A; - public override int UnlitItemID => 0xA1D; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } + Movable = false; + Duration = TimeSpan.Zero; // Never burnt out + Burning = false; + Light = LightType.Circle300; + Weight = 40.0; } + + public override int LitItemID => 0xA1A; + public override int UnlitItemID => 0xA1D; } diff --git a/Projects/UOContent/Items/Lights/HeatingStand.cs b/Projects/UOContent/Items/Lights/HeatingStand.cs index bfc55fcb1..1b1abe044 100644 --- a/Projects/UOContent/Items/Lights/HeatingStand.cs +++ b/Projects/UOContent/Items/Lights/HeatingStand.cs @@ -1,71 +1,49 @@ using System; +using ModernUO.Serialization; -namespace Server.Items +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class HeatingStand : BaseLight { - public class HeatingStand : BaseLight + [Constructible] + public HeatingStand() : base(0x1849) { - [Constructible] - public HeatingStand() : base(0x1849) - { - if (Burnout) - { - Duration = TimeSpan.FromMinutes(25); - } - else - { - Duration = TimeSpan.Zero; - } + Duration = Burnout ? TimeSpan.FromMinutes(25) : TimeSpan.Zero; - Burning = false; + Burning = false; + Light = LightType.Empty; + Weight = 1.0; + } + + public override int LitItemID => 0x184A; + public override int UnlitItemID => 0x1849; + + public override void Ignite() + { + base.Ignite(); + + if (ItemID == LitItemID) + { + Light = LightType.Circle150; + } + else if (ItemID == UnlitItemID) + { Light = LightType.Empty; - Weight = 1.0; } + } - public HeatingStand(Serial serial) : base(serial) + public override void Douse() + { + base.Douse(); + + if (ItemID == LitItemID) { + Light = LightType.Circle150; } - - public override int LitItemID => 0x184A; - public override int UnlitItemID => 0x1849; - - public override void Ignite() + else if (ItemID == UnlitItemID) { - base.Ignite(); - - if (ItemID == LitItemID) - { - Light = LightType.Circle150; - } - else if (ItemID == UnlitItemID) - { - Light = LightType.Empty; - } - } - - public override void Douse() - { - base.Douse(); - - if (ItemID == LitItemID) - { - Light = LightType.Circle150; - } - else if (ItemID == UnlitItemID) - { - Light = LightType.Empty; - } - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); + Light = LightType.Empty; } } } diff --git a/Projects/UOContent/Items/Lights/LampPost1.cs b/Projects/UOContent/Items/Lights/LampPost1.cs index 8d9c2bae0..985e6e7b1 100644 --- a/Projects/UOContent/Items/Lights/LampPost1.cs +++ b/Projects/UOContent/Items/Lights/LampPost1.cs @@ -1,36 +1,21 @@ using System; +using ModernUO.Serialization; -namespace Server.Items +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class LampPost1 : BaseLight { - public class LampPost1 : BaseLight + [Constructible] + public LampPost1() : base(0xB21) { - [Constructible] - public LampPost1() : base(0xB21) - { - Movable = false; - Duration = TimeSpan.Zero; // Never burnt out - Burning = false; - Light = LightType.Circle300; - Weight = 40.0; - } - - public LampPost1(Serial serial) : base(serial) - { - } - - public override int LitItemID => 0xB20; - public override int UnlitItemID => 0xB21; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } + Movable = false; + Duration = TimeSpan.Zero; // Never burnt out + Burning = false; + Light = LightType.Circle300; + Weight = 40.0; } + + public override int LitItemID => 0xB20; + public override int UnlitItemID => 0xB21; } diff --git a/Projects/UOContent/Items/Lights/LampPost2.cs b/Projects/UOContent/Items/Lights/LampPost2.cs index e041ea02d..f36bdf4db 100644 --- a/Projects/UOContent/Items/Lights/LampPost2.cs +++ b/Projects/UOContent/Items/Lights/LampPost2.cs @@ -1,36 +1,21 @@ using System; +using ModernUO.Serialization; -namespace Server.Items +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class LampPost2 : BaseLight { - public class LampPost2 : BaseLight + [Constructible] + public LampPost2() : base(0xB23) { - [Constructible] - public LampPost2() : base(0xB23) - { - Movable = false; - Duration = TimeSpan.Zero; // Never burnt out - Burning = false; - Light = LightType.Circle300; - Weight = 40.0; - } - - public LampPost2(Serial serial) : base(serial) - { - } - - public override int LitItemID => 0xB22; - public override int UnlitItemID => 0xB23; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } + Movable = false; + Duration = TimeSpan.Zero; // Never burnt out + Burning = false; + Light = LightType.Circle300; + Weight = 40.0; } + + public override int LitItemID => 0xB22; + public override int UnlitItemID => 0xB23; } diff --git a/Projects/UOContent/Items/Lights/LampPost3.cs b/Projects/UOContent/Items/Lights/LampPost3.cs index 16000c03b..c9cb237a0 100644 --- a/Projects/UOContent/Items/Lights/LampPost3.cs +++ b/Projects/UOContent/Items/Lights/LampPost3.cs @@ -1,36 +1,21 @@ using System; +using ModernUO.Serialization; -namespace Server.Items +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class LampPost3 : BaseLight { - public class LampPost3 : BaseLight + [Constructible] + public LampPost3() : base(0xb25) { - [Constructible] - public LampPost3() : base(0xb25) - { - Movable = false; - Duration = TimeSpan.Zero; // Never burnt out - Burning = false; - Light = LightType.Circle300; - Weight = 40.0; - } - - public LampPost3(Serial serial) : base(serial) - { - } - - public override int LitItemID => 0xB24; - public override int UnlitItemID => 0xB25; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } + Movable = false; + Duration = TimeSpan.Zero; // Never burnt out + Burning = false; + Light = LightType.Circle300; + Weight = 40.0; } + + public override int LitItemID => 0xB24; + public override int UnlitItemID => 0xB25; } diff --git a/Projects/UOContent/Items/Lights/Lantern.cs b/Projects/UOContent/Items/Lights/Lantern.cs index 50635bda3..df38a988c 100644 --- a/Projects/UOContent/Items/Lights/Lantern.cs +++ b/Projects/UOContent/Items/Lights/Lantern.cs @@ -7,14 +7,7 @@ namespace Server.Items [Constructible] public Lantern() : base(0xA25) { - if (Burnout) - { - Duration = TimeSpan.FromMinutes(20); - } - else - { - Duration = TimeSpan.Zero; - } + Duration = Burnout ? TimeSpan.FromMinutes(20) : TimeSpan.Zero; Burning = false; Light = LightType.Circle300; @@ -25,31 +18,9 @@ namespace Server.Items { } - public override int LitItemID - { - get - { - if (ItemID is 0xA15 or 0xA17) - { - return ItemID; - } + public override int LitItemID => ItemID is 0xA15 or 0xA17 ? ItemID : 0xA22; - return 0xA22; - } - } - - public override int UnlitItemID - { - get - { - if (ItemID == 0xA18) - { - return ItemID; - } - - return 0xA25; - } - } + public override int UnlitItemID => ItemID == 0xA18 ? ItemID : 0xA25; public override void Serialize(IGenericWriter writer) { diff --git a/Projects/UOContent/Items/Lights/LightSource.cs b/Projects/UOContent/Items/Lights/LightSource.cs index fb6061ae3..b3a9d1df4 100644 --- a/Projects/UOContent/Items/Lights/LightSource.cs +++ b/Projects/UOContent/Items/Lights/LightSource.cs @@ -1,28 +1,14 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class LightSource : Item { - public class LightSource : Item + [Constructible] + public LightSource() : base(0x1647) { - [Constructible] - public LightSource() : base(0x1647) - { - Layer = Layer.TwoHanded; - Movable = false; - } - - public LightSource(Serial serial) : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } + Layer = Layer.TwoHanded; + Movable = false; } } diff --git a/Projects/UOContent/Items/Lights/PaperLantern.cs b/Projects/UOContent/Items/Lights/PaperLantern.cs index eabaaa561..681bf7705 100644 --- a/Projects/UOContent/Items/Lights/PaperLantern.cs +++ b/Projects/UOContent/Items/Lights/PaperLantern.cs @@ -1,37 +1,22 @@ using System; +using ModernUO.Serialization; -namespace Server.Items +namespace Server.Items; + +[Flippable] +[SerializationGenerator(0, false)] +public partial class PaperLantern : BaseLight { - [Flippable] - public class PaperLantern : BaseLight + [Constructible] + public PaperLantern() : base(0x24BE) { - [Constructible] - public PaperLantern() : base(0x24BE) - { - Movable = true; - Duration = TimeSpan.Zero; // Never burnt out - Burning = false; - Light = LightType.Circle150; - Weight = 3.0; - } - - public PaperLantern(Serial serial) : base(serial) - { - } - - public override int LitItemID => 0x24BD; - public override int UnlitItemID => 0x24BE; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } + Movable = true; + Duration = TimeSpan.Zero; // Never burnt out + Burning = false; + Light = LightType.Circle150; + Weight = 3.0; } + + public override int LitItemID => 0x24BD; + public override int UnlitItemID => 0x24BE; } diff --git a/Projects/UOContent/Items/Lights/RedHangingLantern.cs b/Projects/UOContent/Items/Lights/RedHangingLantern.cs index 216fbd1be..3643c2e12 100644 --- a/Projects/UOContent/Items/Lights/RedHangingLantern.cs +++ b/Projects/UOContent/Items/Lights/RedHangingLantern.cs @@ -1,74 +1,37 @@ using System; +using ModernUO.Serialization; -namespace Server.Items +namespace Server.Items; + +[Flippable] +[SerializationGenerator(0, false)] +public partial class RedHangingLantern : BaseLight { - [Flippable] - public class RedHangingLantern : BaseLight + [Constructible] + public RedHangingLantern() : base(0x24C2) { - [Constructible] - public RedHangingLantern() : base(0x24C2) + Movable = true; + Duration = TimeSpan.Zero; // Never burnt out + Burning = false; + Light = LightType.Circle300; + Weight = 3.0; + } + + public override int LitItemID => ItemID == 0x24C2 ? 0x24C1 : 0x24C3; + + public override int UnlitItemID => ItemID == 0x24C1 ? 0x24C2 : 0x24C4; + + public void Flip() + { + Light = LightType.Circle300; + + ItemID = ItemID switch { - Movable = true; - Duration = TimeSpan.Zero; // Never burnt out - Burning = false; - Light = LightType.Circle300; - Weight = 3.0; - } - - public RedHangingLantern(Serial serial) : base(serial) - { - } - - public override int LitItemID - { - get - { - if (ItemID == 0x24C2) - { - return 0x24C1; - } - - return 0x24C3; - } - } - - public override int UnlitItemID - { - get - { - if (ItemID == 0x24C1) - { - return 0x24C2; - } - - return 0x24C4; - } - } - - public void Flip() - { - Light = LightType.Circle300; - - ItemID = ItemID switch - { - 0x24C2 => 0x24C4, - 0x24C1 => 0x24C3, - 0x24C4 => 0x24C2, - 0x24C3 => 0x24C1, - _ => ItemID - }; - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } + 0x24C2 => 0x24C4, + 0x24C1 => 0x24C3, + 0x24C4 => 0x24C2, + 0x24C3 => 0x24C1, + _ => ItemID + }; } } diff --git a/Projects/UOContent/Items/Lights/RoundPaperLantern.cs b/Projects/UOContent/Items/Lights/RoundPaperLantern.cs index 54c732995..3b028a0d3 100644 --- a/Projects/UOContent/Items/Lights/RoundPaperLantern.cs +++ b/Projects/UOContent/Items/Lights/RoundPaperLantern.cs @@ -1,37 +1,22 @@ using System; +using ModernUO.Serialization; -namespace Server.Items +namespace Server.Items; + +[Flippable] +[SerializationGenerator(0, false)] +public partial class RoundPaperLantern : BaseLight { - [Flippable] - public class RoundPaperLantern : BaseLight + [Constructible] + public RoundPaperLantern() : base(0x24CA) { - [Constructible] - public RoundPaperLantern() : base(0x24CA) - { - Movable = true; - Duration = TimeSpan.Zero; // Never burnt out - Burning = false; - Light = LightType.Circle150; - Weight = 3.0; - } - - public RoundPaperLantern(Serial serial) : base(serial) - { - } - - public override int LitItemID => 0x24C9; - public override int UnlitItemID => 0x24CA; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } + Movable = true; + Duration = TimeSpan.Zero; // Never burnt out + Burning = false; + Light = LightType.Circle150; + Weight = 3.0; } + + public override int LitItemID => 0x24C9; + public override int UnlitItemID => 0x24CA; } diff --git a/Projects/UOContent/Items/Lights/ShojiLantern.cs b/Projects/UOContent/Items/Lights/ShojiLantern.cs index 979566251..56aa5d81e 100644 --- a/Projects/UOContent/Items/Lights/ShojiLantern.cs +++ b/Projects/UOContent/Items/Lights/ShojiLantern.cs @@ -1,37 +1,22 @@ using System; +using ModernUO.Serialization; -namespace Server.Items +namespace Server.Items; + +[Flippable] +[SerializationGenerator(0, false)] +public partial class ShojiLantern : BaseLight { - [Flippable] - public class ShojiLantern : BaseLight + [Constructible] + public ShojiLantern() : base(0x24BC) { - [Constructible] - public ShojiLantern() : base(0x24BC) - { - Movable = true; - Duration = TimeSpan.Zero; // Never burnt out - Burning = false; - Light = LightType.Circle150; - Weight = 3.0; - } - - public ShojiLantern(Serial serial) : base(serial) - { - } - - public override int LitItemID => 0x24BB; - public override int UnlitItemID => 0x24BC; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } + Movable = true; + Duration = TimeSpan.Zero; // Never burnt out + Burning = false; + Light = LightType.Circle150; + Weight = 3.0; } + + public override int LitItemID => 0x24BB; + public override int UnlitItemID => 0x24BC; } diff --git a/Projects/UOContent/Items/Lights/Torch.cs b/Projects/UOContent/Items/Lights/Torch.cs index 8e4eecbf5..083d2ec55 100644 --- a/Projects/UOContent/Items/Lights/Torch.cs +++ b/Projects/UOContent/Items/Lights/Torch.cs @@ -8,16 +8,10 @@ namespace Server.Items [Constructible] public Torch() : base(0xF6B) { - if (Burnout) - { - Duration = TimeSpan.FromMinutes(30); - } - else - { - Duration = TimeSpan.Zero; - } - + Duration = Burnout ? TimeSpan.FromMinutes(30) : TimeSpan.Zero; Burning = false; + + Stackable = true; Light = LightType.Circle300; Weight = 1.0; } diff --git a/Projects/UOContent/Items/Lights/WallSconce.cs b/Projects/UOContent/Items/Lights/WallSconce.cs index 6967d91f0..3268efcaa 100644 --- a/Projects/UOContent/Items/Lights/WallSconce.cs +++ b/Projects/UOContent/Items/Lights/WallSconce.cs @@ -1,81 +1,42 @@ using System; +using ModernUO.Serialization; -namespace Server.Items +namespace Server.Items; + +[Flippable] +[SerializationGenerator(0, false)] +public partial class WallSconce : BaseLight { - [Flippable] - public class WallSconce : BaseLight + [Constructible] + public WallSconce() : base(0x9FB) { - [Constructible] - public WallSconce() : base(0x9FB) + Movable = false; + Duration = TimeSpan.Zero; // Never burnt out + Burning = false; + Light = LightType.WestBig; + Weight = 3.0; + } + + public override int LitItemID => ItemID == 0x9FB ? 0x9FD : 0xA02; + + public override int UnlitItemID => ItemID == 0x9FD ? 0x9FB : 0xA00; + + public void Flip() + { + Light = Light switch { - Movable = false; - Duration = TimeSpan.Zero; // Never burnt out - Burning = false; - Light = LightType.WestBig; - Weight = 3.0; - } + LightType.WestBig => LightType.NorthBig, + LightType.NorthBig => LightType.WestBig, + _ => Light + }; - public WallSconce(Serial serial) : base(serial) + ItemID = ItemID switch { - } - - public override int LitItemID - { - get - { - if (ItemID == 0x9FB) - { - return 0x9FD; - } - - return 0xA02; - } - } - - public override int UnlitItemID - { - get - { - if (ItemID == 0x9FD) - { - return 0x9FB; - } - - return 0xA00; - } - } - - public void Flip() - { - if (Light == LightType.WestBig) - { - Light = LightType.NorthBig; - } - else if (Light == LightType.NorthBig) - { - Light = LightType.WestBig; - } - - ItemID = ItemID switch - { - 0x9FB => 0xA00, - 0x9FD => 0xA02, - 0xA00 => 0x9FB, - 0xA02 => 0x9FD, - _ => ItemID - }; - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } + 0x9FB => 0xA00, + 0x9FD => 0xA02, + 0xA00 => 0x9FB, + 0xA02 => 0x9FD, + _ => ItemID + }; } } diff --git a/Projects/UOContent/Items/Lights/WallTorch.cs b/Projects/UOContent/Items/Lights/WallTorch.cs index 084ac8ce5..968b0bbae 100644 --- a/Projects/UOContent/Items/Lights/WallTorch.cs +++ b/Projects/UOContent/Items/Lights/WallTorch.cs @@ -1,81 +1,42 @@ using System; +using ModernUO.Serialization; -namespace Server.Items +namespace Server.Items; + +[Flippable] +[SerializationGenerator(0, false)] +public partial class WallTorch : BaseLight { - [Flippable] - public class WallTorch : BaseLight + [Constructible] + public WallTorch() : base(0xA05) { - [Constructible] - public WallTorch() : base(0xA05) + Movable = false; + Duration = TimeSpan.Zero; // Never burnt out + Burning = false; + Light = LightType.WestBig; + Weight = 3.0; + } + + public override int LitItemID => ItemID == 0xA05 ? 0xA07 : 0xA0C; + + public override int UnlitItemID => ItemID == 0xA07 ? 0xA05 : 0xA0A; + + public void Flip() + { + Light = Light switch { - Movable = false; - Duration = TimeSpan.Zero; // Never burnt out - Burning = false; - Light = LightType.WestBig; - Weight = 3.0; - } + LightType.WestBig => LightType.NorthBig, + LightType.NorthBig => LightType.WestBig, + _ => Light + }; - public WallTorch(Serial serial) : base(serial) + ItemID = ItemID switch { - } - - public override int LitItemID - { - get - { - if (ItemID == 0xA05) - { - return 0xA07; - } - - return 0xA0C; - } - } - - public override int UnlitItemID - { - get - { - if (ItemID == 0xA07) - { - return 0xA05; - } - - return 0xA0A; - } - } - - public void Flip() - { - if (Light == LightType.WestBig) - { - Light = LightType.NorthBig; - } - else if (Light == LightType.NorthBig) - { - Light = LightType.WestBig; - } - - ItemID = ItemID switch - { - 0xA05 => 0xA0A, - 0xA07 => 0xA0C, - 0xA0A => 0xA05, - 0xA0C => 0xA07, - _ => ItemID - }; - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } + 0xA05 => 0xA0A, + 0xA07 => 0xA0C, + 0xA0A => 0xA05, + 0xA0C => 0xA07, + _ => ItemID + }; } } diff --git a/Projects/UOContent/Items/Lights/WhiteHangingLantern.cs b/Projects/UOContent/Items/Lights/WhiteHangingLantern.cs index ee21e7458..7d62bde96 100644 --- a/Projects/UOContent/Items/Lights/WhiteHangingLantern.cs +++ b/Projects/UOContent/Items/Lights/WhiteHangingLantern.cs @@ -1,74 +1,37 @@ using System; +using ModernUO.Serialization; -namespace Server.Items +namespace Server.Items; + +[Flippable] +[SerializationGenerator(0, false)] +public partial class WhiteHangingLantern : BaseLight { - [Flippable] - public class WhiteHangingLantern : BaseLight + [Constructible] + public WhiteHangingLantern() : base(0x24C6) { - [Constructible] - public WhiteHangingLantern() : base(0x24C6) + Movable = true; + Duration = TimeSpan.Zero; // Never burnt out + Burning = false; + Light = LightType.Circle300; + Weight = 3.0; + } + + public override int LitItemID => ItemID == 0x24C6 ? 0x24C5 : 0x24C7; + + public override int UnlitItemID => ItemID == 0x24C5 ? 0x24C6 : 0x24C8; + + public void Flip() + { + Light = LightType.Circle300; + + ItemID = ItemID switch { - Movable = true; - Duration = TimeSpan.Zero; // Never burnt out - Burning = false; - Light = LightType.Circle300; - Weight = 3.0; - } - - public WhiteHangingLantern(Serial serial) : base(serial) - { - } - - public override int LitItemID - { - get - { - if (ItemID == 0x24C6) - { - return 0x24C5; - } - - return 0x24C7; - } - } - - public override int UnlitItemID - { - get - { - if (ItemID == 0x24C5) - { - return 0x24C6; - } - - return 0x24C8; - } - } - - public void Flip() - { - Light = LightType.Circle300; - - ItemID = ItemID switch - { - 0x24C6 => 0x24C8, - 0x24C5 => 0x24C7, - 0x24C8 => 0x24C6, - 0x24C7 => 0x24C5, - _ => ItemID - }; - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } + 0x24C6 => 0x24C8, + 0x24C5 => 0x24C7, + 0x24C8 => 0x24C6, + 0x24C7 => 0x24C5, + _ => ItemID + }; } } diff --git a/Projects/UOContent/Migrations/Server.Items.BaseEquipableLight.v0.json b/Projects/UOContent/Migrations/Server.Items.BaseEquipableLight.v0.json new file mode 100644 index 000000000..83e2e509b --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.BaseEquipableLight.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.BaseEquipableLight" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.BaseLight.v1.json b/Projects/UOContent/Migrations/Server.Items.BaseLight.v1.json new file mode 100644 index 000000000..ca43118d1 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.BaseLight.v1.json @@ -0,0 +1,43 @@ +{ + "version": 1, + "type": "Server.Items.BaseLight", + "properties": [ + { + "name": "BurntOut", + "type": "bool", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "Burning", + "type": "bool", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "Duration", + "type": "System.TimeSpan", + "rule": "PrimitiveTypeMigrationRule" + }, + { + "name": "Protected", + "type": "bool", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "BurnTimer", + "type": "Server.Timer", + "rule": "TimerMigrationRule", + "ruleArguments": [ + "@TimerDrift" + ] + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Brazier.v0.json b/Projects/UOContent/Migrations/Server.Items.Brazier.v0.json new file mode 100644 index 000000000..e241f90d9 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Brazier.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Brazier" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.BrazierTall.v0.json b/Projects/UOContent/Migrations/Server.Items.BrazierTall.v0.json new file mode 100644 index 000000000..f89dcfcdf --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.BrazierTall.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.BrazierTall" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Candelabra.v0.json b/Projects/UOContent/Migrations/Server.Items.Candelabra.v0.json new file mode 100644 index 000000000..8c30f6c7f --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Candelabra.v0.json @@ -0,0 +1,14 @@ +{ + "version": 0, + "type": "Server.Items.Candelabra", + "properties": [ + { + "name": "IsShipwreckedItem", + "type": "bool", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.CandelabraStand.v0.json b/Projects/UOContent/Migrations/Server.Items.CandelabraStand.v0.json new file mode 100644 index 000000000..f66380218 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.CandelabraStand.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.CandelabraStand" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.CandleLarge.v0.json b/Projects/UOContent/Migrations/Server.Items.CandleLarge.v0.json new file mode 100644 index 000000000..4a2b3da8d --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.CandleLarge.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.CandleLarge" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.CandleLong.v0.json b/Projects/UOContent/Migrations/Server.Items.CandleLong.v0.json new file mode 100644 index 000000000..2bf422d2e --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.CandleLong.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.CandleLong" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.CandleShort.v0.json b/Projects/UOContent/Migrations/Server.Items.CandleShort.v0.json new file mode 100644 index 000000000..9e7c7864c --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.CandleShort.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.CandleShort" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.CandleSkull.v0.json b/Projects/UOContent/Migrations/Server.Items.CandleSkull.v0.json new file mode 100644 index 000000000..28174b43d --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.CandleSkull.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.CandleSkull" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.DarkSource.v0.json b/Projects/UOContent/Migrations/Server.Items.DarkSource.v0.json new file mode 100644 index 000000000..1f66b7fa7 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.DarkSource.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.DarkSource" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.HangingLantern.v0.json b/Projects/UOContent/Migrations/Server.Items.HangingLantern.v0.json new file mode 100644 index 000000000..e356f97fb --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.HangingLantern.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.HangingLantern" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.HeatingStand.v0.json b/Projects/UOContent/Migrations/Server.Items.HeatingStand.v0.json new file mode 100644 index 000000000..256c5e950 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.HeatingStand.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.HeatingStand" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.LampPost1.v0.json b/Projects/UOContent/Migrations/Server.Items.LampPost1.v0.json new file mode 100644 index 000000000..a71ae5f05 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.LampPost1.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.LampPost1" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.LampPost2.v0.json b/Projects/UOContent/Migrations/Server.Items.LampPost2.v0.json new file mode 100644 index 000000000..3c6a06aa3 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.LampPost2.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.LampPost2" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.LampPost3.v0.json b/Projects/UOContent/Migrations/Server.Items.LampPost3.v0.json new file mode 100644 index 000000000..f31c4e975 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.LampPost3.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.LampPost3" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.LightSource.v0.json b/Projects/UOContent/Migrations/Server.Items.LightSource.v0.json new file mode 100644 index 000000000..dc3adc368 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.LightSource.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.LightSource" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.PaperLantern.v0.json b/Projects/UOContent/Migrations/Server.Items.PaperLantern.v0.json new file mode 100644 index 000000000..f06c1c07a --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.PaperLantern.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.PaperLantern" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.RedHangingLantern.v0.json b/Projects/UOContent/Migrations/Server.Items.RedHangingLantern.v0.json new file mode 100644 index 000000000..7e48a84f6 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.RedHangingLantern.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.RedHangingLantern" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.RoundPaperLantern.v0.json b/Projects/UOContent/Migrations/Server.Items.RoundPaperLantern.v0.json new file mode 100644 index 000000000..70715fb8f --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.RoundPaperLantern.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.RoundPaperLantern" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.ShojiLantern.v0.json b/Projects/UOContent/Migrations/Server.Items.ShojiLantern.v0.json new file mode 100644 index 000000000..68d7d19a0 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.ShojiLantern.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.ShojiLantern" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.WallSconce.v0.json b/Projects/UOContent/Migrations/Server.Items.WallSconce.v0.json new file mode 100644 index 000000000..d0283988d --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.WallSconce.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.WallSconce" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.WallTorch.v0.json b/Projects/UOContent/Migrations/Server.Items.WallTorch.v0.json new file mode 100644 index 000000000..f552e5e58 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.WallTorch.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.WallTorch" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.WhiteHangingLantern.v0.json b/Projects/UOContent/Migrations/Server.Items.WhiteHangingLantern.v0.json new file mode 100644 index 000000000..06213191a --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.WhiteHangingLantern.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.WhiteHangingLantern" +} \ No newline at end of file From 35689a395baf1628c822e64b6bf3f65ef8358f8c Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Fri, 17 Jun 2022 23:29:36 -0700 Subject: [PATCH 209/213] fix: Fixes codegenning sack of flour (#1076) --- .config/dotnet-tools.json | 2 +- Projects/Server/Server.csproj | 2 +- Projects/UOContent/Items/Food/Cooking.cs | 2 +- Projects/UOContent/UOContent.csproj | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 9a1e358ec..e5a7001db 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "modernuoschemagenerator": { - "version": "2.1.3", + "version": "2.1.4", "commands": [ "ModernUOSchemaGenerator" ] diff --git a/Projects/Server/Server.csproj b/Projects/Server/Server.csproj index 1b00238b0..bb8e91949 100755 --- a/Projects/Server/Server.csproj +++ b/Projects/Server/Server.csproj @@ -41,7 +41,7 @@ - + diff --git a/Projects/UOContent/Items/Food/Cooking.cs b/Projects/UOContent/Items/Food/Cooking.cs index 787a8334f..e665c490f 100644 --- a/Projects/UOContent/Items/Food/Cooking.cs +++ b/Projects/UOContent/Items/Food/Cooking.cs @@ -68,7 +68,7 @@ public partial class SackFlour : Item, IHasQuantity } [CommandProperty(AccessLevel.GameMaster)] - [SerializableField(1)] + [SerializableField(0)] public int Quantity { get => _quantity; diff --git a/Projects/UOContent/UOContent.csproj b/Projects/UOContent/UOContent.csproj index 4bc001e19..bd101f145 100755 --- a/Projects/UOContent/UOContent.csproj +++ b/Projects/UOContent/UOContent.csproj @@ -46,7 +46,7 @@ - + From 7a7637d2b58ba8b18e7ca8785ba57d49cc9e14fd Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Fri, 17 Jun 2022 23:54:33 -0700 Subject: [PATCH 210/213] fix: Fixes release workflow (#1077) --- .github/workflows/create-release.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml index b2d3a260a..7be14200d 100644 --- a/.github/workflows/create-release.yml +++ b/.github/workflows/create-release.yml @@ -31,7 +31,11 @@ jobs: git checkout ${{ steps.last_release.outputs.release }} git tag -fa v0.1.0 -m "Fake release" git checkout - - git push --follow-tags + - name: Push git changes + uses: ad-m/github-push-action@master + with: + GITHUB_TOKEN: ${{ secrets.WORKFLOW_TOKEN }} + tags: true - name: Conventional Changelog id: changelog uses: TriPSs/conventional-changelog-action@v3 @@ -56,7 +60,7 @@ jobs: delete_release: true tag_name: v0.1.0 env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ secrets.WORKFLOW_TOKEN }} - name: Create Release id: create_release uses: actions/create-release@v1 From 354f7e2f419be70ed6065978e3ba01673d85b0f5 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sat, 18 Jun 2022 08:39:44 -0700 Subject: [PATCH 211/213] fix: Codegens torches, candles, and lanterns (#1078) --- Projects/UOContent/Items/Lights/Candle.cs | 45 ++++------- Projects/UOContent/Items/Lights/Lantern.cs | 74 ++++++------------ Projects/UOContent/Items/Lights/Torch.cs | 88 +++++++++------------- 3 files changed, 71 insertions(+), 136 deletions(-) diff --git a/Projects/UOContent/Items/Lights/Candle.cs b/Projects/UOContent/Items/Lights/Candle.cs index 8ae12eb43..99ff0e46a 100644 --- a/Projects/UOContent/Items/Lights/Candle.cs +++ b/Projects/UOContent/Items/Lights/Candle.cs @@ -1,37 +1,22 @@ using System; +using ModernUO.Serialization; -namespace Server.Items +namespace Server.Items; + +[SerializationGenerator(0)] +public partial class Candle : BaseEquipableLight { - public class Candle : BaseEquipableLight + [Constructible] + public Candle() : base(0xA28) { - [Constructible] - public Candle() : base(0xA28) - { - Duration = Burnout ? TimeSpan.FromMinutes(20) : TimeSpan.Zero; - Burning = false; + Duration = Burnout ? TimeSpan.FromMinutes(20) : TimeSpan.Zero; + Burning = false; - Stackable = true; - Light = LightType.Circle150; - Weight = 1.0; - } - - public Candle(Serial serial) : base(serial) - { - } - - public override int LitItemID => 0xA0F; - public override int UnlitItemID => 0xA28; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } + Stackable = true; + Light = LightType.Circle150; + Weight = 1.0; } + + public override int LitItemID => 0xA0F; + public override int UnlitItemID => 0xA28; } diff --git a/Projects/UOContent/Items/Lights/Lantern.cs b/Projects/UOContent/Items/Lights/Lantern.cs index df38a988c..14e1a8fec 100644 --- a/Projects/UOContent/Items/Lights/Lantern.cs +++ b/Projects/UOContent/Items/Lights/Lantern.cs @@ -1,61 +1,31 @@ using System; +using ModernUO.Serialization; -namespace Server.Items +namespace Server.Items; + +[SerializationGenerator(0)] +public partial class Lantern : BaseEquipableLight { - public class Lantern : BaseEquipableLight + [Constructible] + public Lantern() : base(0xA25) { - [Constructible] - public Lantern() : base(0xA25) - { - Duration = Burnout ? TimeSpan.FromMinutes(20) : TimeSpan.Zero; + Duration = Burnout ? TimeSpan.FromMinutes(20) : TimeSpan.Zero; - Burning = false; - Light = LightType.Circle300; - Weight = 2.0; - } - - public Lantern(Serial serial) : base(serial) - { - } - - public override int LitItemID => ItemID is 0xA15 or 0xA17 ? ItemID : 0xA22; - - public override int UnlitItemID => ItemID == 0xA18 ? ItemID : 0xA25; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } + Burning = false; + Light = LightType.Circle300; + Weight = 2.0; } - public class LanternOfSouls : Lantern - { - [Constructible] - public LanternOfSouls() => Hue = 0x482; + public override int LitItemID => ItemID is 0xA15 or 0xA17 ? ItemID : 0xA22; - public LanternOfSouls(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1061618; // Lantern of Souls - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } - } + public override int UnlitItemID => ItemID == 0xA18 ? ItemID : 0xA25; +} + +[SerializationGenerator(0)] +public partial class LanternOfSouls : Lantern +{ + [Constructible] + public LanternOfSouls() => Hue = 0x482; + + public override int LabelNumber => 1061618; // Lantern of Souls } diff --git a/Projects/UOContent/Items/Lights/Torch.cs b/Projects/UOContent/Items/Lights/Torch.cs index 083d2ec55..75c5f0967 100644 --- a/Projects/UOContent/Items/Lights/Torch.cs +++ b/Projects/UOContent/Items/Lights/Torch.cs @@ -1,66 +1,46 @@ using System; +using ModernUO.Serialization; using Server.Mobiles; -namespace Server.Items +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class Torch : BaseEquipableLight { - public class Torch : BaseEquipableLight + [Constructible] + public Torch() : base(0xF6B) { - [Constructible] - public Torch() : base(0xF6B) - { - Duration = Burnout ? TimeSpan.FromMinutes(30) : TimeSpan.Zero; - Burning = false; + Duration = Burnout ? TimeSpan.FromMinutes(30) : TimeSpan.Zero; + Burning = false; - Stackable = true; - Light = LightType.Circle300; - Weight = 1.0; + Stackable = true; + Light = LightType.Circle300; + Weight = 1.0; + } + + public override int LitItemID => 0xA12; + public override int UnlitItemID => 0xF6B; + + public override int LitSound => 0x54; + public override int UnlitSound => 0x4BB; + + public override void OnAdded(IEntity parent) + { + base.OnAdded(parent); + + if (parent is Mobile mobile && Burning) + { + MeerMage.StopEffect(mobile, true); } + } - public Torch(Serial serial) : base(serial) + public override void Ignite() + { + base.Ignite(); + + if (Parent is Mobile mobile && Burning) { - } - - public override int LitItemID => 0xA12; - public override int UnlitItemID => 0xF6B; - - public override int LitSound => 0x54; - public override int UnlitSound => 0x4BB; - - public override void OnAdded(IEntity parent) - { - base.OnAdded(parent); - - if (parent is Mobile mobile && Burning) - { - MeerMage.StopEffect(mobile, true); - } - } - - public override void Ignite() - { - base.Ignite(); - - if (Parent is Mobile mobile && Burning) - { - MeerMage.StopEffect(mobile, true); - } - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - - if (Weight == 2.0) - { - Weight = 1.0; - } + MeerMage.StopEffect(mobile, true); } } } From dc7033d71f1207e8e3a7ff49f28d099d6a31a324 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sat, 18 Jun 2022 16:09:02 -0700 Subject: [PATCH 212/213] fix: Fixes candle serialization (#1081) --- Projects/UOContent/Items/Lights/Candle.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Projects/UOContent/Items/Lights/Candle.cs b/Projects/UOContent/Items/Lights/Candle.cs index 99ff0e46a..f0d5bd42e 100644 --- a/Projects/UOContent/Items/Lights/Candle.cs +++ b/Projects/UOContent/Items/Lights/Candle.cs @@ -3,7 +3,7 @@ using ModernUO.Serialization; namespace Server.Items; -[SerializationGenerator(0)] +[SerializationGenerator(0, false)] public partial class Candle : BaseEquipableLight { [Constructible] From 7adf52ef48df7ae2b034c27e67b0c332b37fb053 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sat, 18 Jun 2022 21:28:51 -0700 Subject: [PATCH 213/213] fix: Moves mods and fixes migrations for lights (#1080) - [X] Removes duplicate property for owner. - [X] Codegens them all (even though they aren't used, just in case someone wants to). --- .../Migrations/Server.DefaultSkillMod.v0.json | 4 + .../Server.EquippedSkillMod.v0.json | 11 + .../Migrations/Server.MobileMod.v0.json | 4 + .../Migrations/Server.ResistanceMod.v0.json | 19 ++ .../Server/Migrations/Server.SkillMod.v0.json | 43 ++++ .../Server/Migrations/Server.StatMod.v0.json | 40 ++++ .../Migrations/Server.TimedSkillMod.v0.json | 14 ++ Projects/Server/Mobiles/Mobile.cs | 218 ------------------ .../Server/Mobiles/Mods/DefaultSkillMod.cs | 32 +++ .../Server/Mobiles/Mods/EquippedSkillMod.cs | 34 +++ Projects/Server/Mobiles/Mods/MobileMod.cs | 27 +++ Projects/Server/Mobiles/Mods/ResistanceMod.cs | 70 ++++++ Projects/Server/Mobiles/Mods/SkillMod.cs | 146 ++++++++++++ Projects/Server/Mobiles/Mods/StatMod.cs | 53 +++++ Projects/Server/Mobiles/Mods/TimedSkillMod.cs | 40 ++++ .../Serialization/ISerializableExtensions.cs | 5 +- .../Migrations/Server.Items.Candle.v0.json | 4 + .../Migrations/Server.Items.Lantern.v0.json | 4 + .../Server.Items.LanternOfSouls.v0.json | 4 + .../Migrations/Server.Items.Torch.v0.json | 4 + 20 files changed, 557 insertions(+), 219 deletions(-) create mode 100644 Projects/Server/Migrations/Server.DefaultSkillMod.v0.json create mode 100644 Projects/Server/Migrations/Server.EquippedSkillMod.v0.json create mode 100644 Projects/Server/Migrations/Server.MobileMod.v0.json create mode 100644 Projects/Server/Migrations/Server.ResistanceMod.v0.json create mode 100644 Projects/Server/Migrations/Server.SkillMod.v0.json create mode 100644 Projects/Server/Migrations/Server.StatMod.v0.json create mode 100644 Projects/Server/Migrations/Server.TimedSkillMod.v0.json create mode 100644 Projects/Server/Mobiles/Mods/DefaultSkillMod.cs create mode 100644 Projects/Server/Mobiles/Mods/EquippedSkillMod.cs create mode 100644 Projects/Server/Mobiles/Mods/MobileMod.cs create mode 100644 Projects/Server/Mobiles/Mods/ResistanceMod.cs create mode 100644 Projects/Server/Mobiles/Mods/SkillMod.cs create mode 100644 Projects/Server/Mobiles/Mods/StatMod.cs create mode 100644 Projects/Server/Mobiles/Mods/TimedSkillMod.cs create mode 100644 Projects/UOContent/Migrations/Server.Items.Candle.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Lantern.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.LanternOfSouls.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.Torch.v0.json diff --git a/Projects/Server/Migrations/Server.DefaultSkillMod.v0.json b/Projects/Server/Migrations/Server.DefaultSkillMod.v0.json new file mode 100644 index 000000000..846a99051 --- /dev/null +++ b/Projects/Server/Migrations/Server.DefaultSkillMod.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.DefaultSkillMod" +} \ No newline at end of file diff --git a/Projects/Server/Migrations/Server.EquippedSkillMod.v0.json b/Projects/Server/Migrations/Server.EquippedSkillMod.v0.json new file mode 100644 index 000000000..e1761685f --- /dev/null +++ b/Projects/Server/Migrations/Server.EquippedSkillMod.v0.json @@ -0,0 +1,11 @@ +{ + "version": 0, + "type": "Server.EquippedSkillMod", + "properties": [ + { + "name": "Item", + "type": "Server.Item", + "rule": "SerializableInterfaceMigrationRule" + } + ] +} \ No newline at end of file diff --git a/Projects/Server/Migrations/Server.MobileMod.v0.json b/Projects/Server/Migrations/Server.MobileMod.v0.json new file mode 100644 index 000000000..5e9c66631 --- /dev/null +++ b/Projects/Server/Migrations/Server.MobileMod.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.MobileMod" +} \ No newline at end of file diff --git a/Projects/Server/Migrations/Server.ResistanceMod.v0.json b/Projects/Server/Migrations/Server.ResistanceMod.v0.json new file mode 100644 index 000000000..b2d027d5f --- /dev/null +++ b/Projects/Server/Migrations/Server.ResistanceMod.v0.json @@ -0,0 +1,19 @@ +{ + "version": 0, + "type": "Server.ResistanceMod", + "properties": [ + { + "name": "Type", + "type": "Server.ResistanceType", + "rule": "EnumMigrationRule" + }, + { + "name": "Offset", + "type": "int", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + } + ] +} \ No newline at end of file diff --git a/Projects/Server/Migrations/Server.SkillMod.v0.json b/Projects/Server/Migrations/Server.SkillMod.v0.json new file mode 100644 index 000000000..174c434c2 --- /dev/null +++ b/Projects/Server/Migrations/Server.SkillMod.v0.json @@ -0,0 +1,43 @@ +{ + "version": 0, + "type": "Server.SkillMod", + "properties": [ + { + "name": "ObeyCap", + "type": "bool", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "Skill", + "type": "Server.SkillName", + "rule": "EnumMigrationRule" + }, + { + "name": "Relative", + "type": "bool", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "Absolute", + "type": "bool", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "Value", + "type": "double", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + } + ] +} \ No newline at end of file diff --git a/Projects/Server/Migrations/Server.StatMod.v0.json b/Projects/Server/Migrations/Server.StatMod.v0.json new file mode 100644 index 000000000..5b3b28174 --- /dev/null +++ b/Projects/Server/Migrations/Server.StatMod.v0.json @@ -0,0 +1,40 @@ +{ + "version": 0, + "type": "Server.StatMod", + "properties": [ + { + "name": "Added", + "type": "System.DateTime", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "Duration", + "type": "System.TimeSpan", + "rule": "PrimitiveTypeMigrationRule" + }, + { + "name": "Type", + "type": "Server.StatType", + "rule": "EnumMigrationRule" + }, + { + "name": "Name", + "type": "string", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "Offset", + "type": "int", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + } + ] +} \ No newline at end of file diff --git a/Projects/Server/Migrations/Server.TimedSkillMod.v0.json b/Projects/Server/Migrations/Server.TimedSkillMod.v0.json new file mode 100644 index 000000000..d1c4b0296 --- /dev/null +++ b/Projects/Server/Migrations/Server.TimedSkillMod.v0.json @@ -0,0 +1,14 @@ +{ + "version": 0, + "type": "Server.TimedSkillMod", + "properties": [ + { + "name": "Expire", + "type": "System.DateTime", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + } + ] +} \ No newline at end of file diff --git a/Projects/Server/Mobiles/Mobile.cs b/Projects/Server/Mobiles/Mobile.cs index c811926af..2677a6051 100644 --- a/Projects/Server/Mobiles/Mobile.cs +++ b/Projects/Server/Mobiles/Mobile.cs @@ -27,224 +27,6 @@ namespace Server public delegate void PromptStateCallback(Mobile from, string text, T state); - public class TimedSkillMod : SkillMod - { - private readonly DateTime m_Expire; - - public TimedSkillMod(SkillName skill, bool relative, double value, TimeSpan delay) - : this(skill, relative, value, Core.Now + delay) - { - } - - public TimedSkillMod(SkillName skill, bool relative, double value, DateTime expire) - : base(skill, relative, value) => - m_Expire = expire; - - public override bool CheckCondition() => Core.Now < m_Expire; - } - - public class EquippedSkillMod : SkillMod - { - private readonly Item m_Item; - private readonly Mobile m_Mobile; - - public EquippedSkillMod(SkillName skill, bool relative, double value, Item item, Mobile mobile) - : base(skill, relative, value) - { - m_Item = item; - m_Mobile = mobile; - } - - public override bool CheckCondition() => !m_Item.Deleted && !m_Mobile.Deleted && m_Item.Parent == m_Mobile; - } - - public class DefaultSkillMod : SkillMod - { - public DefaultSkillMod(SkillName skill, bool relative, double value) - : base(skill, relative, value) - { - } - - public override bool CheckCondition() => true; - } - - public abstract class SkillMod - { - private bool m_ObeyCap; - private Mobile m_Owner; - private bool m_Relative; - private SkillName m_Skill; - private double m_Value; - - protected SkillMod(SkillName skill, bool relative, double value) - { - m_Skill = skill; - m_Relative = relative; - m_Value = value; - } - - public bool ObeyCap - { - get => m_ObeyCap; - set - { - m_ObeyCap = value; - - var sk = m_Owner?.Skills[m_Skill]; - sk?.Update(); - } - } - - public Mobile Owner - { - get => m_Owner; - set - { - if (m_Owner != value) - { - m_Owner?.RemoveSkillMod(this); - m_Owner = value; - m_Owner?.AddSkillMod(this); - } - } - } - - public SkillName Skill - { - get => m_Skill; - set - { - if (m_Skill != value) - { - var oldUpdate = m_Owner?.Skills[m_Skill]; - - m_Skill = value; - - var sk = m_Owner?.Skills[m_Skill]; - sk?.Update(); - oldUpdate?.Update(); - } - } - } - - public bool Relative - { - get => m_Relative; - set - { - if (m_Relative != value) - { - m_Relative = value; - - var sk = m_Owner?.Skills[m_Skill]; - sk?.Update(); - } - } - } - - public bool Absolute - { - get => !m_Relative; - set - { - if (m_Relative == value) - { - m_Relative = !value; - - var sk = m_Owner?.Skills[m_Skill]; - sk?.Update(); - } - } - } - - public double Value - { - get => m_Value; - set - { - if (m_Value != value) - { - m_Value = value; - - var sk = m_Owner?.Skills[m_Skill]; - sk?.Update(); - } - } - } - - public void Remove() - { - Owner = null; - } - - public abstract bool CheckCondition(); - } - - public class ResistanceMod - { - private int m_Offset; - private ResistanceType m_Type; - - public ResistanceMod(ResistanceType type, int offset) - { - m_Type = type; - m_Offset = offset; - } - - public Mobile Owner { get; set; } - - public ResistanceType Type - { - get => m_Type; - set - { - if (m_Type != value) - { - m_Type = value; - - Owner?.UpdateResistances(); - } - } - } - - public int Offset - { - get => m_Offset; - set - { - if (m_Offset != value) - { - m_Offset = value; - - Owner?.UpdateResistances(); - } - } - } - } - - public class StatMod - { - private readonly DateTime m_Added; - private readonly TimeSpan m_Duration; - - public StatMod(StatType type, string name, int offset, TimeSpan duration) - { - Type = type; - Name = name; - Offset = offset; - m_Duration = duration; - m_Added = Core.Now; - } - - public StatType Type { get; } - - public string Name { get; } - - public int Offset { get; } - - public bool HasElapsed() => m_Duration != TimeSpan.Zero && Core.Now - m_Added >= m_Duration; - } - public class DamageEntry { public DamageEntry(Mobile damager) => Damager = damager; diff --git a/Projects/Server/Mobiles/Mods/DefaultSkillMod.cs b/Projects/Server/Mobiles/Mods/DefaultSkillMod.cs new file mode 100644 index 000000000..578cf2cb5 --- /dev/null +++ b/Projects/Server/Mobiles/Mods/DefaultSkillMod.cs @@ -0,0 +1,32 @@ +/************************************************************************* + * ModernUO * + * Copyright 2019-2022 - ModernUO Development Team * + * Email: hi@modernuo.com * + * File: DefaultSkillMod.cs * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + +using ModernUO.Serialization; + +namespace Server; + +[SerializationGenerator(0)] +public partial class DefaultSkillMod : SkillMod +{ + public DefaultSkillMod(Mobile owner) : base(owner) + { + } + + public DefaultSkillMod(SkillName skill, bool relative, double value) : base(skill, relative, value) + { + } + + public override bool CheckCondition() => true; +} diff --git a/Projects/Server/Mobiles/Mods/EquippedSkillMod.cs b/Projects/Server/Mobiles/Mods/EquippedSkillMod.cs new file mode 100644 index 000000000..101a19681 --- /dev/null +++ b/Projects/Server/Mobiles/Mods/EquippedSkillMod.cs @@ -0,0 +1,34 @@ +/************************************************************************* + * ModernUO * + * Copyright 2019-2022 - ModernUO Development Team * + * Email: hi@modernuo.com * + * File: EquippedSkillMod.cs * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + +using ModernUO.Serialization; + +namespace Server; + +[SerializationGenerator(0)] +public partial class EquippedSkillMod : SkillMod +{ + [SerializableField(0)] + private Item _item; + + public EquippedSkillMod(Mobile owner) : base(owner) + { + } + + public EquippedSkillMod(SkillName skill, bool relative, double value, Item item, Mobile mobile) + : base(skill, relative, value, mobile) => _item = item; + + public override bool CheckCondition() => !_item.Deleted && Owner?.Deleted == false && _item.Parent == Owner; +} diff --git a/Projects/Server/Mobiles/Mods/MobileMod.cs b/Projects/Server/Mobiles/Mods/MobileMod.cs new file mode 100644 index 000000000..be1083c0d --- /dev/null +++ b/Projects/Server/Mobiles/Mods/MobileMod.cs @@ -0,0 +1,27 @@ +/************************************************************************* + * ModernUO * + * Copyright 2019-2022 - ModernUO Development Team * + * Email: hi@modernuo.com * + * File: MobileMod.cs * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + +using ModernUO.Serialization; + +namespace Server; + +[SerializationGenerator(0)] +public partial class MobileMod +{ + [DirtyTrackingEntity] + public virtual Mobile Owner { get; set; } + + public MobileMod(Mobile owner) => Owner = owner; +} diff --git a/Projects/Server/Mobiles/Mods/ResistanceMod.cs b/Projects/Server/Mobiles/Mods/ResistanceMod.cs new file mode 100644 index 000000000..8b14cc1a5 --- /dev/null +++ b/Projects/Server/Mobiles/Mods/ResistanceMod.cs @@ -0,0 +1,70 @@ +/************************************************************************* + * ModernUO * + * Copyright 2019-2022 - ModernUO Development Team * + * Email: hi@modernuo.com * + * File: ResistanceMod.cs * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + +using ModernUO.Serialization; + +namespace Server; + +[SerializationGenerator(0)] +public partial class ResistanceMod : MobileMod +{ + // Field 0 + private int _offset; + + // Field 1 + private ResistanceType _type; + + public ResistanceMod(Mobile owner) : base(owner) + { + } + + public ResistanceMod(ResistanceType type, int offset, Mobile owner = null) : base(owner) + { + _type = type; + _offset = offset; + } + + [SerializableField(0)] + public ResistanceType Type + { + get => _type; + set + { + if (_type != value) + { + _type = value; + + Owner?.UpdateResistances(); + MarkDirty(); + } + } + } + + [SerializableField(1)] + public int Offset + { + get => _offset; + set + { + if (_offset != value) + { + _offset = value; + + Owner?.UpdateResistances(); + MarkDirty(); + } + } + } +} diff --git a/Projects/Server/Mobiles/Mods/SkillMod.cs b/Projects/Server/Mobiles/Mods/SkillMod.cs new file mode 100644 index 000000000..a30f29ad1 --- /dev/null +++ b/Projects/Server/Mobiles/Mods/SkillMod.cs @@ -0,0 +1,146 @@ +/************************************************************************* + * ModernUO * + * Copyright 2019-2022 - ModernUO Development Team * + * Email: hi@modernuo.com * + * File: SkillMod.cs * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + +using ModernUO.Serialization; + +namespace Server; + +[SerializationGenerator(0)] +public abstract partial class SkillMod : MobileMod +{ + private bool _obeyCap; + + private bool _relative; + private SkillName _skill; + private double _value; + + public SkillMod(Mobile owner) : base(owner) + { + } + + public SkillMod(SkillName skill, bool relative, double value, Mobile owner = null) : base(owner) + { + _skill = skill; + _relative = relative; + _value = value; + } + + [SerializableField(0)] + public bool ObeyCap + { + get => _obeyCap; + set + { + _obeyCap = value; + + var sk = Owner?.Skills[_skill]; + sk?.Update(); + MarkDirty(); + } + } + + public override Mobile Owner + { + get => base.Owner; + set + { + var owner = base.Owner; + if (owner != value) + { + owner?.RemoveSkillMod(this); + owner = value; + owner?.AddSkillMod(this); + } + } + } + + [SerializableField(1)] + public SkillName Skill + { + get => _skill; + set + { + if (_skill != value) + { + var oldUpdate = Owner?.Skills[_skill]; + + _skill = value; + + var sk = Owner?.Skills[_skill]; + sk?.Update(); + oldUpdate?.Update(); + MarkDirty(); + } + } + } + + [SerializableField(2)] + public bool Relative + { + get => _relative; + set + { + if (_relative != value) + { + _relative = value; + + var sk = Owner?.Skills[_skill]; + sk?.Update(); + MarkDirty(); + } + } + } + + [SerializableField(3)] + public bool Absolute + { + get => !_relative; + set + { + if (_relative == value) + { + _relative = !value; + + var sk = Owner?.Skills[_skill]; + sk?.Update(); + MarkDirty(); + } + } + } + + [SerializableField(4)] + public double Value + { + get => _value; + set + { + if (_value != value) + { + _value = value; + + var sk = Owner?.Skills[_skill]; + sk?.Update(); + MarkDirty(); + } + } + } + + public void Remove() + { + Owner = null; + } + + public abstract bool CheckCondition(); +} diff --git a/Projects/Server/Mobiles/Mods/StatMod.cs b/Projects/Server/Mobiles/Mods/StatMod.cs new file mode 100644 index 000000000..d92067368 --- /dev/null +++ b/Projects/Server/Mobiles/Mods/StatMod.cs @@ -0,0 +1,53 @@ +/************************************************************************* + * ModernUO * + * Copyright 2019-2022 - ModernUO Development Team * + * Email: hi@modernuo.com * + * File: StatMod.cs * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + +using System; +using ModernUO.Serialization; + +namespace Server; + +[SerializationGenerator(0)] +public partial class StatMod : MobileMod +{ + [SerializableField(0, getter: "private", setter: "private")] + private DateTime _added; + + [SerializableField(1, getter: "private", setter: "private")] + private TimeSpan _duration; + + [SerializableField(2, setter: "private")] + private StatType _type; + + [SerializableField(3, setter: "private")] + private string _name; + + [SerializableField(4, setter: "private")] + private int _offset; + + public StatMod(Mobile owner) : base(owner) + { + } + + public StatMod(StatType type, string name, int offset, TimeSpan duration, Mobile owner = null) : base(owner) + { + _type = type; + _name = name; + _offset = offset; + _duration = duration; + _added = Core.Now; + } + + public bool HasElapsed() => _duration != TimeSpan.Zero && Core.Now - _added >= _duration; +} diff --git a/Projects/Server/Mobiles/Mods/TimedSkillMod.cs b/Projects/Server/Mobiles/Mods/TimedSkillMod.cs new file mode 100644 index 000000000..388e79c0e --- /dev/null +++ b/Projects/Server/Mobiles/Mods/TimedSkillMod.cs @@ -0,0 +1,40 @@ +/************************************************************************* + * ModernUO * + * Copyright 2019-2022 - ModernUO Development Team * + * Email: hi@modernuo.com * + * File: TimedSkillMod.cs * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + +using System; +using ModernUO.Serialization; + +namespace Server; + +[SerializationGenerator(0)] +public partial class TimedSkillMod : SkillMod +{ + [SerializableField(0, setter: "private")] + private DateTime _expire; + + public TimedSkillMod(Mobile owner) : base(owner) + { + } + + public TimedSkillMod(SkillName skill, bool relative, double value, TimeSpan delay) + : this(skill, relative, value, Core.Now + delay) + { + } + + public TimedSkillMod(SkillName skill, bool relative, double value, DateTime expire) + : base(skill, relative, value) => _expire = expire; + + public override bool CheckCondition() => Core.Now < _expire; +} diff --git a/Projects/Server/Serialization/ISerializableExtensions.cs b/Projects/Server/Serialization/ISerializableExtensions.cs index b98b239ef..15ecb4f1c 100644 --- a/Projects/Server/Serialization/ISerializableExtensions.cs +++ b/Projects/Server/Serialization/ISerializableExtensions.cs @@ -24,7 +24,10 @@ namespace Server [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void MarkDirty(this ISerializable entity) { - entity.SavePosition = -1; + if (entity != null) + { + entity.SavePosition = -1; + } } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/Projects/UOContent/Migrations/Server.Items.Candle.v0.json b/Projects/UOContent/Migrations/Server.Items.Candle.v0.json new file mode 100644 index 000000000..fa8c3c662 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Candle.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Candle" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Lantern.v0.json b/Projects/UOContent/Migrations/Server.Items.Lantern.v0.json new file mode 100644 index 000000000..98dd8da0b --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Lantern.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Lantern" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.LanternOfSouls.v0.json b/Projects/UOContent/Migrations/Server.Items.LanternOfSouls.v0.json new file mode 100644 index 000000000..aeede5b0e --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.LanternOfSouls.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.LanternOfSouls" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Torch.v0.json b/Projects/UOContent/Migrations/Server.Items.Torch.v0.json new file mode 100644 index 000000000..d1ed7780a --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Torch.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Torch" +} \ No newline at end of file