using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using OutwardGameSettings.Events;
using OutwardGameSettings.Managers;
using OutwardGameSettings.Utility.Helpers;
using OutwardModsCommunicator.EventBus;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("OutwardGameSettings")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("OutwardGameSettings")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("c5450fe0-edcf-483f-b9ea-4b1ef9d36da7")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace OutwardGameSettings
{
[BepInPlugin("gymmed.outward_game_settings", "Outward Game Settings", "1.0.1")]
public class OutwardGameSettings : BaseUnityPlugin
{
[HarmonyPatch(typeof(ResourcesPrefabManager), "Load")]
public class ResourcesPrefabManager_Load
{
private static void Postfix(ResourcesPrefabManager __instance)
{
EnchantmentsHelper.FixFilterRecipe();
EventBusDataPresenter.LogRegisteredEvents();
}
}
[HarmonyPatch(typeof(EnchantmentMenu), "TryEnchant")]
public class Patch_TryEnchant
{
private static bool Prefix(EnchantmentMenu __instance)
{
EventBusPublisher.SendTryEnchant(__instance);
if (!Object.op_Implicit((Object)(object)((SingleItemInventoryMenu)__instance).m_refItemInChest))
{
return true;
}
int enchantmentID = __instance.GetEnchantmentID();
if (enchantmentID == -1 || ((SingleItemInventoryMenu)__instance).m_refItemInChest.IsEnchanted)
{
return true;
}
if ((Object)(object)ResourcesPrefabManager.Instance.GetEnchantmentPrefab(enchantmentID) == (Object)null)
{
return true;
}
if ((Object)(object)((SingleItemContainer)__instance.m_refEnchantmentStation).ContainedItem == (Object)null)
{
return true;
}
List<EnchantmentRecipeItem> availableEnchantmentRecipeItemsInInventory = EnchantmentsHelper.GetAvailableEnchantmentRecipeItemsInInventory(((SingleItemContainer)__instance.m_refEnchantmentStation).ContainedItem, ((UIElement)__instance).LocalCharacter.Inventory);
if (RequireRecipeToAllowEnchant.Value && !EnchantmentsHelper.IsEnchantmentInList(enchantmentID, availableEnchantmentRecipeItemsInInventory))
{
((UIElement)__instance).m_characterUI.ShowInfoNotification("You need to have enchantment!");
return false;
}
if (UseRecipeOnEnchanting.Value)
{
EnchantmentRecipeItem enchantmentInTheList = EnchantmentsHelper.GetEnchantmentInTheList(enchantmentID, availableEnchantmentRecipeItemsInInventory);
if (Object.op_Implicit((Object)(object)enchantmentInTheList))
{
((UIElement)__instance).m_characterUI.ShowInfoNotification(((Item)enchantmentInTheList).Name + " has been used!");
ItemManager.Instance.DestroyItem((Item)(object)enchantmentInTheList);
}
}
return true;
}
}
public const string GUID = "gymmed.outward_game_settings";
public const string NAME = "Outward Game Settings";
public const string VERSION = "1.0.1";
public static string prefix = "[GymMed-Game-Settings]";
internal static ManualLogSource Log;
public static ConfigEntry<bool> RequireRecipeToAllowEnchant;
public static ConfigEntry<bool> UseRecipeOnEnchanting;
public static ConfigEntry<int> EnchantingSuccessChance;
public static ConfigEntry<bool> PlayAudioOnEnchantingDone;
internal void Awake()
{
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: Expected O, but got Unknown
//IL_0149: Unknown result type (might be due to invalid IL or missing references)
Log = ((BaseUnityPlugin)this).Logger;
Log.LogMessage((object)"Hello world from Outward Game Settings 1.0.1!");
RequireRecipeToAllowEnchant = ((BaseUnityPlugin)this).Config.Bind<bool>("Enchanting Modifications", "RequireRecipeToAllowEnchant", true, "Allow enchanting only if enchantment is on character?");
UseRecipeOnEnchanting = ((BaseUnityPlugin)this).Config.Bind<bool>("Enchanting Modifications", "UseRecipeOnEnchanting", true, "Remove recipe after using it on enchanting?");
ConfigDescription val = new ConfigDescription("What is success chance(%) of enchanting?", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>());
EnchantingSuccessChance = ((BaseUnityPlugin)this).Config.Bind<int>("Enchanting Modifications", "EnchantingSuccessChance", 50, val);
PlayAudioOnEnchantingDone = ((BaseUnityPlugin)this).Config.Bind<bool>("Enchanting Modifications", "PlayAudioOnEnchantingDone", true, "Play additional audio on enchanting failed/success?");
EventBus.RegisterEvent("gymmed.outward_game_settings", "EnchantmentMenu@TryEnchant", new(string, Type, string)[1] { ("menu", typeof(EnchantmentMenu), "The enchantment menu instance that invoked the TryEnchant method.") });
EventBus.RegisterEvent("gymmed.outward_game_settings", "EnchantmentTable@DoneEnchanting_Fail", new(string, Type)[1] { ("table", typeof(EnchantmentTable)) });
EventBus.RegisterEvent("gymmed.outward_game_settings", "EnchantmentTable@DoneEnchanting_Success", new(string, Type)[1] { ("table", typeof(EnchantmentTable)) });
new Harmony("gymmed.outward_game_settings").PatchAll();
}
internal void Update()
{
}
public static void LogMessage(string message)
{
Log.LogMessage((object)(prefix + " " + message));
}
}
}
namespace OutwardGameSettings.Utility.Helpers
{
public class ConfigsHelper
{
public static int GetPercentageValueFromConfig(int originalValue)
{
if (originalValue < 0)
{
return 0;
}
if (originalValue > 100)
{
return 100;
}
return originalValue;
}
}
public class EnchantmentsHelper
{
public static List<EnchantmentRecipeItem> GetAvailableEnchantmentRecipeItemsInInventory(Item item, CharacterInventory inventory)
{
List<EnchantmentRecipeItem> allItemsOfType = ItemsHelper.GetAllItemsOfType<EnchantmentRecipeItem>(ItemsHelper.GetUniqueItemsInInventory(inventory));
List<EnchantmentRecipeItem> list = new List<EnchantmentRecipeItem>();
foreach (EnchantmentRecipeItem item2 in allItemsOfType)
{
EnchantmentRecipe[] recipes = item2.Recipes;
for (int i = 0; i < recipes.Length; i++)
{
if (recipes[i].GetHasMatchingEquipment(item))
{
list.Add(item2);
}
}
}
return list;
}
public static List<EnchantmentRecipe> GetAvailableEnchantmentRecipies(Item item)
{
List<EnchantmentRecipe> enchantmentRecipes = RecipeManager.Instance.GetEnchantmentRecipes();
List<EnchantmentRecipe> list = new List<EnchantmentRecipe>();
foreach (EnchantmentRecipe item2 in enchantmentRecipes)
{
if (item2.GetHasMatchingEquipment(item))
{
list.Add(item2);
}
}
return list;
}
public static List<EnchantmentRecipe> GetMissingEnchantments(List<EnchantmentRecipe> availableEnchantments, List<EnchantmentRecipe> haveEnchantments)
{
List<EnchantmentRecipe> list = new List<EnchantmentRecipe>();
bool flag = false;
foreach (EnchantmentRecipe availableEnchantment in availableEnchantments)
{
foreach (EnchantmentRecipe haveEnchantment in haveEnchantments)
{
if (availableEnchantment.RecipeID == haveEnchantment.RecipeID)
{
flag = true;
}
}
if (flag)
{
flag = false;
}
else
{
list.Add(availableEnchantment);
}
}
return list;
}
public static bool IsEnchantmentInList(int enchantmentId, List<EnchantmentRecipeItem> enchantmentItems)
{
foreach (EnchantmentRecipeItem enchantmentItem in enchantmentItems)
{
EnchantmentRecipe[] recipes = enchantmentItem.Recipes;
for (int i = 0; i < recipes.Length; i++)
{
if (recipes[i].RecipeID == enchantmentId)
{
return true;
}
}
}
return false;
}
public static EnchantmentRecipeItem GetEnchantmentInTheList(int enchantmentId, List<EnchantmentRecipeItem> enchantmentItems)
{
foreach (EnchantmentRecipeItem enchantmentItem in enchantmentItems)
{
EnchantmentRecipe[] recipes = enchantmentItem.Recipes;
for (int i = 0; i < recipes.Length; i++)
{
if (recipes[i].RecipeID == enchantmentId)
{
return enchantmentItem;
}
}
}
return null;
}
public static void FixFilterRecipe()
{
Item itemPrefab = ResourcesPrefabManager.Instance.GetItemPrefab("5800047");
if ((Object)(object)itemPrefab == (Object)null)
{
return;
}
EnchantmentRecipeItem val = (EnchantmentRecipeItem)(object)((itemPrefab is EnchantmentRecipeItem) ? itemPrefab : null);
if (Object.op_Implicit((Object)(object)val) && val.Recipes.Count() != 3)
{
EnchantmentRecipe enchantmentRecipeForID = RecipeManager.Instance.GetEnchantmentRecipeForID(52);
EnchantmentRecipe enchantmentRecipeForID2 = RecipeManager.Instance.GetEnchantmentRecipeForID(53);
EnchantmentRecipe enchantmentRecipeForID3 = RecipeManager.Instance.GetEnchantmentRecipeForID(54);
if (!((Object)(object)enchantmentRecipeForID == (Object)null) && !((Object)(object)enchantmentRecipeForID2 == (Object)null) && !((Object)(object)enchantmentRecipeForID3 == (Object)null))
{
EnchantmentRecipe[] recipes = (EnchantmentRecipe[])(object)new EnchantmentRecipe[3] { enchantmentRecipeForID, enchantmentRecipeForID2, enchantmentRecipeForID3 };
val.Recipes = recipes;
}
}
}
}
public class ItemsHelper
{
public static List<T> GetAllItemsOfType<T>(List<Item> items) where T : Item
{
List<T> list = new List<T>();
foreach (Item item in items)
{
T val = (T)(object)((item is T) ? item : null);
if (val != null)
{
list.Add(val);
}
}
return list;
}
public static List<Item> GetUniqueItemsInInventory(CharacterInventory inventory)
{
ItemContainer pouch = inventory.Pouch;
List<Item> first = ((pouch != null) ? pouch.GetContainedItems() : null);
List<Item> second = new List<Item>();
if (inventory.HasABag)
{
second = ((ItemContainer)inventory.EquippedBag.Container).GetContainedItems();
}
return first.Union(second).ToList();
}
}
}
namespace OutwardGameSettings.Patches
{
[HarmonyPatch(typeof(EnchantmentTable), "DoneEnchanting")]
public class Patch_DoneEnchanting
{
private static bool Prefix(EnchantmentTable __instance)
{
int percentageValueFromConfig = ConfigsHelper.GetPercentageValueFromConfig(OutwardGameSettings.EnchantingSuccessChance.Value);
if (percentageValueFromConfig != 100 && new Random().Next(1, 101) > percentageValueFromConfig)
{
Enchantment pendingEnchantment = __instance.PendingEnchantment;
if (((pendingEnchantment != null) ? pendingEnchantment.Name : null) != null && (Object)/*isinst with value type is only supported in some contexts*/ != (Object)null)
{
Item obj = ((ItemContainer)__instance).m_containedItems.Values[0];
Equipment val = (Equipment)(object)((obj is Equipment) ? obj : null);
NotificationsManager.Instance.BroadcastGlobalSideNotification(((Item)val).DisplayName + " failed to be enchanted with " + __instance.PendingEnchantment.Name + "!");
}
else
{
NotificationsManager.Instance.BroadcastGlobalSideNotification("Enchanting failed!");
}
__instance.ActivateFX(false);
if (!PhotonNetwork.isNonMasterClientInRoom)
{
__instance.LockPillars(false);
}
__instance.ConsumeIncenses();
__instance.m_pendingEnchantment = null;
__instance.m_remainingEnchantTime = -999f;
FieldInfo field = typeof(EnchantmentTable).GetField("OnDoneEnchanting", BindingFlags.Instance | BindingFlags.NonPublic);
if (field != null && field.GetValue(__instance) is EventHandler eventHandler)
{
eventHandler(__instance, EventArgs.Empty);
}
if (OutwardGameSettings.PlayAudioOnEnchantingDone.Value)
{
Global.AudioManager.PlaySoundAtPosition((Sounds)11145, ((Component)__instance).transform, 0f, 1f, 1f, 1f, 1f);
}
EventBusPublisher.SendFailEnchanting(__instance);
return false;
}
Enchantment pendingEnchantment2 = __instance.PendingEnchantment;
if (((pendingEnchantment2 != null) ? pendingEnchantment2.Name : null) != null && (Object)/*isinst with value type is only supported in some contexts*/ != (Object)null)
{
Item obj2 = ((ItemContainer)__instance).m_containedItems.Values[0];
Equipment val2 = (Equipment)(object)((obj2 is Equipment) ? obj2 : null);
NotificationsManager.Instance.BroadcastGlobalSideNotification(((Item)val2).DisplayName + " was successfully enchanted with " + __instance.PendingEnchantment.Name + "!");
}
else
{
NotificationsManager.Instance.BroadcastGlobalSideNotification("Enchanting succeeded!");
}
if (OutwardGameSettings.PlayAudioOnEnchantingDone.Value)
{
Global.AudioManager.PlaySoundAtPosition((Sounds)13130, ((Component)__instance).transform, 0f, 1f, 1f, 1f, 1f);
}
EventBusPublisher.SendSuccessEnchanting(__instance);
return true;
}
}
}
namespace OutwardGameSettings.Managers
{
public class NotificationsManager
{
private static NotificationsManager _instance;
public static NotificationsManager Instance
{
get
{
if (_instance == null)
{
_instance = new NotificationsManager();
}
return _instance;
}
}
private NotificationsManager()
{
}
public void BroadcastGlobalSideNotification(string message)
{
Character val = null;
foreach (PlayerSystem item in Global.Lobby.PlayersInLobby)
{
val = item.ControlledCharacter;
if ((Object)(object)val?.CharacterUI != (Object)null)
{
val.CharacterUI.ShowInfoNotification(message);
}
}
}
public void BroadcastGlobalTopNotification(string message)
{
Character val = null;
foreach (PlayerSystem item in Global.Lobby.PlayersInLobby)
{
val = item.ControlledCharacter;
object obj;
if (val == null)
{
obj = null;
}
else
{
CharacterUI characterUI = val.CharacterUI;
obj = ((characterUI != null) ? characterUI.NotificationPanel : null);
}
if ((Object)obj != (Object)null)
{
val.CharacterUI.NotificationPanel.ShowNotification(message);
}
}
}
}
}
namespace OutwardGameSettings.Events
{
public static class EventBusPublisher
{
public const string EnchantmentMenuTryEnchant = "EnchantmentMenu@TryEnchant";
public const string EnchantmentTableDoneEnchantingFail = "EnchantmentTable@DoneEnchanting_Fail";
public const string EnchantmentTableDoneEnchantingSuccess = "EnchantmentTable@DoneEnchanting_Success";
public static void SendTryEnchant(EnchantmentMenu enchantmentMenu)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Expected O, but got Unknown
//IL_0012: Expected O, but got Unknown
EventPayload val = new EventPayload();
((Dictionary<string, object>)val)["menu"] = enchantmentMenu;
EventPayload val2 = val;
EventBus.Publish("gymmed.outward_game_settings", "EnchantmentMenu@TryEnchant", val2);
}
public static void SendFailEnchanting(EnchantmentTable enchantmentTable)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Expected O, but got Unknown
//IL_0012: Expected O, but got Unknown
EventPayload val = new EventPayload();
((Dictionary<string, object>)val)["table"] = enchantmentTable;
EventPayload val2 = val;
EventBus.Publish("gymmed.outward_game_settings", "EnchantmentTable@DoneEnchanting_Fail", val2);
}
public static void SendSuccessEnchanting(EnchantmentTable enchantmentTable)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Expected O, but got Unknown
//IL_0012: Expected O, but got Unknown
EventPayload val = new EventPayload();
((Dictionary<string, object>)val)["table"] = enchantmentTable;
EventPayload val2 = val;
EventBus.Publish("gymmed.outward_game_settings", "EnchantmentTable@DoneEnchanting_Success", val2);
}
}
}