From 83b68744d4292be8b34206f8bdde315725960c2a Mon Sep 17 00:00:00 2001 From: MrPurple6411 Date: Sun, 17 Dec 2023 15:35:43 -0700 Subject: [PATCH] Survival Handler Fixes and Improvements. (#509) Fix: Setting negative oxygen did not work right. Fix: Setting Negative Health would never kill and could glitch the player if reaching 0. Fix: InventoryUsables was list instead of HashSet Improvement: Added RunActionOnConsume(TechType techType, Action customAction, bool isEdible) to allow mods to send their own custom action to be performed when item is consumed. --- Nautilus/Handlers/SurvivalHandler.cs | 83 ++++++++++++++++++---------- Nautilus/Patchers/SurvivalPatcher.cs | 2 +- 2 files changed, 55 insertions(+), 30 deletions(-) diff --git a/Nautilus/Handlers/SurvivalHandler.cs b/Nautilus/Handlers/SurvivalHandler.cs index f71dd280..0b477069 100644 --- a/Nautilus/Handlers/SurvivalHandler.cs +++ b/Nautilus/Handlers/SurvivalHandler.cs @@ -7,7 +7,7 @@ namespace Nautilus.Handlers; /// /// Handler class that relates to the component. Allows the defining of oxygen or health gains when consuming specific items. /// -public static class SurvivalHandler +public static class SurvivalHandler { /// /// makes the item gives oxygen on use. @@ -15,56 +15,81 @@ public static class SurvivalHandler /// the TechType that you want to make it give oxygen on use /// the oxygen amount the item gives /// set it to if the item is edible and has the component attached to it. - /// defaults to /// public static void GiveOxygenOnConsume(TechType techType, float oxygenGiven, bool isEdible) { - if (SurvivalPatcher.CustomSurvivalInventoryAction.TryGetValue(techType, out List action)) + if (!isEdible) { - action.Add(() => { Player.main.GetComponent().AddOxygen(oxygenGiven); }); // add an action to the list - return; + SurvivalPatcher.InventoryUseables.Add(techType); // add it to the HashSet of useables if its not edible } - // if we reach to this point then the techtype doesn't exist in the dictionary so we add it - SurvivalPatcher.CustomSurvivalInventoryAction[techType] = new List() - { - () => - { - Player.main.GetComponent().AddOxygen(oxygenGiven); - } - }; - if (!isEdible) + if (!SurvivalPatcher.CustomSurvivalInventoryAction.TryGetValue(techType, out List actions)) + actions = new List(); + + // add an action to the list + actions.Add(() => { - SurvivalPatcher.InventoryUseables.Add(techType); - } + var oxygenManager = Player.main.GetComponent(); + if (oxygenGiven > 0f) + oxygenManager.AddOxygen(oxygenGiven); + else + oxygenManager.RemoveOxygen(-oxygenGiven); + }); + + SurvivalPatcher.CustomSurvivalInventoryAction[techType] = actions; } + /// /// makes the item Heal the player on consume. /// /// the TechType that you want it to heal back /// amount to heal the player /// set it to if the item is edible and has the component attached to it. - /// defaults to /// public static void GiveHealthOnConsume(TechType techType, float healthBack, bool isEdible) { - if (SurvivalPatcher.CustomSurvivalInventoryAction.TryGetValue(techType, out List action)) + if (!isEdible) { - action.Add(() => { Player.main.GetComponent().AddHealth(healthBack); }); // add an action to the list - return; + SurvivalPatcher.InventoryUseables.Add(techType); // add it to the HashSet of useables if its not edible } - // if we reach to this point then the techtype doesn't exist in the dictionary so we add it - SurvivalPatcher.CustomSurvivalInventoryAction[techType] = new List() - { - () => - { - Player.main.GetComponent().AddHealth(healthBack); - } - }; + if (!SurvivalPatcher.CustomSurvivalInventoryAction.TryGetValue(techType, out List actions)) + actions = new List(); + + actions.Add(() => { + var liveMixin = Player.main.GetComponent(); + if (healthBack > 0) + liveMixin.AddHealth(healthBack); + else + liveMixin.TakeDamage(-healthBack, default, DamageType.Poison); + }); + + SurvivalPatcher.CustomSurvivalInventoryAction[techType] = actions; + } + + /// + /// runs a custom action on consume. + /// + /// the TechType that you want it to heal back + /// the Action to perform. + /// set it to if the item is edible and has the component attached to it. + /// + public static void RunActionOnConsume(TechType techType, Action customAction, bool isEdible) + { + if (techType == TechType.None) + throw new ArgumentNullException(nameof(techType), "TechType cannot be None."); + if (customAction == null) + throw new ArgumentNullException(nameof(customAction), "Action cannot be null."); + if (!isEdible) { - SurvivalPatcher.InventoryUseables.Add(techType); + SurvivalPatcher.InventoryUseables.Add(techType); // add it to the HashSet of useables if its not edible } + + if (!SurvivalPatcher.CustomSurvivalInventoryAction.TryGetValue(techType, out List actions)) + actions = new List(); + + actions.Add(customAction); + SurvivalPatcher.CustomSurvivalInventoryAction[techType] = actions; } } \ No newline at end of file diff --git a/Nautilus/Patchers/SurvivalPatcher.cs b/Nautilus/Patchers/SurvivalPatcher.cs index 00ae3f77..62ec5dcd 100644 --- a/Nautilus/Patchers/SurvivalPatcher.cs +++ b/Nautilus/Patchers/SurvivalPatcher.cs @@ -10,7 +10,7 @@ namespace Nautilus.Patchers; internal class SurvivalPatcher { internal static IDictionary> CustomSurvivalInventoryAction = new SelfCheckingDictionary>("CustomSurvivalInventoryAction", TechTypeExtensions.sTechTypeComparer); - internal static List InventoryUseables = new(); + internal static HashSet InventoryUseables = new(); internal static void Patch(Harmony harmony) {