From 7dbfa086bc000c26b935d70f94190e98eea8d7e6 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sat, 12 Sep 2020 01:57:07 -0700 Subject: [PATCH] Cleanup and adds configuration for crashguard (#240) --- Projects/Server/Main.cs | 2 - Projects/Server/Network/NetState.cs | 2 +- .../Accounting/AccountAttackLimiter.cs | 28 +- .../UOContent/Engines/Ethics/Core/Ethic.cs | 59 +- .../Engines/Factions/Items/TownStone.cs | 2 +- .../Engines/MLQuests/MLQuestSystem.cs | 134 +++- .../UOContent/Engines/Party/AddPartyTarget.cs | 16 +- .../UOContent/Engines/Pathing/PathFollower.cs | 2 +- .../UOContent/Engines/Plants/PlantItem.cs | 4 +- .../The Summoning/Items/BellOfTheDead.cs | 2 +- .../Engines/VeteranRewards/RewardSystem.cs | 62 +- Projects/UOContent/Gumps/WhoGump.cs | 2 +- .../UOContent/Items/Containers/Container.cs | 2 +- .../UOContent/Items/Containers/SalvageBag.cs | 4 +- Projects/UOContent/Items/Games/BaseBoard.cs | 8 +- Projects/UOContent/Items/Guilds/Guildstone.cs | 2 +- Projects/UOContent/Items/Misc/Moonstone.cs | 2 +- Projects/UOContent/Items/Misc/Scales.cs | 2 +- .../Skill Items/Magical/Misc/Moongate.cs | 4 +- .../Explosion Potions/BaseExplosionPotion.cs | 4 +- .../Items/Skill Items/Misc/FireHorn.cs | 2 +- .../Blacksmithy/PowderOfTemperament.cs | 2 +- Projects/UOContent/Misc/AOS.cs | 128 ++- Projects/UOContent/Misc/BuffIcons.cs | 17 +- Projects/UOContent/Misc/ClientVerification.cs | 25 +- Projects/UOContent/Misc/CrashGuard.cs | 17 +- Projects/UOContent/Misc/Email.cs | 17 +- Projects/UOContent/Misc/Emitter.cs | 12 +- Projects/UOContent/Misc/Notoriety.cs | 4 +- Projects/UOContent/Misc/RegenRates.cs | 4 +- Projects/UOContent/Misc/ServerList.cs | 17 +- Projects/UOContent/Misc/SkillCheck.cs | 2 +- Projects/UOContent/Misc/uoamVendors.cs | 2 - .../Mobiles/Animals/Mounts/BaseMount.cs | 4 +- Projects/UOContent/Mobiles/BaseCreature.cs | 737 +++++++++++++++++- .../UOContent/Mobiles/Vendors/BaseVendor.cs | 2 +- Projects/UOContent/Multis/HouseSign.cs | 2 +- Projects/UOContent/Skills/Discordance.cs | 4 +- Projects/UOContent/Skills/RemoveTrap.cs | 4 +- 39 files changed, 1248 insertions(+), 97 deletions(-) diff --git a/Projects/Server/Main.cs b/Projects/Server/Main.cs index 2422f5f61..13a85631d 100644 --- a/Projects/Server/Main.cs +++ b/Projects/Server/Main.cs @@ -25,8 +25,6 @@ using System.Text; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; using Server.Json; using Server.Network; diff --git a/Projects/Server/Network/NetState.cs b/Projects/Server/Network/NetState.cs index eda972410..ff4abed67 100644 --- a/Projects/Server/Network/NetState.cs +++ b/Projects/Server/Network/NetState.cs @@ -387,7 +387,7 @@ namespace Server.Network if (from.Mobile == Mobile && to.Mobile == m) { - return @from.Container; + return from.Container; } if (from.Mobile == m && to.Mobile == Mobile) diff --git a/Projects/UOContent/Accounting/AccountAttackLimiter.cs b/Projects/UOContent/Accounting/AccountAttackLimiter.cs index 1dc6f743c..3a9f6f4c4 100644 --- a/Projects/UOContent/Accounting/AccountAttackLimiter.cs +++ b/Projects/UOContent/Accounting/AccountAttackLimiter.cs @@ -6,7 +6,7 @@ using Server.Network; namespace Server.Accounting { - public class AccountAttackLimiter + public static class AccountAttackLimiter { public static bool Enabled; @@ -20,7 +20,9 @@ namespace Server.Accounting public static void Initialize() { if (!Enabled) + { return; + } PacketHandlers.RegisterThrottler(0x80, Throttle_Callback); PacketHandlers.RegisterThrottler(0x91, Throttle_Callback); @@ -32,7 +34,9 @@ namespace Server.Accounting var accessLog = FindAccessLog(ns); if (accessLog == null) + { return TimeSpan.Zero; + } var date = DateTime.UtcNow; var access = accessLog.LastAccessTime + ComputeThrottle(accessLog.Counts); @@ -42,7 +46,9 @@ namespace Server.Accounting public static InvalidAccountAccessLog FindAccessLog(NetState ns) { if (ns == null) + { return null; + } var ipAddress = ns.Address; @@ -51,9 +57,13 @@ namespace Server.Accounting var accessLog = m_List[i]; if (accessLog.HasExpired) + { m_List.RemoveAt(i--); + } else if (accessLog.Address.Equals(ipAddress)) + { return accessLog; + } } return null; @@ -62,17 +72,22 @@ namespace Server.Accounting public static void RegisterInvalidAccess(NetState ns) { if (ns == null || !Enabled) + { return; + } var accessLog = FindAccessLog(ns); if (accessLog == null) + { m_List.Add(accessLog = new InvalidAccountAccessLog(ns.Address)); + } accessLog.Counts += 1; accessLog.RefreshAccessTime(); if (accessLog.Counts >= 3) + { try { using var op = new StreamWriter("throttle.log", true); @@ -87,24 +102,35 @@ namespace Server.Accounting { // ignored } + } } public static TimeSpan ComputeThrottle(int counts) { if (counts >= 15) + { return TimeSpan.FromMinutes(5.0); + } if (counts >= 10) + { return TimeSpan.FromMinutes(1.0); + } if (counts >= 5) + { return TimeSpan.FromSeconds(20.0); + } if (counts >= 3) + { return TimeSpan.FromSeconds(10.0); + } if (counts >= 1) + { return TimeSpan.FromSeconds(2.0); + } return TimeSpan.Zero; } diff --git a/Projects/UOContent/Engines/Ethics/Core/Ethic.cs b/Projects/UOContent/Engines/Ethics/Core/Ethic.cs index 8cf674545..c2d777e36 100644 --- a/Projects/UOContent/Engines/Ethics/Core/Ethic.cs +++ b/Projects/UOContent/Engines/Ethics/Core/Ethic.cs @@ -33,7 +33,9 @@ namespace Server.Ethics if ((item.SavedFlags & 0x100) != 0) { if (item.Hue == Hero.Definition.PrimaryHue) + { return Hero; + } item.SavedFlags &= ~0x100; } @@ -41,7 +43,9 @@ namespace Server.Ethics if ((item.SavedFlags & 0x200) != 0) { if (item.Hue == Evil.Definition.PrimaryHue) + { return Evil; + } item.SavedFlags &= ~0x200; } @@ -54,12 +58,18 @@ namespace Server.Ethics var itemEthic = Find(item); if (itemEthic == null || Find(newOwner) == itemEthic) + { return true; + } if (itemEthic == Hero) + { (from == newOwner ? to : from).SendMessage("Only heros may receive this item."); + } else if (itemEthic == Evil) + { (from == newOwner ? to : from).SendMessage("Only the evil may receive this item."); + } return false; } @@ -69,12 +79,18 @@ namespace Server.Ethics var itemEthic = Find(item); if (itemEthic == null || Find(from) == itemEthic) + { return true; + } if (itemEthic == Hero) + { from.SendMessage("Only heros may wear this item."); + } else if (itemEthic == Evil) + { from.SendMessage("Only the evil may wear this item."); + } return false; } @@ -84,28 +100,43 @@ namespace Server.Ethics public static bool IsImbued(Item item, bool recurse) { if (Find(item) != null) + { return true; + } if (recurse) + { foreach (var child in item.Items) + { if (IsImbued(child, true)) + { return true; + } + } + } return false; } - public static void Initialize() + public static void Configure() { Enabled = ServerConfiguration.GetOrUpdateSetting("ethics.enable", false); + } + public static void Initialize() + { if (Enabled) + { EventSink.Speech += EventSink_Speech; + } } public static void EventSink_Speech(SpeechEventArgs e) { if (e.Blocked || e.Handled) + { return; + } var pl = Player.Find(e.Mobile); @@ -116,13 +147,19 @@ namespace Server.Ethics var ethic = Ethics[i]; if (!ethic.IsEligible(e.Mobile)) + { continue; + } if (!Insensitive.Equals(ethic.Definition.JoinPhrase.String, e.Speech)) + { continue; + } if (!e.Mobile.GetItemsInRange(2).Any(item => item is AnkhNorth || item is AnkhWest)) + { continue; + } pl = new Player(ethic, e.Mobile); @@ -138,7 +175,9 @@ namespace Server.Ethics else { if (e.Mobile is PlayerMobile mobile && mobile.DuelContext != null) + { return; + } var ethic = pl.Ethic; @@ -147,10 +186,14 @@ namespace Server.Ethics var power = ethic.Definition.Powers[i]; if (!Insensitive.Equals(power.Definition.Phrase.String, e.Speech)) + { continue; + } if (!power.CheckInvoke(pl)) + { continue; + } power.BeginInvoke(pl); e.Handled = true; @@ -169,16 +212,26 @@ namespace Server.Ethics var pl = Player.Find(mob); if (pl != null) + { return pl.Ethic; + } if (inherit && mob is BaseCreature bc) { if (bc.Controlled) + { return Find(bc.ControlMaster, false); + } + if (bc.Summoned) + { return Find(bc.SummonMaster, false); + } + if (allegiance) + { return bc.EthicAllegiance; + } } return null; @@ -201,7 +254,9 @@ namespace Server.Ethics var pl = new Player(this, reader); if (pl.Mobile != null) + { Timer.DelayCall(pl.CheckAttach); + } } break; @@ -216,7 +271,9 @@ namespace Server.Ethics writer.WriteEncodedInt(m_Players.Count); for (var i = 0; i < m_Players.Count; ++i) + { m_Players[i].Serialize(writer); + } } } } diff --git a/Projects/UOContent/Engines/Factions/Items/TownStone.cs b/Projects/UOContent/Engines/Factions/Items/TownStone.cs index b452f4905..222153116 100644 --- a/Projects/UOContent/Engines/Factions/Items/TownStone.cs +++ b/Projects/UOContent/Engines/Factions/Items/TownStone.cs @@ -41,7 +41,7 @@ namespace Server.Factions if (faction == null && from.AccessLevel < AccessLevel.GameMaster) return; // TODO: Message? - if (m_Town.Owner == null || @from.AccessLevel < AccessLevel.GameMaster && faction != m_Town.Owner) + if (m_Town.Owner == null || from.AccessLevel < AccessLevel.GameMaster && faction != m_Town.Owner) from.SendLocalizedMessage(1010332); // Your faction does not control this town else if (!m_Town.Owner.IsCommander(from)) from.SendLocalizedMessage(1005242); // Only faction Leaders can use townstones diff --git a/Projects/UOContent/Engines/MLQuests/MLQuestSystem.cs b/Projects/UOContent/Engines/MLQuests/MLQuestSystem.cs index 862c8ae6c..7888c66ce 100644 --- a/Projects/UOContent/Engines/MLQuests/MLQuestSystem.cs +++ b/Projects/UOContent/Engines/MLQuests/MLQuestSystem.cs @@ -43,7 +43,9 @@ namespace Server.Engines.MLQuests while ((line = sr.ReadLine()) != null) { if (line.Length == 0 || line.StartsWith("#")) + { continue; + } var split = line.Split('\t'); @@ -52,11 +54,13 @@ namespace Server.Engines.MLQuests if (type == null || !baseQuestType.IsAssignableFrom(type)) { if (Debug) + { Console.WriteLine( "Warning: {1} quest type '{0}'", split[0], type == null ? "Unknown" : "Invalid" ); + } continue; } @@ -73,7 +77,9 @@ namespace Server.Engines.MLQuests } if (quest == null) + { continue; + } Register(type, quest); @@ -84,11 +90,13 @@ namespace Server.Engines.MLQuests if (questerType == null || !baseQuesterType.IsAssignableFrom(questerType)) { if (Debug) + { Console.WriteLine( "Warning: {1} quester type '{0}'", split[i], questerType == null ? "Unknown" : "Invalid" ); + } continue; } @@ -115,7 +123,9 @@ namespace Server.Engines.MLQuests private static void RegisterQuestGiver(MLQuest quest, Type questerType) { if (!QuestGivers.TryGetValue(questerType, out var questList)) + { QuestGivers[questerType] = questList = new List(); + } questList.Add(quest); } @@ -125,20 +135,33 @@ namespace Server.Engines.MLQuests Register(quest.GetType(), quest); foreach (var questerType in questerTypes) + { RegisterQuestGiver(quest, questerType); + } + } + + public static void Configure() + { + Enabled = ServerConfiguration.GetOrUpdateSetting("questSystem.enableMLQuests", Core.ML); } public static void Initialize() { - Enabled = ServerConfiguration.GetOrUpdateSetting("questSystem.enableMLQuests", Core.ML); - if (!Enabled) + { return; + } if (AutoGenerateNew) + { foreach (var quest in Quests.Values) + { if (quest?.Deserialized == false) + { quest.Generate(); + } + } + } MLQuestPersistence.EnsureExistence(); @@ -205,9 +228,11 @@ namespace Server.Engines.MLQuests m.SendMessage("Serialization for quest {0} is now {1}.", quest.GetType().Name, enable ? "enabled" : "disabled"); if (AutoGenerateNew && !enable) + { m.SendMessage( "Please note that automatic generation of new quests is ON. This quest will be regenerated on the next server start." ); + } } [Usage("SaveAllQuests [saveEnabled=true]")] @@ -225,14 +250,18 @@ namespace Server.Engines.MLQuests var enable = e.Length == 1 ? e.GetBoolean(0) : true; foreach (var quest in Quests.Values) + { quest.SaveEnabled = enable; + } m.SendMessage("Serialization for all quests is now {0}.", enable ? "enabled" : "disabled"); if (AutoGenerateNew && !enable) + { m.SendMessage( "Please note that automatic generation of new quests is ON. All quests will be regenerated on the next server start." ); + } } [Usage("InvalidQuestItems")] @@ -244,19 +273,29 @@ namespace Server.Engines.MLQuests var found = new List(); foreach (var item in World.Items.Values) + { if (item.QuestItem) { if (item.Parent is Backpack pack) + { if (pack.Parent is PlayerMobile player && player.Backpack == pack) + { continue; + } + } found.Add(item); } + } if (found.Count == 0) + { m.SendMessage("No matching objects found."); + } else + { m.SendGump(new InterfaceGump(m, new[] { "Object" }, found, 0, null)); + } } private static bool FindQuest( @@ -272,6 +311,7 @@ namespace Server.Engines.MLQuests // 1. Check quests in progress with this NPC (overriding deliveries is intended) if (context != null) + { foreach (var questEntry in quests) { var instance = context.FindInstance(questEntry); @@ -284,6 +324,7 @@ namespace Server.Engines.MLQuests return true; } } + } // 2. Check deliveries (overriding chain offers is intended) if ((entry = HandleDelivery(pm, quester, questerType)) != null) @@ -294,12 +335,16 @@ namespace Server.Engines.MLQuests // 3. Check chain quest offers if (context != null) + { foreach (var questEntry in quests) + { if (questEntry.IsChainTriggered && context.ChainOffers.Contains(questEntry)) { quest = questEntry; return true; } + } + } // 4. Random quest quest = RandomStarterQuest(quester, pm, context); @@ -310,7 +355,9 @@ namespace Server.Engines.MLQuests public static void OnDoubleClick(IQuestGiver quester, PlayerMobile pm) { if (quester.Deleted || !pm.Alive) + { return; + } var context = GetContext(pm); @@ -325,13 +372,22 @@ namespace Server.Engines.MLQuests TurnToFace(quester, pm); if (entry.Failed) + { return; // Note: OSI sends no gump at all for failed quests, they have to be cancelled in the quest overview + } + if (entry.ClaimReward) + { entry.SendRewardOffer(); + } else if (entry.IsCompleted()) + { entry.SendReportBackGump(); + } else + { entry.SendProgressGump(); + } } else if (quest.CanOffer(quester, pm, context, true)) { @@ -346,9 +402,15 @@ namespace Server.Engines.MLQuests var context = GetContext(pm); if (context != null) + { foreach (var quest in context.QuestInstances) + { if (!quest.ClaimReward && quest.AllowsQuestItem(item, type)) + { return true; + } + } + } return false; } @@ -358,7 +420,9 @@ namespace Server.Engines.MLQuests var context = GetContext(pm); if (context == null) + { return; + } var instances = context.QuestInstances; @@ -368,14 +432,18 @@ namespace Server.Engines.MLQuests var instance = instances[i]; if (instance.ClaimReward) + { continue; + } foreach (var objective in instance.Objectives) + { if (!objective.Expired && objective.AllowsQuestItem(item, type)) { objective.CheckComplete(); // yes, this can happen multiple times (for multiple quests) break; } + } } } @@ -399,7 +467,9 @@ namespace Server.Engines.MLQuests var context = GetContext(pm); if (context == null) + { return; + } var instances = context.QuestInstances; @@ -408,15 +478,19 @@ namespace Server.Engines.MLQuests var instance = instances[i]; if (instance.ClaimReward) + { continue; + } foreach (var objective in instance.Objectives) + { if (!objective.Expired && objective is GainSkillObjectiveInstance objectiveInstance && objectiveInstance.Handles(skill)) { objectiveInstance.CheckComplete(); break; } + } } } @@ -425,7 +499,9 @@ namespace Server.Engines.MLQuests var context = GetContext(pm); if (context == null) + { return; + } var instances = context.QuestInstances; @@ -436,13 +512,16 @@ namespace Server.Engines.MLQuests var instance = instances[i]; if (instance.ClaimReward) + { continue; + } /* A kill only counts for a single objective within a quest, * but it can count for multiple quests. This is something not * currently observable on OSI, so it is assumed behavior. */ foreach (var objective in instance.Objectives) + { if (!objective.Expired && objective is KillObjectiveInstance kill) { type ??= mob.GetType(); @@ -453,6 +532,7 @@ namespace Server.Engines.MLQuests break; } } + } } } @@ -461,7 +541,9 @@ namespace Server.Engines.MLQuests var context = GetContext(pm); if (context == null) + { return null; + } var instances = context.QuestInstances; MLQuestInstance deliverInstance = null; @@ -476,6 +558,7 @@ namespace Server.Engines.MLQuests foreach (var objective in instance.Objectives) // Note: On OSI, expired deliveries can still be completed. Bug? + { if (!objective.Expired && objective is DeliverObjectiveInstance deliver && deliver.IsDestination(quester, questerType)) { @@ -492,6 +575,7 @@ namespace Server.Engines.MLQuests break; // don't return, we may have to complete more deliveries } + } } return deliverInstance; @@ -507,7 +591,9 @@ namespace Server.Engines.MLQuests public static MLQuestContext GetOrCreateContext(PlayerMobile pm) { if (!Contexts.TryGetValue(pm, out var context)) + { Contexts[pm] = context = new MLQuestContext(pm); + } return context; } @@ -541,7 +627,9 @@ namespace Server.Engines.MLQuests var instance = instances[i]; if (instance.Quester == quester) + { instance.OnQuesterDeleted(); + } } } } @@ -549,7 +637,9 @@ namespace Server.Engines.MLQuests public static void EventSink_QuestGumpRequest(Mobile m) { if (!Enabled || !(m is PlayerMobile pm)) + { return; + } pm.SendGump(new QuestLogGump(pm)); } @@ -559,7 +649,9 @@ namespace Server.Engines.MLQuests var quests = quester.MLQuests; if (quests.Count == 0) + { return null; + } m_EligiblePool.Clear(); MLQuest fallback = null; @@ -567,7 +659,9 @@ namespace Server.Engines.MLQuests foreach (var quest in quests) { if (quest.IsChainTriggered || context?.IsDoingQuest(quest) == true) + { continue; + } /* * Save first quest that reaches the CanOffer call. @@ -576,7 +670,9 @@ namespace Server.Engines.MLQuests fallback ??= quest; if (quest.CanOffer(quester, pm, context, false)) + { m_EligiblePool.Add(quest); + } } return m_EligiblePool.Count == 0 ? fallback : m_EligiblePool.RandomElement(); @@ -585,7 +681,9 @@ namespace Server.Engines.MLQuests public static void TurnToFace(IQuestGiver quester, Mobile mob) { if (quester is Mobile m) + { m.Direction = m.GetDirectionTo(mob); + } } public static void Tell(IQuestGiver quester, PlayerMobile pm, int cliloc) @@ -593,11 +691,17 @@ namespace Server.Engines.MLQuests TurnToFace(quester, pm); if (quester is Mobile mobile) + { mobile.PrivateOverheadMessage(MessageType.Regular, SpeechColor, cliloc, pm.NetState); + } else if (quester is Item item) + { MessageHelper.SendLocalizedMessageTo(item, pm, cliloc, SpeechColor); + } else + { pm.SendLocalizedMessage(cliloc); + } } public static void Tell(IQuestGiver quester, PlayerMobile pm, int cliloc, string args) @@ -605,11 +709,17 @@ namespace Server.Engines.MLQuests TurnToFace(quester, pm); if (quester is Mobile mobile) + { mobile.PrivateOverheadMessage(MessageType.Regular, SpeechColor, cliloc, args, pm.NetState); + } else if (quester is Item item) + { MessageHelper.SendLocalizedMessageTo(item, pm, cliloc, args, SpeechColor); + } else + { pm.SendLocalizedMessage(cliloc, args); + } } public static void Tell(IQuestGiver quester, PlayerMobile pm, string message) @@ -617,22 +727,34 @@ namespace Server.Engines.MLQuests TurnToFace(quester, pm); if (quester is Mobile mobile) + { mobile.PrivateOverheadMessage(MessageType.Regular, SpeechColor, false, message, pm.NetState); + } else if (quester is Item item) + { MessageHelper.SendMessageTo(item, pm, message, SpeechColor); + } else + { pm.SendMessage(SpeechColor, message); + } } public static void TellDef(IQuestGiver quester, PlayerMobile pm, TextDefinition def) { if (def == null) + { return; + } if (def.Number > 0) + { Tell(quester, pm, def.Number); + } else if (def.String != null) + { Tell(quester, pm, def.String); + } } public static void WriteQuestRef(IGenericWriter writer, MLQuest quest) @@ -645,12 +767,16 @@ namespace Server.Engines.MLQuests var typeName = reader.ReadString(); if (typeName == null) + { return null; // not serialized + } var questType = AssemblyHandler.FindFirstTypeForName(typeName); if (questType == null) + { return null; // no longer a type + } return FindQuest(questType); } @@ -713,9 +839,13 @@ namespace Server.Engines.MLQuests public override void Execute(CommandEventArgs e, object obj) { if (!(obj is PlayerMobile pm)) + { LogFailure("They have no ML quest context."); + } else + { e.Mobile.SendGump(new PropertiesGump(e.Mobile, GetOrCreateContext(pm))); + } } } } diff --git a/Projects/UOContent/Engines/Party/AddPartyTarget.cs b/Projects/UOContent/Engines/Party/AddPartyTarget.cs index e267c46c3..999b5fd61 100644 --- a/Projects/UOContent/Engines/Party/AddPartyTarget.cs +++ b/Projects/UOContent/Engines/Party/AddPartyTarget.cs @@ -18,38 +18,38 @@ namespace Server.Engines.PartySystem if (from == m) { - @from.SendLocalizedMessage(1005439); // You cannot add yourself to a party. + from.SendLocalizedMessage(1005439); // You cannot add yourself to a party. } else if (p != null && p.Leader != from) { - @from.SendLocalizedMessage(1005453); // You may only add members to the party if you are the leader. + from.SendLocalizedMessage(1005453); // You may only add members to the party if you are the leader. } else if (m.Party is Mobile) { } else if (p != null && p.Members.Count + p.Candidates.Count >= Party.Capacity) { - @from.SendLocalizedMessage(1008095); // You may only have 10 in your party (this includes candidates). + from.SendLocalizedMessage(1008095); // You may only have 10 in your party (this includes candidates). } else if (!m.Player && m.Body.IsHuman) { - m.SayTo(@from, 1005443); // Nay, I would rather stay here and watch a nail rust. + m.SayTo(from, 1005443); // Nay, I would rather stay here and watch a nail rust. } else if (!m.Player) { - @from.SendLocalizedMessage(1005444); // The creature ignores your offer. + from.SendLocalizedMessage(1005444); // The creature ignores your offer. } else if (mp != null && mp == p) { - @from.SendLocalizedMessage(1005440); // This person is already in your party! + from.SendLocalizedMessage(1005440); // This person is already in your party! } else if (mp != null) { - @from.SendLocalizedMessage(1005441); // This person is already in a party! + from.SendLocalizedMessage(1005441); // This person is already in a party! } else { - Party.Invite(@from, m); + Party.Invite(from, m); } } else diff --git a/Projects/UOContent/Engines/Pathing/PathFollower.cs b/Projects/UOContent/Engines/Pathing/PathFollower.cs index 3414970d3..3cd9ef44f 100644 --- a/Projects/UOContent/Engines/Pathing/PathFollower.cs +++ b/Projects/UOContent/Engines/Pathing/PathFollower.cs @@ -24,7 +24,7 @@ namespace Server public IPoint3D Goal { get; } - public static void Initialize() + public static void Configure() { Enabled = ServerConfiguration.GetOrUpdateSetting("pathfinding.enable", true); } diff --git a/Projects/UOContent/Engines/Plants/PlantItem.cs b/Projects/UOContent/Engines/Plants/PlantItem.cs index a63dc73ec..d0cfb4e3b 100644 --- a/Projects/UOContent/Engines/Plants/PlantItem.cs +++ b/Projects/UOContent/Engines/Plants/PlantItem.cs @@ -284,8 +284,8 @@ namespace Server.Engines.Plants } public bool IsUsableBy(Mobile from) => - IsChildOf(from.Backpack) || IsChildOf(from.FindBankNoCreate()) || IsLockedDown && IsAccessibleTo(@from) || - RootParent is Item root && root.IsSecure && root.IsAccessibleTo(@from); + IsChildOf(from.Backpack) || IsChildOf(from.FindBankNoCreate()) || IsLockedDown && IsAccessibleTo(from) || + RootParent is Item root && root.IsSecure && root.IsAccessibleTo(from); public override void OnDoubleClick(Mobile from) { diff --git a/Projects/UOContent/Engines/Quests/The Summoning/Items/BellOfTheDead.cs b/Projects/UOContent/Engines/Quests/The Summoning/Items/BellOfTheDead.cs index 30b42578a..326bf467f 100644 --- a/Projects/UOContent/Engines/Quests/The Summoning/Items/BellOfTheDead.cs +++ b/Projects/UOContent/Engines/Quests/The Summoning/Items/BellOfTheDead.cs @@ -95,7 +95,7 @@ namespace Server.Engines.Quests.Doom ); Effects.PlaySound(loc, Map, 0x1FE); - Chyloth = new Chyloth { Direction = (Direction)(7 & (4 + (int)@from.GetDirectionTo(loc))) }; + Chyloth = new Chyloth { Direction = (Direction)(7 & (4 + (int)from.GetDirectionTo(loc))) }; Chyloth.MoveToWorld(loc, Map); diff --git a/Projects/UOContent/Engines/VeteranRewards/RewardSystem.cs b/Projects/UOContent/Engines/VeteranRewards/RewardSystem.cs index 683d42345..f3e1fd437 100644 --- a/Projects/UOContent/Engines/VeteranRewards/RewardSystem.cs +++ b/Projects/UOContent/Engines/VeteranRewards/RewardSystem.cs @@ -22,7 +22,9 @@ namespace Server.Engines.VeteranRewards get { if (m_Categories == null) + { SetupRewardTables(); + } return m_Categories; } @@ -33,7 +35,9 @@ namespace Server.Engines.VeteranRewards get { if (m_Lists == null) + { SetupRewardTables(); + } return m_Lists; } @@ -45,15 +49,22 @@ namespace Server.Engines.VeteranRewards for (var j = 0; j < entries.Count; ++j) // RewardEntry entry = entries[j]; + { if (HasAccess(mob, entries[j])) + { return true; + } + } + return false; } public static bool HasAccess(Mobile mob, RewardEntry entry) { if (Core.Expansion < entry.RequiredExpansion) + { return false; + } return HasAccess(mob, entry.List, out var _); } @@ -77,7 +88,9 @@ namespace Server.Engines.VeteranRewards ts = list.Age - totalTime; if (ts <= TimeSpan.Zero) + { return true; + } return false; } @@ -85,7 +98,9 @@ namespace Server.Engines.VeteranRewards public static int GetRewardLevel(Mobile mob) { if (!(mob.Account is Account acct)) + { return 0; + } return GetRewardLevel(acct); } @@ -100,7 +115,9 @@ namespace Server.Engines.VeteranRewards public static bool HasHalfLevel(Mobile mob) { if (!(mob.Account is Account acct)) + { return false; + } return HasHalfLevel(acct); } @@ -119,10 +136,14 @@ namespace Server.Engines.VeteranRewards ComputeRewardInfo(mob, out var cur, out var max); if (cur >= max) + { return false; + } if (!(mob.Account is Account acct)) + { return false; + } // if (mob.AccessLevel < AccessLevel.GameMaster) acct.SetTag("numRewardsChosen", (cur + 1).ToString()); @@ -154,14 +175,22 @@ namespace Server.Engines.VeteranRewards var tag = acct.GetTag("numRewardsChosen"); if (string.IsNullOrEmpty(tag)) + { cur = 0; + } else + { cur = Utility.ToInt32(tag); + } if (level >= 6) + { max = 9 + (level - 6) * 2; + } else + { max = 2 + level; + } } public static bool CheckIsUsableBy(Mobile from, Item item, object[] args = null) @@ -178,12 +207,16 @@ namespace Server.Engines.VeteranRewards for (var j = 0; j < entries.Length; ++j) { if (entries[j].ItemType != type) + { continue; + } if (args == null && entries[j].Args.Length == 0) { if (isRelaxedRules && i <= 0 || HasAccess(from, list, out var ts)) + { return true; + } from.SendLocalizedMessage( 1008126, @@ -195,17 +228,23 @@ namespace Server.Engines.VeteranRewards } if (args?.Length != entries[j].Args.Length) + { continue; + } var match = true; for (var k = 0; match && k < args.Length; ++k) + { match = args[k].Equals(entries[j].Args[k]); + } if (match) { if (isRelaxedRules && i <= 0 || HasAccess(from, list, out var ts)) + { return true; + } from.SendLocalizedMessage( 1008126, @@ -240,22 +279,30 @@ namespace Server.Engines.VeteranRewards var entries = list.Entries; for (var j = 0; j < entries.Length; ++j) + { if (entries[j].ItemType == type) { if (args == null && entries[j].Args.Length == 0) + { return i + 1; + } if (args?.Length == entries[j].Args.Length) { var match = true; for (var k = 0; match && k < args.Length; ++k) + { match = args[k].Equals(entries[j].Args[k]); + } if (match) + { return i + 1; + } } } + } } // no entry? @@ -532,20 +579,27 @@ namespace Server.Engines.VeteranRewards }; } - public static void Initialize() + public static void Configure() { Enabled = ServerConfiguration.GetOrUpdateSetting("vetRewards.enable", true); SkillCapRewards = ServerConfiguration.GetOrUpdateSetting("vetRewards.skillCapRewards", true); RewardInterval = ServerConfiguration.GetOrUpdateSetting("vetRewards.rewardInterval", TimeSpan.FromDays(30.0)); + } + public static void Initialize() + { if (Enabled) + { EventSink.Login += EventSink_Login; + } } private static void EventSink_Login(Mobile m) { if (!m.Alive) + { return; + } ComputeRewardInfo(m, out var cur, out var max, out var level); @@ -555,9 +609,13 @@ namespace Server.Engines.VeteranRewards level = Math.Clamp(level, 0, 4); if (SkillCapRewards) + { m.SkillsCap = 7000 + level * 50; + } else + { m.SkillsCap = 7000; + } } if (Core.ML && m is PlayerMobile pm && !pm.HasStatReward && HasHalfLevel(pm)) @@ -567,7 +625,9 @@ namespace Server.Engines.VeteranRewards } if (cur < max) + { m.SendGump(new RewardNoticeGump(m)); + } } } diff --git a/Projects/UOContent/Gumps/WhoGump.cs b/Projects/UOContent/Gumps/WhoGump.cs index f2ce28130..71e237f3b 100644 --- a/Projects/UOContent/Gumps/WhoGump.cs +++ b/Projects/UOContent/Gumps/WhoGump.cs @@ -273,7 +273,7 @@ namespace Server.Gumps from.SendGump(new WhoGump(from, m_Mobiles, m_Page)); } else if (m == from || !m.Hidden || from.AccessLevel >= m.AccessLevel || - m is PlayerMobile mobile && mobile.VisibilityList.Contains(@from)) + m is PlayerMobile mobile && mobile.VisibilityList.Contains(from)) { from.SendGump(new ClientGump(from, m.NetState)); } diff --git a/Projects/UOContent/Items/Containers/Container.cs b/Projects/UOContent/Items/Containers/Container.cs index 0e33a3d3c..231363b4a 100644 --- a/Projects/UOContent/Items/Containers/Container.cs +++ b/Projects/UOContent/Items/Containers/Container.cs @@ -234,7 +234,7 @@ namespace Server.Items base.CheckHold(m, item, false, checkItems, plusItems, plusWeight); public override bool CheckContentDisplay(Mobile from) => - RootParent is BaseCreature creature && creature.Controlled && creature.ControlMaster == @from || + RootParent is BaseCreature creature && creature.Controlled && creature.ControlMaster == from || base.CheckContentDisplay(from); public override void Serialize(IGenericWriter writer) diff --git a/Projects/UOContent/Items/Containers/SalvageBag.cs b/Projects/UOContent/Items/Containers/SalvageBag.cs index f04fe34e7..5fb665eea 100644 --- a/Projects/UOContent/Items/Containers/SalvageBag.cs +++ b/Projects/UOContent/Items/Containers/SalvageBag.cs @@ -180,8 +180,8 @@ namespace Server.Items if (item?.Deleted != false) continue; - if (item is BaseArmor armor && Resmelt(@from, armor, armor.Resource) || - item is BaseWeapon weapon && Resmelt(@from, weapon, weapon.Resource) || + if (item is BaseArmor armor && Resmelt(from, armor, armor.Resource) || + item is BaseWeapon weapon && Resmelt(from, weapon, weapon.Resource) || item is DragonBardingDeed) salvaged++; else diff --git a/Projects/UOContent/Items/Games/BaseBoard.cs b/Projects/UOContent/Items/Games/BaseBoard.cs index e3a0100a0..991e7045f 100644 --- a/Projects/UOContent/Items/Games/BaseBoard.cs +++ b/Projects/UOContent/Items/Games/BaseBoard.cs @@ -102,10 +102,10 @@ 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.Map == @from.Map && @from.InRange(board.GetWorldLocation(), 1) && - BaseHouse.FindHouseAt(board)?.IsOwner(@from) == true)); + !board.Deleted && (from.AccessLevel >= AccessLevel.GameMaster || from.Alive && + (board.IsChildOf(from.Backpack) || !(board.RootParent is Mobile) && + board.Map == from.Map && from.InRange(board.GetWorldLocation(), 1) && + BaseHouse.FindHouseAt(board)?.IsOwner(from) == true)); public class DefaultEntry : ContextMenuEntry { diff --git a/Projects/UOContent/Items/Guilds/Guildstone.cs b/Projects/UOContent/Items/Guilds/Guildstone.cs index 8d805d146..1f86178f4 100644 --- a/Projects/UOContent/Items/Guilds/Guildstone.cs +++ b/Projects/UOContent/Items/Guilds/Guildstone.cs @@ -71,7 +71,7 @@ namespace Server.Items var contains = false; if (house == null && m_BeforeChangeover || - house?.IsOwner(@from) == true && (contains = house.Addons.Contains(this))) + house?.IsOwner(from) == true && (contains = house.Addons.Contains(this))) { Effects.PlaySound(GetWorldLocation(), Map, 0x3B3); from.SendLocalizedMessage(500461); // You destroy the item. diff --git a/Projects/UOContent/Items/Misc/Moonstone.cs b/Projects/UOContent/Items/Misc/Moonstone.cs index 15a1740f7..045485230 100644 --- a/Projects/UOContent/Items/Misc/Moonstone.cs +++ b/Projects/UOContent/Items/Misc/Moonstone.cs @@ -69,7 +69,7 @@ namespace Server.Items { from.SendLocalizedMessage(1061632); // You can't do that while carrying the sigil. } - else if (from.Map == GetTargetMap() || @from.Map != Map.Trammel && @from.Map != Map.Felucca) + else if (from.Map == GetTargetMap() || from.Map != Map.Trammel && from.Map != Map.Felucca) { from.SendLocalizedMessage(1005401); // You cannot bury the stone here. } diff --git a/Projects/UOContent/Items/Misc/Scales.cs b/Projects/UOContent/Items/Misc/Scales.cs index b66fe1e8a..b8d8104cc 100644 --- a/Projects/UOContent/Items/Misc/Scales.cs +++ b/Projects/UOContent/Items/Misc/Scales.cs @@ -49,7 +49,7 @@ namespace Server.Items { var root = item.RootParent; - if (root != null && root != @from || item.Parent == from) + if (root != null && root != from || item.Parent == from) { message = "You decide that item's current location is too awkward to get an accurate result."; } diff --git a/Projects/UOContent/Items/Skill Items/Magical/Misc/Moongate.cs b/Projects/UOContent/Items/Skill Items/Magical/Misc/Moongate.cs index 611570c87..68942521b 100644 --- a/Projects/UOContent/Items/Skill Items/Magical/Misc/Moongate.cs +++ b/Projects/UOContent/Items/Skill Items/Magical/Misc/Moongate.cs @@ -157,8 +157,8 @@ namespace Server.Items public virtual void BeginConfirmation(Mobile from) { - if (IsInTown(@from.Location, @from.Map) && !IsInTown(Target, TargetMap) || - @from.Map != Map.Felucca && TargetMap == Map.Felucca && ShowFeluccaWarning) + if (IsInTown(from.Location, from.Map) && !IsInTown(Target, TargetMap) || + from.Map != Map.Felucca && TargetMap == Map.Felucca && ShowFeluccaWarning) { if (from.AccessLevel == AccessLevel.Player || !from.Hidden) from.Send(new PlaySound(0x20E, from.Location)); 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 c3b35b6cd..7fba6e4b7 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 @@ -188,8 +188,8 @@ namespace Server.Items var toExplode = eable.Where( o => { - if (!(o is Mobile mobile) || @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; diff --git a/Projects/UOContent/Items/Skill Items/Misc/FireHorn.cs b/Projects/UOContent/Items/Skill Items/Misc/FireHorn.cs index ed550fc8a..7239c446b 100644 --- a/Projects/UOContent/Items/Skill Items/Misc/FireHorn.cs +++ b/Projects/UOContent/Items/Skill Items/Misc/FireHorn.cs @@ -104,7 +104,7 @@ namespace Server.Items m => { if (from == m || !SpellHelper.ValidIndirectTarget(from, m) || !from.CanBeHarmful(m, false) - || Core.AOS && !@from.InLOS(m)) + || Core.AOS && !from.InLOS(m)) return false; if (m.Player) 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 68a59c605..91ebb8bb6 100644 --- a/Projects/UOContent/Items/Special/Bulk Order Rewards/Blacksmithy/PowderOfTemperament.cs +++ b/Projects/UOContent/Items/Special/Bulk Order Rewards/Blacksmithy/PowderOfTemperament.cs @@ -111,7 +111,7 @@ namespace Server.Items return; } - if ((item.IsChildOf(from.Backpack) || Core.ML && item.Parent == @from) && + if ((item.IsChildOf(from.Backpack) || Core.ML && item.Parent == from) && m_Powder.IsChildOf(from.Backpack)) { var origMaxHP = wearable.MaxHitPoints; diff --git a/Projects/UOContent/Misc/AOS.cs b/Projects/UOContent/Misc/AOS.cs index 6078e0cda..b480e3848 100644 --- a/Projects/UOContent/Misc/AOS.cs +++ b/Projects/UOContent/Misc/AOS.cs @@ -51,10 +51,14 @@ namespace Server ) { if (m?.Deleted != false || !m.Alive || damage <= 0) + { return 0; + } if (phys == 0 && fire == 100 && cold == 0 && pois == 0 && nrgy == 0) + { MeerMage.StopEffect(m, true); + } if (!Core.AOS) { @@ -71,6 +75,7 @@ namespace Server Fix(ref direct); if (Core.ML && chaos > 0) + { switch (Utility.Random(5)) { case 0: @@ -89,11 +94,14 @@ namespace Server nrgy += chaos; break; } + } BaseQuiver quiver = null; if (archer && from != null) - quiver = from.FindItemOnLayer(Layer.Cloak) as BaseQuiver; + { + quiver = @from.FindItemOnLayer(Layer.Cloak) as BaseQuiver; + } int totalDamage; @@ -119,31 +127,44 @@ namespace Server totalDamage += damage * direct / 100; if (quiver != null) + { totalDamage += totalDamage * quiver.DamageIncrease / 100; + } } if (totalDamage < 1) + { totalDamage = 1; + } } else if (Core.ML && m is PlayerMobile && from is PlayerMobile) { if (quiver != null) + { damage += damage * quiver.DamageIncrease / 100; + } if (!deathStrike) + { totalDamage = Math.Min(damage, 35); // Direct Damage cap of 35 + } else + { totalDamage = Math.Min(damage, 70); // Direct Damage cap of 70 + } } else { totalDamage = damage; if (Core.ML && quiver != null) + { totalDamage += totalDamage * quiver.DamageIncrease / 100; + } } if (from?.Player != true && m.Player && m.Mount is SwampDragon pet) + { if (pet.HasBarding) { var percent = pet.BardingExceptional ? 20 : 10; @@ -160,9 +181,12 @@ namespace Server m.SendLocalizedMessage(1053031); // Your dragon's barding has been destroyed! } } + } if (keepAlive && totalDamage > m.Hits) + { totalDamage = m.Hits; + } if (from?.Deleted == false && from.Alive) { @@ -194,7 +218,9 @@ namespace Server public static void Fix(ref int val) { if (val < 0) + { val = 0; + } } public static int Scale(int input, int percent) => input * percent / 100; @@ -447,7 +473,9 @@ namespace Server public static int GetValue(Mobile m, AosAttribute attribute) { if (!Core.AOS) + { return 0; + } var items = m.Items; var value = 0; @@ -461,55 +489,73 @@ namespace Server var attrs = weapon.Attributes; if (attrs != null) + { value += attrs[attribute]; + } if (attribute == AosAttribute.Luck) + { value += weapon.GetLuckBonus(); + } } else if (obj is BaseArmor armor) { var attrs = armor.Attributes; if (attrs != null) + { value += attrs[attribute]; + } if (attribute == AosAttribute.Luck) + { value += armor.GetLuckBonus(); + } } else if (obj is BaseJewel jewel) { var attrs = jewel.Attributes; if (attrs != null) + { value += attrs[attribute]; + } } else if (obj is BaseClothing clothing) { var attrs = clothing.Attributes; if (attrs != null) + { value += attrs[attribute]; + } } else if (obj is Spellbook spellbook) { var attrs = spellbook.Attributes; if (attrs != null) + { value += attrs[attribute]; + } } else if (obj is BaseQuiver quiver) { var attrs = quiver.Attributes; if (attrs != null) + { value += attrs[attribute]; + } } else if (obj is BaseTalisman talisman) { var attrs = talisman.Attributes; if (attrs != null) + { value += attrs[attribute]; + } } } @@ -529,13 +575,19 @@ namespace Server var modName = Owner.Serial.ToString(); if (strBonus != 0) + { to.AddStatMod(new StatMod(StatType.Str, $"{modName}Str", strBonus, TimeSpan.Zero)); + } if (dexBonus != 0) + { to.AddStatMod(new StatMod(StatType.Dex, $"{modName}Dex", dexBonus, TimeSpan.Zero)); + } if (intBonus != 0) + { to.AddStatMod(new StatMod(StatType.Int, $"{modName}Int", intBonus, TimeSpan.Zero)); + } } to.CheckStatTimers(); @@ -784,7 +836,9 @@ namespace Server public static int GetValue(Mobile m, AosWeaponAttribute attribute) { if (!Core.AOS) + { return 0; + } var items = m.Items; var value = 0; @@ -798,14 +852,18 @@ namespace Server var attrs = weapon.WeaponAttributes; if (attrs != null) + { value += attrs[attribute]; + } } else if (obj is ElvenGlasses glasses) { var attrs = glasses.WeaponAttributes; if (attrs != null) + { value += attrs[attribute]; + } } } @@ -878,7 +936,9 @@ namespace Server public static int GetValue(Mobile m, AosArmorAttribute attribute) { if (!Core.AOS) + { return 0; + } var items = m.Items; var value = 0; @@ -892,14 +952,18 @@ namespace Server var attrs = armor.ArmorAttributes; if (attrs != null) + { value += attrs[attribute]; + } } else if (obj is BaseClothing clothing) { var attrs = clothing.ClothingAttributes; if (attrs != null) + { value += attrs[attribute]; + } } } @@ -1001,8 +1065,12 @@ namespace Server public void GetProperties(ObjectPropertyList 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); + } + } } public static int GetLabel(SkillName skill) @@ -1023,7 +1091,9 @@ namespace Server for (var i = 0; i < 5; ++i) { if (!GetValues(i, out var skill, out var bonus)) + { continue; + } m_Mods ??= new List(); @@ -1037,7 +1107,9 @@ namespace Server public void Remove() { if (m_Mods == null) + { return; + } for (var i = 0; i < m_Mods.Count; ++i) { @@ -1045,7 +1117,9 @@ namespace Server m_Mods[i].Remove(); if (Core.ML) + { CheckCancelMorph(m); + } } m_Mods = null; @@ -1123,7 +1197,9 @@ namespace Server public void CheckCancelMorph(Mobile m) { if (m == null) + { return; + } var acontext = AnimalForm.GetContext(m); var context = TransformationSpellHelper.GetContext(m); @@ -1132,17 +1208,26 @@ namespace Server { spell.GetCastSkills(out var minSkill, out _); if (m.Skills[spell.CastSkill].Value < minSkill) + { TransformationSpellHelper.RemoveContext(m, context, true); + } } if (acontext != null) { int i; for (i = 0; i < AnimalForm.Entries.Length; ++i) + { if (AnimalForm.Entries[i].Type == acontext.Type) + { break; + } + } + if (m.Skills.Ninjitsu.Value < AnimalForm.Entries[i].ReqSkill) + { AnimalForm.RemoveContext(m, true); + } } if (!m.CanBeginAction() && m.Skills.Magery.Value < 66.1) @@ -1158,7 +1243,10 @@ namespace Server if (!m.CanBeginAction() && m.Skills.Magery.Value < 38.1) { if (m is PlayerMobile mobile) + { mobile.SetHairMods(-1, -1); + } + m.BodyMod = 0; m.HueMod = -1; m.NameMod = null; @@ -1292,7 +1380,9 @@ namespace Server m_Values = new int[reader.ReadEncodedInt()]; for (var i = 0; i < m_Values.Length; ++i) + { m_Values[i] = reader.ReadEncodedInt(); + } break; } @@ -1302,7 +1392,9 @@ namespace Server m_Values = new int[reader.ReadInt()]; for (var i = 0; i < m_Values.Length; ++i) + { m_Values[i] = reader.ReadInt(); + } break; } @@ -1320,23 +1412,31 @@ namespace Server writer.WriteEncodedInt(m_Values.Length); for (var i = 0; i < m_Values.Length; ++i) + { writer.WriteEncodedInt(m_Values[i]); + } } public int GetValue(int bitmask) { if (!Core.AOS) + { return 0; + } var mask = (uint)bitmask; if ((m_Names & mask) == 0) + { return 0; + } var index = GetIndex(mask); if (index >= 0 && index < m_Values.Length) + { return m_Values[index]; + } return 0; } @@ -1346,14 +1446,20 @@ namespace Server if (bitmask == (int)AosWeaponAttribute.DurabilityBonus && this is AosWeaponAttributes) { if (Owner is BaseWeapon weapon) + { weapon.UnscaleDurability(); + } } else if (bitmask == (int)AosArmorAttribute.DurabilityBonus && this is AosArmorAttributes) { if (Owner is BaseArmor armor) + { armor.UnscaleDurability(); + } else if (Owner is BaseClothing clothing) + { clothing.UnscaleDurability(); + } } var mask = (uint)bitmask; @@ -1365,7 +1471,9 @@ namespace Server var index = GetIndex(mask); if (index >= 0 && index < m_Values.Length) + { m_Values[index] = value; + } } else { @@ -1377,12 +1485,16 @@ namespace Server m_Values = new int[old.Length + 1]; for (var i = 0; i < index; ++i) + { m_Values[i] = old[i]; + } m_Values[index] = value; for (var i = index; i < old.Length; ++i) + { m_Values[i + 1] = old[i]; + } m_Names |= mask; } @@ -1406,10 +1518,14 @@ namespace Server m_Values = new int[old.Length - 1]; for (var i = 0; i < index; ++i) + { m_Values[i] = old[i]; + } for (var i = index + 1; i < old.Length; ++i) + { m_Values[i - 1] = old[i]; + } } } } @@ -1417,14 +1533,20 @@ namespace Server if (bitmask == (int)AosWeaponAttribute.DurabilityBonus && this is AosWeaponAttributes) { if (Owner is BaseWeapon weapon) + { weapon.ScaleDurability(); + } } else if (bitmask == (int)AosArmorAttribute.DurabilityBonus && this is AosArmorAttributes) { if (Owner is BaseArmor armor) + { armor.ScaleDurability(); + } else if (Owner is BaseClothing clothing) + { clothing.ScaleDurability(); + } } if (Owner.Parent is Mobile m) @@ -1455,10 +1577,14 @@ namespace Server while (currentBit != mask) { if ((ourNames & currentBit) != 0) + { ++index; + } if (currentBit == 0x80000000) + { return -1; + } currentBit <<= 1; } diff --git a/Projects/UOContent/Misc/BuffIcons.cs b/Projects/UOContent/Misc/BuffIcons.cs index 36a1b7442..a4f7a3105 100644 --- a/Projects/UOContent/Misc/BuffIcons.cs +++ b/Projects/UOContent/Misc/BuffIcons.cs @@ -108,36 +108,49 @@ namespace Server public TextDefinition Args { get; } - public static void Initialize() + public static void Configure() { Enabled = ServerConfiguration.GetOrUpdateSetting("buffIcons.enable", Core.ML); + } + public static void Initialize() + { if (Enabled) + { EventSink.ClientVersionReceived += ResendBuffsOnClientVersionReceived; + } } public static void ResendBuffsOnClientVersionReceived(NetState ns, ClientVersion cv) { if (ns.Mobile is PlayerMobile pm) + { Timer.DelayCall(pm.ResendBuffs); + } } public static void AddBuff(Mobile m, BuffInfo b) { if (m is PlayerMobile pm) + { pm.AddBuff(b); + } } public static void RemoveBuff(Mobile m, BuffInfo b) { if (m is PlayerMobile pm) + { pm.RemoveBuff(b); + } } public static void RemoveBuff(Mobile m, BuffIcon b) { if (m is PlayerMobile pm) + { pm.RemoveBuff(b); + } } } @@ -235,7 +248,9 @@ namespace Server Stream.Fill(4); if (length < TimeSpan.Zero) + { length = TimeSpan.Zero; + } Stream.Write((short)length.TotalSeconds); // Time in seconds diff --git a/Projects/UOContent/Misc/ClientVerification.cs b/Projects/UOContent/Misc/ClientVerification.cs index 3e65afac0..fab83511b 100644 --- a/Projects/UOContent/Misc/ClientVerification.cs +++ b/Projects/UOContent/Misc/ClientVerification.cs @@ -7,7 +7,7 @@ using Server.Network; namespace Server.Misc { - public class ClientVerification + public static class ClientVerification { private static bool m_DetectClientRequirement; private static OldClientResponse m_OldClientResponse; @@ -25,7 +25,7 @@ namespace Server.Misc public static TimeSpan KickDelay { get; set; } - public static void Initialize() + public static void Configure() { m_DetectClientRequirement = ServerConfiguration.GetOrUpdateSetting("clientVerification.enable", true); m_OldClientResponse = @@ -36,7 +36,10 @@ namespace Server.Misc TimeSpan.FromHours(25) ); KickDelay = ServerConfiguration.GetOrUpdateSetting("clientVerification.kickDelay", TimeSpan.FromSeconds(20.0)); + } + public static void Initialize() + { EventSink.ClientVersionReceived += EventSink_ClientVersionReceived; if (m_DetectClientRequirement) @@ -49,12 +52,14 @@ namespace Server.Misc if (info.FileMajorPart != 0 || info.FileMinorPart != 0 || info.FileBuildPart != 0 || info.FilePrivatePart != 0) + { Required = new ClientVersion( info.FileMajorPart, info.FileMinorPart, info.FileBuildPart, info.FilePrivatePart ); + } } } @@ -75,7 +80,9 @@ namespace Server.Misc string kickMessage = null; if (state.Mobile?.AccessLevel != AccessLevel.Player) + { return; + } if (Required != null && version < Required && (m_OldClientResponse == OldClientResponse.Kick || m_OldClientResponse == OldClientResponse.LenientKick && @@ -88,11 +95,17 @@ namespace Server.Misc else if (!AllowGod || !AllowRegular || !AllowUOTD) { if (!AllowGod && version.Type == ClientType.God) + { 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."; + } else if (!AllowUOTD && state.IsUOTDClient) + { kickMessage = "This server does not allow UO:TD clients to connect."; + } if (!AllowGod && !AllowRegular && !AllowUOTD) { @@ -105,11 +118,17 @@ namespace Server.Misc else if (kickMessage != null) { if (AllowRegular && AllowUOTD) + { kickMessage += " You can use regular or UO:TD clients."; + } else if (AllowRegular) + { kickMessage += " You can use regular clients."; + } else if (AllowUOTD) + { kickMessage += " You can use UO:TD clients."; + } } } @@ -162,11 +181,13 @@ namespace Server.Misc from.SendMessage("You will be reminded of this again."); if (m_OldClientResponse == OldClientResponse.LenientKick) + { from.SendMessage( "Old clients will be kicked after {0} days of character age and {1} hours of play time", m_AgeLeniency, m_GameTimeLeniency ); + } Timer.DelayCall(TimeSpan.FromMinutes(Utility.Random(5, 15)), SendAnnoyGump, from); } diff --git a/Projects/UOContent/Misc/CrashGuard.cs b/Projects/UOContent/Misc/CrashGuard.cs index d1d22de41..60482e214 100644 --- a/Projects/UOContent/Misc/CrashGuard.cs +++ b/Projects/UOContent/Misc/CrashGuard.cs @@ -8,11 +8,18 @@ namespace Server.Misc { public static class CrashGuard { - // TODO: Make this configurable - private const bool Enabled = true; - private const bool SaveBackup = true; - private const bool RestartServer = true; - private const bool GenerateReport = true; + private static bool Enabled; + private static bool SaveBackup; + private static bool RestartServer; // Disable this if using a daemon/service + private static bool GenerateReport; + + public static void Configure() + { + Enabled = ServerConfiguration.GetOrUpdateSetting("crashGuard.enabled", true); + SaveBackup = ServerConfiguration.GetOrUpdateSetting("crashGuard.saveBackup", true); + RestartServer = ServerConfiguration.GetOrUpdateSetting("crashGuard.restartServer", true); + GenerateReport = ServerConfiguration.GetOrUpdateSetting("crashGuard.generateReport", true); + } public static void Initialize() { diff --git a/Projects/UOContent/Misc/Email.cs b/Projects/UOContent/Misc/Email.cs index b33562e5b..86eedd10c 100644 --- a/Projects/UOContent/Misc/Email.cs +++ b/Projects/UOContent/Misc/Email.cs @@ -18,7 +18,10 @@ namespace Server.Misc /// public static void SendQueueEmail(PageEntry entry, string pageType) { - if (!EmailConfiguration.EmailEnabled) return; + if (!EmailConfiguration.EmailEnabled) + { + return; + } var sender = entry.Sender; var time = DateTime.UtcNow; @@ -75,7 +78,10 @@ namespace Server.Misc /// public static void SendCrashEmail(string filePath) { - if (EmailConfiguration.EmailEnabled) return; + if (EmailConfiguration.EmailEnabled) + { + return; + } var message = new MimeMessage(); message.From.Add(EmailConfiguration.FromAddress); @@ -96,7 +102,10 @@ namespace Server.Misc /// private static async void SendAsync(MimeMessage message) { - if (!EmailConfiguration.EmailEnabled) return; + if (!EmailConfiguration.EmailEnabled) + { + return; + } var now = DateTime.UtcNow; var messageID = $"<{now:yyyyMMdd}.{now:HHmmssff}@{EmailConfiguration.EmailServer}>"; @@ -106,6 +115,7 @@ namespace Server.Misc var delay = EmailConfiguration.EmailSendRetryDelay; for (var i = 0; i < EmailConfiguration.EmailSendRetryCount; i++) + { try { using var client = new SmtpClient(); @@ -130,6 +140,7 @@ namespace Server.Misc await Task.Delay(delay * 1000); } + } } } } diff --git a/Projects/UOContent/Misc/Emitter.cs b/Projects/UOContent/Misc/Emitter.cs index 65506af5c..f5d3bcf06 100644 --- a/Projects/UOContent/Misc/Emitter.cs +++ b/Projects/UOContent/Misc/Emitter.cs @@ -7,24 +7,16 @@ namespace Server { public class AssemblyEmitter { - private readonly AssemblyBuilder m_AssemblyBuilder; private readonly ModuleBuilder m_ModuleBuilder; - private AppDomain m_AppDomain; - private string m_AssemblyName; - public AssemblyEmitter(string assemblyName) { - m_AssemblyName = assemblyName; - - m_AppDomain = AppDomain.CurrentDomain; - - m_AssemblyBuilder = AssemblyBuilder.DefineDynamicAssembly( + var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly( new AssemblyName(assemblyName), AssemblyBuilderAccess.Run ); - m_ModuleBuilder = m_AssemblyBuilder.DefineDynamicModule(assemblyName); + m_ModuleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName); } public TypeBuilder DefineType(string typeName, TypeAttributes attrs, Type parentType) => diff --git a/Projects/UOContent/Misc/Notoriety.cs b/Projects/UOContent/Misc/Notoriety.cs index e4ee30d27..4a5760641 100644 --- a/Projects/UOContent/Misc/Notoriety.cs +++ b/Projects/UOContent/Misc/Notoriety.cs @@ -52,7 +52,7 @@ namespace Server.Misc { if (from == GuildStatus.Waring && target == GuildStatus.Waring) return true; - + return false; }*/ @@ -193,7 +193,7 @@ namespace Server.Misc (fromGuild == targetGuild || fromGuild.IsAlly(targetGuild) || fromGuild.IsEnemy(targetGuild))) return true; // Guild allies or enemies can be harmful - if (bcTarg?.Controlled == true || bcTarg?.Summoned == true && bcTarg?.SummonMaster != @from) + if (bcTarg?.Controlled == true || bcTarg?.Summoned == true && bcTarg?.SummonMaster != from) return false; // Cannot harm other controlled mobiles if (target.Player) diff --git a/Projects/UOContent/Misc/RegenRates.cs b/Projects/UOContent/Misc/RegenRates.cs index c1664774e..0a2ebecd9 100644 --- a/Projects/UOContent/Misc/RegenRates.cs +++ b/Projects/UOContent/Misc/RegenRates.cs @@ -82,7 +82,7 @@ namespace Server.Misc var points = (int)(from.Skills.Focus.Value * 0.1); - if (@from is BaseCreature creature && creature.IsParagon || from is Leviathan) + if (from is BaseCreature creature && creature.IsParagon || from is Leviathan) points += 40; var cappedPoints = AosAttributes.GetValue(from, AosAttribute.RegenStam); @@ -130,7 +130,7 @@ namespace Server.Misc var totalPoints = focusPoints + medPoints + (from.Meditating ? medPoints > 13.0 ? 13.0 : medPoints : 0.0); - if (@from is BaseCreature creature && creature.IsParagon || from is Leviathan) + if (from is BaseCreature creature && creature.IsParagon || from is Leviathan) totalPoints += 40; var cappedPoints = AosAttributes.GetValue(from, AosAttribute.RegenMana); diff --git a/Projects/UOContent/Misc/ServerList.cs b/Projects/UOContent/Misc/ServerList.cs index 32d9d6bf7..d1c84028a 100644 --- a/Projects/UOContent/Misc/ServerList.cs +++ b/Projects/UOContent/Misc/ServerList.cs @@ -43,16 +43,21 @@ namespace Server.Misc public static bool AutoDetect { get; private set; } - public static void Initialize() + public static void Configure() { Address = ServerConfiguration.GetOrUpdateSetting("serverListing.address", null); AutoDetect = ServerConfiguration.GetOrUpdateSetting("serverListing.autoDetect", true); ServerName = ServerConfiguration.GetOrUpdateSetting("serverListing.serverName", "ModernUO"); + } + public static void Initialize() + { if (Address == null) { if (AutoDetect) + { AutoDetection(); + } } else { @@ -77,7 +82,9 @@ namespace Server.Misc { ipep = (IPEndPoint)ns.Connection.RemoteEndPoint; if (!IsPrivateNetwork(ipep.Address) && m_PublicAddress != null) + { localAddress = m_PublicAddress; + } } e.AddServer(ServerName, new IPEndPoint(localAddress, localPort)); @@ -97,23 +104,31 @@ namespace Server.Misc m_PublicAddress = FindPublicAddress(); if (m_PublicAddress != null) + { Console.WriteLine("done ({0})", m_PublicAddress); + } else + { Console.WriteLine("failed"); + } } } private static void Resolve(string addr, out IPAddress outValue) { if (IPAddress.TryParse(addr, out outValue)) + { return; + } try { var iphe = Dns.GetHostEntry(addr); if (iphe.AddressList.Length > 0) + { outValue = iphe.AddressList[^1]; + } } catch { diff --git a/Projects/UOContent/Misc/SkillCheck.cs b/Projects/UOContent/Misc/SkillCheck.cs index 02bf4459f..c1d9741a6 100644 --- a/Projects/UOContent/Misc/SkillCheck.cs +++ b/Projects/UOContent/Misc/SkillCheck.cs @@ -156,7 +156,7 @@ namespace Server.Misc if (from is BaseCreature creature && creature.Controlled) gc *= 2; - if (from.Alive && (gc >= Utility.RandomDouble() && AllowGain(@from, skill, amObj) || skill.Base < 10.0)) + if (from.Alive && (gc >= Utility.RandomDouble() && AllowGain(from, skill, amObj) || skill.Base < 10.0)) Gain(from, skill); return success; diff --git a/Projects/UOContent/Misc/uoamVendors.cs b/Projects/UOContent/Misc/uoamVendors.cs index eb2cd5bb8..ae0b9af02 100644 --- a/Projects/UOContent/Misc/uoamVendors.cs +++ b/Projects/UOContent/Misc/uoamVendors.cs @@ -3,8 +3,6 @@ using System.Collections.Generic; using System.IO; using Server.Engines.Spawners; -// Version 0.8 - namespace Server { public class UOAMVendorGenerator diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/BaseMount.cs b/Projects/UOContent/Mobiles/Animals/Mounts/BaseMount.cs index 293d25d7c..e938877d1 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/BaseMount.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/BaseMount.cs @@ -232,8 +232,8 @@ namespace Server.Mobiles if (from.InRange(this, 1)) { var canAccess = from.AccessLevel >= AccessLevel.GameMaster - || Controlled && ControlMaster == @from - || Summoned && SummonMaster == @from; + || Controlled && ControlMaster == from + || Summoned && SummonMaster == from; if (canAccess) { diff --git a/Projects/UOContent/Mobiles/BaseCreature.cs b/Projects/UOContent/Mobiles/BaseCreature.cs index 65b2b6e5c..67a5db71b 100644 --- a/Projects/UOContent/Mobiles/BaseCreature.cs +++ b/Projects/UOContent/Mobiles/BaseCreature.cs @@ -144,7 +144,9 @@ namespace Server.Mobiles var objs = t.GetCustomAttributes(typeof(FriendlyNameAttribute), false); if (objs.Length > 0) + { return (objs[0] as FriendlyNameAttribute)?.FriendlyName ?? ""; + } } return t.Name; @@ -339,7 +341,9 @@ namespace Server.Mobiles ) { if (iRangePerception == OldRangePerception) + { iRangePerception = DefaultRangePerception; + } m_Loyalty = MaxLoyalty; // Wonderfully Happy @@ -382,7 +386,9 @@ namespace Server.Mobiles speechType?.OnConstruct(this); if (IsInvulnerable && !Core.AOS) + { NameHue = 0x35; + } GenerateLoot(true); } @@ -404,7 +410,9 @@ namespace Server.Mobiles get { if (NameMod == null && base.Name == null) + { return DefaultName; + } return base.Name; } @@ -429,7 +437,9 @@ namespace Server.Mobiles { m_IsStabled = value; if (m_IsStabled) + { StopDeleteTimer(); + } } } @@ -453,11 +463,18 @@ namespace Server.Mobiles set { if (m_Paragon == value) + { return; + } + if (value) + { Paragon.Convert(this); + } else + { Paragon.UnConvert(this); + } m_Paragon = value; @@ -517,14 +534,18 @@ namespace Server.Mobiles get { if (!Summoned) + { return false; + } var type = GetType(); var contains = false; for (var i = 0; !contains && i < m_AnimateDeadTypes.Length; ++i) + { contains = type == m_AnimateDeadTypes[i]; + } return contains; } @@ -607,7 +628,7 @@ namespace Server.Mobiles recently. Either way, this is, or was, accurate OSI behavior, and just entirely removing it was incorrect. OSI followers were distracted by being attacked well into AoS, at very least. - + */ public virtual bool CanBeDistracted => !Core.ML; @@ -627,7 +648,9 @@ namespace Server.Mobiles m_CurrentAI = value; if (m_CurrentAI == AIType.AI_Use_Default) + { m_CurrentAI = m_DefaultAI; + } ChangeAIType(m_CurrentAI); } @@ -699,7 +722,9 @@ namespace Server.Mobiles set { if (m_Controlled == value) + { return; + } m_Controlled = value; Delta(MobileDelta.Noto); @@ -715,13 +740,17 @@ namespace Server.Mobiles set { if (m_ControlMaster == value || this == value) + { return; + } RemoveFollowers(); m_ControlMaster = value; AddFollowers(); if (m_ControlMaster != null) + { StopDeleteTimer(); + } Delta(MobileDelta.Noto); } @@ -734,7 +763,9 @@ namespace Server.Mobiles set { if (m_SummonMaster == value || this == value) + { return; + } RemoveFollowers(); m_SummonMaster = value; @@ -798,7 +829,9 @@ namespace Server.Mobiles set { if (m_bSummoned == value) + { return; + } NextReacquireTime = Core.TickCount; @@ -896,7 +929,9 @@ namespace Server.Mobiles get { if (Owners == null || Owners.Count == 0) + { return null; + } return Owners[^1]; } @@ -927,7 +962,9 @@ namespace Server.Mobiles get { if (m_DeleteTimer?.Running == true) + { return m_DeleteTimer.Next - DateTime.UtcNow; + } return TimeSpan.Zero; } @@ -1125,14 +1162,20 @@ namespace Server.Mobiles if (m_MLQuests == null) { if (StaticMLQuester) + { m_MLQuests = MLQuestSystem.FindQuestList(GetType()); + } else + { m_MLQuests = ConstructQuestList(); + } if (m_MLQuests == null) + { return MLQuestSystem .EmptyList; // return EmptyList, but don't cache it (run construction again next time) + } } return m_MLQuests; @@ -1144,38 +1187,57 @@ namespace Server.Mobiles public virtual bool IsEnemy(Mobile m) { if (OppositionGroup?.IsEnemy(this, m) == true) + { return true; + } if (m is BaseGuard) + { return false; + } if (GetFactionAllegiance(m) == Allegiance.Ally) + { return false; + } var ourEthic = EthicAllegiance; var pl = Ethics.Player.Find(m, true); if (pl?.IsShielded == true && (ourEthic == null || ourEthic == pl.Ethic)) + { return false; + } if (m is PlayerMobile mobile && mobile.HonorActive) + { return false; + } if (!(m is BaseCreature c) || m is MilitiaFighter) + { return true; + } if (TransformationSpellHelper.UnderTransformation(m, typeof(EtherealVoyageSpell))) + { return false; + } if (FightMode == FightMode.Evil && m.Karma < 0 || c.FightMode == FightMode.Evil && Karma < 0) + { return true; + } return m_Team != c.m_Team || (m_bSummoned || m_Controlled) != (c.m_bSummoned || c.m_Controlled); } public override string ApplyNameSuffix(string suffix) { - if (IsParagon && !GivesMLMinorArtifact) suffix = suffix.Length == 0 ? "(Paragon)" : $"{suffix} (Paragon)"; + if (IsParagon && !GivesMLMinorArtifact) + { + suffix = suffix.Length == 0 ? "(Paragon)" : $"{suffix} (Paragon)"; + } return base.ApplyNameSuffix(suffix); } @@ -1191,9 +1253,13 @@ namespace Server.Mobiles PlaySound(GetAngerSound()); if (Body.IsAnimal) + { Animate(10, 5, 1, true, false, 0); + } else if (Body.IsMonster) + { Animate(18, 5, 1, true, false, 0); + } Loyalty -= 3; return false; @@ -1204,12 +1270,16 @@ namespace Server.Mobiles public virtual double GetControlChance(Mobile m, bool useBaseSkill = false) { if (MinTameSkill <= 29.1 || m_bSummoned || m.AccessLevel >= AccessLevel.GameMaster) + { return 1.0; + } var dMinTameSkill = MinTameSkill; if (dMinTameSkill > -24.9 && AnimalTaming.CheckMastery(m, this)) + { dMinTameSkill = -24.9; + } var taming = (int)((useBaseSkill ? m.Skills.AnimalTaming.Base : m.Skills.AnimalTaming.Value) * 10); @@ -1226,10 +1296,14 @@ namespace Server.Mobiles var LoreMod = 6; if (SkillBonus < 0) + { SkillMod = 28; + } if (LoreBonus < 0) + { LoreMod = 14; + } SkillBonus *= SkillMod; LoreBonus *= LoreMod; @@ -1243,17 +1317,25 @@ namespace Server.Mobiles bonus = weighted - difficulty; if (bonus <= 0) + { bonus *= 14; + } else + { bonus *= 6; + } } chance += bonus; if (chance >= 0 && chance < 200) + { chance = 200; + } else if (chance > 990) + { chance = 990; + } chance -= (MaxLoyalty - m_Loyalty) * 10; @@ -1265,10 +1347,14 @@ namespace Server.Mobiles var oldHits = Hits; if (Core.AOS && !Summoned && Controlled && Utility.RandomDouble() < 0.2) + { amount = (int)(amount * BonusPetDamageScalar); + } if (EvilOmenSpell.TryEndEffect(this)) + { amount = (int)(amount * 1.25); + } var oath = BloodOathSpell.GetBloodOath(from); @@ -1281,12 +1367,14 @@ namespace Server.Mobiles base.Damage(amount, from); if (SubdueBeforeTame && !Controlled && oldHits > HitsMax / 10 && Hits <= HitsMax / 10) + { PublicOverheadMessage( MessageType.Regular, 0x3B2, false, "* The creature has been beaten into subjugation! *" ); + } } public override void SetLocation(Point3D newLocation, bool isTeleport) @@ -1294,13 +1382,17 @@ namespace Server.Mobiles base.SetLocation(newLocation, isTeleport); if (isTeleport) + { AIObject?.OnTeleported(); + } } public override void OnBeforeSpawn(Point3D location, Map m) { if (Paragon.CheckConvert(this, location, m)) + { IsParagon = true; + } base.OnBeforeSpawn(location, m); } @@ -1308,15 +1400,21 @@ namespace Server.Mobiles public override ApplyPoisonResult ApplyPoison(Mobile from, Poison poison) { if (!Alive || IsDeadPet) + { return ApplyPoisonResult.Immune; + } if (EvilOmenSpell.TryEndEffect(this)) + { poison = PoisonImpl.IncreaseLevel(poison); + } var result = base.ApplyPoison(from, poison); if (from != null && result == ApplyPoisonResult.Poisoned && PoisonTimer is PoisonImpl.PoisonTimer timer) + { timer.From = from; + } return result; } @@ -1345,16 +1443,24 @@ namespace Server.Mobiles public override void OnDamage(int amount, Mobile from, bool willKill) { if (BardPacified && (HitsMax - Hits) * 0.001 > Utility.RandomDouble()) + { Unpacify(); + } int disruptThreshold; // NPCs can use bandages too! if (!Core.AOS) + { disruptThreshold = 0; + } else if (from?.Player == true) + { disruptThreshold = 18; + } else + { disruptThreshold = 25; + } if (amount > disruptThreshold) { @@ -1364,20 +1470,27 @@ namespace Server.Mobiles } if (Confidence.IsRegenerating(this)) + { Confidence.StopRegenerating(this); + } WeightOverloading.FatigueOnDamage(this, amount); var speechType = SpeechType; if (speechType != null && !willKill) + { speechType.OnDamage(this, amount); + } ReceivedHonorContext?.OnTargetDamaged(from, amount); if (!willKill) { - if (CanBeDistracted && ControlOrder == OrderType.Follow) CheckDistracted(from); + if (CanBeDistracted && ControlOrder == OrderType.Follow) + { + CheckDistracted(from); + } } else if (from is PlayerMobile mobile) { @@ -1389,7 +1502,10 @@ namespace Server.Mobiles public virtual void OnDamagedBySpell(Mobile from) { - if (CanBeDistracted && ControlOrder == OrderType.Follow) CheckDistracted(from); + if (CanBeDistracted && ControlOrder == OrderType.Follow) + { + CheckDistracted(from); + } } public virtual void OnHarmfulSpell(Mobile from) @@ -1412,14 +1528,20 @@ namespace Server.Mobiles corpse.Animated) { if (corpse.Animated) + { corpse.SendLocalizedMessageTo(from, 500464); // Use this on corpses to carve away meat and hide + } else + { from.SendLocalizedMessage(500485); // You see nothing useful to carve from the corpse. + } } else { if (Core.ML && from.Race == Race.Human) + { hides = (int)Math.Ceiling(hides * 1.1); // 10% bonus only applies to hides, ore & logs + } if (corpse.Map == Map.Felucca) { @@ -1451,11 +1573,17 @@ namespace Server.Mobiles if (meat != 0) { if (MeatType == MeatType.Ribs) + { corpse.AddCarvedItem(new RawRibs(meat), from); + } else if (MeatType == MeatType.Bird) + { corpse.AddCarvedItem(new RawBird(meat), from); + } else if (MeatType == MeatType.LambLeg) + { corpse.AddCarvedItem(new RawLambLeg(meat), from); + } from.SendLocalizedMessage(500467); // You carve some meat, which remains on the corpse. } @@ -1493,13 +1621,21 @@ namespace Server.Mobiles else { if (HideType == HideType.Regular) + { corpse.DropItem(new Hides(hides)); + } else if (HideType == HideType.Spined) + { corpse.DropItem(new SpinedHides(hides)); + } else if (HideType == HideType.Horned) + { corpse.DropItem(new HornedHides(hides)); + } else if (HideType == HideType.Barbed) + { corpse.DropItem(new BarbedHides(hides)); + } from.SendLocalizedMessage(500471); // You skin it, and the hides are now in the corpse. } @@ -1547,7 +1683,9 @@ namespace Server.Mobiles corpse.Carved = true; if (corpse.IsCriminalAction(from)) + { from.CriminalAction(true); + } } } @@ -1576,13 +1714,17 @@ namespace Server.Mobiles // Version 1 writer.Write(RangeHome); - var i = 0; - writer.Write(m_SpellAttack.Count); - for (i = 0; i < m_SpellAttack.Count; i++) writer.Write(m_SpellAttack[i].ToString()); + for (var i = 0; i < m_SpellAttack.Count; i++) + { + writer.Write(m_SpellAttack[i].ToString()); + } writer.Write(m_SpellDefense.Count); - for (i = 0; i < m_SpellDefense.Count; i++) writer.Write(m_SpellDefense[i].ToString()); + for (var i = 0; i < m_SpellDefense.Count; i++) + { + writer.Write(m_SpellDefense[i].ToString()); + } // Version 2 writer.Write((int)FightMode); @@ -1599,7 +1741,9 @@ namespace Server.Mobiles writer.Write(m_bSummoned); if (m_bSummoned) + { writer.WriteDeltaTime(SummonEnd); + } writer.Write(ControlSlots); @@ -1654,7 +1798,9 @@ namespace Server.Mobiles writer.Write(Friends?.Count > 0); if (Friends?.Count > 0) + { writer.Write(Friends, true); + } // Version 14 writer.Write(RemoveIfUntamed); @@ -1662,9 +1808,13 @@ namespace Server.Mobiles // Version 17 if (IsStabled || Controlled && ControlMaster != null) + { writer.Write(TimeSpan.Zero); + } else + { writer.Write(DeleteTimeLeft); + } // Version 18 writer.Write(CorpseNameOverride); @@ -1692,7 +1842,9 @@ namespace Server.Mobiles m_CurrentSpeed = reader.ReadDouble(); if (RangePerception == OldRangePerception) + { RangePerception = DefaultRangePerception; + } m_Home.X = reader.ReadInt(); m_Home.Y = reader.ReadInt(); @@ -1708,7 +1860,10 @@ namespace Server.Mobiles var str = reader.ReadString(); var type = Type.GetType(str); - if (type != null) m_SpellAttack.Add(type); + if (type != null) + { + m_SpellAttack.Add(type); + } } iCount = reader.ReadInt(); @@ -1717,7 +1872,10 @@ namespace Server.Mobiles var str = reader.ReadString(); var type = Type.GetType(str); - if (type != null) m_SpellDefense.Add(type); + if (type != null) + { + m_SpellDefense.Add(type); + } } } else @@ -1738,7 +1896,9 @@ namespace Server.Mobiles MinTameSkill = reader.ReadDouble(); if (version < 9) + { reader.ReadDouble(); + } m_bTamable = reader.ReadBool(); m_bSummoned = reader.ReadBool(); @@ -1762,15 +1922,23 @@ namespace Server.Mobiles } if (version >= 3) + { m_Loyalty = reader.ReadInt(); + } else + { m_Loyalty = MaxLoyalty; // Wonderfully Happy + } if (version >= 4) + { CurrentWayPoint = reader.ReadItem() as WayPoint; + } if (version >= 5) + { m_SummonMaster = reader.ReadMobile(); + } if (version >= 6) { @@ -1800,9 +1968,13 @@ namespace Server.Mobiles } if (version >= 8) + { Owners = reader.ReadStrongMobileList(); + } else + { Owners = new List(); + } if (version >= 10) { @@ -1813,22 +1985,36 @@ namespace Server.Mobiles } if (version >= 11) + { m_HasGeneratedLoot = reader.ReadBool(); + } else + { m_HasGeneratedLoot = true; + } if (version >= 12) + { m_Paragon = reader.ReadBool(); + } else + { m_Paragon = false; + } if (version >= 13 && reader.ReadBool()) + { Friends = reader.ReadStrongMobileList(); + } else if (version < 13 && m_ControlOrder >= OrderType.Unfriend) + { ++m_ControlOrder; + } if (version < 16 && Loyalty != MaxLoyalty) + { Loyalty *= 10; + } var activeSpeed = ActiveSpeed; var passiveSpeed = PassiveSpeed; @@ -1837,22 +2023,34 @@ namespace Server.Mobiles 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) { @@ -1863,27 +2061,40 @@ namespace Server.Mobiles var deleteTime = TimeSpan.Zero; if (version >= 17) + { deleteTime = reader.ReadTimeSpan(); + } if (deleteTime > TimeSpan.Zero || LastOwner != null && !Controlled && !IsStabled) { if (deleteTime == TimeSpan.Zero) + { deleteTime = TimeSpan.FromDays(3.0); + } m_DeleteTimer = new DeleteTimer(this, deleteTime); m_DeleteTimer.Start(); } if (version >= 18) + { CorpseNameOverride = reader.ReadString(); + } if (version >= 19) + { HomeMap = reader.ReadMap(); + } - if (version <= 14 && m_Paragon && Hue == 0x31) Hue = Paragon.Hue; // Paragon hue fixed, should now be 0x501. + if (version <= 14 && m_Paragon && Hue == 0x31) + { + Hue = Paragon.Hue; // Paragon hue fixed, should now be 0x501. + } if (Core.AOS && NameHue == 0x35) + { NameHue = -1; + } CheckStatTimers(); @@ -1892,7 +2103,9 @@ namespace Server.Mobiles AddFollowers(); if (IsAnimatedDead) + { AnimateDeadSpell.Register(m_SummonMaster, this); + } } public virtual bool IsHumanInTown() => Body.IsHuman && Region.IsPartOf(); @@ -1937,9 +2150,14 @@ namespace Server.Mobiles public override bool OnDragDrop(Mobile from, Item dropped) { if (CheckFeed(from, dropped)) + { return true; + } + if (CheckGold(from, dropped)) + { return true; + } // Note: Yes, this happens for all questers (regardless of type, e.g. escorts), // even if they can't offer you anything at the moment @@ -2003,7 +2221,9 @@ namespace Server.Mobiles { mobile.AllFollowers.Remove(this); if (mobile.AutoStabled.Contains(this)) + { mobile.AutoStabled.Remove(this); + } } } else if (m_SummonMaster != null) @@ -2013,10 +2233,14 @@ namespace Server.Mobiles } if (m_ControlMaster?.Followers < 0) + { m_ControlMaster.Followers = 0; + } if (m_SummonMaster?.Followers < 0) + { m_SummonMaster.Followers = 0; + } } public void AddFollowers() @@ -2025,13 +2249,17 @@ namespace Server.Mobiles { m_ControlMaster.Followers += ControlSlots; if (m_ControlMaster is PlayerMobile mobile) + { mobile.AllFollowers.Add(this); + } } else if (m_SummonMaster != null) { m_SummonMaster.Followers += ControlSlots; if (m_SummonMaster is PlayerMobile mobile) + { mobile.AllFollowers.Add(this); + } } } @@ -2039,7 +2267,9 @@ namespace Server.Mobiles { if (AutoDispel && attacker is BaseCreature creature && creature.IsDispellable && AutoDispelChance > Utility.RandomDouble()) + { Dispel(creature); + } } public virtual void Dispel(Mobile m) @@ -2065,12 +2295,16 @@ namespace Server.Mobiles defender.ApplyPoison(this, p); if (Controlled) + { CheckSkill(SkillName.Poisoning, 0, Skills.Poisoning.Cap); + } } if (AutoDispel && defender is BaseCreature creature && creature.IsDispellable && AutoDispelChance > Utility.RandomDouble()) + { Dispel(creature); + } } public override void OnAfterDelete() @@ -2090,10 +2324,14 @@ namespace Server.Mobiles FocusMob = null; if (IsAnimatedDead) + { AnimateDeadSpell.Unregister(m_SummonMaster, this); + } if (MLQuestSystem.Enabled) + { MLQuestSystem.HandleDeletion(this); + } base.OnAfterDelete(); } @@ -2101,13 +2339,17 @@ namespace Server.Mobiles public void DebugSay(string text) { if (Debug) + { PublicOverheadMessage(MessageType.Regular, 41, false, text); + } } public void DebugSay(string format, params object[] args) { if (Debug) + { PublicOverheadMessage(MessageType.Regular, 41, false, string.Format(format, args)); + } } /* @@ -2120,7 +2362,9 @@ namespace Server.Mobiles public virtual double GetFightModeRanking(Mobile m, FightMode acqType, bool bPlayerOnly) { if (bPlayerOnly && !m.Player) + { return double.MinValue; + } return acqType switch { @@ -2155,9 +2399,13 @@ namespace Server.Mobiles var iCount = 0; foreach (var m in GetMobilesInRange(iRange)) + { if (m != this && m is BaseCreature creature && !creature.Deleted && creature.Team == Team && CanSee(creature)) + { iCount++; + } + } return iCount; } @@ -2167,7 +2415,9 @@ namespace Server.Mobiles base.AggressiveAction(aggressor, criminal); if (ControlMaster != null && NotorietyHandlers.CheckAggressor(ControlMaster.Aggressors, aggressor)) + { aggressor.Aggressors.Add(AggressorInfo.Create(this, aggressor, true)); + } var ct = m_ControlOrder; @@ -2194,7 +2444,9 @@ namespace Server.Mobiles var pl = Ethics.Player.Find(aggressor, true); if (pl?.IsShielded == true) + { pl.FinishShield(); + } } if (aggressor.ChangingCombatant && (m_Controlled || m_bSummoned) && @@ -2214,13 +2466,17 @@ namespace Server.Mobiles public override bool OnMoveOver(Mobile m) { if (m is BaseCreature creature && !creature.Controlled) + { return !Alive || !creature.Alive || IsDeadBondedPet || creature.IsDeadBondedPet || Hidden && AccessLevel > AccessLevel.Player; + } if (Region.IsPartOf() && m is PlayerMobile pm && (pm.DuelContext?.Started != true || pm.DuelContext.Finished || pm.DuelPlayer?.Eliminated != false)) + { return true; + } return base.OnMoveOver(m); } @@ -2234,10 +2490,14 @@ namespace Server.Mobiles base.GetContextMenuEntries(from, list); if (Commandable) + { AIObject?.GetContextMenuEntries(from, list); + } if (m_bTamable && !m_Controlled && from.Alive) + { list.Add(new TameEntry(from, this)); + } AddCustomContextEntries(from, list); @@ -2256,7 +2516,9 @@ namespace Server.Mobiles var toTeach = skill.BaseFixedPoint / 3; if (toTeach > 420) + { toTeach = 420; + } list.Add(new TeachEntry((SkillName)i, this, from, toTeach > theirSkill.BaseFixedPoint)); } @@ -2273,9 +2535,13 @@ namespace Server.Mobiles var speechType = SpeechType; if (speechType?.OnSpeech(this, e.Mobile, e.Speech) == true) + { e.Handled = true; + } else if (!e.Handled && AIObject != null && e.Mobile.InRange(this, RangePerception)) + { AIObject.OnSpeech(e); + } } public override bool IsHarmfulCriminal(Mobile target) => @@ -2290,9 +2556,13 @@ namespace Server.Mobiles if (Controlled || Summoned) { if (m_ControlMaster?.Player == true) + { m_ControlMaster.CriminalAction(false); + } else if (m_SummonMaster?.Player == true) + { m_SummonMaster.CriminalAction(false); + } } } @@ -2301,7 +2571,9 @@ namespace Server.Mobiles base.DoHarmful(target, indirect); if (target == this || target == m_ControlMaster || target == m_SummonMaster || !Controlled && !Summoned) + { return; + } var list = Aggressors; @@ -2310,7 +2582,9 @@ namespace Server.Mobiles var ai = list[i]; if (ai.Attacker == target) + { return; + } } list = Aggressed; @@ -2322,9 +2596,13 @@ namespace Server.Mobiles if (ai.Defender == target) { if (m_ControlMaster?.Player == true && m_ControlMaster.CanBeHarmful(target, false)) + { m_ControlMaster.DoHarmful(target, true); + } else if (m_SummonMaster?.Player == true && m_SummonMaster.CanBeHarmful(target, false)) + { m_SummonMaster.DoHarmful(target, true); + } return; } @@ -2344,7 +2622,9 @@ namespace Server.Mobiles public virtual bool CheckIdle() { if (Combatant != null) + { return false; // in combat.. not idling + } if (m_IdleReleaseTime > DateTime.MinValue) { @@ -2360,11 +2640,14 @@ namespace Server.Mobiles } if (Utility.Random(100) < 95) + { return false; // not idling, but don't want to enter idle state + } m_IdleReleaseTime = DateTime.UtcNow + TimeSpan.FromSeconds(Utility.RandomMinMax(15, 25)); if (Body.IsHuman) + { switch (Utility.Random(2)) { case 0: @@ -2374,7 +2657,9 @@ namespace Server.Mobiles CheckedAnimate(6, 5, 1, true, false, 1); break; } + } else if (Body.IsAnimal) + { switch (Utility.Random(3)) { case 0: @@ -2387,7 +2672,9 @@ namespace Server.Mobiles CheckedAnimate(10, 5, 1, true, false, 1); break; } + } else if (Body.IsMonster) + { switch (Utility.Random(2)) { case 0: @@ -2397,6 +2684,7 @@ namespace Server.Mobiles CheckedAnimate(18, 5, 1, true, false, 1); break; } + } PlaySound(GetIdleSound()); return true; // entered idle state @@ -2411,7 +2699,9 @@ namespace Server.Mobiles public virtual void CheckedAnimate(int action, int frameCount, int repeatCount, bool forward, bool repeat, int delay) { if (!Mounted) + { Animate(action, frameCount, repeatCount, forward, repeat, delay); + } } private void CheckAIActive() @@ -2419,7 +2709,9 @@ namespace Server.Mobiles var map = Map; if (PlayerRangeSensitive && AIObject != null && map?.GetSector(Location).Active == true) + { AIObject.Activate(); + } } public override void OnCombatantChange() @@ -2429,7 +2721,9 @@ namespace Server.Mobiles Warmode = Combatant?.Deleted == false && Combatant.Alive; if (CanFly && Warmode) + { Flying = false; + } } protected override void OnMapChange(Map oldMap) @@ -2478,21 +2772,29 @@ namespace Server.Mobiles InRange(m.Location, 18) && !InRange(oldLocation, 18)) { if (Body.IsMonster) + { Animate(11, 5, 1, true, false, 1); + } PlaySound(GetAngerSound()); } /* End notice sound */ if (MLQuestSystem.Enabled && CanShout && m is PlayerMobile mobile) + { CheckShout(mobile, oldLocation); + } if (m_NoDupeGuards == m) + { return; + } if (!Body.IsHuman || Kills >= 5 || AlwaysMurderer || AlwaysAttackable || m.Kills < 5 || !m.InRange(Location, 12) || !m.Alive) + { return; + } var guardedRegion = Region.GetRegion(); @@ -2535,12 +2837,20 @@ namespace Server.Mobiles int i; for (i = 0; i < m_SpellAttack.Count; i++) + { if (m_SpellAttack[i] == type) + { return ActivatorUtil.CreateInstance(type, this, null) as Spell; + } + } for (i = 0; i < m_SpellDefense.Count; i++) + { if (m_SpellDefense[i] == type) + { return ActivatorUtil.CreateInstance(type, this, null) as Spell; + } + } return null; } @@ -2548,9 +2858,13 @@ namespace Server.Mobiles 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) @@ -2563,14 +2877,18 @@ namespace Server.Mobiles } if (DeathAdderCharmable && from.CanBeHarmful(this, false)) + { if (SummonFamiliarSpell.Table.TryGetValue(from, out var bc) && (bc as DeathAdder)?.Deleted == false) { from.SendAsciiMessage("You charm the snake. Select a target to attack."); from.Target = new DeathAdderCharmTarget(this); } + } if (MLQuestSystem.Enabled && CanGiveMLQuest && from is PlayerMobile mobile) + { MLQuestSystem.OnDoubleClick(this, mobile); + } base.OnDoubleClick(from); } @@ -2580,15 +2898,21 @@ namespace Server.Mobiles base.AddNameProperties(list); if (MLQuestSystem.Enabled && CanGiveMLQuest) + { list.Add(1072269); // Quest Giver + } if (Core.ML) { if (DisplayWeight) + { list.Add(TotalWeight == 1 ? 1072788 : 1072789, TotalWeight.ToString()); // Weight: ~1_WEIGHT~ stones + } if (m_ControlOrder == OrderType.Guard) + { list.Add(1080078); // guarding + } } if (Summoned && !(IsAnimatedDead || IsNecroFamiliar || this is Clone)) @@ -2598,9 +2922,13 @@ namespace Server.Mobiles else if (Controlled && Commandable) { if (IsBonded) // Intentional difference (showing ONLY bonded when bonded instead of bonded & tame) + { list.Add(1049608); // (bonded) + } else + { list.Add(502006); // (tame) + } } } @@ -2611,11 +2939,17 @@ namespace Server.Mobiles int number; if (Summoned) + { number = 1049646; // (summoned) + } else if (IsBonded) + { number = 1049608; // (bonded) + } else + { number = 502006; // (tame) + } PrivateOverheadMessage(MessageType.Regular, 0x3B2, number, from.NetState); } @@ -2632,10 +2966,14 @@ namespace Server.Mobiles var killer = LastKiller; if (killer is BaseCreature bc) + { killer = bc.GetMaster(); + } if (killer is PlayerMobile mobile && mobile.Young) + { treasureLevel = 0; + } } if (!Summoned && !NoKillAwards && !IsBonded) @@ -2643,12 +2981,17 @@ namespace Server.Mobiles if (treasureLevel >= 0) { if (m_Paragon && Paragon.ChestChance > Utility.RandomDouble()) + { PackItem(new ParagonChest(Name, treasureLevel)); + } else if ((Map == Map.Felucca || Map == Map.Trammel) && Utility.RandomDouble() <= TreasureMap.LootChance) + { PackItem(new TreasureMap(treasureLevel, Map)); + } } if (m_Paragon && Paragon.ChocolateIngredientChance > Utility.RandomDouble()) + { switch (Utility.Random(4)) { case 0: @@ -2664,6 +3007,7 @@ namespace Server.Mobiles PackItem(new Vanilla()); break; } + } } if (!Summoned && !NoKillAwards && !m_HasGeneratedLoot) @@ -2677,11 +3021,15 @@ namespace Server.Mobiles var bones = TheSummoningQuest.GetDaemonBonesFor(this); if (bones > 0) + { PackItem(new DaemonBone(bones)); + } } if (IsAnimatedDead) + { Effects.SendLocationEffect(Location, Map, 0x3728, 13, 1, 0x461, 4); + } var speechType = SpeechType; speechType?.OnDeath(this); @@ -2699,10 +3047,14 @@ namespace Server.Mobiles var de = list[i]; if (de.Damager == m || !(de.Damager is BaseCreature bc)) + { continue; + } if (bc.GetMaster() == m) + { bonus += de.DamageGiven; + } } return bonus; @@ -2711,9 +3063,14 @@ namespace Server.Mobiles public Mobile GetMaster() { if (Controlled && ControlMaster != null) + { return ControlMaster; + } + if (Summoned && SummonMaster != null) + { return SummonMaster; + } return null; } @@ -2725,7 +3082,9 @@ namespace Server.Mobiles for (var i = damageEntries.Count - 1; i >= 0; --i) { if (i >= damageEntries.Count) + { continue; + } var de = damageEntries[i]; @@ -2745,7 +3104,9 @@ namespace Server.Mobiles var master = subEntry.Damager; if (master?.Deleted != false || !master.Player) + { continue; + } var needNewSubEntry = true; @@ -2761,7 +3122,9 @@ namespace Server.Mobiles } if (needNewSubEntry) + { rights.Add(new DamageStore(master, subEntry.DamageGiven)); + } damage -= subEntry.DamageGiven; } @@ -2769,10 +3132,14 @@ namespace Server.Mobiles var m = de.Damager; if (m?.Deleted != false || !m.Player) + { continue; + } if (damage <= 0) + { continue; + } var needNewEntry = true; @@ -2788,7 +3155,9 @@ namespace Server.Mobiles } if (needNewEntry) + { rights.Add(new DamageStore(m, damage)); + } } if (rights.Count > 0) @@ -2799,19 +3168,29 @@ namespace Server.Mobiles ); // This would be the first valid person attacking it. Gets a 25% bonus. Per 1/19/07 Five on Friday if (rights.Count > 1) + { rights.Sort(); // Sort by damage + } var topDamage = rights[0].m_Damage; int minDamage; if (hitsMax >= 3000) + { minDamage = topDamage / 16; + } else if (hitsMax >= 1000) + { minDamage = topDamage / 8; + } else if (hitsMax >= 200) + { minDamage = topDamage / 4; + } else + { minDamage = topDamage / 2; + } for (var i = 0; i < rights.Count; ++i) { @@ -2829,12 +3208,16 @@ namespace Server.Mobiles if (GivesMLMinorArtifact) { if (MondainsLegacy.CheckArtifactChance(mob, this)) + { MondainsLegacy.GiveArtifactTo(mob); + } } else if (m_Paragon) { if (Paragon.CheckArtifactChance(mob, this)) + { Paragon.GiveArtifactTo(mob); + } } } @@ -2847,7 +3230,9 @@ namespace Server.Mobiles var sound = GetDeathSound(); if (sound >= 0) + { Effects.PlaySound(this, Map, sound); + } Warmode = false; @@ -2874,7 +3259,9 @@ namespace Server.Mobiles var info = aggressors[i]; if (info.Attacker.Combatant == this) + { info.Attacker.Combatant = null; + } } var aggressed = Aggressed; @@ -2884,7 +3271,9 @@ namespace Server.Mobiles var info = aggressed[i]; if (info.Defender.Combatant == this) + { info.Defender.Combatant = null; + } } var owner = ControlMaster; @@ -2893,7 +3282,9 @@ namespace Server.Mobiles !InLOS(owner)) { if (OwnerAbandonTime == DateTime.MinValue) + { OwnerAbandonTime = DateTime.UtcNow; + } } else { @@ -2931,7 +3322,9 @@ namespace Server.Mobiles var ds = list[i]; if (!ds.m_HasRight) + { continue; + } var party = Engines.PartySystem.Party.Get(ds.m_Mobile); @@ -2988,10 +3381,15 @@ namespace Server.Mobiles if (ds.m_Mobile is PlayerMobile pm) { - if (MLQuestSystem.Enabled) MLQuestSystem.HandleKill(pm, this); + if (MLQuestSystem.Enabled) + { + MLQuestSystem.HandleKill(pm, this); + } if (givenQuestKill) + { continue; + } var qs = pm.Quest; @@ -3013,7 +3411,9 @@ namespace Server.Mobiles base.OnDeath(c); if (DeleteCorpseOnDeath) + { c.Delete(); + } } } @@ -3031,16 +3431,22 @@ namespace Server.Mobiles public override bool CanBeHarmful(Mobile target, bool message, bool ignoreOurBlessedness) { if (target is BaseFactionGuard) + { return false; + } if (target is BaseCreature creature && creature.IsInvulnerable || target is PlayerVendor || target is TownCrier) { if (message) { if (target.Title == null) + { SendMessage("{0} cannot be harmed.", target.Name); + } else + { SendMessage("{0} {1} cannot be harmed.", target.Name, target.Title); + } } return false; @@ -3133,7 +3539,9 @@ namespace Server.Mobiles Summoning = true; if (controlled) + { creature.SetControlMaster(caster); + } creature.RangeHome = 10; creature.Summoned = true; @@ -3143,13 +3551,17 @@ namespace Server.Mobiles var pack = creature.Backpack; if (pack != null) + { for (var i = pack.Items.Count - 1; i >= 0; --i) { if (i >= pack.Items.Count) + { continue; + } pack.Items[i].Delete(); } + } new UnsummonTimer(caster, creature, duration).Start(); creature.SummonEnd = DateTime.UtcNow + duration; @@ -3194,7 +3606,10 @@ namespace Server.Mobiles if (target?.Alive == true && !target.IsDeadBondedPet && CanBeHarmful(target) && target.Map == Map && !IsDeadBondedPet && target.InRange(this, BreathRange) && InLOS(target) && !BardPacified) { - if (Core.TickCount - m_NextBreathTime < 30000 && Utility.RandomBool()) BreathStart(target); + if (Core.TickCount - m_NextBreathTime < 30000 && Utility.RandomBool()) + { + BreathStart(target); + } m_NextBreathTime = tc + (int)TimeSpan .FromSeconds(BreathMinDelay + Utility.RandomDouble() * (BreathMaxDelay - BreathMinDelay)) @@ -3257,10 +3672,14 @@ namespace Server.Mobiles eable.Free(); if (toRummage == null) + { return false; + } if (Backpack == null) + { return false; + } var items = toRummage.Items; @@ -3291,11 +3710,19 @@ namespace Server.Mobiles public override Mobile GetDamageMaster(Mobile damagee) { if (BardProvoked && damagee == BardTarget) + { return BardMaster; + } + if (m_Controlled && m_ControlMaster != null) + { return m_ControlMaster; + } + if (m_bSummoned && m_SummonMaster != null) + { return m_SummonMaster; + } return base.GetDamageMaster(damagee); } @@ -3304,7 +3731,10 @@ namespace Server.Mobiles { BardProvoked = true; - if (!Core.ML) PublicOverheadMessage(MessageType.Emote, EmoteHue, false, "*looks furious*"); + if (!Core.ML) + { + PublicOverheadMessage(MessageType.Emote, EmoteHue, false, "*looks furious*"); + } if (bSuccess) { @@ -3318,7 +3748,9 @@ namespace Server.Mobiles if (target is BaseCreature t) { if (t.Unprovokable || t.IsParagon && BaseInstrument.GetBaseDifficulty(t) >= 160.0) + { return; + } t.BardProvoked = true; @@ -3342,7 +3774,9 @@ namespace Server.Mobiles var name = Name; if (name == null || str.Length < name.Length) + { return false; + } var wordsString = str.Split(' '); var wordsName = name.Split(' '); @@ -3357,14 +3791,20 @@ namespace Server.Mobiles var word = wordsString[i]; if (Insensitive.Equals(word, wordName)) + { bFound = true; + } if (bWithAll && Insensitive.Equals(word, "all")) + { return true; + } } if (!bFound) + { return false; + } } return true; @@ -3375,20 +3815,32 @@ namespace Server.Mobiles var move = new List(); foreach (var m in master.GetMobilesInRange(3)) + { if (m is BaseCreature pet) + { if (pet.Controlled && pet.ControlMaster == master && !onlyBonded || pet.IsBonded) + { if (pet.ControlOrder == OrderType.Guard || pet.ControlOrder == OrderType.Follow || pet.ControlOrder == OrderType.Come) + { move.Add(pet); + } + } + } + } foreach (var m in move) + { m.MoveToWorld(loc, map); + } } public virtual void ResurrectPet() { if (!IsDeadPet) + { return; + } OnBeforeResurrect(); @@ -3417,7 +3869,9 @@ namespace Server.Mobiles !InLOS(owner)) { if (OwnerAbandonTime == DateTime.MinValue) + { OwnerAbandonTime = DateTime.UtcNow; + } } else { @@ -3430,7 +3884,9 @@ namespace Server.Mobiles public override bool CanBeDamaged() { if (IsDeadPet || IsInvulnerable) + { return false; + } return base.CanBeDamaged(); } @@ -3459,19 +3915,27 @@ namespace Server.Mobiles public void GoHome_Callback() { if (m_ReturnQueued && IsSpawnerBound()) + { if (!Map.GetSector(X, Y).Active) { SetLocation(Home, true); - if (!Map.GetSector(X, Y).Active) AIObject?.Deactivate(); + if (!Map.GetSector(X, Y).Active) + { + AIObject?.Deactivate(); + } } + } m_ReturnQueued = false; } public override void OnSectorActivate() { - if (PlayerRangeSensitive) AIObject?.Activate(); + if (PlayerRangeSensitive) + { + AIObject?.Activate(); + } base.OnSectorActivate(); } @@ -3481,22 +3945,30 @@ namespace Server.Mobiles private void CheckShout(PlayerMobile pm, Point3D oldLocation) { if (m_MLNextShout > DateTime.UtcNow || pm.Hidden || !pm.Alive) + { return; + } var shoutRange = ShoutRange; if (!InRange(pm.Location, shoutRange) || InRange(oldLocation, shoutRange) || !CanSee(pm) || !InLOS(pm)) + { return; + } var context = MLQuestSystem.GetContext(pm); if (context?.IsFull == true) + { return; + } var quest = MLQuestSystem.RandomStarterQuest(this, pm, context); if (quest?.Activated != true || context?.IsDoingQuest(quest) == true) + { return; + } Shout(pm); m_MLNextShout = DateTime.UtcNow + ShoutDelay; @@ -3506,7 +3978,7 @@ namespace Server.Mobiles { } - public static void Initialize() + public static void Configure() { BondingEnabled = ServerConfiguration.GetOrUpdateSetting("taming.enableBonding", true); } @@ -3544,7 +4016,9 @@ namespace Server.Mobiles public virtual void BreathStallMovement() { if (AIObject != null) + { AIObject.NextMove = Core.TickCount + (int)(BreathStallTime * 1000); + } } public virtual void BreathPlayAngerSound() @@ -3560,7 +4034,9 @@ namespace Server.Mobiles public virtual void BreathEffect_Callback(Mobile target) { if (!target.Alive || !CanBeHarmful(target)) + { return; + } BreathPlayEffectSound(); BreathPlayEffect(target); @@ -3591,7 +4067,9 @@ namespace Server.Mobiles public virtual void BreathDamage_Callback(Mobile target) { if (target is BaseCreature creature && creature.BreathImmune) + { return; + } if (CanBeHarmful(target)) { @@ -3611,6 +4089,7 @@ namespace Server.Mobiles var nrgyDamage = BreathEnergyDamage; if (BreathChaosDamage > 0) + { switch (Utility.Random(5)) { case 0: @@ -3629,10 +4108,14 @@ namespace Server.Mobiles nrgyDamage += BreathChaosDamage; break; } + } if (physDamage == 0 && fireDamage == 0 && coldDamage == 0 && poisDamage == 0 && nrgyDamage == 0) + { target.Damage(BreathComputeDamage(), this); // Unresistable damage even in AOS + } else + { AOS.Damage( target, this, @@ -3643,6 +4126,7 @@ namespace Server.Mobiles poisDamage, nrgyDamage ); + } } } @@ -3651,10 +4135,14 @@ namespace Server.Mobiles var damage = (int)(Hits * BreathDamageScalar); if (IsParagon) + { damage = (int)(damage / Paragon.HitsBuff); + } if (damage > 200) + { damage = 200; + } return damage; } @@ -3667,7 +4155,9 @@ namespace Server.Mobiles public void SpillAcid(Mobile target, int amount) { if (target != null && target.Map == null || Map == null) + { return; + } for (var i = 0; i < amount; ++i) { @@ -3704,7 +4194,9 @@ namespace Server.Mobiles public virtual bool CheckFlee() { if (EndFleeTime == DateTime.MinValue) + { return false; + } if (DateTime.UtcNow >= EndFleeTime) { @@ -3741,12 +4233,16 @@ namespace Server.Mobiles public virtual Allegiance GetFactionAllegiance(Mobile mob) { if (mob == null || mob.Map != Faction.Facet || FactionAllegiance == null) + { return Allegiance.None; + } var fac = Faction.Find(mob, true); if (fac == null) + { return Allegiance.None; + } return fac == FactionAllegiance ? Allegiance.Ally : Allegiance.Enemy; } @@ -3754,12 +4250,16 @@ namespace Server.Mobiles public virtual Allegiance GetEthicAllegiance(Mobile mob) { if (mob == null || mob.Map != Faction.Facet || EthicAllegiance == null) + { return Allegiance.None; + } var ethic = Ethic.Find(mob, true); if (ethic == null) + { return Allegiance.None; + } return ethic == EthicAllegiance ? Allegiance.Ally : Allegiance.Enemy; } @@ -3791,22 +4291,34 @@ 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; } @@ -3814,13 +4326,17 @@ namespace Server.Mobiles public virtual bool CheckFoodPreference(Item fed, FoodType type, Type[] types) { if ((FavoriteFood & type) == 0) + { return false; + } var fedType = fed.GetType(); var contains = false; for (var i = 0; !contains && i < types.Length; ++i) + { contains = fedType == types[i]; + } return contains; } @@ -3840,22 +4356,35 @@ namespace Server.Mobiles int stamGain; if (f is Gold) + { stamGain = amount - 50; + } else + { stamGain = amount * 15 - 50; + } if (stamGain > 0) + { Stam += stamGain; + } if (Core.SE) { - if (m_Loyalty < MaxLoyalty) m_Loyalty = MaxLoyalty; + if (m_Loyalty < MaxLoyalty) + { + m_Loyalty = MaxLoyalty; + } } else { for (var i = 0; i < amount; ++i) + { if (m_Loyalty < MaxLoyalty && Utility.RandomDouble() <= 0.5) + { m_Loyalty += 10; + } + } } /* if (happier )*/ @@ -3863,9 +4392,13 @@ namespace Server.Mobiles SayTo(from, 502060); // Your pet looks happier. if (Body.IsAnimal) + { Animate(3, 5, 1, true, false, 0); + } else if (Body.IsMonster) + { Animate(17, 5, 1, true, false, 0); + } if (IsBondable && !IsBonded) { @@ -3933,17 +4466,25 @@ namespace Server.Mobiles public virtual bool CheckTeach(SkillName skill, Mobile from) { if (!CanTeach) + { return false; + } if (skill == SkillName.Stealth && from.Skills.Hiding.Base < Stealth.HidingRequirement) + { return false; + } if (skill == SkillName.RemoveTrap && (from.Skills.Lockpicking.Base < 50.0 || from.Skills.DetectHidden.Base < 50.0)) + { return false; + } if (!Core.AOS && (skill == SkillName.Focus || skill == SkillName.Chivalry || skill == SkillName.Necromancy)) + { return false; + } return true; } @@ -3954,23 +4495,33 @@ namespace Server.Mobiles ) { if (!CheckTeach(skill, m) || !m.CheckAlive()) + { return TeachResult.Failure; + } var ourSkill = Skills[skill]; var theirSkill = m.Skills[skill]; if (ourSkill == null || theirSkill == null) + { return TeachResult.Failure; + } var baseToSet = ourSkill.BaseFixedPoint / 3; if (baseToSet > 420) + { baseToSet = 420; + } else if (baseToSet < 200) + { return TeachResult.Failure; + } if (baseToSet > theirSkill.CapFixedPoint) + { baseToSet = theirSkill.CapFixedPoint; + } pointsToLearn = baseToSet - theirSkill.BaseFixedPoint; @@ -3981,13 +4532,19 @@ namespace Server.Mobiles } if (pointsToLearn < 0) + { return TeachResult.KnowsMoreThanMe; + } if (pointsToLearn == 0) + { return TeachResult.KnowsWhatIKnow; + } if (theirSkill.Lock != SkillLock.Up) + { return TeachResult.SkillNotRaisable; + } var freePoints = Math.Max(m.Skills.Cap - m.Skills.Total, 0); var freeablePoints = 0; @@ -3997,13 +4554,17 @@ namespace Server.Mobiles var sk = m.Skills[i]; if (sk == theirSkill || sk.Lock != SkillLock.Down) + { continue; + } freeablePoints += sk.BaseFixedPoint; } if (freePoints + freeablePoints == 0) + { return TeachResult.NotEnoughFreePoints; + } if (freePoints + freeablePoints < pointsToLearn) { @@ -4020,7 +4581,9 @@ namespace Server.Mobiles var sk = m.Skills[i]; if (sk == theirSkill || sk.Lock != SkillLock.Down) + { continue; + } if (sk.BaseFixedPoint < need) { @@ -4037,7 +4600,9 @@ namespace Server.Mobiles /* Sanity check */ if (baseToSet > theirSkill.CapFixedPoint || m.Skills.Total - theirSkill.BaseFixedPoint + baseToSet > m.Skills.Cap) + { return TeachResult.NotEnoughFreePoints; + } theirSkill.BaseFixedPoint = baseToSet; } @@ -4048,10 +4613,14 @@ namespace Server.Mobiles public virtual bool CheckTeachingMatch(Mobile m) { if (m_Teaching == (SkillName)(-1)) + { return false; + } if (m is PlayerMobile mobile) + { return mobile.Learning == m_Teaching; + } return true; } @@ -4090,7 +4659,9 @@ namespace Server.Mobiles m_Teaching = (SkillName)(-1); if (m is PlayerMobile mobile) + { mobile.Learning = (SkillName)(-1); + } } else { @@ -4101,7 +4672,9 @@ namespace Server.Mobiles m_Teaching = skill; if (m is PlayerMobile mobile) + { mobile.Learning = skill; + } } return true; @@ -4126,7 +4699,9 @@ namespace Server.Mobiles public void SetHits(int val) { if (val < 1000 && !Core.AOS) + { val = val * 100 / 60; + } HitsMaxSeed = val; Hits = HitsMax; @@ -4267,7 +4842,9 @@ namespace Server.Mobiles if (Skills[name].Base > Skills[name].Cap) { if (Core.SE) + { SkillsCap += Skills[name].BaseFixedPoint - Skills[name].CapFixedPoint; + } Skills[name].Cap = Skills[name].Base; } @@ -4283,7 +4860,9 @@ namespace Server.Mobiles if (Skills[name].Base > Skills[name].Cap) { if (Core.SE) + { SkillsCap += Skills[name].BaseFixedPoint - Skills[name].CapFixedPoint; + } Skills[name].Cap = Skills[name].Base; } @@ -4324,13 +4903,17 @@ namespace Server.Mobiles public void PackArcaneScroll(int amount) { for (var i = 0; i < amount; ++i) + { PackArcaneScroll(); + } } public void PackArcaneScroll() { if (!Core.ML) + { return; + } PackItem(Loot.Construct(Loot.ArcanistScrollTypes)); } @@ -4343,7 +4926,9 @@ namespace Server.Mobiles public void PackArcanceScroll(double chance) { if (!Core.ML || chance <= Utility.RandomDouble()) + { return; + } PackItem(Loot.Construct(Loot.ArcanistScrollTypes)); } @@ -4351,7 +4936,9 @@ namespace Server.Mobiles public void PackNecroScroll(int index) { if (!Core.AOS || Utility.RandomDouble() >= 0.05) + { return; + } PackItem(Loot.Construct(Loot.NecromancyScrollTypes, index)); } @@ -4371,7 +4958,9 @@ namespace Server.Mobiles public void PackMagicItems(int minLevel, int maxLevel, double armorChance = 0.30, double weaponChance = 0.15) { if (!PackArmor(minLevel, maxLevel, armorChance)) + { PackWeapon(minLevel, maxLevel, weaponChance); + } } public virtual void DropBackpack() @@ -4381,13 +4970,20 @@ namespace Server.Mobiles Backpack b = new CreatureBackpack(Name); var list = new List(Backpack.Items); - foreach (var item in list) b.DropItem(item); + foreach (var item in list) + { + b.DropItem(item); + } var house = BaseHouse.FindHouseAt(this); if (house != null) + { b.MoveToWorld(house.BanLocation, house.Map); + } else + { b.MoveToWorld(Location, Map); + } } } @@ -4396,22 +4992,34 @@ namespace Server.Mobiles m_Spawning = spawning; if (!spawning) + { m_KillersLuck = LootPack.GetLuckChanceForKiller(this); + } GenerateLoot(); if (m_Paragon) { if (Fame < 1250) + { AddLoot(LootPack.Meager); + } else if (Fame < 2500) + { AddLoot(LootPack.Average); + } else if (Fame < 5000) + { AddLoot(LootPack.Rich); + } else if (Fame < 10000) + { AddLoot(LootPack.FilthyRich); + } else + { AddLoot(LootPack.UltraRich); + } } m_Spawning = false; @@ -4425,13 +5033,17 @@ namespace Server.Mobiles public virtual void AddLoot(LootPack pack, int amount) { for (var i = 0; i < amount; ++i) + { AddLoot(pack); + } } public virtual void AddLoot(LootPack pack) { if (Summoned) + { return; + } var backpack = Backpack ?? new Backpack { Movable = false }; AddItem(backpack); @@ -4444,7 +5056,9 @@ namespace Server.Mobiles public bool PackArmor(int minLevel, int maxLevel, double chance) { if (chance <= Utility.RandomDouble()) + { return false; + } Cap(ref minLevel, 0, 5); Cap(ref maxLevel, 0, 5); @@ -4454,14 +5068,20 @@ namespace Server.Mobiles var item = Loot.RandomArmorOrShieldOrJewelry(); if (item == null) + { return false; + } GetRandomAOSStats(minLevel, maxLevel, out var attributeCount, out var min, out var max); if (item is BaseArmor armor) + { BaseRunicTool.ApplyAttributesTo(armor, attributeCount, min, max); + } else if (item is BaseJewel jewel) + { BaseRunicTool.ApplyAttributesTo(jewel, attributeCount, min, max); + } PackItem(item); } @@ -4470,7 +5090,9 @@ namespace Server.Mobiles var armor = Loot.RandomArmorOrShield(); if (armor == null) + { return false; + } armor.ProtectionLevel = (ArmorProtectionLevel)RandomMinMaxScaled(minLevel, maxLevel); armor.Durability = (ArmorDurabilityLevel)RandomMinMaxScaled(minLevel, maxLevel); @@ -4520,7 +5142,9 @@ namespace Server.Mobiles public static int RandomMinMaxScaled(int min, int max) { if (min == max) + { return min; + } if (min > max) { @@ -4547,7 +5171,9 @@ namespace Server.Mobiles int total = 0, toAdd = count; for (var i = 0; i < count; ++i, --toAdd) + { total += toAdd * toAdd; + } var rand = Utility.Random(total); toAdd = count; @@ -4559,7 +5185,9 @@ namespace Server.Mobiles rand -= toAdd * toAdd; if (rand < 0) + { break; + } } return val; @@ -4568,7 +5196,9 @@ namespace Server.Mobiles public bool PackSlayer(double chance = 0.05) { if (chance <= Utility.RandomDouble()) + { return false; + } if (Utility.RandomBool()) { @@ -4597,7 +5227,9 @@ namespace Server.Mobiles public bool PackWeapon(int minLevel, int maxLevel, double chance = 1.0) { if (chance <= Utility.RandomDouble()) + { return false; + } Cap(ref minLevel, 0, 5); Cap(ref maxLevel, 0, 5); @@ -4607,14 +5239,20 @@ namespace Server.Mobiles var item = Loot.RandomWeaponOrJewelry(); if (item == null) + { return false; + } GetRandomAOSStats(minLevel, maxLevel, out var attributeCount, out var min, out var max); if (item is BaseWeapon weapon) + { BaseRunicTool.ApplyAttributesTo(weapon, attributeCount, min, max); + } else if (item is BaseJewel jewel) + { BaseRunicTool.ApplyAttributesTo(jewel, attributeCount, min, max); + } PackItem(item); } @@ -4623,10 +5261,14 @@ namespace Server.Mobiles var weapon = Loot.RandomWeapon(); if (weapon == null) + { return false; + } if (Utility.RandomDouble() < 0.05) + { weapon.Slayer = SlayerName.Silver; + } weapon.DamageLevel = (WeaponDamageLevel)RandomMinMaxScaled(minLevel, maxLevel); weapon.AccuracyLevel = (WeaponAccuracyLevel)RandomMinMaxScaled(minLevel, maxLevel); @@ -4641,7 +5283,9 @@ namespace Server.Mobiles public void PackGold(int amount) { if (amount > 0) + { PackItem(new Gold(amount)); + } } public void PackGold(int min, int max) @@ -4657,7 +5301,9 @@ namespace Server.Mobiles public void PackStatue(int amount) { for (var i = 0; i < amount; ++i) + { PackStatue(); + } } public void PackStatue() @@ -4673,7 +5319,9 @@ namespace Server.Mobiles public void PackGem(int amount = 1) { if (amount <= 0) + { return; + } var gem = Loot.RandomGem(); @@ -4690,13 +5338,17 @@ namespace Server.Mobiles public void PackNecroReg(int amount) { for (var i = 0; i < amount; ++i) + { PackNecroReg(); + } } public void PackNecroReg() { if (!Core.AOS) + { return; + } PackItem(Loot.RandomNecromancyReagent()); } @@ -4709,7 +5361,9 @@ namespace Server.Mobiles public void PackReg(int amount) { if (amount <= 0) + { return; + } var reg = Loot.RandomReagent(); @@ -4720,7 +5374,10 @@ namespace Server.Mobiles public void PackItem(Item item) { - if (item == null) return; + if (item == null) + { + return; + } if (Summoned) { @@ -4732,7 +5389,9 @@ namespace Server.Mobiles AddItem(pack); if (!item.Stackable || !pack.TryDropItem(this, item, false)) // try stack - pack.DropItem(item); // failed, drop it anyway + { + pack.DropItem(item); // failed, drop it anyway + } } public virtual void HealStart(Mobile patient) @@ -4777,6 +5436,7 @@ namespace Server.Mobiles var chance = (healing - 30.0) / 50.0 - poisonLevel * 0.1; if (healing >= 60.0 && anatomy >= 60.0 && chance > Utility.RandomDouble()) + { if (patient.CurePoison(this)) { patient.SendLocalizedMessage(1010059); // You have been cured of all poisons. @@ -4784,6 +5444,7 @@ namespace Server.Mobiles CheckSkill(SkillName.Healing, 0.0, 60.0 + poisonLevel * 10.0); // TODO: Verify formula CheckSkill(SkillName.Anatomy, 0.0, 100.0); } + } } else if (BleedAttack.IsBleeding(patient)) { @@ -4802,7 +5463,9 @@ namespace Server.Mobiles var max = anatomy / 8.0 + healing / 3.0 + 4.0; if (onSelf) + { max += 10; + } var toHeal = min + Utility.RandomDouble() * (max - min); @@ -4822,7 +5485,9 @@ namespace Server.Mobiles if (onSelf && HealFully && Hits >= HealTrigger * HitsMax && Hits < HitsMax || !onSelf && HealOwnerFully && patient.Hits >= HealOwnerTrigger * patient.HitsMax && patient.Hits < patient.HitsMax) + { HealStart(patient); + } } public virtual void StopHeal() @@ -4840,7 +5505,9 @@ namespace Server.Mobiles public virtual void AuraDamage() { if (!Alive || IsDeadBondedPet) + { return; + } var eable = GetMobilesInRange(AuraRange); @@ -4887,13 +5554,17 @@ namespace Server.Mobiles public override void OnClick() { if (!Owner.From.CheckAlive()) + { return; + } Owner.From.TargetLocked = true; AnimalTaming.DisableMessage = true; if (Owner.From.UseSkill(SkillName.AnimalTaming)) + { Owner.From.Target.Invoke(Owner.From, m_Mobile); + } AnimalTaming.DisableMessage = false; Owner.From.TargetLocked = false; @@ -4909,13 +5580,19 @@ namespace Server.Mobiles protected override void OnTarget(Mobile from, object targeted) { if (!m_Charmed.DeathAdderCharmable || m_Charmed.Combatant != null || !from.CanBeHarmful(m_Charmed, false)) + { return; + } if (!(SummonFamiliarSpell.Table.TryGetValue(from, out var bc) && (bc as DeathAdder)?.Deleted == false)) + { return; + } if (!(targeted is Mobile targ && from.CanBeHarmful(targ, false))) + { return; + } from.RevealingAction(); from.DoHarmful(targ, true); @@ -4923,7 +5600,9 @@ namespace Server.Mobiles m_Charmed.Combatant = targ; if (m_Charmed.AIObject != null) + { m_Charmed.AIObject.Action = ActionType.Combat; + } } } @@ -4964,9 +5643,13 @@ namespace Server.Mobiles protected override void OnTick() { if (DateTime.UtcNow >= m_NextHourlyCheck) + { m_NextHourlyCheck = DateTime.UtcNow + TimeSpan.FromHours(1.0); + } else + { return; + } var toRelease = new List(); @@ -4978,7 +5661,9 @@ namespace Server.Mobiles m => { if (!(m is BaseCreature c)) + { return; + } if (c is BaseMount mount && mount.Rider != null) { @@ -4994,12 +5679,16 @@ namespace Server.Mobiles !owner.InRange(c, 12) || !c.CanSee(owner) || !c.InLOS(owner))) { if (c.OwnerAbandonTime == DateTime.MinValue) + { c.OwnerAbandonTime = DateTime.UtcNow; + } else if (c.OwnerAbandonTime + c.BondingAbandonDelay <= DateTime.UtcNow) + { lock (toRemove) { toRemove.Add(c); } + } } else { @@ -5021,10 +5710,12 @@ namespace Server.Mobiles } if (c.Loyalty <= 0) + { lock (toRelease) { toRelease.Add(c); } + } } } @@ -5035,10 +5726,12 @@ namespace Server.Mobiles c.RemoveStep++; if (c.RemoveStep >= 20) + { lock (toRemove) { toRemove.Add(c); } + } } else { @@ -5062,7 +5755,9 @@ namespace Server.Mobiles } foreach (var c in toRemove) + { c.Delete(); + } } } } diff --git a/Projects/UOContent/Mobiles/Vendors/BaseVendor.cs b/Projects/UOContent/Mobiles/Vendors/BaseVendor.cs index 91f46ba9a..ab9dc5b52 100644 --- a/Projects/UOContent/Mobiles/Vendors/BaseVendor.cs +++ b/Projects/UOContent/Mobiles/Vendors/BaseVendor.cs @@ -1087,7 +1087,7 @@ namespace Server.Mobiles public virtual bool CheckVendorAccess(Mobile from) => Region.GetRegion()?.CheckVendorAccess(this, from) != false || - Region != @from.Region && @from.Region.GetRegion()?.CheckVendorAccess(this, @from) != false; + Region != from.Region && from.Region.GetRegion()?.CheckVendorAccess(this, from) != false; public override void Serialize(IGenericWriter writer) { diff --git a/Projects/UOContent/Multis/HouseSign.cs b/Projects/UOContent/Multis/HouseSign.cs index 3e13e389a..c45e66a96 100644 --- a/Projects/UOContent/Multis/HouseSign.cs +++ b/Projects/UOContent/Multis/HouseSign.cs @@ -127,7 +127,7 @@ namespace Server.Multis { if (okay && Owner != null && Owner.Owner == null && Owner.DecayLevel != DecayLevel.DemolitionPending) { - var canClaim = Owner.CoOwners?.Count > 0 && Owner.IsCoOwner(@from) || Owner.IsFriend(from); + var canClaim = Owner.CoOwners?.Count > 0 && Owner.IsCoOwner(from) || Owner.IsFriend(from); if (canClaim && !BaseHouse.HasAccountHouse(from)) { diff --git a/Projects/UOContent/Skills/Discordance.cs b/Projects/UOContent/Skills/Discordance.cs index 82b555dfa..cf4cb2735 100644 --- a/Projects/UOContent/Skills/Discordance.cs +++ b/Projects/UOContent/Skills/Discordance.cs @@ -164,8 +164,8 @@ namespace Server.SkillHandlers else if (target is Mobile targ) { if (targ == from || targ is BaseCreature bc && - (bc.BardImmune || !@from.CanBeHarmful(bc, false)) && - bc.ControlMaster != @from) + (bc.BardImmune || !from.CanBeHarmful(bc, false)) && + bc.ControlMaster != from) { from.SendLocalizedMessage(1049535); // A song of discord would have no effect on that. } diff --git a/Projects/UOContent/Skills/RemoveTrap.cs b/Projects/UOContent/Skills/RemoveTrap.cs index 0dc418327..69855e67f 100644 --- a/Projects/UOContent/Skills/RemoveTrap.cs +++ b/Projects/UOContent/Skills/RemoveTrap.cs @@ -94,8 +94,8 @@ namespace Server.SkillHandlers } else { - if (Core.ML && isOwner || @from.CheckTargetSkill(SkillName.RemoveTrap, trap, 80.0, 100.0) && - @from.CheckTargetSkill(SkillName.Tinkering, trap, 80.0, 100.0)) + if (Core.ML && isOwner || from.CheckTargetSkill(SkillName.RemoveTrap, trap, 80.0, 100.0) && + from.CheckTargetSkill(SkillName.Tinkering, trap, 80.0, 100.0)) { from.PrivateOverheadMessage( MessageType.Regular,