Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ExtraFoodSlots v1.0.1
ExtraFoodSlots.dll
Decompiled 2 weeks agousing System; using System.Collections.Generic; using System.Diagnostics; 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 TMPro; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("ExtraFoodSlots")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("HP")] [assembly: AssemblyProduct("ExtraFoodSlots")] [assembly: AssemblyCopyright("Copyright © HP 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("83294e72-4c43-4a61-8792-54257419a120")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace ExtraFoodSlots; [BepInPlugin("youdied.extrafoodslots", "Extra Food Slots", "1.0.1")] [BepInProcess("valheim.exe")] public class ExtraFoodSlotsPlugin : BaseUnityPlugin { public const string PluginGUID = "youdied.extrafoodslots"; public const string PluginName = "Extra Food Slots"; public const string PluginVersion = "1.0.1"; public static ManualLogSource Log; public static ConfigEntry<int> ExtraSlotCount; private readonly Harmony _harmony = new Harmony("youdied.extrafoodslots"); private void Awake() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; ExtraSlotCount = ((BaseUnityPlugin)this).Config.Bind<int>("General", "ExtraSlotCount", 1, new ConfigDescription("How many extra food slots to add (1-3). Can be changed in-game via the Config Manager.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 3), Array.Empty<object>())); _harmony.PatchAll(); Log.LogInfo((object)string.Format("[EFS] Extra Food Slots v{0} loaded (build 19). ExtraSlots={1}", "1.0.1", ExtraSlotCount.Value)); } private void OnDestroy() { _harmony.UnpatchSelf(); } } public static class ExtraFoodSlotsHUD { private class SlotUI { public RectTransform Root; public Image TimerBar; public Image Icon; public TMP_Text Time; } private static readonly List<SlotUI> _slots = new List<SlotUI>(); private static Hud _builtFor = null; private static bool _gaveUp = false; private static int _builtCount = 0; private const float SlotX = -67.15259f; private const float SlotY0 = 57.998566f; private const float SlotStep = 46f; private const float SlotSize = 45f; public static bool IsBuiltFor(Hud hud) { int value = ExtraFoodSlotsPlugin.ExtraSlotCount.Value; if (_builtCount != value) { _gaveUp = false; _builtFor = null; } return (Object)(object)_builtFor == (Object)(object)hud && _slots.Count == value; } public static void MarkDirty() { _builtFor = null; _gaveUp = false; } public static void BuildSlots(Hud hud) { //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Expected O, but got Unknown if (_gaveUp) { return; } foreach (SlotUI slot in _slots) { if ((Object)(object)slot.Root != (Object)null) { Object.Destroy((Object)(object)((Component)slot.Root).gameObject); } } _slots.Clear(); int value = ExtraFoodSlotsPlugin.ExtraSlotCount.Value; GameObject val = FindInChildren(((Component)hud).transform, "food0"); if ((Object)(object)val == (Object)null) { ExtraFoodSlotsPlugin.Log.LogWarning((object)"[EFS] Could not find 'food0' in HUD hierarchy."); _gaveUp = true; _builtFor = hud; return; } RectTransform component = val.GetComponent<RectTransform>(); Transform parent = ((Transform)component).parent; RectTransform val2 = (RectTransform)(object)((parent is RectTransform) ? parent : null); for (int i = 0; i < value; i++) { GameObject val3 = Object.Instantiate<GameObject>(val, (Transform)(object)val2, false); ((Object)val3).name = $"EFS_food{3 + i}"; RectTransform component2 = val3.GetComponent<RectTransform>(); component2.anchorMin = component.anchorMin; component2.anchorMax = component.anchorMax; component2.pivot = component.pivot; component2.sizeDelta = new Vector2(45f, 45f); component2.anchoredPosition = new Vector2(-67.15259f, 57.998566f + 46f * (float)(3 + i)); ((Transform)component2).SetAsLastSibling(); val3.SetActive(true); Image component3 = val3.GetComponent<Image>(); Image val4 = null; TMP_Text val5 = null; foreach (Transform item in val3.transform) { Transform val6 = item; if ((Object)(object)val4 == (Object)null) { val4 = ((Component)val6).GetComponent<Image>(); } if ((Object)(object)val5 == (Object)null) { val5 = ((Component)val6).GetComponent<TMP_Text>(); } } _slots.Add(new SlotUI { Root = component2, TimerBar = component3, Icon = val4, Time = val5 }); } _builtFor = hud; _builtCount = value; ExtraFoodSlotsPlugin.Log.LogInfo((object)$"[EFS] Built {value} extra slot(s)."); } public static void UpdateSlots(Player player) { //IL_02b0: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) if (_slots.Count == 0 || (Object)(object)player == (Object)null) { return; } List<Food> foods = player.GetFoods(); for (int i = 0; i < _slots.Count; i++) { SlotUI slotUI = _slots[i]; if ((Object)(object)slotUI.Root == (Object)null) { continue; } int num = 3 + i; bool flag = num < foods.Count; ((Component)slotUI.Root).gameObject.SetActive(true); if (flag) { Food val = foods[num]; float fillAmount = Mathf.Clamp01(val.m_time / val.m_item.m_shared.m_foodBurnTime); if ((Object)(object)slotUI.TimerBar != (Object)null) { slotUI.TimerBar.fillAmount = fillAmount; ((Graphic)slotUI.TimerBar).color = new Color(0f, 0f, 0f, 0.503f); } if ((Object)(object)slotUI.Icon != (Object)null) { ((Component)slotUI.Icon).gameObject.SetActive(true); slotUI.Icon.sprite = val.m_item.GetIcon(); ((Graphic)slotUI.Icon).color = (Color)(val.CanEatAgain() ? new Color(1f, 1f, 1f, 0.7f + Mathf.Sin(Time.time * 5f) * 0.3f) : Color.white); } if ((Object)(object)slotUI.Time != (Object)null) { ((Component)slotUI.Time).gameObject.SetActive(true); if (val.m_time >= 60f) { slotUI.Time.text = Mathf.CeilToInt(val.m_time / 60f) + "m"; ((Graphic)slotUI.Time).color = Color.white; } else { slotUI.Time.text = Mathf.FloorToInt(val.m_time) + "s"; ((Graphic)slotUI.Time).color = new Color(1f, 1f, 1f, 0.4f + Mathf.Sin(Time.time * 10f) * 0.6f); } } } else { if ((Object)(object)slotUI.TimerBar != (Object)null) { slotUI.TimerBar.fillAmount = 1f; ((Graphic)slotUI.TimerBar).color = new Color(0f, 0f, 0f, 0.2f); } if ((Object)(object)slotUI.Icon != (Object)null) { ((Component)slotUI.Icon).gameObject.SetActive(false); } if ((Object)(object)slotUI.Time != (Object)null) { ((Component)slotUI.Time).gameObject.SetActive(true); slotUI.Time.text = ""; } } } } private static GameObject FindInChildren(Transform parent, string name) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown foreach (Transform item in parent) { Transform val = item; if (((Object)val).name == name) { return ((Component)val).gameObject; } GameObject val2 = FindInChildren(val, name); if ((Object)(object)val2 != (Object)null) { return val2; } } return null; } } [HarmonyPatch(typeof(Player), "CanEat")] public static class Patch_Player_CanEat { private static readonly FieldInfo FFoods = typeof(Player).GetField("m_foods", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); [HarmonyPrefix] public static bool Prefix(Player __instance, ItemData item, bool showMessages, ref bool __result) { if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return true; } if (FFoods == null) { return true; } List<Food> list = (List<Food>)FFoods.GetValue(__instance); int count = list.Count; int num = 3 + ExtraFoodSlotsPlugin.ExtraSlotCount.Value; if (count < 3 || count >= num) { return true; } foreach (Food item2 in list) { if (item2.m_item.m_shared.m_name == item.m_shared.m_name) { if (item2.CanEatAgain()) { __result = true; return false; } if (showMessages) { ((Character)__instance).Message((MessageType)2, Localization.instance.Localize("$msg_nomore", new string[1] { item.m_shared.m_name }), 0, (Sprite)null); } __result = false; return false; } } foreach (Food item3 in list) { if (item3.CanEatAgain()) { __result = true; return false; } } __result = true; return false; } } [HarmonyPatch(typeof(Player), "EatFood")] public static class Patch_Player_EatFood { private static readonly FieldInfo FFoods = typeof(Player).GetField("m_foods", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); [HarmonyPrefix] public static bool Prefix(Player __instance, ItemData item, ref bool __result) { //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Expected O, but got Unknown if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return true; } if (FFoods == null) { return true; } List<Food> list = (List<Food>)FFoods.GetValue(__instance); int count = list.Count; if (count < 3) { return true; } foreach (Food item2 in list) { if (item2.m_item.m_shared.m_name == item.m_shared.m_name) { return true; } } int num = 3 + ExtraFoodSlotsPlugin.ExtraSlotCount.Value; if (count < num) { string text = ""; if (item.m_shared.m_food > 0f) { text += $" +{item.m_shared.m_food} $item_food_health "; } if (item.m_shared.m_foodStamina > 0f) { text += $" +{item.m_shared.m_foodStamina} $item_food_stamina "; } if (item.m_shared.m_foodEitr > 0f) { text += $" +{item.m_shared.m_foodEitr} $item_food_eitr "; } ((Character)__instance).Message((MessageType)2, text, 0, (Sprite)null); Food val = new Food(); val.m_name = (Object.op_Implicit((Object)(object)item.m_dropPrefab) ? ((Object)item.m_dropPrefab).name : item.m_shared.m_name); val.m_item = item; val.m_time = item.m_shared.m_foodBurnTime; val.m_health = item.m_shared.m_food; val.m_stamina = item.m_shared.m_foodStamina; val.m_eitr = item.m_shared.m_foodEitr; list.Add(val); typeof(Player).GetMethod("UpdateFood", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(__instance, new object[2] { 0f, true }); __result = true; return false; } return true; } } [HarmonyPatch(typeof(Hud), "UpdateFood")] public static class Patch_Hud_UpdateFood { [HarmonyPostfix] public static void Postfix(Hud __instance) { if (!ExtraFoodSlotsHUD.IsBuiltFor(__instance)) { ExtraFoodSlotsHUD.BuildSlots(__instance); } ExtraFoodSlotsHUD.UpdateSlots(Player.m_localPlayer); } } [HarmonyPatch(typeof(Hud), "LateUpdate")] public static class Patch_Hud_LateUpdate { [HarmonyPostfix] public static void Postfix(Hud __instance) { if (!ExtraFoodSlotsHUD.IsBuiltFor(__instance)) { ExtraFoodSlotsHUD.BuildSlots(__instance); ExtraFoodSlotsPlugin.Log.LogInfo((object)"[EFS] HUD built via LateUpdate fallback."); } } }