Decompiled source of Nivalis Unofficial Patch v0.3.61
BepInEx/plugins/NivalisUnofficialPatch/NivalisUnofficialPatch.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Buffers.Binary; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.ExceptionServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using System.Text.Json; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using BepInEx.Unity.IL2CPP.Hook; using CrazyMinnow.SALSA; using DG.Tweening; using DG.Tweening.Core; using DG.Tweening.Plugins.Options; using Funly.SkyStudio; using HarmonyLib; using Hvizeu.NivalisMods; using Il2CppInterop.Runtime; using Il2CppInterop.Runtime.Attributes; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppInterop.Runtime.Runtime; using Il2CppInterop.Runtime.Runtime.VersionSpecific.MethodInfo; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using Il2CppSystem.Reflection; using MagicaCloth; using Microsoft.CodeAnalysis; using MonoMod.RuntimeDetour; using Nivalis; using Nivalis.CraftingSystem; using Nivalis.DayNightCycle; using Nivalis.Dialogue; using Nivalis.Economy; using Nivalis.GhostSystem; using Nivalis.GhostSystem.Ai; using Nivalis.GhostSystem.CustomerLoop; using Nivalis.InventorySystem; using Nivalis.Locale; using Nivalis.Locale.UI; using Nivalis.Localization; using Nivalis.Player; using Nivalis.SkillSystem; using Nivalis.UI; using Nivalis.UI.Concrete; using Nivalis.UI.Greenhouse; using Nivalis.UI.InGameMenu; using Nivalis.UI.MinMaxSlider; using Nivalis.Utility; using Nivalis.Weather; using NivalisUnofficialPatch.Core; using NivalisUnofficialPatch.Hauling; using RootMotion.FinalIK; using TMPro; using TheraBytes.BetterUi; using UnityEngine; using UnityEngine.AI; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Utilities; using UnityEngine.Rendering; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("Hvizeu")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.3.61.0")] [assembly: AssemblyInformationalVersion("0.3.61")] [assembly: AssemblyProduct("NivalisUnofficialPatch")] [assembly: AssemblyTitle("NivalisUnofficialPatch")] [assembly: AssemblyMetadata("PrivateDiagnosticsBuild", "false")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.3.61.0")] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NativeIntegerAttribute : Attribute { public readonly bool[] TransformFlags; public NativeIntegerAttribute() { TransformFlags = new bool[1] { true }; } public NativeIntegerAttribute(bool[] P_0) { TransformFlags = P_0; } } } namespace Hvizeu.NivalisMods { internal static class CharacterClearance { internal static void Volume(Character character, out Vector3 lower, out Vector3 upper, out float radius) { //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0139: 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_0031: 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_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_016c: 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_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: 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_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) Collider collide = character.Collide; CapsuleCollider val = ((collide != null) ? ((Il2CppObjectBase)collide).TryCast<CapsuleCollider>() : null); Vector3 val2; float num; if ((Object)(object)val != (Object)null && val.direction == 1) { Vector3 lossyScale = ((Component)val).transform.lossyScale; val2 = ((Component)val).transform.TransformPoint(val.center); radius = val.radius * Mathf.Max(Mathf.Abs(lossyScale.x), Mathf.Abs(lossyScale.z)); num = val.height * Mathf.Abs(lossyScale.y); } else { if ((Object)(object)collide != (Object)null && collide.enabled) { Bounds bounds = collide.bounds; Vector3 size = ((Bounds)(ref bounds)).size; if (((Vector3)(ref size)).sqrMagnitude > 0.01f) { Bounds bounds2 = collide.bounds; val2 = ((Bounds)(ref bounds2)).center; radius = Mathf.Max(((Bounds)(ref bounds2)).extents.x, ((Bounds)(ref bounds2)).extents.z); num = ((Bounds)(ref bounds2)).size.y; goto IL_013a; } } NavMeshAgent agent = character.Movement.Agent; radius = agent.radius; num = agent.height; val2 = ((BaseCharacter)character).ThisTransform.position + Vector3.up * (num * 0.5f + agent.baseOffset); } goto IL_013a; IL_013a: radius = Mathf.Max(0.1f, radius); float num2 = Mathf.Max(0f, num * 0.5f - radius); lower = val2 - Vector3.up * num2; upper = val2 + Vector3.up * num2; } internal static bool Blocks(Character character, Collider collider) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) Character componentInParent = ((Component)collider).GetComponentInParent<Character>(); if ((Object)(object)componentInParent != (Object)null) { return ((Il2CppObjectBase)componentInParent).Pointer != ((Il2CppObjectBase)character).Pointer; } Collider collide = character.Collide; if ((Object)(object)collide == (Object)null) { return true; } int layer = ((Component)collider).gameObject.layer; if (Singleton<CharacterManager>.InstanceExist() && (LayerMask.op_Implicit(Singleton<CharacterManager>.Instance.EnvironmentLayer) & (1 << layer)) != 0) { return true; } return !Physics.GetIgnoreLayerCollision(((Component)collide).gameObject.layer, layer); } } } namespace NivalisUnofficialPatch { [HarmonyPatch(typeof(Character), "DoLateUpdate")] internal static class AnimationLodPatch { private static bool failed; private static bool Prepare() { return PerformanceCompatibility.Owns(PerformanceFeature.Animation); } private static void Prefix(Character __instance, out int __state) { __state = 0; if (failed || !PerformanceCompatibility.Owns(PerformanceFeature.Animation)) { return; } try { float value = RenderingOptions.AnimationLodReduction.Value; if (!(value <= 0f) && __instance.AnimatorUpdateStep <= 0 && ((BaseCharacter)__instance).CameraVisible) { __state = AnimationLodPolicy.Step(((BaseCharacter)__instance).SqrVisibleDistance, value); } } catch (Exception ex) { failed = true; PerformanceCompatibility.Health(PerformanceFeature.Animation, ex.Message); ModFaults.Report("Animation cadence (disabled for session)", ex); } } private static void Postfix(Character __instance, int __state) { try { if (__state > 0 && !failed) { __instance.AnimatorUpdateStep = RuntimePerformance.Stagger(__instance, __state); } } catch (Exception ex) { failed = true; PerformanceCompatibility.Health(PerformanceFeature.Animation, ex.Message); ModFaults.Report("Animation cadence (disabled for session)", ex); } } } internal static class AvaVoice { private sealed record VoiceSource(AudioSource Source, bool OriginalMute); internal const string PersonGuid = "7aa86416-295d-40ad-a22b-3eb7a32c638f"; private static readonly Dictionary<int, VoiceSource> Sources = new Dictionary<int, VoiceSource>(); private static AudioSource? phoneSource; internal static bool Enabled; internal static AudioSource? CharacterSource(CharacterCommunication character) { if (!((Object)(object)character != (Object)null) || !((Object)(object)character.Salsa != (Object)null)) { return null; } return character.Salsa.audioSrc; } internal static void BeginPhone(NewPageShownArgs line) { AudioSource inEarVOSource = AudioHandler.InEarVOSource; if ((Object)(object)phoneSource != (Object)(object)inEarVOSource) { Release(phoneSource); } phoneSource = inEarVOSource; Begin(inEarVOSource, line, line != null && line.isPhoneCall); } internal static void ReleasePhone() { Release(phoneSource); phoneSource = null; } internal static void Begin(AudioSource? source, NewPageShownArgs? line, bool audiblePath = true) { if ((Object)(object)source == (Object)null) { return; } KeyValuePair<int, VoiceSource>[] array = Sources.ToArray(); for (int i = 0; i < array.Length; i++) { KeyValuePair<int, VoiceSource> keyValuePair = array[i]; if ((Object)(object)keyValuePair.Value.Source == (Object)null) { Sources.Remove(keyValuePair.Key); } } object obj; if (line == null) { obj = null; } else { DialogueStepDisplayData dialogue = line.dialogue; obj = ((dialogue != null) ? dialogue.Speaker : null); } Person val = (Person)obj; if (!audiblePath || !((Object)(object)val != (Object)null) || !string.Equals(val.Guid, "7aa86416-295d-40ad-a22b-3eb7a32c638f", StringComparison.OrdinalIgnoreCase)) { Release(source); return; } int instanceID = ((Object)source).GetInstanceID(); if (!Sources.TryGetValue(instanceID, out VoiceSource value)) { Sources.Add(instanceID, value = new VoiceSource(source, source.mute)); } source.mute = value.OriginalMute || Enabled; } internal static void Apply(bool enabled) { Enabled = enabled; KeyValuePair<int, VoiceSource>[] array = Sources.ToArray(); for (int i = 0; i < array.Length; i++) { KeyValuePair<int, VoiceSource> keyValuePair = array[i]; if ((Object)(object)keyValuePair.Value.Source == (Object)null) { Sources.Remove(keyValuePair.Key); } else { keyValuePair.Value.Source.mute = keyValuePair.Value.OriginalMute || enabled; } } } internal static void Release(AudioSource? source) { if ((Object)(object)source != (Object)null && Sources.Remove(((Object)source).GetInstanceID(), out VoiceSource value)) { source.mute = value.OriginalMute; } } internal static void Clear() { foreach (VoiceSource value in Sources.Values) { if ((Object)(object)value.Source != (Object)null) { value.Source.mute = value.OriginalMute; } } Sources.Clear(); phoneSource = null; } } [HarmonyPatch(typeof(DialoguePhoneAudioPlayer), "OnNewDialogueLine")] internal static class AvaPhoneVoicePatch { internal static void Prefix(NewPageShownArgs obj) { AvaVoice.BeginPhone(obj); } } [HarmonyPatch(typeof(DialoguePhoneAudioPlayer), "OnDialogueEnd")] internal static class AvaPhoneVoiceEndPatch { internal static void Postfix() { AvaVoice.ReleasePhone(); } } [HarmonyPatch(typeof(DialoguePhoneAudioPlayer), "OnDestroy")] internal static class AvaPhoneVoiceDestroyPatch { internal static void Prefix() { AvaVoice.ReleasePhone(); } } [HarmonyPatch(typeof(CharacterCommunication), "StartTalk")] internal static class AvaCharacterVoicePatch { internal static void Prefix(CharacterCommunication __instance, NewPageShownArgs lineArgs) { AvaVoice.Begin(AvaVoice.CharacterSource(__instance), lineArgs); } } [HarmonyPatch(typeof(CharacterCommunication), "OnPostRelease")] internal static class AvaCharacterVoiceReleasePatch { internal static void Postfix(CharacterCommunication __instance) { AvaVoice.Release(AvaVoice.CharacterSource(__instance)); } } internal static class BalancedDetailOptimizations { private sealed class ChangedLod { internal LODGroup Group; internal LOD[] Original; } private static readonly Dictionary<int, ChangedLod> lods = new Dictionary<int, ChangedLod>(); private static readonly Dictionary<int, BaseCloth> cloth = new Dictionary<int, BaseCloth>(); private static readonly List<int> retired = new List<int>(); internal static int LodCount => lods.Count; internal static int ClothCount => cloth.Count; internal static void Inspect(LODGroup group) { //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009f: 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) if (!RenderingOptions.BalancedDetailEnabled || (Object)(object)group == (Object)null || lods.ContainsKey(((Object)group).GetInstanceID())) { return; } LOD[] array = ((IEnumerable<LOD>)group.GetLODs()).ToArray(); Character component = ((Component)group).GetComponent<Character>(); bool flag = (Object)(object)component != (Object)null && (Object)(object)component.LODGroup == (Object)(object)group; if (!flag && array.Any((LOD l) => ((IEnumerable<Renderer>)l.renderers).Any((Renderer r) => (Object)(object)r == (Object)null || (Object)(object)((Il2CppObjectBase)r).TryCast<MeshRenderer>() == (Object)null))) { return; } Vector3 lossyScale = ((Component)group).transform.lossyScale; float worldSize = group.size * Math.Max(Math.Abs(lossyScale.x), Math.Max(Math.Abs(lossyScale.y), Math.Abs(lossyScale.z))); float[] heights = BalancedDetailPolicy.Heights(((Object)((Component)group).gameObject).name, worldSize, array.Select((LOD l) => l.screenRelativeTransitionHeight).ToArray(), flag, RenderingOptions.AppliedDetailStrength); if (heights != null) { LOD[] array2 = ((IEnumerable<LOD>)array).Select((Func<LOD, int, LOD>)((LOD l, int i) => new LOD(heights[i], Il2CppReferenceArray<Renderer>.op_Implicit(((IEnumerable<Renderer>)l.renderers).ToArray())) { fadeTransitionWidth = l.fadeTransitionWidth })).ToArray(); lods.Add(((Object)group).GetInstanceID(), new ChangedLod { Group = group, Original = array }); group.SetLODs(Il2CppReferenceArray<LOD>.op_Implicit(array2)); } } internal static void Inspect(Character character) { if (!RenderingOptions.BalancedDetailEnabled || (Object)(object)character == (Object)null || character.magicaCloth == null) { return; } Enumerator<BaseCloth> enumerator = character.magicaCloth.GetEnumerator(); while (enumerator.MoveNext()) { BaseCloth current = enumerator.Current; if (!((Object)(object)current == (Object)null) && !cloth.ContainsKey(((Object)current).GetInstanceID()) && BalancedDetailPolicy.MissingClothLimit(((Object)((Component)character).gameObject).name, ((Object)((Component)current).gameObject).name, current.DistanceDisable_Active, current.DistanceDisable_Distance, current.DistanceDisable_FadeDistance)) { cloth.Add(((Object)current).GetInstanceID(), current); current.DistanceDisable_Active = true; } } } internal static void Prune() { retired.Clear(); foreach (KeyValuePair<int, ChangedLod> lod in lods) { if ((Object)(object)lod.Value.Group == (Object)null) { retired.Add(lod.Key); } } foreach (int item in retired) { lods.Remove(item); } retired.Clear(); foreach (KeyValuePair<int, BaseCloth> item2 in cloth) { if ((Object)(object)item2.Value == (Object)null) { retired.Add(item2.Key); } } foreach (int item3 in retired) { cloth.Remove(item3); } retired.Clear(); } internal static bool OwnsLod(int id) { return lods.ContainsKey(id); } internal static void Stop() { KeyValuePair<int, ChangedLod>[] array = lods.ToArray(); for (int i = 0; i < array.Length; i++) { KeyValuePair<int, ChangedLod> entry = array[i]; if (!DistantCharacterMeshes.OwnsLod(entry.Key) && RenderingOptimizations.TryRestore($"balanced LOD {entry.Key}", delegate { if ((Object)(object)entry.Value.Group != (Object)null) { entry.Value.Group.SetLODs(Il2CppReferenceArray<LOD>.op_Implicit(entry.Value.Original)); } })) { lods.Remove(entry.Key); } } KeyValuePair<int, BaseCloth>[] array2 = cloth.ToArray(); for (int i = 0; i < array2.Length; i++) { KeyValuePair<int, BaseCloth> entry2 = array2[i]; if (RenderingOptimizations.TryRestore($"cloth {entry2.Key}", delegate { if ((Object)(object)entry2.Value != (Object)null) { entry2.Value.DistanceDisable_Active = false; } })) { cloth.Remove(entry2.Key); } } } } internal static class BusinessReminders { internal static ConfigEntry<bool> Hide; internal static void Bind(ConfigFile config) { //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Expected O, but got Unknown bool flag = true; string text = Path.Combine(Paths.ConfigPath, "hvizeu.nivalis.trackedquestshud.cfg"); try { if (File.Exists(text) && new FileInfo(text).Length <= 65536) { string text2 = ""; foreach (string item in File.ReadLines(text)) { string text3 = item.Trim(); if (text3.StartsWith('[') && text3.EndsWith(']')) { string text4 = text3; text2 = text4.Substring(1, text4.Length - 1 - 1); } if (!(text2 != "HUD")) { string[] array = text3.Split('=', 2); if (array.Length == 2 && array[0].Trim() == "HideBusinessReminders" && bool.TryParse(array[1].Trim(), out var result)) { flag = result; } } } } } catch (Exception ex) { ManualLogSource modLog = Plugin.ModLog; bool flag2 = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(53, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Could not read retired HUD preference; default used: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message); } modLog.LogWarning(val); } Hide = config.Bind<bool>("HUD", "HideBusinessReminders", flag, "Hide automatic business reminders on the HUD. Native quest filtering remains authoritative."); } } [HarmonyPatch(typeof(ActiveJournalEntriesUi), "Refresh")] internal static class BusinessReminderRefresh { private sealed class HiddenState { internal readonly List<GameObject> Rows = new List<GameObject>(); internal float? Alpha; } private static readonly Dictionary<int, HiddenState> hidden = new Dictionary<int, HiddenState>(); internal static void RefreshVisible() { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown if (ApplicationState.IsQuitting) { return; } try { foreach (ActiveJournalEntriesUi item in Object.FindObjectsOfType<ActiveJournalEntriesUi>(true)) { if ((Object)(object)item != (Object)null) { item.Refresh(); } } } catch (Exception ex) { ManualLogSource modLog = Plugin.ModLog; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(34, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Business reminder refresh failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex); } modLog.LogError(val); } } internal static void RestoreVisible() { foreach (ActiveJournalEntriesUi item in Object.FindObjectsOfType<ActiveJournalEntriesUi>(true)) { if ((Object)(object)item != (Object)null) { Prefix(item, __runOriginal: true); } } hidden.Clear(); } internal static void Forget(ActiveJournalEntriesUi ui) { hidden.Remove(((Object)ui).GetInstanceID()); } [HarmonyPrefix] internal static void Prefix(ActiveJournalEntriesUi __instance, bool __runOriginal) { if (!__runOriginal || !hidden.Remove(((Object)__instance).GetInstanceID(), out HiddenState value)) { return; } foreach (GameObject row in value.Rows) { if ((Object)(object)row != (Object)null) { row.SetActive(true); } } float? alpha = value.Alpha; if (alpha.HasValue) { float valueOrDefault = alpha.GetValueOrDefault(); if ((Object)(object)__instance.entriesGroup != (Object)null && __instance.entriesGroup.alpha == 0f) { __instance.entriesGroup.alpha = valueOrDefault; } } } [HarmonyPostfix] [HarmonyPriority(0)] internal static void Postfix(ActiveJournalEntriesUi __instance, bool __runOriginal) { if (!__runOriginal || ApplicationState.IsQuitting || !((UIPanel)__instance).IsVisible || !BusinessReminders.Hide.Value || (Object)(object)__instance.entriesGroup == (Object)null || (Object)(object)__instance.questList == (Object)null || (Object)(object)__instance.venueQuestList == (Object)null) { return; } HiddenState hiddenState = new HiddenState(); ItemListUI venueQuestList = __instance.venueQuestList; for (int i = 0; i < venueQuestList.DisplayedCount; i++) { GameObject gameObject = venueQuestList.GetItem(i).GameObject; if (gameObject.activeSelf) { hiddenState.Rows.Add(gameObject); gameObject.SetActive(false); } } bool flag = false; for (int j = 0; j < __instance.questList.DisplayedCount; j++) { flag |= __instance.questList.GetItem(j).GameObject.activeSelf; } if (!flag && __instance.entriesGroup.alpha != 0f) { hiddenState.Alpha = __instance.entriesGroup.alpha; __instance.entriesGroup.alpha = 0f; } if (hiddenState.Rows.Count != 0 || hiddenState.Alpha.HasValue) { hidden[((Object)__instance).GetInstanceID()] = hiddenState; if (hiddenState.Rows.Count != 0) { LayoutRebuilder.ForceRebuildLayoutImmediate(__instance.entryParent); } } } } [HarmonyPatch(typeof(ActiveJournalEntriesUi), "ShowAnimated")] internal static class BusinessReminderShow { private static void Postfix(ActiveJournalEntriesUi __instance) { if (!ApplicationState.IsQuitting && ((UIPanel)__instance).IsVisible) { __instance.Refresh(); } } } [HarmonyPatch(typeof(ActiveJournalEntriesUi), "OnDestroy")] internal static class BusinessReminderDestroy { private static void Prefix(ActiveJournalEntriesUi __instance) { BusinessReminderRefresh.Forget(__instance); } } [HarmonyPatch(typeof(CharacterMovement), "Side")] internal static class ChairExitPatch { internal static long Recovered; private static int unresolvedReports; private static bool Prefix(CharacterMovement __instance, TransitionType transition, ref float __result) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) try { return ChooseExit(__instance, transition, ref __result); } catch (Exception error) { ModFaults.Report("Chair exit selection", error); return true; } } private static bool ChooseExit(CharacterMovement __instance, TransitionType transition, ref float __result) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_005b: 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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0124: 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_0152: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0306: Unknown result type (might be due to invalid IL or missing references) //IL_030d: Expected O, but got Unknown //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_036e: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Expected O, but got Unknown //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Unknown result type (might be due to invalid IL or missing references) if ((int)transition != 1) { return true; } Character character = __instance.character; if ((Object)(object)character == (Object)null) { return true; } AISpot previousSpot = character.previousSpot; Il2CppArrayBase<AISlot> val = ((Spot<AISlot>)(object)previousSpot)?.points; NavMeshAgent agent = __instance.Agent; if ((Object)(object)previousSpot == (Object)null || val == null || (Object)(object)agent == (Object)null || !Singleton<CharacterManager>.InstanceExist()) { return true; } Vector3 origin = ((Component)__instance).transform.position; int environment = LayerMask.op_Implicit(Singleton<CharacterManager>.Instance.EnvironmentLayer); string blocker = "unknown"; NavMeshHit val3 = default(NavMeshHit); foreach (AISlot item in val) { if (item == null) { return true; } Vector3 val2 = CharacterUtils.TransformPointUnscaled(((Component)previousSpot).transform, ((Slot)item).position); if (NavMesh.SamplePosition(val2, ref val3, 0.2f, -1) && NativeClear(val2)) { return true; } } string text = "no authored exit slots"; NavMeshHit val5 = default(NavMeshHit); bool flag = default(bool); foreach (AISlot item2 in val) { Vector3 val4 = CharacterUtils.TransformPointUnscaled(((Component)previousSpot).transform, ((Slot)item2).position); if (!NavMesh.SamplePositionFilter(val4, ref val5, 0.45f, agent.agentTypeID, agent.areaMask)) { text = "no matching NavMesh near authored exit"; continue; } if (Mathf.Abs(((NavMeshHit)(ref val5)).position.y - val4.y) > 0.2f) { text = "authored exit projects to a different height"; continue; } if (!NativeClear(val4)) { text = "native exit sweep blocked by environment"; continue; } if (((Component)previousSpot).transform.InverseTransformPoint(((NavMeshHit)(ref val5)).position).x <= 0f != ((Slot)item2).position.x <= 0f) { text = "NavMesh projects across the chair center"; continue; } string text2 = SceneLifecyclePatches.ProjectionObstruction(__instance, origin, val4) ?? SceneLifecyclePatches.ProjectionObstruction(__instance, origin, ((NavMeshHit)(ref val5)).position); if (text2 != null) { text = text2; continue; } __result = ((((Slot)item2).position.x <= 0f) ? 1f : (-1f)); Recovered++; if (Recovered <= 8) { ManualLogSource modLog = Plugin.ModLog; BepInExInfoLogInterpolatedStringHandler val6 = new BepInExInfoLogInterpolatedStringHandler(57, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val6).AppendLiteral("Chair exit recovered: character="); ((BepInExLogInterpolatedStringHandler)val6).AppendFormatted<string>(((Object)character).name); ((BepInExLogInterpolatedStringHandler)val6).AppendLiteral("; spot="); ((BepInExLogInterpolatedStringHandler)val6).AppendFormatted<string>(((Object)previousSpot).name); ((BepInExLogInterpolatedStringHandler)val6).AppendLiteral("; navmeshOffset="); ((BepInExLogInterpolatedStringHandler)val6).AppendFormatted<float>(Vector3.Distance(val4, ((NavMeshHit)(ref val5)).position), "F3"); ((BepInExLogInterpolatedStringHandler)val6).AppendLiteral("m."); } modLog.LogInfo(val6); } return false; } if (unresolvedReports++ < 16) { ManualLogSource modLog2 = Plugin.ModLog; BepInExWarningLogInterpolatedStringHandler val7 = new BepInExWarningLogInterpolatedStringHandler(112, 6, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val7).AppendLiteral("Chair exit unresolved: character="); ((BepInExLogInterpolatedStringHandler)val7).AppendFormatted<string>(((Object)character).name); ((BepInExLogInterpolatedStringHandler)val7).AppendLiteral("; spot="); ((BepInExLogInterpolatedStringHandler)val7).AppendFormatted<string>(((Object)previousSpot).name); ((BepInExLogInterpolatedStringHandler)val7).AppendLiteral("; slots="); ((BepInExLogInterpolatedStringHandler)val7).AppendFormatted<int>(val.Length); ((BepInExLogInterpolatedStringHandler)val7).AppendLiteral("; position="); ((BepInExLogInterpolatedStringHandler)val7).AppendFormatted<Vector3>(origin); ((BepInExLogInterpolatedStringHandler)val7).AppendLiteral("; reason="); ((BepInExLogInterpolatedStringHandler)val7).AppendFormatted<string>(text); ((BepInExLogInterpolatedStringHandler)val7).AppendLiteral("; sweepBlocker="); ((BepInExLogInterpolatedStringHandler)val7).AppendFormatted<string>(blocker); ((BepInExLogInterpolatedStringHandler)val7).AppendLiteral(". Native transition retained."); } modLog2.LogWarning(val7); } return true; bool NativeClear(Vector3 point) { //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_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) Vector3 val8 = origin + Vector3.up * 0.75f; Vector3 val9 = point - origin; RaycastHit val10 = default(RaycastHit); bool num = Physics.SphereCast(val8, 0.15f, ((Vector3)(ref val9)).normalized, ref val10, 0.6f, environment, (QueryTriggerInteraction)0); if (num) { blocker = (((Object)(object)((RaycastHit)(ref val10)).collider == (Object)null) ? "unknown" : $"{((Object)((RaycastHit)(ref val10)).collider).name}, layer={((Component)((RaycastHit)(ref val10)).collider).gameObject.layer}"); } return !num; } } } internal sealed class CleanupWork { private readonly List<(string Name, Action Action)> steps = new List<(string, Action)>(); internal int Remaining => steps.Count; internal void Add(string name, Action action) { steps.Add((name, action)); } internal bool Run() { int num = 0; while (num < steps.Count) { (string, Action) tuple = steps[num]; try { tuple.Item2(); steps.RemoveAt(num); } catch (Exception error) { ModFaults.Report(tuple.Item1, error); num++; } } return steps.Count == 0; } } internal static class CleanupRetries { private sealed class Pending { internal CleanupWork Work; internal int Left = 3; internal long Due; } private static readonly List<Pending> pending = new List<Pending>(); internal static bool HasPending => pending.Count != 0; internal static string Status { get { if (pending.Count != 0) { return "Some cleanup could not finish. See the log for the affected controls or resources. Restart the game before unloading the patch."; } return ""; } } internal static bool CanCreate => pending.Count < 256; internal static void Submit(CleanupWork work) { if (!work.Run()) { Retry(work); } } internal static void Retry(CleanupWork work) { pending.Add(new Pending { Work = work, Due = Stopwatch.GetTimestamp() + Stopwatch.Frequency }); } internal static void RetireCompleted(CleanupWork work) { if (work.Remaining != 0) { return; } for (int num = pending.Count - 1; num >= 0; num--) { if (pending[num].Work == work) { pending.RemoveAt(num); } } } internal static void Tick() { if (CleanupRetries.pending.Count == 0) { return; } long timestamp = Stopwatch.GetTimestamp(); for (int num = CleanupRetries.pending.Count - 1; num >= 0; num--) { Pending pending = CleanupRetries.pending[num]; if (pending.Left != 0 && timestamp >= pending.Due) { pending.Left--; pending.Due = timestamp + Stopwatch.Frequency; if (pending.Work.Run()) { CleanupRetries.pending.RemoveAt(num); } else if (pending.Left == 0) { ModFaults.Report("Cleanup retry exhaustion", new InvalidOperationException("Cleanup stopped after three retries; unresolved native state retained. Restart is required before creating more affected controls.")); } } } } } internal static class DistantCharacterDetails { private sealed class State { internal Character Character; internal GameObject Object; internal Transform Transform; internal CharacterCommunication? Communication; internal Salsa? Salsa; internal IKSolverLookAt? Look; internal bool Far; } private static readonly Dictionary<nint, State> characters = new Dictionary<IntPtr, State>(); private static readonly Dictionary<nint, State> lips = new Dictionary<IntPtr, State>(); private static readonly Dictionary<nint, State> looks = new Dictionary<IntPtr, State>(); private static readonly List<nint> retired = new List<IntPtr>(); private static readonly Harmony harmony = new Harmony("hvizeu.nivalis.unofficialpatch.distant-details"); private static bool hooks; private static bool running; private static bool failed; private static float nextCheck; internal static bool HooksPending => hooks; internal static int Count => characters.Count; internal static void Start() { if (failed || hooks || !PerformanceCompatibility.Owns(PerformanceFeature.DistantCharacterDetails)) { return; } hooks = true; try { Patch(typeof(Salsa), "LateUpdate", "LipPrefix"); Patch(typeof(IKSolverLookAt), "SolveHead", "LookPrefix"); Patch(typeof(IKSolverLookAt), "SolveEyes", "LookPrefix"); Patch(typeof(Character), "OnPoolingDisable", "RetirePrefix"); Patch(typeof(CharacterCommunication), "StartDialogue", "DialoguePrefix"); Patch(typeof(CharacterCommunication), "StartTalk", "DialoguePrefix"); running = true; nextCheck = 0f; PerformanceCompatibility.Health(PerformanceFeature.DistantCharacterDetails, null); } catch { failed = true; PerformanceCompatibility.Health(PerformanceFeature.DistantCharacterDetails, "Presentation hooks failed; disabled for this session"); Stop(); throw; } } private static void Patch(Type type, string target, string prefix) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown harmony.Patch((MethodBase)(AccessTools.Method(type, target, (Type[])null, (Type[])null) ?? throw new MissingMethodException(type.FullName, target)), new HarmonyMethod(typeof(DistantCharacterDetails), prefix, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } internal static void Inspect(Character character) { if (running && !((Object)(object)character == (Object)null) && !characters.ContainsKey(((Il2CppObjectBase)character).Pointer)) { if (characters.Count >= 1024) { throw new InvalidOperationException("Distant character presentation inventory exceeded its limit."); } CharacterCommunication communication = character.Communication; CharacterIK iK = character.IK; LookAtIK val = (((Object)(object)iK == (Object)null) ? null : iK.lookIK); State state = new State { Character = character, Object = ((Component)character).gameObject, Transform = ((BaseCharacter)character).ThisTransform, Communication = communication, Salsa = (((Object)(object)communication == (Object)null) ? null : communication.Salsa), Look = (((Object)(object)val == (Object)null) ? null : val.solver) }; if (((Object)(object)state.Salsa != (Object)null && lips.ContainsKey(((Il2CppObjectBase)state.Salsa).Pointer)) || (state.Look != null && looks.ContainsKey(((Il2CppObjectBase)state.Look).Pointer))) { throw new InvalidOperationException("Characters share a presentation component; distance ownership is ambiguous."); } characters.Add(((Il2CppObjectBase)character).Pointer, state); if ((Object)(object)state.Salsa != (Object)null) { lips[((Il2CppObjectBase)state.Salsa).Pointer] = state; } if (state.Look != null) { looks[((Il2CppObjectBase)state.Look).Pointer] = state; } } } internal static bool WantsTick(float now) { if (running && characters.Count > 0) { return now >= nextCheck; } return false; } internal static void Tick() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) float unscaledTime = Time.unscaledTime; if (WantsTick(unscaledTime)) { Camera main = Camera.main; Tick(unscaledTime, ((Object)(object)main != (Object)null) ? new Vector3?(((Component)main).transform.position) : ((Vector3?)null)); } } internal static void Tick(float now, Vector3? cameraPosition) { //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_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) if (!WantsTick(now)) { return; } nextCheck = now + 0.25f; try { bool hasValue = cameraPosition.HasValue; Vector3 valueOrDefault = cameraPosition.GetValueOrDefault(); retired.Clear(); foreach (KeyValuePair<IntPtr, State> character in characters) { State value = character.Value; if ((Object)(object)value.Character == (Object)null || (Object)(object)value.Transform == (Object)null || (Object)(object)value.Object == (Object)null || !value.Object.activeInHierarchy) { retired.Add(character.Key); continue; } bool flag = (Object)(object)value.Communication != (Object)null && value.Communication.IsPlayerDialogue; bool far = false; if (hasValue && !flag) { Vector3 position = value.Transform.position; far = DistantPresentationPolicy.Far(DistantPresentationPolicy.SquaredDistance(position.x, position.y, position.z, valueOrDefault.x, valueOrDefault.y, valueOrDefault.z), value.Far, 25f, 22f); } value.Far = far; } foreach (IntPtr item in retired) { Retire(item); } retired.Clear(); } catch (Exception ex) { failed = true; Plugin.ModLog.LogError((object)("Distant character presentation stopped for this session. " + ex)); PerformanceCompatibility.Health(PerformanceFeature.DistantCharacterDetails, "Presentation check failed; disabled for this session"); RenderingOptimizations.Stop(); } } internal static bool LipPrefix(Salsa __instance) { if (running && lips.TryGetValue(((Il2CppObjectBase)__instance).Pointer, out State value)) { return !value.Far; } return true; } internal static bool LookPrefix(IKSolverLookAt __instance) { if (running && looks.TryGetValue(((Il2CppObjectBase)__instance).Pointer, out State value)) { return !value.Far; } return true; } private static void RetirePrefix(Character __instance) { Retire(((Il2CppObjectBase)__instance).Pointer); } private static void DialoguePrefix(CharacterCommunication __instance) { foreach (State value in characters.Values) { CharacterCommunication? communication = value.Communication; if (((communication != null) ? new IntPtr?(((Il2CppObjectBase)communication).Pointer) : ((IntPtr?)null)) == ((Il2CppObjectBase)__instance).Pointer) { value.Far = false; break; } } } internal static void Retire(nint id) { if (characters.Remove(id, out State value)) { if (value.Salsa != null) { lips.Remove(((Il2CppObjectBase)value.Salsa).Pointer); } if (value.Look != null) { looks.Remove(((Il2CppObjectBase)value.Look).Pointer); } } } internal static bool Stop() { if (!failed && (running || hooks)) { PerformanceCompatibility.Health(PerformanceFeature.DistantCharacterDetails, "Stopped; waiting for rendering owner"); } running = false; characters.Clear(); lips.Clear(); looks.Clear(); retired.Clear(); if (!hooks) { return true; } if (!RenderingOptimizations.TryRestore("distant presentation hooks", (Action)harmony.UnpatchSelf)) { return false; } hooks = false; return true; } } internal static class DistantCharacterMeshes { private sealed class State { internal LODGroup Group; internal LOD[] Original; internal bool ChangedLods; internal readonly List<(Renderer Renderer, bool Original)> Retired = new List<(Renderer, bool)>(); } private static readonly Dictionary<int, State> states = new Dictionary<int, State>(); private static readonly List<int> retired = new List<int>(); internal static int Count => states.Count; internal static bool OwnsLod(int id) { if (states.TryGetValue(id, out State value)) { return value.ChangedLods; } return false; } internal static bool SmallGlasses(string character, string renderer, int triangles, int bones, int slots) { if (bones != 1) { return false; } switch (BalancedDetailPolicy.ObjectName(character)) { case "Ceres Coilson": if (!(renderer == "Glasses_LOD_04") || triangles != 96 || slots != 2) { break; } return true; case "Steven McFellow": if (!(renderer == "Glasses_LOD_04") || triangles != 30 || slots != 2) { break; } return true; case "Mizzy Weiss": if (!(renderer == "Glasses_LOD_04") || triangles != 32 || slots != 1) { break; } return true; case "Roxi Fynx": if (!(renderer == "Glasses_LOD_04") || triangles != 32 || slots != 1) { break; } return true; case "Alexandria": if (!(renderer == "Glasses_LOD_04") || triangles != 48 || slots != 2) { break; } return true; case "Rice Walket": if (!(renderer == "Sunglasses_LOD_04") || triangles != 7 || slots != 1) { break; } return true; case "Male007": if (!(renderer == "GLASSES_LOD_004") || triangles != 90 || slots != 1) { break; } return true; case "Lynnphora Adams": if (!(renderer == "Glasses_LOD_04") || triangles != 20 || slots != 1) { break; } return true; case "Male008": if (!(renderer == "Garret_Glasses1_LOD_04") || triangles != 28 || slots != 1) { break; } return true; case "Milo": if (!(renderer == "Glasses_LOD_04") || triangles != 32 || slots != 1) { break; } return true; case "Random Male 03": if (!(renderer == "Glasses _LOD_004") || triangles != 27 || slots != 1) { break; } return true; case "Random Male 03_2": if (!(renderer == "Glasses _LOD_004") || triangles != 27 || slots != 1) { break; } return true; case "Dagmar Fitz": if (!(renderer == "Glasses_LOD_004") || triangles != 31 || slots != 2) { break; } return true; case "Mila Kalcifer": if (!(renderer == "Glasses_LOD_04") || triangles != 5 || slots != 1) { break; } return true; } return false; } internal static void Inspect(LODGroup group) { //IL_0354: Unknown result type (might be due to invalid IL or missing references) //IL_0359: Unknown result type (might be due to invalid IL or missing references) //IL_0368: Expected O, but got Unknown if (!RenderingOptions.DistantCharacterMeshesEnabled || (Object)(object)group == (Object)null || states.ContainsKey(((Object)group).GetInstanceID())) { return; } Character component = ((Component)group).GetComponent<Character>(); if ((Object)(object)component == (Object)null || (Object)(object)component.LODGroup != (Object)(object)group) { return; } string name = BalancedDetailPolicy.ObjectName(((Object)((Component)component).gameObject).name); bool flag; switch (name) { case "Ceres Coilson": case "Mila Kalcifer": case "Lynnphora Adams": case "Steven McFellow": case "Dagmar Fitz": case "Mizzy Weiss": case "Rice Walket": case "Male007": case "Male008": case "Roxi Fynx": case "Alexandria": case "Milo": case "Random Male 03": case "Random Male 03_2": flag = true; break; default: flag = false; break; } if (!flag) { return; } LOD[] array = ((IEnumerable<LOD>)group.GetLODs()).ToArray(); if (array.Length != 5 || array[0].screenRelativeTransitionHeight != 0.5f || array[4].screenRelativeTransitionHeight != 0.02f) { return; } State state = new State { Group = group, Original = array }; Renderer[] array2 = ((IEnumerable<Renderer>)array[4].renderers).Where((Renderer r) => !Omit(name, r)).ToArray(); state.ChangedLods = array2.Length != ((Il2CppArrayBase<Renderer>)(object)array[4].renderers).Length && array2.Length != 0; if (!state.ChangedLods) { return; } if (states.Count >= 1024) { throw new InvalidOperationException("Distant character mesh inventory exceeded its limit."); } states.Add(((Object)group).GetInstanceID(), state); if (!state.ChangedLods) { return; } LOD[] array3 = ((IEnumerable<LOD>)array).Select((Func<LOD, LOD>)((LOD l) => new LOD(l.screenRelativeTransitionHeight, l.renderers) { fadeTransitionWidth = l.fadeTransitionWidth })).ToArray(); array3[4] = new LOD(array[4].screenRelativeTransitionHeight, Il2CppReferenceArray<Renderer>.op_Implicit(array2)) { fadeTransitionWidth = array[4].fadeTransitionWidth }; HashSet<IntPtr> hashSet = (from r in array3.SelectMany((LOD l) => (IEnumerable<Renderer>)l.renderers) where (Object)(object)r != (Object)null select ((Il2CppObjectBase)r).Pointer).ToHashSet(); foreach (Renderer item in (Il2CppArrayBase<Renderer>)(object)array[4].renderers) { if ((Object)(object)item != (Object)null && !hashSet.Contains(((Il2CppObjectBase)item).Pointer)) { state.Retired.Add((item, item.forceRenderingOff)); } } group.SetLODs(Il2CppReferenceArray<LOD>.op_Implicit(array3)); foreach (var item2 in state.Retired) { item2.Renderer.forceRenderingOff = true; } } private static bool Omit(string character, Renderer renderer) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)renderer == (Object)null || (int)renderer.shadowCastingMode != 0) { return false; } SkinnedMeshRenderer val = ((Il2CppObjectBase)renderer).TryCast<SkinnedMeshRenderer>(); if ((Object)(object)val == (Object)null) { return false; } Mesh sharedMesh = val.sharedMesh; if ((Object)(object)sharedMesh == (Object)null || sharedMesh.subMeshCount > 2) { return false; } int num = 0; for (int i = 0; i < sharedMesh.subMeshCount; i++) { if ((int)sharedMesh.GetTopology(i) != 0) { return false; } num += checked((int)sharedMesh.GetIndexCount(i)) / 3; } return SmallGlasses(character, ((Object)((Component)renderer).gameObject).name, num, ((Il2CppArrayBase<Transform>)(object)val.bones).Length, ((Il2CppArrayBase<Material>)(object)renderer.sharedMaterials).Length); } internal static void Prune() { retired.Clear(); foreach (KeyValuePair<int, State> state in states) { if ((Object)(object)state.Value.Group == (Object)null) { retired.Add(state.Key); } } foreach (int item in retired) { if (!Restore(states[item])) { throw new InvalidOperationException("A removed LODGroup still has unrestored distant mesh state."); } states.Remove(item); } retired.Clear(); } internal static void Stop() { KeyValuePair<int, State>[] array = states.ToArray(); for (int i = 0; i < array.Length; i++) { KeyValuePair<int, State> keyValuePair = array[i]; if (Restore(keyValuePair.Value)) { states.Remove(keyValuePair.Key); } } } private static bool Restore(State state) { bool flag; if (flag = !state.ChangedLods || RenderingOptimizations.TryRestore("distant character LOD", delegate { if ((Object)(object)state.Group != (Object)null) { state.Group.SetLODs(Il2CppReferenceArray<LOD>.op_Implicit(state.Original)); } })) { foreach (var item in state.Retired) { flag &= RenderingOptimizations.TryRestore("distant accessory visibility", delegate { if ((Object)(object)item.Renderer != (Object)null) { item.Renderer.forceRenderingOff = item.Original; } }); } } return flag; } } internal static class DistantWorldPanels { private sealed class State { internal MeshRenderer Renderer; internal bool Hidden; } private static readonly Dictionary<int, State> states = new Dictionary<int, State>(); private static readonly List<int> retired = new List<int>(); private static float nextCheck; internal static int Count => states.Count; internal static void Inspect(Transform node) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0136: 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) if (!RenderingOptions.DistantWorldPanelsEnabled) { return; } string text = BalancedDetailPolicy.ObjectName(((Object)((Component)node).gameObject).name); bool flag; switch (text) { case "Animated_Billboard_1x1": case "Animated_Billboard_1x2": case "Animated_Billboard_2x1": flag = true; break; default: flag = false; break; } if (!flag) { return; } MeshRenderer component = ((Component)node).GetComponent<MeshRenderer>(); if ((Object)(object)component == (Object)null || states.ContainsKey(((Object)component).GetInstanceID()) || ((Renderer)component).forceRenderingOff || (int)((Renderer)component).shadowCastingMode != 0) { return; } MeshFilter component2 = ((Component)node).GetComponent<MeshFilter>(); Mesh val = ((component2 != null) ? component2.sharedMesh : null); if ((Object)(object)val == (Object)null || val.subMeshCount != 1 || (int)val.GetTopology(0) != 0) { return; } Il2CppReferenceArray<Material> sharedMaterials = ((Renderer)component).sharedMaterials; if (((Il2CppArrayBase<Material>)(object)sharedMaterials).Length != 1 || (Object)(object)((Il2CppArrayBase<Material>)(object)sharedMaterials)[0] == (Object)null) { return; } Material val2 = ((Il2CppArrayBase<Material>)(object)sharedMaterials)[0]; Shader shader = val2.shader; if ((Object)(object)shader == (Object)null) { return; } Bounds bounds = val.bounds; Vector3 size = ((Bounds)(ref bounds)).size; Vector3 lossyScale = node.lossyScale; if (DistantPresentationPolicy.SmallPanel(text, ((Object)val).name, val.GetIndexCount(0), ((Object)val2).name, ((Object)shader).name, Math.Abs(size.x * lossyScale.x), Math.Abs(size.y * lossyScale.y))) { if (states.Count >= 256) { throw new InvalidOperationException("Small world-panel inventory exceeded its limit."); } states.Add(((Object)component).GetInstanceID(), new State { Renderer = component }); } } internal static bool WantsTick(float now) { if (states.Count > 0) { return now >= nextCheck; } return false; } internal static void Tick() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) float unscaledTime = Time.unscaledTime; if (WantsTick(unscaledTime)) { Camera main = Camera.main; Tick(unscaledTime, ((Object)(object)main != (Object)null) ? new Vector3?(((Component)main).transform.position) : ((Vector3?)null)); } } internal static void Tick(float now, Vector3? cameraPosition) { //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_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) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) if (!WantsTick(now)) { return; } nextCheck = now + 0.25f; bool hasValue = cameraPosition.HasValue; Vector3 valueOrDefault = cameraPosition.GetValueOrDefault(); retired.Clear(); foreach (KeyValuePair<int, State> state in states) { State value = state.Value; if ((Object)(object)value.Renderer == (Object)null) { retired.Add(state.Key); continue; } bool flag = false; if (hasValue && ((Component)value.Renderer).gameObject.activeInHierarchy) { Vector3 center = ((Renderer)value.Renderer).bounds.m_Center; flag = DistantPresentationPolicy.Far(DistantPresentationPolicy.SquaredDistance(center.x, center.y, center.z, valueOrDefault.x, valueOrDefault.y, valueOrDefault.z), value.Hidden, 40f, 35f); } if (flag != value.Hidden) { if (flag) { value.Hidden = true; ((Renderer)value.Renderer).forceRenderingOff = true; } else { ((Renderer)value.Renderer).forceRenderingOff = false; value.Hidden = false; } } } foreach (int item in retired) { states.Remove(item); } retired.Clear(); } internal static void Stop() { KeyValuePair<int, State>[] array = states.ToArray(); for (int i = 0; i < array.Length; i++) { KeyValuePair<int, State> keyValuePair = array[i]; State state = keyValuePair.Value; if (!state.Hidden || RenderingOptimizations.TryRestore("small world panel", delegate { if ((Object)(object)state.Renderer != (Object)null) { ((Renderer)state.Renderer).forceRenderingOff = false; } })) { states.Remove(keyValuePair.Key); } } nextCheck = 0f; } } internal static class LightingPatches { private sealed class LightingState { internal readonly LightingClockGate Clock = new LightingClockGate(); internal readonly ExactCache Snapshot = new ExactCache(); } [HarmonyPatch(typeof(LightCycleManager), "UpdateLightingInternal")] private static class Refresh { private static bool Prefix(LightCycleManager __instance, bool updateProbesIntensity, bool reuseUnchanged, out bool __state) { __state = false; if (!Plugin.Lighting || failed.Contains(((Il2CppObjectBase)__instance).Pointer)) { return true; } bool flag; try { if (LightCycleManager.APPLY_FIXES) { Invalidate(); return true; } LightingState lightingState = Cache(((Il2CppObjectBase)__instance).Pointer); if (!reuseUnchanged || __instance.inTransition || !updateProbesIntensity) { lightingState.Snapshot.Invalidate(); lightingState.Clock.Reset(); lastOwner = 0; return true; } if (!lightingState.Clock.Stable(__instance.currentTime, __instance.currentTimeRemapped)) { lightingState.Snapshot.Invalidate(); lastOwner = 0; return true; } Span<byte> buffer = stackalloc byte[1024]; SnapshotWriter key = new SnapshotWriter(buffer); Capture(__instance, ref key); flag = lastOwner == ((Il2CppObjectBase)__instance).Pointer && lightingState.Snapshot.Matches(key.Written); } catch (Exception error) { Failed(__instance, error); return true; } if (flag) { __instance.sunLightComponent.UpdateLight(false); TimeOfDayController otherTimeOfDayController = __instance.otherTimeOfDayController; if ((Object)(object)otherTimeOfDayController != (Object)null) { otherTimeOfDayController.m_SkyTime = Math.Abs(__instance.currentTimeRemapped); otherTimeOfDayController.UpdateSkyForCurrentTime(); } Skipped++; if (Skipped == 1) { Plugin.ModLog.LogInfo((object)"First unchanged lighting refresh reused; sun transforms and secondary sky callbacks continue."); } return false; } __state = true; return true; } private static void Postfix(LightCycleManager __instance, bool __state, bool __runOriginal) { if (!__state || failed.Contains(((Il2CppObjectBase)__instance).Pointer)) { return; } if (!__runOriginal) { Cache(((Il2CppObjectBase)__instance).Pointer).Snapshot.Invalidate(); lastOwner = 0; return; } try { Span<byte> buffer = stackalloc byte[1024]; SnapshotWriter key = new SnapshotWriter(buffer); Capture(__instance, ref key); Cache(((Il2CppObjectBase)__instance).Pointer).Snapshot.Store(key.Written); lastOwner = ((Il2CppObjectBase)__instance).Pointer; } catch (Exception error) { Failed(__instance, error); } } private static void Finalizer(LightCycleManager __instance, Exception? __exception) { if (__exception != null) { if (caches.TryGetValue(((Il2CppObjectBase)__instance).Pointer, out LightingState value)) { value.Snapshot.Invalidate(); value.Clock.Reset(); } lastOwner = 0; } } } [HarmonyPatch(typeof(LightCycleManager), "OnDestroy")] private static class Destroy { private static void Prefix(LightCycleManager __instance) { caches.Remove(((Il2CppObjectBase)__instance).Pointer); failed.Remove(((Il2CppObjectBase)__instance).Pointer); if (lastOwner == ((Il2CppObjectBase)__instance).Pointer) { lastOwner = 0; } } } private static nint lastOwner; private static readonly Dictionary<nint, LightingState> caches = new Dictionary<IntPtr, LightingState>(); private static readonly HashSet<nint> failed = new HashSet<IntPtr>(); internal static long Skipped; internal static void Invalidate() { caches.Clear(); lastOwner = 0; } internal static void Clear() { caches.Clear(); failed.Clear(); lastOwner = 0; } private static LightingState Cache(nint owner) { if (!caches.TryGetValue(owner, out LightingState value)) { caches.Add(owner, value = new LightingState()); } return value; } private static void Capture(LightCycleManager owner, ref SnapshotWriter key) { key.Fields(((Il2CppObjectBase)owner).Pointer, 24, 112); key.Fields(((Il2CppObjectBase)owner).Pointer, 136, 32); key.Value(owner.LightObjects?._version ?? (-1)); SceneFogSettings sceneOverrides = owner.sceneOverrides; key.Fields((sceneOverrides != null) ? ((Il2CppObjectBase)sceneOverrides).Pointer : IntPtr.Zero, 24, 129); LightCycleSettings currentLightCycleSettings = owner.currentLightCycleSettings; key.Fields((currentLightCycleSettings != null) ? ((Il2CppObjectBase)currentLightCycleSettings).Pointer : IntPtr.Zero, 24, 168); IntPtr? obj; if (currentLightCycleSettings == null) { obj = null; } else { VolumetricSettings volumetricSettings = currentLightCycleSettings.volumetricSettings; obj = ((volumetricSettings != null) ? new IntPtr?(((Il2CppObjectBase)volumetricSettings).Pointer) : ((IntPtr?)null)); } key.Fields(obj ?? IntPtr.Zero, 16, 36); IntPtr? obj2; if (currentLightCycleSettings == null) { obj2 = null; } else { GlobalFogSettings fogSettings = currentLightCycleSettings.fogSettings; obj2 = ((fogSettings != null) ? new IntPtr?(((Il2CppObjectBase)fogSettings).Pointer) : ((IntPtr?)null)); } key.Fields(obj2 ?? IntPtr.Zero, 16, 40); IntPtr? obj3; if (currentLightCycleSettings == null) { obj3 = null; } else { GlobalFogSettings rainSettings = currentLightCycleSettings.rainSettings; obj3 = ((rainSettings != null) ? new IntPtr?(((Il2CppObjectBase)rainSettings).Pointer) : ((IntPtr?)null)); } key.Fields(obj3 ?? IntPtr.Zero, 16, 40); WeatherManager weatherManager = owner.weatherManager; key.Fields((weatherManager != null) ? ((Il2CppObjectBase)weatherManager).Pointer : IntPtr.Zero, 48, 32); } private static void Failed(LightCycleManager owner, Exception error) { Cache(((Il2CppObjectBase)owner).Pointer).Snapshot.Invalidate(); lastOwner = 0; failed.Add(((Il2CppObjectBase)owner).Pointer); ModFaults.Report("Lighting cache disabled for this scene; native refreshes continue", error); } } [HarmonyPatch(typeof(ResolveComplaintSubAction), "Enter")] internal static class ManagerComplaintPatch { internal readonly record struct Scope(ManageComplaintTask? Task, AgentGhost? Customer, State? Visit); internal static void Prefix(State state, out Scope __state) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) __state = default(Scope); try { ManageComplaintTask task = state.Task; if (task != null && !((StaffTask)task).IsCompleted) { CustomerGhost customer = task.Customer; AgentGhost val = ((customer != null) ? ((Il2CppObjectBase)customer).TryCast<AgentGhost>() : null); State val2 = ((val != null) ? val.VisitVenueState : null); if (val2 != null && (int)val2.ComplaintReason != 0 && (int)val2.Interaction == 0) { __state = new Scope(task, val, val2); } } } catch (Exception error) { ModFaults.Report("Manager complaint capture", error); } } internal static void Postfix(State state, Scope __state, bool __runOriginal) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Invalid comparison between Unknown and I4 //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Invalid comparison between Unknown and I4 //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Invalid comparison between Unknown and I4 try { if (__runOriginal && __state.Task != null && __state.Visit != null && __state.Customer != null && state.Task != null && !(((Il2CppObjectBase)state.Task).Pointer != ((Il2CppObjectBase)__state.Task).Pointer) && ((StaffTask)__state.Task).IsCompleted && (int)((ActionState)state).Result == 1) { State visitVenueState = __state.Customer.VisitVenueState; bool flag = visitVenueState == null || ((Il2CppObjectBase)visitVenueState).Pointer != ((Il2CppObjectBase)__state.Visit).Pointer || (int)visitVenueState.ComplaintReason == 0 || (int)visitVenueState.Interaction > 0; if (!flag) { CustomerReaction interactionOutcome = visitVenueState.InteractionOutcome; bool flag2 = interactionOutcome - 1 <= 1; flag = !flag2; } if (!flag) { visitVenueState.Interaction = (CustomerInteraction)3; } } } catch (Exception error) { ModFaults.Report("Manager complaint review", error); } } } internal static class ManagerMenu { private sealed class View : IDisposable { internal readonly VenueStaffOverviewTab Owner; internal readonly int Id; private Action<UISubPanel>? visibility; private bool disposed; private readonly Button entry; private readonly RectTransform schedule; private readonly Vector2 originalScheduleTop; private CanvasBehaviourManager? entryCanvas; private bool lastPurchasing = true; private Button? returnFocus; private CanvasBehaviourManager? panelCanvas; private CanvasGroup? staffSurface; private float staffAlpha; private bool staffInteractable; private bool staffRaycasts; private readonly List<Func<bool>> validateMoney = new List<Func<bool>>(); private GameObject? root; private Venue? venue; private ManagerPolicy draft = new ManagerPolicy(); private SharedBudgetPolicy sharedDraft = new SharedBudgetPolicy(); private long lastRevision = -1L; private string? lastCompatibility; private TextMeshProUGUI status; private ScrollRect scroll; private RectTransform content; private readonly List<Selectable> controls = new List<Selectable>(); private readonly List<Action> refresh = new List<Action>(); private readonly List<(Selectable Control, bool Enabled)> disabled = new List<(Selectable, bool)>(); private GameObject? details; private bool dirty; private string applied = ""; private int moneyStep = 50; internal View(VenueStaffOverviewTab owner) { //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_018a: 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_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) Owner = owner; Id = ((Object)owner).GetInstanceID(); Transform val = ((Component)owner).transform.Find("StaffTabWrapper"); if ((Object)(object)val == (Object)null) { throw new InvalidOperationException("StaffTabWrapper was not found."); } Transform obj = val.Find("ScheduleAndStaffPanelWrapper"); schedule = ((obj != null) ? ((Component)obj).GetComponent<RectTransform>() : null) ?? throw new InvalidOperationException("Staff schedule wrapper was not found."); Transform obj2 = val.Find("P_Element_TitleFrame"); RectTransform val2 = ((obj2 != null) ? ((Component)obj2).GetComponent<RectTransform>() : null) ?? throw new InvalidOperationException("Staff title was not found."); originalScheduleTop = schedule.offsetMax; try { entry = Button(owner.hireButton, val, "ADVANCED MANAGER", delegate { Open(entry); }); ((Object)((Component)entry).gameObject).name = "Hvizeu.EditManagerBehavior"; RectTransform component = ((Component)entry).GetComponent<RectTransform>(); ((Transform)component).localScale = Vector3.one; component.anchorMin = new Vector2(0f, 1f); component.anchorMax = Vector2.one; component.pivot = new Vector2(0.5f, 1f); float y = val2.anchoredPosition.y; Rect rect = val2.rect; float num = y - ((Rect)(ref rect)).height * val2.pivot.y - 12f; component.offsetMin = new Vector2(schedule.offsetMin.x, num - 48f); component.offsetMax = new Vector2(originalScheduleTop.x, num); LayoutElement component2 = ((Component)entry).GetComponent<LayoutElement>(); if ((Object)(object)component2 != (Object)null) { component2.ignoreLayout = true; } schedule.offsetMax = new Vector2(originalScheduleTop.x, Math.Min(originalScheduleTop.y, num - 64f)); Navigation navigation = ((Selectable)entry).navigation; navigation.mode = (Mode)3; ((Selectable)entry).navigation = navigation; ManualUINavigation component3 = ((Component)entry).GetComponent<ManualUINavigation>(); if ((Object)(object)component3 != (Object)null) { component3._autoNavigation = navigation; bool searchSelectableOnUp = (component3.searchSelectableOnDown = true); component3.searchSelectableOnUp = searchSelectableOnUp; searchSelectableOnUp = (component3.searchSelectableOnRight = true); component3.searchSelectableOnLeft = searchSelectableOnUp; } CanvasBehaviourManager.RegisterRuntimeChildren(((Component)entry).gameObject, ref entryCanvas); visibility = Action<UISubPanel>.op_Implicit((Action<UISubPanel>)delegate { try { Refreshed(); } catch (Exception error) { ModFaults.Report("Manager menu visibility", error); } }); ((UISubPanel)Owner).OnVisibilityChanged += visibility; Refreshed(); Plugin.ModLog.LogInfo((object)"Added Edit Manager Behavior below the Staff and Working Schedule heading."); } catch { Dispose(); throw; } } internal void Refreshed() { if (disposed) { return; } bool isVisible = ((UISubPanel)Owner).IsVisible; SetVisible(this, isVisible); if (!isVisible) { Close(); return; } Venue forVenue = Owner._forVenue; bool flag = (Object)(object)forVenue != (Object)null && ((BaseProperty)forVenue).PlayerOwned; if (((Component)entry).gameObject.activeSelf != flag) { ((Component)entry).gameObject.SetActive(flag); } RefreshEntry(); } private void RefreshEntry() { if (!((Object)(object)entry == (Object)null)) { bool flag = ManagerPurchasingCompatibility.Enabled && (Object)(object)root == (Object)null; if (((Selectable)entry).interactable != flag) { ((Selectable)entry).interactable = flag; } string reason = ManagerPurchasingCompatibility.Reason; if (lastPurchasing != Plugin.Purchasing || lastCompatibility != reason) { lastPurchasing = Plugin.Purchasing; lastCompatibility = reason; RelabelButton(((Component)entry).gameObject, (reason != null) ? "FARM FIRST OWNS MANAGER PURCHASING" : (Plugin.Purchasing ? "ADVANCED MANAGER" : "MANAGER PURCHASING DISABLED")); } } } internal void Tick() { if (!((UISubPanel)Owner).IsVisible) { SetVisible(this, active: false); Close(); return; } if (lastPurchasing != Plugin.Purchasing || lastCompatibility != ManagerPurchasingCompatibility.Reason) { RefreshEntry(); } if ((Object)(object)root == (Object)null) { return; } Venue forVenue = Owner._forVenue; if (!((Object)(object)forVenue == (Object)null)) { string guid = ((BaseProperty)forVenue).Guid; Venue? obj = venue; if (!(guid != ((obj != null) ? ((BaseProperty)obj).Guid : null)) && ManagerPurchasingCompatibility.Enabled) { ManagerPolicies.AdvanceDay(); if (lastRevision != ManagerPolicies.Revision) { lastRevision = ManagerPolicies.Revision; Changed(edit: false); } if ((Object)(object)EventSystem.current != (Object)null) { GameObject currentSelectedGameObject = EventSystem.current.currentSelectedGameObject; if ((Object)(object)currentSelectedGameObject == (Object)null || !currentSelectedGameObject.transform.IsChildOf(root.transform)) { controls[0].Select(); } } return; } } Close(); } private void Open(Button source) { //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Expected O, but got Unknown Close(); returnFocus = source; venue = Owner._forVenue; if ((Object)(object)venue == (Object)null || !((BaseProperty)venue).PlayerOwned || !ManagerPurchasingCompatibility.Enabled) { return; } ManagerPolicies.AdvanceDay(); draft = ManagerPolicies.Get(venue); sharedDraft = ManagerPolicies.Shared; lastRevision = ManagerPolicies.Revision; dirty = false; applied = "Changes apply to the next restock. Save your game to keep them."; try { Build(); RefreshEntry(); } catch (Exception ex) { Close(); ManualLogSource modLog = Plugin.ModLog; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(38, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Unable to open manager configuration: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex); } modLog.LogError(val); } } private void Build() { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: 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_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_0338: Unknown result type (might be due to invalid IL or missing references) //IL_034e: Unknown result type (might be due to invalid IL or missing references) //IL_0364: Unknown result type (might be due to invalid IL or missing references) //IL_03f0: Unknown result type (might be due to invalid IL or missing references) //IL_0400: Unknown result type (might be due to invalid IL or missing references) //IL_041a: Unknown result type (might be due to invalid IL or missing references) //IL_042a: Unknown result type (might be due to invalid IL or missing references) //IL_0b28: Unknown result type (might be due to invalid IL or missing references) //IL_0b43: Unknown result type (might be due to invalid IL or missing references) //IL_0b58: Unknown result type (might be due to invalid IL or missing references) //IL_0b6c: Unknown result type (might be due to invalid IL or missing references) //IL_09db: Unknown result type (might be due to invalid IL or missing references) //IL_0a01: Unknown result type (might be due to invalid IL or missing references) //IL_0a0c: Unknown result type (might be due to invalid IL or missing references) //IL_0a11: Unknown result type (might be due to invalid IL or missing references) //IL_0a12: Unknown result type (might be due to invalid IL or missing references) //IL_0a19: Unknown result type (might be due to invalid IL or missing references) //IL_0c1e: Unknown result type (might be due to invalid IL or missing references) TextMeshProUGUI workingHoursText = Owner.workingHoursText; root = ((Component)MenuVisuals.Rect(((Component)Owner).transform.parent, "Hvizeu.ManagerPolicy")).gameObject; MenuVisuals.CopyRect(((Component)Owner).transform, root.transform); RectTransform component = ((Component)Owner).GetComponent<RectTransform>(); RectTransform component2 = root.GetComponent<RectTransform>(); Rect rect = component.rect; float width = ((Rect)(ref rect)).width; rect = component.rect; float num = Math.Max(0f, (width - Math.Min(1240f, ((Rect)(ref rect)).width * 0.94f)) * 0.5f); rect = component.rect; float height = ((Rect)(ref rect)).height; rect = component.rect; Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(num, Math.Max(0f, (height - Math.Min(760f, ((Rect)(ref rect)).height * 0.94f)) * 0.5f)); component2.offsetMin += val; component2.offsetMax -= val; root.SetActive(false); root.layer = ((Component)Owner).gameObject.layer; CanvasGroup obj = root.AddComponent<CanvasGroup>(); obj.alpha = 1f; bool flag = (obj.ignoreParentGroups = true); bool interactable = (obj.blocksRaycasts = flag); obj.interactable = interactable; ((Graphic)root.AddComponent<Image>()).color = new Color(0.09f, 0.085f, 0.078f, 1f); root.transform.SetAsLastSibling(); TextMeshProUGUI val2 = MenuVisuals.Text(root.transform, workingHoursText, ((BaseProperty)venue).GetName() + " / Manager", 24f); ((Graphic)val2).color = new Color(0.84f, 0.68f, 0.43f); Place(((TMP_Text)val2).rectTransform, 20f, 4f, 20f, 38f, top: true); string[] array = (from row in (IEnumerable<VenueStaffListItem>)((Component)Owner).GetComponentsInChildren<VenueStaffListItem>(true) where (Object)(object)row._person != (Object)null && (Object)(object)row.toggleManage != (Object)null && row.toggleManage.isOn select row._person.DisplayedName).Distinct().ToArray(); string text = ((array.Length == 0) ? "No manager assigned" : ("Managers: " + string.Join(", ", array.Take(3)) + ((array.Length > 3) ? $" +{array.Length - 3}" : ""))); Place(((TMP_Text)MenuVisuals.Text(root.transform, workingHoursText, text + "\nApplies to all managers at this venue", 16f)).rectTransform, 20f, 42f, 20f, 40f, top: true); RectTransform val3 = MenuVisuals.Rect(root.transform, "PolicyViewport"); val3.offsetMin = new Vector2(20f, 96f); val3.offsetMax = new Vector2(-46f, -88f); ((Graphic)((Component)val3).gameObject.AddComponent<Image>()).color = Color.clear; ((Component)val3).gameObject.AddComponent<RectMask2D>(); scroll = ((Component)val3).gameObject.AddComponent<ScrollRect>(); scroll.horizontal = false; scroll.vertical = true; scroll.movementType = (MovementType)2; scroll.scrollSensitivity = 36f; scroll.viewport = val3; content = MenuVisuals.Rect((Transform)(object)val3, "PolicyRows"); content.anchorMin = new Vector2(0f, 1f); content.anchorMax = Vector2.one; content.pivot = new Vector2(0.5f, 1f); content.sizeDelta = Vector2.zero; scroll.content = content; VerticalLayoutGroup obj2 = ((Component)content).gameObject.AddComponent<VerticalLayoutGroup>(); interactable = (((HorizontalOrVerticalLayoutGroup)obj2).childControlHeight = true); ((HorizontalOrVerticalLayoutGroup)obj2).childControlWidth = interactable; ((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = false; ((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)obj2).spacing = 6f; ((Component)content).gameObject.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2; RectTransform parent = Section((Transform)(object)content, "Operating policy"); Choice((Transform)(object)parent, "Priority", () => draft.Priority switch { OperatingPriority.SaveMoney => "Save money", OperatingPriority.MenuAvailability => "Keep menu available", _ => "Balanced", }, delegate { draft.Preset((OperatingPriority)((int)(draft.Priority + 1) % 3)); }, "Balanced spreads stock coverage. Save money favours cheaper complete batches. Keep menu available spreads batches across dishes."); RectTransform parent2 = Section((Transform)(object)content, "Purchasing"); Choice((Transform)(object)parent2, "Restaurant funding priority", () => draft.Funding.ToString(), delegate { draft.Funding = (FundingPriority)((int)(draft.Funding + 1) % 3); }, "With shared budgets enabled, High / Normal / Low receive weighted shares of 4 / 2 / 1. Dish priorities apply within this restaurant."); Button expand = null; expand = Button(Owner.hireButton, (Transform)(object)parent2, "SHOW SETTINGS", delegate { details.SetActive(!details.activeSelf); RelabelButton(((Component)expand).gameObject, details.activeSelf ? "HIDE SETTINGS" : "SHOW SETTINGS"); Reflow(); }); Height(((Component)expand).gameObject, 34f); controls.Add((Selectable)(object)expand); AutoScroll((Selectable)(object)expand); RectTransform val4 = MenuVisuals.Rect((Transform)(object)parent2, "PurchasingDetails"); details = ((Component)val4).gameObject; VerticalLayoutGroup obj3 = details.AddComponent<VerticalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)obj3).spacing = 6f; interactable = (((HorizontalOrVerticalLayoutGroup)obj3).childControlWidth = true); ((HorizontalOrVerticalLayoutGroup)obj3).childControlHeight = interactable; ((HorizontalOrVerticalLayoutGroup)obj3).childForceExpandHeight = false; Note((Transform)(object)val4, "Supply targets, daily venue budgets and shopping notifications use the game's saved management settings. Legacy stock formulas are retired.", 64f, 17f); Choice((Transform)(object)val4, "Supplier preference", () => draft.Suppliers.ToString(), delegate { draft.Suppliers = (SupplierPreference)((int)(draft.Suppliers + 1) % 3); }, "Nearby uses district connections, not a delivery-time guarantee. Every mode can use another supplier when stock runs out."); Money((Transform)(object)val4, "Cash reserve", () => draft.CashReserve, delegate(int value) { draft.CashReserve = value; }, "Purchases must leave this much in the venue owner's wallet. Emergency orders also respect this reserve."); Money((Transform)(object)val4, "Limit per restock", () => draft.SpendingLimit, delegate(int value) { draft.SpendingLimit = value; }, "Zero keeps the game's limit. Applies to the whole menu; never raises the game's allowance."); Choice((Transform)(object)val4, "Amount adjustment", () => $"{moneyStep} LIM", delegate { int num4 = moneyStep; moneyStep = num4 switch { 1 => 10, 10 => 50, 50 => 100, 100 => 1000, _ => 1, }; }, "Step used by the minus and plus buttons above.", edits: false); Choice((Transform)(object)val4, "Emergency purchases", () => (!draft.EmergencyPurchases) ? "Off" : "Allowed", delegate { draft.EmergencyPurchases = !draft.EmergencyPurchases; }, "For a dish without a covered batch, allow cheaper suppliers if the preferred order exceeds the budget."); details.SetActive(false); RectTransform parent3 = Section((Transform)(object)content, "All restaurants"); Choice((Transform)(object)parent3, "Shared budgeting", () => (!sharedDraft.Enabled) ? "Off" : "On", delegate { sharedDraft.Enabled = !sharedDraft.Enabled; }, "One shared wallet reserve and daily manager ingredient limit. Other expenses are not charged to this limit. Save the game to keep settings and accounting."); Money((Transform)(object)parent3, "Shared cash reserve", () => sharedDraft.CashReserve, delegate(int value) { sharedDraft.CashReserve = value; }, "Every restaurant must respect the higher of this reserve and its own reserve. Other player expenses can still use this money."); Money((Transform)(object)parent3, "Daily ingredient limit", () => sharedDraft.DailyLimit, delegate(int value) { sharedDraft.DailyLimit = value; }, "Zero means unlimited. The gameplay day resets at 08:00. One complete batch may borrow another restaurant's share within all hard limits."); RectTransform val5 = MenuVisuals.Rect((Transform)(object)parent3, "TodaySpending"); Height(((Component)val5).gameObject, 72f); TextMeshProUGUI spendText = MenuVisuals.Text((Transform)(object)val5, Owner.workingHoursText, "", 17f); refresh.Add(delegate { ManagerSpendLedger ledger = ManagerPolicies.Account.Ledger; ((TMP_Text)spendText).text = $"Today: {(decimal)ledger.Total / 100m:0.00} LIM across restaurants · {(decimal)ledger.Spent.GetValueOrDefault(((BaseProperty)venue).Guid) / 100m:0.00} LIM here\n" + (ledger.Faulted ? "Paid purchasing suspended: transaction accounting needs recovery." : "Changing limits or restoring defaults does not erase spending."); }); RectTransform parent4 = Section((Transform)(object)content, "Dish priorities"); Note((Transform)(object)parent4, "Higher priorities receive complete batches first when ingredients or funds are limited.", 34f, 17f); List<IRecipe> list = ManagerPlanning.Menu(((Il2CppObjectBase)((BaseProperty)venue).Ghost).TryCast<VenueAreaGhost>() ?? throw new InvalidOperationException("Venue runtime state is unavailable.")); if (list.Count == 0) { Note((Transform)(object)parent4, "No cookable menu items. Add a dish and its required equipment first.", 60f); } foreach (IRecipe item in list) { string id = ManagerPlanning.RecipeId(item); DishRow((Transform)(object)parent4, item.Output.type.Name, () => draft.DishPriority(id), delegate(int direction2) { draft.AdjustDishPriority(id, direction2); }); } RectTransform parent5 = Section((Transform)(object)content, "Last restock"); RectTransform val6 = MenuVisuals.Rect((Transform)(object)parent5, "RestockSummary"); Height(((Component)val6).gameObject, 76f); TextMeshProUGUI summaryText = MenuVisuals.Text((Transform)(object)val6, workingHoursText, "", 17f); int page = 0; RectTransform val7 = MenuVisuals.Rect((Transform)(object)parent5, "RestockDecisions"); Height(((Component)val7).gameObject, 140f); TextMeshProUGUI reportText = MenuVisuals.Text((Transform)(object)val7, workingHoursText, "", 18f); RectTransform val8 = MenuVisuals.Rect((Transform)(object)parent5, "ReportPages"); Height(((Component)val8).gameObject, 46f); TextMeshProUGUI pageText = MenuVisuals.Text((Transform)(object)val8, workingHoursText, "", 18f); ((TMP_Text)pageText).alignment = (TextAlignmentOptions)514; int[] array2 = new int[2] { -1, 1 }; foreach (int direction in array2) { Button val9 = Button(Owner.hireButton, (Transform)(object)val8, (direction < 0) ? "PREVIOUS" : "NEXT", delegate { page += direction; ShowPage(); }); RectTransform component3 = ((Component)val9).GetComponent<RectTransform>(); component3.anchorMin = new Vector2((direction < 0) ? 0f : 0.7f, 0f); component3.anchorMax = new Vector2((direction < 0) ? 0.3f : 1f, 1f); Vector2 offsetMin = (component3.offsetMax = Vector2.zero); component3.offsetMin = offsetMin; controls.Add((Selectable)(object)val9); AutoScroll((Selectable)(object)val9); } refresh.Add(ShowPage); RectTransform val10 = MenuVisuals.Rect(root.transform, "Actions"); Place(val10, 20f, 10f, 20f, 38f, top: false); Button[] array3 = (Button[])(object)new Button[3] { Button(Owner.hireButton, (Transform)(object)val10, "APPLY", Commit), Button(Owner.hireButton, (Transform)(object)val10, "CANCEL", Close), Button(Owner.hireButton, (Transform)(object)val10, "RESTORE DEFAULTS", delegate { draft = new ManagerPolicy(); sharedDraft = new SharedBudgetPolicy(); Changed(); }) }; for (int num3 = 0; num3 < array3.Length; num3++) { RectTransform component4 = ((Component)array3[num3]).GetComponent<RectTransform>(); component4.anchorMin = new Vector2((float)num3 / 3f, 0f); component4.anchorMax = new Vector2((float)(num3 + 1) / 3f, 1f); component4.offsetMin = new Vector2(4f, 0f); component4.offsetMax = new Vector2(-4f, 0f); controls.Add((Selectable)(object)array3[num3]); } status = MenuVisuals.Text(root.transform, workingHoursText, applied, 15f); Place(((TMP_Text)status).rectTransform, 20f, 50f, 20f, 40f, top: false); AddScrollbar(); foreach (TextMeshProUGUI componentsInChild in root.GetComponentsInChildren<TextMeshProUGUI>(true)) { if ((Object)(object)componentsInChild != (Object)(object)val2) { ((Graphic)componentsInChild).color = new Color(0.9f, 0.88f, 0.82f); } } foreach (Selectable item2 in ((IEnumerable<Selectable>)((Component)Owner._window).GetComponentsInChildren<Selectable>(true)).Where((Selectable c) => !((Component)c).transform.IsChildOf(root.transform))) { disabled.Add((item2, item2.interactable)); item2.interactable = false; } staffSurface = ((Component)Owner).GetComponent<CanvasGroup>(); if ((Object)(object)staffSurface != (Object)null) { staffAlpha = staffSurface.alpha; staffInteractable = staffSurface.interactable; staffRaycasts = staffSurface.blocksRaycasts; staffSurface.alpha = 0f; CanvasGroup? obj4 = staffSurface; interactable = (staffSurface.blocksRaycasts = false); obj4.interactable = interactable; } root.SetActive(true); CanvasBehaviourManager.RegisterRuntimeChildren(root, ref panelCanvas); RefreshScrollRouting(); Changed(edit: false); Reflow(); scroll.verticalNormalizedPosition = 1f; controls[0].Select(); void ShowPage() { if (!ManagerPolicies.Reports.TryGetValue(((BaseProperty)venue).Guid, out RestockReport value)) { ((TMP_Text)summaryText).text = "No restock recorded in this session."; ((TMP_Text)reportText).text = "Purchases and funding decisions will appear after a manager attempts an order."; ((TMP_Text)pageText).text = "1 / 1"; } else { long num4 = Math.Max(0L, TimeOfDayManager.TotalGameSeconds - value.Time); ((TMP_Text)summaryText).text = $"{value.Summary}\n{num4 / 3600}h {num4 % 3600 / 60}m ago in game · {(value.Failed ? "Order incomplete — inspect the mod log" : "Restock finished")}"; int num5 = Math.Max(1, (value.Lines.Count + 1) / 2); page = Math.Clamp(page, 0, num5 - 1); ((TMP_Text)reportText).text = string.Join("\n\n", value.Lines.Skip(page * 2).Take(2)); ((TMP_Text)pageText).text = $"{page + 1} / {num5}"; } } } internal void RouteScroll(UIWindow window, List<ScrollRect> results) { if (!((Object)(object)root == (Object)null) && !((Object)(object)Owner._window != (Object)(object)window)) { results.Clear(); results.Add(scroll); } } private void RefreshScrollRouting() { if ((Object)(object)Owner == (Object)null || (Object)(object)Owner._window == (Object)null) { return; } UIScrollViewHandler val = Object.FindObjectOfType<UIScrollViewHandler>(); if (!((Object)(object)val == (Object)null)) { IScrollRectsProvider val2 = ((Il2CppObjectBase)Owner._window).Cast<IScrollRectsProvider>(); val._scrollRectCache.Remove(val2); if (val._focusedWindow != null && ((Il2CppObjectBase)val._focusedWindow).Pointer == ((Il2CppObjectBase)val2).Pointer) { val._focusedScrollRects = val.GetScrollRects(val2); } } } private void AddScrollbar() { //IL_0020: 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_0040: 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_007e: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) RectTransform obj = MenuVisuals.Rect(root.transform, "VerticalScrollbar"); obj.anchorMin = new Vector2(1f, 0f); obj.anchorMax = Vector2.one; obj.offsetMin = new Vector2(-36f, 96f); obj.offsetMax = new Vector2(-20f, -88f); ((Graphic)((Component)obj).gameObject.AddComponent<Image>()).color = new Color(0.18f, 0.17f, 0.15f, 1f); RectTransform val = MenuVisuals.Rect((Transform)(object)obj, "Handle"); Image val2 = ((Component)val).gameObject.AddComponent<Image>(); ((Graphic)val2).color = new Color(0.77f, 0.64f, 0.44f, 1f); Scrollbar val3 = ((Component)obj).gameObject.AddComponent<Scrollbar>(); val3.handleRect = val; ((Selectable)val3).targetGraphic = (Graphic)(object)val2; val3.direction = (Direction)2; scroll.verticalScrollbar = val3; scroll.verticalScrollbarVisibility = (ScrollbarVisibility)0; controls.Add((Selectable)(object)val3); } private void DishRow(Transform parent, string label, Func<int> value, Action<int> adjust) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: 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_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0168: 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_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_024b: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) RectTransform obj = MenuVisuals.Rect(parent, "Dish