using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using IngredientVisualEffectSystem;
using Microsoft.CodeAnalysis;
using PotionCraft;
using PotionCraft.Assemblies.GamepadNavigation;
using PotionCraft.Assemblies.GamepadNavigation.Conditions;
using PotionCraft.Core;
using PotionCraft.Core.SerializableDictionary;
using PotionCraft.LocalizationSystem;
using PotionCraft.ManagersSystem;
using PotionCraft.ManagersSystem.Input.ControlProviders;
using PotionCraft.ManagersSystem.Player;
using PotionCraft.ManagersSystem.Potion;
using PotionCraft.ManagersSystem.Room;
using PotionCraft.NotificationSystem;
using PotionCraft.ObjectBased;
using PotionCraft.ObjectBased.AlchemyMachine;
using PotionCraft.ObjectBased.Cauldron;
using PotionCraft.ObjectBased.InteractiveItem;
using PotionCraft.ObjectBased.InteractiveItem.InventoryObject;
using PotionCraft.ObjectBased.InteractiveItem.SoundControllers;
using PotionCraft.ObjectBased.InteractiveItem.SoundControllers.Presets;
using PotionCraft.ObjectBased.InteractiveItem.Vacuuming;
using PotionCraft.ObjectBased.Mortar;
using PotionCraft.ObjectBased.Potion;
using PotionCraft.ObjectBased.RecipeMap.RecipeMapItem.PotionEffectMapItem;
using PotionCraft.ObjectBased.ScalesSystem;
using PotionCraft.ObjectBased.Stack;
using PotionCraft.ObjectBased.Stack.StackItem;
using PotionCraft.ObjectBased.UIElements;
using PotionCraft.ObjectBased.UIElements.Books;
using PotionCraft.ObjectBased.UIElements.Books.RecipeBook;
using PotionCraft.ObjectBased.UIElements.PotionCraftPanel;
using PotionCraft.ObjectBased.UIElements.Tooltip;
using PotionCraft.SaveLoadSystem;
using PotionCraft.ScriptableObjects;
using PotionCraft.ScriptableObjects.Ingredient;
using PotionCraft.ScriptableObjects.Potion;
using PotionCraft.Settings;
using PotionCraft.SoundSystem;
using PotionCraft.SoundSystem.SoundPresets;
using PotionCraftPourBackIn.Scripts.Services;
using PotionCraftPourBackIn.Scripts.Storage;
using PotionCraftPourBackIn.Scripts.UIElements;
using UnityEngine;
using UnityEngine.Rendering;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("PotionCraftPourBackIn")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Recipe Waypoint Mod for Potion Craft")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("PotionCraftPourBackIn")]
[assembly: AssemblyTitle("PotionCraftPourBackIn")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace PotionCraftPourBackIn
{
[BepInPlugin("com.fahlgorithm.potioncraftpourbackin", "PotionCraftPourBackIn", "1.1.0.0")]
[BepInProcess("Potion Craft.exe")]
public class Plugin : BaseUnityPlugin
{
public const string PLUGIN_GUID = "com.fahlgorithm.potioncraftpourbackin";
public static ManualLogSource PluginLogger { get; private set; }
private void Awake()
{
PluginLogger = ((BaseUnityPlugin)this).Logger;
PluginLogger.LogInfo((object)"Plugin com.fahlgorithm.potioncraftpourbackin is loaded!");
Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "com.fahlgorithm.potioncraftpourbackin");
PluginLogger.LogInfo((object)"Plugin com.fahlgorithm.potioncraftpourbackin: Patch Succeeded!");
}
}
public static class PluginInfo
{
public const string PLUGIN_GUID = "PotionCraftPourBackIn";
public const string PLUGIN_NAME = "PotionCraftPourBackIn";
public const string PLUGIN_VERSION = "1.0.0";
}
}
namespace PotionCraftPourBackIn.Scripts
{
public static class Ex
{
public static bool RunSafe(Func<bool> action, Func<bool> errorAction = null)
{
try
{
return action();
}
catch (Exception ex)
{
LogException(ex);
}
return errorAction?.Invoke() ?? true;
}
public static void RunSafe(Action action, Action errorAction = null)
{
try
{
action();
}
catch (Exception ex)
{
LogException(ex);
errorAction?.Invoke();
}
}
public static void LogException(Exception ex)
{
string text = $"{ex.GetType()}: {ex.Message}\r\n{ex.StackTrace}\r\n{ex.InnerException?.Message}";
Plugin.PluginLogger.LogError((object)text);
}
}
}
namespace PotionCraftPourBackIn.Scripts.UIElements
{
public class PotionStackItem : StackItem
{
public PotionItem potionItem;
public override Bounds? GetHoveringColliderBounds()
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
return ((MovableItem)potionItem).mainCollider.bounds;
}
public override void SetPhysicsToDefault()
{
((Component)potionItem).gameObject.layer = 0;
}
public override void SetThisItemLayersToNormal()
{
((Component)potionItem).gameObject.layer = 14;
}
public override void IgnoreCollision(Collider2D target, bool ignore = true)
{
if (!((Object)(object)((Component)target).GetComponentInParent<ThrowVacuuming>() != (Object)(object)Managers.Ingredient.cauldron.throwVacuuming) && (ignore || !Managers.Potion.potionCraftPanel.IsPotionBrewingStarted()))
{
((InteractiveItem)potionItem).IgnoreCollision(target, ignore);
}
}
}
}
namespace PotionCraftPourBackIn.Scripts.Storage
{
public static class StaticStorage
{
public static bool CurrentlyMakingPotion;
public static bool CurrentlyGeneratingRecipe;
public static List<PotionUsedComponent> PouredInUsedComponents;
public static List<PotionEffect> PouredInEffects;
public static List<Potion> PotionItemsNotifiedFor = new List<Potion>();
public static float LastNotifiedTime;
public static Potion CurrentPotionCraftPanelPotion;
public static bool DummyEffectAddedToEnableFinishPotionGrab;
}
}
namespace PotionCraftPourBackIn.Scripts.Services
{
public static class EquipmentInteractionService
{
public static bool DisallowMortarPotionCollisions(Collider2D other, ThrowVacuuming throwVacuuming)
{
PotionStackItem componentInChildren = ((Component)other).GetComponentInChildren<PotionStackItem>();
if ((Object)(object)componentInChildren == (Object)null)
{
return true;
}
if (((StackItem)componentInChildren).IsVacuumingNow)
{
return false;
}
if ((Object)(object)throwVacuuming == (Object)(object)Managers.Ingredient.cauldron.throwVacuuming)
{
return true;
}
return false;
}
public static bool DisallowMortarGraphicStateSwitch(GraphicStateMachine instance, Collider2D other)
{
if (!(instance.stackItem is PotionStackItem))
{
return true;
}
if (Managers.Potion.potionCraftPanel.IsPotionBrewingStarted())
{
return false;
}
return !(((Component)other).GetComponentInParent<InteractiveItem>() is Mortar);
}
public static bool SetupSlotCauldronSlotConditionToAllowPotion(Slot instance)
{
if ((Object)(object)((Component)instance).GetComponentInParent<Cauldron>() == (Object)null)
{
return true;
}
if (((Object)((Component)((Component)instance).transform.parent).gameObject).name != "Cauldron")
{
return true;
}
if (instance.conditions.Contains((Condition)30))
{
return true;
}
if (!instance.conditions.Contains((Condition)10))
{
return true;
}
instance.conditions = instance.conditions.Concat((IEnumerable<Condition>)(object)new Condition[1] { (Condition)30 }).ToArray();
return true;
}
}
public static class PotionDataService
{
public static bool PotionHasSerializedData(Potion potion)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
if (!(potion.potionFromPanel.serializedPath.indicatorTargetPosition != Vector2.zero))
{
return (potion.potionFromPanel?.serializedPath?.fixedPathPoints?.Any()).GetValueOrDefault();
}
return true;
}
public static bool IsPotionStackItemEffect(StackVisualEffects instance)
{
return ((ItemFromInventory)(instance?.stackScript?)).inventoryItem is Potion;
}
public static void CopyImportantInfoToPotionInstance(Potion copyTo, Potion copyFromPotion, SerializedPotionFromPanel copyFrom)
{
List<SerializedRecipeMark> recipeMarks = copyTo.potionFromPanel.recipeMarks;
recipeMarks.Clear();
copyFrom.recipeMarks.ForEach(delegate(SerializedRecipeMark m)
{
recipeMarks.Add(m.Clone());
});
copyTo.potionFromPanel.collectedPotionEffects.Clear();
PotionEffect[] array = ((copyFromPotion != null) ? copyFromPotion.Effects : null) ?? Managers.Potion.collectedPotionEffects;
foreach (PotionEffect val in array)
{
if ((ComparableScriptableObject<PotionEffect>)(object)val == (ComparableScriptableObject<PotionEffect>)null)
{
break;
}
copyTo.potionFromPanel.collectedPotionEffects.Add(((Object)val).name);
}
copyTo.potionFromPanel.serializedPath = copyFrom.serializedPath;
List<PotionUsedComponent> usedComponents = copyTo.usedComponents;
if (usedComponents != null && !usedComponents.Any())
{
if (copyTo.usedComponents == null)
{
copyTo.usedComponents = new List<PotionUsedComponent>();
}
copyTo.usedComponents = Managers.Potion.usedComponents.Select((PotionUsedComponent component) => component.Clone()).ToList();
}
if (!copyFrom.potionUsedComponents.Any())
{
copyTo.usedComponents.ForEach(delegate(PotionUsedComponent component)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Expected O, but got Unknown
copyFrom.potionUsedComponents.Add(new SerializedUsedComponent
{
componentName = ((Object)component.componentObject).name,
componentAmount = component.amount,
componentType = ((object)(ComponentType)(ref component.componentType)).ToString()
});
});
}
copyTo.potionFromPanel.potionUsedComponents = copyFrom.potionUsedComponents;
copyTo.potionFromPanel.potionSkinSettings = copyFrom.potionSkinSettings;
}
}
public static class PotionItemStackService
{
public static void SetupPotionItemForPouringIn(PotionItem potionItem)
{
//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
//IL_00c3: Expected O, but got Unknown
//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
InventoryItem inventoryItem = ((ItemFromInventory)potionItem).inventoryItem;
Potion potion = (Potion)(object)((inventoryItem is Potion) ? inventoryItem : null);
if (PotionDataService.PotionHasSerializedData(potion) || RecipeService.GetRecipeForPotion(potion) != null)
{
StackVisualEffects obj = ((Component)potionItem).gameObject.AddComponent<StackVisualEffects>();
Stack val = ((Component)potionItem).gameObject.AddComponent<Stack>();
typeof(MovableItem).GetField("thisRigidbody", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(val, ((ItemFromInventory)potionItem).GetRigidbody());
PotionStackItem potionStackItem = ((Component)potionItem).gameObject.AddComponent<PotionStackItem>();
potionStackItem.potionItem = potionItem;
typeof(StackItem).GetField("thisRigidbody", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(potionStackItem, ((ItemFromInventory)potionItem).GetRigidbody());
((Component)potionStackItem).transform.parent = ((Component)potionItem).transform;
val.itemsFromThisStack = new List<StackItem> { (StackItem)(object)potionStackItem };
SoundController val2 = (SoundController)FormatterServices.GetUninitializedObject(typeof(SoundController));
InitPotionStackSoundController(val2, (ItemFromInventory)(object)val, (ItemFromInventoryPreset)(object)((Potion)((ItemFromInventory)potionItem).inventoryItem).soundPreset);
typeof(ItemFromInventory).GetField("_soundController", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(val, val2);
((StackItem)potionStackItem).Initialize(val);
obj.stackScript = val;
((ItemFromInventory)val).inventoryItem = ((ItemFromInventory)potionItem).inventoryItem;
((StackItem)potionStackItem).spriteRenderers = (SpriteRenderer[])(object)new SpriteRenderer[0];
((StackItem)potionStackItem).graphicStateMachine = ((Component)potionItem).gameObject.AddComponent<GraphicStateMachine>();
((StackItem)potionStackItem).graphicStateMachine.Init((StackItem)(object)potionStackItem);
}
}
private static void InitPotionStackSoundController(SoundController instance, ItemFromInventory itemFromInventory, ItemFromInventoryPreset preset)
{
//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
//IL_00d5: Expected O, but got Unknown
//IL_012c: Unknown result type (might be due to invalid IL or missing references)
//IL_0136: Expected O, but got Unknown
Ingredient val = ((SerializableDictionaryBase<InventoryItem, int, int>)(object)Managers.Player.inventory.items).Keys.ToList().OfType<Ingredient>().FirstOrDefault();
if ((Object)(object)val == (Object)null)
{
val = Ingredient.allIngredients.FirstOrDefault();
if ((Object)(object)val?.soundPreset == (Object)null)
{
Plugin.PluginLogger.LogError((object)"Failed to setup sound controller for potion because there were no ingredients in the player inventory.");
return;
}
}
SoundPresetIngredient val2 = Object.Instantiate<SoundPresetIngredient>(val.soundPreset);
((HitRubPreset)val2).hit = ((HitRubPreset)preset).hit;
typeof(SoundController).GetField("stack", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(instance, itemFromInventory);
typeof(SoundController).GetField("soundPresetIngredient", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(instance, val2);
typeof(SoundController).GetField("rubGrindLoopEmitter", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(instance, (object?)new LoopEmitter(val2.rubGrindLoop));
typeof(ItemFromInventoryController).GetField("itemFromInventory", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(instance, itemFromInventory);
typeof(ItemFromInventoryController).GetField("preset", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(instance, preset);
typeof(ItemFromInventoryController).GetField("rubLoopEmitter", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(instance, (object?)new LoopEmitter(((HitRubPreset)preset).rubLoop));
typeof(ItemFromInventoryController).GetField("newCollisions", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(instance, new List<Vector2>());
typeof(ItemFromInventoryController).GetField("collidedWith", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(instance, new Dictionary<int, GameObject>());
typeof(ItemFromInventoryController).GetField("collidedWithToRemove", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(instance, new Dictionary<int, Tuple<float, GameObject>>());
}
public static void NotifyForPreModPotion(PotionItem instance)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Invalid comparison between Unknown and I4
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Expected O, but got Unknown
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Invalid comparison between Unknown and I4
if ((int)Managers.Room.currentRoom == 1 || (int)Managers.Room.targetRoom == 1)
{
Potion val = (Potion)((ItemFromInventory)instance).inventoryItem;
if (!PotionDataService.PotionHasSerializedData(val) && RecipeService.GetRecipeForPotion(val) == null && (Object)(object)val != (Object)(object)StaticStorage.CurrentPotionCraftPanelPotion && !StaticStorage.PotionItemsNotifiedFor.Contains(val) && !(Time.unscaledTime - StaticStorage.LastNotifiedTime < 5f))
{
StaticStorage.LastNotifiedTime = Time.unscaledTime;
StaticStorage.PotionItemsNotifiedFor.Add(val);
Plugin.PluginLogger.LogInfo((object)"Grabbed potion does not have recipe data. This is likely a pre-mod potion with no corresponding recipe.");
Notification.ShowText("This potion is missing critical markings", "You wouldn't know where to start if you poured it back in the cauldron", (TextType)0);
}
}
}
}
public static class RecipeService
{
public static SerializedPotionFromPanel GetRecipeForPotion(Potion potion)
{
return ((IEnumerable<Potion>)Managers.Potion.recipeBook.savedRecipes).FirstOrDefault((Func<Potion, bool>)((Potion recipe) => RecipeMatchesPotion(potion, recipe)))?.potionFromPanel;
}
private static bool RecipeMatchesPotion(Potion potion, Potion recipe)
{
if ((Object)(object)recipe == (Object)null)
{
return false;
}
if (!((InventoryItem)recipe).GetLocalizedTitle().Equals(((InventoryItem)potion).GetLocalizedTitle()))
{
return false;
}
if (recipe.Effects.Count() != potion.Effects.Count())
{
return false;
}
if (!SequencesMatch(recipe.Effects.Select((PotionEffect e) => ((Object)e).name).ToList(), potion.Effects.Select((PotionEffect e) => ((Object)e).name).ToList()))
{
return false;
}
if (recipe.usedComponents.Count() != potion.usedComponents.Count())
{
return false;
}
var seq = recipe.usedComponents.Select((PotionUsedComponent e) => new
{
((Object)e.componentObject).name,
e.amount
}).ToList();
var seq2 = potion.usedComponents.Select((PotionUsedComponent e) => new
{
((Object)e.componentObject).name,
e.amount
}).ToList();
if (!SequencesMatch(seq, seq2))
{
return false;
}
return true;
}
private static bool SequencesMatch<T>(IList<T> seq1, IList<T> seq2)
{
if (seq1.Count != seq2.Count)
{
return false;
}
for (int i = 0; i < seq1.Count; i++)
{
if (!seq1[i].Equals(seq2[i]))
{
return false;
}
}
return true;
}
}
}
namespace PotionCraftPourBackIn.Scripts.Patches
{
[HarmonyPatch(typeof(EnterZone), "OnTriggerStay2D")]
public class AcceptPotionCollisionEnterZonePatch
{
private static bool Prefix(Collider2D other, ThrowVacuuming ___throwVacuuming)
{
return Ex.RunSafe(() => EquipmentInteractionService.DisallowMortarPotionCollisions(other, ___throwVacuuming));
}
}
[HarmonyPatch(typeof(GraphicStateMachine), "OnTriggerExit2D")]
public class DisallowMortarGraphicStateSwitchExitPatch
{
private static bool Prefix(GraphicStateMachine __instance, Collider2D other)
{
return Ex.RunSafe(() => EquipmentInteractionService.DisallowMortarGraphicStateSwitch(__instance, other));
}
}
[HarmonyPatch(typeof(GraphicStateMachine), "OnTriggerEnter2D")]
public class DisallowMortarGraphicStateSwitchPatch
{
private static bool Prefix(GraphicStateMachine __instance, Collider2D other)
{
return Ex.RunSafe(() => EquipmentInteractionService.DisallowMortarGraphicStateSwitch(__instance, other));
}
}
[HarmonyPatch(typeof(AlchemyMachineSlot), "CanBeInteractedNow")]
public class OverrideAlchemyMachineSlotCanBeInteractedPatch
{
private static void Postfix(ref bool __result)
{
OverrideAlchemyMachineSlotCanBeInteracted(ref __result);
}
private static void OverrideAlchemyMachineSlotCanBeInteracted(ref bool result)
{
if (!result)
{
return;
}
bool newResult = true;
Ex.RunSafe(delegate
{
InteractiveItem grabbedInteractiveItem = Managers.Cursor.grabbedInteractiveItem;
PotionItem val = (PotionItem)(object)((grabbedInteractiveItem is PotionItem) ? grabbedInteractiveItem : null);
if (val != null)
{
InventoryItem inventoryItem = ((ItemFromInventory)val).inventoryItem;
Potion val2 = (Potion)(object)((inventoryItem is Potion) ? inventoryItem : null);
if (val2.Effects.Length == 0 || (ComparableScriptableObject<PotionEffect>)(object)val2.Effects[0] == (ComparableScriptableObject<PotionEffect>)null)
{
newResult = false;
}
}
});
if (!newResult)
{
result = false;
}
}
}
public class OverrideCauldronCanBeInteractedPatch
{
[HarmonyPatch(typeof(Cauldron), "CanBeInteractedNow")]
public class Cauldron_CanBeInteractedNow
{
private static void Postfix(ref bool __result, Cauldron __instance)
{
OverrideCauldronCanBeInteracted(ref __result, __instance);
}
}
[HarmonyPatch(typeof(SlotSelector), "SelectNextSlotByStick")]
public class SlotSelector_SelectNextSlotByStick
{
private static bool Prefix()
{
SetIsSelectingSlotByStick(isSelectingSlotByStick: true);
return true;
}
private static void Postfix()
{
SetIsSelectingSlotByStick(isSelectingSlotByStick: false);
}
}
private static bool IsSelectingSlotByStick;
private static void OverrideCauldronCanBeInteracted(ref bool result, Cauldron instance)
{
if (result)
{
return;
}
bool newResult = false;
Ex.RunSafe(delegate
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Expected O, but got Unknown
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: Expected O, but got Unknown
//IL_008e: Unknown result type (might be due to invalid IL or missing references)
InteractiveItem grabbedInteractiveItem = Managers.Cursor.grabbedInteractiveItem;
PotionItem val = (PotionItem)(object)((grabbedInteractiveItem is PotionItem) ? grabbedInteractiveItem : null);
if (val != null && !Managers.Potion.potionCraftPanel.IsPotionBrewingStarted() && (PotionDataService.PotionHasSerializedData((Potion)((ItemFromInventory)val).inventoryItem) || RecipeService.GetRecipeForPotion((Potion)((ItemFromInventory)val).inventoryItem) != null) && (IsSelectingSlotByStick || IsPotionItemWithinCauldronBounds(instance, val)))
{
ControlsProvider controlsProvider = Managers.Input.controlsProvider;
newResult = instance.СanTakeIngredients && ((Object)(object)((ItemFromInventory)val).GetRigidbody() == (Object)null || InteractiveItem.CanBeInteractedByVelocity(((ItemFromInventory)val).GetRigidbody().velocity) || (controlsProvider is Gamepad && !Gamepad.MustFreeModeBeEnabled()));
}
});
if (newResult)
{
result = true;
}
}
private static bool IsPotionItemWithinCauldronBounds(Cauldron instance, PotionItem potionItem)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: Unknown result type (might be due to invalid IL or missing references)
//IL_008f: Unknown result type (might be due to invalid IL or missing references)
//IL_0094: Unknown result type (might be due to invalid IL or missing references)
//IL_0098: Unknown result type (might be due to invalid IL or missing references)
//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
//IL_010f: Unknown result type (might be due to invalid IL or missing references)
//IL_011b: Unknown result type (might be due to invalid IL or missing references)
Bounds bounds = instance.waterZoneCollider.bounds;
if (((Component)potionItem).transform.position.x <= ((Bounds)(ref bounds)).min.x || ((Component)potionItem).transform.position.x >= ((Bounds)(ref bounds)).max.x)
{
return false;
}
CauldronPhysicsCollider componentInChildren = ((Component)instance).GetComponentInChildren<CauldronPhysicsCollider>();
PolygonCollider2D val = ((componentInChildren != null) ? ((Component)componentInChildren).GetComponent<PolygonCollider2D>() : null);
if ((Object)(object)val != (Object)null)
{
float y = ((Component)potionItem).transform.position.y;
Bounds bounds2 = ((Collider2D)val).bounds;
float num = y - ((Bounds)(ref bounds2)).min.y;
bounds2 = ((Collider2D)val).bounds;
float num2 = num / ((Bounds)(ref bounds2)).size.y;
if (num2 < 0.5f)
{
return false;
}
if (num2 >= 0.7f)
{
num2 = 1f;
}
else if (num2 > 0.5f)
{
num2 += 0.2f;
}
float num3 = 0.7f * (1f - num2) * ((Bounds)(ref bounds)).size.x;
if (((Component)potionItem).transform.position.x <= ((Bounds)(ref bounds)).min.x + num3 || ((Component)potionItem).transform.position.x >= ((Bounds)(ref bounds)).max.x - num3)
{
return false;
}
}
return true;
}
private static void SetIsSelectingSlotByStick(bool isSelectingSlotByStick)
{
IsSelectingSlotByStick = isSelectingSlotByStick;
}
}
[HarmonyPatch(typeof(EnterZone), "OnTriggerExit2D")]
public class OverrideEnterZoneOnTriggerExit2DPatch
{
private static bool Prefix(Collider2D other, ThrowVacuuming ___throwVacuuming)
{
return Ex.RunSafe(() => EquipmentInteractionService.DisallowMortarPotionCollisions(other, ___throwVacuuming));
}
}
[HarmonyPatch(typeof(PotionItem), "VacuumItem")]
public class OverridePotionItemVaccumItemPatch
{
private static bool Prefix(PotionItem __instance, bool isPrimaryGrab, bool forceMassModifier, bool forceAltModifier)
{
return Ex.RunSafe(() => OverridePotionItemVaccumItem(__instance, isPrimaryGrab, forceMassModifier, forceAltModifier));
}
private static bool OverridePotionItemVaccumItem(PotionItem instance, bool isPrimaryGrab, bool forceMassModifier, bool forceAltModifier)
{
if (!isPrimaryGrab)
{
return true;
}
((ItemFromInventory)((Component)instance).gameObject.GetComponent<Stack>()).VacuumItem(isPrimaryGrab, forceMassModifier, forceAltModifier);
return false;
}
}
[HarmonyPatch(typeof(Stack), "OnCollisionEnter2D")]
public class OverrideStackOnCollisionEnter2DPatch
{
private static bool Prefix(Stack __instance)
{
return Ex.RunSafe(() => OverrideStackOnCollisionEnter2D(__instance));
}
private static bool OverrideStackOnCollisionEnter2D(Stack instance)
{
if (instance.itemsFromThisStack.FirstOrDefault() is PotionStackItem)
{
return false;
}
return true;
}
}
[HarmonyPatch(typeof(PotionItem), "CanBeInteractedNow")]
public class PreventPotionInteractionWhileVacuumPatch
{
private static void Postfix(ref bool __result, PotionItem __instance)
{
PreventPotionInteractionWhileVacuum(ref __result, __instance);
}
private static void PreventPotionInteractionWhileVacuum(ref bool result, PotionItem instance)
{
if (!result)
{
return;
}
bool newResult = true;
Ex.RunSafe(delegate
{
Stack component = ((Component)instance).GetComponent<Stack>();
if (!((Object)(object)component == (Object)null))
{
newResult = (Object)(object)component.vacuumingTo == (Object)null && ((Component)instance).GetComponent<SortingGroup>().sortingLayerID != 16;
}
});
if (!newResult)
{
result = false;
}
}
}
[HarmonyPatch(typeof(WaterZone), "OnTriggerStay2D")]
public class RejectPotionCollisionWhenBrewingPatch
{
private static bool Prefix(Collider2D other)
{
return Ex.RunSafe(() => RejectPotionCollisionWhenBrewing(other));
}
private static bool RejectPotionCollisionWhenBrewing(Collider2D other)
{
if ((Object)(object)((Component)other).GetComponentInParent<PotionItem>() == (Object)null)
{
return true;
}
if (Managers.Potion.potionCraftPanel.IsPotionBrewingStarted())
{
return false;
}
return true;
}
}
[HarmonyPatch(typeof(GraphicStateMachine), "SetCurrentGraphicState")]
public class RemovePotionHighlightWhenEnteringCauldronPatch
{
private static void Postfix(GraphicStateMachine __instance)
{
Ex.RunSafe(delegate
{
RemovePotionHighlightWhenEnteringCauldron(__instance);
});
}
private static void RemovePotionHighlightWhenEnteringCauldron(GraphicStateMachine instance)
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
StackItem stackItem = instance.stackItem;
string sortingLayerName = ((InteractiveItem)stackItem).sortingGroup.sortingLayerName;
SpriteSortingLayers val = (SpriteSortingLayers)16;
if (sortingLayerName == ((object)(SpriteSortingLayers)(ref val)).ToString())
{
IHoverable iHoverableScript = ((InteractiveItem)stackItem.stackScript).iHoverableScript;
PotionItem val2 = (PotionItem)(object)((iHoverableScript is PotionItem) ? iHoverableScript : null);
if ((Object)(object)val2 != (Object)null)
{
val2.SetHovered(false);
}
}
}
}
public class SetupSlotCauldronSlotConditionToAllowPotion
{
[HarmonyPatch(typeof(Slot), "SetupConditions")]
public class Slot_SetupConditions
{
private static bool Prefix(Slot __instance)
{
return Ex.RunSafe(() => EquipmentInteractionService.SetupSlotCauldronSlotConditionToAllowPotion(__instance));
}
}
}
[HarmonyPatch(typeof(ExperienceSubManager))]
public class AddModifiedExperienceForPouredBackInPotionsPatch
{
private static MethodInfo TargetMethod()
{
return typeof(ExperienceSubManager).GetMethod("AddExperience", new Type[2]
{
typeof(Potion),
typeof(int)
});
}
private static bool Prefix(Potion potion, int count)
{
return Ex.RunSafe(() => AddModifiedExperienceForPouredBackInPotions(potion, count));
}
private static bool AddModifiedExperienceForPouredBackInPotions(Potion potion, int count)
{
if (StaticStorage.PouredInUsedComponents == null)
{
return true;
}
PlayerManagerSettings asset = Settings<PlayerManagerSettings>.Asset;
float ingredientsExperience = 0f;
(potion.usedComponents.Any() ? potion.usedComponents : Managers.Potion.usedComponents).Skip(StaticStorage.PouredInUsedComponents.Count).ToList().ForEach(delegate(PotionUsedComponent component)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
if ((int)component.componentType == 0)
{
ingredientsExperience += ((InventoryItem)component.componentObject).GetPrice() * (float)component.amount;
}
});
ingredientsExperience *= asset.experiencePotionIngredientsMultiplier;
new List<PotionEffect>();
int num = 0;
for (int i = 0; i < (StaticStorage.PouredInEffects?.Count ?? 0); i++)
{
if ((ComparableScriptableObject<PotionEffect>)(object)potion.Effects[num] == (ComparableScriptableObject<PotionEffect>)(object)StaticStorage.PouredInEffects[i])
{
num++;
}
else if (num > 0)
{
break;
}
}
List<PotionEffect> list = potion.Effects.Skip(num).ToList();
float num2 = (list.Any() ? ((float)potion.GetPotionReview(list.ToArray()).cost * asset.experiencePotionEffectsMultiplier) : 0f);
Managers.Player.AddExperience((ingredientsExperience + num2) * (float)count);
StaticStorage.PouredInUsedComponents = null;
StaticStorage.PouredInEffects = null;
return false;
}
}
[HarmonyPatch(typeof(PotionManager), "GeneratePotionFromCurrentPotion")]
public class CopyImportantInfoToPotionInstancePotionManagerPatch
{
[HarmonyAfter(new string[] { "com.fahlgorithm.potioncraftalchemymachinerecipies" })]
private static void Postfix(Potion __result)
{
Ex.RunSafe(delegate
{
CopyImportantInfoToPotionInstance(__result);
});
}
private static void CopyImportantInfoToPotionInstance(Potion copyTo)
{
if (!StaticStorage.CurrentlyMakingPotion || StaticStorage.CurrentlyGeneratingRecipe)
{
return;
}
SerializedPotionFromPanel potionFromCurrentPotion = SerializedPotionFromPanel.GetPotionFromCurrentPotion();
Potion currentPotion = Managers.Potion.potionCraftPanel.GetCurrentPotion();
PotionItem val = null;
if ((Object)(object)currentPotion == (Object)null)
{
InteractiveItem grabbedInteractiveItem = Managers.Cursor.grabbedInteractiveItem;
PotionItem val2 = (PotionItem)(object)((grabbedInteractiveItem is PotionItem) ? grabbedInteractiveItem : null);
if (val2 != null)
{
((ItemFromInventory)val2).inventoryItem = (InventoryItem)(object)copyTo;
val = val2;
}
}
PotionDataService.CopyImportantInfoToPotionInstance(copyTo, currentPotion, potionFromCurrentPotion);
if ((Object)(object)val != (Object)null)
{
PotionItemStackService.SetupPotionItemForPouringIn(val);
((ItemFromInventory)val).OnGrabPrimary();
}
}
}
[HarmonyPatch(typeof(Potion), "Clone")]
public class CopyImportantInfoToPotionInstancePotionPatch
{
private static void Postfix(Potion __result, Potion __instance)
{
Ex.RunSafe(delegate
{
CopyImportantInfoToPotionInstance(__result, __instance);
});
}
private static void CopyImportantInfoToPotionInstance(Potion copyTo, Potion copyFrom)
{
PotionDataService.CopyImportantInfoToPotionInstance(copyTo, copyFrom, copyFrom.potionFromPanel);
}
}
[HarmonyPatch(typeof(StackVisualEffects))]
public class HidePotionStackExplosionEffectsPatch
{
private static MethodInfo TargetMethod()
{
return typeof(StackVisualEffects).GetMethod("SpawnEffectsExplosion", new Type[3]
{
typeof(IngredientVisualEffect),
typeof(Vector3),
typeof(SpriteSortingLayers)
});
}
private static bool Prefix(StackVisualEffects __instance)
{
return Ex.RunSafe(() => !PotionDataService.IsPotionStackItemEffect(__instance));
}
}
[HarmonyPatch(typeof(StackVisualEffects), "SpawnEffectsUpdate")]
public class HidePotionStackVisualEffectsPatch
{
private static bool Prefix(StackVisualEffects __instance)
{
return Ex.RunSafe(() => !PotionDataService.IsPotionStackItemEffect(__instance));
}
}
[HarmonyPatch(typeof(PotionCraftPanel), "UpdatePotionInCraftPanel")]
public class KeepTrackOfCurrentPotionCraftPanelPotionPatch
{
private static void Postfix()
{
Ex.RunSafe(delegate
{
KeepTrackOfCurrentPotionCraftPanelPotion();
});
}
private static void KeepTrackOfCurrentPotionCraftPanelPotion()
{
StaticStorage.CurrentPotionCraftPanelPotion = Managers.Potion.potionCraftPanel.GetCurrentPotion();
}
}
[HarmonyPatch(typeof(Potion))]
public class LoadPotionSerializedDataPatch
{
private static MethodInfo TargetMethod()
{
return typeof(Potion).GetMethod("GetFromSerializedObject", new Type[1] { typeof(SerializedInventorySlot) });
}
private static void Postfix(Potion __result, SerializedInventorySlot serializedObject)
{
Ex.RunSafe(delegate
{
LoadPotionSerializedData(__result, serializedObject);
});
}
private static void LoadPotionSerializedData(Potion result, SerializedInventorySlot serializedRecipe)
{
int num = serializedRecipe.data.IndexOf("potionFromPanel");
if (num == -1)
{
return;
}
int num2 = serializedRecipe.data.IndexOf('{', num);
if (num2 == -1)
{
Plugin.PluginLogger.LogInfo((object)"Error: potionFromPanel data in serialized potion is malformed.");
return;
}
int endJsonIndex = GetEndJsonIndex(serializedRecipe.data, num2, useBrackets: false);
if (endJsonIndex >= serializedRecipe.data.Length)
{
Plugin.PluginLogger.LogInfo((object)"Error: potionFromPanel data in serialized potion is malformed (bad end index).");
return;
}
string text = serializedRecipe.data.Substring(num2, endJsonIndex - num2);
if (text.Length <= 2)
{
Plugin.PluginLogger.LogInfo((object)"Error: potionFromPanel data in serialized potion is malformed (empty object).");
}
else
{
result.potionFromPanel = JsonUtility.FromJson<SerializedPotionFromPanel>(text);
}
}
private static int GetEndJsonIndex(string input, int startIndex, bool useBrackets)
{
int num = startIndex + 1;
int num2 = 1;
char value = (useBrackets ? '[' : '{');
char value2 = (useBrackets ? ']' : '}');
while (num2 > 0 && num < input.Length - 1)
{
int num3 = input.IndexOf(value, num);
int num4 = input.IndexOf(value2, num);
if (num3 == -1 && num4 == -1)
{
break;
}
if (num3 == -1)
{
num3 = int.MaxValue;
}
if (num4 == -1)
{
num4 = int.MaxValue;
}
if (num3 < num4)
{
num = num3 + 1;
num2++;
}
else if (num4 < num3)
{
num = num4 + 1;
num2--;
}
}
return num;
}
}
[HarmonyPatch(typeof(Stack), "AddIngredientPathToMapPath")]
public class OverrideAddIngredientPathToMapPathPatch
{
private static bool Prefix(Stack __instance)
{
return Ex.RunSafe(() => OverrideAddIngredientPathToMapPath(__instance), () => OnError(__instance));
}
private static bool OnError(Stack stack)
{
try
{
if (stack.itemsFromThisStack.FirstOrDefault() is PotionStackItem)
{
return false;
}
}
catch (Exception ex)
{
Ex.LogException(ex);
}
return true;
}
private static bool OverrideAddIngredientPathToMapPath(Stack instance)
{
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Expected O, but got Unknown
PotionStackItem potionStackItem = (instance.itemsFromThisStack.FirstOrDefault() as PotionStackItem) ?? (instance.vacuumedItemsFromThisStack.FirstOrDefault() as PotionStackItem);
if ((Object)(object)potionStackItem == (Object)null)
{
return true;
}
ContinueBrewingFromPotion((Potion)((ItemFromInventory)potionStackItem.potionItem).inventoryItem);
return false;
}
private static void ContinueBrewingFromPotion(Potion potion)
{
SerializedPotionFromPanel recipeForPotion = RecipeService.GetRecipeForPotion(potion);
SerializedPotionFromPanel val = ((!PotionDataService.PotionHasSerializedData(potion)) ? recipeForPotion : potion.potionFromPanel);
if (val == null)
{
Plugin.PluginLogger.LogInfo((object)"ERROR: Failed to find recipe for poured-in, pre-mod potion!");
return;
}
PotionBase val2 = ((val.potionUsedComponents.Count == 0) ? Managers.RecipeMap.currentMap.potionBase : PotionBase.GetByName(val.potionUsedComponents[0].componentName, false, true));
val.ApplyPotionToCurrentPotion(val2);
StaticStorage.PouredInUsedComponents = potion.usedComponents.ToList();
StaticStorage.PouredInEffects = potion.Effects.ToList();
if (recipeForPotion != null)
{
Managers.Potion.potionCraftPanel.potionChangedAfterSavingRecipe = false;
((Button)Managers.Potion.potionCraftPanel.saveRecipeButton).Locked = true;
}
PotionEffect[] collectedPotionEffects = Managers.Potion.collectedPotionEffects;
foreach (PotionEffect val3 in collectedPotionEffects)
{
if ((ComparableScriptableObject<PotionEffect>)(object)val3 == (ComparableScriptableObject<PotionEffect>)null)
{
continue;
}
foreach (PotionEffectMapItem item in Managers.RecipeMap.currentMap.potionEffectsOnMap)
{
if ((ComparableScriptableObject<PotionEffect>)(object)item.Effect == (ComparableScriptableObject<PotionEffect>)(object)val3)
{
item.Status = (PotionEffectStatus)3;
break;
}
}
}
}
}
[HarmonyPatch(typeof(Potion), "GetSerializedInventorySlot")]
public class SavePotionSerializedDataPatch
{
private static void Postfix(SerializedInventorySlot __result, Potion __instance)
{
Ex.RunSafe(delegate
{
SavePotionSerializedData(__result, __instance);
});
}
private static void SavePotionSerializedData(SerializedInventorySlot result, Potion instance)
{
if (!result.data.Contains("potionFromPanel"))
{
string value = ",\"potionFromPanel\":" + JsonUtility.ToJson((object)instance.potionFromPanel);
int startIndex = result.data.LastIndexOf('}');
result.data = result.data.Insert(startIndex, value);
}
}
}
[HarmonyPatch(typeof(SaveRecipeButton), "GenerateRecipe")]
public class SetCurrentlyGeneratingRecipePatch
{
private static bool Prefix()
{
return Ex.RunSafe(() => SetCurrentlyGeneratingRecipe(currentlyGeneratingRecipe: true));
}
private static void Postfix()
{
Ex.RunSafe(() => SetCurrentlyGeneratingRecipe(currentlyGeneratingRecipe: false));
}
private static bool SetCurrentlyGeneratingRecipe(bool currentlyGeneratingRecipe)
{
StaticStorage.CurrentlyGeneratingRecipe = currentlyGeneratingRecipe;
return true;
}
}
[HarmonyPatch(typeof(PotionCraftPanel), "MakePotion")]
public class SetCurrentlyMakingPotionPatch
{
private static bool Prefix()
{
return Ex.RunSafe(() => SetCurrentlyMakingPotion(currentlyMakingPotion: true));
}
private static void Postfix()
{
Ex.RunSafe(() => SetCurrentlyMakingPotion(currentlyMakingPotion: false));
}
private static bool SetCurrentlyMakingPotion(bool currentlyMakingPotion)
{
StaticStorage.CurrentlyMakingPotion = currentlyMakingPotion;
return true;
}
}
[HarmonyPatch(typeof(PotionItem), "OnGrabPrimary")]
public class ForwardGrabPrimaryPatch
{
private static void Postfix(PotionItem __instance)
{
Ex.RunSafe(delegate
{
ForwardGrabPrimary(__instance);
});
}
private static void ForwardGrabPrimary(PotionItem instance)
{
Stack component = ((Component)instance).GetComponent<Stack>();
if ((Object)(object)component == (Object)null)
{
PotionItemStackService.NotifyForPreModPotion(instance);
return;
}
((ItemFromInventory)component).OnGrabPrimary();
MethodInfo method = typeof(ConditionValue).GetMethod("SetConditionValue", BindingFlags.Static | BindingFlags.NonPublic, null, new Type[2]
{
typeof(Condition),
typeof(bool)
}, new ParameterModifier[0]);
if (!(method == null))
{
method.Invoke(null, new object[2]
{
(object)(Condition)30,
true
});
}
}
}
[HarmonyPatch(typeof(ItemFromInventory), "CustomOnReleasePrimaryCondition")]
public class ForwardPotionItemOnReleasePrimaryPatch
{
private static void Postfix(ItemFromInventory __instance)
{
Ex.RunSafe(delegate
{
ForwardPotionItemOnReleasePrimary(__instance);
});
}
private static void ForwardPotionItemOnReleasePrimary(ItemFromInventory instance)
{
if (instance is PotionItem)
{
Stack component = ((Component)instance).gameObject.GetComponent<Stack>();
if (!((Object)(object)component == (Object)null) && !(Managers.Cursor.hoveredInteractiveItem is ScalesCupDisplay) && !(Managers.Cursor.hoveredInteractiveItem is AlchemyMachineSlot))
{
typeof(Stack).GetMethod("CustomOnReleasePrimaryCondition", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(component, null);
}
}
}
}
[HarmonyPatch(typeof(ItemFromInventory), "OnReleasePrimary")]
public class ForwardReleasePrimaryPatch
{
private static void Postfix(ItemFromInventory __instance)
{
Ex.RunSafe(delegate
{
ForwardReleasePrimary(__instance);
});
}
private static void ForwardReleasePrimary(ItemFromInventory instance)
{
if ((Object)(object)instance == (Object)null || instance.markedAsDestroyed)
{
return;
}
PotionItem val = (PotionItem)(object)((instance is PotionItem) ? instance : null);
if (val != null)
{
Stack component = ((Component)val).GetComponent<Stack>();
if (!((Object)(object)component == (Object)null) && !(Managers.Cursor.hoveredInteractiveItem is ScalesCupDisplay) && !(Managers.Cursor.hoveredInteractiveItem is AlchemyMachineSlot))
{
((ItemFromInventory)component).OnReleasePrimary();
}
}
}
}
[HarmonyPatch(typeof(RoomManager), "GoTo")]
public class NotifyForPreModPotionOnRoomChangePatch
{
private static void Postfix()
{
Ex.RunSafe(delegate
{
NotifyForPreModPotionOnRoomChange();
});
}
private static void NotifyForPreModPotionOnRoomChange()
{
InteractiveItem grabbedInteractiveItem = Managers.Cursor.grabbedInteractiveItem;
PotionItem val = (PotionItem)(object)((grabbedInteractiveItem is PotionItem) ? grabbedInteractiveItem : null);
if (val != null)
{
PotionItemStackService.NotifyForPreModPotion(val);
}
}
}
[HarmonyPatch(/*Could not decode attribute arguments.*/)]
public class OverridePotionStackItemSoundControllerPatch
{
private static bool Prefix(SoundController __instance, StackItem stackItem)
{
return Ex.RunSafe(() => OverridePotionStackItemSoundController(__instance, stackItem), () => OnError(stackItem));
}
private static bool OnError(StackItem stackItem)
{
try
{
if (stackItem is PotionStackItem)
{
return false;
}
}
catch (Exception ex)
{
Ex.LogException(ex);
}
return true;
}
private static bool OverridePotionStackItemSoundController(SoundController instance, StackItem stackItem)
{
//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
//IL_012a: Unknown result type (might be due to invalid IL or missing references)
//IL_0134: Expected O, but got Unknown
if (!(stackItem is PotionStackItem))
{
return true;
}
PotionItem potionItem = ((PotionStackItem)(object)stackItem).potionItem;
typeof(SoundController).GetField("stackItem", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(instance, stackItem);
typeof(SoundController).GetField("newCollisions", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(instance, new List<Vector2>());
typeof(SoundController).GetField("collidedWith", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(instance, new List<GameObject>());
Ingredient val = ((SerializableDictionaryBase<InventoryItem, int, int>)(object)Managers.Player.inventory.items).Keys.ToList().OfType<Ingredient>().FirstOrDefault();
if ((Object)(object)val == (Object)null)
{
val = Ingredient.allIngredients.FirstOrDefault();
if ((Object)(object)val == (Object)null)
{
Plugin.PluginLogger.LogError((object)"Failed to setup sound controller for potion because there were no ingredients in the player inventory.");
return false;
}
}
SoundPresetIngredient val2 = Object.Instantiate<SoundPresetIngredient>(val.soundPreset);
SoundPresetPotion soundPreset = ((Potion)((ItemFromInventory)potionItem).inventoryItem).soundPreset;
((HitRubPreset)val2).hit = ((HitRubPreset)soundPreset).hit;
typeof(SoundController).GetField("preset", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(instance, val2);
typeof(SoundController).GetField("rubLoopEmitter", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(instance, (object?)new LoopEmitter(((HitRubPreset)val2).rubLoop));
return false;
}
}
[HarmonyPatch(typeof(SoundController), "OnGrind")]
public class OverrideSoundControllerOnGrindPatch
{
private static bool Prefix(SoundController __instance)
{
return Ex.RunSafe(() => OverrideSoundControllerOnGrind(__instance));
}
private static bool OverrideSoundControllerOnGrind(SoundController instance)
{
return !(typeof(SoundController).GetField("stackItem", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(instance) is PotionStackItem);
}
}
public class PreventCrashOnStackItemDestroy
{
[HarmonyPatch(typeof(StackItem), "RemoveItemFromStackAndReset")]
public class StackItem_RemoveItemFromStackAndReset
{
private static bool Prefix(StackItem __instance)
{
return Ex.RunSafe(() => DoPreventCrashOnStackItemDestroy(__instance));
}
}
private static bool DoPreventCrashOnStackItemDestroy(StackItem instance)
{
if (!(instance is PotionStackItem))
{
return true;
}
Stack stackScript = instance.stackScript;
if (stackScript != null)
{
stackScript.RemoveItemFromStack(instance);
}
instance.soundController.ResetController();
return false;
}
}
[HarmonyPatch(typeof(Stack), "DisassembleStack")]
public class PreventPotionStackDissassemblyPatch
{
private static bool Prefix(Stack __instance)
{
return Ex.RunSafe(() => PreventPotionStackDissassembly(__instance));
}
private static bool PreventPotionStackDissassembly(Stack instance)
{
return (Object)(object)((Component)instance).GetComponent<PotionItem>() == (Object)null;
}
}
[HarmonyPatch(typeof(StackItem), "OnDestroy")]
public class PreventStackItemOnDestroyExceptionPatch
{
private static bool Prefix(StackItem __instance)
{
return Ex.RunSafe(() => PreventStackItemOnDestroyException(__instance));
}
private static bool PreventStackItemOnDestroyException(StackItem instance)
{
if (!(instance is PotionStackItem))
{
return true;
}
Stack stackScript = instance.stackScript;
if (stackScript != null)
{
stackScript.RemoveItemFromStack(instance);
}
SoundController soundController = instance.soundController;
if (soundController != null)
{
soundController.ResetController();
}
return false;
}
}
[HarmonyPatch(typeof(PotionItem), "SpawnNewPotion")]
public class SetupPotionItemForPouringInPatch
{
private static void Postfix(PotionItem __result)
{
Ex.RunSafe(delegate
{
PotionItemStackService.SetupPotionItemForPouringIn(__result);
});
}
}
[HarmonyPatch(typeof(RecipeBook), "OnLoad")]
public class SetupPotionItemsForPouringInOnRecipeLoadPatch
{
private static void Postfix()
{
Ex.RunSafe(delegate
{
SetupPotionItemsForPouringInOnRecipeLoad();
});
}
private static void SetupPotionItemsForPouringInOnRecipeLoad()
{
(from p in ((Component)Managers.Game.ItemContainer).GetComponentsInChildren<PotionItem>()
where (Object)(object)((Component)p).GetComponent<Stack>() == (Object)null
select p).ToList().ForEach(PotionItemStackService.SetupPotionItemForPouringIn);
}
}
public static class UnfinishedPotionPatcher
{
[HarmonyPatch(typeof(PotionCraftPanel), "UpdatePotionInCraftPanel")]
public class EnableFinishPotionButtonForUnfinishedPotionsPatch
{
private static void Postfix(PotionCraftPanel __instance)
{
Ex.RunSafe(delegate
{
EnableFinishPotionButtonForUnfinishedPotions(__instance);
});
}
private static void EnableFinishPotionButtonForUnfinishedPotions(PotionCraftPanel instance)
{
if (instance.IsPotionBrewingStarted())
{
((Button)((ItemsPanel)instance.limitedInventoryPanel).buttons.First()).Locked = false;
((Button)instance.potionFinishingButton).Locked = false;
}
}
}
[HarmonyPatch(typeof(PotionInventoryObject), "CanBeInteractedNow")]
public class EnableGrabUnfinishedPotionToFinishPatch
{
private static bool Prefix(InventoryItem ___inventoryItem)
{
return Ex.RunSafe(() => EnableGrabUnfinishedPotionToFinishPrefix(___inventoryItem));
}
private static void Postfix(InventoryItem ___inventoryItem)
{
Ex.RunSafe(delegate
{
EnableGrabUnfinishedPotionToFinishPostfix(___inventoryItem);
});
}
}
[HarmonyPatch(typeof(RecipeBookPotionInventoryObject), "CanBeInteractedNow")]
public class RecipeBookPotionInventoryObject_CanBeInteractedNow
{
private static bool Prefix(InventoryItem ___inventoryItem)
{
return Ex.RunSafe(() => EnableGrabUnfinishedPotionToFinishPrefix(___inventoryItem, requireBrewStart: false));
}
private static void Postfix(InventoryItem ___inventoryItem)
{
Ex.RunSafe(delegate
{
EnableGrabUnfinishedPotionToFinishPostfix(___inventoryItem, requireBrewStart: false);
});
}
}
private static bool EnableGrabUnfinishedPotionToFinishPrefix(InventoryItem inventoryItem, bool requireBrewStart = true)
{
Potion val = (Potion)(object)((inventoryItem is Potion) ? inventoryItem : null);
if (val == null)
{
return true;
}
if (requireBrewStart && !Managers.Potion.potionCraftPanel.IsPotionBrewingStarted())
{
return true;
}
if (val.Effects.Any())
{
return true;
}
val.Effects = (PotionEffect[])(object)new PotionEffect[1] { PotionEffect.allPotionEffects.First() };
StaticStorage.DummyEffectAddedToEnableFinishPotionGrab = true;
return true;
}
private static void EnableGrabUnfinishedPotionToFinishPostfix(InventoryItem inventoryItem, bool requireBrewStart = true)
{
Potion val = (Potion)(object)((inventoryItem is Potion) ? inventoryItem : null);
if (val != null && (!requireBrewStart || Managers.Potion.potionCraftPanel.IsPotionBrewingStarted()) && StaticStorage.DummyEffectAddedToEnableFinishPotionGrab)
{
val.Effects = (PotionEffect[])(object)new PotionEffect[0];
StaticStorage.DummyEffectAddedToEnableFinishPotionGrab = false;
}
}
}
}
namespace PotionCraftPourBackIn.Scripts.Patches.UnfinishedPotion
{
public class AllowBrewingNoEffectPotionsFromRecipeBookPatch
{
[HarmonyPatch(typeof(RecipeBookPotionPlaceholderForTooltip), "GetTooltipContent")]
public class RecipeBookPotionPlaceholderForTooltip_GetTooltipContent
{
private static void Postfix(ref TooltipContent __result, RecipeBookLeftPageContent ___leftPageContent)
{
OverrideRecipeBookPotionIconTooltip(ref __result, ___leftPageContent);
}
}
[HarmonyPatch(typeof(RecipeBookPotionInventoryObject), "UpdateVisual")]
public class RecipeBookPotionInventoryObject_UpdateVisual
{
private static void Postfix(RecipeBookPotionInventoryObject __instance)
{
Ex.RunSafe(delegate
{
AllowBrewingNoEffectPotionsFromRecipeBook(__instance);
});
}
}
private static void OverrideRecipeBookPotionIconTooltip(ref TooltipContent result, RecipeBookLeftPageContent leftPageContent)
{
if (result == null)
{
return;
}
TooltipContent newResult = result;
string header = result.header;
Ex.RunSafe(delegate
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Expected O, but got Unknown
string text = new Key("#recipebook_brew_potion_no_effects", (List<string>)null, false).GetText();
if (!(header != text))
{
if (RecipeBook.GetAvailableResultPotionsCount(((PageContent)leftPageContent).currentState, leftPageContent.pageContentPotion) != 0)
{
newResult = null;
}
else
{
string text2 = new Key("#recipebook_brew_potion_not_enough_ingredients", (List<string>)null, false).GetText();
newResult = new TooltipContent
{
header = text2
};
}
}
});
result = newResult;
}
private static void AllowBrewingNoEffectPotionsFromRecipeBook(RecipeBookPotionInventoryObject instance)
{
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
if (((Button)instance).Locked)
{
ItemsPanel itemsPanel = ((InventoryObject)instance).itemsPanel;
ItemsPanel obj = ((itemsPanel is RecipeBookPanelInventoryPanel) ? itemsPanel : null);
State currentState = ((PageContent)((RecipeBookPanelInventoryPanel)obj).leftPageContent).currentState;
Potion pageContentPotion = ((RecipeBookPanelInventoryPanel)obj).leftPageContent.pageContentPotion;
if ((int)currentState != 0 && (pageContentPotion.Effects.Length == 0 || (ComparableScriptableObject<PotionEffect>)(object)pageContentPotion.Effects[0] == (ComparableScriptableObject<PotionEffect>)null) && RecipeBook.GetAvailableResultPotionsCount(currentState, pageContentPotion) != 0)
{
((Button)instance).Locked = false;
}
}
}
}
}