Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of BalancedDiet v1.0.0
plugins/BalancedDiet.dll
Decompiled 2 days agousing 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<string, FoodNutrients> Values; static BalancedDietFoodValues() { Values = new Dictionary<string, FoodNutrients>(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<float> UiScale; private static ConfigEntry<bool> CloseOnEscape; private static ConfigEntry<bool> 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<float>("UI", "UiScale", 1f, Localize("Diet window scale.", "Масштаб окна системы питания.")); CloseOnEscape = ((BaseUnityPlugin)this).Config.Bind<bool>("UI", "CloseOnEscape", true, Localize("Close the diet window with Escape.", "Закрывать окно клавишей Escape.")); DebugLogs = ((BaseUnityPlugin)this).Config.Bind<bool>("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<GUILayoutOption>()); GUILayout.Label(Localize("VIKING NUTRITION", "ПИТАНИЕ ВИКИНГА"), _titleStyle, Array.Empty<GUILayoutOption>()); GUILayout.Label(Localize("NUTRIENT BALANCE", "БАЛАНС НУТРИЕНТОВ"), _subtitleStyle, Array.Empty<GUILayoutOption>()); 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>B</b> open / close", "<b>B</b> открыть / закрыть"), _footerStyle, Array.Empty<GUILayoutOption>()); GUILayout.FlexibleSpace(); if (CloseOnEscape.Value) { GUILayout.Label(Localize("<b>ESC</b> close", "<b>ESC</b> закрыть"), _footerStyle, Array.Empty<GUILayoutOption>()); 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("<color=#83C97A>TARGET REACHED</color>", "<color=#83C97A>НОРМА ДОСТИГНУТА</color>") : (Localize("<color=#E7836E>MISSING ", "<color=#E7836E>НЕ ХВАТАЕТ ") + num.ToString(CultureInfo.InvariantCulture) + "%</color>"), _rowHintStyle, Array.Empty<GUILayoutOption>()); GUILayout.FlexibleSpace(); GUILayout.Label(Localize("threshold 30%", "порог 30%"), _rowHintStyle, Array.Empty<GUILayoutOption>()); 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<string, string>(); } 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("<color=#E7836E>DEPLETION</color>", "<color=#E7836E>ИСТОЩЕНИЕ</color>"), DietStatus.Unbalanced => Localize("<color=#E5A653>UNBALANCED DIET</color>", "<color=#E5A653>НЕСБАЛАНСИРОВАННОЕ ПИТАНИЕ</color>"), DietStatus.Satisfactory => Localize("<color=#D8C766>SATISFACTORY DIET</color>", "<color=#D8C766>УДОВЛЕТВОРИТЕЛЬНОЕ ПИТАНИЕ</color>"), DietStatus.Balanced => Localize("<color=#83C97A>BALANCED DIET</color>", "<color=#83C97A>СБАЛАНСИРОВАННОЕ ПИТАНИЕ</color>"), DietStatus.Ideal => Localize("<color=#74C9D6>IDEAL DIET</color>", "<color=#74C9D6>ИДЕАЛЬНОЕ ПИТАНИЕ</color>"), _ => Localize("<color=#B8B8B8>UNKNOWN STATUS</color>", "<color=#B8B8B8>НЕИЗВЕСТНЫЙ СТАТУС</color>"), }; } 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("<color=#E7836E>-10 health, -10 stamina</color>", "<color=#E7836E>-10 здоровья, -10 выносливости</color>"), DietStatus.Unbalanced => Localize("<color=#E5A653>-5 health, -5 stamina</color>", "<color=#E5A653>-5 здоровья, -5 выносливости</color>"), DietStatus.Satisfactory => Localize("<color=#D8C766>+5 health, +5 stamina</color>", "<color=#D8C766>+5 здоровья, +5 выносливости</color>"), DietStatus.Balanced => Localize("<color=#83C97A>+10 health, +10 stamina</color>", "<color=#83C97A>+10 здоровья, +10 выносливости</color>"), DietStatus.Ideal => Localize("<color=#74C9D6>+15 health, +15 stamina, +10% stamina regeneration, +10% movement speed</color>", "<color=#74C9D6>+15 здоровья, +15 выносливости, +10% восстановления выносливости, +10% скорости</color>"), _ => Localize("<color=#B8B8B8>No effect</color>", "<color=#B8B8B8>Нет эффекта</color>"), }; } 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; } }