From 8be291fe6719f1226b279ff8d8da016147b2aa5e Mon Sep 17 00:00:00 2001 From: jonathan-robertson Date: Sun, 22 Jan 2023 09:27:03 -0600 Subject: [PATCH 1/2] update formatting to match lang standards --- src/Commands/ConsoleCmdAmnesia.cs | 281 ++++++++++++++++++--------- src/Data/Config.cs | 237 +++++++++++++++------- src/Data/Values.cs | 6 +- src/Handlers/EntityKilled.cs | 22 ++- src/Handlers/GameMessage.cs | 41 ++-- src/Handlers/GameUpdate.cs | 45 +++-- src/Handlers/PlayerSpawnedInWorld.cs | 51 +++-- src/Handlers/SavePlayerData.cs | 37 ++-- src/ModApi.cs | 9 +- src/Utilities/MessagingSystem.cs | 36 +++- src/Utilities/ModLog.cs | 43 ++-- src/Utilities/PlayerHelper.cs | 73 ++++--- src/Utilities/QuestHelper.cs | 104 ++++++---- 13 files changed, 674 insertions(+), 311 deletions(-) diff --git a/src/Commands/ConsoleCmdAmnesia.cs b/src/Commands/ConsoleCmdAmnesia.cs index ada7fe8..f061265 100644 --- a/src/Commands/ConsoleCmdAmnesia.cs +++ b/src/Commands/ConsoleCmdAmnesia.cs @@ -4,15 +4,18 @@ using System.Collections.Generic; using System.Linq; -namespace Amnesia.Commands { - internal class ConsoleCmdAmnesia : ConsoleCmdAbstract { +namespace Amnesia.Commands +{ + internal class ConsoleCmdAmnesia : ConsoleCmdAbstract + { private static readonly string[] Commands = new string[] { "amnesia", "amn" }; private readonly string help; - public ConsoleCmdAmnesia() { + public ConsoleCmdAmnesia() + { var dict = new Dictionary() { { "", "show players and their amnesia-related info" }, { "grant ", "grant player some bonus xp time" }, @@ -32,24 +35,38 @@ public ConsoleCmdAmnesia() { help = $"Usage:\n {string.Join("\n ", dict.Keys.Select(command => $"{i++}. {GetCommands()[0]} {command}").ToList())}\nDescription Overview\n{string.Join("\n", dict.Values.Select(description => $"{j++}. {description}").ToList())}"; } - public override string[] GetCommands() => Commands; + public override string[] GetCommands() + { + return Commands; + } - public override string GetDescription() => "Configure or adjust settings for the Amnesia mod."; + public override string GetDescription() + { + return "Configure or adjust settings for the Amnesia mod."; + } - public override string GetHelp() => help; + public override string GetHelp() + { + return help; + } - public override void Execute(List _params, CommandSenderInfo _senderInfo) { - try { - if (_params.Count == 0) { + public override void Execute(List _params, CommandSenderInfo _senderInfo) + { + try + { + if (_params.Count == 0) + { HandleShowPlayers(); return; } - switch (_params[0].ToLower()) { + switch (_params[0].ToLower()) + { case "test": HandleTest(_params, _senderInfo); return; case "grant": - if (_params.Count != 3) { + if (_params.Count != 3) + { break; } HandleGrant(_params); @@ -68,41 +85,54 @@ public override void Execute(List _params, CommandSenderInfo _senderInfo return; } SdtdConsole.Instance.Output("Invald request"); - } catch (Exception e) { + } + catch (Exception e) + { SdtdConsole.Instance.Output($"Exception encountered: \"{e.Message}\"\n{e.StackTrace}"); } } - private void HandleShowPlayers() { + private void HandleShowPlayers() + { var players = GameManager.Instance.World.Players.list; - if (players.Count == 0) { + if (players.Count == 0) + { SdtdConsole.Instance.Output("No players are currently online."); } - foreach (var player in players) { + foreach (var player in players) + { SdtdConsole.Instance.Output($"{player.entityId}. {Values.BuffHardenedMemory}: {player.Buffs.HasBuff(Values.BuffHardenedMemory)}, {Values.CVarPositiveOutlookRemTime}: {player.GetCVar(Values.CVarPositiveOutlookRemTime)} ({player.GetDebugName()})"); } } - private void HandleTest(List @params, CommandSenderInfo senderInfo) { - if (@params.Count == 2 && @params[1].EqualsCaseInsensitive("confirm")) { - if (senderInfo.RemoteClientInfo == null || !GameManager.Instance.World.Players.dict.TryGetValue(senderInfo.RemoteClientInfo.entityId, out var playerToReset)) { + private void HandleTest(List @params, CommandSenderInfo senderInfo) + { + if (@params.Count == 2 && @params[1].EqualsCaseInsensitive("confirm")) + { + if (senderInfo.RemoteClientInfo == null || !GameManager.Instance.World.Players.dict.TryGetValue(senderInfo.RemoteClientInfo.entityId, out var playerToReset)) + { SdtdConsole.Instance.Output("RemoteClientInfo and/or player is null; if using telnet, you need to actually be inside the game instead."); return; } PlayerHelper.ResetPlayer(playerToReset); SdtdConsole.Instance.Output("Your player was reset. Some UI elements might not have updated; schematics on your toolbelt, for example, may need to be moved to another slot to indicate they now need to be learned."); - } else { + } + else + { SdtdConsole.Instance.Output($"Running this command will allow you to test your amnesia configurations by wiping YOUR OWN character.\nThis ONLY TESTS non-experimental features and will not trigger a disconnection.\nIf you're sure you want to do this, run \"{GetCommands()[0]} test confirm\""); } } - private void HandleGrant(List @params) { - if (!int.TryParse(@params[2], out var valueToAdd)) { + private void HandleGrant(List @params) + { + if (!int.TryParse(@params[2], out var valueToAdd)) + { SdtdConsole.Instance.Output("Unable to parse valueToAdd: must be of type int"); return; } var clientInfo = ConsoleHelper.ParseParamIdOrName(@params[1], true, false); - if (clientInfo == null || !GameManager.Instance.World.Players.dict.TryGetValue(clientInfo.entityId, out var player)) { + if (clientInfo == null || !GameManager.Instance.World.Players.dict.TryGetValue(clientInfo.entityId, out var player)) + { SdtdConsole.Instance.Output("Unable to find this player; note: player must be online"); return; } @@ -110,55 +140,72 @@ private void HandleGrant(List @params) { SdtdConsole.Instance.Output($"Added {valueToAdd} seconds of bonus xp time to {player.GetDebugName()} for a new value of {newValue}."); } - private void RouteListRequest(List @params) { - if (@params.Count() == 1) { + private void RouteListRequest(List @params) + { + if (@params.Count() == 1) + { SdtdConsole.Instance.Output(Values.KeyValueFieldNamesAndDescriptions); return; } if (@params.Count() >= 3 && !"add".EqualsCaseInsensitive(@params[2]) && !"rem".EqualsCaseInsensitive(@params[2]) && - !"clear".EqualsCaseInsensitive(@params[2])) { + !"clear".EqualsCaseInsensitive(@params[2])) + { SdtdConsole.Instance.Output($"Unable to parse command value; expecting 'add', 'rem', or 'clear'.\n{string.Join(", ", @params)}"); return; } - if (Values.NamePositiveOutlookTimeOnKill.EqualsCaseInsensitive(@params[1])) { + if (Values.NamePositiveOutlookTimeOnKill.EqualsCaseInsensitive(@params[1])) + { UpdatePositiveOutlookOnKill(@params); return; } } - private void UpdatePositiveOutlookOnKill(List @params) { - if (@params.Count == 2) { + private void UpdatePositiveOutlookOnKill(List @params) + { + if (@params.Count == 2) + { SdtdConsole.Instance.Output(Config.PrintPositiveOutlookTimeOnMemoryLoss()); return; } - switch (@params[2]) { + switch (@params[2]) + { case "add": if (@params.Count != 6) { break; } - if (!int.TryParse(@params[5], out var intValue)) { + if (!int.TryParse(@params[5], out var intValue)) + { SdtdConsole.Instance.Output($"Unable to parse value; expecting int"); break; } - if (Config.AddPositiveOutlookTimeOnKill(@params[3], @params[4], intValue)) { + if (Config.AddPositiveOutlookTimeOnKill(@params[3], @params[4], intValue)) + { SdtdConsole.Instance.Output($"Successfully added {@params[3]} to the collection."); - } else { + } + else + { SdtdConsole.Instance.Output($"Updating {@params[3]} was not necessary; it already exists in the collection just as entered."); } return; case "rem": if (@params.Count != 4) { break; } - if (Config.RemPositiveOutlookTimeOnKill(@params[3])) { + if (Config.RemPositiveOutlookTimeOnKill(@params[3])) + { SdtdConsole.Instance.Output($"Successfully removed {@params[3]} from the collection."); - } else { + } + else + { SdtdConsole.Instance.Output($"Removal of {@params[3]} was not necessary; due to either not being present or due to a typo."); } return; case "clear": if (@params.Count != 3) { break; } - if (Config.ClearPositiveOutlookTimeOnKill()) { + if (Config.ClearPositiveOutlookTimeOnKill()) + { SdtdConsole.Instance.Output($"Successfully cleared the collection."); - } else { + } + else + { SdtdConsole.Instance.Output($"This collection was already clear."); } return; @@ -167,229 +214,283 @@ private void UpdatePositiveOutlookOnKill(List @params) { return; } - private void RouteSetRequest(List @params) { - if (@params.Count() == 1) { + private void RouteSetRequest(List @params) + { + if (@params.Count() == 1) + { SdtdConsole.Instance.Output(Values.SingleValueFieldNamesAndDescriptions); return; } - if (Values.NameLongTermMemoryLevel.EqualsCaseInsensitive(@params[1])) { + if (Values.NameLongTermMemoryLevel.EqualsCaseInsensitive(@params[1])) + { UpdateLongTermMemoryLevel(@params); return; } - if (Values.NamePositiveOutlookMaxTime.EqualsCaseInsensitive(@params[1])) { + if (Values.NamePositiveOutlookMaxTime.EqualsCaseInsensitive(@params[1])) + { UpdatePositiveOutlookMaxTime(@params); return; } - if (Values.NamePositiveOutlookTimeOnFirstJoin.EqualsCaseInsensitive(@params[1])) { + if (Values.NamePositiveOutlookTimeOnFirstJoin.EqualsCaseInsensitive(@params[1])) + { UpdatePositiveOutlookTimeOnFirstJoin(@params); return; } - if (Values.NamePositiveOutlookTimeOnMemoryLoss.EqualsCaseInsensitive(@params[1])) { + if (Values.NamePositiveOutlookTimeOnMemoryLoss.EqualsCaseInsensitive(@params[1])) + { UpdatePositiveOutlookTimeOnMemoryLoss(@params); return; } - if (Values.NameProtectMemoryDuringBloodmoon.EqualsCaseInsensitive(@params[1])) { + if (Values.NameProtectMemoryDuringBloodmoon.EqualsCaseInsensitive(@params[1])) + { UpdateProtectMemoryDuringBloodmoon(@params); return; } - if (Values.NameProtectMemoryDuringPvp.EqualsCaseInsensitive(@params[1])) { + if (Values.NameProtectMemoryDuringPvp.EqualsCaseInsensitive(@params[1])) + { UpdateProtectMemoryDuringPvp(@params); return; } - if (Values.NameForgetLevelsAndSkills.EqualsCaseInsensitive(@params[1])) { + if (Values.NameForgetLevelsAndSkills.EqualsCaseInsensitive(@params[1])) + { UpdateForgetLevelsAndSkills(@params); return; } - if (Values.NameForgetBooks.EqualsCaseInsensitive(@params[1])) { + if (Values.NameForgetBooks.EqualsCaseInsensitive(@params[1])) + { UpdateForgetBooks(@params); return; } - if (Values.NameForgetSchematics.EqualsCaseInsensitive(@params[1])) { + if (Values.NameForgetSchematics.EqualsCaseInsensitive(@params[1])) + { UpdateForgetSchematics(@params); return; } - if (Values.NameForgetKdr.EqualsCaseInsensitive(@params[1])) { + if (Values.NameForgetKdr.EqualsCaseInsensitive(@params[1])) + { UpdateForgetKdr(@params); return; } - if (Values.NameForgetActiveQuests.EqualsCaseInsensitive(@params[1])) { + if (Values.NameForgetActiveQuests.EqualsCaseInsensitive(@params[1])) + { UpdateForgetActiveQuests(@params); return; } - if (Values.NameForgetInactiveQuests.EqualsCaseInsensitive(@params[1])) { + if (Values.NameForgetInactiveQuests.EqualsCaseInsensitive(@params[1])) + { UpdateForgetInactiveQuests(@params); return; } - if (Values.NameForgetIntroQuests.EqualsCaseInsensitive(@params[1])) { + if (Values.NameForgetIntroQuests.EqualsCaseInsensitive(@params[1])) + { UpdateForgetIntroQuests(@params); return; } SdtdConsole.Instance.Output($"Invald request; run '{Commands[0]} set' to see a list of options."); } - private void UpdateLongTermMemoryLevel(List @params) { - if (@params.Count == 2) { + private void UpdateLongTermMemoryLevel(List @params) + { + if (@params.Count == 2) + { SdtdConsole.Instance.Output($@"{Values.SingleValueNamesAndDescriptionsDict[Values.NameLongTermMemoryLevel]} {Commands[0]} set {Values.NameLongTermMemoryLevel} "); return; } - if (!int.TryParse(@params[2], out var value)) { + if (!int.TryParse(@params[2], out var value)) + { SdtdConsole.Instance.Output($"Unable to parse value; expecting int"); return; } Config.SetLongTermMemoryLevel(value); } - private void UpdatePositiveOutlookMaxTime(List @params) { - if (@params.Count == 2) { + private void UpdatePositiveOutlookMaxTime(List @params) + { + if (@params.Count == 2) + { SdtdConsole.Instance.Output($@"{Values.SingleValueNamesAndDescriptionsDict[Values.NamePositiveOutlookMaxTime]} {Commands[0]} set {Values.NamePositiveOutlookMaxTime} "); return; } - if (!int.TryParse(@params[2], out var value)) { + if (!int.TryParse(@params[2], out var value)) + { SdtdConsole.Instance.Output($"Unable to parse value; expecting int"); return; } Config.SetPositiveOutlookMaxTime(value); } - private void UpdatePositiveOutlookTimeOnFirstJoin(List @params) { - if (@params.Count == 2) { + private void UpdatePositiveOutlookTimeOnFirstJoin(List @params) + { + if (@params.Count == 2) + { SdtdConsole.Instance.Output($@"{Values.SingleValueNamesAndDescriptionsDict[Values.NamePositiveOutlookTimeOnFirstJoin]} {Commands[0]} set {Values.NamePositiveOutlookTimeOnFirstJoin} "); return; } - if (!int.TryParse(@params[2], out var value)) { + if (!int.TryParse(@params[2], out var value)) + { SdtdConsole.Instance.Output($"Unable to parse value; expecting int"); return; } Config.SetPositiveOutlookTimeOnFirstJoin(value); } - private void UpdatePositiveOutlookTimeOnMemoryLoss(List @params) { - if (@params.Count == 2) { + private void UpdatePositiveOutlookTimeOnMemoryLoss(List @params) + { + if (@params.Count == 2) + { SdtdConsole.Instance.Output($@"{Values.SingleValueNamesAndDescriptionsDict[Values.NamePositiveOutlookTimeOnMemoryLoss]} {Commands[0]} set {Values.NamePositiveOutlookTimeOnMemoryLoss} "); return; } - if (!int.TryParse(@params[2], out var value)) { + if (!int.TryParse(@params[2], out var value)) + { SdtdConsole.Instance.Output($"Unable to parse value; expecting int"); return; } Config.SetPositiveOutlookTimeOnMemoryLoss(value); } - private void UpdateProtectMemoryDuringBloodmoon(List @params) { - if (@params.Count == 2) { + private void UpdateProtectMemoryDuringBloodmoon(List @params) + { + if (@params.Count == 2) + { SdtdConsole.Instance.Output($@"{Values.SingleValueNamesAndDescriptionsDict[Values.NameProtectMemoryDuringBloodmoon]} {Commands[0]} set {Values.NameProtectMemoryDuringBloodmoon} "); return; } - if (!bool.TryParse(@params[2], out var value)) { + if (!bool.TryParse(@params[2], out var value)) + { SdtdConsole.Instance.Output($"Unable to parse value; expecting bool"); return; } Config.SetProtectMemoryDuringBloodmoon(value); } - private void UpdateProtectMemoryDuringPvp(List @params) { - if (@params.Count == 2) { + private void UpdateProtectMemoryDuringPvp(List @params) + { + if (@params.Count == 2) + { SdtdConsole.Instance.Output($@"{Values.SingleValueNamesAndDescriptionsDict[Values.NameProtectMemoryDuringPvp]} {Commands[0]} set {Values.NameProtectMemoryDuringPvp} "); return; } - if (!bool.TryParse(@params[2], out var value)) { + if (!bool.TryParse(@params[2], out var value)) + { SdtdConsole.Instance.Output($"Unable to parse value; expecting bool"); return; } Config.SetProtectMemoryDuringPvp(value); } - private void UpdateForgetLevelsAndSkills(List @params) { - if (@params.Count == 2) { + private void UpdateForgetLevelsAndSkills(List @params) + { + if (@params.Count == 2) + { SdtdConsole.Instance.Output($@"{Values.SingleValueNamesAndDescriptionsDict[Values.NameForgetLevelsAndSkills]} {Commands[0]} set {Values.NameForgetLevelsAndSkills} "); return; } - if (!bool.TryParse(@params[2], out var value)) { + if (!bool.TryParse(@params[2], out var value)) + { SdtdConsole.Instance.Output($"Unable to parse value; expecting bool"); return; } Config.SetForgetLevelsAndSkills(value); } - private void UpdateForgetBooks(List @params) { - if (@params.Count == 2) { + private void UpdateForgetBooks(List @params) + { + if (@params.Count == 2) + { SdtdConsole.Instance.Output($@"{Values.SingleValueNamesAndDescriptionsDict[Values.NameForgetBooks]} {Commands[0]} set {Values.NameForgetBooks} "); return; } - if (!bool.TryParse(@params[2], out var value)) { + if (!bool.TryParse(@params[2], out var value)) + { SdtdConsole.Instance.Output($"Unable to parse value; expecting bool"); return; } Config.SetForgetBooks(value); } - private void UpdateForgetSchematics(List @params) { - if (@params.Count == 2) { + private void UpdateForgetSchematics(List @params) + { + if (@params.Count == 2) + { SdtdConsole.Instance.Output($@"{Values.SingleValueNamesAndDescriptionsDict[Values.NameForgetSchematics]} {Commands[0]} set {Values.NameForgetSchematics} "); return; } - if (!bool.TryParse(@params[2], out var value)) { + if (!bool.TryParse(@params[2], out var value)) + { SdtdConsole.Instance.Output($"Unable to parse value; expecting bool"); return; } Config.SetForgetSchematics(value); } - private void UpdateForgetKdr(List @params) { - if (@params.Count == 2) { + private void UpdateForgetKdr(List @params) + { + if (@params.Count == 2) + { SdtdConsole.Instance.Output($@"{Values.SingleValueNamesAndDescriptionsDict[Values.NameForgetKdr]} {Commands[0]} set {Values.NameForgetKdr} "); return; } - if (!bool.TryParse(@params[2], out var value)) { + if (!bool.TryParse(@params[2], out var value)) + { SdtdConsole.Instance.Output($"Unable to parse value; expecting bool"); return; } Config.SetForgetKdr(value); } - private void UpdateForgetActiveQuests(List @params) { - if (@params.Count == 2) { + private void UpdateForgetActiveQuests(List @params) + { + if (@params.Count == 2) + { SdtdConsole.Instance.Output($@"{Values.SingleValueNamesAndDescriptionsDict[Values.NameForgetActiveQuests]} {Commands[0]} set {Values.NameForgetActiveQuests} "); return; } - if (!bool.TryParse(@params[2], out var value)) { + if (!bool.TryParse(@params[2], out var value)) + { SdtdConsole.Instance.Output($"Unable to parse value; expecting bool"); return; } Config.SetForgetActiveQuests(value); } - private void UpdateForgetInactiveQuests(List @params) { - if (@params.Count == 2) { + private void UpdateForgetInactiveQuests(List @params) + { + if (@params.Count == 2) + { SdtdConsole.Instance.Output($@"{Values.SingleValueNamesAndDescriptionsDict[Values.NameForgetInactiveQuests]} {Commands[0]} set {Values.NameForgetInactiveQuests} "); return; } - if (!bool.TryParse(@params[2], out var value)) { + if (!bool.TryParse(@params[2], out var value)) + { SdtdConsole.Instance.Output($"Unable to parse value; expecting bool"); return; } Config.SetForgetInactiveQuests(value); } - private void UpdateForgetIntroQuests(List @params) { - if (@params.Count == 2) { + private void UpdateForgetIntroQuests(List @params) + { + if (@params.Count == 2) + { SdtdConsole.Instance.Output($@"{Values.SingleValueNamesAndDescriptionsDict[Values.NameForgetIntroQuests]} {Commands[0]} set {Values.NameForgetInactiveQuests} "); return; } - if (!bool.TryParse(@params[2], out var value)) { + if (!bool.TryParse(@params[2], out var value)) + { SdtdConsole.Instance.Output($"Unable to parse value; expecting bool"); return; } diff --git a/src/Data/Config.cs b/src/Data/Config.cs index 09411a3..79387c3 100644 --- a/src/Data/Config.cs +++ b/src/Data/Config.cs @@ -5,8 +5,10 @@ using System.Linq; using System.Xml.Linq; -namespace Amnesia.Data { - internal class Config { +namespace Amnesia.Data +{ + internal class Config + { private static readonly ModLog log = new ModLog(); private static readonly string filename = Path.Combine(GameIO.GetSaveGameDir(), "amnesia.xml"); @@ -25,14 +27,21 @@ internal class Config { public static int PositiveOutlookTimeOnMemoryLoss { get; private set; } = 3600; // 1 hr /// Length of time for server-wide xp boost buff when killing specific zombies. public static Dictionary PositiveOutlookTimeOnKill { get; private set; } = new Dictionary(); - public struct TimeOnKill { + public struct TimeOnKill + { public string name; public string caption; public int value; - public override string ToString() => ToString("name", "caption", "value"); + public override string ToString() + { + return ToString("name", "caption", "value"); + } - public string ToString(string nameDisplay, string captionDisplay, string valueDisplay, bool hideName = false) => $"{{ {(hideName ? "" : nameDisplay + ": " + name + ", ")}{captionDisplay}: {caption}, {valueDisplay}: {value} }}"; + public string ToString(string nameDisplay, string captionDisplay, string valueDisplay, bool hideName = false) + { + return $"{{ {(hideName ? "" : nameDisplay + ": " + name + ", ")}{captionDisplay}: {caption}, {valueDisplay}: {value} }}"; + } }; /// Whether to prevent memory loss during blood moon. @@ -56,8 +65,14 @@ public struct TimeOnKill { /// Whether the intro quests should be forgotten/reset on memory loss. public static bool ForgetIntroQuests { get; private set; } = false; - public static string PrintPositiveOutlookTimeOnMemoryLoss() => PositiveOutlookTimeOnKill.Count == 0 ? "None" : "[\n " + string.Join(",\n ", PositiveOutlookTimeOnKill.Select(kvp => kvp.Value.ToString("entityName", "displayName", "bonusTimeInSeconds")).ToArray()) + "\n]"; - public static string AsString() => $@"=== Amnesia Configuration === + public static string PrintPositiveOutlookTimeOnMemoryLoss() + { + return PositiveOutlookTimeOnKill.Count == 0 ? "None" : "[\n " + string.Join(",\n ", PositiveOutlookTimeOnKill.Select(kvp => kvp.Value.ToString("entityName", "displayName", "bonusTimeInSeconds")).ToArray()) + "\n]"; + } + + public static string AsString() + { + return $@"=== Amnesia Configuration === {Values.NameLongTermMemoryLevel}: {LongTermMemoryLevel} {Values.NamePositiveOutlookMaxTime}: {PositiveOutlookMaxTime} @@ -77,24 +92,31 @@ public static string AsString() => $@"=== Amnesia Configuration === {Values.NameForgetActiveQuests}: {ForgetActiveQuests} {Values.NameForgetInactiveQuests}: {ForgetInactiveQuests} {Values.NameForgetIntroQuests}: {ForgetIntroQuests}"; + } /// /// Update the long term memory level. This will determine when Amnesia activates and the level players will be reset to on death. /// /// The new level to use for long term memory. - public static void SetLongTermMemoryLevel(int value) { - if (LongTermMemoryLevel == value) { + public static void SetLongTermMemoryLevel(int value) + { + if (LongTermMemoryLevel == value) + { return; } LongTermMemoryLevel = Math.Max(1, value); _ = Save(); - foreach (var player in GameManager.Instance.World.Players.list) { + foreach (var player in GameManager.Instance.World.Players.list) + { player.SetCVar(Values.CVarLongTermMemoryLevel, LongTermMemoryLevel); - if (player.Progression.Level <= LongTermMemoryLevel) { - if (!player.Buffs.HasBuff(Values.BuffNewbieCoat)) { + if (player.Progression.Level <= LongTermMemoryLevel) + { + if (!player.Buffs.HasBuff(Values.BuffNewbieCoat)) + { _ = player.Buffs.AddBuff(Values.BuffNewbieCoat); } - if (player.Buffs.HasBuff(Values.BuffHardenedMemory)) { + if (player.Buffs.HasBuff(Values.BuffHardenedMemory)) + { player.Buffs.RemoveBuff(Values.BuffHardenedMemory); PlayerHelper.GiveItem(player, Values.NameMemoryBoosters); } @@ -106,19 +128,26 @@ public static void SetLongTermMemoryLevel(int value) { /// Generously update max time for the positive outlook buff. /// /// The new value to limit max time to (generally represented as timeInSeconds). - public static void SetPositiveOutlookMaxTime(int timeInSeconds) { - if (PositiveOutlookMaxTime == timeInSeconds) { + public static void SetPositiveOutlookMaxTime(int timeInSeconds) + { + if (PositiveOutlookMaxTime == timeInSeconds) + { return; } PositiveOutlookMaxTime = Math.Max(0, timeInSeconds); _ = Save(); - foreach (var player in GameManager.Instance.World.Players.list) { + foreach (var player in GameManager.Instance.World.Players.list) + { var playerRemTime = player.GetCVar(Values.CVarPositiveOutlookRemTime); - if (playerRemTime > 0) { + if (playerRemTime > 0) + { var playerMaxTime = player.GetCVar(Values.CVarPositiveOutlookMaxTime); - if (playerMaxTime < PositiveOutlookMaxTime) { + if (playerMaxTime < PositiveOutlookMaxTime) + { player.SetCVar(Values.CVarPositiveOutlookRemTime, PositiveOutlookMaxTime - playerMaxTime + playerRemTime); - } else if (playerMaxTime > PositiveOutlookMaxTime) { + } + else if (playerMaxTime > PositiveOutlookMaxTime) + { player.SetCVar(Values.CVarPositiveOutlookRemTime, PositiveOutlookMaxTime); } } @@ -131,8 +160,10 @@ public static void SetPositiveOutlookMaxTime(int timeInSeconds) { /// /// The number of seconds to grant. /// Set to <= zero to disable. - public static void SetPositiveOutlookTimeOnFirstJoin(int timeInSeconds) { - if (PositiveOutlookTimeOnFirstJoin == timeInSeconds) { + public static void SetPositiveOutlookTimeOnFirstJoin(int timeInSeconds) + { + if (PositiveOutlookTimeOnFirstJoin == timeInSeconds) + { return; } PositiveOutlookTimeOnFirstJoin = Math.Min(PositiveOutlookMaxTime, Math.Max(0, timeInSeconds)); @@ -144,8 +175,10 @@ public static void SetPositiveOutlookTimeOnFirstJoin(int timeInSeconds) { /// /// The number of seconds to grant. /// Set to <= zero to disable. - public static void SetPositiveOutlookTimeOnMemoryLoss(int timeInSeconds) { - if (PositiveOutlookTimeOnMemoryLoss == timeInSeconds) { + public static void SetPositiveOutlookTimeOnMemoryLoss(int timeInSeconds) + { + if (PositiveOutlookTimeOnMemoryLoss == timeInSeconds) + { return; } PositiveOutlookTimeOnMemoryLoss = Math.Min(PositiveOutlookMaxTime, Math.Max(0, timeInSeconds)); @@ -158,18 +191,25 @@ public static void SetPositiveOutlookTimeOnMemoryLoss(int timeInSeconds) { /// Lookup key and name id of the entity. /// The display name of the entity to trigger on. /// Number of seconds to grant xp boost for. - public static bool AddPositiveOutlookTimeOnKill(string name, string caption, int timeInSeconds) { - if (PositiveOutlookTimeOnKill.TryGetValue(name, out var entry)) { - if (entry.name.Equals(name) && entry.caption.Equals(caption) && entry.value == timeInSeconds) { + public static bool AddPositiveOutlookTimeOnKill(string name, string caption, int timeInSeconds) + { + if (PositiveOutlookTimeOnKill.TryGetValue(name, out var entry)) + { + if (entry.name.Equals(name) && entry.caption.Equals(caption) && entry.value == timeInSeconds) + { return false; } - PositiveOutlookTimeOnKill[name] = new TimeOnKill { + PositiveOutlookTimeOnKill[name] = new TimeOnKill + { name = name, caption = caption, value = Math.Min(PositiveOutlookMaxTime, Math.Max(1, timeInSeconds)) }; - } else { - PositiveOutlookTimeOnKill.Add(name, new TimeOnKill { + } + else + { + PositiveOutlookTimeOnKill.Add(name, new TimeOnKill + { name = name, caption = caption, value = Math.Min(PositiveOutlookMaxTime, Math.Max(1, timeInSeconds)) @@ -183,8 +223,10 @@ public static bool AddPositiveOutlookTimeOnKill(string name, string caption, int /// Remove a zombie or animal by key from the Time On Kill list. /// /// Name of the entity to remove the trigger for. - public static bool RemPositiveOutlookTimeOnKill(string name) { - if (!PositiveOutlookTimeOnKill.ContainsKey(name)) { + public static bool RemPositiveOutlookTimeOnKill(string name) + { + if (!PositiveOutlookTimeOnKill.ContainsKey(name)) + { return false; } _ = PositiveOutlookTimeOnKill.Remove(name); @@ -195,8 +237,10 @@ public static bool RemPositiveOutlookTimeOnKill(string name) { /// /// Clear all zombies or animals from the Time On Kill list. /// - public static bool ClearPositiveOutlookTimeOnKill() { - if (PositiveOutlookTimeOnKill.Count == 0) { + public static bool ClearPositiveOutlookTimeOnKill() + { + if (PositiveOutlookTimeOnKill.Count == 0) + { return false; } PositiveOutlookTimeOnKill.Clear(); @@ -208,18 +252,25 @@ public static bool ClearPositiveOutlookTimeOnKill() { /// Enable or disable whether memory can be lost during Blood Moon. /// /// New value to use. - public static void SetProtectMemoryDuringBloodmoon(bool value) { - if (ProtectMemoryDuringBloodmoon == value) { + public static void SetProtectMemoryDuringBloodmoon(bool value) + { + if (ProtectMemoryDuringBloodmoon == value) + { return; } ProtectMemoryDuringBloodmoon = value; _ = Save(); - if (ProtectMemoryDuringBloodmoon && GameManager.Instance.World.aiDirector.BloodMoonComponent.BloodMoonActive) { - foreach (var player in GameManager.Instance.World.Players.list) { + if (ProtectMemoryDuringBloodmoon && GameManager.Instance.World.aiDirector.BloodMoonComponent.BloodMoonActive) + { + foreach (var player in GameManager.Instance.World.Players.list) + { _ = player.Buffs.AddBuff(Values.BuffBloodmoonLifeProtection); } - } else { - foreach (var player in GameManager.Instance.World.Players.list) { + } + else + { + foreach (var player in GameManager.Instance.World.Players.list) + { player.Buffs.RemoveBuff(Values.BuffBloodmoonLifeProtection); player.Buffs.RemoveBuff(Values.BuffPostBloodmoonLifeProtection); } @@ -230,8 +281,10 @@ public static void SetProtectMemoryDuringBloodmoon(bool value) { /// Enable or disable whether memory can be lost to PVP. /// /// New value to use. - public static void SetProtectMemoryDuringPvp(bool value) { - if (ProtectMemoryDuringPvp == value) { + public static void SetProtectMemoryDuringPvp(bool value) + { + if (ProtectMemoryDuringPvp == value) + { return; } ProtectMemoryDuringPvp = value; @@ -242,8 +295,10 @@ public static void SetProtectMemoryDuringPvp(bool value) { /// Enable or disable ForgetLevelsAndSkills on memory loss. /// /// New value to use. - public static void SetForgetLevelsAndSkills(bool value) { - if (ForgetLevelsAndSkills == value) { + public static void SetForgetLevelsAndSkills(bool value) + { + if (ForgetLevelsAndSkills == value) + { return; } ForgetLevelsAndSkills = value; @@ -254,8 +309,10 @@ public static void SetForgetLevelsAndSkills(bool value) { /// Enable or disable ForgetBooks on memory loss. /// /// New value to use. - public static void SetForgetBooks(bool value) { - if (ForgetBooks == value) { + public static void SetForgetBooks(bool value) + { + if (ForgetBooks == value) + { return; } ForgetBooks = value; @@ -266,8 +323,10 @@ public static void SetForgetBooks(bool value) { /// Enable or disable ForgetSchematics on memory loss. /// /// New value to use. - public static void SetForgetSchematics(bool value) { - if (ForgetSchematics == value) { + public static void SetForgetSchematics(bool value) + { + if (ForgetSchematics == value) + { return; } ForgetSchematics = value; @@ -278,8 +337,10 @@ public static void SetForgetSchematics(bool value) { /// Enable or disable ForgetKdr on memory loss. /// /// New value to use. - public static void SetForgetKdr(bool value) { - if (ForgetKdr == value) { + public static void SetForgetKdr(bool value) + { + if (ForgetKdr == value) + { return; } ForgetKdr = value; @@ -290,8 +351,10 @@ public static void SetForgetKdr(bool value) { /// Enable or disable ForgetActiveQuests on memory loss. /// /// New value to use. - public static void SetForgetActiveQuests(bool value) { - if (ForgetActiveQuests == value) { + public static void SetForgetActiveQuests(bool value) + { + if (ForgetActiveQuests == value) + { return; } ForgetActiveQuests = value; @@ -302,8 +365,10 @@ public static void SetForgetActiveQuests(bool value) { /// Enable or disable ForgetIntroQuests on memory loss. /// /// New value to use. - public static void SetForgetIntroQuests(bool value) { - if (ForgetIntroQuests == value) { + public static void SetForgetIntroQuests(bool value) + { + if (ForgetIntroQuests == value) + { return; } ForgetIntroQuests = value; @@ -314,18 +379,23 @@ public static void SetForgetIntroQuests(bool value) { /// Enable or disable ForgetInactiveQuests on memory loss. /// /// New value to use. - public static void SetForgetInactiveQuests(bool value) { - if (ForgetInactiveQuests == value) { + public static void SetForgetInactiveQuests(bool value) + { + if (ForgetInactiveQuests == value) + { return; } ForgetInactiveQuests = value; _ = Save(); } - public static bool Save() { - try { + public static bool Save() + { + try + { var timeOnKillElement = new XElement(Values.NamePositiveOutlookTimeOnKill); - foreach (var kvp in PositiveOutlookTimeOnKill) { + foreach (var kvp in PositiveOutlookTimeOnKill) + { timeOnKillElement.Add(new XElement("entry", new XAttribute("name", kvp.Value.name), new XAttribute("caption", kvp.Value.caption), @@ -354,14 +424,18 @@ public static bool Save() { ).Save(filename); log.Info($"Successfully saved {filename}"); return true; - } catch (Exception e) { + } + catch (Exception e) + { log.Error($"Failed to save {filename}", e); return false; } } - public static void Load() { - try { + public static void Load() + { + try + { var config = XElement.Load(filename); LongTermMemoryLevel = ParseInt(config, Values.NameLongTermMemoryLevel, LongTermMemoryLevel); @@ -370,12 +444,15 @@ public static void Load() { PositiveOutlookTimeOnMemoryLoss = ParseInt(config, Values.NamePositiveOutlookTimeOnMemoryLoss, PositiveOutlookTimeOnMemoryLoss); PositiveOutlookTimeOnKill.Clear(); - foreach (var entry in config.Descendants(Values.NamePositiveOutlookTimeOnKill).First().Descendants("entry")) { - if (!int.TryParse(entry.Attribute("value").Value, out var intValue)) { + foreach (var entry in config.Descendants(Values.NamePositiveOutlookTimeOnKill).First().Descendants("entry")) + { + if (!int.TryParse(entry.Attribute("value").Value, out var intValue)) + { log.Error($"Unable to parse value; expecting int"); return; } - PositiveOutlookTimeOnKill.Add(entry.Attribute("name").Value, new TimeOnKill { + PositiveOutlookTimeOnKill.Add(entry.Attribute("name").Value, new TimeOnKill + { name = entry.Attribute("name").Value, caption = entry.Attribute("caption").Value, value = intValue, @@ -395,31 +472,43 @@ public static void Load() { ForgetIntroQuests = ParseBool(config, Values.NameForgetIntroQuests, ForgetIntroQuests); log.Info($"Successfully loaded {filename}"); Loaded = true; - } catch (FileNotFoundException) { + } + catch (FileNotFoundException) + { log.Info($"No file detected, creating a config with defaults under {filename}"); Loaded = Save(); - } catch (Exception e) { + } + catch (Exception e) + { log.Error($"Failed to load {filename}; Amnesia will remain disabled until server restart - fix file (possibly delete or try updating settings) then try restarting server.", e); Loaded = false; } } - private static int ParseInt(XElement config, string name, int fallback) { - try { - if (int.TryParse(config.Descendants(name).First().Value, out var value)) { + private static int ParseInt(XElement config, string name, int fallback) + { + try + { + if (int.TryParse(config.Descendants(name).First().Value, out var value)) + { return value; } - } catch (Exception) { } + } + catch (Exception) { } log.Warn($"Unable to parse {name} from {filename}.\nFalling back to a default value of {fallback}.\nTry updating any setting to write the default option to this file."); return fallback; } - private static bool ParseBool(XElement config, string name, bool fallback) { - try { - if (bool.TryParse(config.Descendants(name).First().Value, out var value)) { + private static bool ParseBool(XElement config, string name, bool fallback) + { + try + { + if (bool.TryParse(config.Descendants(name).First().Value, out var value)) + { return value; } - } catch (Exception) { } + } + catch (Exception) { } log.Warn($"Unable to parse {name} from {filename}.\nFalling back to a default value of {fallback}.\nTry updating any setting to write the default option to this file."); return fallback; } diff --git a/src/Data/Values.cs b/src/Data/Values.cs index a6694a8..6aebb6b 100644 --- a/src/Data/Values.cs +++ b/src/Data/Values.cs @@ -1,8 +1,10 @@ using System.Collections.Generic; using System.Linq; -namespace Amnesia.Data { - internal class Values { +namespace Amnesia.Data +{ + internal class Values + { // cvars public const string CVarLongTermMemoryLevel = "amnesiaLongTermMemoryLevel"; diff --git a/src/Handlers/EntityKilled.cs b/src/Handlers/EntityKilled.cs index 4ba7cd4..5a33a92 100644 --- a/src/Handlers/EntityKilled.cs +++ b/src/Handlers/EntityKilled.cs @@ -2,24 +2,32 @@ using Amnesia.Utilities; using System; -namespace Amnesia.Handlers { - internal class EntityKilled { +namespace Amnesia.Handlers +{ + internal class EntityKilled + { private static readonly ModLog log = new ModLog(); - internal static void Handle(Entity killedEntity, Entity killerEntity) { - try { + internal static void Handle(Entity killedEntity, Entity killerEntity) + { + try + { if (killerEntity == null || killerEntity.entityType != EntityType.Player) { return; } - if (!Config.PositiveOutlookTimeOnKill.TryGetValue(killedEntity.GetDebugName(), out var entry)) { + if (!Config.PositiveOutlookTimeOnKill.TryGetValue(killedEntity.GetDebugName(), out var entry)) + { return; } var minutes = entry.value / 60f; MessagingSystem.Broadcast($"[007fff]{killerEntity.GetDebugName()} just took down a {entry.caption}!"); MessagingSystem.Broadcast($"[007fff]Relief washes over each survivor as a newfound confidence takes hold: [00ff80]all online players receive Double XP for {(minutes > 1 ? minutes + " Minutes!" : entry.value + " Seconds!")}"); - foreach (var player in GameManager.Instance.World.Players.list) { + foreach (var player in GameManager.Instance.World.Players.list) + { _ = PlayerHelper.AddPositiveOutlookTime(player, entry.value); } - } catch (Exception e) { + } + catch (Exception e) + { log.Error("HandleEntityKilled", e); } } diff --git a/src/Handlers/GameMessage.cs b/src/Handlers/GameMessage.cs index 39a064f..fd02757 100644 --- a/src/Handlers/GameMessage.cs +++ b/src/Handlers/GameMessage.cs @@ -2,45 +2,60 @@ using Amnesia.Utilities; using System; -namespace Amnesia.Handlers { - internal class GameMessage { +namespace Amnesia.Handlers +{ + internal class GameMessage + { private static readonly ModLog log = new ModLog(); - public static bool Handle(ClientInfo clientInfo, EnumGameMessages messageType, string message, string mainName, bool localizeMain, string secondaryName, bool localizeSecondary) { + public static bool Handle(ClientInfo clientInfo, EnumGameMessages messageType, string message, string mainName, bool localizeMain, string secondaryName, bool localizeSecondary) + { if (!Config.Loaded) { return true; } // do not interrupt other mods from processing event - try { - if (EnumGameMessages.EntityWasKilled != messageType) { + try + { + if (EnumGameMessages.EntityWasKilled != messageType) + { return true; // only focus on entity killed messages } - if (!GameManager.Instance.World.Players.dict.TryGetValue(clientInfo.entityId, out var player)) { + if (!GameManager.Instance.World.Players.dict.TryGetValue(clientInfo.entityId, out var player)) + { return true; // player not present; skip } - if (player.Buffs.HasBuff(Values.BuffBloodmoonLifeProtection) || player.Buffs.HasBuff(Values.BuffPostBloodmoonLifeProtection)) { + if (player.Buffs.HasBuff(Values.BuffBloodmoonLifeProtection) || player.Buffs.HasBuff(Values.BuffPostBloodmoonLifeProtection)) + { log.Trace($"{clientInfo.InternalId.CombinedString} ({player.GetDebugName()}) died but had bloodmoon memory protection."); return true; // player had protection - } else { + } + else + { log.Trace($"{clientInfo.InternalId.CombinedString} ({player.GetDebugName()}) died and did not have bloodmoon memory protection."); } - if (Config.ProtectMemoryDuringPvp && mainName != secondaryName) { + if (Config.ProtectMemoryDuringPvp && mainName != secondaryName) + { var killerClient = ConnectionManager.Instance.Clients.GetForNameOrId(secondaryName); - if (killerClient != null) { + if (killerClient != null) + { log.Trace($"{clientInfo.InternalId.CombinedString} ({player.GetDebugName()}) was killed by {secondaryName} but this server has pvp deaths set to not harm memory."); return true; // being killed in pvp doesn't count against player } } - if (player.Progression.Level < Config.LongTermMemoryLevel) { + if (player.Progression.Level < Config.LongTermMemoryLevel) + { log.Trace($"{clientInfo.InternalId.CombinedString} ({player.GetDebugName()}) died but had not yet reached the configured LongTermMemoryLevel of {Config.LongTermMemoryLevel}"); return true; } - if (!ModApi.Obituary.ContainsKey(clientInfo.entityId)) { + if (!ModApi.Obituary.ContainsKey(clientInfo.entityId)) + { ModApi.Obituary.Add(clientInfo.entityId, true); } - } catch (Exception e) { + } + catch (Exception e) + { log.Error("Failed to handle GameMessage event.", e); } return true; // do not interrupt other mods from processing event diff --git a/src/Handlers/GameUpdate.cs b/src/Handlers/GameUpdate.cs index 876317a..215ea74 100644 --- a/src/Handlers/GameUpdate.cs +++ b/src/Handlers/GameUpdate.cs @@ -2,46 +2,63 @@ using Amnesia.Utilities; using System; -namespace Amnesia.Handlers { - internal class GameUpdate { +namespace Amnesia.Handlers +{ + internal class GameUpdate + { private static readonly ModLog log = new ModLog(); private static readonly uint _ceiling = 100; private static uint _counter = 0; private static bool isBloodmoon = false; - internal static void Handle() { + internal static void Handle() + { if (!Config.Loaded || !Config.ProtectMemoryDuringBloodmoon) { return; } - try { + try + { _counter++; - if (_counter > _ceiling) { + if (_counter > _ceiling) + { _counter = 0; HandleBloodMoon(); } - } catch (Exception e) { + } + catch (Exception e) + { log.Error("Failed to handle GameUpdate event.", e); } } - private static void HandleBloodMoon() { + private static void HandleBloodMoon() + { // TODO: this should probably be injected into triggers when bloodmoon starts and ends, honestly - try { - if (isBloodmoon == GameManager.Instance.World.aiDirector.BloodMoonComponent.BloodMoonActive) { + try + { + if (isBloodmoon == GameManager.Instance.World.aiDirector.BloodMoonComponent.BloodMoonActive) + { return; } isBloodmoon = !isBloodmoon; var players = GameManager.Instance.World.Players.list; - if (isBloodmoon) { - for (var i = 0; i < players.Count; i++) { + if (isBloodmoon) + { + for (var i = 0; i < players.Count; i++) + { _ = players[i].Buffs.AddBuff(Values.BuffBloodmoonLifeProtection); } - } else { - for (var i = 0; i < players.Count; i++) { + } + else + { + for (var i = 0; i < players.Count; i++) + { _ = players[i].Buffs.AddBuff(Values.BuffPostBloodmoonLifeProtection); players[i].Buffs.RemoveBuff(Values.BuffBloodmoonLifeProtection); } } - } catch (Exception e) { + } + catch (Exception e) + { log.Error("Failed to handle bloodmoon.", e); } } diff --git a/src/Handlers/PlayerSpawnedInWorld.cs b/src/Handlers/PlayerSpawnedInWorld.cs index 5c37160..3a1bb2a 100644 --- a/src/Handlers/PlayerSpawnedInWorld.cs +++ b/src/Handlers/PlayerSpawnedInWorld.cs @@ -2,8 +2,10 @@ using Amnesia.Utilities; using System; -namespace Amnesia.Handlers { - internal class PlayerSpawnedInWorld { +namespace Amnesia.Handlers +{ + internal class PlayerSpawnedInWorld + { private static readonly ModLog log = new ModLog(); /// @@ -13,13 +15,17 @@ internal class PlayerSpawnedInWorld { /// The type of respawn. /// The position this player is respawning to. /// This mod supports being dropped into an existing game, thanks to how we handle this process. - public static void Handle(ClientInfo clientInfo, RespawnType respawnType, Vector3i pos) { + public static void Handle(ClientInfo clientInfo, RespawnType respawnType, Vector3i pos) + { if (!Config.Loaded) { return; } - try { - if (clientInfo == null || !GameManager.Instance.World.Players.dict.TryGetValue(clientInfo.entityId, out var player) || !player.IsAlive()) { + try + { + if (clientInfo == null || !GameManager.Instance.World.Players.dict.TryGetValue(clientInfo.entityId, out var player) || !player.IsAlive()) + { return; // exit early if player cannot be found in active world or is dead } - switch (respawnType) { + switch (respawnType) + { case RespawnType.EnterMultiplayer: // first-time login for new player _ = PlayerHelper.AddPositiveOutlookTime(player, Config.PositiveOutlookTimeOnFirstJoin); RefundHardenedMemory(clientInfo, player); @@ -36,7 +42,9 @@ public static void Handle(ClientInfo clientInfo, RespawnType respawnType, Vector HandleStandardRespawnSteps(player); break; } - } catch (Exception e) { + } + catch (Exception e) + { log.Error("Failed to handle PlayerSpawnedInWorld event.", e); } } @@ -46,27 +54,36 @@ public static void Handle(ClientInfo clientInfo, RespawnType respawnType, Vector /// /// Player to process steps for. /// This method also handles cleanup when player was already dead on Enter/Join (happens if player logged out while dead). - private static void HandleStandardRespawnSteps(EntityPlayer player) { + private static void HandleStandardRespawnSteps(EntityPlayer player) + { // Ensure joining/respawning players have their constants updated - if (player.GetCVar(Values.CVarLongTermMemoryLevel) != Config.LongTermMemoryLevel) { + if (player.GetCVar(Values.CVarLongTermMemoryLevel) != Config.LongTermMemoryLevel) + { player.SetCVar(Values.CVarLongTermMemoryLevel, Config.LongTermMemoryLevel); } // Remove Positive Outlook if admin disabled it since player's last login - if (Config.PositiveOutlookTimeOnMemoryLoss == 0 && player.Buffs.HasBuff(Values.BuffPositiveOutlook)) { + if (Config.PositiveOutlookTimeOnMemoryLoss == 0 && player.Buffs.HasBuff(Values.BuffPositiveOutlook)) + { player.Buffs.RemoveBuff(Values.BuffPositiveOutlook); } // Apply/Remove memory protection based on configuration - if (Config.ProtectMemoryDuringBloodmoon) { + if (Config.ProtectMemoryDuringBloodmoon) + { // add or remove protection based on whether BM is active - if (GameManager.Instance.World.aiDirector.BloodMoonComponent.BloodMoonActive) { + if (GameManager.Instance.World.aiDirector.BloodMoonComponent.BloodMoonActive) + { _ = player.Buffs.AddBuff(Values.BuffBloodmoonLifeProtection); - } else { + } + else + { player.Buffs.RemoveBuff(Values.BuffBloodmoonLifeProtection); } - } else { + } + else + { // remove/clean up since protection is inactive player.Buffs.RemoveBuff(Values.BuffBloodmoonLifeProtection); player.Buffs.RemoveBuff(Values.BuffPostBloodmoonLifeProtection); @@ -77,8 +94,10 @@ private static void HandleStandardRespawnSteps(EntityPlayer player) { /// Temporary method to automatically refund any players with the Hardened Memory buff from version 1.0.0. /// /// EntityPlayer to check buffs for and refund if hardened. - private static void RefundHardenedMemory(ClientInfo clientInfo, EntityPlayer player) { - if (player.Buffs.HasBuff(Values.BuffHardenedMemory)) { + private static void RefundHardenedMemory(ClientInfo clientInfo, EntityPlayer player) + { + if (player.Buffs.HasBuff(Values.BuffHardenedMemory)) + { PlayerHelper.GiveItem(clientInfo, player, Values.NameMemoryBoosters); player.Buffs.RemoveBuff(Values.BuffHardenedMemory); } diff --git a/src/Handlers/SavePlayerData.cs b/src/Handlers/SavePlayerData.cs index f0b929e..54d52cc 100644 --- a/src/Handlers/SavePlayerData.cs +++ b/src/Handlers/SavePlayerData.cs @@ -4,30 +4,38 @@ using System.Collections; using UnityEngine; -namespace Amnesia.Handlers { - internal class SavePlayerData { +namespace Amnesia.Handlers +{ + internal class SavePlayerData + { private static readonly ModLog log = new ModLog(); - public static void Handle(ClientInfo clientInfo, PlayerDataFile playerDataFile) { + public static void Handle(ClientInfo clientInfo, PlayerDataFile playerDataFile) + { if (!Config.Loaded) { return; } - try { - if (!ModApi.Obituary.ContainsKey(clientInfo.entityId)) { + try + { + if (!ModApi.Obituary.ContainsKey(clientInfo.entityId)) + { return; } _ = ModApi.Obituary.Remove(clientInfo.entityId); - if (clientInfo == null || !GameManager.Instance.World.Players.dict.TryGetValue(clientInfo.entityId, out var player)) { + if (clientInfo == null || !GameManager.Instance.World.Players.dict.TryGetValue(clientInfo.entityId, out var player)) + { log.Warn("EntityWasKilled event sent from a non-player client... may want to investigate"); return; // exit early, do not interrupt other mods from processing event } - if (!player.Buffs.HasBuff(Values.BuffFragileMemory)) { + if (!player.Buffs.HasBuff(Values.BuffFragileMemory)) + { _ = player.Buffs.AddBuff(Values.BuffFragileMemory); log.Info($"{clientInfo.InternalId.CombinedString} ({player.GetDebugName()}) died and will not be reset, but now has a Fragile Memory."); return; // let player know it's time for memory boosters } - if ((Config.ForgetActiveQuests || Config.ForgetInactiveQuests) && QuestHelper.ResetQuests(player)) { + if ((Config.ForgetActiveQuests || Config.ForgetInactiveQuests) && QuestHelper.ResetQuests(player)) + { // TODO: actually just redesign quest resets to issue remote admin call for client to run locally (an amazing feature!) // ================================================= @@ -48,18 +56,22 @@ public static void Handle(ClientInfo clientInfo, PlayerDataFile playerDataFile) // Reset Player log.Info($"{clientInfo.InternalId.CombinedString} ({player.GetDebugName()}) died and has suffered memory loss."); PlayerHelper.ResetPlayer(player); - } catch (Exception e) { + } + catch (Exception e) + { log.Error("Failed to handle OnSavePlayerData", e); } } - protected static IEnumerator SaveLater(float _delayInSec, ClientInfo clientInfo, EntityPlayer player) { + protected static IEnumerator SaveLater(float _delayInSec, ClientInfo clientInfo, EntityPlayer player) + { yield return new WaitForSecondsRealtime(_delayInSec); WritePlayerData(clientInfo, player); yield break; } - private static void WritePlayerData(ClientInfo clientInfo, EntityPlayer player, bool saveMap = false) { + private static void WritePlayerData(ClientInfo clientInfo, EntityPlayer player, bool saveMap = false) + { var pdf = new PlayerDataFile(); pdf.FromPlayer(player); @@ -69,7 +81,8 @@ private static void WritePlayerData(ClientInfo clientInfo, EntityPlayer player, //clientInfo.latestPlayerData = pdf; //clientInfo.latestPlayerData.Save(GameIO.GetPlayerDataDir(), clientInfo.InternalId.CombinedString); - if (saveMap && player.ChunkObserver.mapDatabase != null) { + if (saveMap && player.ChunkObserver.mapDatabase != null) + { _ = ThreadManager.AddSingleTask( new ThreadManager.TaskFunctionDelegate(player.ChunkObserver.mapDatabase.SaveAsync), new MapChunkDatabase.DirectoryPlayerId(GameIO.GetPlayerDataDir(), diff --git a/src/ModApi.cs b/src/ModApi.cs index a6bad7e..4f4dc01 100644 --- a/src/ModApi.cs +++ b/src/ModApi.cs @@ -2,11 +2,14 @@ using Amnesia.Handlers; using System.Collections.Generic; -namespace Amnesia { - internal class ModApi : IModApi { +namespace Amnesia +{ + internal class ModApi : IModApi + { public static Dictionary Obituary { get; private set; } = new Dictionary(); - public void InitMod(Mod _modInstance) { + public void InitMod(Mod _modInstance) + { ModEvents.GameStartDone.RegisterHandler(Config.Load); ModEvents.GameUpdate.RegisterHandler(GameUpdate.Handle); ModEvents.PlayerSpawnedInWorld.RegisterHandler(PlayerSpawnedInWorld.Handle); diff --git a/src/Utilities/MessagingSystem.cs b/src/Utilities/MessagingSystem.cs index 1145a22..79394a5 100644 --- a/src/Utilities/MessagingSystem.cs +++ b/src/Utilities/MessagingSystem.cs @@ -2,31 +2,41 @@ using System.Collections.Generic; using System.Linq; -namespace Amnesia.Utilities { - internal class MessagingSystem { +namespace Amnesia.Utilities +{ + internal class MessagingSystem + { /// /// Send a private message to a specific player. /// /// The message to send. /// The player entityId(s) this message is addressed to. - public static void Whisper(string message, params int[] recipients) => Send(EChatType.Whisper, message, recipients.ToList()); + public static void Whisper(string message, params int[] recipients) + { + Send(EChatType.Whisper, message, recipients.ToList()); + } /// /// Send a private message to a specific player. /// /// The message to send. /// The player entityId(s) this message is addressed to. - public static void Whisper(string message, List recipients) => Send(EChatType.Whisper, message, recipients); + public static void Whisper(string message, List recipients) + { + Send(EChatType.Whisper, message, recipients); + } /// /// Send a message to all players. /// /// The message to send. - public static void Broadcast(string message) { + public static void Broadcast(string message) + { var players = GameManager.Instance.World.Players.list; var entityIds = new List(); - for (var i = 0; i < players.Count; i++) { + for (var i = 0; i < players.Count; i++) + { entityIds.Add(players[i].entityId); } Send(EChatType.Global, message, entityIds); @@ -37,18 +47,23 @@ public static void Broadcast(string message) { /// /// The message to send. /// The condition determining whether the player will receive the given message. - public static void Broadcast(string message, Func condition) { + public static void Broadcast(string message, Func condition) + { var players = GameManager.Instance.World.Players.list; var entityIds = new List(); - for (var i = 0; i < players.Count; i++) { - if (condition.Invoke(players[i])) { + for (var i = 0; i < players.Count; i++) + { + if (condition.Invoke(players[i])) + { entityIds.Add(players[i].entityId); } } Send(EChatType.Global, message, entityIds); } - private static void Send(EChatType chatType, string message, List recipients) => GameManager.Instance.ChatMessageServer( + private static void Send(EChatType chatType, string message, List recipients) + { + GameManager.Instance.ChatMessageServer( _cInfo: null, _chatType: chatType, _senderEntityId: -1, @@ -56,5 +71,6 @@ private static void Send(EChatType chatType, string message, List recipient _mainName: "", _localizeMain: false, _recipientEntityIds: recipients); + } } } diff --git a/src/Utilities/ModLog.cs b/src/Utilities/ModLog.cs index ffd5a1d..02dab42 100644 --- a/src/Utilities/ModLog.cs +++ b/src/Utilities/ModLog.cs @@ -1,40 +1,57 @@ using System; -namespace Amnesia.Utilities { - internal static class ModLog { +namespace Amnesia.Utilities +{ + internal static class ModLog + { internal static bool DebugMode { get; set; } = false; } - internal class ModLog { + internal class ModLog + { private readonly string className; - public ModLog() => className = typeof(T).FullName; + public ModLog() + { + className = typeof(T).FullName; + } - public void Trace(string message) { - if (ModLog.DebugMode) { + public void Trace(string message) + { + if (ModLog.DebugMode) + { Log.Out($"[{className}] TRACE: {message}"); } } - public void Debug(string message) { - if (ModLog.DebugMode) { + public void Debug(string message) + { + if (ModLog.DebugMode) + { Log.Out($"[{className}] DEBUG: {message}"); } } - public void Info(string message) => Log.Out($"[{className}] {message}"); + public void Info(string message) + { + Log.Out($"[{className}] {message}"); + } - public void Warn(string message, Exception e = null) { + public void Warn(string message, Exception e = null) + { Log.Warning($"[{className}] {message}"); - if (e != null) { + if (e != null) + { Log.Warning($"[{className}] {message}\n{e.Message}\n{e.StackTrace}"); Log.Exception(e); } } - public void Error(string message, Exception e = null) { + public void Error(string message, Exception e = null) + { Log.Error($"[{className}] {message}"); - if (e != null) { + if (e != null) + { Log.Error($"[{className}] {message}\n{e.Message}\n{e.StackTrace}"); Log.Exception(e); } diff --git a/src/Utilities/PlayerHelper.cs b/src/Utilities/PlayerHelper.cs index ed2021a..ff1519a 100644 --- a/src/Utilities/PlayerHelper.cs +++ b/src/Utilities/PlayerHelper.cs @@ -2,51 +2,67 @@ using System; using UnityEngine; -namespace Amnesia.Utilities { - internal class PlayerHelper { +namespace Amnesia.Utilities +{ + internal class PlayerHelper + { private static readonly ModLog log = new ModLog(); /// Most of the following core logic was lifted from ActionResetPlayerData.PerformTargetAction - public static void ResetPlayer(EntityPlayer player) { + public static void ResetPlayer(EntityPlayer player) + { var needsSave = false; - if (Config.ForgetSchematics) { + if (Config.ForgetSchematics) + { var recipes = CraftingManager.GetRecipes(); - for (var i = 0; i < recipes.Count; i++) { - if (recipes[i].IsLearnable) { + for (var i = 0; i < recipes.Count; i++) + { + if (recipes[i].IsLearnable) + { player.SetCVar(recipes[i].GetName(), 0); } } } // Zero out Player KD Stats - if (Config.ForgetKdr) { + if (Config.ForgetKdr) + { player.Died = 0; player.KilledPlayers = 0; player.KilledZombies = 0; needsSave = true; } - if (Config.ForgetLevelsAndSkills) { + if (Config.ForgetLevelsAndSkills) + { player.Progression.ResetProgression(Config.ForgetBooks); player.Progression.Level = Config.LongTermMemoryLevel; player.Progression.ExpToNextLevel = player.Progression.GetExpForNextLevel(); player.Progression.SkillPoints = Config.LongTermMemoryLevel - 1; // Return all skill points rewarded from completed quest; should cover vanilla quest_BasicSurvival8, for example - if (!Config.ForgetIntroQuests) { - try { - for (var i = 0; i < player.QuestJournal.quests.Count; i++) { - if (player.QuestJournal.quests[i].CurrentState == Quest.QuestState.Completed) { + if (!Config.ForgetIntroQuests) + { + try + { + for (var i = 0; i < player.QuestJournal.quests.Count; i++) + { + if (player.QuestJournal.quests[i].CurrentState == Quest.QuestState.Completed) + { var rewards = player.QuestJournal.quests[i].Rewards; - for (var j = 0; j < rewards.Count; j++) { - if (rewards[j] is RewardSkillPoints) { + for (var j = 0; j < rewards.Count; j++) + { + if (rewards[j] is RewardSkillPoints) + { player.Progression.SkillPoints += Convert.ToInt32((rewards[j] as RewardSkillPoints).Value); } } } } - } catch (Exception e) { + } + catch (Exception e) + { log.Error("Failed to scan for completed skillpoints.", e); } } @@ -65,7 +81,8 @@ public static void ResetPlayer(EntityPlayer player) { needsSave = true; } - if (needsSave) { + if (needsSave) + { // Set flags to trigger incorporation of new stats/values into update cycle player.Progression.bProgressionStatsChanged = true; player.bPlayerStatsChanged = true; @@ -73,21 +90,25 @@ public static void ResetPlayer(EntityPlayer player) { } _ = player.Buffs.AddBuff(Values.BuffMemoryLoss); - if (Config.PositiveOutlookTimeOnMemoryLoss > 0) { + if (Config.PositiveOutlookTimeOnMemoryLoss > 0) + { log.Trace($"{player.GetDebugName()} will receive the Positive Outlook buff."); player.SetCVar(Values.CVarPositiveOutlookRemTime, Config.PositiveOutlookTimeOnMemoryLoss); _ = player.Buffs.AddBuff(Values.BuffPositiveOutlook); } } - public static float AddPositiveOutlookTime(EntityPlayer player, int valueToAdd) { - if (valueToAdd == 0) { + public static float AddPositiveOutlookTime(EntityPlayer player, int valueToAdd) + { + if (valueToAdd == 0) + { return 0; } var playerRemTime = Math.Max(0, player.GetCVar(Values.CVarPositiveOutlookRemTime)); var targetValue = Math.Min(playerRemTime + valueToAdd, Config.PositiveOutlookMaxTime); player.SetCVar(Values.CVarPositiveOutlookRemTime, targetValue); - if (!player.Buffs.HasBuff(Values.BuffPositiveOutlook)) { + if (!player.Buffs.HasBuff(Values.BuffPositiveOutlook)) + { _ = player.Buffs.AddBuff(Values.BuffPositiveOutlook); } return targetValue; @@ -99,7 +120,8 @@ public static float AddPositiveOutlookTime(EntityPlayer player, int valueToAdd) /// EntityPlayer to give item to. /// Name of the item to give the player. /// Number of items to give within a single stack (only works with stackable items). - public static void GiveItem(EntityPlayer player, string itemName, int count = 1) { + public static void GiveItem(EntityPlayer player, string itemName, int count = 1) + { var itemStack = new ItemStack(ItemClass.GetItem(itemName, true), count); var clientInfo = ConnectionManager.Instance.Clients.ForEntityId(player.entityId); GiveItemStack(clientInfo, player.GetBlockPosition(), itemStack); @@ -112,14 +134,17 @@ public static void GiveItem(EntityPlayer player, string itemName, int count = 1) /// EntityPlayer to give item to. /// Name of the item to give the player. /// Number of items to give within a single stack (only works with stackable items). - public static void GiveItem(ClientInfo clientInfo, EntityPlayer player, string itemName, int count = 1) { + public static void GiveItem(ClientInfo clientInfo, EntityPlayer player, string itemName, int count = 1) + { var itemStack = new ItemStack(ItemClass.GetItem(itemName, true), count); GiveItemStack(clientInfo, player.GetBlockPosition(), itemStack); } - internal static void GiveItemStack(ClientInfo clientInfo, Vector3i pos, ItemStack itemStack) { + internal static void GiveItemStack(ClientInfo clientInfo, Vector3i pos, ItemStack itemStack) + { var entityId = EntityFactory.nextEntityID++; - GameManager.Instance.World.SpawnEntityInWorld((EntityItem)EntityFactory.CreateEntity(new EntityCreationData { + GameManager.Instance.World.SpawnEntityInWorld((EntityItem)EntityFactory.CreateEntity(new EntityCreationData + { entityClass = EntityClass.FromString("item"), id = entityId, itemStack = itemStack, diff --git a/src/Utilities/QuestHelper.cs b/src/Utilities/QuestHelper.cs index 7584a86..0a65206 100644 --- a/src/Utilities/QuestHelper.cs +++ b/src/Utilities/QuestHelper.cs @@ -3,8 +3,10 @@ using System.Globalization; using static Quest; -namespace Amnesia.Utilities { - internal class QuestHelper { +namespace Amnesia.Utilities +{ + internal class QuestHelper + { private static readonly ModLog log = new ModLog(); /// @@ -12,23 +14,29 @@ internal class QuestHelper { /// /// The player to remove quests for. /// Whether any quests were removed. - public static bool ResetQuests(EntityPlayer player) { - try { + public static bool ResetQuests(EntityPlayer player) + { + try + { var changed = false; - for (var i = 0; i < player.QuestJournal.quests.Count; i++) { + for (var i = 0; i < player.QuestJournal.quests.Count; i++) + { changed = changed || RemoveQuest(player, player.QuestJournal.quests[i]); } log.Trace($"Quests Changed after RemoveQuests? {changed}"); changed = changed || GiveStarterQuestIfMissing(player); log.Trace($"Quests Changed after GiveStarterQuestIfMissing? {changed}"); return changed; - } catch (Exception e) { + } + catch (Exception e) + { log.Error("Failed to reset quests.", e); return true; // tell server to disconnect player } } - private static bool RemoveQuest(EntityPlayer player, Quest quest) { + private static bool RemoveQuest(EntityPlayer player, Quest quest) + { log.Trace($"{quest.ID}\n - CurrentState: {quest.CurrentState}\n - Active: {quest.Active}\n - IsIntroQuest: {IsIntroQuest(quest)}\n - QuestClass: {quest.QuestClass}\n - Tracked: {quest.Tracked}\n!quest.ID.EqualsCaseInsensitive('quest_BasicSurvival1') {!quest.ID.EqualsCaseInsensitive("quest_BasicSurvival1")}"); var questIsActive = quest.Active; // cache calculated value @@ -44,33 +52,41 @@ private static bool RemoveQuest(EntityPlayer player, Quest quest) { : Config.ForgetInactiveQuests && RemoveInactiveQuest(player, quest); } - private static bool IsIntroQuest(Quest quest) { + private static bool IsIntroQuest(Quest quest) + { var idToLower = quest.ID.ToLower(); return idToLower.StartsWith("quest_BasicSurvival".ToLower()) || idToLower.StartsWith("quest_whiteRiverCitizen".ToLower()); } - private static bool RemoveActiveQuest(EntityPlayer player, Quest quest) { + private static bool RemoveActiveQuest(EntityPlayer player, Quest quest) + { log.Trace($"Removing {quest.ID}"); quest.CurrentState = QuestState.Failed; HandleUnlockPOI(player.entityId, quest); - if (quest.SharedOwnerID != -1) { + if (quest.SharedOwnerID != -1) + { SingletonMonoBehaviour.Instance.SendPackage(NetPackageManager.GetPackage().Setup(quest.QuestCode, quest.SharedOwnerID, player.entityId, false), false, quest.SharedOwnerID, -1, -1, -1); } - try { + try + { quest.RemoveMapObject(); // TODO: test this log.Debug($"success: removed map object for {quest.ID}"); - } catch (Exception e) { + } + catch (Exception e) + { log.Debug($"fail: remove map object for {quest.ID}: {e.Message}"); } PreProcessTrickyQuestObjectives(player, quest); player.QuestJournal.ForceRemoveQuest(quest.ID); // NOTE: removes quest from journal, triggers UnhookQuest, and triggers quest removal delegate - if (player.QuestJournal.TrackedQuest == quest) { + if (player.QuestJournal.TrackedQuest == quest) + { player.QuestJournal.TrackedQuest = null; // TODO: does this really need to be called for server-side op? } HandlePartyRemoveQuest(player, quest); - if (player.QuestJournal.ActiveQuest == quest) { + if (player.QuestJournal.ActiveQuest == quest) + { player.QuestJournal.ActiveQuest = null; // TODO: is this necessary for server-side op? player.QuestJournal.RefreshRallyMarkerPositions(); // TODO: this seems like it would probably be necessary... not 100% sure, though } @@ -82,25 +98,33 @@ private static bool RemoveActiveQuest(EntityPlayer player, Quest quest) { /// /// Entity Id to unlock POI with. /// Quest object to unlock. - private static void HandleUnlockPOI(int playerEntityId, Quest quest) { - if (quest.SharedOwnerID == -1) { - if (quest.GetPositionData(out var pos, PositionDataTypes.POIPosition)) { + private static void HandleUnlockPOI(int playerEntityId, Quest quest) + { + if (quest.SharedOwnerID == -1) + { + if (quest.GetPositionData(out var pos, PositionDataTypes.POIPosition)) + { QuestEventManager.Current.QuestUnlockPOI(playerEntityId, pos); } } } - private static void PreProcessTrickyQuestObjectives(EntityPlayer player, Quest quest) { - for (var i = 0; i < quest.Objectives.Count; i++) { + private static void PreProcessTrickyQuestObjectives(EntityPlayer player, Quest quest) + { + for (var i = 0; i < quest.Objectives.Count; i++) + { if (quest.Objectives[i] is ObjectiveFetch || quest.Objectives[i] is ObjectiveClearSleepers || quest.Objectives[i] is ObjectiveFetchAnyContainer || quest.Objectives[i] is ObjectiveFetchFromTreasure || quest.Objectives[i] is ObjectiveFetchFromContainer || - quest.Objectives[i] is ObjectiveBaseFetchContainer) { - try { + quest.Objectives[i] is ObjectiveBaseFetchContainer) + { + try + { // Process for objective.HandleFailed() and objective.RemoveHooks - switch (quest.Objectives[i]) { + switch (quest.Objectives[i]) + { case ObjectiveFetchFromContainer o: RemoveFetchItems(player, quest, o, o.questItemClassID); quest.RemovePositionData((o.FetchMode == ObjectiveFetchFromContainer.FetchModeTypes.Standard) ? PositionDataTypes.FetchContainer : PositionDataTypes.HiddenCache); @@ -125,7 +149,8 @@ quest.Objectives[i] is ObjectiveFetchFromContainer || quest.Objectives[i].RemoveNavObject(); // Process for objective.RemoveObjectives() - if (!(quest.Objectives[i] is ObjectiveFetch)) { // if not ObjectiveFetch... + if (!(quest.Objectives[i] is ObjectiveFetch)) + { // if not ObjectiveFetch... quest.Objectives[i].RemoveObjectives(); } @@ -133,7 +158,9 @@ quest.Objectives[i] is ObjectiveFetchFromContainer || //quest.RemoveMapObject(); QuestEventManager.Current.RemoveObjectiveToBeUpdated(quest.Objectives[i]); _ = quest.Objectives.Remove(quest.Objectives[i]); - } catch (Exception e) { + } + catch (Exception e) + { log.Error($@"Failed to process tricky quest objectives: ID: {quest.Objectives[i].ID} Owner Class: {quest.Objectives[i].OwnerQuestClass} @@ -144,10 +171,12 @@ quest.Objectives[i] is ObjectiveFetchFromContainer || } } - private static void RemoveFetchItems(EntityPlayer player, Quest quest, BaseObjective objective, string questItemClassID) { // TODO: TEST + private static void RemoveFetchItems(EntityPlayer player, Quest quest, BaseObjective objective, string questItemClassID) + { // TODO: TEST var expectedItemClass = ItemClass.GetItemClass(questItemClassID, false); var expectedItem = new ItemValue(expectedItemClass.Id, false); - if (expectedItemClass is ItemClassQuest) { + if (expectedItemClass is ItemClassQuest) + { var num = StringParsers.ParseUInt16(objective.ID, 0, -1, NumberStyles.Integer); //expectedItemClass = ItemClassQuest.GetItemQuestById(num); expectedItem.Seed = num; @@ -162,24 +191,33 @@ private static void RemoveFetchItems(EntityPlayer player, Quest quest, BaseObjec /// /// Player to remove quest for. /// Quest to remove. - private static void HandlePartyRemoveQuest(EntityPlayer player, Quest quest) { - if (player.IsInParty() && quest.SharedOwnerID == -1) { - for (var i = 0; i < player.Party.MemberList.Count; i++) { + private static void HandlePartyRemoveQuest(EntityPlayer player, Quest quest) + { + if (player.IsInParty() && quest.SharedOwnerID == -1) + { + for (var i = 0; i < player.Party.MemberList.Count; i++) + { ConnectionManager.Instance.SendPackage(NetPackageManager.GetPackage().Setup(quest.QuestCode, player.entityId), false, player.Party.MemberList[i].entityId, -1, -1, -1); } } } - private static bool RemoveInactiveQuest(EntityPlayer player, Quest quest) => player.QuestJournal.quests.Remove(quest); + private static bool RemoveInactiveQuest(EntityPlayer player, Quest quest) + { + return player.QuestJournal.quests.Remove(quest); + } - private static bool GiveStarterQuestIfMissing(EntityPlayer player) { // TODO: TEST THIS + private static bool GiveStarterQuestIfMissing(EntityPlayer player) + { // TODO: TEST THIS // TODO: does not fire... perhaps issue this on each player's login? //GameEventManager.Current.HandleAction("game_first_spawn", player, player, false, "", "", false); // TODO: perhaps.. just create the quest and put it in the quests list? Using QuestJournal.Add might not be necessary at all - for (var i = 0; i < player.QuestJournal.quests.Count; i++) { - if (player.QuestJournal.quests[i].ID.EqualsCaseInsensitive("quest_BasicSurvival1")) { + for (var i = 0; i < player.QuestJournal.quests.Count; i++) + { + if (player.QuestJournal.quests[i].ID.EqualsCaseInsensitive("quest_BasicSurvival1")) + { log.Trace("quest_BasicSurvival1 was present"); return false; } From d2007f352603042d6f3634154cdc9b1e0d54f508 Mon Sep 17 00:00:00 2001 From: jonathan-robertson Date: Sun, 19 Feb 2023 19:36:48 -0600 Subject: [PATCH 2/2] update xp debt prevention text --- CHANGELOG.md | 4 ++++ Config/Localization.txt | 3 +++ ModInfo.xml | 2 +- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d3b6788..21186d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.1.1] - 2023-02-19 + +- update xp debt prevention text + ## [1.1.0] - 2023-01-03 - add fragile memory state diff --git a/Config/Localization.txt b/Config/Localization.txt index acaf17b..52dbb9c 100644 --- a/Config/Localization.txt +++ b/Config/Localization.txt @@ -3,6 +3,9 @@ amnesiaJournalTip,Journal Tip,,"Survivors are reporting strange occurrences of Amnesia when experiencing severe trauma... At level [007fff]{cvar(amnesiaLongTermMemoryLevel)}[-] and beyond, becoming incapacitated will result in a [ff8000]Fragile Memory[-]. This [ff8000]Fragile Memory[-] will cause full-blown [ff007f]Memory Loss[-] if you were to become incapacitated once more.\n\n[ff8000]This Happens Every Time I Die?[-]\nDying will impact memory, but there are a few exceptions: if [00ff80]another player kills you[-], or if [00ff80]you die during Blood Moon for any reason[-].\n\n[ff8000]What Would I Forget Due to Memory Loss?[-]\nYou will forget your level, learned skills, and unspent skill points (you'll be reset back to level [007fff]{cvar(amnesiaLongTermMemoryLevel)}[-] and can reallocate the skillpoints you would've had at that level).\n\n[ff8000]Will I Remember Anything After Memory Loss?[-]\nYou will never forget schematics, books, items/equipment (backpack is dropped on ground, but not deleted), vehicles, map, waypoints, land claims, bedroll location, quests, trader relationships.\n\n[ff8000]How Can I Recover From a Fragile Memory?[-]\nYou'll find that all traders sell a new item called [007fff]Trader Jen's Memory Boosters[-] in limited quantities, which you can use to recover from a [ff8000]Fragile Memory[-]. This will give you a buffer against memory loss, but the sale price is also quite high; you probably won't be able to afford it right away.\n\n[ff8000]Anything Else I Should Know?[-]\nDefeating certain powerful zombies will lift your spirits, providing a timed boost of double xp for you and everyone else on the server! Try to take these challenging enemies down for the benefit and relief of the entire community." amnesiaJournalTip_title,Journal Tip,,"Amnesia [ff8000][MOD]" +buffNewbieCoatDesc,buffs,Buff,"There is no XP penalty on death.\n\nThis protection will eventually disappear, so plan ahead." +buffNewbieCoatName,buffs,Buff,"Death XP Penalty Protection" + buffAmnesiaFragileMemoryName,buffs,Buffs,"Fragile Memory" buffAmnesiaFragileMemoryDesc,buffs,Buffs,"You now have a [ff8000]Fragile Memory[-] due to being incapacitated. \n\nIf you become incapacitated again, you will experience [ff007f]Memory Loss[-].\n\n[007fff]Trader Jen's Memory Boosters[-] can be purchased from any trader to cure your [ff8000]Fragile Memory[-], which will provide a buffer against [ff007f]Memory Loss[-]." buffAmnesiaFragileMemoryStartTooltip,buffs,Buffs,"You now have a [ff8000]Fragile Memory[-] due to being incapacitated" diff --git a/ModInfo.xml b/ModInfo.xml index b16d974..0c86fa4 100644 --- a/ModInfo.xml +++ b/ModInfo.xml @@ -3,7 +3,7 @@ - + \ No newline at end of file