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 Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PotionCraft;
using PotionCraft.Assemblies.GamepadNavigation;
using PotionCraft.Assemblies.GamepadNavigation.Conditions;
using PotionCraft.Core;
using PotionCraft.Core.SerializableDictionary;
using PotionCraft.InventorySystem;
using PotionCraft.LocalizationSystem;
using PotionCraft.ManagersSystem;
using PotionCraft.ManagersSystem.Input.ControlProviders;
using PotionCraft.ManagersSystem.Player;
using PotionCraft.ManagersSystem.Potion;
using PotionCraft.ManagersSystem.Potion.Entities;
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.PathMapItem;
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.ScriptableObjects;
using PotionCraft.ScriptableObjects.Ingredient;
using PotionCraft.ScriptableObjects.Potion;
using PotionCraft.Settings;
using PotionCraft.SoundSystem;
using PotionCraft.SoundSystem.SoundPresets;
using PotionCraftPourBackIn.Scripts.Extensions;
using PotionCraftPourBackIn.Scripts.Services;
using PotionCraftPourBackIn.Scripts.Storage;
using PotionCraftPourBackIn.Scripts.UIElements;
using TMPro;
using TooltipSystem;
using UnityEngine;
using UnityEngine.Audio;
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+1eb1fc372d31ff82812bc2e8ea2afdb2dba5f778")]
[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", "2.0.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<AlchemySubstanceComponent> 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_0006: 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_0017: Unknown result type (might be due to invalid IL or missing references)
SerializedPath serializedPath = ((SerializedPotionRecipeData)potion.GetSerializedRecipeData()).serializedPath;
if (!(serializedPath.indicatorTargetPosition != Vector2.zero))
{
return (serializedPath?.fixedPathPoints?.Any()).GetValueOrDefault();
}
return true;
}
public static bool IsPotionStackItemEffect(StackVisualEffects instance)
{
if ((Object)(object)instance?.stackScript == (Object)null)
{
return false;
}
return Traverse.Create((object)instance.stackScript).Property<InventoryItem>("InventoryItem", (object[])null).Value is Potion;
}
public static void CopyImportantInfoToPotionInstance(IRecipeBookPageContent copyToPg, Potion copyFromPotion, SerializedPotionRecipeData copyFrom)
{
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Expected O, but got Unknown
Potion copyTo = (Potion)(object)((copyToPg is Potion) ? copyToPg : null);
if (copyTo == null)
{
return;
}
SerializedPotionRecipeData val = (SerializedPotionRecipeData)copyTo.GetSerializedRecipeData();
List<SerializedRecipeMark> recipeMarks = val.recipeMarks;
recipeMarks.Clear();
copyFrom.recipeMarks.ForEach(delegate(SerializedRecipeMark m)
{
recipeMarks.Add(m.Clone());
});
val.collectedPotionEffects.Clear();
PotionEffect[] array = ((copyFromPotion != null) ? copyFromPotion.Effects : null) ?? Managers.Potion.collectedPotionEffects;
foreach (PotionEffect val2 in array)
{
if ((ComparableScriptableObject<PotionEffect>)(object)val2 == (ComparableScriptableObject<PotionEffect>)null)
{
break;
}
val.collectedPotionEffects.Add(((Object)val2).name);
}
val.serializedPath = copyFrom.serializedPath;
SimpleAlchemySubstanceComponents usedComponents = copyTo.usedComponents;
bool? obj;
if (usedComponents == null)
{
obj = null;
}
else
{
List<AlchemySubstanceComponent> summaryComponents = usedComponents.GetSummaryComponents();
obj = ((summaryComponents != null) ? new bool?(!summaryComponents.Any()) : null);
}
bool? flag = obj;
if (flag.GetValueOrDefault())
{
copyTo.usedComponents.Clear();
(from component in Managers.Potion.PotionUsedComponents.GetSummaryComponents()
select component.Clone()).ToList().ForEach(delegate(AlchemySubstanceComponent c)
{
copyTo.usedComponents.Add(c, -1);
});
}
if (!copyFrom.usedComponents.components.Any())
{
copyTo.usedComponents.GetSummaryComponents().ForEach(delegate(AlchemySubstanceComponent component)
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Expected O, but got Unknown
List<SerializedAlchemySubstanceComponent> components = copyFrom.usedComponents.components;
SerializedAlchemySubstanceComponent val3 = new SerializedAlchemySubstanceComponent
{
name = ((Object)component.Component).name,
amount = component.Amount
};
AlchemySubstanceComponentType type = component.Type;
val3.type = ((object)(AlchemySubstanceComponentType)(ref type)).ToString();
components.Add(val3);
});
}
val.usedComponents = copyFrom.usedComponents;
val.skinSettings = copyFrom.skinSettings;
}
}
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)(object)potionItem).GetInventoryItem();
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)(object)potionItem).GetInventoryItem()).soundPreset);
typeof(ItemFromInventory).GetField("_soundController", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(val, val2);
((StackItem)potionStackItem).Initialize(val);
obj.stackScript = val;
((ItemFromInventory)(object)val).SetInventoryItem(((ItemFromInventory)(object)potionItem).GetInventoryItem());
((StackItem)potionStackItem).spriteRenderers = (SpriteRenderer[])(object)new SpriteRenderer[1] { potionItem.visualObject.bottleLiquidMainSpriteRenderer };
((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_00cd: Unknown result type (might be due to invalid IL or missing references)
//IL_00d7: Expected O, but got Unknown
//IL_0130: Unknown result type (might be due to invalid IL or missing references)
//IL_013a: 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, (AudioMixerGroup)null, (Transform)null));
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, (AudioMixerGroup)null, (Transform)null));
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_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Expected O, but got Unknown
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Invalid comparison between Unknown and I4
if ((int)Managers.Room.CurrentRoomIndex == 1 || (int)Traverse.Create((object)Managers.Room).Field<RoomIndex>("targetRoom").Value == 1)
{
Potion val = (Potion)((ItemFromInventory)(object)instance).GetInventoryItem();
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 SerializedPotionRecipeData GetRecipeForPotion(Potion potion)
{
IRecipeBookPageContent? obj = ((IEnumerable<IRecipeBookPageContent>)RecipeBook.Instance.savedRecipes).FirstOrDefault((Func<IRecipeBookPageContent, bool>)((IRecipeBookPageContent recipe) => RecipeMatchesPotion(potion, (Potion)(object)((recipe is Potion) ? recipe : null))));
ISerializedRecipeData obj2 = ((obj != null) ? obj.GetSerializedRecipeData() : null);
return (SerializedPotionRecipeData)(object)((obj2 is SerializedPotionRecipeData) ? obj2 : null);
}
private static bool RecipeMatchesPotion(Potion potion, Potion recipe)
{
if ((Object)(object)recipe == (Object)null)
{
return false;
}
if (!((InventoryItem)recipe).GetLocalizedTitleText().Equals(((InventoryItem)potion).GetLocalizedTitleText()))
{
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.GetSummaryComponentsCount() != potion.usedComponents.GetSummaryComponentsCount())
{
return false;
}
var seq = (from e in recipe.usedComponents.GetSummaryComponents()
select new
{
((Object)e.Component).name,
e.Amount
}).ToList();
var seq2 = (from e in potion.usedComponents.GetSummaryComponents()
select new
{
((Object)e.Component).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(AlchemyMachineSlotObject), "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 value = Traverse.Create((object)val).Property<InventoryItem>("InventoryItem", (object[])null).Value;
Potion val2 = (Potion)(object)((value is Potion) ? value : 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_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Expected O, but got Unknown
//IL_0096: 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())
{
Potion potion = (Potion)Traverse.Create((object)val).Property<InventoryItem>("InventoryItem", (object[])null).Value;
if ((PotionDataService.PotionHasSerializedData(potion) || RecipeService.GetRecipeForPotion(potion) != 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(Potion).GetMethod("AddBrewingExperience", new Type[2]
{
typeof(int),
typeof(bool)
});
}
private static bool Prefix(Potion __instance, int count, bool isBrewingFromRecipeBook)
{
return Ex.RunSafe(() => AddModifiedExperienceForPouredBackInPotions(__instance, count, isBrewingFromRecipeBook));
}
private static bool AddModifiedExperienceForPouredBackInPotions(Potion potion, int count, bool isBrewingFromRecipeBook)
{
if (isBrewingFromRecipeBook)
{
return true;
}
if (StaticStorage.PouredInUsedComponents == null)
{
return true;
}
PlayerManagerSettings asset = Settings<PlayerManagerSettings>.Asset;
float ingredientsExperience = 0f;
(potion.usedComponents.GetSummaryComponents().Any() ? potion.usedComponents : Managers.Potion.PotionUsedComponents).GetSummaryComponents().Skip(StaticStorage.PouredInUsedComponents.Count).ToList()
.ForEach(delegate(AlchemySubstanceComponent 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.Type == 0)
{
ingredientsExperience += ((InventoryItem)component.Component).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(Array.Empty<PotionEffect>(), list.ToArray()).cost * asset.experiencePotionEffectsMultiplier) : 0f);
Managers.Player.experience.AddExperience((ingredientsExperience + num2) * (float)count, (ExperienceCategory)1);
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;
}
SerializedPotionRecipeData serializedPotionRecipeDataFromCurrentPotion = Managers.Potion.GetSerializedPotionRecipeDataFromCurrentPotion();
IRecipeBookPageContent recipeBookPageContent = Managers.Potion.potionCraftPanel.GetRecipeBookPageContent();
Potion val = (Potion)(object)((recipeBookPageContent is Potion) ? recipeBookPageContent : null);
PotionItem val2 = null;
if ((Object)(object)val == (Object)null)
{
InteractiveItem grabbedInteractiveItem = Managers.Cursor.grabbedInteractiveItem;
PotionItem val3 = (PotionItem)(object)((grabbedInteractiveItem is PotionItem) ? grabbedInteractiveItem : null);
if (val3 != null)
{
Traverse.Create((object)val3).Property("InventoryItem", (object[])null).SetValue((object)copyTo);
val2 = val3;
}
}
PotionDataService.CopyImportantInfoToPotionInstance((IRecipeBookPageContent)(object)copyTo, val, serializedPotionRecipeDataFromCurrentPotion);
if ((Object)(object)val2 != (Object)null)
{
PotionItemStackService.SetupPotionItemForPouringIn(val2);
((ItemFromInventory)val2).OnGrabPrimary();
}
}
}
[HarmonyPatch(typeof(Potion), "Clone")]
public class CopyImportantInfoToPotionInstancePotionPatch
{
private static void Postfix(IRecipeBookPageContent __result, Potion __instance)
{
Ex.RunSafe(delegate
{
CopyImportantInfoToPotionInstance(__result, __instance);
});
}
private static void CopyImportantInfoToPotionInstance(IRecipeBookPageContent copyTo, Potion copyFrom)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Expected O, but got Unknown
PotionDataService.CopyImportantInfoToPotionInstance(copyTo, copyFrom, (SerializedPotionRecipeData)copyFrom.GetSerializedRecipeData());
}
}
[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()
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Expected O, but got Unknown
StaticStorage.CurrentPotionCraftPanelPotion = (Potion)Managers.Potion.potionCraftPanel.GetRecipeBookPageContent();
}
}
[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("recipeData");
if (num == -1)
{
return;
}
int num2 = serializedRecipe.data.IndexOf('{', num);
if (num2 == -1)
{
Plugin.PluginLogger.LogInfo((object)"Error: recipeData 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: recipeData 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: recipeData data in serialized potion is malformed (empty object).");
}
else
{
result.SetSerializedPotionFromPanel(JsonUtility.FromJson<SerializedPotionRecipeData>(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_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_0055: 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)Traverse.Create((object)potionStackItem.potionItem).Property<InventoryItem>("InventoryItem", (object[])null).Value);
return false;
}
private static void ContinueBrewingFromPotion(Potion potion)
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
SerializedPotionRecipeData recipeForPotion = RecipeService.GetRecipeForPotion(potion);
SerializedPotionRecipeData val = (SerializedPotionRecipeData)((!PotionDataService.PotionHasSerializedData(potion)) ? ((object)recipeForPotion) : ((object)(SerializedPotionRecipeData)potion.GetSerializedRecipeData()));
if (val == null)
{
Plugin.PluginLogger.LogInfo((object)"ERROR: Failed to find recipe for poured-in, pre-mod potion!");
return;
}
PotionBase potionBase = val.usedComponents.GetPotionBase();
Managers.Potion.ApplySerializedPotionRecipeDataToCurrentPotion(val, potionBase, true);
StaticStorage.PouredInUsedComponents = potion.usedComponents.GetSummaryComponents().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 val2 in collectedPotionEffects)
{
if ((ComparableScriptableObject<PotionEffect>)(object)val2 == (ComparableScriptableObject<PotionEffect>)null)
{
continue;
}
foreach (PotionEffectMapItem item in Managers.RecipeMap.currentMap.referencesContainer.potionEffectsOnMap)
{
if ((ComparableScriptableObject<PotionEffect>)(object)item.Effect == (ComparableScriptableObject<PotionEffect>)(object)val2)
{
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("recipeData"))
{
string value = ",\"recipeData\":" + JsonUtility.ToJson((object)instance.GetSerializedRecipeData());
int startIndex = result.data.LastIndexOf('}');
result.data = result.data.Insert(startIndex, value);
}
}
}
[HarmonyPatch(typeof(SavePotionRecipeButton), "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;
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 || ((MovableItem)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;
((ItemFromInventory)component).OnReleasePrimary(false);
}
}
}
}
[HarmonyPatch(typeof(LedgeController), "DetachItem")]
public class ForwardLedgeControllerDetachItemToPotionStackItemPatch
{
private static void Postfix(LedgeController __instance, ILedgeTarget ledgeTarget, bool removeFromColliders)
{
Ex.RunSafe(delegate
{
ForwardLedgeControllerDetachItemToPotionStackItem(__instance, ledgeTarget, removeFromColliders);
});
}
private static void ForwardLedgeControllerDetachItemToPotionStackItem(LedgeController __instance, ILedgeTarget ledgeTarget, bool removeFromColliders)
{
PotionItem val = (PotionItem)(object)((ledgeTarget is PotionItem) ? ledgeTarget : null);
if (val != null)
{
PotionStackItem component = ((Component)val).GetComponent<PotionStackItem>();
__instance.DetachItem((ILedgeTarget)(object)component, removeFromColliders);
}
}
}
[HarmonyPatch(typeof(LedgeController), "AttachItem")]
public class ForwardLedgeControllerAttachItemToPotionStackItemPatch
{
private static void Postfix(LedgeController __instance, ILedgeTarget ledgeTarget)
{
Ex.RunSafe(delegate
{
ForwardLedgeControllerAttachItemToPotionStackItem(__instance, ledgeTarget);
});
}
private static void ForwardLedgeControllerAttachItemToPotionStackItem(LedgeController __instance, ILedgeTarget ledgeTarget)
{
PotionItem val = (PotionItem)(object)((ledgeTarget is PotionItem) ? ledgeTarget : null);
if (val != null)
{
PotionStackItem component = ((Component)val).GetComponent<PotionStackItem>();
__instance.AttachItem((ILedgeTarget)(object)component);
}
}
}
[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_00e9: Unknown result type (might be due to invalid IL or missing references)
//IL_013c: Unknown result type (might be due to invalid IL or missing references)
//IL_0146: 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)Traverse.Create((object)potionItem).Property<InventoryItem>("InventoryItem", (object[])null).Value).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, (AudioMixerGroup)null, (Transform)null));
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(PotionInventoryObject __instance)
{
return Ex.RunSafe(() => EnableGrabUnfinishedPotionToFinishPrefix(((InventoryObject)(object)__instance).GetInventoryItem()));
}
private static void Postfix(PotionInventoryObject __instance)
{
Ex.RunSafe(delegate
{
EnableGrabUnfinishedPotionToFinishPostfix(((InventoryObject)(object)__instance).GetInventoryItem());
});
}
}
[HarmonyPatch(typeof(RecipeBookInventoryObjectPotion), "CanBeInteractedNow")]
public class RecipeBookPotionInventoryObject_CanBeInteractedNow
{
private static bool Prefix(RecipeBookInventoryObjectPotion __instance)
{
return Ex.RunSafe(() => EnableGrabUnfinishedPotionToFinishPrefix(((InventoryObject)(object)__instance).GetInventoryItem(), requireBrewStart: false));
}
private static void Postfix(RecipeBookInventoryObjectPotion __instance)
{
Ex.RunSafe(delegate
{
EnableGrabUnfinishedPotionToFinishPostfix(((InventoryObject)(object)__instance).GetInventoryItem(), 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 = Array.Empty<PotionEffect>();
StaticStorage.DummyEffectAddedToEnableFinishPotionGrab = false;
}
}
}
public class ConvertPotionInventoryItemV1toV2Pacth
{
[HarmonyPatch("PotionCraft.Assemblies.ConverterFrom110To200.SerializedInventorySlot, PotionCraft.ConverterFrom110To200, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", "ConvertPotionAndLegendarySubstancesToNew")]
public class SerializedInventorySlot_ConvertPotionAndLegendarySubstancesToNew
{
private static void Postfix(ref object __result, string ___data, string ___classFullName)
{
object myResult = __result;
Ex.RunSafe(delegate
{
ConvertPotionInventoryItem(myResult, ___data, ___classFullName);
});
}
private static void ConvertPotionInventoryItem(object result, string unconvertedJson, string classFullName)
{
if (classFullName.ToLower().Equals("PotionCraft.ScriptableObjects.Potion.Potion".ToLower()))
{
Traverse val = Traverse.Create(result);
JObject val2 = JObject.Parse(val.Field<string>("data").Value);
JToken val3 = JObject.Parse(unconvertedJson)["potionFromPanel"];
if (val3 != null)
{
JObject val4 = JObject.Parse(JsonUtility.ToJson(Traverse.Create(JsonConvert.DeserializeObject(val3.ToString((Formatting)0, Array.Empty<JsonConverter>()), AccessTools.TypeByName("PotionCraft.Assemblies.ConverterFrom110To200.SerializedPotionRecipeDataOld"))).Method("ConvertPotionToNew", Array.Empty<object>()).GetValue()));
val2["recipeData"] = (JToken)(object)val4;
string value = ((JToken)val2).ToString((Formatting)0, Array.Empty<JsonConverter>());
val.Field("data").SetValue((object)value);
}
}
}
}
}
}
namespace PotionCraftPourBackIn.Scripts.Patches.UnfinishedPotion
{
public class AllowBrewingNoEffectPotionsFromRecipeBookPatch
{
[HarmonyPatch(typeof(RecipeBookInventoryPanelTooltip), "GetTooltipContent")]
public class RecipeBookPotionPlaceholderForTooltip_GetTooltipContent
{
private static void Postfix(ref TooltipContent __result, RecipeBookLeftPageContent ___leftPageContent)
{
OverrideRecipeBookPotionIconTooltip(ref __result, ___leftPageContent);
}
}
[HarmonyPatch(typeof(RecipeBookInventoryObjectPotion), "UpdateVisual")]
public class RecipeBookPotionInventoryObject_UpdateVisual
{
private static void Postfix(RecipeBookInventoryObjectPotion __instance)
{
Ex.RunSafe(delegate
{
AllowBrewingNoEffectPotionsFromRecipeBook(__instance);
});
}
}
private static void OverrideRecipeBookPotionIconTooltip(ref TooltipContent result, RecipeBookLeftPageContent leftPageContent)
{
if (result == (TooltipContent)null)
{
return;
}
TooltipContent newResult = result;
string header = result.header;
Ex.RunSafe(delegate
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_006d: Expected O, but got Unknown
string text = new Key("#recipebook_brew_potion_no_effects", (List<string>)null, (KeyParametersStyle)0, (TMP_FontAsset)null, Array.Empty<KeyTagParameter>()).GetText();
if (!(header != text))
{
if (RecipeBookRecipeBrewController.GetMaxRecipesCountForBrew(leftPageContent.GetRecipeBookPageContent(), false, false) != 0)
{
newResult = null;
}
else
{
string text2 = new Key("#recipebook_brew_potion_not_enough_ingredients", (List<string>)null, (KeyParametersStyle)0, (TMP_FontAsset)null, Array.Empty<KeyTagParameter>()).GetText();
newResult = new TooltipContent
{
header = text2
};
}
}
});
result = newResult;
}
private static void AllowBrewingNoEffectPotionsFromRecipeBook(RecipeBookInventoryObjectPotion instance)
{
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
if (((Button)instance).Locked)
{
ItemsPanel value = Traverse.Create((object)instance).Property<ItemsPanel>("ItemsPanel", (object[])null).Value;
ItemsPanel obj = ((value is RecipeBookPanelInventoryPanel) ? value : null);
PageContentState currentState = ((PageContent)((RecipeBookPanelInventoryPanel)obj).leftPageContent).currentState;
IRecipeBookPageContent recipeBookPageContent = ((RecipeBookPanelInventoryPanel)obj).leftPageContent.GetRecipeBookPageContent();
Potion val = (Potion)(object)((recipeBookPageContent is Potion) ? recipeBookPageContent : null);
if ((int)currentState != 0 && (val.Effects.Length == 0 || (ComparableScriptableObject<PotionEffect>)(object)val.Effects[0] == (ComparableScriptableObject<PotionEffect>)null) && RecipeBookRecipeBrewController.GetMaxRecipesCountForBrew((IRecipeBookPageContent)(object)val, false, false) != 0)
{
((Button)instance).Locked = false;
}
}
}
}
}
namespace PotionCraftPourBackIn.Scripts.Extensions
{
public static class PotionExtensions
{
public static InventoryItem GetInventoryItem(this ItemFromInventory item)
{
return Traverse.Create((object)item).Property<InventoryItem>("InventoryItem", (object[])null).Value;
}
public static void SetInventoryItem(this ItemFromInventory item, InventoryItem value)
{
Traverse.Create((object)item).Property("InventoryItem", (object[])null).SetValue((object)value);
}
public static InventoryItem GetInventoryItem(this InventoryObject item)
{
return Traverse.Create((object)item).Property<InventoryItem>("InventoryItem", (object[])null).Value;
}
public static void SetInventoryItem(this InventoryObject item, InventoryItem value)
{
Traverse.Create((object)item).Property("InventoryItem", (object[])null).SetValue((object)value);
}
}
}