Skip to content

Commit

Permalink
Survival Handler Fixes and Improvements. (#509)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
MrPurple6411 committed Dec 17, 2023
1 parent 62fc980 commit 83b6874
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 30 deletions.
83 changes: 54 additions & 29 deletions Nautilus/Handlers/SurvivalHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,64 +7,89 @@ namespace Nautilus.Handlers;
/// <summary>
/// Handler class that relates to the <see cref="Survival"/> component. Allows the defining of oxygen or health gains when consuming specific items.
/// </summary>
public static class SurvivalHandler
public static class SurvivalHandler
{
/// <summary>
/// <para>makes the item gives oxygen on use.</para>
/// </summary>
/// <param name="techType">the TechType that you want to make it give oxygen on use</param>
/// <param name="oxygenGiven">the oxygen amount the item gives</param>
/// <param name="isEdible">set it to <see langword="true" /> if the item is edible and has the <see cref="Eatable"/> component attached to it.
/// <para>defaults to <see langword="false" /></para>
/// </param>
public static void GiveOxygenOnConsume(TechType techType, float oxygenGiven, bool isEdible)
{
if (SurvivalPatcher.CustomSurvivalInventoryAction.TryGetValue(techType, out List<Action> action))
if (!isEdible)
{
action.Add(() => { Player.main.GetComponent<OxygenManager>().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<Action>()
{
() =>
{
Player.main.GetComponent<OxygenManager>().AddOxygen(oxygenGiven);
}
};
if (!isEdible)
if (!SurvivalPatcher.CustomSurvivalInventoryAction.TryGetValue(techType, out List<Action> actions))
actions = new List<Action>();

// add an action to the list
actions.Add(() =>
{
SurvivalPatcher.InventoryUseables.Add(techType);
}
var oxygenManager = Player.main.GetComponent<OxygenManager>();
if (oxygenGiven > 0f)
oxygenManager.AddOxygen(oxygenGiven);
else
oxygenManager.RemoveOxygen(-oxygenGiven);
});

SurvivalPatcher.CustomSurvivalInventoryAction[techType] = actions;
}

/// <summary>
/// <para>makes the item Heal the player on consume.</para>
/// </summary>
/// <param name="techType">the TechType that you want it to heal back</param>
/// <param name="healthBack">amount to heal the player</param>
/// <param name="isEdible">set it to <see langword="true" /> if the item is edible and has the <see cref="Eatable"/> component attached to it.
/// <para>defaults to <see langword="false" /></para>
/// </param>
public static void GiveHealthOnConsume(TechType techType, float healthBack, bool isEdible)
{
if (SurvivalPatcher.CustomSurvivalInventoryAction.TryGetValue(techType, out List<Action> action))
if (!isEdible)
{
action.Add(() => { Player.main.GetComponent<LiveMixin>().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<Action>()
{
() =>
{
Player.main.GetComponent<LiveMixin>().AddHealth(healthBack);
}
};
if (!SurvivalPatcher.CustomSurvivalInventoryAction.TryGetValue(techType, out List<Action> actions))
actions = new List<Action>();

actions.Add(() => {
var liveMixin = Player.main.GetComponent<LiveMixin>();
if (healthBack > 0)
liveMixin.AddHealth(healthBack);
else
liveMixin.TakeDamage(-healthBack, default, DamageType.Poison);
});

SurvivalPatcher.CustomSurvivalInventoryAction[techType] = actions;
}

/// <summary>
/// <para>runs a custom action on consume.</para>
/// </summary>
/// <param name="techType">the TechType that you want it to heal back</param>
/// <param name="customAction"> the Action to perform.</param>
/// <param name="isEdible">set it to <see langword="true" /> if the item is edible and has the <see cref="Eatable"/> component attached to it.
/// </param>
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<Action> actions))
actions = new List<Action>();

actions.Add(customAction);
SurvivalPatcher.CustomSurvivalInventoryAction[techType] = actions;
}
}
2 changes: 1 addition & 1 deletion Nautilus/Patchers/SurvivalPatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace Nautilus.Patchers;
internal class SurvivalPatcher
{
internal static IDictionary<TechType, List<Action>> CustomSurvivalInventoryAction = new SelfCheckingDictionary<TechType, List<Action>>("CustomSurvivalInventoryAction", TechTypeExtensions.sTechTypeComparer);
internal static List<TechType> InventoryUseables = new();
internal static HashSet<TechType> InventoryUseables = new();

internal static void Patch(Harmony harmony)
{
Expand Down

0 comments on commit 83b6874

Please sign in to comment.