using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("BalancedDiet")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("BalancedDiet")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("a22c48c8-afd6-481e-9e94-2817d45a4cff")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.0.0")] namespace BalancedDiet; internal static class BalancedDietFoodValues { private static readonly Dictionary Values; static BalancedDietFoodValues() { Values = new Dictionary(StringComparer.OrdinalIgnoreCase); Add("CookedDeerMeat", "$item_deer_meat_cooked", 3, 2, 0, 0); Add("CookedMeat", "$item_boar_meat_cooked", 3, 3, 0, 0); Add("Honey", "$item_honey", 0, 0, 3, 1); Add("NeckTailGrilled", "$item_necktailgrilled", 2, 2, 0, 2); Add("Mushroom", "$item_mushroomcommon", 0, 0, 1, 1); Add("Raspberry", "$item_raspberries", 0, 0, 1, 4); Add("BoarJerky", 1, 1, 1, 0); Add("CarrotSoup", 0, 0, 2, 3); Add("QueensJam", 0, 0, 3, 2); Add("MushroomYellow", 0, 0, 1, 2); Add("Carrot", 0, 0, 1, 2); Add("Blueberries", 0, 0, 2, 2); Add("FishCooked", 3, 1, 0, 1); Add("MinceMeatSauce", 3, 2, 1, 0); Add("DeerStew", 2, 2, 2, 2); Add("CookedBjornMeat", 3, 3, 0, 0); Add("Sausages", 4, 3, 0, 0); Add("BlackSoup", 2, 1, 2, 2); Add("SerpentMeatCooked", 5, 4, 0, 0); Add("SerpentStew", 5, 4, 2, 2); Add("ShocklateSmoothie", 0, 0, 3, 4); Add("TurnipStew", 1, 2, 3, 3); Add("CookedWolfMeat", 4, 3, 0, 0); Add("WolfMeatSkewer", 4, 3, 2, 1); Add("Onion", 0, 0, 2, 3); Add("OnionSoup", 0, 0, 3, 4); Add("Eyescream", 0, 1, 4, 2); Add("WolfJerky", 2, 2, 2, 0); Add("LoxMeat", 5, 4, 0, 0); Add("FishWraps", 4, 3, 3, 2); Add("LoxPie", 5, 4, 4, 2); Add("Cloudberry", 0, 0, 1, 1); Add("BloodPudding", 2, 2, 5, 0); Add("Bread", 0, 0, 7, 0); Add("CookedEgg", 4, 0, 0, 0); Add("CookedBugMeat", 5, 3, 0, 0); Add("CookedHareMeat", 5, 2, 0, 0); Add("CookedChickenMeat", 5, 3, 0, 0); Add("MeatPlatter", 6, 6, 0, 0); Add("HoneyGlazedChicken", 5, 4, 3, 2); Add("MisthareSupreme", 5, 4, 3, 4); Add("Salad", 0, 0, 4, 5); Add("MushroomOmelette", 3, 3, 3, 3); Add("FishAndBread", 6, 4, 6, 0); Add("MagicallyStuffedShroom", 0, 0, 4, 4); Add("YggdrasilPorridge", 2, 2, 6, 6); Add("SeekerAspic", 3, 3, 3, 3); Add("RoyalJelly", 0, 0, 2, 2); Add("MushroomMagecap", 0, 0, 2, 2); Add("MushroomJotunPuffs", 0, 0, 2, 2); Add("VikingCupcake", 2, 2, 4, 2); Add("CookedVoltureMeat", 6, 4, 0, 0); Add("CookedAsksvinMeat", 6, 5, 0, 0); Add("CookedBoneMawSerpentMeat", 8, 6, 0, 0); Add("FierySvinstew", 5, 5, 4, 3); Add("MashedMeat", 7, 7, 0, 0); Add("PiquantPie", 5, 5, 5, 5); Add("SpicyMarmalade", 0, 0, 6, 5); Add("ScorchingMedley", 0, 0, 5, 5); Add("RoastedCrustPie", 0, 0, 9, 0); Add("SizzlingBerryBroth", 0, 0, 5, 6); Add("SparklingShroomshake", 0, 0, 6, 6); Add("MarinatedGreens", 0, 0, 5, 7); Add("FiddleheadFern", 0, 0, 2, 3); Add("MushroomSmokePuff", 0, 0, 2, 3); Add("Vineberry", 0, 0, 3, 3); } internal static bool TryGet(ItemData item, out FoodNutrients nutrients, out string matchedId) { nutrients = default(FoodNutrients); matchedId = string.Empty; if (item == null) { return false; } try { if ((Object)(object)item.m_dropPrefab != (Object)null) { string text = NormalizePrefabName(((Object)item.m_dropPrefab).name); if (!string.IsNullOrEmpty(text) && Values.TryGetValue(text, out nutrients)) { matchedId = text; return true; } } } catch { } try { string text2 = ((item.m_shared != null) ? item.m_shared.m_name : string.Empty); if (!string.IsNullOrEmpty(text2) && Values.TryGetValue(text2, out nutrients)) { matchedId = text2; return true; } } catch { } return false; } private static void Add(string prefabName, int protein, int fat, int carbohydrate, int vitamin) { Add(prefabName, string.Empty, protein, fat, carbohydrate, vitamin); } private static void Add(string prefabName, string localizationToken, int protein, int fat, int carbohydrate, int vitamin) { FoodNutrients value = new FoodNutrients(protein, fat, carbohydrate, vitamin); if (!string.IsNullOrEmpty(prefabName)) { Values[prefabName] = value; } if (!string.IsNullOrEmpty(localizationToken)) { Values[localizationToken] = value; } } private static string NormalizePrefabName(string prefabName) { if (string.IsNullOrEmpty(prefabName)) { return string.Empty; } if (prefabName.EndsWith("(Clone)", StringComparison.Ordinal)) { prefabName = prefabName.Substring(0, prefabName.Length - "(Clone)".Length); } return prefabName.Trim(); } } internal struct FoodNutrients { internal readonly int Protein; internal readonly int Fat; internal readonly int Carbohydrate; internal readonly int Vitamin; internal FoodNutrients(int protein, int fat, int carbohydrate, int vitamin) { Protein = protein; Fat = fat; Carbohydrate = carbohydrate; Vitamin = vitamin; } } [BepInPlugin("mint.balanceddiet", "BalancedDiet", "1.7.1")] public sealed class BalancedDietPlugin : BaseUnityPlugin { private struct DietState { internal int Protein; internal int Fat; internal int Carbohydrate; internal int Vitamin; } private enum DietStatus { Exhaustion, Unbalanced, Satisfactory, Balanced, Ideal } public const string ModGuid = "mint.balanceddiet"; public const string ModName = "BalancedDiet"; public const string ModVersion = "1.7.1"; private const KeyCode MenuKey = (KeyCode)98; private const int WindowId = 18402731; private const double DecayIntervalSeconds = 1200.0; private const double DecayPersistIntervalSeconds = 5.0; private const int DecayAmount = 1; private const int DeathPenaltyAmount = 10; private const int MinimumBalancedNutrient = 30; private const int MaximumBalancedSpread = 10; private const int ExhaustionStatModifier = -10; private const int UnbalancedStatModifier = -5; private const int SatisfactoryStatModifier = 5; private const int BalancedStatModifier = 10; private const int IdealStatModifier = 15; private const float IdealStaminaRegenMultiplier = 1.1f; private const float IdealMovementSpeedMultiplier = 1.1f; private const string ProteinKey = "balanced_diet_protein"; private const string FatKey = "balanced_diet_fat"; private const string CarbohydrateKey = "balanced_diet_carbohydrate"; private const string VitaminKey = "balanced_diet_vitamin"; private const string DecayElapsedKey = "balanced_diet_decay_elapsed"; internal static BalancedDietPlugin Instance; internal static ManualLogSource Log; private Harmony _harmony; private bool _menuVisible; private Player _lastLocalPlayer; private double _decayElapsedSeconds; private double _decayPersistElapsedSeconds; private static ConfigEntry UiScale; private static ConfigEntry CloseOnEscape; private static ConfigEntry DebugLogs; private static MethodInfo _zInputGetKeyDown; private static MethodInfo _unityInputGetKeyDown; private static bool _languageReflectionCached; private static FieldInfo _localizationInstanceField; private static PropertyInfo _localizationInstanceProperty; private static MethodInfo _getSelectedLanguageMethod; private static FieldInfo _selectedLanguageField; private static PropertyInfo _selectedLanguageProperty; private static FieldInfo _terminalInstance; private static FieldInfo _terminalInput; private static FieldInfo _chatInstance; private static FieldInfo _chatInput; private static FieldInfo _characterSEMan; private bool _uiReady; private Rect _windowRect; private Texture2D _dimTexture; private Texture2D _windowTexture; private Texture2D _panelTexture; private Texture2D _rowTexture; private Texture2D _summaryTexture; private Texture2D _effectTexture; private Texture2D _footerTexture; private Texture2D _barTexture; private Texture2D _solidTexture; private Texture2D _buttonTexture; private Texture2D _buttonHoverTexture; private Texture2D _buttonActiveTexture; private GUIStyle _windowStyle; private GUIStyle _panelStyle; private GUIStyle _titleStyle; private GUIStyle _subtitleStyle; private GUIStyle _rowStyle; private GUIStyle _rowLabelStyle; private GUIStyle _percentStyle; private GUIStyle _targetStyle; private GUIStyle _rowHintStyle; private GUIStyle _summaryStyle; private GUIStyle _balanceValueStyle; private GUIStyle _dietStatusStyle; private GUIStyle _balanceMetaStyle; private GUIStyle _effectCardStyle; private GUIStyle _effectTitleStyle; private GUIStyle _effectStyle; private GUIStyle _footerBarStyle; private GUIStyle _footerStyle; private GUIStyle _buttonStyle; private void Awake() { //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Expected O, but got Unknown //IL_00c8: Unknown result type (might be due to invalid IL or missing references) Instance = this; Log = ((BaseUnityPlugin)this).Logger; UiScale = ((BaseUnityPlugin)this).Config.Bind("UI", "UiScale", 1f, Localize("Diet window scale.", "Масштаб окна системы питания.")); CloseOnEscape = ((BaseUnityPlugin)this).Config.Bind("UI", "CloseOnEscape", true, Localize("Close the diet window with Escape.", "Закрывать окно клавишей Escape.")); DebugLogs = ((BaseUnityPlugin)this).Config.Bind("Debug", "DebugLogs", false, Localize("Write nutrient changes to the log.", "Писать в лог информацию об изменении питательных веществ.")); CacheInputMethods(); CacheFocusedInputFields(); _harmony = new Harmony("mint.balanceddiet"); BalancedDietPatches.ApplyAll(_harmony); Log.LogInfo((object)("BalancedDiet v1.7.1 loaded. Menu key: " + ((object)(KeyCode)98/*cast due to .constrained prefix*/).ToString())); } internal static string Localize(string english, string russian) { return IsRussianLanguage() ? russian : english; } private static bool IsRussianLanguage() { try { string text = ReadSelectedGameLanguage(); if (string.IsNullOrEmpty(text)) { return false; } string text2 = text.Trim(); return text2.Equals("Russian", StringComparison.OrdinalIgnoreCase) || text2.Equals("Русский", StringComparison.OrdinalIgnoreCase) || text2.Equals("ru", StringComparison.OrdinalIgnoreCase) || text2.StartsWith("ru-", StringComparison.OrdinalIgnoreCase) || text2.StartsWith("ru_", StringComparison.OrdinalIgnoreCase) || text2.IndexOf("russian", StringComparison.OrdinalIgnoreCase) >= 0 || text2.IndexOf("рус", StringComparison.OrdinalIgnoreCase) >= 0; } catch { return false; } } private static string ReadSelectedGameLanguage() { CacheLanguageReflection(); object localizationInstance = GetLocalizationInstance(); object obj = null; if (_getSelectedLanguageMethod != null && (_getSelectedLanguageMethod.IsStatic || localizationInstance != null)) { object obj2 = (_getSelectedLanguageMethod.IsStatic ? null : localizationInstance); obj = _getSelectedLanguageMethod.Invoke(obj2, null); } if (obj == null) { obj = ReadFieldValue(_selectedLanguageField, localizationInstance); } if (obj == null) { obj = ReadPropertyValue(_selectedLanguageProperty, localizationInstance); } return (obj == null) ? null : Convert.ToString(obj, CultureInfo.InvariantCulture); } private static void CacheLanguageReflection() { if (_languageReflectionCached) { return; } _languageReflectionCached = true; Type type = FindRuntimeType("Localization", "LocalizationManager"); if (!(type == null)) { _localizationInstanceField = FindField(type, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, "instance", "m_instance", "Instance"); _localizationInstanceProperty = FindProperty(type, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, "instance", "Instance"); _getSelectedLanguageMethod = type.GetMethod("GetSelectedLanguage", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null); if (_getSelectedLanguageMethod == null) { _getSelectedLanguageMethod = type.GetMethod("GetLanguage", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null); } _selectedLanguageField = FindField(type, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, "m_language", "m_selectedLanguage", "selectedLanguage"); _selectedLanguageProperty = FindProperty(type, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, "SelectedLanguage", "Language"); } } private static Type FindRuntimeType(params string[] typeNames) { if (typeNames == null) { return null; } for (int i = 0; i < typeNames.Length; i++) { Type type = AccessTools.TypeByName(typeNames[i]); if (type != null) { return type; } } Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); for (int j = 0; j < assemblies.Length; j++) { Type[] types; try { types = assemblies[j].GetTypes(); } catch (ReflectionTypeLoadException ex) { types = ex.Types; } catch { continue; } if (types == null) { continue; } foreach (Type type2 in types) { if (type2 == null) { continue; } for (int l = 0; l < typeNames.Length; l++) { if (type2.Name.Equals(typeNames[l], StringComparison.Ordinal)) { return type2; } } } } return null; } private static object GetLocalizationInstance() { object obj = ReadFieldValue(_localizationInstanceField, null); return obj ?? ReadPropertyValue(_localizationInstanceProperty, null); } private static FieldInfo FindField(Type type, BindingFlags flags, params string[] names) { if (type == null || names == null) { return null; } for (int i = 0; i < names.Length; i++) { FieldInfo field = type.GetField(names[i], flags); if (field != null) { return field; } } return null; } private static PropertyInfo FindProperty(Type type, BindingFlags flags, params string[] names) { if (type == null || names == null) { return null; } for (int i = 0; i < names.Length; i++) { PropertyInfo property = type.GetProperty(names[i], flags); if (property != null && property.GetIndexParameters().Length == 0) { return property; } } return null; } private static object ReadFieldValue(FieldInfo field, object instance) { if (field == null || (!field.IsStatic && instance == null)) { return null; } object obj = (field.IsStatic ? null : instance); return field.GetValue(obj); } private static object ReadPropertyValue(PropertyInfo property, object instance) { if (property == null) { return null; } MethodInfo getMethod = property.GetGetMethod(nonPublic: true); if (getMethod == null || (!getMethod.IsStatic && instance == null)) { return null; } object obj = (getMethod.IsStatic ? null : instance); return property.GetValue(obj, null); } private void OnDestroy() { PersistDecayProgress(_lastLocalPlayer); DietMaximumStatsRuntime.RestoreTrackedMaximums(_lastLocalPlayer); if (_harmony != null) { try { _harmony.UnpatchSelf(); } catch { } } DestroyTexture(_dimTexture); DestroyTexture(_windowTexture); DestroyTexture(_panelTexture); DestroyTexture(_rowTexture); DestroyTexture(_summaryTexture); DestroyTexture(_effectTexture); DestroyTexture(_footerTexture); DestroyTexture(_barTexture); DestroyTexture(_solidTexture); DestroyTexture(_buttonTexture); DestroyTexture(_buttonHoverTexture); DestroyTexture(_buttonActiveTexture); if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } private void Update() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { PersistDecayProgress(_lastLocalPlayer); DietMaximumStatsRuntime.ForgetPlayer(); _lastLocalPlayer = null; _decayElapsedSeconds = 0.0; _decayPersistElapsedSeconds = 0.0; _menuVisible = false; return; } if ((Object)(object)_lastLocalPlayer != (Object)(object)localPlayer) { PersistDecayProgress(_lastLocalPlayer); DietMaximumStatsRuntime.ForgetPlayer(); _lastLocalPlayer = localPlayer; _menuVisible = false; EnsureDietDataExists(localPlayer); _decayElapsedSeconds = ReadDoubleValue(localPlayer, "balanced_diet_decay_elapsed"); _decayPersistElapsedSeconds = 0.0; } UpdateDietDecay(localPlayer); DietMaximumStatsRuntime.Sync(localPlayer); if (!IsUserTypingOrInventoryOpen()) { if (IsKeyDown((KeyCode)98)) { _menuVisible = !_menuVisible; } if (_menuVisible && CloseOnEscape.Value && IsKeyDown((KeyCode)27)) { _menuVisible = false; } } } private void OnGUI() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Expected O, but got Unknown //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) if (_menuVisible) { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null)) { EnsureUi(); float num = Mathf.Clamp(UiScale.Value, 0.75f, 1.5f); Matrix4x4 matrix = GUI.matrix; Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor((float)Screen.width * 0.5f, (float)Screen.height * 0.5f); GUIUtility.ScaleAroundPivot(new Vector2(num, num), val); GUI.DrawTexture(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), (Texture)(object)_dimTexture, (ScaleMode)0); ((Rect)(ref _windowRect)).width = 590f; ((Rect)(ref _windowRect)).height = 575f; ((Rect)(ref _windowRect)).x = ((float)Screen.width - ((Rect)(ref _windowRect)).width) * 0.5f; ((Rect)(ref _windowRect)).y = ((float)Screen.height - ((Rect)(ref _windowRect)).height) * 0.5f; _windowRect = GUI.Window(18402731, _windowRect, new WindowFunction(DrawDietWindow), string.Empty, _windowStyle); GUI.matrix = matrix; } } } private void DrawDietWindow(int id) { //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_02d7: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { _menuVisible = false; return; } DietState state = ReadDietState(localPlayer); int averageValue = GetAverageValue(state); int nutrientSpread = GetNutrientSpread(state); DietStatus dietStatus = GetDietStatus(state); DrawWindowFrame(); GUILayout.BeginVertical(_panelStyle, Array.Empty()); GUILayout.Label(Localize("VIKING NUTRITION", "ПИТАНИЕ ВИКИНГА"), _titleStyle, Array.Empty()); GUILayout.Label(Localize("NUTRIENT BALANCE", "БАЛАНС НУТРИЕНТОВ"), _subtitleStyle, Array.Empty()); DrawHorizontalAccent(new Color(0.78f, 0.57f, 0.29f, 0.9f), 2f); GUILayout.Space(8f); DrawBalanceRow(averageValue, nutrientSpread, dietStatus, state); GUILayout.Space(10f); DrawNutrientRow(Localize("Protein", "Белки"), state.Protein, new Color(0.8f, 0.31f, 0.25f, 1f)); GUILayout.Space(6f); DrawNutrientRow(Localize("Fats", "Жиры"), state.Fat, new Color(0.88f, 0.64f, 0.22f, 1f)); GUILayout.Space(6f); DrawNutrientRow(Localize("Carbohydrates", "Углеводы"), state.Carbohydrate, new Color(0.77f, 0.48f, 0.24f, 1f)); GUILayout.Space(6f); DrawNutrientRow(Localize("Vitamins", "Витамины"), state.Vitamin, new Color(0.38f, 0.68f, 0.38f, 1f)); GUILayout.Space(10f); DrawActiveEffectRow(dietStatus); GUILayout.FlexibleSpace(); GUILayout.BeginHorizontal(_footerBarStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(35f) }); GUILayout.Label(Localize("B open / close", "B открыть / закрыть"), _footerStyle, Array.Empty()); GUILayout.FlexibleSpace(); if (CloseOnEscape.Value) { GUILayout.Label(Localize("ESC close", "ESC закрыть"), _footerStyle, Array.Empty()); GUILayout.Space(14f); } if (GUILayout.Button(Localize("CLOSE", "ЗАКРЫТЬ"), _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(102f), GUILayout.Height(25f) })) { _menuVisible = false; } GUILayout.EndHorizontal(); GUILayout.EndVertical(); GUI.DragWindow(new Rect(0f, 0f, 10000f, 38f)); } private void DrawWindowFrame() { //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) float width = ((Rect)(ref _windowRect)).width; float height = ((Rect)(ref _windowRect)).height; Color color = default(Color); ((Color)(ref color))..ctor(0.16f, 0.17f, 0.15f, 1f); Color color2 = default(Color); ((Color)(ref color2))..ctor(0.52f, 0.44f, 0.29f, 0.72f); Color color3 = default(Color); ((Color)(ref color3))..ctor(0.82f, 0.59f, 0.27f, 0.95f); DrawOutline(new Rect(1f, 1f, width - 2f, height - 2f), color, 3f); DrawOutline(new Rect(5f, 5f, width - 10f, height - 10f), color2, 1f); DrawColoredRect(new Rect(8f, 5f, 58f, 2f), color3); DrawColoredRect(new Rect(width - 8f - 58f, 5f, 58f, 2f), color3); DrawColoredRect(new Rect(8f, height - 7f, 58f, 2f), color3); DrawColoredRect(new Rect(width - 8f - 58f, height - 7f, 58f, 2f), color3); } private void DrawNutrientRow(string label, int value, Color nutrientColor) { //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_016b: 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_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) value = Mathf.Clamp(value, 0, 100); bool flag = value >= 30; int num = Mathf.Max(0, 30 - value); GUILayout.BeginVertical(_rowStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(61f) }); GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(24f) }); Rect rect = GUILayoutUtility.GetRect(5f, 18f, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(5f), GUILayout.Height(18f) }); DrawColoredRect(rect, nutrientColor); GUILayout.Space(8f); GUILayout.Label(label, _rowLabelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(180f) }); GUILayout.FlexibleSpace(); GUILayout.Label(value.ToString(CultureInfo.InvariantCulture) + "%", _percentStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(58f) }); GUILayout.Label(Localize("minimum ", "минимум ") + 30.ToString(CultureInfo.InvariantCulture) + "%", _targetStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(88f) }); GUILayout.EndHorizontal(); Rect rect2 = GUILayoutUtility.GetRect(10f, 10f, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.ExpandWidth(true), GUILayout.Height(10f) }); GUI.DrawTexture(rect2, (Texture)(object)_barTexture, (ScaleMode)0); DrawOutline(rect2, new Color(0.43f, 0.4f, 0.32f, 0.52f), 1f); float num2 = Mathf.Max(0f, ((Rect)(ref rect2)).width - 2f); float num3 = num2 * (float)value / 100f; if (num3 > 0f) { DrawColoredRect(new Rect(((Rect)(ref rect2)).x + 1f, ((Rect)(ref rect2)).y + 1f, num3, ((Rect)(ref rect2)).height - 2f), nutrientColor); } float num4 = ((Rect)(ref rect2)).x + num2 * 30f / 100f; DrawColoredRect(new Rect(num4, ((Rect)(ref rect2)).y - 1f, 2f, ((Rect)(ref rect2)).height + 2f), new Color(0.9f, 0.84f, 0.68f, 0.95f)); GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(15f) }); GUILayout.Label(flag ? Localize("TARGET REACHED", "НОРМА ДОСТИГНУТА") : (Localize("MISSING ", "НЕ ХВАТАЕТ ") + num.ToString(CultureInfo.InvariantCulture) + "%"), _rowHintStyle, Array.Empty()); GUILayout.FlexibleSpace(); GUILayout.Label(Localize("threshold 30%", "порог 30%"), _rowHintStyle, Array.Empty()); GUILayout.EndHorizontal(); GUILayout.EndVertical(); } private void DrawBalanceRow(int average, int spread, DietStatus dietStatus, DietState state) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: 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_0066: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) Rect rect = GUILayoutUtility.GetRect(10f, 68f, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.ExpandWidth(true), GUILayout.Height(68f) }); GUI.Box(rect, GUIContent.none, _summaryStyle); Color statusColor = GetStatusColor(dietStatus); DrawColoredRect(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y, 5f, ((Rect)(ref rect)).height), statusColor); Rect val = default(Rect); ((Rect)(ref val))..ctor(((Rect)(ref rect)).x + 16f, ((Rect)(ref rect)).y + 10f, ((Rect)(ref rect)).width - 128f, 25f); GUI.Label(val, GetStatusRichText(dietStatus), _dietStatusStyle); int num = Mathf.Min(Mathf.Min(state.Protein, state.Fat), Mathf.Min(state.Carbohydrate, state.Vitamin)); Rect val2 = default(Rect); ((Rect)(ref val2))..ctor(((Rect)(ref rect)).x + 16f, ((Rect)(ref rect)).y + 36f, ((Rect)(ref rect)).width - 128f, 20f); GUI.Label(val2, Localize("Spread: ", "Разброс: ") + spread.ToString(CultureInfo.InvariantCulture) + Localize("% of ", "% из ") + 10.ToString(CultureInfo.InvariantCulture) + Localize("% Minimum: ", "% Минимум: ") + num.ToString(CultureInfo.InvariantCulture) + "%", _balanceMetaStyle); Rect val3 = default(Rect); ((Rect)(ref val3))..ctor(((Rect)(ref rect)).x + ((Rect)(ref rect)).width - 104f, ((Rect)(ref rect)).y + 7f, 88f, 34f); GUI.Label(val3, average.ToString(CultureInfo.InvariantCulture) + "%", _balanceValueStyle); GUI.Label(new Rect(((Rect)(ref rect)).x + ((Rect)(ref rect)).width - 104f, ((Rect)(ref rect)).y + 39f, 88f, 17f), Localize("AVERAGE", "СРЕДНЕЕ"), _targetStyle); } private void DrawActiveEffectRow(DietStatus dietStatus) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) Rect rect = GUILayoutUtility.GetRect(10f, 62f, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.ExpandWidth(true), GUILayout.Height(62f) }); GUI.Box(rect, GUIContent.none, _effectCardStyle); DrawColoredRect(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y, 4f, ((Rect)(ref rect)).height), GetStatusColor(dietStatus)); GUI.Label(new Rect(((Rect)(ref rect)).x + 15f, ((Rect)(ref rect)).y + 7f, ((Rect)(ref rect)).width - 28f, 18f), Localize("ACTIVE EFFECT", "АКТИВНЫЙ ЭФФЕКТ"), _effectTitleStyle); GUI.Label(new Rect(((Rect)(ref rect)).x + 15f, ((Rect)(ref rect)).y + 25f, ((Rect)(ref rect)).width - 28f, 29f), GetEffectRichText(dietStatus), _effectStyle); } private void DrawHorizontalAccent(Color color, float height) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_0027: Unknown result type (might be due to invalid IL or missing references) Rect rect = GUILayoutUtility.GetRect(10f, height, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.ExpandWidth(true), GUILayout.Height(height) }); DrawColoredRect(rect, color); } private void DrawColoredRect(Rect rect, Color color) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) Color color2 = GUI.color; GUI.color = color; GUI.DrawTexture(rect, (Texture)(object)_solidTexture, (ScaleMode)0); GUI.color = color2; } private void DrawOutline(Rect rect, Color color, float thickness) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) DrawColoredRect(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y, ((Rect)(ref rect)).width, thickness), color); DrawColoredRect(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y + ((Rect)(ref rect)).height - thickness, ((Rect)(ref rect)).width, thickness), color); DrawColoredRect(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y, thickness, ((Rect)(ref rect)).height), color); DrawColoredRect(new Rect(((Rect)(ref rect)).x + ((Rect)(ref rect)).width - thickness, ((Rect)(ref rect)).y, thickness, ((Rect)(ref rect)).height), color); } private void EnsureUi() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Expected O, but got Unknown //IL_027c: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Expected O, but got Unknown //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_02a3: Expected O, but got Unknown //IL_02ae: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Expected O, but got Unknown //IL_02c7: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Expected O, but got Unknown //IL_02e9: Unknown result type (might be due to invalid IL or missing references) //IL_02ee: Unknown result type (might be due to invalid IL or missing references) //IL_02f6: Unknown result type (might be due to invalid IL or missing references) //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_0307: Unknown result type (might be due to invalid IL or missing references) //IL_0313: Unknown result type (might be due to invalid IL or missing references) //IL_0320: Expected O, but got Unknown //IL_033f: Unknown result type (might be due to invalid IL or missing references) //IL_0355: Unknown result type (might be due to invalid IL or missing references) //IL_035a: Unknown result type (might be due to invalid IL or missing references) //IL_0362: Unknown result type (might be due to invalid IL or missing references) //IL_036b: Unknown result type (might be due to invalid IL or missing references) //IL_0373: Unknown result type (might be due to invalid IL or missing references) //IL_0384: Expected O, but got Unknown //IL_03a3: Unknown result type (might be due to invalid IL or missing references) //IL_03b9: Unknown result type (might be due to invalid IL or missing references) //IL_03be: Unknown result type (might be due to invalid IL or missing references) //IL_03c5: Unknown result type (might be due to invalid IL or missing references) //IL_03cf: Expected O, but got Unknown //IL_03d0: Unknown result type (might be due to invalid IL or missing references) //IL_03d5: Unknown result type (might be due to invalid IL or missing references) //IL_03df: Expected O, but got Unknown //IL_03e0: Unknown result type (might be due to invalid IL or missing references) //IL_03f7: Expected O, but got Unknown //IL_0402: Unknown result type (might be due to invalid IL or missing references) //IL_0407: Unknown result type (might be due to invalid IL or missing references) //IL_040f: Unknown result type (might be due to invalid IL or missing references) //IL_0418: Unknown result type (might be due to invalid IL or missing references) //IL_0420: Unknown result type (might be due to invalid IL or missing references) //IL_0431: Expected O, but got Unknown //IL_0450: Unknown result type (might be due to invalid IL or missing references) //IL_0466: Unknown result type (might be due to invalid IL or missing references) //IL_046b: Unknown result type (might be due to invalid IL or missing references) //IL_0473: Unknown result type (might be due to invalid IL or missing references) //IL_047c: Unknown result type (might be due to invalid IL or missing references) //IL_0484: Unknown result type (might be due to invalid IL or missing references) //IL_0495: Expected O, but got Unknown //IL_04b4: Unknown result type (might be due to invalid IL or missing references) //IL_04ca: Unknown result type (might be due to invalid IL or missing references) //IL_04cf: Unknown result type (might be due to invalid IL or missing references) //IL_04d7: Unknown result type (might be due to invalid IL or missing references) //IL_04e0: Unknown result type (might be due to invalid IL or missing references) //IL_04e8: Unknown result type (might be due to invalid IL or missing references) //IL_04f9: Expected O, but got Unknown //IL_0518: Unknown result type (might be due to invalid IL or missing references) //IL_052e: Unknown result type (might be due to invalid IL or missing references) //IL_0533: Unknown result type (might be due to invalid IL or missing references) //IL_053b: Unknown result type (might be due to invalid IL or missing references) //IL_0544: Unknown result type (might be due to invalid IL or missing references) //IL_054c: Unknown result type (might be due to invalid IL or missing references) //IL_0558: Unknown result type (might be due to invalid IL or missing references) //IL_0565: Expected O, but got Unknown //IL_0584: Unknown result type (might be due to invalid IL or missing references) //IL_059a: Unknown result type (might be due to invalid IL or missing references) //IL_059f: Unknown result type (might be due to invalid IL or missing references) //IL_05a4: Unknown result type (might be due to invalid IL or missing references) //IL_05ae: Expected O, but got Unknown //IL_05af: Unknown result type (might be due to invalid IL or missing references) //IL_05b4: Unknown result type (might be due to invalid IL or missing references) //IL_05be: Expected O, but got Unknown //IL_05bf: Unknown result type (might be due to invalid IL or missing references) //IL_05d6: Expected O, but got Unknown //IL_05e1: Unknown result type (might be due to invalid IL or missing references) //IL_05e6: Unknown result type (might be due to invalid IL or missing references) //IL_05ee: Unknown result type (might be due to invalid IL or missing references) //IL_05f7: Unknown result type (might be due to invalid IL or missing references) //IL_05ff: Unknown result type (might be due to invalid IL or missing references) //IL_0610: Expected O, but got Unknown //IL_062f: Unknown result type (might be due to invalid IL or missing references) //IL_0645: Unknown result type (might be due to invalid IL or missing references) //IL_064a: Unknown result type (might be due to invalid IL or missing references) //IL_0652: Unknown result type (might be due to invalid IL or missing references) //IL_065b: Unknown result type (might be due to invalid IL or missing references) //IL_0663: Unknown result type (might be due to invalid IL or missing references) //IL_066f: Unknown result type (might be due to invalid IL or missing references) //IL_067c: Expected O, but got Unknown //IL_0687: Unknown result type (might be due to invalid IL or missing references) //IL_068c: Unknown result type (might be due to invalid IL or missing references) //IL_0694: Unknown result type (might be due to invalid IL or missing references) //IL_069d: Unknown result type (might be due to invalid IL or missing references) //IL_06ae: Expected O, but got Unknown //IL_06cd: Unknown result type (might be due to invalid IL or missing references) //IL_06e3: Unknown result type (might be due to invalid IL or missing references) //IL_06e8: Unknown result type (might be due to invalid IL or missing references) //IL_06ed: Unknown result type (might be due to invalid IL or missing references) //IL_06f7: Expected O, but got Unknown //IL_06f8: Unknown result type (might be due to invalid IL or missing references) //IL_06fd: Unknown result type (might be due to invalid IL or missing references) //IL_0707: Expected O, but got Unknown //IL_0708: Unknown result type (might be due to invalid IL or missing references) //IL_071f: Expected O, but got Unknown //IL_072a: Unknown result type (might be due to invalid IL or missing references) //IL_072f: Unknown result type (might be due to invalid IL or missing references) //IL_0737: Unknown result type (might be due to invalid IL or missing references) //IL_0740: Unknown result type (might be due to invalid IL or missing references) //IL_0748: Unknown result type (might be due to invalid IL or missing references) //IL_0759: Expected O, but got Unknown //IL_0778: Unknown result type (might be due to invalid IL or missing references) //IL_078e: Unknown result type (might be due to invalid IL or missing references) //IL_0793: Unknown result type (might be due to invalid IL or missing references) //IL_079b: Unknown result type (might be due to invalid IL or missing references) //IL_07a4: Unknown result type (might be due to invalid IL or missing references) //IL_07ac: Unknown result type (might be due to invalid IL or missing references) //IL_07b8: Unknown result type (might be due to invalid IL or missing references) //IL_07c0: Unknown result type (might be due to invalid IL or missing references) //IL_07cd: Expected O, but got Unknown //IL_07d8: Unknown result type (might be due to invalid IL or missing references) //IL_07dd: Unknown result type (might be due to invalid IL or missing references) //IL_07e3: Unknown result type (might be due to invalid IL or missing references) //IL_07ed: Expected O, but got Unknown //IL_07ee: Unknown result type (might be due to invalid IL or missing references) //IL_07f3: Unknown result type (might be due to invalid IL or missing references) //IL_07fd: Expected O, but got Unknown //IL_07fe: Unknown result type (might be due to invalid IL or missing references) //IL_0815: Expected O, but got Unknown //IL_0820: Unknown result type (might be due to invalid IL or missing references) //IL_0825: Unknown result type (might be due to invalid IL or missing references) //IL_082d: Unknown result type (might be due to invalid IL or missing references) //IL_0836: Unknown result type (might be due to invalid IL or missing references) //IL_0843: Expected O, but got Unknown //IL_0862: Unknown result type (might be due to invalid IL or missing references) //IL_0878: Unknown result type (might be due to invalid IL or missing references) //IL_087d: Unknown result type (might be due to invalid IL or missing references) //IL_0885: Unknown result type (might be due to invalid IL or missing references) //IL_088e: Unknown result type (might be due to invalid IL or missing references) //IL_0896: Unknown result type (might be due to invalid IL or missing references) //IL_089b: Unknown result type (might be due to invalid IL or missing references) //IL_08a5: Expected O, but got Unknown //IL_08a6: Unknown result type (might be due to invalid IL or missing references) //IL_08b8: Unknown result type (might be due to invalid IL or missing references) //IL_08ca: Unknown result type (might be due to invalid IL or missing references) //IL_08e1: Expected O, but got Unknown //IL_0900: Unknown result type (might be due to invalid IL or missing references) //IL_0916: Unknown result type (might be due to invalid IL or missing references) //IL_092c: Unknown result type (might be due to invalid IL or missing references) //IL_094c: Unknown result type (might be due to invalid IL or missing references) //IL_0951: Unknown result type (might be due to invalid IL or missing references) if (!_uiReady) { _dimTexture = MakeTexture(new Color(0f, 0f, 0f, 0.6f)); _windowTexture = MakeTexture(new Color(0.075f, 0.08f, 0.07f, 0.995f)); _panelTexture = MakeTexture(new Color(0.095f, 0.105f, 0.095f, 0.985f)); _rowTexture = MakeBorderedTexture(new Color(0.16f, 0.17f, 0.15f, 0.985f), new Color(0.4f, 0.37f, 0.29f, 0.34f)); _summaryTexture = MakeBorderedTexture(new Color(0.19f, 0.19f, 0.16f, 0.99f), new Color(0.5f, 0.43f, 0.29f, 0.48f)); _effectTexture = MakeBorderedTexture(new Color(0.135f, 0.145f, 0.13f, 0.99f), new Color(0.42f, 0.39f, 0.3f, 0.38f)); _footerTexture = MakeBorderedTexture(new Color(0.12f, 0.125f, 0.11f, 0.99f), new Color(0.38f, 0.35f, 0.27f, 0.34f)); _barTexture = MakeTexture(new Color(0.055f, 0.06f, 0.055f, 1f)); _solidTexture = MakeTexture(Color.white); _buttonTexture = MakeBorderedTexture(new Color(0.22f, 0.21f, 0.17f, 1f), new Color(0.56f, 0.45f, 0.26f, 0.7f)); _buttonHoverTexture = MakeBorderedTexture(new Color(0.35f, 0.29f, 0.18f, 1f), new Color(0.77f, 0.57f, 0.27f, 0.95f)); _buttonActiveTexture = MakeBorderedTexture(new Color(0.46f, 0.34f, 0.17f, 1f), new Color(0.9f, 0.68f, 0.31f, 1f)); GUIStyle val = new GUIStyle(GUI.skin.window) { padding = new RectOffset(8, 8, 8, 8), border = new RectOffset(0, 0, 0, 0) }; val.normal.background = _windowTexture; _windowStyle = val; GUIStyle val2 = new GUIStyle(GUI.skin.box) { padding = new RectOffset(22, 22, 15, 14) }; val2.normal.background = _panelTexture; _panelStyle = val2; _titleStyle = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)4, fontSize = 23, fontStyle = (FontStyle)1, fixedHeight = 32f, richText = true }; _titleStyle.normal.textColor = new Color(0.92f, 0.88f, 0.78f, 1f); _subtitleStyle = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)4, fontSize = 10, fontStyle = (FontStyle)1, fixedHeight = 17f }; _subtitleStyle.normal.textColor = new Color(0.7f, 0.67f, 0.58f, 1f); GUIStyle val3 = new GUIStyle(GUI.skin.box) { padding = new RectOffset(11, 11, 5, 4), border = new RectOffset(1, 1, 1, 1) }; val3.normal.background = _rowTexture; _rowStyle = val3; _rowLabelStyle = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)3, fontSize = 15, fontStyle = (FontStyle)1, fixedHeight = 22f }; _rowLabelStyle.normal.textColor = new Color(0.88f, 0.86f, 0.8f, 1f); _percentStyle = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)5, fontSize = 17, fontStyle = (FontStyle)1, fixedHeight = 22f }; _percentStyle.normal.textColor = new Color(0.96f, 0.92f, 0.8f, 1f); _targetStyle = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)5, fontSize = 10, fontStyle = (FontStyle)1, fixedHeight = 20f }; _targetStyle.normal.textColor = new Color(0.7f, 0.68f, 0.61f, 1f); _rowHintStyle = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)3, fontSize = 9, fontStyle = (FontStyle)1, fixedHeight = 14f, richText = true }; _rowHintStyle.normal.textColor = new Color(0.67f, 0.65f, 0.58f, 1f); GUIStyle val4 = new GUIStyle(GUI.skin.box) { padding = new RectOffset(0, 0, 0, 0), border = new RectOffset(1, 1, 1, 1) }; val4.normal.background = _summaryTexture; _summaryStyle = val4; _balanceValueStyle = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)4, fontSize = 22, fontStyle = (FontStyle)1, fixedHeight = 34f }; _balanceValueStyle.normal.textColor = new Color(0.93f, 0.85f, 0.65f, 1f); _dietStatusStyle = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)3, fontSize = 15, fontStyle = (FontStyle)1, fixedHeight = 25f, richText = true }; _balanceMetaStyle = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)3, fontSize = 11, fixedHeight = 20f }; _balanceMetaStyle.normal.textColor = new Color(0.72f, 0.7f, 0.63f, 1f); GUIStyle val5 = new GUIStyle(GUI.skin.box) { padding = new RectOffset(0, 0, 0, 0), border = new RectOffset(1, 1, 1, 1) }; val5.normal.background = _effectTexture; _effectCardStyle = val5; _effectTitleStyle = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)3, fontSize = 9, fontStyle = (FontStyle)1, fixedHeight = 18f }; _effectTitleStyle.normal.textColor = new Color(0.72f, 0.7f, 0.63f, 1f); _effectStyle = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)3, fontSize = 11, fontStyle = (FontStyle)1, fixedHeight = 29f, richText = true, wordWrap = true }; GUIStyle val6 = new GUIStyle(GUI.skin.box) { padding = new RectOffset(9, 6, 4, 4), border = new RectOffset(1, 1, 1, 1) }; val6.normal.background = _footerTexture; _footerBarStyle = val6; _footerStyle = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)3, fontSize = 10, richText = true }; _footerStyle.normal.textColor = new Color(0.75f, 0.72f, 0.64f, 1f); GUIStyle val7 = new GUIStyle(GUI.skin.button) { alignment = (TextAnchor)4, fontSize = 10, fontStyle = (FontStyle)1, border = new RectOffset(1, 1, 1, 1) }; val7.normal.background = _buttonTexture; val7.hover.background = _buttonHoverTexture; val7.active.background = _buttonActiveTexture; _buttonStyle = val7; _buttonStyle.normal.textColor = new Color(0.86f, 0.82f, 0.72f, 1f); _buttonStyle.hover.textColor = Color.white; _buttonStyle.active.textColor = Color.white; _windowRect = new Rect(0f, 0f, 590f, 575f); _uiReady = true; } } private static Texture2D MakeTexture(Color color) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_002c: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); Color[] pixels = (Color[])(object)new Color[4] { color, color, color, color }; val.SetPixels(pixels); val.Apply(false, true); return val; } private static Texture2D MakeBorderedTexture(Color fillColor, Color borderColor) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(6, 6, (TextureFormat)4, false); Color[] array = (Color[])(object)new Color[36]; for (int i = 0; i < 6; i++) { for (int j = 0; j < 6; j++) { bool flag = j == 0 || i == 0 || j == 5 || i == 5; array[i * 6 + j] = (flag ? borderColor : fillColor); } } val.SetPixels(array); val.Apply(false, true); return val; } private static void DestroyTexture(Texture2D texture) { if ((Object)(object)texture != (Object)null) { Object.Destroy((Object)(object)texture); } } private static void CacheInputMethods() { try { Type type = AccessTools.TypeByName("ZInput"); if (type != null) { _zInputGetKeyDown = type.GetMethod("GetKeyDown", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(KeyCode) }, null); } } catch { _zInputGetKeyDown = null; } try { Type type2 = Type.GetType("UnityEngine.Input, UnityEngine.InputLegacyModule", throwOnError: false) ?? Type.GetType("UnityEngine.Input, UnityEngine", throwOnError: false) ?? Type.GetType("UnityEngine.Input", throwOnError: false); if (type2 != null) { _unityInputGetKeyDown = type2.GetMethod("GetKeyDown", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(KeyCode) }, null); } } catch { _unityInputGetKeyDown = null; } } private static bool IsKeyDown(KeyCode key) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) if (_zInputGetKeyDown != null) { try { if (_zInputGetKeyDown.Invoke(null, new object[1] { key }) is int num && num != 0) { return true; } } catch { } } if (_unityInputGetKeyDown != null) { try { if (_unityInputGetKeyDown.Invoke(null, new object[1] { key }) is int num2 && num2 != 0) { return true; } } catch { } } return false; } private static void CacheFocusedInputFields() { try { Type typeFromHandle = typeof(Terminal); _terminalInstance = typeFromHandle.GetField("m_instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) ?? typeFromHandle.GetField("instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); _terminalInput = typeFromHandle.GetField("m_input", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? typeFromHandle.GetField("m_inputField", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } catch { _terminalInstance = null; _terminalInput = null; } try { Type typeFromHandle2 = typeof(Chat); _chatInstance = typeFromHandle2.GetField("m_instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) ?? typeFromHandle2.GetField("instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); _chatInput = typeFromHandle2.GetField("m_input", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? typeFromHandle2.GetField("m_inputField", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } catch { _chatInstance = null; _chatInput = null; } } private static bool IsUserTypingOrInventoryOpen() { try { if (InventoryGui.IsVisible()) { return true; } } catch { } return IsInputFieldFocused(_terminalInstance, _terminalInput) || IsInputFieldFocused(_chatInstance, _chatInput); } private static bool IsInputFieldFocused(FieldInfo instanceField, FieldInfo inputField) { if (instanceField == null || inputField == null) { return false; } try { object value = instanceField.GetValue(null); if (value == null) { return false; } object value2 = inputField.GetValue(value); if (value2 == null) { return false; } PropertyInfo property = value2.GetType().GetProperty("isFocused", BindingFlags.Instance | BindingFlags.Public); if (property == null) { return false; } object value3 = property.GetValue(value2, null); return value3 is bool && (bool)value3; } catch { return false; } } private static void EnsureDietDataExists(Player player) { if ((Object)(object)player == (Object)null) { return; } try { if (player.m_customData == null) { player.m_customData = new Dictionary(); } EnsureValueExists(player, "balanced_diet_protein"); EnsureValueExists(player, "balanced_diet_fat"); EnsureValueExists(player, "balanced_diet_carbohydrate"); EnsureValueExists(player, "balanced_diet_vitamin"); EnsureValueExists(player, "balanced_diet_decay_elapsed"); } catch (Exception ex) { Log.LogWarning((object)("Could not initialize diet data: " + ex.Message)); } } private static void EnsureValueExists(Player player, string key) { if (!player.m_customData.ContainsKey(key)) { player.m_customData[key] = "0"; } } private static DietState ReadDietState(Player player) { if ((Object)(object)player == (Object)null) { return default(DietState); } EnsureDietDataExists(player); return new DietState { Protein = ReadValue(player, "balanced_diet_protein"), Fat = ReadValue(player, "balanced_diet_fat"), Carbohydrate = ReadValue(player, "balanced_diet_carbohydrate"), Vitamin = ReadValue(player, "balanced_diet_vitamin") }; } private static int ReadValue(Player player, string key) { try { if (player.m_customData != null && player.m_customData.TryGetValue(key, out var value) && int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result)) { return Mathf.Clamp(result, 0, 100); } } catch { } return 0; } private static void WriteValue(Player player, string key, int value) { EnsureDietDataExists(player); player.m_customData[key] = Mathf.Clamp(value, 0, 100).ToString(CultureInfo.InvariantCulture); } private static double ReadDoubleValue(Player player, string key) { try { if ((Object)(object)player != (Object)null && player.m_customData != null && player.m_customData.TryGetValue(key, out var value) && double.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) { return ClampDouble(result, 0.0, 1200.0); } } catch { } return 0.0; } private static void WriteDoubleValue(Player player, string key, double value) { if (!((Object)(object)player == (Object)null)) { EnsureDietDataExists(player); player.m_customData[key] = ClampDouble(value, 0.0, 1200.0).ToString("R", CultureInfo.InvariantCulture); } } private static double ClampDouble(double value, double minimum, double maximum) { if (double.IsNaN(value) || double.IsInfinity(value)) { return minimum; } if (value < minimum) { return minimum; } return (value > maximum) ? maximum : value; } private void UpdateDietDecay(Player player) { if ((Object)(object)player == (Object)null) { return; } float unscaledDeltaTime = Time.unscaledDeltaTime; if (!(unscaledDeltaTime <= 0f) && !float.IsNaN(unscaledDeltaTime) && !float.IsInfinity(unscaledDeltaTime)) { double num = unscaledDeltaTime; _decayElapsedSeconds += num; _decayPersistElapsedSeconds += num; bool flag = false; while (_decayElapsedSeconds >= 1200.0) { _decayElapsedSeconds -= 1200.0; ChangeAllNutrients(player, -1, "1200-second decay"); Log.LogInfo((object)"Diet decay applied: -1% to every nutrient after 1200 seconds."); flag = true; } if (flag || _decayPersistElapsedSeconds >= 5.0) { PersistDecayProgress(player); _decayPersistElapsedSeconds = 0.0; } } } private void PersistDecayProgress(Player player) { if ((Object)(object)player == (Object)null) { return; } try { WriteDoubleValue(player, "balanced_diet_decay_elapsed", _decayElapsedSeconds); } catch { } } private static void ChangeAllNutrients(Player player, int amount, string reason) { if (!((Object)(object)player == (Object)null)) { DietState dietState = ReadDietState(player); WriteValue(player, "balanced_diet_protein", dietState.Protein + amount); WriteValue(player, "balanced_diet_fat", dietState.Fat + amount); WriteValue(player, "balanced_diet_carbohydrate", dietState.Carbohydrate + amount); WriteValue(player, "balanced_diet_vitamin", dietState.Vitamin + amount); if (DebugLogs != null && DebugLogs.Value) { Log.LogInfo((object)(reason + ": " + ((amount >= 0) ? "+" : string.Empty) + amount.ToString(CultureInfo.InvariantCulture) + "% to every nutrient.")); } } } internal static void HandlePlayerDeath(Player player) { if (!((Object)(object)player == (Object)null) && !((Object)(object)Player.m_localPlayer == (Object)null) && !((Object)(object)player != (Object)(object)Player.m_localPlayer)) { ChangeAllNutrients(player, -10, "death penalty"); } } private static int GetAverageValue(DietState state) { float num = (float)(state.Protein + state.Fat + state.Carbohydrate + state.Vitamin) / 4f; return Mathf.Clamp(Mathf.RoundToInt(num), 0, 100); } private static int GetNutrientSpread(DietState state) { int num = Mathf.Min(Mathf.Min(state.Protein, state.Fat), Mathf.Min(state.Carbohydrate, state.Vitamin)); int num2 = Mathf.Max(Mathf.Max(state.Protein, state.Fat), Mathf.Max(state.Carbohydrate, state.Vitamin)); return num2 - num; } private static DietStatus GetDietStatus(DietState state) { int num = Mathf.Min(Mathf.Min(state.Protein, state.Fat), Mathf.Min(state.Carbohydrate, state.Vitamin)); if (num < 30) { return DietStatus.Exhaustion; } if (GetNutrientSpread(state) > 10) { return DietStatus.Unbalanced; } int averageValue = GetAverageValue(state); if (averageValue >= 90) { return DietStatus.Ideal; } if (averageValue >= 70) { return DietStatus.Balanced; } return DietStatus.Satisfactory; } private static string GetStatusRichText(DietStatus status) { return status switch { DietStatus.Exhaustion => Localize("DEPLETION", "ИСТОЩЕНИЕ"), DietStatus.Unbalanced => Localize("UNBALANCED DIET", "НЕСБАЛАНСИРОВАННОЕ ПИТАНИЕ"), DietStatus.Satisfactory => Localize("SATISFACTORY DIET", "УДОВЛЕТВОРИТЕЛЬНОЕ ПИТАНИЕ"), DietStatus.Balanced => Localize("BALANCED DIET", "СБАЛАНСИРОВАННОЕ ПИТАНИЕ"), DietStatus.Ideal => Localize("IDEAL DIET", "ИДЕАЛЬНОЕ ПИТАНИЕ"), _ => Localize("UNKNOWN STATUS", "НЕИЗВЕСТНЫЙ СТАТУС"), }; } private static Color GetStatusColor(DietStatus status) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0057: 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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: 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_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) return (Color)(status switch { DietStatus.Exhaustion => new Color(0.91f, 0.4f, 0.32f, 1f), DietStatus.Unbalanced => new Color(0.9f, 0.61f, 0.27f, 1f), DietStatus.Satisfactory => new Color(0.84f, 0.75f, 0.32f, 1f), DietStatus.Balanced => new Color(0.42f, 0.73f, 0.38f, 1f), DietStatus.Ideal => new Color(0.34f, 0.72f, 0.8f, 1f), _ => new Color(0.6f, 0.6f, 0.6f, 1f), }); } private static string GetEffectRichText(DietStatus status) { return status switch { DietStatus.Exhaustion => Localize("-10 health, -10 stamina", "-10 здоровья, -10 выносливости"), DietStatus.Unbalanced => Localize("-5 health, -5 stamina", "-5 здоровья, -5 выносливости"), DietStatus.Satisfactory => Localize("+5 health, +5 stamina", "+5 здоровья, +5 выносливости"), DietStatus.Balanced => Localize("+10 health, +10 stamina", "+10 здоровья, +10 выносливости"), DietStatus.Ideal => Localize("+15 health, +15 stamina, +10% stamina regeneration, +10% movement speed", "+15 здоровья, +15 выносливости, +10% восстановления выносливости, +10% скорости"), _ => Localize("No effect", "Нет эффекта"), }; } internal static int GetHealthModifier(Player player) { return GetDietStatModifier(player); } internal static int GetStaminaModifier(Player player) { return GetDietStatModifier(player); } private static int GetDietStatModifier(Player player) { if (!IsLocalDietPlayer(player)) { return 0; } return GetDietStatus(ReadDietState(player)) switch { DietStatus.Exhaustion => -10, DietStatus.Unbalanced => -5, DietStatus.Satisfactory => 5, DietStatus.Balanced => 10, DietStatus.Ideal => 15, _ => 0, }; } internal static bool HasIdealDiet(Player player) { return IsLocalDietPlayer(player) && GetDietStatus(ReadDietState(player)) == DietStatus.Ideal; } internal static float GetIdealStaminaRegenMultiplier(Player player) { return HasIdealDiet(player) ? 1.1f : 1f; } internal static float GetIdealMovementSpeedMultiplier(Player player) { return HasIdealDiet(player) ? 1.1f : 1f; } internal static bool IsLocalPlayerSEMan(object seMan) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || seMan == null) { return false; } try { if (_characterSEMan == null) { _characterSEMan = AccessTools.Field(typeof(Character), "m_seman"); } return _characterSEMan != null && _characterSEMan.GetValue(localPlayer) == seMan; } catch { return false; } } private static bool IsLocalDietPlayer(Player player) { return (Object)(object)player != (Object)null && (Object)(object)Player.m_localPlayer != (Object)null && player == Player.m_localPlayer; } internal static bool TrySetAllNutrients(int value) { if (value < 0 || value > 100) { return false; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return false; } WriteValue(localPlayer, "balanced_diet_protein", value); WriteValue(localPlayer, "balanced_diet_fat", value); WriteValue(localPlayer, "balanced_diet_carbohydrate", value); WriteValue(localPlayer, "balanced_diet_vitamin", value); if (DebugLogs != null && DebugLogs.Value) { Log.LogInfo((object)("Console command set every nutrient to " + value.ToString(CultureInfo.InvariantCulture) + "%.")); } return true; } internal static void HandleConsumedItem(Player player, ItemData item) { if (!((Object)(object)player == (Object)null) && item != null && item.m_shared != null && !((Object)(object)Player.m_localPlayer == (Object)null) && !((Object)(object)player != (Object)(object)Player.m_localPlayer) && BalancedDietFoodValues.TryGet(item, out var nutrients, out var matchedId)) { DietState dietState = ReadDietState(player); WriteValue(player, "balanced_diet_protein", dietState.Protein + nutrients.Protein); WriteValue(player, "balanced_diet_fat", dietState.Fat + nutrients.Fat); WriteValue(player, "balanced_diet_carbohydrate", dietState.Carbohydrate + nutrients.Carbohydrate); WriteValue(player, "balanced_diet_vitamin", dietState.Vitamin + nutrients.Vitamin); if (DebugLogs != null && DebugLogs.Value) { ManualLogSource log = Log; string[] obj = new string[11] { "Consumed ", matchedId, ": protein +", null, null, null, null, null, null, null, null }; int protein = nutrients.Protein; obj[3] = protein.ToString(); obj[4] = "%, fat +"; protein = nutrients.Fat; obj[5] = protein.ToString(); obj[6] = "%, carbohydrates +"; protein = nutrients.Carbohydrate; obj[7] = protein.ToString(); obj[8] = "%, vitamins +"; protein = nutrients.Vitamin; obj[9] = protein.ToString(); obj[10] = "%."; log.LogInfo((object)string.Concat(obj)); } } } } internal static class BalancedDietPatches { internal static void ApplyAll(Harmony harmony) { FoodConsumptionPatch.Apply(harmony); PlayerDeathPatch.Apply(harmony); DietConsoleCommandPatch.Apply(harmony); DietMaximumStatsPatch.Apply(harmony); DietRuntimeMultipliersPatch.Apply(harmony); } } internal static class FoodConsumptionPatch { private static bool _applied; internal static void Apply(Harmony harmony) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected O, but got Unknown if (!_applied && harmony != null) { _applied = true; MethodInfo methodInfo = FindConsumptionMethod(); if (methodInfo == null) { BalancedDietPlugin.Log.LogError((object)"BalancedDiet could not find Player.ConsumeItem/EatFood/AddFood returning bool."); return; } HarmonyMethod val = new HarmonyMethod(typeof(FoodConsumptionPatch), "Postfix", (Type[])null); harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); BalancedDietPlugin.Log.LogInfo((object)("Food consumption patch bound to Player." + methodInfo.Name + ".")); } } private static MethodInfo FindConsumptionMethod() { MethodInfo[] methods = typeof(Player).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); string[] array = new string[3] { "ConsumeItem", "EatFood", "AddFood" }; foreach (string value in array) { foreach (MethodInfo methodInfo in methods) { if (methodInfo == null || !methodInfo.Name.Equals(value, StringComparison.Ordinal) || methodInfo.ReturnType != typeof(bool)) { continue; } ParameterInfo[] parameters = methodInfo.GetParameters(); for (int k = 0; k < parameters.Length; k++) { if (parameters[k].ParameterType == typeof(ItemData)) { return methodInfo; } } } } return null; } public static void Postfix(Player __instance, object[] __args, bool __result) { if (!__result || (Object)(object)__instance == (Object)null || __args == null) { return; } ItemData val = null; foreach (object obj in __args) { val = (ItemData)((obj is ItemData) ? obj : null); if (val != null) { break; } } if (val != null) { BalancedDietPlugin.HandleConsumedItem(__instance, val); } } } internal static class PlayerDeathPatch { private static bool _applied; internal static void Apply(Harmony harmony) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected O, but got Unknown if (!_applied && harmony != null) { _applied = true; MethodInfo methodInfo = FindPlayerDeathMethod(); if (methodInfo == null) { BalancedDietPlugin.Log.LogError((object)"BalancedDiet could not find Player.OnDeath."); return; } HarmonyMethod val = new HarmonyMethod(typeof(PlayerDeathPatch), "Prefix", (Type[])null); harmony.Patch((MethodBase)methodInfo, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); BalancedDietPlugin.Log.LogInfo((object)("Death penalty patch bound to Player." + methodInfo.Name + ".")); } } private static MethodInfo FindPlayerDeathMethod() { MethodInfo[] methods = typeof(Player).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { if (methodInfo != null && methodInfo.Name.Equals("OnDeath", StringComparison.Ordinal) && methodInfo.GetParameters().Length == 0) { return methodInfo; } } return null; } public static void Prefix(Player __instance) { BalancedDietPlugin.HandlePlayerDeath(__instance); } } internal static class DietConsoleCommandPatch { private const string LongCommand = "balanceddiet_set"; private const string ShortCommand = "bd_set"; private static bool _applied; private static MethodInfo _addStringMethod; private static bool _devCommandsReflectionCached; private static FieldInfo _terminalDevCommandsField; private static FieldInfo _consoleDevCommandsField; internal static void Apply(Harmony harmony) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected O, but got Unknown if (!_applied && harmony != null) { _applied = true; CacheDevCommandsReflection(); MethodInfo methodInfo = FindTryRunCommandMethod(); if (methodInfo == null) { BalancedDietPlugin.Log.LogError((object)"BalancedDiet could not find Terminal.TryRunCommand."); return; } HarmonyMethod val = new HarmonyMethod(typeof(DietConsoleCommandPatch), "Prefix", (Type[])null); harmony.Patch((MethodBase)methodInfo, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); BalancedDietPlugin.Log.LogInfo((object)"Console commands registered: balanceddiet_set and bd_set (devcommands required)."); } } private static void CacheDevCommandsReflection() { if (!_devCommandsReflectionCached) { _devCommandsReflectionCached = true; _terminalDevCommandsField = FindDevCommandsField(typeof(Terminal), allowInstanceField: true); Type type = AccessTools.TypeByName("Console"); if (type != null) { _consoleDevCommandsField = FindDevCommandsField(type, allowInstanceField: false); } FieldInfo fieldInfo = _terminalDevCommandsField ?? _consoleDevCommandsField; if (fieldInfo == null) { BalancedDietPlugin.Log.LogWarning((object)"BalancedDiet could not resolve the Valheim devcommands flag. Diet console commands will remain locked."); return; } BalancedDietPlugin.Log.LogInfo((object)("Diet console command access bound to " + fieldInfo.DeclaringType.Name + "." + fieldInfo.Name + ".")); } } private static FieldInfo FindDevCommandsField(Type type, bool allowInstanceField) { if (type == null) { return null; } string[] array = new string[4] { "m_cheat", "m_cheats", "m_devCommands", "m_devcommands" }; for (int i = 0; i < array.Length; i++) { FieldInfo field = type.GetField(array[i], BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (IsUsableDevCommandsField(field, allowInstanceField)) { return field; } } FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { if (IsUsableDevCommandsField(fieldInfo, allowInstanceField)) { string text = fieldInfo.Name.ToLowerInvariant(); if (text.Contains("cheat") || text.Contains("devcommand")) { return fieldInfo; } } } return null; } private static bool IsUsableDevCommandsField(FieldInfo field, bool allowInstanceField) { return field != null && field.FieldType == typeof(bool) && (field.IsStatic || allowInstanceField); } private static bool AreDevCommandsEnabled(Terminal terminal) { CacheDevCommandsReflection(); if (TryReadBooleanField(_terminalDevCommandsField, terminal, out var value)) { return value; } if (TryReadBooleanField(_consoleDevCommandsField, null, out value)) { return value; } return false; } private static bool TryReadBooleanField(FieldInfo field, object instance, out bool value) { value = false; if (field == null || (!field.IsStatic && instance == null)) { return false; } try { object obj = (field.IsStatic ? null : instance); object value2 = field.GetValue(obj); if (value2 is bool) { value = (bool)value2; return true; } } catch { } return false; } private static MethodInfo FindTryRunCommandMethod() { MethodInfo[] methods = typeof(Terminal).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { if (!(methodInfo == null) && methodInfo.Name.Equals("TryRunCommand", StringComparison.Ordinal)) { ParameterInfo[] parameters = methodInfo.GetParameters(); if (parameters.Length != 0 && parameters[0].ParameterType == typeof(string)) { return methodInfo; } } } return null; } public static bool Prefix(Terminal __instance, string __0) { if (string.IsNullOrWhiteSpace(__0)) { return true; } string[] array = __0.Trim().Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (array.Length == 0 || (!array[0].Equals("balanceddiet_set", StringComparison.OrdinalIgnoreCase) && !array[0].Equals("bd_set", StringComparison.OrdinalIgnoreCase))) { return true; } if (!AreDevCommandsEnabled(__instance)) { Reply(__instance, BalancedDietPlugin.Localize("BalancedDiet: enable devcommands first.", "BalancedDiet: сначала включите devcommands.")); return false; } if (array.Length != 2 || !int.TryParse(array[1], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result) || result < 0 || result > 100) { Reply(__instance, BalancedDietPlugin.Localize("BalancedDiet: use ", "BalancedDiet: используйте ") + "balanceddiet_set <0-100>."); return false; } if (!BalancedDietPlugin.TrySetAllNutrients(result)) { Reply(__instance, BalancedDietPlugin.Localize("BalancedDiet: the local player is not loaded yet.", "BalancedDiet: локальный персонаж ещё не загружен.")); return false; } Reply(__instance, BalancedDietPlugin.Localize("BalancedDiet: all nutrients have been set to ", "BalancedDiet: все показатели установлены на ") + result.ToString(CultureInfo.InvariantCulture) + "%."); return false; } private static void Reply(Terminal terminal, string message) { bool flag = false; try { if (_addStringMethod == null) { _addStringMethod = typeof(Terminal).GetMethod("AddString", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(string) }, null); } if ((Object)(object)terminal != (Object)null && _addStringMethod != null) { _addStringMethod.Invoke(terminal, new object[1] { message }); flag = true; } } catch { flag = false; } if (!flag) { BalancedDietPlugin.Log.LogInfo((object)message); } } } internal static class DietMaximumStatsPatch { public struct FoodUpdateState { public bool RestoreStamina; public float StaminaBefore; } private static bool _applied; internal static void Apply(Harmony harmony) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Expected O, but got Unknown //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Expected O, but got Unknown if (!_applied && harmony != null) { _applied = true; DietMaximumStatsRuntime.Initialize(); MethodInfo maxHealthSetter = DietMaximumStatsRuntime.MaxHealthSetter; if (maxHealthSetter == null) { BalancedDietPlugin.Log.LogError((object)"BalancedDiet could not find Character.SetMaxHealth(float)."); } else { HarmonyMethod val = new HarmonyMethod(typeof(DietMaximumStatsPatch), "SetMaxHealthPrefix", (Type[])null); harmony.Patch((MethodBase)maxHealthSetter, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); BalancedDietPlugin.Log.LogInfo((object)("Diet health maximum bound to " + maxHealthSetter.DeclaringType.Name + "." + maxHealthSetter.Name + ".")); } MethodInfo methodInfo = FindUpdateFoodMethod(); if (methodInfo == null) { BalancedDietPlugin.Log.LogWarning((object)"BalancedDiet could not find Player.UpdateFood. Maximum stats will still be synchronized by the plugin update loop."); return; } HarmonyMethod val2 = new HarmonyMethod(typeof(DietMaximumStatsPatch), "Prefix", (Type[])null); HarmonyMethod val3 = new HarmonyMethod(typeof(DietMaximumStatsPatch), "Postfix", (Type[])null); harmony.Patch((MethodBase)methodInfo, val2, val3, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); BalancedDietPlugin.Log.LogInfo((object)("Diet maximum stat refresh bound to Player." + methodInfo.Name + ".")); } } private static MethodInfo FindUpdateFoodMethod() { MethodInfo[] methods = typeof(Player).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); MethodInfo methodInfo = null; foreach (MethodInfo methodInfo2 in methods) { if (!(methodInfo2 == null) && methodInfo2.Name.Equals("UpdateFood", StringComparison.Ordinal) && !(methodInfo2.ReturnType != typeof(void))) { ParameterInfo[] parameters = methodInfo2.GetParameters(); if (parameters.Length == 2 && parameters[0].ParameterType == typeof(float) && parameters[1].ParameterType == typeof(bool)) { return methodInfo2; } if (methodInfo == null) { methodInfo = methodInfo2; } } } return methodInfo; } public static void SetMaxHealthPrefix(object __instance, ref float __0) { DietMaximumStatsRuntime.ModifyHealthMaximum((Player)((__instance is Player) ? __instance : null), ref __0); } public static void Prefix(Player __instance, ref FoodUpdateState __state) { __state = default(FoodUpdateState); if ((Object)(object)__instance == (Object)null || (Object)(object)Player.m_localPlayer == (Object)null || __instance != Player.m_localPlayer) { return; } try { __state.RestoreStamina = true; __state.StaminaBefore = __instance.GetStamina(); } catch { __state.RestoreStamina = false; __state.StaminaBefore = 0f; } } public static void Postfix(Player __instance, FoodUpdateState __state) { DietMaximumStatsRuntime.AfterFoodUpdate(__instance, __state.RestoreStamina, __state.StaminaBefore); } } internal static class DietMaximumStatsRuntime { private const float ComparisonTolerance = 0.001f; private static bool _initialized; private static FieldInfo _maxStaminaField; private static MethodInfo _getMaxHealthMethod; private static MethodInfo _setMaxHealthMethod; private static bool _suppressHealthModifier; private static Player _trackedPlayer; private static bool _healthBaseKnown; private static float _vanillaMaxHealth; private static int _appliedHealthModifier; private static float _lastWrittenMaxHealth; private static bool _staminaTracked; private static int _appliedStaminaModifier; private static float _lastWrittenMaxStamina; internal static MethodInfo MaxHealthSetter { get { Initialize(); return _setMaxHealthMethod; } } internal static void Initialize() { if (!_initialized) { _initialized = true; _getMaxHealthMethod = FindFloatGetter(typeof(Character), "GetMaxHealth"); _setMaxHealthMethod = FindFloatSetter(typeof(Character), "SetMaxHealth"); _maxStaminaField = FindMaximumField(typeof(Player), "m_maxStamina", "stamina"); LogResolvedHealthMethods(); LogResolvedField("stamina", _maxStaminaField); } } internal static void Sync(Player player) { if (!((Object)(object)player == (Object)null) && !((Object)(object)Player.m_localPlayer == (Object)null) && player == Player.m_localPlayer) { Initialize(); if (_trackedPlayer != player) { ForgetPlayer(); _trackedPlayer = player; } SyncHealthMaximum(player); SyncField(player, _maxStaminaField, BalancedDietPlugin.GetStaminaModifier(player), ref _staminaTracked, ref _appliedStaminaModifier, ref _lastWrittenMaxStamina); } } internal static void ModifyHealthMaximum(Player player, ref float vanillaMaximum) { if (!_suppressHealthModifier && !((Object)(object)player == (Object)null) && !((Object)(object)Player.m_localPlayer == (Object)null) && player == Player.m_localPlayer) { EnsureTrackedPlayer(player); float num = vanillaMaximum; int healthModifier = BalancedDietPlugin.GetHealthModifier(player); float lastWrittenMaxHealth = (vanillaMaximum = Mathf.Max(1f, num + (float)healthModifier)); _healthBaseKnown = true; _vanillaMaxHealth = num; _appliedHealthModifier = healthModifier; _lastWrittenMaxHealth = lastWrittenMaxHealth; } } internal static void AfterFoodUpdate(Player player, bool restoreStamina, float staminaBefore) { if ((Object)(object)player == (Object)null || (Object)(object)Player.m_localPlayer == (Object)null || player != Player.m_localPlayer) { return; } float num = 0f; bool flag = false; if (restoreStamina) { try { num = player.GetStamina(); flag = num + 0.001f < staminaBefore; } catch { restoreStamina = false; } } if (flag) { _staminaTracked = false; } Sync(player); if (!restoreStamina || !flag) { return; } try { float num2 = ReadMaximum(player, _maxStaminaField, staminaBefore); float num3 = Mathf.Min(staminaBefore, num2); float stamina = player.GetStamina(); if (stamina + 0.001f < num3) { ((Character)player).AddStamina(num3 - stamina); } } catch { } } internal static void RestoreTrackedMaximums(Player player) { if ((Object)(object)player == (Object)null || player != _trackedPlayer) { ForgetPlayer(); return; } RestoreHealthMaximum(player); RemoveAppliedModifier(player, _maxStaminaField, ref _staminaTracked, ref _appliedStaminaModifier, ref _lastWrittenMaxStamina); ForgetPlayer(); } internal static void ForgetPlayer() { _trackedPlayer = null; _healthBaseKnown = false; _vanillaMaxHealth = 0f; _appliedHealthModifier = 0; _lastWrittenMaxHealth = 0f; _staminaTracked = false; _appliedStaminaModifier = 0; _lastWrittenMaxStamina = 0f; } private static void EnsureTrackedPlayer(Player player) { if (_trackedPlayer != player) { ForgetPlayer(); _trackedPlayer = player; } } private static void SyncHealthMaximum(Player player) { if (_getMaxHealthMethod == null || _setMaxHealthMethod == null) { return; } int healthModifier = BalancedDietPlugin.GetHealthModifier(player); if (!_healthBaseKnown) { try { object obj = _getMaxHealthMethod.Invoke(player, new object[0]); if (obj is float) { _vanillaMaxHealth = (float)obj; _healthBaseKnown = true; WriteHealthMaximum(player, _vanillaMaxHealth, healthModifier); } return; } catch (Exception ex) { BalancedDietPlugin.Log.LogError((object)("BalancedDiet could not read maximum health: " + ex.Message)); return; } } if (healthModifier != _appliedHealthModifier) { WriteHealthMaximum(player, _vanillaMaxHealth, healthModifier); } } private static void WriteHealthMaximum(Player player, float vanillaMaximum, int modifier) { if (_setMaxHealthMethod == null) { return; } float num = Mathf.Max(1f, vanillaMaximum + (float)modifier); try { _suppressHealthModifier = true; _setMaxHealthMethod.Invoke(player, new object[1] { num }); _healthBaseKnown = true; _vanillaMaxHealth = vanillaMaximum; _appliedHealthModifier = modifier; _lastWrittenMaxHealth = num; } catch (Exception ex) { BalancedDietPlugin.Log.LogError((object)("BalancedDiet could not write maximum health: " + ex.Message)); } finally { _suppressHealthModifier = false; } } private static void RestoreHealthMaximum(Player player) { if (!_healthBaseKnown || _setMaxHealthMethod == null) { return; } try { _suppressHealthModifier = true; _setMaxHealthMethod.Invoke(player, new object[1] { Mathf.Max(1f, _vanillaMaxHealth) }); } catch { } finally { _suppressHealthModifier = false; } } private static void SyncField(Player player, FieldInfo field, int desiredModifier, ref bool tracked, ref int appliedModifier, ref float lastWrittenMaximum) { if (field == null) { return; } try { if (field.GetValue(player) is float num) { float num2 = ((!tracked || !(Mathf.Abs(num - lastWrittenMaximum) <= 0.001f)) ? num : (num - (float)appliedModifier)); float num3 = Mathf.Max(1f, num2 + (float)desiredModifier); if (Mathf.Abs(num - num3) > 0.001f) { field.SetValue(player, num3); } tracked = true; appliedModifier = desiredModifier; lastWrittenMaximum = num3; } } catch (Exception ex) { tracked = false; BalancedDietPlugin.Log.LogError((object)("BalancedDiet could not synchronize " + field.Name + ": " + ex.Message)); } } private static void RemoveAppliedModifier(Player player, FieldInfo field, ref bool tracked, ref int appliedModifier, ref float lastWrittenMaximum) { if (field == null || !tracked) { tracked = false; appliedModifier = 0; lastWrittenMaximum = 0f; return; } try { if (field.GetValue(player) is float num && Mathf.Abs(num - lastWrittenMaximum) <= 0.001f) { field.SetValue(player, Mathf.Max(1f, num - (float)appliedModifier)); } } catch { } tracked = false; appliedModifier = 0; lastWrittenMaximum = 0f; } private static float ReadMaximum(Player player, FieldInfo field, float fallback) { if ((Object)(object)player == (Object)null || field == null) { return fallback; } object value = field.GetValue(player); return (value is float) ? ((float)value) : fallback; } private static MethodInfo FindFloatGetter(Type startingType, string methodName) { MethodInfo[] methods = startingType.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { if (methodInfo != null && methodInfo.Name.Equals(methodName, StringComparison.Ordinal) && methodInfo.ReturnType == typeof(float) && methodInfo.GetParameters().Length == 0) { return methodInfo; } } return null; } private static MethodInfo FindFloatSetter(Type startingType, string methodName) { MethodInfo[] methods = startingType.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { if (!(methodInfo == null) && methodInfo.Name.Equals(methodName, StringComparison.Ordinal) && !(methodInfo.ReturnType != typeof(void))) { ParameterInfo[] parameters = methodInfo.GetParameters(); if (parameters.Length == 1 && parameters[0].ParameterType == typeof(float)) { return methodInfo; } } } return null; } private static FieldInfo FindMaximumField(Type startingType, string preferredName, string requiredNamePart) { Type type = startingType; while (type != null) { FieldInfo field = type.GetField(preferredName, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null && field.FieldType == typeof(float)) { return field; } type = type.BaseType; } type = startingType; while (type != null) { FieldInfo[] fields = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { if (fieldInfo != null && fieldInfo.FieldType == typeof(float) && fieldInfo.Name.IndexOf("max", StringComparison.OrdinalIgnoreCase) >= 0 && fieldInfo.Name.IndexOf(requiredNamePart, StringComparison.OrdinalIgnoreCase) >= 0) { return fieldInfo; } } type = type.BaseType; } return null; } private static void LogResolvedHealthMethods() { if (_getMaxHealthMethod == null || _setMaxHealthMethod == null) { BalancedDietPlugin.Log.LogError((object)"BalancedDiet could not resolve Character health maximum methods."); return; } BalancedDietPlugin.Log.LogInfo((object)("Diet health maximum synchronized through " + _setMaxHealthMethod.DeclaringType.Name + "." + _setMaxHealthMethod.Name + ".")); } private static void LogResolvedField(string statName, FieldInfo field) { if (field == null) { BalancedDietPlugin.Log.LogError((object)("BalancedDiet could not find the internal maximum " + statName + " field.")); return; } BalancedDietPlugin.Log.LogInfo((object)("Diet " + statName + " maximum synchronized through " + field.DeclaringType.Name + "." + field.Name + ".")); } } internal static class DietRuntimeMultipliersPatch { private static bool _applied; internal static void Apply(Harmony harmony) { if (!_applied && harmony != null) { _applied = true; PatchMovementSpeed(harmony, "GetJogSpeedFactor"); PatchMovementSpeed(harmony, "GetRunSpeedFactor"); PatchStaminaRegen(harmony); } } private static void PatchMovementSpeed(Harmony harmony, string methodName) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown MethodInfo methodInfo = FindPlayerFloatGetter(methodName); if (methodInfo == null) { BalancedDietPlugin.Log.LogError((object)("BalancedDiet could not find Player." + methodName + " returning float.")); return; } HarmonyMethod val = new HarmonyMethod(typeof(DietRuntimeMultipliersPatch), "MovementSpeedPostfix", (Type[])null); harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); BalancedDietPlugin.Log.LogInfo((object)("Ideal diet movement bonus bound to Player." + methodInfo.Name + ".")); } private static void PatchStaminaRegen(Harmony harmony) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown MethodInfo methodInfo = FindStaminaRegenMethod(); if (methodInfo == null) { BalancedDietPlugin.Log.LogError((object)"BalancedDiet could not find SEMan.ModifyStaminaRegen."); return; } HarmonyMethod val = new HarmonyMethod(typeof(DietRuntimeMultipliersPatch), "StaminaRegenPostfix", (Type[])null); harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); BalancedDietPlugin.Log.LogInfo((object)"Ideal diet stamina regeneration bonus bound to SEMan.ModifyStaminaRegen."); } private static MethodInfo FindPlayerFloatGetter(string methodName) { MethodInfo[] methods = typeof(Player).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { if (methodInfo != null && methodInfo.Name.Equals(methodName, StringComparison.Ordinal) && methodInfo.ReturnType == typeof(float) && methodInfo.GetParameters().Length == 0) { return methodInfo; } } return null; } private static MethodInfo FindStaminaRegenMethod() { MethodInfo[] methods = typeof(SEMan).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { if (!(methodInfo == null) && methodInfo.Name.Equals("ModifyStaminaRegen", StringComparison.Ordinal)) { ParameterInfo[] parameters = methodInfo.GetParameters(); if (FindRefFloatIndex(parameters) >= 0) { return methodInfo; } } } return null; } public static void MovementSpeedPostfix(Player __instance, ref float __result) { float idealMovementSpeedMultiplier = BalancedDietPlugin.GetIdealMovementSpeedMultiplier(__instance); if (idealMovementSpeedMultiplier > 1f) { __result *= idealMovementSpeedMultiplier; } } public static void StaminaRegenPostfix(object __instance, MethodBase __originalMethod, object[] __args) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || !BalancedDietPlugin.IsLocalPlayerSEMan(__instance) || __originalMethod == null || __args == null) { return; } int num = FindRefFloatIndex(__originalMethod.GetParameters()); if (num >= 0 && num < __args.Length && __args[num] is float) { float num2 = (float)__args[num]; float idealStaminaRegenMultiplier = BalancedDietPlugin.GetIdealStaminaRegenMultiplier(localPlayer); if (idealStaminaRegenMultiplier > 1f) { __args[num] = num2 * idealStaminaRegenMultiplier; } } } private static int FindRefFloatIndex(ParameterInfo[] parameters) { if (parameters == null) { return -1; } Type type = typeof(float).MakeByRefType(); for (int i = 0; i < parameters.Length; i++) { if (parameters[i] != null && parameters[i].ParameterType == type) { return i; } } return -1; } }