Skip to content

Commit

Permalink
feat: Large ACU support for eggs (#463)
Browse files Browse the repository at this point in the history
* Fixed stacked ACUs not working on large room ACU

* Fixed eggs throwing NRE on hatch

* Added a way to configure the required large ACU size

* Fixed undiscovered tech type not working

* Make sure that the eggs are hard locked.
  • Loading branch information
Metious committed Oct 26, 2023
1 parent 2d58afd commit d32b925
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 16 deletions.
31 changes: 23 additions & 8 deletions Nautilus/Assets/Gadgets/EggGadget.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,15 @@ namespace Nautilus.Assets.Gadgets;
public class EggGadget : Gadget
{
/// <summary>
/// The total amount of ACU floors required for the egg to be dropped in the ACU. defaulted to 1.
/// The total amount of normal ACU floors required for the egg to be dropped in the ACU. If this is set to 0, the egg will not be accepted in the normal ACU. Defaulted to 1.
/// </summary>
public int RequiredAcuSize { get; set; } = 1;

/// <summary>
/// The total amount of Large ACU floors required for the egg to be dropped in. If this is set to 0, the egg will not be accepted in the large ACU. Defaulted to 1.
/// </summary>
public int RequiredLargeAcuSize { get; set; } = 1;

/// <summary>
/// makes the egg immune to the Lost River's Acidic Brine.
/// </summary>
Expand All @@ -23,23 +28,36 @@ public class EggGadget : Gadget
/// Constructs a Creature egg gadget instance.
/// </summary>
/// <param name="prefab">The custom prefab to operate on.</param>
/// <param name="requiredAcuSize">The total amount of ACU floors required for the egg to be dropped in the ACU.</param>
/// <param name="requiredAcuSize">The total amount of ACU floors required for the egg to be dropped in the ACU. This value is shared between the normal and large ACU.</param>
public EggGadget(ICustomPrefab prefab, int requiredAcuSize = 1) : base(prefab)
{
RequiredAcuSize = requiredAcuSize;
RequiredLargeAcuSize = requiredAcuSize;
}

/// <summary>
/// The total amount of ACU floors required for the egg to be dropped in the ACU.
/// The total amount of normal ACU floors required for the egg to be dropped in the ACU.
/// </summary>
/// <param name="requiredAcuSize">The ACU stacks value.</param>
/// <param name="requiredAcuSize">The ACU stacks value. If this is set to 0, the egg will not be accepted in the normal ACU.</param>
/// <returns>A reference to this instance after the operation has completed.</returns>
public EggGadget WithRequiredAcuSize(int requiredAcuSize)
{
RequiredAcuSize = requiredAcuSize;

return this;
}

/// <summary>
/// The total amount of Large ACU floors required for the egg to be dropped in.
/// </summary>
/// <param name="requiredLargeAcuSize">The large ACU stacks value. If this is set to 0, the egg will not be accepted in the large ACU.</param>
/// <returns>A reference to this instance after the operation has completed.</returns>
public EggGadget WithRequiredLargeAcuSize(int requiredLargeAcuSize)
{
RequiredLargeAcuSize = requiredLargeAcuSize;

return this;
}

/// <summary>
/// makes the egg immune to the Lost River's Acidic Brine.
Expand All @@ -65,9 +83,6 @@ protected internal override void Build()
if (AcidImmune)
DamageSystem.acidImmune.Add(prefab.Info.TechType);

if (RequiredAcuSize > 1)
{
WaterParkPatcher.requiredAcuSize[prefab.Info.TechType] = RequiredAcuSize;
}
WaterParkPatcher.requiredAcuSize[prefab.Info.TechType] = this;
}
}
3 changes: 2 additions & 1 deletion Nautilus/Assets/Gadgets/GadgetExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -269,14 +269,15 @@ public static ICustomPrefab SetSpawns(this ICustomPrefab customPrefab, WorldEnti
/// Makes this item have additional creature-egg-related functionality.
/// </summary>
/// <param name="customPrefab">The custom prefab the creature egg gadget is created for.</param>
/// <param name="requiredAcuSize">The total amount of ACU floors required for the egg to be dropped in the ACU.</param>
/// <param name="requiredAcuSize">The total amount of ACU floors required for the egg to be dropped in the ACU. This value is shared between the normal and the large ACU.</param>
/// <returns>A reference to the created <see cref="EggGadget"/> instance after the operation has completed.</returns>
public static EggGadget CreateCreatureEgg(this ICustomPrefab customPrefab, int requiredAcuSize = 1)
{
if (!customPrefab.TryGetGadget(out EggGadget creatureEggGadget))
creatureEggGadget = customPrefab.AddGadget(new EggGadget(customPrefab, requiredAcuSize));

creatureEggGadget.RequiredAcuSize = requiredAcuSize;
creatureEggGadget.RequiredLargeAcuSize = requiredAcuSize;
return creatureEggGadget;
}
}
5 changes: 5 additions & 0 deletions Nautilus/Assets/PrefabTemplates/EggTemplate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections;
using Nautilus.Extensions;
using Nautilus.Handlers;
using Nautilus.Patchers;
using Nautilus.Utility;
using UnityEngine;
using UnityEngine.AddressableAssets;
Expand Down Expand Up @@ -196,6 +197,9 @@ public EggTemplate SetUndiscoveredTechType()
.WithSizeInInventory(TechData.GetItemSize(info.TechType));
#endif

// eggs with undiscovered tech types shouldn't be unlocked by default at all, even on creative.
KnownTechHandler.SetHardLocked(info.TechType);

return this;
}

Expand Down Expand Up @@ -266,6 +270,7 @@ private IEnumerator ProcessEgg(GameObject obj)
#else
creatureEgg.animators = obj.GetComponentsInChildren<Animator>();
#endif
creatureEgg.liveMixin = liveMixin;
creatureEgg.creatureType = HatchingCreature;
PrefabDatabase.TryGetPrefabFilename(CraftData.GetClassIdForTechType(HatchingCreature), out var filename);
creatureEgg.creaturePrefab = new AssetReferenceGameObject(filename).ForceValid();
Expand Down
43 changes: 36 additions & 7 deletions Nautilus/Patchers/WaterParkPatcher.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
using System.Collections.Generic;
using HarmonyLib;
using Nautilus.Assets.Gadgets;
using Nautilus.Extensions;

namespace Nautilus.Patchers;

[HarmonyPatch(typeof(WaterPark))]
internal static class WaterParkPatcher
{
internal static Dictionary<TechType, int> requiredAcuSize = new();
internal static Dictionary<TechType, EggGadget> requiredAcuSize = new();

internal static void Patch(Harmony harmony)
{
Expand All @@ -19,17 +20,45 @@ internal static void Patch(Harmony harmony)
private static bool CanDropItemInsidePrefix(Pickupable item, ref bool __result)
{
var tt = CraftData.GetTechType(item.gameObject);
if (requiredAcuSize.TryGetValue(tt, out var maxHeight))
if (requiredAcuSize.TryGetValue(tt, out var eggGadget))
{
var waterPark = Player.main.currentWaterPark;
if (waterPark is not null && waterPark.height >= maxHeight)
// large ACU
if (waterPark is LargeRoomWaterPark largeRoomWaterPark)
{
__result = true;
if (eggGadget.RequiredLargeAcuSize == 0)
{
ErrorMessage.main.AddHint($"Cannot drop {Language.main.Get(tt)} here. Drop in the normal ACU instead.");
__result = false;
}
else if (largeRoomWaterPark.size < eggGadget.RequiredLargeAcuSize)
{
ErrorMessage.main.AddHint($"Cannot drop {Language.main.Get(tt)} here, the large ACU must be at least {eggGadget.RequiredAcuSize} floors tall.");
__result = false;
}
else
{
__result = true;
}

}
else
// normal ACU
else if (waterPark is not null)
{
ErrorMessage.main.AddHint(string.Format("Cannot drop {0} here, the ACU must be at least {1} units tall.", Language.main.Get(tt), maxHeight));
__result = false;
if (eggGadget.RequiredAcuSize == 0)
{
ErrorMessage.main.AddHint($"Cannot drop {Language.main.Get(tt)} here. Drop in the large ACU instead.");
__result = false;
}
else if (waterPark.height < eggGadget.RequiredAcuSize)
{
ErrorMessage.main.AddHint($"Cannot drop {Language.main.Get(tt)} here, the large ACU must be at least {eggGadget.RequiredAcuSize} floors tall.");
__result = false;
}
else
{
__result = true;
}
}

return false;
Expand Down

0 comments on commit d32b925

Please sign in to comment.