Decompiled source of Sense of Direction v1.0.1
SenseOfDirection.dll
Decompiled 8 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using SenseOfDirection.CampfireIndicator; using SenseOfDirection.Common; using SenseOfDirection.Compass; using SenseOfDirection.GhostFreeCam; using SenseOfDirection.Indicators; using SenseOfDirection.ItemPings; using SenseOfDirection.Labels; using SenseOfDirection.LuggagePing; using SenseOfDirection.Pings; using SenseOfDirection.PirateCompass; using SenseOfDirection.Ui; using SenseOfDirection.Ui.Localization; using TMPro; using Unity.Mathematics; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.InputSystem.Utilities; using UnityEngine.Localization; using UnityEngine.Rendering; using UnityEngine.SceneManagement; using UnityEngine.UI; using Zorro.ControllerSupport; using Zorro.Core; using Zorro.Settings; using Zorro.Settings.UI; using pworld.Scripts.Extensions; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("SenseOfDirection")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1+1483bcb74cc5ce4aa73f0d1a3b70abfc8f6a4c6d")] [assembly: AssemblyProduct("SenseOfDirection")] [assembly: AssemblyTitle("SenseOfDirection")] [assembly: AssemblyVersion("1.0.1.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] internal sealed class IsUnmanagedAttribute : Attribute { } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace SenseOfDirection { [BepInPlugin("OnlyCook.SenseOfDirection", "Sense of Direction", "1.0.1")] public class Plugin : BaseUnityPlugin { private Harmony _harmony; internal static Plugin Instance { get; private set; } internal PluginConfig Cfg { get; private set; } internal ManualLogSource Log => ((BaseUnityPlugin)this).Logger; private void Awake() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Expected O, but got Unknown Instance = this; Cfg = new PluginConfig(((BaseUnityPlugin)this).Config); _harmony = new Harmony("OnlyCook.SenseOfDirection"); PlayerLabelPatches.Apply(_harmony, ((BaseUnityPlugin)this).Logger); VanillaLabelSuppressionPatch.Apply(_harmony, ((BaseUnityPlugin)this).Logger); PointPingerPatches.Apply(_harmony, ((BaseUnityPlugin)this).Logger); GhostFreeCamPatches.Apply(_harmony, ((BaseUnityPlugin)this).Logger); PauseSuppressPatch.Apply(_harmony, ((BaseUnityPlugin)this).Logger); _ = CampfireIndicatorController.Instance; _ = PingAudioTuner.Instance; _ = CompassManager.Instance; _ = PirateCompassLuggageIndicatorController.Instance; _ = LuggagePingController.Instance; _ = PingableRegistry.Instance; _ = PingPrewarm.Instance; _ = PreviewMenu.Instance; _ = ZombieDebugEsp.Instance; if (Cfg.EnableIndicatorTestHarness.Value) { GameObject val = new GameObject("SenseOfDirection.IndicatorTestHarness"); Object.DontDestroyOnLoad((Object)val); val.AddComponent<IndicatorTestHarness>(); } ((BaseUnityPlugin)this).Logger.LogInfo((object)"Sense of Direction 1.0.1 loaded."); } } public class PluginConfig { public readonly ConfigEntry<IndicatorPlacement> PlayerLabelPlacement; public readonly ConfigEntry<IndicatorPlacement> CampfirePlacement; public readonly ConfigEntry<IndicatorPlacement> PingPlacement; public readonly ConfigEntry<IndicatorPlacement> ItemPingPlacement; public readonly ConfigEntry<IndicatorPlacement> PirateCompassLuggagePlacement; public readonly ConfigEntry<bool> EnableLabelOverlapAvoidance; public readonly ConfigEntry<KeyCode> PreviewMenuKey; public readonly ConfigEntry<float> OnScreenNameFontScale; public readonly ConfigEntry<float> OnScreenDistanceFontScale; public readonly ConfigEntry<float> OffScreenNameFontScale; public readonly ConfigEntry<float> OffScreenDistanceFontScale; public readonly ConfigEntry<float> CompassNameFontScale; public readonly ConfigEntry<float> CompassDistanceFontScale; public readonly ConfigEntry<bool> EnablePlayerLabels; public readonly ConfigEntry<KeyCode> PlayerLabelToggleKey; public readonly ConfigEntry<LabelDisplayMode> PlayerLabelDisplayMode; public readonly ConfigEntry<float> HoldShownDuration; public readonly ConfigEntry<float> PlayerLabelMaxDistanceMeters; public readonly ConfigEntry<float> PlayerLabelNameFontSize; public readonly ConfigEntry<float> PlayerLabelDistanceFontSize; public readonly ConfigEntry<bool> ShowPlayerLabelDistance; public readonly ConfigEntry<bool> ShowStatusBadges; public readonly ConfigEntry<bool> UseCharacterColor; public readonly ConfigEntry<bool> ReplaceVanillaLabels; public readonly ConfigEntry<bool> ShowPlayerSkeleton; public readonly ConfigEntry<float> PlayerSkeletonLineThickness; public readonly ConfigEntry<bool> PlayerSkeletonUseCharacterColor; public readonly ConfigEntry<bool> ShowPlayerSkeletonJoints; public readonly ConfigEntry<bool> EnableCampfireIndicator; public readonly ConfigEntry<bool> ShowCampfireDistance; public readonly ConfigEntry<bool> RemoveVisibilityCutoff; public readonly ConfigEntry<bool> EnablePingScaling; public readonly ConfigEntry<float> PingScaleMultiplier; public readonly ConfigEntry<bool> EnablePingRipple; public readonly ConfigEntry<bool> EnablePingOffScreenIndicator; public readonly ConfigEntry<bool> ShowPingDistanceLabel; public readonly ConfigEntry<bool> EnableGhostPing; public readonly ConfigEntry<bool> EnablePingAudioBoost; public readonly ConfigEntry<float> PingAudioRangeMeters; public readonly ConfigEntry<float> PingAudioMinDistanceMeters; public readonly ConfigEntry<float> PingAudioVolumeMultiplier; public readonly ConfigEntry<bool> EnablePingAntiSpam; public readonly ConfigEntry<int> PingAntiSpamFreeSpamCount; public readonly ConfigEntry<float> PingAntiSpamSlowModeIntervalSeconds; public readonly ConfigEntry<int> PingAntiSpamMaxQueueLength; public readonly ConfigEntry<float> PingAntiSpamResetSeconds; public readonly ConfigEntry<bool> EnableItemPings; public readonly ConfigEntry<float> ItemPingDurationSeconds; public readonly ConfigEntry<bool> EnableItemPingGrouping; public readonly ConfigEntry<bool> EnableCreaturePings; public readonly ConfigEntry<bool> UseNativeItemPingIcons; public readonly ConfigEntry<ItemPingNameMode> ItemPingNameMode; public readonly ConfigEntry<bool> ShowItemPingDistance; public readonly ConfigEntry<bool> EnableItemPingOffScreenIndicator; public readonly ConfigEntry<float> ItemPingDetectionRadiusMeters; public readonly ConfigEntry<float> ItemPingCrossKindRadiusMeters; public readonly ConfigEntry<float> LuggagePingDetectionRadiusMeters; public readonly ConfigEntry<bool> EnableItemPingHitAssist; public readonly ConfigEntry<float> ItemPingHitboxRadiusMeters; public readonly ConfigEntry<bool> EnableItemPingRayAssist; public readonly ConfigEntry<float> ItemPingRayAssistRadiusMeters; public readonly ConfigEntry<bool> EnableCompass; public readonly ConfigEntry<float> CompassWidthPixels; public readonly ConfigEntry<float> CompassMarkerGapPixels; public readonly ConfigEntry<float> CompassVerticalOffsetPixels; public readonly ConfigEntry<float> CompassHorizontalOffsetPixels; public readonly ConfigEntry<float> CompassFovDegrees; public readonly ConfigEntry<float> CompassIconSizePixels; public readonly ConfigEntry<float> CompassElevationThresholdMeters; public readonly ConfigEntry<bool> CompassShowDegreeNumbers; public readonly ConfigEntry<bool> CompassShowNames; public readonly ConfigEntry<bool> CompassShowDistances; public readonly ConfigEntry<bool> CompassRequiresHoldingItem; public readonly ConfigEntry<CompassLineColor> CompassLineColor; public readonly ConfigEntry<float> CompassLineThicknessMultiplier; public readonly ConfigEntry<bool> CompassClampIconsToEdge; public readonly ConfigEntry<bool> EnablePirateCompassLuggageIndicator; public readonly ConfigEntry<bool> ShowPirateCompassLuggageName; public readonly ConfigEntry<bool> ShowPirateCompassLuggageDistance; public readonly ConfigEntry<bool> EnablePirateCompassLuggageOffScreenIndicator; public readonly ConfigEntry<bool> EnableLuggagePing; public readonly ConfigEntry<KeyCode> LuggagePingKey; public readonly ConfigEntry<float> LuggagePingRadiusMeters; public readonly ConfigEntry<float> LuggagePingDurationSeconds; public readonly ConfigEntry<float> LuggagePingCooldownSeconds; public readonly ConfigEntry<bool> EnableGhostFreeCam; public readonly ConfigEntry<float> GhostFreeCamMaxDistanceMeters; public readonly ConfigEntry<bool> GhostFreeCamUnlimitedRange; public readonly ConfigEntry<KeyCode> GhostFreeCamToggleKey; public readonly ConfigEntry<float> GhostFreeCamMoveSpeedMetersPerSecond; public readonly ConfigEntry<float> GhostFreeCamSprintMultiplier; public readonly ConfigEntry<bool> GhostFreeCamShowCrosshair; public readonly ConfigEntry<bool> GhostFreeCamShowKeyHint; public readonly ConfigEntry<bool> HideAllGhosts; public readonly ConfigEntry<bool> EnableDebugLogging; public readonly ConfigEntry<bool> EnableIndicatorTestHarness; public readonly ConfigEntry<bool> EnableZombieDebugEsp; public PluginConfig(ConfigFile config) { //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Expected O, but got Unknown //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Expected O, but got Unknown //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Expected O, but got Unknown //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Expected O, but got Unknown //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Expected O, but got Unknown //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Expected O, but got Unknown //IL_02a3: Unknown result type (might be due to invalid IL or missing references) //IL_02ad: Expected O, but got Unknown //IL_02dc: Unknown result type (might be due to invalid IL or missing references) //IL_02e6: Expected O, but got Unknown //IL_0315: Unknown result type (might be due to invalid IL or missing references) //IL_031f: Expected O, but got Unknown //IL_034e: Unknown result type (might be due to invalid IL or missing references) //IL_0358: Expected O, but got Unknown //IL_0413: Unknown result type (might be due to invalid IL or missing references) //IL_041d: Expected O, but got Unknown //IL_04f4: Unknown result type (might be due to invalid IL or missing references) //IL_04fe: Expected O, but got Unknown //IL_05b9: Unknown result type (might be due to invalid IL or missing references) //IL_05c3: Expected O, but got Unknown //IL_05f2: Unknown result type (might be due to invalid IL or missing references) //IL_05fc: Expected O, but got Unknown //IL_062b: Unknown result type (might be due to invalid IL or missing references) //IL_0635: Expected O, but got Unknown //IL_0675: Unknown result type (might be due to invalid IL or missing references) //IL_067f: Expected O, but got Unknown //IL_06ae: Unknown result type (might be due to invalid IL or missing references) //IL_06b8: Expected O, but got Unknown //IL_06dc: Unknown result type (might be due to invalid IL or missing references) //IL_06e6: Expected O, but got Unknown //IL_0715: Unknown result type (might be due to invalid IL or missing references) //IL_071f: Expected O, but got Unknown //IL_076a: Unknown result type (might be due to invalid IL or missing references) //IL_0774: Expected O, but got Unknown //IL_084b: Unknown result type (might be due to invalid IL or missing references) //IL_0855: Expected O, but got Unknown //IL_0884: Unknown result type (might be due to invalid IL or missing references) //IL_088e: Expected O, but got Unknown //IL_08bd: Unknown result type (might be due to invalid IL or missing references) //IL_08c7: Expected O, but got Unknown //IL_0912: Unknown result type (might be due to invalid IL or missing references) //IL_091c: Expected O, but got Unknown //IL_0967: Unknown result type (might be due to invalid IL or missing references) //IL_0971: Expected O, but got Unknown //IL_09bc: Unknown result type (might be due to invalid IL or missing references) //IL_09c6: Expected O, but got Unknown //IL_09f5: Unknown result type (might be due to invalid IL or missing references) //IL_09ff: Expected O, but got Unknown //IL_0a2e: Unknown result type (might be due to invalid IL or missing references) //IL_0a38: Expected O, but got Unknown //IL_0a67: Unknown result type (might be due to invalid IL or missing references) //IL_0a71: Expected O, but got Unknown //IL_0aa0: Unknown result type (might be due to invalid IL or missing references) //IL_0aaa: Expected O, but got Unknown //IL_0ad9: Unknown result type (might be due to invalid IL or missing references) //IL_0ae3: Expected O, but got Unknown //IL_0b12: Unknown result type (might be due to invalid IL or missing references) //IL_0b1c: Expected O, but got Unknown //IL_0bd7: Unknown result type (might be due to invalid IL or missing references) //IL_0be1: Expected O, but got Unknown //IL_0cd5: Unknown result type (might be due to invalid IL or missing references) //IL_0cdf: Expected O, but got Unknown //IL_0d0e: Unknown result type (might be due to invalid IL or missing references) //IL_0d18: Expected O, but got Unknown //IL_0d47: Unknown result type (might be due to invalid IL or missing references) //IL_0d51: Expected O, but got Unknown //IL_0d9c: Unknown result type (might be due to invalid IL or missing references) //IL_0da6: Expected O, but got Unknown //IL_0e0e: Unknown result type (might be due to invalid IL or missing references) //IL_0e18: Expected O, but got Unknown //IL_0e47: Unknown result type (might be due to invalid IL or missing references) //IL_0e51: Expected O, but got Unknown PlayerLabelPlacement = config.Bind<IndicatorPlacement>("General", "player-label-placement", IndicatorPlacement.Both, "Where player labels are drawn. Both: as the edge-of-screen label and as a marker on the compass tape at once. OffScreenOnly: only the edge-of-screen label. CompassOnly: only the compass marker."); CampfirePlacement = config.Bind<IndicatorPlacement>("General", "campfire-placement", IndicatorPlacement.OffScreenOnly, "Where the campfire indicator is drawn, using the same OffScreenOnly/CompassOnly/Both choice as player-label-placement."); PingPlacement = config.Bind<IndicatorPlacement>("General", "ping-placement", IndicatorPlacement.OffScreenOnly, "Where pings are drawn, using the same OffScreenOnly/CompassOnly/Both choice as player-label-placement."); ItemPingPlacement = config.Bind<IndicatorPlacement>("General", "item-ping-placement", IndicatorPlacement.OffScreenOnly, "Where item/luggage/creature ping highlights are drawn, using the same OffScreenOnly/CompassOnly/Both choice as player-label-placement."); PirateCompassLuggagePlacement = config.Bind<IndicatorPlacement>("General", "pirate-compass-luggage-placement", IndicatorPlacement.Both, "Where the Pirate's Compass luggage indicator is drawn, using the same OffScreenOnly/CompassOnly/Both choice as player-label-placement."); EnableLabelOverlapAvoidance = config.Bind<bool>("General", "enable-label-overlap-avoidance", true, "Nudges overlapping player/ping/item-ping/campfire labels (and compass markers) apart so they stay readable when several land on top of each other, instead of stacking illegibly. Off restores every label/marker to its exact tracked position with no nudging at all."); PreviewMenuKey = config.Bind<KeyCode>("General", "preview-menu-key", (KeyCode)289, "Key that opens the in-game settings menu: every visual setting in this mod, laid out over a live preview of what it actually does (player labels, pings, item pings, the campfire indicator and the compass, all drawn on a real screenshot and updating as you change them). Changes there are written straight to this config file. Set to None to disable the key entirely."); OnScreenNameFontScale = config.Bind<float>("Fonts", "on-screen-name-scale", 1f, new ConfigDescription("Scales every name label drawn on a thing you can actually see (player labels, item/creature pings). 1 keeps the shipped sizes.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 2f), Array.Empty<object>())); OnScreenDistanceFontScale = config.Bind<float>("Fonts", "on-screen-distance-scale", 1f, new ConfigDescription("Same, for the distance sub-line under an on-screen label.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 2f), Array.Empty<object>())); OffScreenNameFontScale = config.Bind<float>("Fonts", "off-screen-name-scale", 1f, new ConfigDescription("Scales every name label on a thing that's currently off-screen, i.e. clamped to the edge with an arrow. Set this below on-screen-name-scale to keep a crowded screen edge quieter without shrinking the labels on things you're actually looking at.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 2f), Array.Empty<object>())); OffScreenDistanceFontScale = config.Bind<float>("Fonts", "off-screen-distance-scale", 1f, new ConfigDescription("Same, for the distance sub-line under an off-screen (edge-clamped) label.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 2f), Array.Empty<object>())); CompassNameFontScale = config.Bind<float>("Fonts", "compass-name-scale", 1f, new ConfigDescription("Scales the name label above each compass-tape marker (only shown at all when Compass/show-names is on).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 2f), Array.Empty<object>())); CompassDistanceFontScale = config.Bind<float>("Fonts", "compass-distance-scale", 1f, new ConfigDescription("Scales the distance sub-label under each compass-tape marker.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 2f), Array.Empty<object>())); EnablePlayerLabels = config.Bind<bool>("Player-Labels", "enable-player-labels", true, "Master switch for Sense of Direction's player labels. Off hides them entirely (vanilla's own name labels are unaffected either way)."); PlayerLabelToggleKey = config.Bind<KeyCode>("Player-Labels", "toggle-key", (KeyCode)103, "Key that shows/hides player labels, per display-mode below. Only a single key can be bound here, not a combination like Ctrl+G."); PlayerLabelDisplayMode = config.Bind<LabelDisplayMode>("Player-Labels", "display-mode", LabelDisplayMode.Toggle, "Toggle: press toggle-key to show/hide labels. AlwaysOn: labels are always visible (toggle-key does nothing). Hold: labels show while toggle-key is held down."); HoldShownDuration = config.Bind<float>("Player-Labels", "hold-shown-duration", 1.5f, new ConfigDescription("Hold mode only: how many seconds labels stay visible after the key is released (also covers a quick tap).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>())); PlayerLabelMaxDistanceMeters = config.Bind<float>("Player-Labels", "max-distance-meters", 1000f, new ConfigDescription("A player's label stops showing beyond this distance. Lower it if you'd rather only track teammates who are actually nearby, or raise it to cover longer sightlines.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(50f, 2000f), Array.Empty<object>())); PlayerLabelNameFontSize = config.Bind<float>("Player-Labels", "name-font-size", 28f, new ConfigDescription("Base font size of each player's name label, before the Fonts section's on-screen/off-screen name scale is applied on top.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 60f), Array.Empty<object>())); PlayerLabelDistanceFontSize = config.Bind<float>("Player-Labels", "distance-font-size", 18f, new ConfigDescription("Base font size of the distance sub-line under each name label, before the Fonts section's distance scale is applied on top.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(8f, 40f), Array.Empty<object>())); ShowPlayerLabelDistance = config.Bind<bool>("Player-Labels", "show-distance", true, "Show the distance sub-line under each name label."); ShowStatusBadges = config.Bind<bool>("Player-Labels", "show-status-badges", true, "Show the host crown / unconscious / dead badges on each label."); UseCharacterColor = config.Bind<bool>("Player-Labels", "use-character-color", true, "Color each label's name with that player's own character color instead of the vanilla name-label color."); ReplaceVanillaLabels = config.Bind<bool>("Player-Labels", "replace-vanilla-labels", false, "Hide the game's own close-range player name labels entirely, so Sense of Direction's labels are the only ones ever shown. Normally the two systems hand off to each other instead."); ShowPlayerSkeleton = config.Bind<bool>("Player-Labels", "show-skeleton", false, "Draw each player's skeleton over the world, visible through walls and terrain. Shows and hides together with the labels themselves, so the display-mode and toggle-key above apply to it too. Off by default: it gives away a lot more than a name label does."); PlayerSkeletonLineThickness = config.Bind<float>("Player-Labels", "skeleton-line-thickness", 2f, new ConfigDescription("How thick the skeleton's bones are drawn. Thickness stays the same on screen at any distance, so a far-off player is still a readable stick figure rather than a hairline.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 8f), Array.Empty<object>())); PlayerSkeletonUseCharacterColor = config.Bind<bool>("Player-Labels", "skeleton-use-character-color", true, "Color each skeleton with that player's own character color. Off draws them all in the vanilla name-label color instead. Separate from use-character-color above, so the skeletons and the name labels can be colored differently."); ShowPlayerSkeletonJoints = config.Bind<bool>("Player-Labels", "skeleton-show-joints", true, "Draw a dot at each joint of the skeleton, on top of the bones."); EnableCampfireIndicator = config.Bind<bool>("Campfire", "enable-campfire-indicator", true, "Show an always-on edge-of-screen indicator pointing at the current segment's campfire (the one you're trying to reach next), so you always know which way to go. Turn it off if you'd rather find your own way up and keep the rest of the mod."); ShowCampfireDistance = config.Bind<bool>("Campfire", "show-distance", true, "Show the distance sub-line under the campfire indicator."); RemoveVisibilityCutoff = config.Bind<bool>("Pings", "remove-visibility-cutoff", true, "Vanilla silently refuses to even spawn a ping's visual once its pinging player is more than ~45m from you; turning this on makes far pings still show up at all. Most of the other Pings settings only matter once this is on."); EnablePingScaling = config.Bind<bool>("Pings", "enable-scaling", true, "Scale ping visuals up the further away they are, well past vanilla's own hard-capped scale, so far pings stay easy to spot."); PingScaleMultiplier = config.Bind<float>("Pings", "scale-multiplier", 1f, new ConfigDescription("Extra multiplier applied on top of vanilla's own (uncapped, see remove-visibility-cutoff) ping scale. 1x is vanilla's own uncapped size; higher makes every ping bigger regardless of distance.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 3f), Array.Empty<object>())); EnablePingRipple = config.Bind<bool>("Pings", "enable-ripple", true, "Show an expanding ring in the pinging player's own character color at the ping location, so it reads against similarly-colored terrain. Press your ping key to preview this here."); EnablePingOffScreenIndicator = config.Bind<bool>("Pings", "enable-offscreen-indicator", true, "Show an edge-of-screen arrow pointing toward an active ping when it's off-screen, same mechanism as the player-label/campfire indicators. Only the arrow; the distance line below is show-distance's own call. Does nothing while General/ping-placement is CompassOnly, which hides the whole edge-of-screen widget anyway."); ShowPingDistanceLabel = config.Bind<bool>("Pings", "show-distance", true, "Show a distance sub-line under the ping indicator."); EnableGhostPing = config.Bind<bool>("Pings", "enable-ghost-ping", true, "Let dead players keep pinging as ghosts (vanilla blocks pinging once dead), colored using their own character color same as when alive. Requires both sides to have this mod installed."); EnablePingAudioBoost = config.Bind<bool>("Ping-Audio", "enable-audio-boost", true, "Drastically reduce the ping sound's distance falloff so it's audible from much further away, while sounding unchanged up close. The rest of this section does nothing while this is off."); PingAudioRangeMeters = config.Bind<float>("Ping-Audio", "range-meters", 600f, new ConfigDescription("Ping sound's max audible range (vanilla is 150).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(150f, 2000f), Array.Empty<object>())); PingAudioMinDistanceMeters = config.Bind<float>("Ping-Audio", "min-distance-meters", 10f, new ConfigDescription("Distance under which the ping sound plays at full volume before it starts falling off toward range-meters.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 50f), Array.Empty<object>())); PingAudioVolumeMultiplier = config.Bind<float>("Ping-Audio", "volume-multiplier", 0.85f, new ConfigDescription("Multiplier on the ping sound's own base (close-range) volume. The far-range audibility boost also makes it slightly too loud up close, so this trims that back down.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.3f, 1.5f), Array.Empty<object>())); EnablePingAntiSpam = config.Bind<bool>("Ping-Anti-Spam", "enable-anti-spam", true, "Rate-limits how often *other* players' pings actually render/play once they're pinging rapidly, so spamming the ping key isn't more disruptive than vanilla now that pings are bigger/louder. A short burst always goes through instantly; only once someone keeps spamming does \"slow mode\" kick in, queueing further pings to arrive at a throttled rate instead (never silently dropped, unless the queue itself is full; see max-queue-length). Never applies to your own pings."); PingAntiSpamFreeSpamCount = config.Bind<int>("Ping-Anti-Spam", "free-spam-count", 3, new ConfigDescription("How many pings in a row from the same player always show up instantly before slow mode kicks in.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20), Array.Empty<object>())); PingAntiSpamSlowModeIntervalSeconds = config.Bind<float>("Ping-Anti-Spam", "slow-mode-interval-seconds", 0.5f, new ConfigDescription("Once slow mode kicks in, queued pings from that player are spaced at least this far apart before they're actually shown to you.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 5f), Array.Empty<object>())); PingAntiSpamMaxQueueLength = config.Bind<int>("Ping-Anti-Spam", "max-queue-length", 2, new ConfigDescription("How many of a spamming player's pings can be queued up waiting to show at once while in slow mode. Any further ping while the queue's already full is dropped entirely rather than queued.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10), Array.Empty<object>())); PingAntiSpamResetSeconds = config.Bind<float>("Ping-Anti-Spam", "reset-seconds", 2f, new ConfigDescription("How long a player has to go without pinging (with their queue fully drained) before slow mode fully resets to normal.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 30f), Array.Empty<object>())); EnableItemPings = config.Bind<bool>("Item-Pings", "enable-item-pings", true, "Highlight nearby items/luggage when you ping near them, with a name and distance label, as a native replacement for the (broken/unmaintained) PingItems mod by memiczny."); ItemPingDurationSeconds = config.Bind<float>("Item-Pings", "duration-seconds", 6f, new ConfigDescription("How long an item/luggage highlight stays visible before fading out (ends early regardless if the item is picked up or the luggage is opened).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 20f), Array.Empty<object>())); EnableItemPingGrouping = config.Bind<bool>("Item-Pings", "enable-grouping", true, "Group multiple nearby items of the same kind into a single highlight showing a count (e.g. \"3x Coconut\") instead of one highlight per item."); EnableCreaturePings = config.Bind<bool>("Item-Pings", "enable-creature-pings", true, "Also highlight creatures (beetles, spiders, zombies, ...) when pinged, same as items/luggage. OFF leaves creature pings behaving like vanilla (so it won't work for them)."); UseNativeItemPingIcons = config.Bind<bool>("Item-Pings", "use-native-icons", true, "Show the item's own in-game icon (the art its inventory slot uses, e.g. an actual bandage for a pinged bandage) as the highlight's crosshair and its compass marker, instead of the mod's generic item-ping icon. Only items (and the campfire) have an icon in the game at all; luggage, creatures and hazards keep the generic icon either way. Works with custom modded items as well."); ItemPingNameMode = config.Bind<ItemPingNameMode>("Item-Pings", "name-mode", SenseOfDirection.ItemPings.ItemPingNameMode.Always, "Always: every highlight shows what it is. HideWhenIconShown: anything already showing its own in-game icon (see use-native-icons) drops its name, since the icon says what it is (luggage, creatures and hazards have no icon, so they keep theirs). Never: no names at all. A grouped ping keeps its count regardless (a hidden name still shows \"3x\")."); ShowItemPingDistance = config.Bind<bool>("Item-Pings", "show-distance", true, "Show a distance sub-line under the item/luggage highlight."); EnableItemPingOffScreenIndicator = config.Bind<bool>("Item-Pings", "enable-offscreen-indicator", true, "Show an edge-of-screen arrow pointing toward a highlighted item/luggage when it's off-screen, same mechanism as the ping indicator. Does nothing while General/item-ping-placement is CompassOnly, which hides the whole edge-of-screen widget anyway."); ItemPingDetectionRadiusMeters = config.Bind<float>("Item-Ping-Detection", "item-radius-meters", 2f, new ConfigDescription("How close a ping needs to land to an item for it to get highlighted.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 10f), Array.Empty<object>())); ItemPingCrossKindRadiusMeters = config.Bind<float>("Item-Ping-Detection", "cross-kind-radius-meters", 0.75f, new ConfigDescription("How close a *different* kind of item has to be to the item you actually pinged before it also gets highlighted. Items of the same kind still group together across the full item-radius-meters (that's what makes a \"2x COCONUT\" grouping), but a different item only counts if it was pretty much directly aimed at too, so pinging one item in a luggage doesn't drag in an unrelated one sitting next to it.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>())); LuggagePingDetectionRadiusMeters = config.Bind<float>("Item-Ping-Detection", "luggage-radius-meters", 3.5f, new ConfigDescription("Same as item-radius-meters, but for luggage, which is a bigger target.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 15f), Array.Empty<object>())); EnableItemPingHitAssist = config.Bind<bool>("Item-Ping-Detection", "enable-hit-assist", true, "Widen the ping's own aim raycast so it can land directly on an item/luggage's own collider (not just terrain/ground), instead of phasing through to whatever's behind it. Fixes hard-to-ping items like a coconut up a tree or a small dropped item. Off falls back to vanilla's own terrain-only ping raycast."); ItemPingHitboxRadiusMeters = config.Bind<float>("Item-Ping-Detection", "hitbox-radius-meters", 0.35f, new ConfigDescription("Only used when enable-hit-assist is on. Treats the ping raycast as a sphere of this radius instead of an infinitely-thin line, so aiming near (not pixel-perfect on) an item's collider still hits it. 0 disables the sphere, falling back to a plain (still item-widened) raycast.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1.5f), Array.Empty<object>())); EnableItemPingRayAssist = config.Bind<bool>("Item-Ping-Detection", "enable-ray-assist", true, "Also count an item/luggage as pinged if it's close enough to your aim line, independent of physics entirely. Needed for items that aren't pushable/hittable until first picked up (an unpicked coconut on a tree, berries on a bush, something freshly spawned from opened luggage); their collider is disabled until then, so no physics raycast (not even enable-hit-assist's) can ever land on them."); ItemPingRayAssistRadiusMeters = config.Bind<float>("Item-Ping-Detection", "ray-assist-radius-meters", 0.6f, new ConfigDescription("Only used when enable-ray-assist is on. How far off your exact aim line an item/luggage can be and still count as pinged.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>())); EnableCompass = config.Bind<bool>("Compass", "enable-compass", true, "Master switch for the top-of-screen compass tape. Off hides it entirely regardless of any individual mechanic's placement setting."); CompassWidthPixels = config.Bind<float>("Compass", "width-pixels", 640f, new ConfigDescription("Width of the compass tape, in pixels at the 1920-wide reference resolution (scales with actual resolution same as everything else). Wider shows more of the horizon at once.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(300f, 1400f), Array.Empty<object>())); CompassMarkerGapPixels = config.Bind<float>("Compass", "marker-gap-pixels", 40f, new ConfigDescription("Vertical gap between the tick row and the marker baseline below it, on top of a small fixed minimum. Raise this for more breathing room (e.g. after turning on show-names).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(40f, 200f), Array.Empty<object>())); CompassVerticalOffsetPixels = config.Bind<float>("Compass", "vertical-offset-pixels", 28f, new ConfigDescription("Gap between the top of the screen and the compass tape.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 300f), Array.Empty<object>())); CompassHorizontalOffsetPixels = config.Bind<float>("Compass", "horizontal-offset-pixels", 0f, new ConfigDescription("Horizontal offset from top-center. 0 keeps it centered; positive shifts right, negative shifts left (e.g. to dodge another HUD mod's own top-of-screen element).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-800f, 800f), Array.Empty<object>())); CompassFovDegrees = config.Bind<float>("Compass", "fov-degrees", 150f, new ConfigDescription("How much of the horizon (in degrees) is visible on the tape at once before a heading/marker slides off the edge. Lower feels closer to your actual field of view; higher gives more lead time for things approaching from the side.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(60f, 180f), Array.Empty<object>())); CompassIconSizePixels = config.Bind<float>("Compass", "icon-size-pixels", 26f, new ConfigDescription("Size of each marker's icon on the compass.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(12f, 64f), Array.Empty<object>())); CompassElevationThresholdMeters = config.Bind<float>("Compass", "elevation-threshold-meters", 3f, new ConfigDescription("A marker only gets an up/down elevation arrow once its target is at least this many meters above/below you, which avoids a flickering arrow for things that are roughly level with you.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 30f), Array.Empty<object>())); CompassShowDegreeNumbers = config.Bind<bool>("Compass", "show-degree-numbers", false, "Show a numeric heading (e.g. \"105\") at every non-cardinal tick instead of leaving it as a plain unlabeled line. N/E/S/W are always lettered either way."); CompassShowNames = config.Bind<bool>("Compass", "show-names", false, "Show a name label above each compass marker that has one (players, item/creature pings, the campfire). Distances still show independently of this setting."); CompassShowDistances = config.Bind<bool>("Compass", "show-distances", true, "Show a distance sub-label under each compass marker."); CompassRequiresHoldingItem = config.Bind<bool>("Compass", "requires-holding-item", false, "Only show the compass tape while the local player is actually holding an in-game Compass item, instead of it always being visible."); CompassLineColor = config.Bind<CompassLineColor>("Compass", "line-color", SenseOfDirection.Compass.CompassLineColor.White, "Base color of the compass tape's heading ticks/labels and baseline stripe (true north keeps its own dark red accent regardless)."); CompassLineThicknessMultiplier = config.Bind<float>("Compass", "line-thickness-multiplier", 1f, new ConfigDescription("Scales the thickness of the compass tape's tick lines (both cardinal and minor) and its baseline stripe. 1 keeps the shipped thickness; higher values make the lines bolder.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 3f), Array.Empty<object>())); CompassClampIconsToEdge = config.Bind<bool>("Compass", "clamp-icons-to-edge", false, "Markers that would otherwise not be visible (outside the compass FOV window) are instead clamped to the nearest left/right edge of the tape and shown dimmed, like a mini radar, instead of not appearing at all."); EnablePirateCompassLuggageIndicator = config.Bind<bool>("Pirate-Compass", "enable-pirate-compass-luggage-indicator", true, "While holding a Pirate's Compass, show an indicator pointing at the nearest unopened luggage - the same target its own in-game needle points at, made legible as a real edge-of-screen/compass marker with a distance label instead of only a wobbling 3D needle."); ShowPirateCompassLuggageName = config.Bind<bool>("Pirate-Compass", "show-luggage-name", true, "Show a name label (\"LUGGAGE\") above the Pirate's Compass indicator."); ShowPirateCompassLuggageDistance = config.Bind<bool>("Pirate-Compass", "show-luggage-distance", true, "Show a distance sub-label under the Pirate's Compass indicator."); EnablePirateCompassLuggageOffScreenIndicator = config.Bind<bool>("Pirate-Compass", "enable-off-screen-indicator", true, "Show an off-screen arrow pointing toward the nearest unopened luggage while it isn't in view. Off shows the indicator only once it's actually on screen."); EnableLuggagePing = config.Bind<bool>("Luggage-Ping", "enable-luggage-ping", true, "Master switch: press key below to highlight every unopened luggage within radius-meters of you, visible only to yourself."); LuggagePingKey = config.Bind<KeyCode>("Luggage-Ping", "key", (KeyCode)116, "Key that triggers a luggage ping."); LuggagePingRadiusMeters = config.Bind<float>("Luggage-Ping", "radius-meters", 100f, new ConfigDescription("How far around you luggage gets highlighted. Capped well below the level's own size so this can't turn into a full map-wide luggage ESP.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 250f), Array.Empty<object>())); LuggagePingDurationSeconds = config.Bind<float>("Luggage-Ping", "duration-seconds", 6f, new ConfigDescription("How long each highlighted luggage stays visible before fading out (ends early regardless if it's opened first).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 20f), Array.Empty<object>())); LuggagePingCooldownSeconds = config.Bind<float>("Luggage-Ping", "cooldown-seconds", 15f, new ConfigDescription("How long you have to wait between luggage pings. Trying to ping again while this is still running shows a brief on-screen reminder instead of doing nothing silently. 0 disables the cooldown entirely.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 120f), Array.Empty<object>())); EnableGhostFreeCam = config.Bind<bool>("Ghost-Free-Cam", "enable-ghost-free-cam", true, "Lets dead players fly a free camera instead of being stuck in vanilla's third-person spectate view. Unlike every other setting in this mod, this one and the two below it are host-controlled: only the room host's own value for these three settings ever takes effect for every player, the same way enable-ghost-ping requires both sides to have this mod installed. That's because letting each client fly unlimited distances would be an unfair, effectively ESP-like advantage other players in the same run never agreed to. If the host doesn't have this mod installed, ghost free-cam simply doesn't work for anyone, same as ghost pinging. Your own value here still matters if you end up being the host."); GhostFreeCamMaxDistanceMeters = config.Bind<float>("Ghost-Free-Cam", "max-distance-meters", 50f, new ConfigDescription("Host-controlled, see enable-ghost-free-cam. How far a ghost's free camera can scout from whichever living player they're currently spectating before being pulled back, like a chain of this length. Ignored entirely when unlimited-range is on.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 500f), Array.Empty<object>())); GhostFreeCamUnlimitedRange = config.Bind<bool>("Ghost-Free-Cam", "unlimited-range", false, "Host-controlled, see enable-ghost-free-cam. Removes max-distance-meters' leash entirely, letting ghosts free-cam anywhere on the map. Although note that the leash is what keeps this mechanic from being overpowered."); GhostFreeCamToggleKey = config.Bind<KeyCode>("Ghost-Free-Cam", "toggle-key", (KeyCode)118, "Purely local. Key that toggles free-fly camera mode on/off while you're dead and spectating; each player binds their own. Only does anything while enable-ghost-free-cam ends up effectively on (see that setting for how that's decided)."); GhostFreeCamMoveSpeedMetersPerSecond = config.Bind<float>("Ghost-Free-Cam", "move-speed-meters-per-second", 15f, new ConfigDescription("Purely local. How fast the free camera flies. PEAK's own built-in dev free-camera controller (reused for the first pass of this feature) turned out to feel unusably slow in practice, so this mod drives its own movement directly in real-world meters/second instead of relying on that controller's tuning.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 100f), Array.Empty<object>())); GhostFreeCamSprintMultiplier = config.Bind<float>("Ghost-Free-Cam", "sprint-multiplier", 3f, new ConfigDescription("Purely local. Speed multiplier while holding Left Shift.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), Array.Empty<object>())); GhostFreeCamShowCrosshair = config.Bind<bool>("Ghost-Free-Cam", "show-crosshair", true, "Purely local. Shows a small reticle at the center of the screen while free-cam is engaged, so you have something to aim regular pings at (spectate mode otherwise has no crosshair at all)."); GhostFreeCamShowKeyHint = config.Bind<bool>("Ghost-Free-Cam", "show-key-hint", true, "Purely local. Shows a key badge + short label near vanilla's own \"you are a ghost\" panel reminding you which key toggles free-cam (and whether it'll engage or disengage), since vanilla's UI never mentions this mod's keybind at all."); HideAllGhosts = config.Bind<bool>("Ghost-Free-Cam", "hide-all-ghosts", false, "Purely local. Hides every dead player's ghost body from your own view entirely. Doesn't affect anyone else, and doesn't affect your own ability to spectate/free-cam while dead yourself."); EnableDebugLogging = config.Bind<bool>("Debug", "enable-debug-logging", false, "Log extra diagnostic detail to the BepInEx console/log file."); EnableIndicatorTestHarness = config.Bind<bool>("Debug", "enable-indicator-test-harness", false, "Spawn a handful of fixed dummy world points around the camera to visually verify the edge-of-screen indicator framework. Dev/QA tool only; leave off for normal play."); EnableZombieDebugEsp = config.Bind<bool>("Debug", "enable-zombie-debug-esp", false, "Dev/QA aid: always-visible edge-of-screen label for every naturally-spawned zombie in the level, through walls, to speed up testing zombie-ping detection without hunting a whole level for a rare spawn. Not a real feature; leave off for normal play."); } } public static class PluginInfo { public const string Guid = "OnlyCook.SenseOfDirection"; public const string Name = "Sense of Direction"; public const string Version = "1.0.1"; } } namespace SenseOfDirection.Ui { internal interface IConfigBoundSetting { string DisplayName { get; } string Tooltip { get; } string DefaultValueText { get; } Setting Setting { get; } void ResetToDefault(); void RefreshFromConfig(); } internal class ConfigSettingHandler : ISettingHandler { public void SaveSetting(Setting setting) { } public T GetSetting<T>() where T : Setting { return default(T); } public IEnumerable<Setting> GetAllSettings() { return Array.Empty<Setting>(); } } internal static class ConfigSettingNaming { internal static string DisplayName(ConfigEntryBase entry) { if (!ConfigLocalizationTable.TryGet(entry, out var result)) { return entry.Definition.Key.Replace('-', ' ').ToUpperInvariant(); } return result.Name; } internal static string Tooltip(ConfigEntryBase entry) { object obj; if (!ConfigLocalizationTable.TryGet(entry, out var result)) { ConfigDescription description = entry.Description; obj = ((description != null) ? description.Description : null); if (obj == null) { return string.Empty; } } else { obj = DescriptionPlaceholders.Resolve(result.Description); } return (string)obj; } internal static string EnumDisplayName(Enum value) { string fallback = Regex.Replace(value.ToString(), "(?<!^)([A-Z])", " $1").ToUpperInvariant(); return EnumLocalizationTable.Get(value.GetType(), value.ToString(), fallback); } } internal class ConfigFloatSetting : FloatSetting, IConfigBoundSetting { private readonly ConfigEntry<float> _entry; private readonly ISettingHandler _handler; public string DisplayName { get; } public string Tooltip { get; } public string DefaultValueText { get; private set; } public Setting Setting => (Setting)(object)this; internal ConfigFloatSetting(ConfigEntry<float> entry, ISettingHandler handler) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0034: 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) _entry = entry; _handler = handler; DisplayName = ConfigSettingNaming.DisplayName((ConfigEntryBase)(object)entry); Tooltip = ConfigSettingNaming.Tooltip((ConfigEntryBase)(object)entry); float2 minMaxValue = ((FloatSetting)this).GetMinMaxValue(); ((FloatSetting)this).MinValue = minMaxValue.x; ((FloatSetting)this).MaxValue = minMaxValue.y; ((FloatSetting)this).Value = Mathf.Clamp(entry.Value, ((FloatSetting)this).MinValue, ((FloatSetting)this).MaxValue); DefaultValueText = ((FloatSetting)this).Expose((float)((ConfigEntryBase)entry).DefaultValue); } public override void ApplyValue() { _entry.Value = ((FloatSetting)this).Value; } public override void Save(ISettingsSaveLoad saver) { } public override void Load(ISettingsSaveLoad loader) { RefreshFromConfig(); } protected override float GetDefaultValue() { return (float)((ConfigEntryBase)_entry).DefaultValue; } protected override float2 GetMinMaxValue() { //IL_0059: 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) ConfigDescription description = ((ConfigEntryBase)_entry).Description; if (((description != null) ? description.AcceptableValues : null) is AcceptableValueRange<float> val) { return new float2(val.MinValue, val.MaxValue); } float num = (float)((ConfigEntryBase)_entry).DefaultValue; return new float2(0f, Mathf.Max(1f, num * 2f)); } public override string Expose(float result) { if (!(((FloatSetting)this).MaxValue - ((FloatSetting)this).MinValue > 20f)) { return result.ToString("0.00"); } return Mathf.RoundToInt(result).ToString(); } public void ResetToDefault() { ((FloatSetting)this).SetValue(((FloatSetting)this).GetDefaultValue(), _handler, false); } public void RefreshFromConfig() { ((FloatSetting)this).SetValue(_entry.Value, _handler, false); } } internal class ConfigBoolSetting : OffOnSetting, IConfigBoundSetting, ICustomLocalizedEnumSetting { private readonly ConfigEntry<bool> _entry; private readonly ISettingHandler _handler; public string DisplayName { get; } public string Tooltip { get; } public string DefaultValueText { get; } public Setting Setting => (Setting)(object)this; internal ConfigBoolSetting(ConfigEntry<bool> entry, ISettingHandler handler) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) _entry = entry; _handler = handler; DisplayName = ConfigSettingNaming.DisplayName((ConfigEntryBase)(object)entry); Tooltip = ConfigSettingNaming.Tooltip((ConfigEntryBase)(object)entry); DefaultValueText = ConfigSettingNaming.EnumDisplayName((Enum)(object)((EnumSetting<OffOnMode>)(object)this).GetDefaultValue()); ((EnumSetting<OffOnMode>)this).Value = (OffOnMode)(entry.Value ? 1 : 0); } public override void ApplyValue() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 _entry.Value = (int)((EnumSetting<OffOnMode>)this).Value == 1; } public override void Save(ISettingsSaveLoad saver) { } public override void Load(ISettingsSaveLoad loader) { RefreshFromConfig(); } protected override OffOnMode GetDefaultValue() { if ((bool)((ConfigEntryBase)_entry).DefaultValue) { return (OffOnMode)1; } return (OffOnMode)0; } public override List<LocalizedString> GetLocalizedChoices() { return null; } public List<string> GetCustomLocalizedChoices() { //IL_002f: Unknown result type (might be due to invalid IL or missing references) List<string> list = new List<string>(); string[] names = Enum.GetNames(typeof(OffOnMode)); foreach (string value in names) { list.Add(ConfigSettingNaming.EnumDisplayName((Enum)(object)(OffOnMode)Enum.Parse(typeof(OffOnMode), value))); } return list; } public void RegisterCustomLocalized(Action action) { } public void DeregisterCustomLocalized(Action action) { } public void ResetToDefault() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected I4, but got Unknown ((EnumSetting<OffOnMode>)(object)this).SetValue((int)((EnumSetting<OffOnMode>)(object)this).GetDefaultValue(), _handler, false); } public void RefreshFromConfig() { ((EnumSetting<OffOnMode>)(object)this).SetValue(_entry.Value ? 1 : 0, _handler, false); } } internal class ConfigEnumSetting<T> : EnumSetting<T>, IConfigBoundSetting, ICustomLocalizedEnumSetting where T : unmanaged, Enum { private readonly ConfigEntry<T> _entry; private readonly ISettingHandler _handler; public string DisplayName { get; } public string Tooltip { get; } public string DefaultValueText { get; } public Setting Setting => (Setting)(object)this; internal ConfigEnumSetting(ConfigEntry<T> entry, ISettingHandler handler) { _entry = entry; _handler = handler; DisplayName = ConfigSettingNaming.DisplayName((ConfigEntryBase)(object)entry); Tooltip = ConfigSettingNaming.Tooltip((ConfigEntryBase)(object)entry); DefaultValueText = ConfigSettingNaming.EnumDisplayName((T)((ConfigEntryBase)entry).DefaultValue); base.Value = entry.Value; } public override void ApplyValue() { _entry.Value = base.Value; } public override void Save(ISettingsSaveLoad saver) { } public override void Load(ISettingsSaveLoad loader) { RefreshFromConfig(); } protected override T GetDefaultValue() { return (T)((ConfigEntryBase)_entry).DefaultValue; } public override List<LocalizedString> GetLocalizedChoices() { return null; } public List<string> GetCustomLocalizedChoices() { List<string> list = new List<string>(); string[] names = Enum.GetNames(typeof(T)); foreach (string value in names) { list.Add(ConfigSettingNaming.EnumDisplayName((T)Enum.Parse(typeof(T), value))); } return list; } public void RegisterCustomLocalized(Action action) { } public void DeregisterCustomLocalized(Action action) { } public void ResetToDefault() { ((EnumSetting<T>)this).SetValue(Convert.ToInt32(((EnumSetting<T>)this).GetDefaultValue()), _handler, false); } public void RefreshFromConfig() { ((EnumSetting<T>)this).SetValue(Convert.ToInt32(_entry.Value), _handler, false); } } internal static class ConfigSettingFactory { internal static IConfigBoundSetting Create(ConfigEntryBase entry, ISettingHandler handler) { if (!(entry is ConfigEntry<float> entry2)) { if (entry is ConfigEntry<bool> entry3) { return new ConfigBoolSetting(entry3, handler); } Type settingType = entry.SettingType; if (settingType.IsEnum) { return (IConfigBoundSetting)Activator.CreateInstance(typeof(ConfigEnumSetting<>).MakeGenericType(settingType), BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new object[2] { entry, handler }, null); } return null; } return new ConfigFloatSetting(entry2, handler); } } internal class DropdownOverlayFix : MonoBehaviour { private const string DropdownListName = "Dropdown List"; private const string BlockerName = "Blocker"; private const int ListSortingOrder = 30100; private const int BlockerSortingOrder = 30099; private TMP_Dropdown _dropdown; private RectTransform _rootCanvas; internal static void Attach(GameObject control, RectTransform rootCanvas) { TMP_Dropdown componentInChildren = control.GetComponentInChildren<TMP_Dropdown>(true); if (!((Object)(object)componentInChildren == (Object)null)) { DropdownOverlayFix dropdownOverlayFix = control.AddComponent<DropdownOverlayFix>(); dropdownOverlayFix._dropdown = componentInChildren; dropdownOverlayFix._rootCanvas = rootCanvas; } } private void LateUpdate() { if ((Object)(object)_dropdown == (Object)null) { return; } RaiseBlocker(); Transform val = ((Component)_dropdown).transform.Find("Dropdown List"); if ((Object)(object)val == (Object)null) { return; } val.SetParent((Transform)(object)_rootCanvas, true); val.SetAsLastSibling(); Canvas component = ((Component)val).GetComponent<Canvas>(); if ((Object)(object)component != (Object)null) { component.overrideSorting = true; component.sortingOrder = 30100; if ((Object)(object)((Component)val).GetComponent<GraphicRaycaster>() == (Object)null) { ((Component)val).gameObject.AddComponent<GraphicRaycaster>(); } } } private void RaiseBlocker() { Transform val = ((Transform)_rootCanvas).Find("Blocker"); if (!((Object)(object)val == (Object)null)) { Canvas component = ((Component)val).GetComponent<Canvas>(); if (!((Object)(object)component == (Object)null) && component.sortingOrder != 30099) { component.overrideSorting = true; component.sortingOrder = 30099; } } } } internal class JaggedPanel : MonoBehaviour { private Image _fillImage; private Image _grainImage; private RectTransform _rect; private int _jagFrame; private float _jagFrameTimer; private Vector2 _bakedSize = Vector2.zero; internal float Alpha { get; set; } = 1f; internal static JaggedPanel Create(RectTransform parent, string name, Vector2 size) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: 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_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Expected O, but got Unknown //IL_00c0: 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_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Expected O, but got Unknown //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0174: 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_017d: 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_0188: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: 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) GameObject val = new GameObject(name, new Type[2] { typeof(RectTransform), typeof(Image) }); RectTransform val2 = (RectTransform)val.transform; ((Transform)val2).SetParent((Transform)(object)parent, false); val2.sizeDelta = size; JaggedPanel jaggedPanel = val.AddComponent<JaggedPanel>(); jaggedPanel._rect = val2; jaggedPanel._fillImage = val.GetComponent<Image>(); jaggedPanel._fillImage.type = (Type)0; ((Graphic)jaggedPanel._fillImage).raycastTarget = true; GameObject val3 = new GameObject("GrainMask", new Type[3] { typeof(RectTransform), typeof(Image), typeof(Mask) }); RectTransform val4 = (RectTransform)val3.transform; ((Transform)val4).SetParent((Transform)(object)val2, false); val4.anchorMin = Vector2.zero; val4.anchorMax = Vector2.one; val4.offsetMin = new Vector2(11f, 11f); val4.offsetMax = new Vector2(-11f, -11f); Image component = val3.GetComponent<Image>(); component.sprite = PanelChrome.MaskSprite(128, Mathf.Max(1f, 15f)); component.type = (Type)1; ((Graphic)component).raycastTarget = false; val3.GetComponent<Mask>().showMaskGraphic = false; GameObject val5 = new GameObject("Grain", new Type[2] { typeof(RectTransform), typeof(Image) }); RectTransform val6 = (RectTransform)val5.transform; ((Transform)val6).SetParent((Transform)(object)val4, false); val6.anchorMin = Vector2.zero; val6.anchorMax = Vector2.one; val6.offsetMin = Vector2.zero; val6.offsetMax = Vector2.zero; jaggedPanel._grainImage = val5.GetComponent<Image>(); Texture2D val7 = PanelChrome.GrainTexture(); jaggedPanel._grainImage.sprite = Sprite.Create(val7, new Rect(0f, 0f, (float)((Texture)val7).width, (float)((Texture)val7).height), new Vector2(0.5f, 0.5f), 100f); ((Graphic)jaggedPanel._grainImage).raycastTarget = false; jaggedPanel.Rebake(); return jaggedPanel; } private void Update() { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) _jagFrameTimer += Time.unscaledDeltaTime; if (_jagFrameTimer >= 0.5f) { _jagFrameTimer = 0f; _jagFrame = (_jagFrame + 1) % 3; ApplyFrame(); } Rect rect = _rect.rect; if (((Rect)(ref rect)).size != _bakedSize) { Rebake(); } ApplyAlpha(); } private void Rebake() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) Rect rect = _rect.rect; _bakedSize = ((Rect)(ref rect)).size; ApplyFrame(); ApplyAlpha(); } private void ApplyFrame() { int width = Mathf.Max(1, Mathf.RoundToInt(_bakedSize.x)); int height = Mathf.Max(1, Mathf.RoundToInt(_bakedSize.y)); _fillImage.sprite = PanelChrome.PanelSprite(width, height, _jagFrame); } private void ApplyAlpha() { //IL_001b: 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) ((Graphic)_fillImage).color = new Color(1f, 1f, 1f, Alpha); ((Graphic)_grainImage).color = new Color(1f, 1f, 1f, Alpha); } } internal static class NativeSettingCells { private const float LabelInset = 18f; private const float LabelHeight = 30f; private const float LabelTopPadding = 8f; private const float ControlHeight = 52f; private const float ControlBottomPadding = 12f; internal const float RowHeight = 108f; private const float DropdownBoxPadding = 4f; private const float RowCornerRadius = 12f; private static bool _dumpedOneDropdown; private static readonly Color RowPlateColor = new Color(14f / 85f, 0.21960784f, 42f / 85f, 0.92f); internal static bool TryFindPrefab() { InputCellMapper instance = SingletonAsset<InputCellMapper>.Instance; if ((Object)(object)instance != (Object)null && (Object)(object)instance.EnumSettingCell != (Object)null) { return (Object)(object)instance.FloatSettingCell != (Object)null; } return false; } internal static GameObject CreateRow(RectTransform parent, IConfigBoundSetting bound, ISettingHandler handler, Action<string, string> onHover, RectTransform rootCanvas) { //IL_0029: 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) //IL_003a: Expected O, but got Unknown //IL_0044: Expected O, but got Unknown GameObject settingUICell = bound.Setting.GetSettingUICell(); if ((Object)(object)settingUICell == (Object)null) { return null; } GameObject obj = CreatePlate(parent, bound.DisplayName); RectTransform val = (RectTransform)obj.transform; BuildLabel(val, bound.DisplayName); AttachHoverDescription(dropdown: BuildControl(val, settingUICell, bound, handler, rootCanvas), rowGo: obj, tooltip: bound.Tooltip, defaultValueText: bound.DefaultValueText, onHover: onHover); return obj; } internal static GameObject CreateKeyBindRow(RectTransform parent, ConfigEntry<KeyCode> entry, Action<string, string> onHover) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_0026: Expected O, but got Unknown string displayName = ConfigSettingNaming.DisplayName((ConfigEntryBase)(object)entry); GameObject obj = CreatePlate(parent, displayName); RectTransform val = (RectTransform)obj.transform; BuildLabel(val, displayName); BuildKeyBindControl(val, entry); AttachHoverDescription(obj, ConfigSettingNaming.Tooltip((ConfigEntryBase)(object)entry), ((ConfigEntryBase)entry).DefaultValue.ToString().ToUpperInvariant(), onHover, null); return obj; } private static GameObject CreatePlate(RectTransform parent, string displayName) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0042: 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_005a: 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_0082: Expected O, but got Unknown GameObject val = new GameObject("SoD.SettingRow." + displayName, new Type[2] { typeof(RectTransform), typeof(Image) }); ((Transform)(RectTransform)val.transform).SetParent((Transform)(object)parent, false); Image component = val.GetComponent<Image>(); component.sprite = PanelChrome.MakeRoundedSprite(64, 12f, 0f, Color.white, Color.white); component.type = (Type)1; ((Graphic)component).color = RowPlateColor; ((Graphic)component).raycastTarget = true; return val; } private static void BuildKeyBindControl(RectTransform row, ConfigEntry<KeyCode> entry) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: 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_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: 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_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_02b6: Unknown result type (might be due to invalid IL or missing references) //IL_02c0: Expected O, but got Unknown RectTransform val = (RectTransform)new GameObject("Control", new Type[1] { typeof(RectTransform) }).transform; ((Transform)val).SetParent((Transform)(object)row, false); val.anchorMin = new Vector2(0f, 0f); val.anchorMax = new Vector2(1f, 0f); val.pivot = new Vector2(0.5f, 0f); val.offsetMin = new Vector2(18f, 12f); val.offsetMax = new Vector2(-18f, 64f); InputCellMapper instance = SingletonAsset<InputCellMapper>.Instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.FloatSettingCell == (Object)null) { return; } GameObject val2 = Object.Instantiate<GameObject>(instance.FloatSettingCell, (Transform)(object)val); val2.SetActive(true); RectTransform val3 = (RectTransform)val2.transform; val3.anchorMin = Vector2.zero; val3.anchorMax = Vector2.one; val3.offsetMin = Vector2.zero; val3.offsetMax = Vector2.zero; FloatSettingUI component = val2.GetComponent<FloatSettingUI>(); if ((Object)(object)component == (Object)null || (Object)(object)component.inputField == (Object)null) { Object.Destroy((Object)(object)val2); return; } TMP_InputField inputField = component.inputField; GameObject gameObject = ((Component)inputField).gameObject; TMP_Text textComponent = inputField.textComponent; if ((Object)(object)inputField.placeholder != (Object)null) { Object.DestroyImmediate((Object)(object)((Component)inputField.placeholder).gameObject); } if ((Object)(object)component.slider != (Object)null) { Object.DestroyImmediate((Object)(object)((Component)component.slider).gameObject); } Object.DestroyImmediate((Object)(object)inputField); Object.DestroyImmediate((Object)(object)component); RectTransform val4 = (RectTransform)gameObject.transform; val4.anchorMin = Vector2.zero; val4.anchorMax = Vector2.one; val4.offsetMin = new Vector2(20f, 4f); val4.offsetMax = new Vector2(-20f, -4f); if ((Object)(object)textComponent != (Object)null) { RectTransform val5 = (RectTransform)textComponent.transform; val5.anchorMin = Vector2.zero; val5.anchorMax = Vector2.one; val5.offsetMin = new Vector2(14f, 0f); val5.offsetMax = new Vector2(-14f, 0f); textComponent.alignment = (TextAlignmentOptions)514; textComponent.enableWordWrapping = false; textComponent.enableAutoSizing = true; textComponent.fontSizeMin = 14f; textComponent.fontSizeMax = 26f; ((Graphic)textComponent).raycastTarget = false; } KeyRebindControl keyRebindControl = gameObject.AddComponent<KeyRebindControl>(); keyRebindControl.Entry = entry; keyRebindControl.Label = textComponent; keyRebindControl.ShowCurrentKey(); Button val6 = gameObject.GetComponent<Button>(); if ((Object)(object)val6 == (Object)null) { val6 = gameObject.AddComponent<Button>(); } ((UnityEvent)val6.onClick).AddListener(new UnityAction(keyRebindControl.BeginListening)); } private static void BuildLabel(RectTransform row, string displayName) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0067: 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_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_009b: 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) GameObject val = new GameObject("Label", new Type[2] { typeof(RectTransform), typeof(TextMeshProUGUI) }); RectTransform val2 = (RectTransform)val.transform; ((Transform)val2).SetParent((Transform)(object)row, false); val2.anchorMin = new Vector2(0f, 1f); val2.anchorMax = new Vector2(1f, 1f); val2.pivot = new Vector2(0.5f, 1f); val2.offsetMin = new Vector2(18f, -38f); val2.offsetMax = new Vector2(-18f, -8f); TextMeshProUGUI component = val.GetComponent<TextMeshProUGUI>(); ((TMP_Text)component).text = displayName; ((TMP_Text)component).fontSize = 21f; ((Graphic)component).color = PanelChrome.BodyColor; ((TMP_Text)component).alignment = (TextAlignmentOptions)4097; ((TMP_Text)component).enableWordWrapping = false; ((TMP_Text)component).overflowMode = (TextOverflowModes)3; ((TMP_Text)component).enableAutoSizing = true; ((TMP_Text)component).fontSizeMin = 14f; ((TMP_Text)component).fontSizeMax = 21f; ((Graphic)component).raycastTarget = false; if ((Object)(object)NativeAssets.Font != (Object)null) { ((TMP_Text)component).font = NativeAssets.Font; } if ((Object)(object)NativeAssets.OutlineMaterial != (Object)null) { ((TMP_Text)component).fontSharedMaterial = NativeAssets.OutlineMaterial; } } private static TMP_Dropdown BuildControl(RectTransform row, GameObject controlPrefab, IConfigBoundSetting bound, ISettingHandler handler, RectTransform rootCanvas) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_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_00bd: 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_00c8: 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_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) RectTransform val = (RectTransform)new GameObject("Control", new Type[1] { typeof(RectTransform) }).transform; ((Transform)val).SetParent((Transform)(object)row, false); val.anchorMin = new Vector2(0f, 0f); val.anchorMax = new Vector2(1f, 0f); val.pivot = new Vector2(0.5f, 0f); val.offsetMin = new Vector2(18f, 12f); val.offsetMax = new Vector2(-18f, 64f); SettingInputUICell component = Object.Instantiate<GameObject>(controlPrefab, (Transform)(object)val).GetComponent<SettingInputUICell>(); ((Component)component).gameObject.SetActive(true); RectTransform val2 = (RectTransform)((Component)component).transform; val2.anchorMin = Vector2.zero; val2.anchorMax = Vector2.one; val2.offsetMin = Vector2.zero; val2.offsetMax = Vector2.zero; TMP_Dropdown componentInChildren = ((Component)component).GetComponentInChildren<TMP_Dropdown>(true); if ((Object)(object)componentInChildren != (Object)null) { FitDropdownBox(componentInChildren); } component.Setup(bound.Setting, handler); DropdownOverlayFix.Attach(((Component)component).gameObject, rootCanvas); if ((Object)(object)componentInChildren != (Object)null && !_dumpedOneDropdown) { _dumpedOneDropdown = true; UiDebugDump.DumpDeferred(((Component)row).gameObject, "dropdown row: " + bound.DisplayName); } return componentInChildren; } private static void FitDropdownBox(TMP_Dropdown dropdown) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0074: 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_0089: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) RectTransform val = (RectTransform)((Component)dropdown).transform; val.sizeDelta = new Vector2(val.sizeDelta.x, -8f); val.anchoredPosition = new Vector2(val.anchoredPosition.x, 0f); TMP_Text captionText = dropdown.captionText; if (!((Object)(object)captionText == (Object)null)) { ((Component)captionText).gameObject.SetActive(true); RectTransform val2 = (RectTransform)captionText.transform; val2.anchorMin = Vector2.zero; val2.anchorMax = Vector2.one; val2.offsetMin = new Vector2(14f, 0f); val2.offsetMax = new Vector2(-34f, 0f); captionText.alignment = (TextAlignmentOptions)4097; captionText.enableWordWrapping = false; captionText.enableAutoSizing = true; captionText.fontSizeMin = 14f; captionText.fontSizeMax = 26f; } } private static void AttachHoverDescription(GameObject rowGo, string tooltip, string defaultValueText, Action<string, string> onHover, TMP_Dropdown dropdown) { if (!string.IsNullOrEmpty(tooltip) && onHover != null) { SettingRowHover settingRowHover = rowGo.AddComponent<SettingRowHover>(); settingRowHover.Tooltip = tooltip; settingRowHover.DefaultValueText = defaultValueText; settingRowHover.OnHover = onHover; settingRowHover.Dropdown = dropdown; } } } internal class KeyRebindControl : MonoBehaviour { internal ConfigEntry<KeyCode> Entry; internal TMP_Text Label; internal static bool IsCapturing { get; private set; } internal void BeginListening() { IsCapturing = true; SetCaption(PreviewMenuLocalization.Current.PressAKey); } internal void ShowCurrentKey() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) SetCaption(((object)Entry.Value/*cast due to .constrained prefix*/).ToString().ToUpperInvariant()); } private void SetCaption(string caption) { if ((Object)(object)Label != (Object)null) { Label.text = caption; } } private void OnGUI() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Invalid comparison between Unknown and I4 //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Invalid comparison between Unknown and I4 //IL_0048: Unknown result type (might be due to invalid IL or missing references) if (!IsCapturing || (Object)(object)Label == (Object)null) { return; } Event current = Event.current; if (current != null && (int)current.type == 4 && (int)current.keyCode != 0) { IsCapturing = false; if ((int)current.keyCode != 27) { Entry.Value = current.keyCode; } ShowCurrentKey(); current.Use(); } } private void OnDisable() { IsCapturing = false; } } internal class SettingRowHover : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler { internal string Tooltip; internal string DefaultValueText; internal Action<string, string> OnHover; internal TMP_Dropdown Dropdown; private bool _pointerOver; private bool _dropdownWasExpanded; public void OnPointerEnter(PointerEventData eventData) { _pointerOver = true; OnHover?.Invoke(Tooltip, DefaultValueText); } public void OnPointerExit(PointerEventData eventData) { _pointerOver = false; if (!((Object)(object)Dropdown != (Object)null) || !Dropdown.IsExpanded) { OnHover?.Invoke(null, null); } } private void Update() { if (!((Object)(object)Dropdown == (Object)null)) { bool isExpanded = Dropdown.IsExpanded; if (_dropdownWasExpanded && !isExpanded && !_pointerOver) { OnHover?.Invoke(null, null); } _dropdownWasExpanded = isExpanded; } } } internal static class PanelChrome { internal static readonly Color DimColor = new Color(0f, 0f, 0f, 0.78f); internal static readonly Color PanelFillColor = new Color(0.20392157f, 28f / 85f, 0.81960785f); internal static readonly Color PanelBorderColor = new Color(11f / 85f, 0.19215687f, 42f / 85f); internal static readonly Color BadgeBorderColor = new Color(2f / 51f, 0.050980393f, 0.101960786f); internal static readonly Color TitleColor = new Color(0.98f, 0.99f, 1f); internal static readonly Color BodyColor = new Color(0.93f, 0.95f, 1f); internal static readonly Color FooterColor = new Color(0.85f, 0.9f, 1f); internal static readonly Color ChipFillColor = new Color(0.1f, 0.16f, 0.44f); internal static readonly Color ChipTextColor = new Color(1f, 0.95f, 0.72f); internal static readonly Color SelectedFillColor = new Color(1f, 0.82f, 0.22f, 0.97f); internal static readonly Color SelectedTextColor = new Color(0.85f, 0.78f, 0.55f); internal static readonly Color PlaceholderTextColor = new Color(0.55f, 0.55f, 0.58f); internal static readonly Color DefaultValueTextColor = new Color(0.68f, 0.7f, 0.75f); internal static readonly Color ScrollFadeColor = new Color(PanelFillColor.r * 0.8f, PanelFillColor.g * 0.8f, PanelFillColor.b * 0.8f, 1f); internal const float PanelCornerRadius = 26f; internal const float PanelBorderThickness = 11f; internal const float PanelOuterMargin = 4f; private const float EdgeJagAmplitude = 5f; private const float EdgeJagFrequency = 1.2f; private const int EdgeJagOctaves = 2; private const float EdgeJagPersistence = 0.5f; private const float EdgeJagLacunarity = 2.44f; internal const int JagFrameCount = 3; internal const float JagFrameInterval = 0.5f; private static readonly float[] JagFrameSeedOffsets = new float[3] { 0f, 173.2f, 401.7f }; private static readonly Dictionary<(int width, int height, int frame), Sprite> _panelSprites = new Dictionary<(int, int, int), Sprite>(); private static readonly Dictionary<(int size, int radius), Sprite> _maskSprites = new Dictionary<(int, int), Sprite>(); private static readonly Dictionary<(int width, int height, int radius), Sprite> _scrollFadeSprites = new Dictionary<(int, int, int), Sprite>(); private static Sprite _badgeSprite; private static Texture2D _grainTexture; private const int GrainTextureSize = 368; private const float GrainSeed = 1337f; private const float GrainEnvelopeFreq = 14f; private const int GrainOctaves = 6; private const float GrainPersistence = 0.76f; private const float GrainLacunarity = 2.98f; private const float GrainSharpenMin = 0.61f; private const float GrainSharpenMax = 0f; private const float GrainLightMul = 1.03f; private const float GrainDarkMul = 1f; internal static Sprite PanelSprite(int width, int height, int frame) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) (int, int, int) key = (width, height, frame); if (_panelSprites.TryGetValue(key, out var value) && (Object)(object)value != (Object)null) { return value; } Sprite val = MakeFullPanelSprite(width, height, 26f, 11f, PanelFillColor, PanelBorderColor, 5f, 1.2f, JagFrameSeedOffsets[frame]); _panelSprites[key] = val; return val; } private static Sprite MakeFullPanelSprite(int width, int height, float radius, float borderThickness, Color fill, Color border, float edgeJag, float jagFreq, float seedOffset) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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_0018: Expected O, but got Unknown //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: 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_010d: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(width, height, (TextureFormat)5, false) { wrapMode = (TextureWrapMode)1, filterMode = (FilterMode)1 }; Color32[] array = (Color32[])(object)new Color32[width * height]; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { float num = (float)j + 0.5f; float num2 = (float)i + 0.5f; float num3 = Jag(num * jagFreq + 11.3f + seedOffset, num2 * jagFreq + 11.3f + seedOffset, edgeJag); float num4 = Jag(num * jagFreq + 77.1f + seedOffset, num2 * jagFreq + 41.9f + seedOffset, edgeJag); float num5 = Mathf.Clamp(num, radius, (float)width - radius); float num6 = Mathf.Clamp(num2, radius, (float)height - radius); float num7 = Mathf.Sqrt((num - num5) * (num - num5) + (num2 - num6) * (num2 - num6)); float a = Mathf.Clamp01(radius - num7 + num3 + 0.5f); float num8 = Mathf.Clamp01(radius - num7 - borderThickness + num4 + 0.5f); Color val2 = Color.Lerp(border, fill, num8); val2.a = a; array[i * width + j] = Color32.op_Implicit(val2); } } val.SetPixels32(array); val.Apply(); return Sprite.Create(val, new Rect(0f, 0f, (float)width, (float)height), new Vector2(0.5f, 0.5f), 100f); } private static float Jag(float x, float y, float amplitude) { if (amplitude <= 0f) { return 0f; } return (Fbm(x, y, 2, 0.5f, 2.44f) - 0.5f) * amplitude; } internal static Sprite MaskSprite(int size, float radius) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) (int, int) key = (size, Mathf.RoundToInt(radius)); if (_maskSprites.TryGetValue(key, out var value) && (Object)(object)value != (Object)null) { return value; } Sprite val = MakeRoundedSprite(size, radius, 0f, Color.white, Color.white); _maskSprites[key] = val; return val; } internal static Sprite ScrollFadeSprite(int width, int height, float radius) { (int, int, int) key = (width, height, Mathf.RoundToInt(radius)); if (_scrollFadeSprites.TryGetValue(key, out var value) && (Object)(object)value != (Object)null) { return value; } Sprite val = MakeScrollFadeSprite(width, height, radius); _scrollFadeSprites[key] = val; return val; } private static Sprite MakeScrollFadeSprite(int width, int height, float radius) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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_0018: Expected O, but got Unknown //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0115: 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) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(width, height, (TextureFormat)5, false) { wrapMode = (TextureWrapMode)1, filterMode = (FilterMode)1 }; Color32[] array = (Color32[])(object)new Color32[width * height]; for (int i = 0; i < height; i++) { float num = (float)i + 0.5f; float num2 = 1f - num / (float)height; float num3 = num2 * num2 * (3f - 2f * num2); for (int j = 0; j < width; j++) { float num4 = (float)j + 0.5f; float num5 = Mathf.Clamp(num4, radius, (float)width - radius); float num6 = Mathf.Max(num, radius); float num7 = Mathf.Sqrt((num4 - num5) * (num4 - num5) + (num - num6) * (num - num6)); float num8 = Mathf.Clamp01(radius - num7 + 0.5f); array[i * width + j] = Color32.op_Implicit(new Color(1f, 1f, 1f, num3 * num8)); } } val.SetPixels32(array); val.Apply(); return Sprite.Create(val, new Rect(0f, 0f, (float)width, (float)height), new Vector2(0.5f, 0.5f), 100f); } internal static Sprite BadgeSprite() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_badgeSprite != (Object)null)) { return _badgeSprite = MakeRoundedSprite(32, 10f, 3f, ChipFillColor, BadgeBorderColor); } return _badgeSprite; } internal static Sprite MakeRoundedSprite(int size, float radius, float borderThickness, Color fill, Color border) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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_0018: Expected O, but got Unknown //IL_011a: 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_0135: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: 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_00ce: 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_00d5: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(size, size, (TextureFormat)5, false) { wrapMode = (TextureWrapMode)1, filterMode = (FilterMode)1 }; Color32[] array = (Color32[])(object)new Color32[size * size]; for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { float num = (float)j + 0.5f; float num2 = (float)i + 0.5f; float num3 = Mathf.Clamp(num, radius, (float)size - radius); float num4 = Mathf.Clamp(num2, radius, (float)size - radius); float num5 = Mathf.Sqrt((num - num3) * (num - num3) + (num2 - num4) * (num2 - num4)); float a = Mathf.Clamp01(radius - num5 + 0.5f); float num6 = ((borderThickness > 0f) ? Mathf.Clamp01(radius - num5 - borderThickness + 0.5f) : 1f); Color val2 = Color.Lerp(border, fill, num6); val2.a = a; array[i * size + j] = Color32.op_Implicit(val2); } } val.SetPixels32(array); val.Apply(); Vector4 val3 = default(Vector4); ((Vector4)(ref val3))..ctor(radius, radius, radius, radius); return Sprite.Create(val, new Rect(0f, 0f, (float)size, (float)size), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0, val3); } internal static Texture2D GrainTexture() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_grainTexture != (Object)null)) { return _grainTexture = GenerateGrainTexture(PanelFillColor, 368, 368); } return _grainTexture; } private static Texture2D GenerateGrainTexture(Color baseColor, int width, int height) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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_0018: Expected O, but got Unknown //IL_001a: 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_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(width, height, (TextureFormat)3, false) { wrapMode = (TextureWrapMode)1, filterMode = (FilterMode)1 }; Color val2 = default(Color); ((Color)(ref val2))..ctor(Mathf.Clamp01(baseColor.r * 1f), Mathf.Clamp01(baseColor.g * 1f), Mathf.Clamp01(baseColor.b * 1f)); Color val3 = default(Color); ((Color)(ref val3))..ctor(Mathf.Clamp01(baseColor.r * 1.03f), Mathf.Clamp01(baseColor.g * 1.03f), Mathf.Clamp01(baseColor.b * 1.03f)); float[] array = new float[width * height]; float num = float.MaxValue; float num2 = float.MinValue; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { float x = (float)j / (float)width * 14f + 1.337f; float y = (float)i / (float)height * 14f + 1.337f; float num3 = (array[i * width + j] = Fbm(x, y, 6, 0.76f, 2.98f)); if (num3 < num) { num = num3; } if (num3 > num2) { num2 = num3; } } } float num4 = Mathf.Max(0.0001f, num2 - num); Color32[] array2 = (Color32[])(object)new Color32[width * height]; for (int k = 0; k < array2.Length; k++) { float x2 = (array[k] - num) / num4; array2[k] = Color32.op_Implicit(Color.Lerp(val2, val3, SmoothStepEdge(0.61f, 0f, x2))); } val.SetPixels32(array2); val.Apply(); return val; } private static float Fbm(float x, float y, int octaves, float persistence, float lacunarity) { float num = 0f; float num2 = 1f; float num3 = 1f; float num4 = 0f; for (int i = 0; i < octaves; i++) { num += Mathf.PerlinNoise(x * num3, y * num3) * num2; num4 += num2; num2 *= persistence; num3 *= lacunarity; } return num / num4; } private static float SmoothStepEdge(float edge0, float edge1, float x) { float num = Mathf.Clamp01((x - edge0) / Mathf.Max(0.0001f, edge1 - edge0)); return num * num * (3f - 2f * num); } } internal static class PauseSuppressPatch { private static bool _suppressOnce; internal static void Apply(Harmony harmony, ManualLogSource log) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown try { MethodInfo methodInfo = AccessTools.Method(typeof(GUIManager), "UpdatePaused", (Type[])null, (Type[])null); if (methodInfo == null) { log.LogWarning((object)"PauseSuppressPatch: GUIManager.UpdatePaused not found; closing the preview menu with Escape may also open the pause menu."); } else { harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(PauseSuppressPatch), "Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } catch (Exception arg) { log.LogError((object)$"PauseSuppressPatch.Apply failed (non-fatal): {arg}"); } } internal static void SuppressNextOpen() { _suppressOnce = true; } private static bool Prefix() { if (!_suppressOnce) { return true; } _suppressOnce = false; return false; } } public class PreviewMenu : MonoBehaviour { private class PreviewTab { internal string Name; internal List<ConfigEntryBase> Entries; } private class TabButton { internal Image Background; internal TMP_Text Label; } private static PreviewMenu _instance; private const float PanelWidth = 1780f; private const float PanelHeight = 1010f; private const float PanelPadding = 34f; private const float TitleHeight = 44f; private const float TabsHeight = 52f; private const float TabsBottomGap = 20f; private const float TitleNudge = 15f; private const float KeyBadgeTextNudge = 3f; private const float TabTextNudge = 3f; private const float FooterYNudge = 5f; private const float ColumnGap = 26f; private const float PreviewWidth = 1040f; private const float PreviewHeight = 585f; private const float SettingsWidth = 646f; private const float DescriptionHeight = 132f; private const float DefaultValueLineHeight = 20f; private const float DescriptionDefaultValueGap = 4f; private const float MinDescriptionTextHeight = 24f; private const float PreviewDescriptionGap = 16f; private const float FooterHeight = 34f; private const float SettingRowHeight = 108f; private const float SettingRowSpacing = 12f; private const float SettingsCornerRadius = 18f; private const float ScrollFadeHeight = 52f; private const float ScrollFadeFullAt = 18f; private const int SettleFrames = 3; private const float DimFadeDuration = 0.25f; private GameObject _root; private GameObject _loadingRoot; private GameObject _dimRoot; private Image _dimIm