using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("Zichen-MoreUI")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+fbb1a4d755192614516015fd42e4c7a90e32abef")]
[assembly: AssemblyProduct("Zichen-MoreUI")]
[assembly: AssemblyTitle("Zichen-MoreUI")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.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;
}
}
}
public enum TeammateDisplayMode
{
常显,
按键显示
}
public enum DisplayMode
{
文字显示,
原生UI显示
}
public enum DisplayLanguage
{
中文,
English
}
[BepInPlugin("zichen.moreui", "A.MoreUI", "1.2.1")]
public class Plugin : BaseUnityPlugin
{
public const string PluginGuid = "zichen.moreui";
public const string PluginVersion = "1.2.1";
public const string PluginName = "A.MoreUI";
private static Plugin Instance;
private const float MinimumRefreshIntervalSeconds = 0.1f;
private const float ProximityAutoShowLingerSeconds = 5f;
private const float EnemyProximityPopSeconds = 1.2f;
private const float EnemyProximityPopFontMultiplier = 2f;
private const float RunLevelInactiveGraceSeconds = 4f;
private const int PlayerHeadTopColorSlot = 5;
private const float PlayerColorCacheRefreshSeconds = 0.2f;
private const string TeammateIcon = "\ud83e\udd16";
private const string CartIcon = "\ud83d\uded2";
private const string ContactConfigSection = "模组信息";
private const string LanguageConfigSection = "A.全局设置";
private const string TeammateConfigSection = "B.好友局内显示";
private const string EnemyWorldConfigSection = "C.敌人局内显示";
private const string CartWorldConfigSection = "D.购物车局内显示";
private static readonly FieldInfo PlayerDeadSetField = typeof(PlayerAvatar).GetField("deadSet", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo PlayerIsDisabledField = typeof(PlayerAvatar).GetField("isDisabled", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo PlayerNameField = typeof(PlayerAvatar).GetField("playerName", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo PlayerIsLocalField = typeof(PlayerAvatar).GetField("isLocal", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo PlayerCosmeticsColorsEquippedField = typeof(PlayerCosmetics).GetField("colorsEquipped", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo PlayerTransformField = typeof(PlayerAvatar).GetField("playerTransform", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo PlayerDeathSpotField = typeof(PlayerAvatar).GetField("deathSpot", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo PlayerDeathHeadField = typeof(PlayerAvatar).GetField("playerDeathHead", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo PlayerLastNavmeshPositionField = typeof(PlayerAvatar).GetField("LastNavmeshPosition", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo DeathHeadPhysGrabObjectField = typeof(PlayerDeathHead).GetField("physGrabObject", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo DeathHeadTriggeredPositionField = typeof(PlayerDeathHead).GetField("triggeredPosition", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo DeathHeadOverridePositionTransformField = typeof(PlayerDeathHead).GetField("overridePositionTransform", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo SpectateCameraInstanceField = typeof(SpectateCamera).GetField("instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo SpectateCameraPlayerField = typeof(SpectateCamera).GetField("player", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo SpectateCameraPlayerOverrideField = typeof(SpectateCamera).GetField("playerOverride", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo SpectateCameraMainCameraField = typeof(SpectateCamera).GetField("MainCamera", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo EnemyParentField = typeof(Enemy).GetField("EnemyParent", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo EnemyTypeField = typeof(Enemy).GetField("Type", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo EnemyCenterTransformField = typeof(Enemy).GetField("CenterTransform", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo EnemyParentNameField = typeof(EnemyParent).GetField("enemyName", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo EnemyParentLocalizedNameField = typeof(EnemyParent).GetField("enemyNameLocalized", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly MethodInfo LocalizedAssetGetStringMethod = typeof(LocalizedAsset).GetMethod("GetLocalizedString", Type.EmptyTypes);
private static readonly FieldInfo EnemyParentSpawnedField = typeof(EnemyParent).GetField("Spawned", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo EnemyHealthField = typeof(Enemy).GetField("Health", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo EnemyHealthDeadField = typeof(EnemyHealth).GetField("dead", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo GoalUiTextField = typeof(GoalUI).GetField("Text", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? typeof(GoalUI).GetField("uiText", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly GUIContent ReusableGuiContent = new GUIContent();
private static readonly CultureInfo MoneyCulture = CultureInfo.GetCultureInfo("en-US");
private static readonly HashSet<int> BoundsVisitedBuffer = new HashSet<int>();
private static readonly List<Renderer> BoundsRendererBuffer = new List<Renderer>();
private static readonly List<Collider> BoundsColliderBuffer = new List<Collider>();
private static readonly Dictionary<int, bool> PlayerAliveFrameCache = new Dictionary<int, bool>();
private static int playerAliveFrameCacheFrame = -1;
private static readonly FieldInfo ValuableOriginalValueField = typeof(ValuableObject).GetField("dollarValueOriginal", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo ValuableCurrentValueField = typeof(ValuableObject).GetField("dollarValueCurrent", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo ValuableValueSetField = typeof(ValuableObject).GetField("dollarValueSet", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo ValuablePhotonViewField = typeof(ValuableObject).GetField("photonView", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo ValuablePhysGrabObjectField = typeof(ValuableObject).GetField("physGrabObject", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo PhysGrabCartItemsInCartField = typeof(PhysGrabCart).GetField("itemsInCart", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo PhysGrabCartInCartField = typeof(PhysGrabCart).GetField("physGrabInCart", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo PhysGrabInCartObjectsField = typeof(PhysGrabInCart).GetField("inCartObjects", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo PhysGrabInCartCartObjectPhysGrabObjectField = typeof(PhysGrabInCart).GetNestedType("CartObject", BindingFlags.Public | BindingFlags.NonPublic)?.GetField("physGrabObject", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo PhysGrabCartCurrentStateField = typeof(PhysGrabCart).GetField("currentState", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo PhysGrabCartBeingPulledField = typeof(PhysGrabCart).GetField("cartBeingPulled", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo PhysGrabCartActiveField = typeof(PhysGrabCart).GetField("cartActive", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo PhysGrabCartIsSmallCartField = typeof(PhysGrabCart).GetField("isSmallCart", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo PhysGrabCartItemEquippableField = typeof(PhysGrabCart).GetField("itemEquippable", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo PhysGrabCartPhysGrabObjectField = typeof(PhysGrabCart).GetField("physGrabObject", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo PhysGrabCartGrabPointField = typeof(PhysGrabCart).GetField("cartGrabPoint", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo ItemEquippableCurrentStateField = typeof(ItemEquippable).GetField("currentState", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo ItemEquippableIsEquippedField = typeof(ItemEquippable).GetField("isEquipped", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo ItemEquippableIsEquippingField = typeof(ItemEquippable).GetField("isEquipping", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly Dictionary<string, int> EnemyBreakdownRankTable = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase)
{
["Apex Predator"] = 10,
["Bang"] = 11,
["Gnome"] = 12,
["Peeper"] = 13,
["Shadow Child"] = 14,
["Spewer"] = 15,
["Tick"] = 16,
["Bella"] = 17,
["Birthday Boy"] = 18,
["Elsa"] = 19,
["Animal"] = 20,
["Bowtie"] = 21,
["Head Grabber"] = 22,
["Heart Hugger"] = 23,
["Mentalist"] = 24,
["Oogly"] = 25,
["Rugrat"] = 26,
["Upscream"] = 27,
["Head"] = 30,
["Hidden"] = 31,
["Hunter"] = 32,
["Loom"] = 33,
["Reaper"] = 34,
["Robe"] = 35,
["Slow Mouth"] = 36,
["Slow Walker"] = 37,
["Trudge"] = 38,
["Cleanup Crew"] = 39,
["Beamer"] = 40,
["Gambit"] = 41
};
private static readonly FieldInfo PhysGrabObjectGrabbedField = typeof(PhysGrabObject).GetField("grabbed", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo PhysGrabObjectPlayerGrabbingField = typeof(PhysGrabObject).GetField("playerGrabbing", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo PhysGrabberGrabbedPhysGrabObjectField = typeof(PhysGrabber).GetField("grabbedPhysGrabObject", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo PhysGrabberGrabbedField = typeof(PhysGrabber).GetField("grabbed", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo PhysGrabberIsPushingField = typeof(PhysGrabber).GetField("isPushing", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo PhysGrabberIsPullingField = typeof(PhysGrabber).GetField("isPulling", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo RoundDirectorInstanceField = typeof(RoundDirector).GetField("instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo RoundDirectorDollarHaulListField = typeof(RoundDirector).GetField("dollarHaulList", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static readonly FieldInfo RoundDirectorCurrentHaulField = typeof(RoundDirector).GetField("currentHaul", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static int cachedWorldLabelCameraFrame = -1;
private static Camera cachedWorldLabelCamera;
private static int cachedRunLevelActiveFrame = -1;
private static bool cachedRunLevelActive;
private static int cachedLocalPlayerFrame = -1;
private static PlayerAvatar cachedLocalPlayer;
private static ConfigEntry<string> keyCaptureEntry;
private static readonly HashSet<int> valuablesCurrentlyInDollarHaul = new HashSet<int>();
private static readonly Dictionary<Type, PropertyInfo> PhotonViewIdPropertyCache = new Dictionary<Type, PropertyInfo>();
private static readonly Dictionary<Type, FieldInfo> PhotonViewIdFieldCache = new Dictionary<Type, FieldInfo>();
private static readonly Dictionary<Type, PropertyInfo> PhotonViewOwnerPropertyCache = new Dictionary<Type, PropertyInfo>();
private static readonly Dictionary<Type, PropertyInfo> PhotonOwnerNickNamePropertyCache = new Dictionary<Type, PropertyInfo>();
private ConfigEntry<string> moduleNameInfo;
private ConfigEntry<string> moduleVersionInfo;
private ConfigEntry<string> contactInfo;
private ConfigEntry<bool> modEnabled;
private ConfigEntry<bool> overlayEnabled;
private ConfigEntry<bool> sectionSpacing;
private ConfigEntry<DisplayLanguage> displayLanguage;
private ConfigEntry<bool> enemyNicknameEnabled;
private ConfigEntry<DisplayMode> displayMode;
private ConfigEntry<int> fontSize;
private ConfigEntry<float> updateInterval;
private ConfigEntry<int> overlayOffsetX;
private ConfigEntry<int> overlayOffsetY;
private ConfigEntry<bool> showEnemySection;
private ConfigEntry<bool> showBreakdown;
private ConfigEntry<bool> showTotalEnemyCount;
private ConfigEntry<bool> showValueSection;
private ConfigEntry<bool> showMapLostValue;
private ConfigEntry<bool> showExplorationProgress;
private ConfigEntry<bool> showMapTotalValue;
private ConfigEntry<bool> showCurrentRunSubmittedFunds;
private ConfigEntry<bool> showShopRemainingFunds;
private ConfigEntry<bool> showLevelInfo;
private ConfigEntry<bool> showTeammateInfoSection;
private ConfigEntry<bool> showDeadTeammates;
private ConfigEntry<bool> showAliveTeammates;
private ConfigEntry<bool> showPlayerCounts;
private ConfigEntry<bool> teammateOverlayEnabled;
private ConfigEntry<bool> teammateAliveOverlayEnabled;
private ConfigEntry<bool> teammateDeadOverlayEnabled;
private ConfigEntry<int> teammateFontSize;
private ConfigEntry<float> teammateLabelHeightOffset;
private ConfigEntry<int> teammateFarFontShrinkPercent;
private ConfigEntry<float> teammateUpdateInterval;
private ConfigEntry<TeammateDisplayMode> teammateDisplayMode;
private ConfigEntry<string> teammateToggleKey;
private ConfigEntry<int> teammateHoldSeconds;
private ConfigEntry<bool> teammateProximityAutoShowEnabled;
private ConfigEntry<int> teammateProximityAutoShowDistance;
private ConfigEntry<bool> enemyOverlayEnabled;
private ConfigEntry<int> enemyFontSize;
private ConfigEntry<int> enemyFarFontShrinkPercent;
private ConfigEntry<float> enemyUpdateInterval;
private ConfigEntry<TeammateDisplayMode> enemyDisplayMode;
private ConfigEntry<string> enemyToggleKey;
private ConfigEntry<int> enemyHoldSeconds;
private ConfigEntry<bool> enemyProximityAutoShowEnabled;
private ConfigEntry<int> enemyProximityAutoShowDistance;
private ConfigEntry<bool> cartSectionEnabled;
private ConfigEntry<bool> cartOverlayEnabled;
private ConfigEntry<bool> smallCartOverlayEnabled;
private ConfigEntry<int> cartFontSize;
private ConfigEntry<int> cartFarFontShrinkPercent;
private ConfigEntry<float> cartLabelHeightOffset;
private ConfigEntry<float> cartUpdateInterval;
private GameObject overlayObject;
private GameObject overlayCanvasObject;
private Canvas overlayCanvas;
private RectTransform overlayRect;
private TextMeshProUGUI overlayLabel;
private Harmony valuableHaulHarmony;
private string overlayText = string.Empty;
private string lastNativeOverlayText;
private int lastNativeOverlayFontSize = -1;
private int lastNativeOverlayOffsetX = int.MinValue;
private int lastNativeOverlayOffsetY = int.MinValue;
private bool lastNativeOverlayShowBreakdown;
private string lastPlainOverlaySource;
private string lastPlainOverlayText = string.Empty;
private string lastTextOverlaySource;
private int lastTextOverlayFontSize = -1;
private bool lastTextOverlayShowBreakdown;
private int lastTextOverlayOffsetX = int.MinValue;
private int lastTextOverlayOffsetY = int.MinValue;
private int lastTextOverlayScreenWidth = -1;
private int lastTextOverlayScreenHeight = -1;
private Rect cachedTextOverlayRect;
private Rect cachedTextOverlayShadowRect;
private float cachedTextOverlayWidth;
private string cachedTextOverlayPlainText = string.Empty;
private readonly List<EnemyLabelInfo> enemyLabels = new List<EnemyLabelInfo>();
private readonly List<MoreUiCartDistance> cartDistanceCache = new List<MoreUiCartDistance>();
private readonly Dictionary<int, float> enemyProximityPopTimers = new Dictionary<int, float>();
private readonly HashSet<int> enemiesInsideProximityRange = new HashSet<int>();
private readonly HashSet<int> currentEnemiesInsideProximityRange = new HashSet<int>();
private readonly List<int> reusableIntKeys = new List<int>();
private readonly List<int> reusableSnapshotKeys = new List<int>();
private readonly HashSet<int> liveValuableKeys = new HashSet<int>();
private readonly Dictionary<int, int> largeCartLabelIndices = new Dictionary<int, int>();
private readonly Dictionary<int, int> smallCartLabelIndices = new Dictionary<int, int>();
private readonly Dictionary<int, bool> smallCartTypeCache = new Dictionary<int, bool>();
private readonly Dictionary<int, GUIStyle> centeredRichLabelStyleCache = new Dictionary<int, GUIStyle>();
private readonly Dictionary<int, GUIStyle> centeredShadowLabelStyleCache = new Dictionary<int, GUIStyle>();
private readonly Dictionary<int, GUIStyle> overlayRichStyleCache = new Dictionary<int, GUIStyle>();
private readonly Dictionary<int, GUIStyle> overlayShadowStyleCache = new Dictionary<int, GUIStyle>();
private readonly List<Enemy> activeEnemyBuffer = new List<Enemy>();
private readonly Dictionary<string, int> enemyBreakdownBuffer = new Dictionary<string, int>();
private readonly Dictionary<string, int> enemyBreakdownRankBuffer = new Dictionary<string, int>();
private readonly List<KeyValuePair<string, int>> orderedEnemyBreakdownBuffer = new List<KeyValuePair<string, int>>();
private readonly List<string> enemyBreakdownLineBuffer = new List<string>();
private readonly List<string> monsterSectionPartsBuffer = new List<string>();
private readonly List<string> valueSectionPartsBuffer = new List<string>();
private readonly List<string> teammateSectionPartsBuffer = new List<string>();
private readonly List<string> evacuatedFundsLineBuffer = new List<string>();
private readonly List<string> overlayPartsBuffer = new List<string>();
private readonly List<object> currentDollarHaulObjectsBuffer = new List<object>();
private readonly List<object> currentCartObjectsBuffer = new List<object>();
private readonly HashSet<object> haulReferenceSetBuffer = new HashSet<object>(ReferenceObjectComparer.Instance);
private readonly HashSet<object> cartReferenceSetBuffer = new HashSet<object>(ReferenceObjectComparer.Instance);
private readonly List<PhysGrabCart> activeCartBuffer = new List<PhysGrabCart>();
private readonly List<CartLabelCandidate> cartLabelCandidateBuffer = new List<CartLabelCandidate>();
private Enemy[] enemyObjectsFrameCache = Array.Empty<Enemy>();
private PhysGrabCart[] cartObjectsFrameCache = Array.Empty<PhysGrabCart>();
private PhysGrabber[] grabberObjectsFrameCache = Array.Empty<PhysGrabber>();
private ValuableObject[] valuableObjectsFrameCache = Array.Empty<ValuableObject>();
private List<PlayerAvatar> playerObjectsFrameCache;
private readonly Dictionary<int, string> enemyDisplayNameCache = new Dictionary<int, string>();
private readonly Dictionary<int, string> playerNameCache = new Dictionary<int, string>();
private readonly Dictionary<int, PlayerColorCacheEntry> playerColorCache = new Dictionary<int, PlayerColorCacheEntry>();
private readonly Dictionary<int, LabelYOffsetCache> playerLabelYOffsetCache = new Dictionary<int, LabelYOffsetCache>();
private readonly Dictionary<int, LabelYOffsetCache> enemyLabelYOffsetCache = new Dictionary<int, LabelYOffsetCache>();
private readonly Dictionary<int, LabelYOffsetCache> cartLabelYOffsetCache = new Dictionary<int, LabelYOffsetCache>();
private DisplayLanguage cachedEnemyDisplayNameLanguage;
private bool cachedEnemyNicknameEnabled;
private bool hasCachedEnemyDisplayNameLanguage;
private float refreshTimer;
private float keyNormalizeTimer;
private float teammateVisibleTimer;
private float teammateProximityVisibleTimer;
private float teammateProximityRefreshTimer;
private float enemyRefreshTimer;
private float enemyProximityRefreshTimer;
private float enemyVisibleTimer;
private float enemyProximityVisibleTimer;
private float cartRefreshTimer;
private int enemyObjectsFrameCacheFrame = -1;
private int cartObjectsFrameCacheFrame = -1;
private int grabberObjectsFrameCacheFrame = -1;
private int valuableObjectsFrameCacheFrame = -1;
private int playerObjectsFrameCacheFrame = -1;
private int playerNameCacheFrame = -1;
private bool cartDistanceCacheValid;
private int cartLabelIndexLevelNumber = -1;
private int nextLargeCartLabelIndex = 1;
private int nextSmallCartLabelIndex = 1;
private int trackedLevelNumber = -1;
private float previousExtractedValue = -1f;
private float accumulatedLostValue;
private bool hasLoggedUpdateError;
private bool runtimeWasActive;
private bool levelTransitionLogIndicatesRun;
private float lastConfirmedRunLevelTime = -999f;
private int submittedFundsSnapshotLevelNumber = -1;
private float submittedFundsBaselineTotalHaul = -1f;
private float submittedFundsSnapshot;
private int shopRemainingSnapshotLevelNumber = -1;
private float shopRemainingFundsSnapshot = -1f;
private readonly Dictionary<int, ValuableSnapshot> valuableSnapshots = new Dictionary<int, ValuableSnapshot>();
private DisplayLanguage CurrentLanguage
{
get
{
if (displayLanguage != null)
{
return displayLanguage.Value;
}
return DisplayLanguage.中文;
}
}
private bool UseEnemyNicknameNames
{
get
{
if (CurrentLanguage == DisplayLanguage.中文 && enemyNicknameEnabled != null)
{
return enemyNicknameEnabled.Value;
}
return false;
}
}
private void Awake()
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Expected O, but got Unknown
//IL_0084: Unknown result type (might be due to invalid IL or missing references)
//IL_008e: Expected O, but got Unknown
//IL_010a: Unknown result type (might be due to invalid IL or missing references)
//IL_0114: Expected O, but got Unknown
//IL_0190: Unknown result type (might be due to invalid IL or missing references)
//IL_019a: Expected O, but got Unknown
//IL_0323: Unknown result type (might be due to invalid IL or missing references)
//IL_032d: Expected O, but got Unknown
//IL_037a: Unknown result type (might be due to invalid IL or missing references)
//IL_0384: Expected O, but got Unknown
//IL_044d: Unknown result type (might be due to invalid IL or missing references)
//IL_0457: Expected O, but got Unknown
//IL_04f8: Unknown result type (might be due to invalid IL or missing references)
//IL_0502: Expected O, but got Unknown
//IL_05a4: Unknown result type (might be due to invalid IL or missing references)
//IL_05ae: Expected O, but got Unknown
//IL_0677: Unknown result type (might be due to invalid IL or missing references)
//IL_0681: Expected O, but got Unknown
//IL_0722: Unknown result type (might be due to invalid IL or missing references)
//IL_072c: Expected O, but got Unknown
//IL_0824: Unknown result type (might be due to invalid IL or missing references)
//IL_082e: Expected O, but got Unknown
//IL_0938: Unknown result type (might be due to invalid IL or missing references)
//IL_0942: Expected O, but got Unknown
//IL_096d: Unknown result type (might be due to invalid IL or missing references)
//IL_0977: Expected O, but got Unknown
//IL_09ab: Unknown result type (might be due to invalid IL or missing references)
//IL_09b5: Expected O, but got Unknown
//IL_09e5: Unknown result type (might be due to invalid IL or missing references)
//IL_09ef: Expected O, but got Unknown
//IL_0a1f: Unknown result type (might be due to invalid IL or missing references)
//IL_0a29: Expected O, but got Unknown
Instance = this;
MakePluginHostPersistent();
Application.logMessageReceived += new LogCallback(OnUnityLogMessageReceived);
moduleNameInfo = ((BaseUnityPlugin)this).Config.Bind<string>("模组信息", "模组名称", "更多的UI显示", new ConfigDescription("当前模组的中文名称。此处只是提示,不影响功能。", (AcceptableValueBase)null, new object[1]
{
new ConfigurationManagerAttributes
{
Order = 1000,
CustomDrawer = DrawContactInfo,
ReadOnly = true
}
}));
moduleNameInfo.Value = "更多的UI显示";
moduleVersionInfo = ((BaseUnityPlugin)this).Config.Bind<string>("模组信息", "模组版本号", "1.2.1", new ConfigDescription("当前模组版本号。此处只是提示,不影响功能。", (AcceptableValueBase)null, new object[1]
{
new ConfigurationManagerAttributes
{
Order = 990,
CustomDrawer = DrawContactInfo,
ReadOnly = true
}
}));
moduleVersionInfo.Value = "1.2.1";
contactInfo = ((BaseUnityPlugin)this).Config.Bind<string>("模组信息", "REPO交流QQ群", "824639225", new ConfigDescription("REPO游戏交流、BUG反馈、优化建议、功能请求请加QQ群。此处只是提示,不影响功能。", (AcceptableValueBase)null, new object[1]
{
new ConfigurationManagerAttributes
{
Order = 980,
CustomDrawer = DrawContactInfo,
ReadOnly = true
}
}));
contactInfo.Value = "824639225";
modEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("A.全局设置", "模组启用", true, ConfigDescriptionWithOrder("关闭后整个模组所有UI显示功能都不生效,包括右下角显示、队友/敌人距离、购物车距离、怪物统计和价值统计。", 990));
displayLanguage = ((BaseUnityPlugin)this).Config.Bind<DisplayLanguage>("A.全局设置", "语言/Language", DisplayLanguage.中文, ConfigDescriptionWithOrder("选择游戏内显示文本的语言。默认中文,English 会把怪物名称和右下角字段名切换为英文。", 980));
enemyNicknameEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("A.全局设置", "敌人名字优化", true, ConfigDescriptionWithOrder("默认开启。仅在语言为中文时生效,会把直接翻译的敌人名称优化成更顺口、更好辨认的中文名字;语言为 English 时始终显示英文。", 970));
teammateOverlayEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("B.好友局内显示", "启用", true, ConfigDescriptionWithOrder("在局内显示好友名字、距离和死亡状态。", 600));
teammateDeadOverlayEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("B.好友局内显示", "死亡好友显示", true, ConfigDescriptionWithOrder("开启后,局内显示死亡好友的名字和距离。", 599));
teammateAliveOverlayEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("B.好友局内显示", "存活好友显示", true, ConfigDescriptionWithOrder("开启后,局内显示存活好友的名字和距离。", 598));
teammateFontSize = ((BaseUnityPlugin)this).Config.Bind<int>("B.好友局内显示", "字体大小", 22, ConfigDescriptionWithOrder<int>("好友局内文字的字体大小。近距离显示不超过这个大小,远距离会按变小百分比缩小。", new AcceptableValueRange<int>(8, 42), 590));
teammateFarFontShrinkPercent = ((BaseUnityPlugin)this).Config.Bind<int>("B.好友局内显示", "远处字体变小/%", 30, new ConfigDescription("好友距离较远时,局内文字最多变小多少百分比。默认30表示最远显示为字体大小的70%。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 75), new object[1]
{
new ConfigurationManagerAttributes
{
Order = 589
}
}));
teammateLabelHeightOffset = ((BaseUnityPlugin)this).Config.Bind<float>("B.好友局内显示", "显示高度/米", 0.05f, new ConfigDescription("好友文字距离角色模型顶部额外抬高多少米。默认0.05米,数值越大文字越高。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.5f), new object[1]
{
new ConfigurationManagerAttributes
{
Order = 585
}
}));
teammateDisplayMode = ((BaseUnityPlugin)this).Config.Bind<TeammateDisplayMode>("B.好友局内显示", "显示方式", TeammateDisplayMode.常显, ConfigDescriptionWithOrder("常显,或按键后显示一段时间。", 580));
teammateUpdateInterval = ((BaseUnityPlugin)this).Config.Bind<float>("B.好友局内显示", "刷新间隔/秒", 0.5f, ConfigDescriptionWithOrder<float>("每隔多少秒刷新一次好友局内信息。", new AcceptableValueRange<float>(0.1f, 5f), 570));
teammateToggleKey = ((BaseUnityPlugin)this).Config.Bind<string>("B.好友局内显示", "显示按键", "f", new ConfigDescription("按键显示模式下,按下后显示好友局内信息。可以填写 f、t、g、f1、mouse3 这类 KeyCode 名称。", (AcceptableValueBase)null, new object[1]
{
new ConfigurationManagerAttributes
{
Order = 560,
CustomDrawer = DrawKeyBinding
}
}));
teammateHoldSeconds = ((BaseUnityPlugin)this).Config.Bind<int>("B.好友局内显示", "按键显示持续/秒", 5, ConfigDescriptionWithOrder<int>("按下好友显示按键后,好友距离显示持续多少秒。", new AcceptableValueRange<int>(1, 30), 550));
teammateProximityAutoShowEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("B.好友局内显示", "启用靠近自动显示", true, ConfigDescriptionWithOrder("开启后,只要有好友进入指定距离内,就会临时常显好友信息;好友离开范围后5秒恢复原显示方式。", 540));
teammateProximityAutoShowDistance = ((BaseUnityPlugin)this).Config.Bind<int>("B.好友局内显示", "靠近自动显示距离/米", 20, new ConfigDescription("好友距离你多少米以内时自动临时常显。默认20米。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), new object[1]
{
new ConfigurationManagerAttributes
{
Order = 530
}
}));
enemyOverlayEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("C.敌人局内显示", "启用", true, ConfigDescriptionWithOrder("在局内显示敌人名字和距离,统一使用红色。", 540));
enemyFontSize = ((BaseUnityPlugin)this).Config.Bind<int>("C.敌人局内显示", "字体大小", 22, ConfigDescriptionWithOrder<int>("敌人局内文字的字体大小。近距离显示不超过这个大小,远距离会按变小百分比缩小。", new AcceptableValueRange<int>(8, 42), 530));
enemyFarFontShrinkPercent = ((BaseUnityPlugin)this).Config.Bind<int>("C.敌人局内显示", "远处字体变小/%", 30, new ConfigDescription("敌人距离较远时,局内文字最多变小多少百分比。默认30表示最远显示为字体大小的70%。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 75), new object[1]
{
new ConfigurationManagerAttributes
{
Order = 525
}
}));
enemyDisplayMode = ((BaseUnityPlugin)this).Config.Bind<TeammateDisplayMode>("C.敌人局内显示", "显示方式", TeammateDisplayMode.按键显示, ConfigDescriptionWithOrder("常显,或按键后显示一段时间。", 520));
enemyUpdateInterval = ((BaseUnityPlugin)this).Config.Bind<float>("C.敌人局内显示", "刷新间隔/秒", 0.5f, ConfigDescriptionWithOrder<float>("每隔多少秒刷新一次敌人局内信息。", new AcceptableValueRange<float>(0.1f, 5f), 510));
enemyToggleKey = ((BaseUnityPlugin)this).Config.Bind<string>("C.敌人局内显示", "显示按键", "f", new ConfigDescription("按键显示模式下,按下后显示敌人局内信息。可以填写 f、t、y、g、f1、mouse3 这类 KeyCode 名称。", (AcceptableValueBase)null, new object[1]
{
new ConfigurationManagerAttributes
{
Order = 500,
CustomDrawer = DrawKeyBinding
}
}));
enemyHoldSeconds = ((BaseUnityPlugin)this).Config.Bind<int>("C.敌人局内显示", "按键显示持续/秒", 5, ConfigDescriptionWithOrder<int>("按下敌人显示按键后,敌人局内信息显示持续多少秒。", new AcceptableValueRange<int>(1, 30), 490));
enemyProximityAutoShowEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("C.敌人局内显示", "启用靠近自动显示", true, ConfigDescriptionWithOrder("开启后,只要有敌人进入指定距离内,就会临时常显敌人信息;敌人离开范围后5秒恢复原显示方式。", 480));
enemyProximityAutoShowDistance = ((BaseUnityPlugin)this).Config.Bind<int>("C.敌人局内显示", "靠近自动显示距离/米", 20, new ConfigDescription("敌人距离你多少米以内时自动临时常显。默认20米。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), new object[1]
{
new ConfigurationManagerAttributes
{
Order = 470
}
}));
cartSectionEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("D.购物车局内显示", "启用", true, ConfigDescriptionWithOrder("关闭后购物车局内显示全部不显示。", 530));
cartOverlayEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("D.购物车局内显示", "显示大购物车", true, ConfigDescriptionWithOrder("在大购物车上显示编号和距离。", 520));
smallCartOverlayEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("D.购物车局内显示", "显示小购物车", true, ConfigDescriptionWithOrder("在小购物车上显示编号和距离。", 518));
cartFontSize = ((BaseUnityPlugin)this).Config.Bind<int>("D.购物车局内显示", "字体大小", 22, ConfigDescriptionWithOrder<int>("购物车局内文字的字体大小。近距离显示不超过这个大小,远距离会按变小百分比缩小。", new AcceptableValueRange<int>(8, 42), 515));
cartFarFontShrinkPercent = ((BaseUnityPlugin)this).Config.Bind<int>("D.购物车局内显示", "远处字体变小/%", 30, new ConfigDescription("购物车距离较远时,局内文字最多变小多少百分比。默认30表示最远显示为字体大小的70%。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 75), new object[1]
{
new ConfigurationManagerAttributes
{
Order = 513
}
}));
cartLabelHeightOffset = ((BaseUnityPlugin)this).Config.Bind<float>("D.购物车局内显示", "显示高度/米", 0f, ConfigDescriptionWithOrder<float>("购物车文字相对购物车模型底部的上下偏移。默认0米,显示在模型最底部。", new AcceptableValueRange<float>(-0.5f, 0.5f), 510));
cartUpdateInterval = ((BaseUnityPlugin)this).Config.Bind<float>("D.购物车局内显示", "刷新间隔/秒", 0.5f, ConfigDescriptionWithOrder<float>("每隔多少秒刷新一次购物车位置和距离。数值越小越实时,数值越大越省性能。", new AcceptableValueRange<float>(0.1f, 2f), 508));
overlayEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("E1.右下角基础设置", "启用", true, "是否在右下角显示额外信息。");
sectionSpacing = ((BaseUnityPlugin)this).Config.Bind<bool>("E1.右下角基础设置", "不同分区空行", true, "默认开启。开启后不同信息分区之间会插入一行空白。");
displayMode = ((BaseUnityPlugin)this).Config.Bind<DisplayMode>("E1.右下角基础设置", "显示模式", DisplayMode.文字显示, new ConfigDescription("可切换为文字显示或更贴近游戏的原生UI显示。", (AcceptableValueBase)null, new object[1]
{
new ConfigurationManagerAttributes
{
CustomDrawer = DrawDisplayMode
}
}));
fontSize = ((BaseUnityPlugin)this).Config.Bind<int>("E1.右下角基础设置", "字体大小", 22, new ConfigDescription("显示文字的字体大小。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 36), Array.Empty<object>()));
updateInterval = ((BaseUnityPlugin)this).Config.Bind<float>("E1.右下角基础设置", "刷新间隔/秒", 1.5f, new ConfigDescription("每隔多少秒刷新一次显示。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 10f), Array.Empty<object>()));
overlayOffsetX = ((BaseUnityPlugin)this).Config.Bind<int>("E1.右下角基础设置", "右下角X偏移/像素", 0, new ConfigDescription("右下角信息的水平偏移。正数向左移动,负数向右移动。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(-600, 600), Array.Empty<object>()));
overlayOffsetY = ((BaseUnityPlugin)this).Config.Bind<int>("E1.右下角基础设置", "右下角Y偏移/像素", 0, new ConfigDescription("右下角信息的垂直偏移。正数向上移动,负数向下移动。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(-600, 600), Array.Empty<object>()));
showEnemySection = ((BaseUnityPlugin)this).Config.Bind<bool>("E2.右下角怪物统计", "启用", true, "关闭后右下角怪物统计分区全部不显示。");
showBreakdown = ((BaseUnityPlugin)this).Config.Bind<bool>("E2.右下角怪物统计", "显示怪物明细", true, "显示每种怪物当前数量。");
showTotalEnemyCount = ((BaseUnityPlugin)this).Config.Bind<bool>("E2.右下角怪物统计", "显示怪物总数", true, "显示当前存活怪物总数。");
showValueSection = ((BaseUnityPlugin)this).Config.Bind<bool>("E3.右下角价值统计", "启用", true, ConfigDescriptionWithOrder("关闭后右下角价值统计分区全部不显示。", 770));
showExplorationProgress = ((BaseUnityPlugin)this).Config.Bind<bool>("E3.右下角价值统计", "显示已提取进度", true, ConfigDescriptionWithOrder("单独显示已提取进度。进度按地图初始总价值计算,已放到提取点或购物车的物资也算作已提取。", 760));
showMapLostValue = ((BaseUnityPlugin)this).Config.Bind<bool>("E3.右下角价值统计", "显示本局损失资金", true, ConfigDescriptionWithOrder("显示本局中已摔坏或丢失造成的资金损失。", 750));
showMapTotalValue = ((BaseUnityPlugin)this).Config.Bind<bool>("E3.右下角价值统计", "显示地图剩余资金", true, ConfigDescriptionWithOrder("显示当前地图剩余资金。已放到提取点的物品会被排除,购物车里和地图上未提取的物品仍会计入。", 740));
showCurrentRunSubmittedFunds = ((BaseUnityPlugin)this).Config.Bind<bool>("E3.右下角价值统计", "显示本局提交资金", true, ConfigDescriptionWithOrder("显示本局已经成功带走并结算的资金。仅放进提取点但未提取成功时不会计入。", 730));
showShopRemainingFunds = ((BaseUnityPlugin)this).Config.Bind<bool>("E3.右下角价值统计", "显示商店剩余资金", true, ConfigDescriptionWithOrder("显示商店剩余资金。此值只在每局开始读取一次快照,当前关卡提交物品不会让它上涨。", 720));
showLevelInfo = ((BaseUnityPlugin)this).Config.Bind<bool>("E3.右下角价值统计", "显示关卡信息", true, ConfigDescriptionWithOrder("显示当前关卡编号和名称,位于商店剩余资金下面。", 710));
showTeammateInfoSection = ((BaseUnityPlugin)this).Config.Bind<bool>("E4.右下角好友信息", "启用", true, ConfigDescriptionWithOrder("关闭后右下角好友信息分区全部不显示。", 670));
showDeadTeammates = ((BaseUnityPlugin)this).Config.Bind<bool>("E4.右下角好友信息", "显示死亡好友信息", true, ConfigDescriptionWithOrder("在右下角好友信息分区顶部显示死亡好友图标、名字和距离,距离越近越靠上。", 660));
showAliveTeammates = ((BaseUnityPlugin)this).Config.Bind<bool>("E4.右下角好友信息", "显示存活好友信息", true, ConfigDescriptionWithOrder("在右下角好友信息分区显示每个存活好友的名字和距离,距离越近越靠上。", 650));
showPlayerCounts = ((BaseUnityPlugin)this).Config.Bind<bool>("E4.右下角好友信息", "显示玩家数量", true, ConfigDescriptionWithOrder("在右下角好友信息分区最底部显示死亡、存活和总玩家数量。", 640));
NormalizeKeyConfigEntries();
ApplyValuableHaulPatch();
MoreUiApi.IsLoaded = true;
((BaseUnityPlugin)this).Logger.LogInfo((object)"moreui loaded.");
}
private void Update()
{
try
{
UpdateCore();
}
catch (Exception ex)
{
ResetRuntimeDisplayState();
if (!hasLoggedUpdateError)
{
hasLoggedUpdateError = true;
((BaseUnityPlugin)this).Logger.LogWarning((object)("moreui update skipped after an error: " + ex.GetType().Name + ": " + ex.Message));
}
}
}
private void UpdateCore()
{
keyNormalizeTimer += Time.deltaTime;
if (keyNormalizeTimer >= 0.5f)
{
keyNormalizeTimer = 0f;
NormalizeKeyConfigEntries();
}
bool flag = IsRuntimeSessionActive();
if (!IsModEnabled() || !flag)
{
if (runtimeWasActive)
{
runtimeWasActive = false;
ResetLossTracking();
MoreUiApi.ResetSnapshot();
ResetRuntimeDisplayState();
}
return;
}
runtimeWasActive = true;
refreshTimer += Time.deltaTime;
UpdateTeammateOverlayState();
UpdateEnemyOverlayState();
UpdateCartDistanceCache();
bool flag2 = overlayEnabled.Value && displayMode.Value == DisplayMode.原生UI显示;
if (refreshTimer >= ClampRefreshInterval((updateInterval == null) ? 1.5f : updateInterval.Value))
{
refreshTimer = 0f;
string text = BuildOverlayText();
overlayText = (overlayEnabled.Value ? text : string.Empty);
if (flag2)
{
UpdateNativeOverlay();
}
}
if (flag2)
{
SetNativeOverlayVisible(visible: true);
}
else
{
SetNativeOverlayVisible(visible: false);
}
}
private static float ClampRefreshInterval(float value)
{
if (float.IsNaN(value) || float.IsInfinity(value))
{
return 0.1f;
}
return Mathf.Max(0.1f, value);
}
private void MakePluginHostPersistent()
{
try
{
((Component)this).transform.parent = null;
((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to mark plugin host persistent: " + ex.GetType().Name + ": " + ex.Message));
}
}
private void OnUnityLogMessageReceived(string condition, string stackTrace, LogType type)
{
if (!string.IsNullOrEmpty(condition))
{
int num = condition.IndexOf("Changed level to:", StringComparison.OrdinalIgnoreCase);
int length = "Changed level to:".Length;
if (num < 0)
{
num = condition.IndexOf("updated level to:", StringComparison.OrdinalIgnoreCase);
length = "updated level to:".Length;
}
if (num >= 0)
{
string name = condition.Substring(num + length).Trim();
levelTransitionLogIndicatesRun = LooksLikePlayableSessionName(name);
}
}
}
private void ApplyValuableHaulPatch()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Expected O, but got Unknown
try
{
valuableHaulHarmony = new Harmony("zichen.moreui.valuablehaul");
PatchValuableHaulMethod("AddToDollarHaulList", "ValuableDollarHaulAddPostfix");
PatchValuableHaulMethod("AddToDollarHaulListRPC", "ValuableDollarHaulAddPostfix");
PatchValuableHaulMethod("RemoveFromDollarHaulList", "ValuableDollarHaulRemovePostfix");
PatchValuableHaulMethod("RemoveFromDollarHaulListRPC", "ValuableDollarHaulRemovePostfix");
PatchValuableTrackingMethod(typeof(ValuableObject), "DollarValueSetLogic", "ValuableDollarValueSetLogicPostfix");
PatchValuableTrackingMethod(typeof(ValuableObject), "DollarValueSetRPC", "ValuableDollarValueSetRpcPostfix");
PatchValuableTrackingMethod(typeof(PhysGrabObjectImpactDetector), "BreakRPC", "ValuableBreakPostfix");
PatchValuableTrackingMethod(typeof(PhysGrabObject), "DestroyPhysGrabObjectRPC", "ValuableDestroyPhysGrabObjectPostfix");
PatchValuableTrackingMethod(typeof(RoundDirector), "ExtractionCompleted", "RoundDirectorExtractionCompletedPostfix");
PatchValuableTrackingMethod(typeof(LevelGenerator), "StartRoomGeneration", "LevelGeneratorStartRoomGenerationPrefix", prefix: true);
PatchValuableTrackingMethod(typeof(LevelGenerator), "GenerateDone", "LevelGeneratorGenerateDonePostfix");
((BaseUnityPlugin)this).Logger.LogInfo((object)"Valuable haul tracking patched.");
}
catch (Exception arg)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)$"Failed to patch valuable haul tracking: {arg}");
}
}
private void PatchValuableHaulMethod(string originalName, string postfixName)
{
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Expected O, but got Unknown
MethodInfo methodInfo = AccessTools.Method(typeof(ValuableObject), originalName, (Type[])null, (Type[])null);
MethodInfo methodInfo2 = AccessTools.Method(typeof(Plugin), postfixName, (Type[])null, (Type[])null);
if (methodInfo == null || methodInfo2 == null)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to find valuable haul method patch target: " + originalName));
}
else
{
valuableHaulHarmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
}
}
private void PatchValuableTrackingMethod(Type originalType, string originalName, string patchName, bool prefix = false)
{
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Expected O, but got Unknown
MethodInfo methodInfo = AccessTools.Method(originalType, originalName, (Type[])null, (Type[])null);
MethodInfo methodInfo2 = AccessTools.Method(typeof(Plugin), patchName, (Type[])null, (Type[])null);
if (methodInfo == null || methodInfo2 == null)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to find valuable tracking patch target: " + originalType?.Name + "." + originalName));
return;
}
HarmonyMethod val = new HarmonyMethod(methodInfo2);
if (prefix)
{
valuableHaulHarmony.Patch((MethodBase)methodInfo, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
}
else
{
valuableHaulHarmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
}
}
private static void ValuableDollarHaulAddPostfix(ValuableObject __instance)
{
if (!((Object)(object)__instance == (Object)null))
{
valuablesCurrentlyInDollarHaul.Add(GetValuableKey(__instance));
}
}
private static void ValuableDollarHaulRemovePostfix(ValuableObject __instance)
{
if (!((Object)(object)__instance == (Object)null))
{
valuablesCurrentlyInDollarHaul.Remove(GetValuableKey(__instance));
}
}
private static void ValuableDollarValueSetLogicPostfix(ValuableObject __instance)
{
if (IsRunLevelSafe())
{
WzcMapValueService.RegisterValueSet(__instance, GetCurrentMapValueLevelNumber());
}
}
private static void ValuableDollarValueSetRpcPostfix(ValuableObject __instance, float value)
{
if (IsRunLevelSafe())
{
WzcMapValueService.RegisterValueSet(__instance, value, GetCurrentMapValueLevelNumber());
}
}
private static void ValuableBreakPostfix(float valueLost, PhysGrabObjectImpactDetector __instance, bool _loseValue)
{
if (_loseValue && IsRunLevelSafe())
{
WzcMapValueService.RegisterBreak(((Object)(object)__instance == (Object)null) ? null : ((Component)__instance).GetComponent<ValuableObject>(), valueLost, GetCurrentMapValueLevelNumber());
}
}
private static void ValuableDestroyPhysGrabObjectPostfix(PhysGrabObject __instance)
{
if (!((Object)(object)__instance == (Object)null) && IsRunLevelSafe())
{
WzcMapValueService.RegisterDestroy(((Component)__instance).GetComponent<ValuableObject>(), GetCurrentMapValueLevelNumber());
}
}
private static void RoundDirectorExtractionCompletedPostfix()
{
if (IsRunLevelSafe())
{
WzcMapValueService.SyncFromLiveValuables(GetValuableObjectsCachedForFrameStatic(), GetCurrentMapValueLevelNumber());
}
}
private static void LevelGeneratorStartRoomGenerationPrefix()
{
if ((Object)(object)Instance != (Object)null)
{
Instance.ResetLossTracking();
Instance.ClearCartLabelIndices();
Instance.ClearCartDistanceCache();
}
else
{
valuablesCurrentlyInDollarHaul.Clear();
WzcMapValueService.Reset();
}
}
private static void LevelGeneratorGenerateDonePostfix()
{
WzcMapValueService.SyncFromLiveValuables(GetValuableObjectsCachedForFrameStatic(), GetCurrentMapValueLevelNumber());
}
private string BuildOverlayText()
{
Enemy[] enemyObjectsCachedForFrame = GetEnemyObjectsCachedForFrame();
activeEnemyBuffer.Clear();
if (enemyObjectsCachedForFrame != null)
{
Enemy[] array = enemyObjectsCachedForFrame;
foreach (Enemy val in array)
{
if (IsEnemyCountable(val))
{
activeEnemyBuffer.Add(val);
}
}
}
List<MoreUiPlayerDistance> teammateInfos = CreateTeammateDistanceInfos();
enemyBreakdownBuffer.Clear();
enemyBreakdownRankBuffer.Clear();
foreach (Enemy item in activeEnemyBuffer)
{
string cachedEnemyDisplayName = GetCachedEnemyDisplayName(item);
if (!string.IsNullOrWhiteSpace(cachedEnemyDisplayName))
{
enemyBreakdownBuffer.TryGetValue(cachedEnemyDisplayName, out var value);
enemyBreakdownBuffer[cachedEnemyDisplayName] = value + 1;
int enemyBreakdownRank = GetEnemyBreakdownRank(item);
if (!enemyBreakdownRankBuffer.TryGetValue(cachedEnemyDisplayName, out var value2) || enemyBreakdownRank < value2)
{
enemyBreakdownRankBuffer[cachedEnemyDisplayName] = enemyBreakdownRank;
}
}
}
orderedEnemyBreakdownBuffer.Clear();
foreach (KeyValuePair<string, int> item2 in enemyBreakdownBuffer)
{
orderedEnemyBreakdownBuffer.Add(item2);
}
orderedEnemyBreakdownBuffer.Sort(CompareEnemyBreakdownEntry);
DisplayLanguage currentLanguage = CurrentLanguage;
bool flag = showEnemySection == null || showEnemySection.Value;
bool flag2 = showValueSection == null || showValueSection.Value;
bool flag3 = showTeammateInfoSection == null || showTeammateInfoSection.Value;
string text = string.Empty;
if (flag && showBreakdown.Value && orderedEnemyBreakdownBuffer.Count > 0)
{
enemyBreakdownLineBuffer.Clear();
foreach (KeyValuePair<string, int> item3 in orderedEnemyBreakdownBuffer)
{
enemyBreakdownLineBuffer.Add($"{item3.Key}: {item3.Value}");
}
text = string.Join("\n", enemyBreakdownLineBuffer);
}
string text2 = ((flag && showTotalEnemyCount.Value) ? $"{HudText.EnemyTotal(currentLanguage)}: {activeEnemyBuffer.Count}" : string.Empty);
string text3 = string.Empty;
string text4 = string.Empty;
string text5 = string.Empty;
string text6 = string.Empty;
string empty = string.Empty;
float mapValue = 0f;
float initialMapValue = 0f;
ValuableObject[] valuables = null;
int num;
if (flag2)
{
if (!showMapLostValue.Value && !showExplorationProgress.Value)
{
num = (showMapTotalValue.Value ? 1 : 0);
if (num == 0)
{
goto IL_02ef;
}
}
else
{
num = 1;
}
valuables = GetValuableObjectsCachedForFrame();
}
else
{
num = 0;
}
goto IL_02ef;
IL_02ef:
int levelNumber = SemiFunc.RunGetLevelsCompleted() + 1;
bool flag4 = num != 0 && WzcMapValueService.TryGetValues(valuables, levelNumber, out mapValue, out initialMapValue);
float num2 = 0f;
int num3 = 0;
float unexploredValue = 0f;
bool hasLiveValuableData = false;
if (flag2 && flag4)
{
bool value3 = showMapLostValue.Value;
bool value4 = showExplorationProgress.Value;
bool value5 = showMapTotalValue.Value;
float num4 = mapValue;
if (value3 || value4 || value5)
{
FillCurrentDollarHaulObjects(currentDollarHaulObjectsBuffer);
FillReferenceSet(currentDollarHaulObjectsBuffer, haulReferenceSetBuffer);
if (value5)
{
num4 = CalculateRemainingMapValue(mapValue, valuables, haulReferenceSetBuffer);
}
if (value3)
{
num2 = UpdateAndGetLostMapValue(mapValue, valuables, haulReferenceSetBuffer);
}
if (value4)
{
FillCurrentCartObjects(currentCartObjectsBuffer);
FillReferenceSet(currentCartObjectsBuffer, cartReferenceSetBuffer);
num3 = CalculateExplorationProgress(mapValue, initialMapValue, valuables, haulReferenceSetBuffer, cartReferenceSetBuffer, out unexploredValue, out hasLiveValuableData);
}
}
text3 = (showMapLostValue.Value ? (HudText.MapLostValue(currentLanguage) + ": " + FormatMoney(num2)) : string.Empty);
text4 = (showExplorationProgress.Value ? BuildExplorationProgressLine(currentLanguage, num3) : string.Empty);
text5 = (showExplorationProgress.Value ? BuildUnextractedFundsLine(currentLanguage, CalculateUnextractedFunds(initialMapValue, num3, unexploredValue, hasLiveValuableData)) : string.Empty);
mapValue = num4;
text6 = (showMapTotalValue.Value ? BuildMapValueLine(currentLanguage, mapValue) : string.Empty);
}
else if (flag2 && (showMapLostValue.Value || showExplorationProgress.Value || showMapTotalValue.Value))
{
text4 = (showExplorationProgress.Value ? BuildExplorationProgressLine(currentLanguage, 0) : string.Empty);
text5 = (showExplorationProgress.Value ? BuildUnextractedFundsLine(currentLanguage, 0f) : string.Empty);
text3 = (showMapLostValue.Value ? (HudText.MapLostValue(currentLanguage) + ": " + FormatMoney(0f)) : string.Empty);
text6 = (showMapTotalValue.Value ? BuildMapValueLine(currentLanguage, 0f) : string.Empty);
empty = string.Empty;
}
float shopRemainingFunds = (flag2 ? GetShopRemainingFundsSnapshot() : 0f);
float currentLevelFunds = (flag2 ? GetCurrentLevelSubmittedValue() : 0f);
evacuatedFundsLineBuffer.Clear();
if (flag2)
{
BuildEvacuatedFundsLines(currentLanguage, shopRemainingFunds, currentLevelFunds, evacuatedFundsLineBuffer);
}
string text7 = ((flag2 && showLevelInfo.Value) ? BuildLevelLine() : string.Empty);
monsterSectionPartsBuffer.Clear();
valueSectionPartsBuffer.Clear();
teammateSectionPartsBuffer.Clear();
if (flag3)
{
BuildRightBottomTeammateInfoParts(teammateInfos, teammateSectionPartsBuffer);
}
if (!string.IsNullOrWhiteSpace(text))
{
monsterSectionPartsBuffer.Add(text);
}
if (!string.IsNullOrWhiteSpace(text2))
{
monsterSectionPartsBuffer.Add(text2);
}
if (!string.IsNullOrWhiteSpace(text4))
{
valueSectionPartsBuffer.Add(text4);
}
if (!string.IsNullOrWhiteSpace(text5))
{
valueSectionPartsBuffer.Add(text5);
}
if (!string.IsNullOrWhiteSpace(text6))
{
valueSectionPartsBuffer.Add(text6);
}
if (!string.IsNullOrWhiteSpace(empty))
{
valueSectionPartsBuffer.Add(empty);
}
if (!string.IsNullOrWhiteSpace(text3))
{
valueSectionPartsBuffer.Add(text3);
}
if (evacuatedFundsLineBuffer.Count > 0)
{
valueSectionPartsBuffer.AddRange(evacuatedFundsLineBuffer);
}
if (!string.IsNullOrWhiteSpace(text7))
{
valueSectionPartsBuffer.Add(text7);
}
overlayPartsBuffer.Clear();
AppendSection(overlayPartsBuffer, monsterSectionPartsBuffer);
AppendSection(overlayPartsBuffer, valueSectionPartsBuffer);
AppendSection(overlayPartsBuffer, teammateSectionPartsBuffer);
string text8 = string.Join("\n", overlayPartsBuffer);
UpdateApiSnapshot(currentLanguage, text8, activeEnemyBuffer.Count, enemyBreakdownBuffer, flag4, mapValue, initialMapValue, unexploredValue, hasLiveValuableData, num3, num2, currentLevelFunds, shopRemainingFunds, teammateInfos, activeEnemyBuffer);
return text8;
}
private int CompareEnemyBreakdownEntry(KeyValuePair<string, int> left, KeyValuePair<string, int> right)
{
int value;
int num = (enemyBreakdownRankBuffer.TryGetValue(left.Key, out value) ? value : int.MaxValue);
int value2;
int value3 = (enemyBreakdownRankBuffer.TryGetValue(right.Key, out value2) ? value2 : int.MaxValue);
int num2 = num.CompareTo(value3);
if (num2 != 0)
{
return num2;
}
return string.Compare(left.Key, right.Key, StringComparison.Ordinal);
}
private void UpdateApiSnapshot(DisplayLanguage language, string overlayTextValue, int enemyTotalCount, Dictionary<string, int> enemyBreakdown, bool mapValueAvailable, float mapValue, float initialMapValue, float unexploredMapValue, bool hasLiveValuableData, int explorationProgressPercent, float lostValue, float currentLevelFunds, float shopRemainingFunds, List<MoreUiPlayerDistance> teammateInfos, List<Enemy> activeEnemies)
{
GetLevelInfo(language, out var levelNumber, out var levelName);
GetPlayerCountsFromTeammateInfos(teammateInfos, out var totalPlayers, out var alivePlayers, out var deadPlayers);
int capacity = teammateInfos?.Count ?? 0;
List<MoreUiPlayerDistance> list = new List<MoreUiPlayerDistance>(capacity);
List<MoreUiPlayerDistance> list2 = new List<MoreUiPlayerDistance>(capacity);
if (teammateInfos != null)
{
foreach (MoreUiPlayerDistance teammateInfo in teammateInfos)
{
if (teammateInfo != null)
{
if (teammateInfo.IsDead)
{
list2.Add(teammateInfo);
}
else
{
list.Add(teammateInfo);
}
}
}
}
MoreUiApi.UpdateSnapshot(new MoreUiSnapshot
{
IsInRun = true,
Language = language.ToString(),
DisplayMode = ((displayMode != null) ? displayMode.Value : DisplayMode.文字显示).ToString(),
OverlayText = (overlayTextValue ?? string.Empty),
EnemyTotalCount = enemyTotalCount,
EnemyBreakdown = ((enemyBreakdown == null) ? new Dictionary<string, int>() : new Dictionary<string, int>(enemyBreakdown)),
MapValueAvailable = mapValueAvailable,
MapValue = mapValue,
InitialMapValue = initialMapValue,
UnexploredMapValue = unexploredMapValue,
HasLiveValuableData = hasLiveValuableData,
ExplorationProgressPercent = explorationProgressPercent,
LostMapValue = lostValue,
CurrentRunEvacuatedFunds = currentLevelFunds,
CurrentRunSubmittedFunds = currentLevelFunds,
WarehouseFunds = shopRemainingFunds,
ShopRemainingFunds = shopRemainingFunds,
LevelNumber = levelNumber,
LevelName = (levelName ?? string.Empty),
TotalPlayerCount = totalPlayers,
AlivePlayerCount = alivePlayers,
DeadPlayerCount = deadPlayers,
AliveTeammates = list,
DeadTeammates = list2,
Enemies = CreateEnemyDistanceInfos(activeEnemies),
Carts = new List<MoreUiCartDistance>(cartDistanceCache),
Settings = CreateApiSettings(),
UpdatedFrame = Time.frameCount,
UpdatedAtUtc = DateTime.UtcNow
});
}
private void GetPlayerCountsFromTeammateInfos(List<MoreUiPlayerDistance> teammateInfos, out int totalPlayers, out int alivePlayers, out int deadPlayers)
{
List<PlayerAvatar> playerObjectsCachedForFrame = GetPlayerObjectsCachedForFrame();
PlayerAvatar localPlayer = GetLocalPlayer(playerObjectsCachedForFrame);
if (playerObjectsCachedForFrame == null || (Object)(object)localPlayer == (Object)null || teammateInfos == null)
{
GetPlayerCounts(out totalPlayers, out alivePlayers, out deadPlayers);
return;
}
totalPlayers = playerObjectsCachedForFrame.Count;
deadPlayers = 0;
foreach (MoreUiPlayerDistance teammateInfo in teammateInfos)
{
if (teammateInfo != null && teammateInfo.IsDead)
{
deadPlayers++;
}
}
alivePlayers = Math.Max(0, totalPlayers - deadPlayers);
}
private MoreUiDisplaySettings CreateApiSettings()
{
return new MoreUiDisplaySettings
{
ModEnabled = IsModEnabled(),
OverlayEnabled = (overlayEnabled != null && overlayEnabled.Value),
SectionSpacing = (sectionSpacing != null && sectionSpacing.Value),
Language = CurrentLanguage.ToString(),
EnemyNicknameNamesEnabled = UseEnemyNicknameNames,
DisplayMode = ((displayMode != null) ? displayMode.Value : DisplayMode.文字显示).ToString(),
FontSize = ((fontSize == null) ? 22 : fontSize.Value),
UpdateIntervalSeconds = ClampRefreshInterval((updateInterval == null) ? 0.5f : updateInterval.Value),
OverlayOffsetX = ((overlayOffsetX != null) ? overlayOffsetX.Value : 0),
OverlayOffsetY = ((overlayOffsetY != null) ? overlayOffsetY.Value : 0),
ShowEnemySection = (showEnemySection == null || showEnemySection.Value),
ShowEnemyBreakdown = (showBreakdown != null && showBreakdown.Value),
ShowEnemyTotal = (showTotalEnemyCount != null && showTotalEnemyCount.Value),
ShowValueSection = (showValueSection == null || showValueSection.Value),
ShowMapLostValue = (showMapLostValue != null && showMapLostValue.Value),
ShowExplorationProgress = (showExplorationProgress != null && showExplorationProgress.Value),
ShowMapTotalValue = (showMapTotalValue != null && showMapTotalValue.Value),
ShowCurrentRunSubmittedFunds = (showCurrentRunSubmittedFunds != null && showCurrentRunSubmittedFunds.Value),
ShowShopRemainingFunds = (showShopRemainingFunds != null && showShopRemainingFunds.Value),
ShowEvacuatedFunds = ((showCurrentRunSubmittedFunds != null && showCurrentRunSubmittedFunds.Value) || (showShopRemainingFunds != null && showShopRemainingFunds.Value)),
ShowLevelInfo = (showLevelInfo != null && showLevelInfo.Value),
ShowTeammateInfoSection = (showTeammateInfoSection == null || showTeammateInfoSection.Value),
ShowDeadTeammates = (showDeadTeammates != null && showDeadTeammates.Value),
ShowAliveTeammates = (showAliveTeammates != null && showAliveTeammates.Value),
ShowPlayerCounts = (showPlayerCounts != null && showPlayerCounts.Value),
TeammateOverlayEnabled = (teammateOverlayEnabled != null && teammateOverlayEnabled.Value),
TeammateAliveOverlayEnabled = (teammateAliveOverlayEnabled == null || teammateAliveOverlayEnabled.Value),
TeammateDeadOverlayEnabled = (teammateDeadOverlayEnabled == null || teammateDeadOverlayEnabled.Value),
TeammateFontSize = ((teammateFontSize == null) ? 22 : teammateFontSize.Value),
TeammateLabelHeightOffsetMeters = ((teammateLabelHeightOffset == null) ? 0.05f : teammateLabelHeightOffset.Value),
TeammateFarFontShrinkPercent = ((teammateFarFontShrinkPercent == null) ? 30 : teammateFarFontShrinkPercent.Value),
TeammateUpdateIntervalSeconds = ClampRefreshInterval((teammateUpdateInterval == null) ? 0.2f : teammateUpdateInterval.Value),
TeammateDisplayMode = ((teammateDisplayMode != null) ? teammateDisplayMode.Value : TeammateDisplayMode.常显).ToString(),
TeammateToggleKey = ((teammateToggleKey == null) ? "f" : SanitizeConfiguredKeyName(teammateToggleKey.Value)),
TeammateHoldSeconds = ((teammateHoldSeconds == null) ? 5 : teammateHoldSeconds.Value),
TeammateProximityAutoShowEnabled = (teammateProximityAutoShowEnabled != null && teammateProximityAutoShowEnabled.Value),
TeammateProximityAutoShowDistanceMeters = ((teammateProximityAutoShowDistance == null) ? 20 : teammateProximityAutoShowDistance.Value),
EnemyOverlayEnabled = (enemyOverlayEnabled != null && enemyOverlayEnabled.Value),
EnemyFontSize = ((enemyFontSize == null) ? 22 : enemyFontSize.Value),
EnemyFarFontShrinkPercent = ((enemyFarFontShrinkPercent == null) ? 30 : enemyFarFontShrinkPercent.Value),
EnemyUpdateIntervalSeconds = ClampRefreshInterval((enemyUpdateInterval == null) ? 0.2f : enemyUpdateInterval.Value),
EnemyDisplayMode = ((enemyDisplayMode == null) ? TeammateDisplayMode.按键显示 : enemyDisplayMode.Value).ToString(),
EnemyToggleKey = ((enemyToggleKey == null) ? "f" : SanitizeConfiguredKeyName(enemyToggleKey.Value)),
EnemyHoldSeconds = ((enemyHoldSeconds == null) ? 5 : enemyHoldSeconds.Value),
EnemyProximityAutoShowEnabled = (enemyProximityAutoShowEnabled != null && enemyProximityAutoShowEnabled.Value),
EnemyProximityAutoShowDistanceMeters = ((enemyProximityAutoShowDistance == null) ? 20 : enemyProximityAutoShowDistance.Value),
CartSectionEnabled = (cartSectionEnabled == null || cartSectionEnabled.Value),
CartOverlayEnabled = (cartOverlayEnabled != null && cartOverlayEnabled.Value),
SmallCartOverlayEnabled = (smallCartOverlayEnabled != null && smallCartOverlayEnabled.Value),
CartFontSize = ((cartFontSize == null) ? 22 : cartFontSize.Value),
CartFarFontShrinkPercent = ((cartFarFontShrinkPercent == null) ? 30 : cartFarFontShrinkPercent.Value),
CartLabelHeightOffsetMeters = ((cartLabelHeightOffset == null) ? 0f : cartLabelHeightOffset.Value),
CartUpdateIntervalSeconds = ClampRefreshInterval((cartUpdateInterval == null) ? 0.5f : cartUpdateInterval.Value)
};
}
private void BuildRightBottomTeammateInfoParts(List<MoreUiPlayerDistance> teammateInfos, List<string> parts)
{
string text = (showPlayerCounts.Value ? BuildPlayerCountLine() : string.Empty);
if (showDeadTeammates.Value)
{
AppendTeammateDistanceLines(teammateInfos, deadOnly: true, parts);
}
if (showAliveTeammates.Value)
{
AppendTeammateDistanceLines(teammateInfos, deadOnly: false, parts);
}
if (!string.IsNullOrWhiteSpace(text))
{
parts.Add(text);
}
}
private void UpdateTeammateOverlayState()
{
if (!teammateOverlayEnabled.Value)
{
teammateVisibleTimer = 0f;
teammateProximityVisibleTimer = 0f;
teammateProximityRefreshTimer = 0f;
return;
}
if (teammateDisplayMode.Value == TeammateDisplayMode.按键显示 && IsConfiguredKeyDown(teammateToggleKey.Value))
{
teammateVisibleTimer = Mathf.Max(0.1f, (float)teammateHoldSeconds.Value);
}
if (teammateDisplayMode.Value == TeammateDisplayMode.按键显示 && teammateVisibleTimer > 0f)
{
teammateVisibleTimer -= Time.deltaTime;
}
UpdateTeammateProximityAutoShowState();
}
private void UpdateEnemyOverlayState()
{
if (!enemyOverlayEnabled.Value)
{
enemyLabels.Clear();
ClearEnemyProximityTracking();
enemyVisibleTimer = 0f;
enemyProximityVisibleTimer = 0f;
return;
}
if (enemyDisplayMode.Value == TeammateDisplayMode.按键显示 && IsConfiguredKeyDown(enemyToggleKey.Value))
{
enemyVisibleTimer = Mathf.Max(0.1f, (float)enemyHoldSeconds.Value);
}
if (enemyDisplayMode.Value == TeammateDisplayMode.按键显示 && enemyVisibleTimer > 0f)
{
enemyVisibleTimer -= Time.deltaTime;
}
bool flag = UpdateEnemyProximityAutoShowState();
UpdateEnemyProximityPopTimers();
if (!(enemyDisplayMode.Value == TeammateDisplayMode.常显 || enemyVisibleTimer > 0f || flag))
{
enemyLabels.Clear();
return;
}
enemyRefreshTimer += Time.deltaTime;
if (enemyRefreshTimer >= ClampRefreshInterval((enemyUpdateInterval == null) ? 0.5f : enemyUpdateInterval.Value))
{
enemyRefreshTimer = 0f;
RefreshEnemyLabels();
}
}
private void UpdateTeammateProximityAutoShowState()
{
if (teammateProximityAutoShowEnabled == null || !teammateProximityAutoShowEnabled.Value)
{
teammateProximityVisibleTimer = 0f;
teammateProximityRefreshTimer = 0f;
return;
}
bool num = teammateAliveOverlayEnabled == null || teammateAliveOverlayEnabled.Value;
bool flag = teammateDeadOverlayEnabled == null || teammateDeadOverlayEnabled.Value;
if (!num && !flag)
{
teammateProximityVisibleTimer = 0f;
teammateProximityRefreshTimer = 0f;
return;
}
teammateProximityRefreshTimer += Time.deltaTime;
float num2 = ClampRefreshInterval((teammateUpdateInterval == null) ? 0.5f : teammateUpdateInterval.Value);
if (teammateProximityRefreshTimer >= num2)
{
teammateProximityRefreshTimer = 0f;
if (HasTeammateWithinDistance(teammateProximityAutoShowDistance.Value))
{
teammateProximityVisibleTimer = 5f;
}
else if (teammateProximityVisibleTimer > 0f)
{
teammateProximityVisibleTimer -= num2;
}
}
else if (teammateProximityVisibleTimer > 0f)
{
teammateProximityVisibleTimer -= Time.deltaTime;
}
}
private bool UpdateEnemyProximityAutoShowState()
{
if (enemyProximityAutoShowEnabled == null || !enemyProximityAutoShowEnabled.Value)
{
enemyProximityVisibleTimer = 0f;
ClearEnemyProximityTracking();
return false;
}
enemyProximityRefreshTimer += Time.deltaTime;
float num = ClampRefreshInterval((enemyUpdateInterval == null) ? 0.5f : enemyUpdateInterval.Value);
bool flag = false;
bool flag2 = enemiesInsideProximityRange.Count > 0;
if (enemyProximityRefreshTimer >= num)
{
enemyProximityRefreshTimer = 0f;
flag = true;
flag2 = UpdateEnemiesWithinProximityDistance(enemyProximityAutoShowDistance.Value);
}
if (flag2)
{
enemyProximityVisibleTimer = 5f;
}
else if (enemyProximityVisibleTimer > 0f && flag)
{
enemyProximityVisibleTimer -= num;
}
return enemyProximityVisibleTimer > 0f;
}
private bool HasTeammateWithinDistance(float distance)
{
//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_00a9: Unknown result type (might be due to invalid IL or missing references)
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
//IL_00af: 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)
if (distance <= 0f)
{
return false;
}
List<PlayerAvatar> playerObjectsCachedForFrame = GetPlayerObjectsCachedForFrame();
PlayerAvatar localPlayer = GetLocalPlayer(playerObjectsCachedForFrame);
if (playerObjectsCachedForFrame == null || (Object)(object)localPlayer == (Object)null)
{
return false;
}
Vector3 playerDistanceOrigin = GetPlayerDistanceOrigin(localPlayer, IsPlayerAlive(localPlayer));
float num = distance * distance;
bool flag = teammateAliveOverlayEnabled == null || teammateAliveOverlayEnabled.Value;
bool flag2 = teammateDeadOverlayEnabled == null || teammateDeadOverlayEnabled.Value;
foreach (PlayerAvatar item in playerObjectsCachedForFrame)
{
if ((Object)(object)item == (Object)null || item == localPlayer)
{
continue;
}
bool flag3 = IsPlayerAlive(item);
if ((!flag3 || flag) && (flag3 || flag2))
{
Vector3 val = GetPlayerReferencePosition(item, !flag3) - playerDistanceOrigin;
if (((Vector3)(ref val)).sqrMagnitude <= num)
{
return true;
}
}
}
return false;
}
private bool UpdateEnemiesWithinProximityDistance(float distance)
{
//IL_006e: 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_0079: Unknown result type (might be due to invalid IL or missing references)
if (distance <= 0f)
{
enemiesInsideProximityRange.Clear();
return false;
}
if (!TryGetEnemyDistanceOrigin(out var origin))
{
enemiesInsideProximityRange.Clear();
return false;
}
Enemy[] enemyObjectsCachedForFrame = GetEnemyObjectsCachedForFrame();
if (enemyObjectsCachedForFrame == null || enemyObjectsCachedForFrame.Length == 0)
{
enemiesInsideProximityRange.Clear();
return false;
}
float num = distance * distance;
currentEnemiesInsideProximityRange.Clear();
Enemy[] array = enemyObjectsCachedForFrame;
foreach (Enemy enemy in array)
{
if (!IsEnemyCountable(enemy))
{
continue;
}
Vector3 val = GetEnemyReferencePosition(enemy) - origin;
if (((Vector3)(ref val)).sqrMagnitude <= num)
{
int enemyKey = GetEnemyKey(enemy);
currentEnemiesInsideProximityRange.Add(enemyKey);
if (!enemiesInsideProximityRange.Contains(enemyKey))
{
enemyProximityPopTimers[enemyKey] = 1.2f;
}
}
}
enemiesInsideProximityRange.Clear();
foreach (int item in currentEnemiesInsideProximityRange)
{
enemiesInsideProximityRange.Add(item);
}
bool result = currentEnemiesInsideProximityRange.Count > 0;
currentEnemiesInsideProximityRange.Clear();
return result;
}
private void UpdateEnemyProximityPopTimers()
{
if (enemyProximityPopTimers.Count == 0)
{
return;
}
reusableIntKeys.Clear();
foreach (int key in enemyProximityPopTimers.Keys)
{
reusableIntKeys.Add(key);
}
foreach (int reusableIntKey in reusableIntKeys)
{
float num = enemyProximityPopTimers[reusableIntKey] - Time.deltaTime;
if (num <= 0f)
{
enemyProximityPopTimers.Remove(reusableIntKey);
}
else
{
enemyProximityPopTimers[reusableIntKey] = num;
}
}
}
private void ClearEnemyProximityTracking()
{
enemyProximityRefreshTimer = 0f;
enemyProximityPopTimers.Clear();
enemiesInsideProximityRange.Clear();
currentEnemiesInsideProximityRange.Clear();
}
private void UpdateCartDistanceCache()
{
if (!ShouldDrawCartWorldLabels())
{
ClearCartDistanceCache();
return;
}
cartRefreshTimer += Time.deltaTime;
float num = ClampRefreshInterval((cartUpdateInterval == null) ? 0.25f : cartUpdateInterval.Value);
if (!cartDistanceCacheValid || !(cartRefreshTimer < num))
{
cartRefreshTimer = 0f;
cartDistanceCache.Clear();
FillCartDistanceInfos(cartDistanceCache);
cartDistanceCacheValid = true;
}
}
private void ClearCartDistanceCache()
{
cartRefreshTimer = 0f;
cartDistanceCacheValid = false;
cartDistanceCache.Clear();
}
private Enemy[] GetEnemyObjectsCachedForFrame()
{
int frameCount = Time.frameCount;
if (enemyObjectsFrameCacheFrame == frameCount && enemyObjectsFrameCache != null)
{
return enemyObjectsFrameCache;
}
enemyObjectsFrameCacheFrame = frameCount;
enemyObjectsFrameCache = Resources.FindObjectsOfTypeAll<Enemy>() ?? Array.Empty<Enemy>();
return enemyObjectsFrameCache;
}
private PhysGrabCart[] GetCartObjectsCachedForFrame()
{
int frameCount = Time.frameCount;
if (cartObjectsFrameCacheFrame == frameCount && cartObjectsFrameCache != null)
{
return cartObjectsFrameCache;
}
cartObjectsFrameCacheFrame = frameCount;
cartObjectsFrameCache = Object.FindObjectsOfType<PhysGrabCart>(true) ?? Array.Empty<PhysGrabCart>();
return cartObjectsFrameCache;
}
private PhysGrabber[] GetGrabberObjectsCachedForFrame()
{
int frameCount = Time.frameCount;
if (grabberObjectsFrameCacheFrame == frameCount && grabberObjectsFrameCache != null)
{
return grabberObjectsFrameCache;
}
grabberObjectsFrameCacheFrame = frameCount;
grabberObjectsFrameCache = Object.FindObjectsOfType<PhysGrabber>(true) ?? Array.Empty<PhysGrabber>();
return grabberObjectsFrameCache;
}
private ValuableObject[] GetValuableObjectsCachedForFrame()
{
int frameCount = Time.frameCount;
if (valuableObjectsFrameCacheFrame == frameCount && valuableObjectsFrameCache != null)
{
return valuableObjectsFrameCache;
}
valuableObjectsFrameCacheFrame = frameCount;
valuableObjectsFrameCache = Object.FindObjectsOfType<ValuableObject>() ?? Array.Empty<ValuableObject>();
return valuableObjectsFrameCache;
}
private static ValuableObject[] GetValuableObjectsCachedForFrameStatic()
{
ValuableObject[] array;
if (!((Object)(object)Instance != (Object)null))
{
array = Object.FindObjectsOfType<ValuableObject>();
if (array == null)
{
return Array.Empty<ValuableObject>();
}
}
else
{
array = Instance.GetValuableObjectsCachedForFrame();
}
return array;
}
private List<PlayerAvatar> GetPlayerObjectsCachedForFrame()
{
int frameCount = Time.frameCount;
if (playerObjectsFrameCacheFrame == frameCount)
{
return playerObjectsFrameCache;
}
playerObjectsFrameCacheFrame = frameCount;
try
{
playerObjectsFrameCache = SemiFunc.PlayerGetAll();
}
catch
{
playerObjectsFrameCache = null;
}
return playerObjectsFrameCache;
}
private static int GetEnemyKey(Enemy enemy)
{
if (!((Object)(object)enemy == (Object)null))
{
return ((Object)enemy).GetInstanceID();
}
return 0;
}
private bool TryGetEnemyDistanceOrigin(out Vector3 origin)
{
//IL_001d: 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_0053: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_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)
try
{
PlayerAvatar localPlayer = GetLocalPlayer(GetPlayerObjectsCachedForFrame());
if ((Object)(object)localPlayer != (Object)null)
{
origin = GetPlayerDistanceOrigin(localPlayer, IsPlayerAlive(localPlayer));
return true;
}
}
catch
{
}
Camera worldLabelCamera = GetWorldLabelCamera();
if ((Object)(object)worldLabelCamera != (Object)null)
{
origin = ((Component)worldLabelCamera).transform.position;
return true;
}
origin = Vector3.zero;
return false;
}
private static int GetEnemyBreakdownRank(Enemy enemy)
{
string key = NormalizeEnemyBreakdownKey(GetEnemyRawSortName(enemy));
if (!EnemyBreakdownRankTable.TryGetValue(key, out var value))
{
return 999;
}
return value;
}
private static string GetEnemyRawSortName(Enemy enemy)
{
if ((Object)(object)enemy == (Object)null)
{
return string.Empty;
}
try
{
if (TryGetEnemyParentDisplayName(((Component)enemy).GetComponentInParent<EnemyParent>(), out var name))
{
return name;
}
}
catch
{
}
try
{
Type type = ((object)enemy).GetType();
if (type != null && !string.IsNullOrWhiteSpace(type.Name))
{
return type.Name.Replace("(Clone)", string.Empty).Trim();
}
}
catch
{
}
if (!string.IsNullOrWhiteSpace(((Object)enemy).name))
{
return ((Object)enemy).name.Replace("(Clone)", string.Empty).Trim();
}
return string.Empty;
}
private static string NormalizeEnemyBreakdownKey(string value)
{
if (string.IsNullOrWhiteSpace(value))
{
return string.Empty;
}
return ReplaceIgnoreCase(ReplaceIgnoreCase(ReplaceIgnoreCase(ReplaceIgnoreCase(ReplaceIgnoreCase(ReplaceIgnoreCase(ReplaceIgnoreCase(ReplaceIgnoreCase(ReplaceIgnoreCase(ReplaceIgnoreCase(ReplaceIgnoreCase(ReplaceIgnoreCase(value.Replace("(Clone)", string.Empty).Trim(), "Enemy ", string.Empty), "Peeper Ceiling Eye", "Peeper"), "Headgrab", "Head Grabber"), "Headman", "Head"), "Bomb Thrower", "Cleanup Crew"), "Banger", "Bang"), "Runner", "Reaper"), "Clown", "Beamer"), "Chef", "Cleanup Crew"), "Frog", "Cleanup Crew"), "Tumbler", "Cleanup Crew"), "Huntsman", "Hunter").Trim();
}
private static string ReplaceIgnoreCase(string source, string oldValue, string newValue)
{
if (string.IsNullOrEmpty(source) || string.IsNullOrEmpty(oldValue))
{
return source;
}
for (int num = source.IndexOf(oldValue, StringComparison.OrdinalIgnoreCase); num >= 0; num = source.IndexOf(oldValue, num + (newValue?.Length ?? 0), StringComparison.OrdinalIgnoreCase))
{
source = source.Remove(num, oldValue.Length).Insert(num, newValue ?? string.Empty);
}
return source;
}
private void AppendSection(List<string> parts, List<string> sectionItems)
{
if (sectionItems != null && sectionItems.Count != 0)
{
if (parts.Count > 0 && sectionSpacing.Value)
{
parts.Add(string.Empty);
}
parts.AddRange(sectionItems);
}
}
private static string ColorOverlayLine(string text, string colorHex)
{
if (string.IsNullOrWhiteSpace(text))
{
return text;
}
string text2 = (string.IsNullOrWhiteSpace(colorHex) ? "ffffff" : colorHex.TrimStart(new char[1] { '#' }));
return "<color=#" + text2 + ">" + text + "</color>";
}
private static int GetDistanceScaledFontSize(int maxFontSize, float shrinkPercent, float distance, float fullShrinkDistance, int hardMaxFontSize)
{
int num = Mathf.Clamp(maxFontSize, 8, hardMaxFontSize);
float num2 = Mathf.Clamp(shrinkPercent, 0f, 75f) / 100f;
float num3 = (float)num * (1f - num2);
float num4 = Mathf.Max(1f, fullShrinkDistance);
float num5 = Mathf.Clamp01(distance / num4);
return Mathf.Clamp(Mathf.RoundToInt(Mathf.Lerp((float)num, num3, num5)), 8, hardMaxFontSize);
}
private static Vector2 CalcLabelSize(GUIStyle style, string text)
{
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
ReusableGuiContent.text = text ?? string.Empty;
return style.CalcSize(ReusableGuiContent);
}
private static float CalcLabelHeight(GUIStyle style, string text, float width)
{
ReusableGuiContent.text = text ?? string.Empty;
return style.CalcHeight(ReusableGuiContent, width);
}
private GUIStyle GetCenteredLabelStyle(int fontSize, bool shadow)
{
//IL_0033: 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: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: 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_005f: Expected O, but got Unknown
//IL_0083: 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)
Dictionary<int, GUIStyle> dictionary = (shadow ? centeredShadowLabelStyleCache : centeredRichLabelStyleCache);
int key = Mathf.Clamp(fontSize, 8, 60);
if (dictionary.TryGetValue(key, out var value))
{
return value;
}
value = new GUIStyle(GUI.skin.label)
{
fontSize = key,
fontStyle = (FontStyle)1,
alignment = (TextAnchor)4,
wordWrap = false,
richText = !shadow
};
value.normal.textColor = (Color)(shadow ? new Color(0f, 0f, 0f, 0.85f) : Color.white);
dictionary[key] = value;
return value;
}
private GUIStyle GetOverlayLabelStyle(int fontSize, bool shadow)
{
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: 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_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Expected O, but got Unknown
//IL_0084: 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)
Dictionary<int, GUIStyle> dictionary = (shadow ? overlayShadowStyleCache : overlayRichStyleCache);
int key = Mathf.Clamp(fontSize, 10, 28);
if (dictionary.TryGetValue(key, out var value))
{
return value;
}
value = new GUIStyle(GUI.skin.label)
{
fontSize = key,
fontStyle = (FontStyle)1,
alignment = (TextAnchor)8,
wordWrap = false,
richText = !shadow
};
value.normal.textColor = (Color)(shadow ? new Color(0f, 0f, 0f, 0.85f) : Color.white);
dictionary[key] = value;
return value;
}
private void UpdateNativeOverlay()
{
//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
//IL_0147: Unknown result type (might be due to invalid IL or missing references)
//IL_0161: Unknown result type (might be due to invalid IL or missing references)
//IL_017b: Unknown result type (might be due to invalid IL or missing references)
//IL_01af: Unknown result type (might be due to invalid IL or missing references)
//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
if (displayMode.Value != DisplayMode.原生UI显示 || string.IsNullOrWhiteSpace(overlayText))
{
return;
}
EnsureNativeOverlay();
if (!((Object)(object)overlayLabel == (Object)null) && !((Object)(object)overlayRect == (Object)null))
{
int num = Mathf.Clamp(fontSize.Value, 10, 28);
if (!string.Equals(lastNativeOverlayText, overlayText, StringComparison.Ordinal) || lastNativeOverlayFontSize != num || lastNativeOverlayOffsetX != overlayOffsetX.Value || lastNativeOverlayOffsetY != overlayOffsetY.Value || lastNativeOverlayShowBreakdown != showBreakdown.Value)
{
((TMP_Text)overlayLabel).text = overlayText;
((TMP_Text)overlayLabel).fontSize = num;
((Graphic)overlayLabel).color = Color.white;
((TMP_Text)overlayLabel).enableWordWrapping = false;
((TMP_Text)overlayLabel).alignment = (TextAlignmentOptions)1028;
((TMP_Text)overlayLabel).overflowMode = (TextOverflowModes)0;
((TMP_Text)overlayLabel).horizontalAlignment = (HorizontalAlignmentOptions)4;
((TMP_Text)overlayLabel).verticalAlignment = (VerticalAlignmentOptions)1024;
float num2 = (showBreakdown.Value ? 460f : 320f);
overlayRect.anchorMin = new Vector2(1f, 0f);
overlayRect.anchorMax = new Vector2(1f, 0f);
overlayRect.pivot = new Vector2(1f, 0f);
overlayRect.anchoredPosition = new Vector2(-18f - (float)overlayOffsetX.Value, 18f + (float)overlayOffsetY.Value);
overlayRect.sizeDelta = new Vector2(num2, 720f);
lastNativeOverlayText = overlayText;
lastNativeOverlayFontSize = num;
lastNativeOverlayOffsetX = overlayOffsetX.Value;
lastNativeOverlayOffsetY = overlayOffsetY.Value;
lastNativeOverlayShowBreakdown = showBreakdown.Value;
}
}
}
private void EnsureNativeOverlay()
{
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
//IL_0087: Expected O, but got Unknown
//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
//IL_011c: Unknown result type (might be due to invalid IL or missing references)
//IL_0126: Expected O, but got Unknown
if (!((Object)(object)overlayObject != (Object)null) || !((Object)(object)overlayLabel != (Object)null) || !((Object)(object)overlayRect != (Object)null))
{
if ((Object)(object)overlayCanvasObject == (Object)null || (Object)(object)overlayCanvas == (Object)null)
{
overlayCanvasObject = new GameObject("moreui.Canvas", new Type[3]
{
typeof(Canvas),
typeof(CanvasScaler),
typeof(GraphicRaycaster)
});
overlayCanvas = overlayCanvasObject.GetComponent<Canvas>();
overlayCanvas.renderMode = (RenderMode)0;
overlayCanvas.sortingOrder = 32767;
overlayCanvas.pixelPerfect = false;
CanvasScaler component = overlayCanvasObject.GetComponent<CanvasScaler>();
component.uiScaleMode = (ScaleMode)1;
component.referenceResolution = new Vector2(1920f, 1080f);
component.screenMatchMode = (ScreenMatchMode)0;
component.matchWidthOrHeight = 0.5f;
Object.DontDestroyOnLoad((Object)(object)overlayCanvasObject);
}
overlayObject = new GameObject("moreui.NativeOverlay", new Type[1] { typeof(RectTransform) });
overlayObject.transform.SetParent(((Component)overlayCanvas).transform, false);
overlayObject.transform.SetAsLastSibling();
overlayRect = overlayObject.GetComponent<RectTransform>();
overlayLabel = overlayObject.AddComponent<TextMeshProUGUI>();
((Graphic)overlayLabel).raycastTarget = false;
((TMP_Text)overlayLabel).richText = true;
((TMP_Text)overlayLabel).enableWordWrapping = false;
((TMP_Text)overlayLabel).alignment = (TextAlignmentOptions)1028;
TryCopyGoalUiStyle(overlayLabel);
}
}
private static void TryCopyGoalUiStyle(TextMeshProUGUI target)
{
//IL_0027: 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_007d: Unknown result type (might be due to invalid IL or missing references)
//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)target == (Object)null)
{
return;
}
GoalUI val = Object.FindObjectOfType<GoalUI>();
if ((Object)(object)val == (Object)null || GoalUiTextField == null)
{
((Graphic)target).color = Color.white;
return;
}
object? value = GoalUiTextField.GetValue(val);
TextMeshProUGUI val2 = (TextMeshProUGUI)((value is TextMeshProUGUI) ? value : null);
if ((Object)(object)val2 == (Object)null)
{
((Graphic)target).color = Color.white;
return;
}
((TMP_Text)target).font = ((TMP_Text)val2).font;
((TMP_Text)target).fontSharedMaterial = ((TMP_Text)val2).fontSharedMaterial;
((Graphic)target).color = Color.white;
((TMP_Text)target).outlineColor = ((TMP_Text)val2).outlineColor;
((TMP_Text)target).outlineWidth = ((TMP_Text)val2).outlineWidth;
((TMP_Text)target).enableVertexGradient = ((TMP_Text)val2).enableVertexGradient;
((TMP_Text)target).fontStyle = ((TMP_Text)val2).fontStyle;
((TMP_Text)target).characterSpacing = ((TMP_Text)val2).characterSpacing;
((TMP_Text)target).lineSpacing = ((TMP_Text)val2).lineSpacing;
((TMP_Text)target).margin = ((TMP_Text)val2).margin;
}
private float UpdateAndGetLostMapValue(float currentMapValue, ValuableObject[] valuables, HashSet<object> haulObjects)
{
int num = SemiFunc.RunGetLevelsCompleted() + 1;
if (trackedLevelNumber != num || previousExtractedValue < 0f)
{
trackedLevelNumber = num;
previousExtractedValue = 0f;
accumulatedLostValue = 0f;
valuableSnapshots.Clear();
UpdateValuableLossSnapshots(extractionJustChanged: false, valuables, haulObjects);
return accumulatedLostValue;
}
UpdateValuableLossSnapshots(extractionJustChanged: false, valuables, haulObjects);
return accumulatedLostValue;
}
private void ResetLossTracking()
{
trackedLevelNumber = -1;
previousExtractedValue = -1f;
accumulatedLostValue = 0f;
submittedFundsSnapshotLevelNumber = -1;
submittedFundsBaselineTotalHaul = -1f;
submittedFundsSnapshot = 0f;
shopRemainingSnapshotLevelNumber = -1;
shopRemainingFundsSnapshot = -1f;
valuableSnapshots.Clear();
valuablesCurrentlyInDollarHaul.Clear();
WzcMapValueService.Reset();
}
private void UpdateValuableLossSnapshots(bool extractionJustChanged, ValuableObject[] valuables, HashSet<object> haulObjects)
{
valuables = valuables ?? Array.Empty<ValuableObject>();
haulObjects = haulObjects ?? new HashSet<object>(ReferenceObjectComparer.Instance);
liveValuableKeys.Clear();
ValuableObject[] array = valuables;
foreach (ValuableObject val in array)
{
if (!((Object)(object)val == (Object)null) && IsValuableReady(val))
{
int valuableKey = GetValuableKey(val);
float floatField = GetFloatField(ValuableOriginalValueField, val);
float floatField2 = GetFloatField(ValuableCurrentValueField, val);
float num = Mathf.Max(0f, floatField - floatField2);
object physGrabObject = ValuablePhysGrabObjectField?.GetValue(val);
bool flag = IsValuableMarkedInHaul(valuableKey) || IsValuableInReferenceSet(val, physGrabObject, haulObjects);
liveValuableKeys.Add(valuableKey);
if (!valuableSnapshots.TryGetValue(valuableKey, out var value))
{
ValuableSnapshot valuableSnapshot = default(ValuableSnapshot);
valuableSnapshot.CountedLostValue = 0f;
value = valuableSnapshot;
}
value.OriginalValue = floatField;
value.CurrentValue = floatField2;
value.CurrentDamage = num;
value.WasInHaul = flag;
float num2 = Mathf.Clamp(num, 0f, Mathf.Max(0f, floatField));
if (!flag && num2 > value.CountedLostValue + 0.01f)
{
accumulatedLostValue += num2 - value.CountedLostValue;
value.CountedLostValue = num2;
}
valuableSnapshots[valuableKey] = value;
}
}
reusableSnapshotKeys.Clear();
foreach (int key in valuableSnapshots.Keys)
{
reusableSnapshotKeys.Add(key);
}
foreach (int reusableSnapshotKey in reusableSnapshotKeys)
{
if (!liveValuableKeys.Contains(reusableSnapshotKey))
{
ValuableSnapshot snapshot = valuableSnapshots[reusableSnapshotKey];
if (!snapshot.WasInHaul && !extractionJustChanged)
{
accumulatedLostValue += CalculateRemovedValuableLoss(snapshot);
}
valuableSnapshots.Remove(reusableSnapshotKey);
}
}
liveValuableKeys.Clear();
}
private static float CalculateRemovedValuableLoss(ValuableSnapshot snapshot)
{
float num = Mathf.Max(0f, snapshot.OriginalValue);
return Mathf.Max(0f, num - snapshot.CountedLostValue);
}
private static float GetCurrentExtractedValue()
{
try
{
return (float)SemiFunc.StatGetRunCurrency() * 1000f;
}
catch
{
try
{
return (float)SemiFunc.StatGetRunTotalHaul() * 1000f;
}
catch
{
return 0f;
}
}
}
private static float GetShopRemainingFundsValue()
{
try
{
return (float)SemiFunc.StatGetRunCurrency() * 1000f;
}
catch
{
return 0f;
}
}
private float GetShopRemainingFundsSnapshot()
{
int num = SemiFunc.RunGetLevelsCompleted() + 1;
if (shopRemainingSnapshotLevelNumber != num || shopRemainingFundsSnapshot < 0f)
{
shopRemainingSnapshotLevelNumber = num;
shopRemainingFundsSnapshot = GetShopRemainingFundsValue();
}
return shopRemainingFundsSnapshot;
}
private static float GetRunTotalHaulValue()
{
try
{
return (float)SemiFunc.StatGetRunTotalHaul() * 1000f;
}
catch
{
return 0f;
}
}
private float GetCurrentLevelSubmittedValue()
{
int submittedFundsLevelKey = GetSubmittedFundsLevelKey();
if (submittedFundsSnapshotLevelNumber != submittedFundsLevelKey || submittedFundsBaselineTotalHaul < 0f)
{
submittedFundsSnapshotLevelNumber = submittedFundsLevelKey;
submittedFundsBaselineTotalHaul = GetRunTotalHaulValue();
submittedFundsSnapshot = 0f;
}
float num = Mathf.Max(0f, GetRunTotalHaulValue() - submittedFundsBaselineTotalHaul);
submittedFundsSnapshot = Mathf.Max(submittedFundsSnapshot, num);
return submittedFundsSnapshot;
}
private static int GetSubmittedFundsLevelKey()
{
int num = SemiFunc.RunGetLevelsCompleted();
try
{
return SemiFunc.RunIsShop() ? num : (num + 1);
}
catch
{
return num + 1;
}
}
private static float GetRoundDirectorCurrentHaulValue()
{
object obj = RoundDirectorInstanceField?.GetValue(null);
if (obj != null && RoundDirectorCurrentHaulField != null)
{
return Mathf.Max(0f, GetFloatField(RoundDirectorCurrentHaulField, obj));
}
return 0f;
}
private static bool IsValuableReady(ValuableObject valuable)
{
if (ValuableValueSetField == null)
{
return true;
}
object value = ValuableValueSetField.GetValue(valuable);
bool flag = default(bool);
int num;
if (value is bool)
{
flag = (bool)value;
num = ((1 == 0) ? 1 : 0);
}
else
{
num = 1;
}
return (byte)((uint)num | (flag ? 1u : 0u)) != 0;
}
private static int GetValuableKey(ValuableObject valuable)
{
object obj = ValuablePhotonViewField?.GetValue(valuable);
if (obj != null)
{
Type type = obj.GetType();
if (GetCachedPhotonViewIdProperty(type)?.GetValue(obj, null) is int num && num != 0)
{
return num;
}
if (GetCachedPhotonViewIdField(type)?.GetValue(obj) is int num2 && num2 != 0)
{
return num2;
}
}
return ((Object)valuable).GetInstanceID();
}
private static PropertyInfo GetCachedPhotonViewIdProperty(Type photonViewType)
{
if (photonViewType == null)
{
return null;
}
if (!PhotonViewIdPropertyCache.TryGetValue(photonViewType, out var value))
{
value = photonViewType.GetProperty("ViewID", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
PhotonViewIdPropertyCache[photonViewType] = value;
}
return value;
}
private static FieldInfo GetCachedPhotonViewIdField(Type photonViewType)
{
if (photonViewType == null)
{
return null;
}
if (!PhotonViewIdFieldCache.TryGetValue(photonViewType, out var value))
{
value = photonViewType.GetField("viewID", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? photonViewType.GetField("ViewID", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
PhotonViewIdFieldCache[photonViewType] = value;
}
return value;
}
private static PropertyInfo GetCachedPhotonViewOwnerProperty(Type photonViewType)
{
if (photonViewType == null)
{
return null;
}
if (!PhotonViewOwnerPropertyCache.TryGetValue(photonViewType, out var value))
{
value = photonViewType.GetProperty("Owner", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
PhotonViewOwnerPropertyCache[photonViewType] = value;
}
return value;
}
private static PropertyInfo GetCachedPhotonOwnerNickNameProperty(Type ownerType)
{
if (ownerType == null)
{
return null;
}
if (!PhotonOwnerNickNamePropertyCache.TryGetValue(ownerType, out var value))
{
value = ownerType.GetProperty("NickName", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
PhotonOwnerNickNamePropertyCache[ownerType] = value;
}
return value;
}
private static float GetFloatField(FieldInfo field, object instance)
{
if (field == null || instance == null)
{
return 0f;
}
object value = field.GetValue(instance);
if (value != null)
{
return Convert.ToSingle(value, CultureInfo.InvariantCulture);
}
return 0f;
}
private static void FillCurrentDollarHaulObjects(List<object> result)
{
if (result == null)
{
return;
}
result.Clear();
object obj = RoundDirectorInstanceField?.GetValue(null);
if (!(((obj == null) ? null : RoundDirectorDollarHaulListField?.GetValue(obj)) is IEnumerable enumerable))
{
return;
}
foreach (object item in enumerable)
{
if (item != null)
{
result.Add(item);
}
}
}
private void FillCurrentCartObjects(List<object> result)
{
if (result == null)
{
return;
}
result.Clear();
PhysGrabCart[] cartObjectsCachedForFrame = GetCartObjectsCachedForFrame();
if (cartObjectsCachedForFrame == null || cartObjectsCachedForFrame.Length == 0)
{
return;
}
PhysGrabCart[] array = cartObjectsCachedForFrame;
foreach (PhysGrabCart val in array)
{
if ((Object)(object)val == (Object)null)
{
continue;
}
AddEnumerableObjects(result, PhysGrabCartItemsInCartField?.GetValue(val));
object obj = PhysGrabCartInCartField?.GetValue(val);
if (!(((obj == null) ? null : PhysGrabInCartObjectsField?.GetValue(obj)) is IEnumerable enumerable))
{
continue;
}
foreach (object item in enumerable)
{
object obj2 = PhysGrabInCartCartObjectPhysGrabObjectField?.GetValue(item);
if (obj2 != null)
{
result.Add(obj2);
}
}
}
}
private static void AddEnumerableObjects(List<object> result, object rawList)
{
if (!(rawList is IEnumerable enumerable))
{
return;
}
foreach (object item in enumerable)
{
if (item != null)
{
result.Add(item);
}
}
}
private static void FillReferenceSet(List<object> list, HashSet<object> result)
{
if (result == null)
{
return;
}
result.Clear();
if (list == null || list.Count == 0)
{
return;
}
foreach (object item in list)
{
if (item != null)
{
result.Add(item);
}
}
}
private static bool IsReferenceInSet(HashSet<object> set, object target)
{
if (target != null && set != null)
{
return set.Contains(target);
}
return false;
}
private static bool IsValuableMarkedInHaul(int key)
{
if (key != 0)
{
return valuablesCurrentlyInDollarHaul.Contains(key);
}
return false;
}
private static bool IsValuableInReferenceSet(ValuableObject valuable, object physGrabObject, HashSet<object> set)
{
if ((Object)(object)valuable == (Object)null || set == null || set.Count == 0)
{
return false;
}
GameObject gameObject = ((Component)valuable).gameObject;
GameObject objectGameObject = GetObjectGameObject(physGrabObject);
foreach (object item in set)
{
if (item != null)
{
if (item == valuable