using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using CrestsEvolve.Bootstrap; using CrestsEvolve.Core.Balance; using CrestsEvolve.Core.Buffs; using CrestsEvolve.Core.Charms; using CrestsEvolve.Core.Combat; using CrestsEvolve.Core.Events; using CrestsEvolve.Core.Infrastructure; using CrestsEvolve.Core.Input; using CrestsEvolve.Core.Random; using CrestsEvolve.Core.Time; using CrestsEvolve.Core.Tools; using CrestsEvolve.Core.UI; using CrestsEvolve.Features; using CrestsEvolve.Features.StatusIcons; using CrestsEvolve.Features.Tools; using CrestsEvolve.GameInterop; using CrestsEvolve.GameInterop.Binding; using CrestsEvolve.GameInterop.Input; using CrestsEvolve.GameInterop.Patches; using CrestsEvolve.GameInterop.Reflection; using CrestsEvolve.UI; using GlobalEnums; using GlobalSettings; using HarmonyLib; using HutongGames.PlayMaker; using InControl; using Microsoft.CodeAnalysis; using Needleforge; using Needleforge.Data; using Newtonsoft.Json; using TeamCherry.Localization; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: InternalsVisibleTo("CrestsEvolve.LegendsNeverDie")] [assembly: InternalsVisibleTo("CrestsEvolve.RageOfTheGoner")] [assembly: InternalsVisibleTo("CrestsEvolve.ToolsAscension")] [assembly: InternalsVisibleTo("CrestsEvolve.InsectMayCry")] [assembly: InternalsVisibleTo("CrestsEvolve.Core.Tests")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("CrestsEvolve")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+757e75a2d4534028308600b7117b47c56eb48037")] [assembly: AssemblyProduct("CrestsEvolve")] [assembly: AssemblyTitle("CrestsEvolve")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } internal static class IsExternalInit { } } namespace CrestsEvolve { [BepInPlugin("local.crestsevolve", "CrestsEvolve", "0.1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { public const string PluginGuid = "local.crestsevolve"; public const string PluginName = "CrestsEvolve"; public const string PluginVersion = "0.1.0"; private Harmony? _harmony; private ModBootstrap? _bootstrap; private void Awake() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown _harmony = new Harmony("local.crestsevolve"); _bootstrap = new ModBootstrap(((BaseUnityPlugin)this).Logger, ((BaseUnityPlugin)this).Config, _harmony); _bootstrap.Start(); } private void OnDestroy() { try { _bootstrap?.Dispose(); } finally { Harmony? harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } } } namespace CrestsEvolve.UI { public sealed class LogStatusIconPresenter : IStatusIconPresenter { private readonly ManualLogSource _log; public static bool Verbose { get; set; } public LogStatusIconPresenter(ManualLogSource log) { _log = log; } public void Present(StatusIconProjection projection) { if (Verbose) { _log.LogDebug((object)($"[StatusIcons] rev={projection.Revision} " + string.Join("; ", projection.Icons.Select((StatusIconState i) => $"{i.Key}={i.Current}/{i.Max}")))); } } public void Hide() { _log.LogDebug((object)"[StatusIcons] hidden"); } } public sealed class LogUiPresenter : IUiPresenter { private readonly ManualLogSource _log; public static bool Verbose { get; set; } public LogUiPresenter(ManualLogSource log) { _log = log; } public void Present(UiProjection projection) { if (Verbose) { _log.LogDebug((object)($"[UiProjection] crest={projection.CrestId} rev={projection.Revision} " + $"stacks={projection.EnhancementStacks} remaining={projection.RemainingSeconds:F1} " + $"rage={projection.Rage} superRage={projection.SuperRage} special={projection.SpecialMode} " + $"charmOffset={projection.CharmLevelOffset} shield={projection.SilkShieldRemaining} " + $"rageRemaining={projection.RageRemainingSeconds:F1}")); } } public void Hide() { if (Verbose) { _log.LogDebug((object)"[UiProjection] hidden"); } } } public sealed record StatusIconState(string Key, int Current, int Max, bool Visible = true, string? ColorOverride = null, string? CenterText = null, bool Dimmed = false); public sealed record StatusIconProjection(long Revision, IReadOnlyList Icons); public interface IStatusIconPresenter { void Present(StatusIconProjection projection); void Hide(); } public sealed class StatusIconProjector : IDisposable { private readonly StatusIconLedger _ledger; private readonly IStatusIconPresenter _presenter; private long _lastRevision = -1L; public static StatusIconProjector? Current { get; private set; } public StatusIconProjector(StatusIconLedger ledger, IStatusIconPresenter presenter) { _ledger = ledger ?? throw new ArgumentNullException("ledger"); _presenter = presenter ?? throw new ArgumentNullException("presenter"); if (Current != null) { throw new InvalidOperationException("A StatusIconProjector is already active."); } Current = this; _ledger.Changed += OnChanged; OnChanged(_ledger.Snapshot()); } public void Refresh() { StatusIconSnapshot statusIconSnapshot = _ledger.Snapshot(); _lastRevision = statusIconSnapshot.Revision; Present(statusIconSnapshot); } private void OnChanged(StatusIconSnapshot snapshot) { if (snapshot.Revision != _lastRevision) { _lastRevision = snapshot.Revision; Present(snapshot); } } private void Present(StatusIconSnapshot snapshot) { List list = new List(snapshot.Icons.Count); foreach (StatusIconValue icon in snapshot.Icons) { bool flag = icon.Visible; if (flag && icon.Current <= 0 && !StatusIconProjectionRules.ZeroValueVisible(icon.Key)) { flag = false; } list.Add(new StatusIconState(icon.Key, icon.Current, icon.Max, flag, icon.ColorOverride, icon.Text, icon.Dimmed)); } _presenter.Present(new StatusIconProjection(snapshot.Revision, list)); } public void Dispose() { if (Current == this) { Current = null; } _ledger.Changed -= OnChanged; _presenter.Hide(); } } public sealed class CompositeStatusIconPresenter : IStatusIconPresenter { private readonly IStatusIconPresenter _always; private readonly Func _dynamic; public CompositeStatusIconPresenter(IStatusIconPresenter always, Func dynamic) { _always = always ?? throw new ArgumentNullException("always"); _dynamic = dynamic ?? throw new ArgumentNullException("dynamic"); } public void Present(StatusIconProjection projection) { _always.Present(projection); _dynamic()?.Present(projection); } public void Hide() { _always.Hide(); _dynamic()?.Hide(); } } public sealed record UiProjection(string CrestId, int EnhancementStacks, double RemainingSeconds, double NormalAttackDamage, bool Rage, bool SuperRage, bool SpecialMode, int CharmLevelOffset, int SilkShieldRemaining, double RageRemainingSeconds, long Revision); public interface IUiPresenter { void Present(UiProjection projection); void Hide(); } } namespace CrestsEvolve.GameInterop { public static class ArchitectRuneBridge { public static Func IsToolRepairActive { get; set; } = () => false; public static Func IsToolTransformActive { get; set; } = () => false; } public static class AttackKindMapping { public static AttackKind FromAttackType(AttackTypes attackType) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected I4, but got Unknown //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Invalid comparison between Unknown and I4 switch ((int)attackType) { default: if ((int)attackType != 16) { break; } return AttackKind.Charge; case 0: return AttackKind.Normal; case 1: return AttackKind.Normal; case 2: return AttackKind.Skill; case 10: return AttackKind.Skill; case 6: return AttackKind.Dash; case 7: return AttackKind.Projectile; case 11: return AttackKind.Additional; case 3: case 4: case 5: case 8: case 9: break; } return AttackKind.Additional; } } public static class BeastRuneBridge { public static Func IsEnhancementActive { get; set; } = () => false; public static Func IsDamageProtectActive { get; set; } = () => false; public static Func IsPredatorCharged { get; set; } = () => false; public static Action? AcquireChargeSlashInvulnerability { get; set; } } public sealed class BeastStateAccessor { private readonly ManualLogSource _log; private readonly FieldInfo? _warriorStateField; private bool _warned; public BeastStateAccessor(ManualLogSource log) { _log = log; _warriorStateField = AccessTools.Field(typeof(HeroController), "warriorState"); if (_warriorStateField == null) { _log.LogWarning((object)"[BeastState] warriorState field not found; kill duration extension disabled."); } } public void AddRageTime(float seconds, float max) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) if (_warriorStateField == null || seconds <= 0f) { return; } try { HeroController instance = HeroController.instance; if (!((Object)(object)instance == (Object)null)) { WarriorCrestStateInfo val = (WarriorCrestStateInfo)_warriorStateField.GetValue(instance); if (val.IsInRageMode) { val.RageEffectTimeLeft = Math.Min(max, val.RageEffectTimeLeft + seconds); _warriorStateField.SetValue(instance, val); } } } catch (Exception ex) { WarnOnce(ex); } } public bool IsInRageMode() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) if (_warriorStateField == null) { return false; } HeroController instance = HeroController.instance; if ((Object)(object)instance == (Object)null) { return false; } try { return ((WarriorCrestStateInfo)_warriorStateField.GetValue(instance)).IsInRageMode; } catch (Exception ex) { WarnOnce(ex); return false; } } public void SetRageStateActive(bool active) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) if (!active || _warriorStateField == null) { return; } HeroController instance = HeroController.instance; if ((Object)(object)instance == (Object)null) { return; } try { WarriorCrestStateInfo val = (WarriorCrestStateInfo)_warriorStateField.GetValue(instance); val.IsInRageMode = true; val.RageEffectTimeLeft = Gameplay.WarriorRageDuration; val.RageHealTimeLeft = Gameplay.WarriorRageDuration + Gameplay.WarriorRageGraceTime; _warriorStateField.SetValue(instance, val); } catch (Exception ex) { WarnOnce(ex); } } public void SetRageHealBlocked(bool blocked) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) if (!blocked || _warriorStateField == null) { return; } HeroController instance = HeroController.instance; if ((Object)(object)instance == (Object)null) { return; } try { WarriorCrestStateInfo val = (WarriorCrestStateInfo)_warriorStateField.GetValue(instance); val.RageModeHealCount = instance.GetRageModeHealCap(); _warriorStateField.SetValue(instance, val); } catch (Exception ex) { WarnOnce(ex); } } private void WarnOnce(Exception ex) { if (!_warned) { _warned = true; _log.LogWarning((object)("[BeastState] access failed (" + ex.GetType().Name + ": " + ex.Message + "); suppressing further warnings.")); } } } public static class CloaklessRuneBridge { public static Func IsFreeBindCharged { get; set; } = () => false; public static Func TryConsumeFreeBind { get; set; } = () => false; public static Func IsGlacialAugmentCharged { get; set; } = () => false; public static Func TryConsumeGlacialAugment { get; set; } = () => false; } public static class CursedRuneBridge { private sealed class NullLease : IDisposable { public void Dispose() { } } public static Func IsBindEnabled { get; set; } = () => false; public static Func IsBindInvulnerabilityActive { get; set; } = () => false; public static Func AcquireBindInvulnerability { get; set; } = () => new NullLease(); public static Func BindInvulnerabilitySeconds { get; set; } = () => 2.0; } public sealed class DashStateAccessor { private readonly ManualLogSource _log; private bool _warned; public DashStateAccessor(ManualLogSource log) { _log = log ?? throw new ArgumentNullException("log"); } public bool IsDashSprintActive() { try { HeroController instance = HeroController.instance; if ((Object)(object)instance == (Object)null || instance.cState == null) { return false; } if (instance.cState.isSprinting || instance.cState.dashing) { return IsDashPressed(); } return false; } catch (Exception ex) { if (!_warned) { _warned = true; _log.LogWarning((object)("[DashState] dash sprint query failed: " + ex.Message)); } return false; } } private static bool IsDashPressed() { InputHandler instance = ManagerSingleton.Instance; if ((Object)(object)instance == (Object)null || instance.inputActions == null || instance.inputActions.Dash == null) { return true; } return ((OneAxisInputControl)instance.inputActions.Dash).IsPressed; } } public sealed class FleaBrewApplicator { public const string FleaBrewToolId = "Flea Brew"; private readonly ManualLogSource _log; private readonly BuffState _buff; private bool _warned; public bool IsBrewActive => _buff.IsActive; public double BrewRemainingSeconds => _buff.RemainingSeconds; public FleaBrewApplicator(ManualLogSource log, IClock clock, double durationSeconds = 3.0) { _log = log ?? throw new ArgumentNullException("log"); if (durationSeconds <= 0.0) { throw new ArgumentOutOfRangeException("durationSeconds"); } _buff = new BuffState(BuffKind.Meade, 1, durationSeconds, clock ?? throw new ArgumentNullException("clock")); } public void Apply() { if (!TryApplyVanilla()) { _buff.Add(); WarnOnce("vanilla Flea Brew application path is unconfirmed; fell back to internal buff timer (U)."); } } private bool TryApplyVanilla() { try { ToolItem toolByName = ToolItemManager.GetToolByName("Flea Brew"); if ((Object)(object)toolByName == (Object)null) { return false; } _log.LogInfo((object)("[FleaBrew][probe] tool='" + toolByName.name + "' type='" + ((object)toolByName).GetType().FullName + "' (U; FSM/object path pending probe, no event sent until confirmed).")); return false; } catch (Exception ex) { WarnOnce(ex.Message); return false; } } private void WarnOnce(string message) { if (!_warned) { _warned = true; _log.LogWarning((object)("[FleaBrew] " + message)); } } } public static class FracturedMaskBridge { public static Func? IsEquipped { get; set; } = () => false; public static Func? TryRepair { get; set; } = () => false; } public sealed class GameEventPatches : IDisposable { private readonly ManualLogSource _log; private readonly GameEventHub _events; private readonly DynamicPatchResolver _resolver; private readonly Harmony _harmony; private readonly DamageNegotiationService _negotiation; private readonly IGameApi _game; private readonly List _installed = new List(); private static GameEventPatches? _active; private static readonly FieldInfo LastHitInstanceField = AccessTools.Field(typeof(HealthManager), "lastHitInstance"); private static bool _spellKillWarned; private static readonly (string BindingId, string? Prefix, string? Postfix)[] EventBindings = new(string, string, string)[14] { ("player.attack.resolved", null, "NailHitEnemyPostfix"), ("enemy.damage.resolved", null, "ApplyDamageScalingPostfix"), ("player.damage.before", "TakeDamagePrefix", null), ("player.damage.after", null, "TakeDamagePostfix"), ("player.heal.request", "AddHealthPrefix", null), ("player.heal.resolved", null, "AddHealthPostfix"), ("player.silk.get", "AddSilkPrefix", "AddSilkPostfix"), ("player.silk.spend", "TakeSilkPrefix", "TakeSilkPostfix"), ("player.crest.changed", null, "SendEquippedChangedEventPostfix"), ("enemy.killed", null, "SendDeathEventPostfix"), ("player.bench.rested", null, "SetOnBenchPostfix"), ("player.died", "DiePrefix", null), ("scene.changed", null, "SceneInitPostfix"), ("player.reaper.bind.completed", null, "BindCompletedPostfix") }; private static string? _lastCrestId; private static bool _benchWasOnBench; public GameEventPatches(ManualLogSource log, GameEventHub events, DynamicPatchResolver resolver, Harmony harmony, DamageNegotiationService negotiation, IGameApi game) { _log = log; _events = events; _resolver = resolver; _harmony = harmony; _negotiation = negotiation; _game = game; } public void Install() { _active = this; _benchWasOnBench = false; (string, string, string)[] eventBindings = EventBindings; for (int i = 0; i < eventBindings.Length; i++) { (string, string, string) tuple = eventBindings[i]; if (tuple.Item2 != null && tuple.Item3 != null) { PatchBoth(tuple.Item1, tuple.Item2, tuple.Item3); } else if (tuple.Item2 != null) { PatchPrefix(tuple.Item1, tuple.Item2); } else { PatchPostfix(tuple.Item1, tuple.Item3); } } _log.LogInfo((object)("Game event patches installed: " + string.Join(", ", _installed))); } public void Dispose() { _active = null; _benchWasOnBench = false; _installed.Clear(); } private void PatchPrefix(string bindingId, string patchMethod) { PatchWith(bindingId, delegate(MethodBase method) { _harmony.Patch(method, HarmonyMethod(patchMethod), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); }); } private void PatchPostfix(string bindingId, string patchMethod) { PatchWith(bindingId, delegate(MethodBase method) { _harmony.Patch(method, (HarmonyMethod)null, HarmonyMethod(patchMethod), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); }); } private void PatchBoth(string bindingId, string prefixMethod, string postfixMethod) { PatchWith(bindingId, delegate(MethodBase method) { _harmony.Patch(method, HarmonyMethod(prefixMethod), HarmonyMethod(postfixMethod), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); }); } private void PatchWith(string bindingId, Action apply) { MethodBase methodBase = _resolver.Resolve(bindingId); if ((object)methodBase == null) { _log.LogWarning((object)("Event patch disabled (binding unresolved): " + bindingId)); return; } apply(methodBase); _installed.Add(bindingId); _log.LogInfo((object)("Event patch installed: " + bindingId + " -> " + GeneralExtensions.FullDescription(methodBase))); } private static HarmonyMethod HarmonyMethod(string name) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown return new HarmonyMethod(AccessTools.DeclaredMethod(typeof(GameEventPatches), name, (Type[])null, (Type[])null) ?? throw new MissingMethodException(typeof(GameEventPatches).FullName, name)); } private unsafe static void NailHitEnemyPostfix(HeroController __instance, HealthManager enemyHealth, HitInstance hitInstance) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) _active?._events.Publish(new AttackEvent(((long)Time.frameCount << 16) ^ ((Object)enemyHealth).GetInstanceID(), ((Object)__instance).GetInstanceID(), ((Object)enemyHealth).GetInstanceID(), AttackKindMapping.FromAttackType(hitInstance.AttackType), "attack." + ((object)(*(AttackTypes*)(&hitInstance.AttackType))/*cast due to .constrained prefix*/).ToString(), hitInstance.DamageDealt, (!hitInstance.IsFirstHit) ? 1 : 0, IsAdditionalDamage: false, IsHeroDamage: true, ((Component)enemyHealth).transform.position.x, ((Component)enemyHealth).transform.position.y, ((Component)enemyHealth).transform.position.z)); } private unsafe static void ApplyDamageScalingPostfix(HealthManager __instance, HitInstance hitInstance, HitInstance __result) { //IL_0021: 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_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_006a: 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_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) _active?._events.PublishEnemyDamageResolved(new AttackEvent(((long)Time.frameCount << 16) ^ ((Object)__instance).GetInstanceID(), ((Object)(object)hitInstance.Source != (Object)null) ? ((Object)hitInstance.Source).GetInstanceID() : 0, ((Object)__instance).GetInstanceID(), AttackKindMapping.FromAttackType(hitInstance.AttackType), "enemy.damage." + ((object)(*(AttackTypes*)(&hitInstance.AttackType))/*cast due to .constrained prefix*/).ToString(), __result.DamageDealt, (!__result.IsFirstHit) ? 1 : 0, IsAdditionalDamage: false, hitInstance.IsHeroDamage, ((Component)__instance).transform.position.x, ((Component)__instance).transform.position.y, ((Component)__instance).transform.position.z)); } private unsafe static bool TakeDamagePrefix(ref int damageAmount, HazardType hazardType) { GameEventPatches active = _active; if (active == null || damageAmount <= 0) { return true; } active._events.PublishBefore(new PlayerDamageEvent(damageAmount, "hazard." + ((object)(*(HazardType*)(&hazardType))/*cast due to .constrained prefix*/).ToString())); int num = damageAmount; DamageDecision damageDecision = active._negotiation.Negotiate(num, "hazard." + ((object)(*(HazardType*)(&hazardType))/*cast due to .constrained prefix*/).ToString()); if (damageDecision.SilkToSpend > 0) { active._game.TrySpendSilk(damageDecision.SilkToSpend, damageDecision.Reason ?? "damage-negotiation"); } damageAmount = damageDecision.RemainingMaskDamage; if (damageDecision.Verdict != DamageVerdict.Allow || damageAmount <= 0) { active._log.LogInfo((object)("Damage cancelled by negotiation: " + (damageDecision.Reason ?? "unknown") + " " + $"(incoming={num}, remaining={damageDecision.RemainingMaskDamage}, silk={damageDecision.SilkToSpend})")); return false; } return true; } private unsafe static void TakeDamagePostfix(int damageAmount, HazardType hazardType) { GameEventPatches active = _active; if (active != null && damageAmount > 0) { active._events.PublishAfter(new PlayerDamageEvent(damageAmount, "hazard." + ((object)(*(HazardType*)(&hazardType))/*cast due to .constrained prefix*/).ToString())); } } private static bool AddHealthPrefix(HeroController __instance, int amount, ref int __state) { GameEventPatches active = _active; if (active == null || amount <= 0) { return true; } PlayerData val = __instance?.playerData; int num = val?.health ?? 0; int missingWhiteHealth = Math.Max(0, Math.Max(1, val?.maxHealth ?? 0) - num); __state = num; HealEvent healEvent = new HealEvent(amount, 0, "heal.addhealth", missingWhiteHealth); active._events.PublishRequested(healEvent); if (active._events.InterceptHeal(healEvent)) { active._log.LogInfo((object)$"[Heal] consumed by interceptor (amount={amount})"); return false; } return true; } private static void AddHealthPostfix(HeroController __instance, int amount, ref int __state) { GameEventPatches active = _active; if (active != null && amount > 0) { PlayerData val = __instance?.playerData; int num = __state; int num2 = val?.health ?? num; int applied = Math.Max(0, num2 - num); int missingWhiteHealth = Math.Max(0, Math.Max(1, val?.maxHealth ?? 0) - num); active._events.PublishResolved(new HealEvent(amount, applied, "heal.addhealth", missingWhiteHealth)); } } private static void AddSilkPrefix(HeroController __instance, ref int __state) { __state = __instance.playerData?.silk ?? 0; } private unsafe static void AddSilkPostfix(HeroController __instance, SilkAddSource source, int __state) { GameEventPatches active = _active; int num = __instance.playerData?.silk ?? 0; if (active != null && num != __state) { active._events.Publish(new ResourceEvent(__state, num, num - __state, "silk.add." + ((object)(*(SilkAddSource*)(&source))/*cast due to .constrained prefix*/).ToString())); } } private static void TakeSilkPrefix(HeroController __instance, ref int __state) { __state = __instance.playerData?.silk ?? 0; } private unsafe static void TakeSilkPostfix(HeroController __instance, SilkTakeSource source, int __state) { GameEventPatches active = _active; int num = __instance.playerData?.silk ?? 0; if (active != null && num != __state) { active._events.Publish(new ResourceEvent(__state, num, num - __state, "silk.take." + ((object)(*(SilkTakeSource*)(&source))/*cast due to .constrained prefix*/).ToString())); } } private static void SendEquippedChangedEventPostfix() { GameEventPatches active = _active; if (active == null) { return; } active._events.PublishToolEquipsChanged(); string text = HeroController.instance?.playerData?.CurrentCrestID; if (!string.IsNullOrEmpty(text)) { string lastCrestId = _lastCrestId; _lastCrestId = text; if (lastCrestId == null) { active._events.Publish(new CrestChangedEvent("", text)); } else if (!(lastCrestId == text)) { active._events.Publish(new CrestChangedEvent(lastCrestId, text)); } } } private static void SendDeathEventPostfix(HealthManager __instance) { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Invalid comparison between Unknown and I4 GameEventPatches active = _active; if (active == null) { return; } string enemyName; try { enemyName = (((Object)(object)((Component)__instance).gameObject != (Object)null) ? ((Object)((Component)__instance).gameObject).name : "unknown"); } catch { enemyName = "unknown"; } active._events.Publish(new EnemyKilledEvent(((Object)__instance).GetInstanceID(), enemyName)); if (!(LastHitInstanceField != null)) { return; } try { if (LastHitInstanceField.GetValue(__instance) is HitInstance val && val.IsHeroDamage && (int)val.AttackType == 2) { active._events.PublishSpellKilled(); } } catch (Exception ex) { if (!_spellKillWarned) { _spellKillWarned = true; active._log.LogWarning((object)("[SpellKill] lastHitInstance read failed: " + ex.Message)); } } } private static void SetOnBenchPostfix(bool onBench) { GameEventPatches active = _active; if (active == null) { _benchWasOnBench = onBench; return; } if (onBench && !_benchWasOnBench) { active._events.PublishBenchRested(); } _benchWasOnBench = onBench; } private static void DiePrefix(bool nonLethal) { _active?._events.PublishPlayerDied(); } private static void SceneInitPostfix() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) GameEventPatches active = _active; if (active != null) { GameEventHub events = active._events; Scene activeScene = SceneManager.GetActiveScene(); events.PublishSceneChanged(((Scene)(ref activeScene)).name); } } private static void BindCompletedPostfix() { _active?._events.PublishBindCompleted(); } } public static class HudIconCloneSanitizer { public enum ComponentDisposition { Keep, DisableThenDestroy, DestroyImmediate } public static ComponentDisposition Classify(Type type) { if (type == null) { return ComponentDisposition.DestroyImmediate; } if (typeof(RadialHudIcon).IsAssignableFrom(type)) { return ComponentDisposition.DisableThenDestroy; } if (typeof(Animator).IsAssignableFrom(type)) { return ComponentDisposition.DisableThenDestroy; } if (typeof(UnityMessageListener).IsAssignableFrom(type)) { return ComponentDisposition.DisableThenDestroy; } if (typeof(RadialHudSwitchModeSettings).IsAssignableFrom(type)) { return ComponentDisposition.DisableThenDestroy; } if (typeof(EventRegister).IsAssignableFrom(type)) { return ComponentDisposition.DestroyImmediate; } if (typeof(EventResponder).IsAssignableFrom(type)) { return ComponentDisposition.DestroyImmediate; } return ComponentDisposition.Keep; } public static bool IsArrowName(string? objectName) { if (objectName != null) { return objectName.IndexOf("Arrow", StringComparison.OrdinalIgnoreCase) >= 0; } return false; } public static bool ShouldKeepRenderer(string? objectName, bool isCenterIcon, bool isArrow) { if (!(isCenterIcon || isArrow)) { return IsArrowName(objectName); } return true; } public static bool ShouldKeepGraphic(string? objectName, bool isFill, bool isBg) { return isFill || isBg; } public static int Sanitize(GameObject root, string key, ManualLogSource? log, bool immediate = false) { if ((Object)(object)root == (Object)null) { return 0; } MonoBehaviour[] componentsInChildren = root.GetComponentsInChildren(true); if (componentsInChildren == null || componentsInChildren.Length == 0) { return 0; } Dictionary dictionary = new Dictionary(); int num = 0; foreach (MonoBehaviour item in new List(componentsInChildren)) { if ((Object)(object)item == (Object)null) { continue; } Type type = ((object)item).GetType(); ComponentDisposition componentDisposition = Classify(type); if (componentDisposition == ComponentDisposition.Keep) { continue; } if (componentDisposition == ComponentDisposition.DestroyImmediate) { Object.DestroyImmediate((Object)(object)item); } else { Behaviour val = (Behaviour)(object)item; if (val != null) { val.enabled = false; } if (immediate) { Object.DestroyImmediate((Object)(object)item); } else { Object.Destroy((Object)(object)item); } } dictionary[type] = ((!dictionary.TryGetValue(type, out var value)) ? 1 : (value + 1)); num++; } if (num > 0 && log != null) { foreach (KeyValuePair item2 in dictionary) { log.LogInfo((object)string.Format("[HudIconCloneSanitizer] '{0}' removed {1}x {2}{3}", key, item2.Value, item2.Key.FullName, immediate ? " (immediate)" : "")); } } return num; } } internal static class HudRootInstaller { private static StatusIconHostConfig? _config; private static StatusIconTextureService? _textures; private static ManualLogSource? _log; public static void Configure(StatusIconHostConfig config, StatusIconTextureService textures, ManualLogSource log) { _config = config; _textures = textures; _log = log; } public static void Postfix(BindOrbHudFrame __instance) { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) if (_config == null || _textures == null) { return; } Transform val = ToolRowLocator.Resolve(_config.RowAnchorPath, ((Component)__instance).transform); if ((Object)(object)val != (Object)null) { ((Component)val).gameObject.AddComponent().Configure(_config, ((Component)__instance).transform, _textures, _log, val); ManualLogSource? log = _log; if (log != null) { log.LogInfo((object)("[HudStatusIconHost] attached to row container: " + BuildPath(val))); } return; } GameObject val2 = new GameObject("CrestsEvolveHUDRoot") { layer = 5 }; val2.transform.SetParent(((Component)__instance).transform, false); val2.transform.localScale = Vector3.one; val2.transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity); Vector3 localPosition = val2.transform.localPosition; localPosition.z = -0.0001f; val2.transform.localPosition = localPosition; val2.AddComponent().Configure(_config, ((Component)__instance).transform, _textures, _log, null); ManualLogSource? log2 = _log; if (log2 != null) { log2.LogInfo((object)"[HudStatusIconHost] no row container found; created CrestsEvolveHUDRoot fallback under BindOrbHudFrame."); } } private static string BuildPath(Transform transform) { List list = new List(); Transform val = transform; while ((Object)(object)val != (Object)null) { list.Add(((Object)val).name); val = val.parent; } list.Reverse(); return string.Join("/", list); } } public sealed class StatusIconHostConfig { public string RowAnchorPath { get; set; } = "auto"; public Vector3 FallbackOffset { get; set; } = new Vector3(0f, -2.2f, 0f); public float Spacing { get; set; } = 1.1f; public bool LogHierarchyProbe { get; set; } = true; public static bool TryParseOffset(string text, out Vector3 offset) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) offset = Vector3.zero; if (string.IsNullOrWhiteSpace(text)) { return false; } string[] array = text.Split(','); if (array.Length < 2 || !float.TryParse(array[0], out var result) || !float.TryParse(array[1], out var result2)) { return false; } float result3; float num = ((array.Length > 2 && float.TryParse(array[2], out result3)) ? result3 : 0f); offset = new Vector3(result, result2, num); return true; } } public sealed class HudStatusIconHost : MonoBehaviour, IStatusIconPresenter { private sealed class NativeIconTemplate { public Transform Root; public string IconPath; public string FillPath; public string BgPath; public Color? InactiveColor { get; set; } } private sealed class IconView { private readonly Color _iconTint; private readonly string _key; private readonly StatusIconTextureService? _textures; private readonly Color? _nativeInactiveColor; private Text? _centerLabel; private static Font? _centerFont; public GameObject Root { get; } public SpriteRenderer Icon { get; } public Image RingFill { get; } public Image RingBg { get; } public Color RingColor { get; } public IconView(GameObject root, SpriteRenderer icon, Image ringFill, Image ringBg, Color ringColor, Color iconTint, string key, StatusIconTextureService? textures, Color? nativeInactiveColor = null) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) Root = root; Icon = icon; RingFill = ringFill; RingBg = ringBg; RingColor = ringColor; _iconTint = iconTint; _key = key; _textures = textures; _nativeInactiveColor = nativeInactiveColor; } public void Set(StatusIconState state) { //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) Root.SetActive(state.Visible); if (!state.Visible) { return; } ((Renderer)Icon).enabled = true; if (!((Component)Icon).gameObject.activeSelf) { ((Component)Icon).gameObject.SetActive(true); } if (_textures != null && !string.IsNullOrEmpty(_key)) { Sprite iconSprite = _textures.GetIconSprite(_key); if ((Object)(object)iconSprite != (Object)null) { Icon.sprite = iconSprite; } float iconScale = _textures.GetIconScale(_key); ((Component)Icon).transform.localScale = new Vector3(iconScale, iconScale, 1f); } float num = ((state.Max <= 0) ? 1f : Mathf.Clamp01((float)state.Current / (float)state.Max)); RingFill.fillAmount = num; RingBg.fillAmount = 1f - num; bool flag = state.Dimmed || state.Current <= 0; Icon.color = (Color)((!flag) ? _iconTint : (((??)_nativeInactiveColor) ?? Dim(_iconTint, 0.45f))); Color val2 = default(Color); Color val = ((state.ColorOverride != null && ColorUtility.TryParseHtmlString(state.ColorOverride, ref val2)) ? val2 : RingColor); ((Graphic)RingFill).color = ((!flag) ? val : (_nativeInactiveColor.HasValue ? Multiply(val, _nativeInactiveColor.Value) : Dim(val, 0.45f))); ((Graphic)RingBg).color = Dim(val, 0.3f); if (state.CenterText != null) { Text val3 = EnsureCenterText(); if ((Object)(object)val3 != (Object)null) { val3.text = state.CenterText; } } else if ((Object)(object)_centerLabel != (Object)null) { ((Component)_centerLabel).gameObject.SetActive(false); } } private Text? EnsureCenterText() { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_centerLabel != (Object)null) { ((Component)_centerLabel).gameObject.SetActive(true); return _centerLabel; } Font centerFont = GetCenterFont(); if ((Object)(object)centerFont == (Object)null) { return null; } GameObject val = new GameObject("CenterText", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Text) }) { layer = Root.layer }; val.transform.SetParent(Root.transform, false); RectTransform component = val.GetComponent(); component.anchorMin = new Vector2(0.5f, 0.5f); component.anchorMax = new Vector2(0.5f, 0.5f); component.pivot = new Vector2(0.5f, 0.5f); component.sizeDelta = new Vector2(1.8f, 1f); ((Transform)component).localPosition = Vector3.zero; Text component2 = val.GetComponent(); component2.font = centerFont; component2.fontSize = 42; component2.alignment = (TextAnchor)4; ((Graphic)component2).color = Color.white; ((Graphic)component2).raycastTarget = false; component2.horizontalOverflow = (HorizontalWrapMode)1; component2.verticalOverflow = (VerticalWrapMode)1; _centerLabel = component2; return component2; } private static Font? GetCenterFont() { if ((Object)(object)_centerFont != (Object)null) { return _centerFont; } try { _centerFont = Resources.GetBuiltinResource("LegacyRuntime.ttf"); } catch (Exception ex) { Debug.LogWarning((object)("[HudStatusIconHost] LegacyRuntime.ttf unavailable: " + ex.Message)); } if ((Object)(object)_centerFont == (Object)null) { try { _centerFont = Resources.GetBuiltinResource("Arial.ttf"); } catch (Exception ex2) { Debug.LogWarning((object)("[HudStatusIconHost] Arial.ttf unavailable; center text disabled. " + ex2.Message)); } } return _centerFont; } } private StatusIconHostConfig _config = new StatusIconHostConfig(); private Transform? _hudFrame; private Transform? _rowAnchor; private TransformLayoutGrid? _grid; private bool _gridManaged; private StatusIconTextureService? _textures; private ManualLogSource? _log; private readonly Dictionary _icons = new Dictionary(StringComparer.Ordinal); private HashSet _visibleKeys = new HashSet(StringComparer.Ordinal); private long _lastRevision = -1L; private Sprite? _nativeRingSprite; private readonly Dictionary _nativeTemplates = new Dictionary(StringComparer.Ordinal); private NativeIconTemplate? _defaultTemplate; private bool _rowProbeLogged; private bool _toolsAppeared; private static readonly HashSet _nativeCloneHierarchyLogged = new HashSet(StringComparer.Ordinal); public static HudStatusIconHost? Instance { get; private set; } private void Awake() { Instance = this; ((EventBase)EventRegister.GetRegisterGuaranteed(((Component)this).gameObject, "TOOL EQUIPS CHANGED")).ReceivedEvent += RebuildLayout; ((EventBase)EventRegister.GetRegisterGuaranteed(((Component)this).gameObject, "POST TOOL EQUIPS CHANGED")).ReceivedEvent += RebuildLayout; ((EventBase)EventRegister.GetRegisterGuaranteed(((Component)this).gameObject, "TOOLS APPEAR")).ReceivedEvent += OnToolsAppear; } private void OnDestroy() { if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } public void Configure(StatusIconHostConfig config, Transform hudFrame, StatusIconTextureService textures, ManualLogSource log, Transform? rowAnchor) { //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Expected O, but got Unknown _config = config ?? new StatusIconHostConfig(); _hudFrame = hudFrame; _textures = textures; _log = log; if (_config.LogHierarchyProbe) { LogHierarchy(hudFrame, 0, 3); LogSiblingOverview(hudFrame.parent, "Bind Orb parent"); Transform parent = hudFrame.parent; LogSiblingOverview((parent != null) ? parent.parent : null, "Bind Orb grandparent"); } if ((Object)(object)rowAnchor != (Object)null) { AttachToRow(rowAnchor); LogRowStructure("hud-created"); foreach (Transform item in rowAnchor) { Transform val = item; if ((Object)(object)((Component)val).GetComponent() != (Object)null && ((Component)val).gameObject.activeInHierarchy) { _toolsAppeared = true; break; } } } else { ((Component)this).transform.localPosition = _config.FallbackOffset; ManualLogSource? log2 = _log; if (log2 != null) { log2.LogInfo((object)"[HudStatusIconHost][probe] no vanilla tool row detected; using fallback offset."); } } StatusIconProjector.Current?.Refresh(); } public void Present(StatusIconProjection projection) { if (projection.Revision == _lastRevision || !_toolsAppeared) { return; } _lastRevision = projection.Revision; List list = projection.Icons.Where((StatusIconState state) => _textures == null || _textures.IsIconEnabled(state.Key)).ToList(); HashSet hashSet = new HashSet(list.Select((StatusIconState i) => i.Key), StringComparer.Ordinal); foreach (string item in _icons.Keys.ToList()) { if (!hashSet.Contains(item)) { Object.Destroy((Object)(object)_icons[item].Root); _icons.Remove(item); } } HashSet hashSet2 = new HashSet(StringComparer.Ordinal); foreach (StatusIconState item2 in list) { IconView value2; if (item2.Visible) { hashSet2.Add(item2.Key); EnsureIcon(item2.Key); if (_icons.TryGetValue(item2.Key, out IconView value)) { value.Set(item2); } } else if (_icons.TryGetValue(item2.Key, out value2)) { Object.Destroy((Object)(object)value2.Root); _icons.Remove(item2.Key); } } if (!_visibleKeys.SetEquals(hashSet2)) { _visibleKeys = hashSet2; RebuildLayout(); } } public void Hide() { foreach (IconView value in _icons.Values) { Object.Destroy((Object)(object)value.Root); } _icons.Clear(); _visibleKeys.Clear(); _lastRevision = -1L; } private void OnToolsAppear() { _toolsAppeared = true; if (_nativeTemplates.Count == 0 && (Object)(object)_rowAnchor != (Object)null) { CaptureNativeRing(_rowAnchor); } StatusIconProjector.Current?.Refresh(); RebuildLayout(); } private void EnsureIcon(string key) { //IL_004e: 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_005b: Expected O, but got Unknown //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) if (!_icons.ContainsKey(key) && _textures != null && !TryCreateNativeIcon(key)) { int layer = (((Object)(object)_hudFrame != (Object)null) ? ((Component)_hudFrame).gameObject.layer : 5); GameObject val = new GameObject("CE_Icon_" + key) { layer = layer }; val.transform.SetParent(((Component)this).transform, false); val.transform.localScale = Vector3.one; GameObject val2 = new GameObject("Icon") { layer = layer }; val2.transform.SetParent(val.transform, false); SpriteRenderer val3 = val2.AddComponent(); val3.sprite = _textures.GetIconSprite(key); ((Renderer)val3).sortingOrder = 10; float iconScale = _textures.GetIconScale(key); val2.transform.localScale = new Vector3(iconScale, iconScale, 1f); Image ringBg = CreateRingImage(val.transform, layer); Image ringFill = CreateRingImage(val.transform, layer); _icons[key] = new IconView(val, val3, ringFill, ringBg, _textures.GetRingColor(key), _textures.GetIconTint(key), key, _textures); } } private bool TryCreateNativeIcon(string key) { //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) NativeIconTemplate nativeIconTemplate = ResolveTemplate(key); if (nativeIconTemplate == null) { return false; } GameObject val = Object.Instantiate(((Component)nativeIconTemplate.Root).gameObject, ((Component)this).transform); ((Object)val).name = "CE_Icon_" + key; val.SetActive(true); HudIconCloneSanitizer.Sanitize(val, key, _log, immediate: true); Transform obj = val.transform.Find(nativeIconTemplate.IconPath); SpriteRenderer val2 = ((obj != null) ? ((Component)obj).GetComponent() : null); Transform obj2 = val.transform.Find(nativeIconTemplate.FillPath); Image val3 = ((obj2 != null) ? ((Component)obj2).GetComponent() : null); Transform obj3 = val.transform.Find(nativeIconTemplate.BgPath); Image val4 = ((obj3 != null) ? ((Component)obj3).GetComponent() : null); if ((Object)(object)val3 == (Object)null || (Object)(object)val4 == (Object)null) { Object.Destroy((Object)(object)val); ManualLogSource? log = _log; if (log != null) { log.LogWarning((object)("[HudStatusIconHost] native icon clone failed for '" + key + "'; falling back to custom build.")); } return false; } if ((Object)(object)val2 == (Object)null) { GameObject val5 = new GameObject("CE Center Icon") { layer = val.layer }; val5.transform.SetParent(val.transform, false); val2 = val5.AddComponent(); ((Renderer)val2).sortingOrder = 10; } SanitizeNativeCloneContent(val, val2, val3, val4); LogNativeCloneHierarchy(key, val, val2); ((Component)val2).gameObject.SetActive(true); ((Renderer)val2).enabled = true; val2.sprite = _textures.GetIconSprite(key); float iconScale = _textures.GetIconScale(key); ((Component)val2).transform.localScale = new Vector3(iconScale, iconScale, 1f); _icons[key] = new IconView(val, val2, val3, val4, _textures.GetRingColor(key), _textures.GetIconTint(key), key, _textures, nativeIconTemplate.InactiveColor); ManualLogSource? log2 = _log; if (log2 != null) { log2.LogInfo((object)("[HudStatusIconHost][probe] native icon cloned for '" + key + "' from " + BuildPath(nativeIconTemplate.Root))); } return true; } private static void SanitizeNativeCloneContent(GameObject cloneGo, SpriteRenderer icon, Image fill, Image bg) { Renderer[] componentsInChildren = cloneGo.GetComponentsInChildren(true); foreach (Renderer val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)icon)) { SpriteRenderer val2 = (SpriteRenderer)(object)((val is SpriteRenderer) ? val : null); if (val2 == null || !HudIconCloneSanitizer.ShouldKeepRenderer(((Object)val2).name, isCenterIcon: false, isArrow: false)) { val.enabled = false; } } } Graphic[] componentsInChildren2 = cloneGo.GetComponentsInChildren(true); foreach (Graphic val3 in componentsInChildren2) { if (!((Object)(object)val3 == (Object)null) && !((Object)(object)val3 == (Object)(object)fill) && !((Object)(object)val3 == (Object)(object)bg)) { ((Behaviour)val3).enabled = false; } } } private void LogNativeCloneHierarchy(string key, GameObject cloneGo, SpriteRenderer icon) { if (_log != null && _nativeCloneHierarchyLogged.Add(key)) { _log.LogInfo((object)("[HudStatusIconHost][probe] native clone hierarchy '" + key + "' (center=" + ((Object)((Component)icon).transform).name + "):")); LogCloneNode(cloneGo.transform, 1); } } private void LogCloneNode(Transform node, int depth) { //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Expected O, but got Unknown if ((Object)(object)node == (Object)null) { return; } List list = new List(); Component[] components = ((Component)node).GetComponents(); foreach (Component val in components) { if ((Object)(object)val == (Object)null) { continue; } SpriteRenderer val2 = (SpriteRenderer)(object)((val is SpriteRenderer) ? val : null); if (val2 == null) { Image val3 = (Image)(object)((val is Image) ? val : null); if (val3 == null) { RawImage val4 = (RawImage)(object)((val is RawImage) ? val : null); if (val4 == null) { Text val5 = (Text)(object)((val is Text) ? val : null); if (val5 == null) { MeshRenderer val6 = (MeshRenderer)(object)((val is MeshRenderer) ? val : null); if (val6 != null) { list.Add($"MeshRenderer(enabled={((Renderer)val6).enabled})"); } else { list.Add(((object)val).GetType().Name); } } else { list.Add($"Text(enabled={((Behaviour)val5).enabled})"); } } else { object arg = ((Behaviour)val4).enabled; Texture texture = val4.texture; list.Add(string.Format("RawImage(enabled={0},tex={1})", arg, ((texture != null) ? ((Object)texture).name : null) ?? "null")); } } else { object arg2 = ((Behaviour)val3).enabled; Sprite sprite = val3.sprite; list.Add(string.Format("Image(enabled={0},sprite={1})", arg2, ((sprite != null) ? ((Object)sprite).name : null) ?? "null")); } } else { object arg3 = ((Renderer)val2).enabled; Sprite sprite2 = val2.sprite; list.Add(string.Format("SpriteRenderer(enabled={0},sprite={1})", arg3, ((sprite2 != null) ? ((Object)sprite2).name : null) ?? "null")); } } ManualLogSource? log = _log; if (log != null) { log.LogInfo((object)("[HudStatusIconHost][probe] " + new string(' ', (depth - 1) * 2) + ((Object)node).name + " " + string.Format("active={0} [{1}]", ((Component)node).gameObject.activeSelf, string.Join(",", list)))); } foreach (Transform item in node) { Transform node2 = item; LogCloneNode(node2, depth + 1); } } private Image CreateRingImage(Transform parent, int layer) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Ring", new Type[2] { typeof(RectTransform), typeof(Image) }) { layer = layer }; val.transform.SetParent(parent, false); val.GetComponent().sizeDelta = new Vector2(1f, 1f); Image component = val.GetComponent(); component.sprite = _nativeRingSprite ?? _textures.RingSprite; component.type = (Type)3; component.fillMethod = (FillMethod)4; component.fillOrigin = 2; ((Graphic)component).raycastTarget = false; return component; } private void RebuildLayout() { //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) if (_icons.Count == 0) { return; } if (_gridManaged) { TransformLayoutGrid? grid = _grid; if (grid != null) { ((TransformLayout)grid).UpdatePositions(); } LogRowStructureCompact(null); return; } List list = new List(); float? referenceY = null; if ((Object)(object)_rowAnchor != (Object)null) { foreach (Transform item in _rowAnchor) { Transform val = item; if (!((Object)(object)val == (Object)(object)((Component)this).transform) && !val.IsChildOf(((Component)this).transform) && ((Component)val).gameObject.activeInHierarchy && (!((Object)(object)((Component)val).GetComponent() == (Object)null) || !((Object)(object)((Component)val).GetComponent() == (Object)null) || !((Object)(object)((Component)val).GetComponent() == (Object)null))) { list.Add(val.localPosition.x); if (!referenceY.HasValue && (Object)(object)((Component)val).GetComponent() != (Object)null) { referenceY = val.localPosition.y; } } } } ToolRowLayout toolRowLayout = ToolRowLayoutCalculator.Calculate(list, referenceY, _config.Spacing, _config.FallbackOffset.x); int num = 0; foreach (IconView value in _icons.Values) { value.Root.transform.localPosition = new Vector3(toolRowLayout.StartX + (float)num * toolRowLayout.Spacing, toolRowLayout.RowY, 0f); num++; } LogRowStructureCompact(toolRowLayout); } private void AttachToRow(Transform anchor) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) _rowAnchor = anchor; _grid = ((Component)anchor).GetComponent(); _gridManaged = (Object)(object)_grid != (Object)null; if ((Object)(object)anchor != (Object)(object)((Component)this).transform) { ((Component)this).transform.SetParent(anchor, false); ((Component)this).transform.localPosition = Vector3.zero; } ManualLogSource? log = _log; if (log != null) { log.LogInfo((object)$"[HudStatusIconHost][probe] row anchor: {BuildPath(anchor)} gridManaged={_gridManaged}"); } CaptureNativeRing(anchor); } private void CaptureNativeRing(Transform anchor) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)anchor == (Object)null) { return; } foreach (Transform item in anchor) { Transform val = item; ToolHudIcon component = ((Component)val).GetComponent(); if ((Object)(object)component == (Object)null) { continue; } string text = ResolveTemplateKey(val, component); if (text == null || _nativeTemplates.ContainsKey(text)) { continue; } FieldInfo fieldInfo = AccessTools.Field(typeof(RadialHudIcon), "icon"); FieldInfo fieldInfo2 = AccessTools.Field(typeof(RadialHudIcon), "radialImage"); FieldInfo fieldInfo3 = AccessTools.Field(typeof(RadialHudIcon), "radialImageBg"); FieldInfo fieldInfo4 = AccessTools.Field(typeof(RadialHudIcon), "inactiveColor"); object? obj = fieldInfo?.GetValue(component); SpriteRenderer val2 = (SpriteRenderer)((obj is SpriteRenderer) ? obj : null); if (val2 == null) { continue; } object? obj2 = fieldInfo2?.GetValue(component); Image val3 = (Image)((obj2 is Image) ? obj2 : null); if (val3 == null) { continue; } object? obj3 = fieldInfo3?.GetValue(component); Image val4 = (Image)((obj3 is Image) ? obj3 : null); if (val4 != null) { Color? inactiveColor = ((fieldInfo4?.GetValue(component) is Color value) ? new Color?(value) : ((Color?)null)); if ((Object)(object)_nativeRingSprite == (Object)null && (Object)(object)val3.sprite != (Object)null) { _nativeRingSprite = val3.sprite; } GameObject val5 = Object.Instantiate(((Component)val).gameObject, ((Component)this).transform); ((Object)val5).name = "CE_OwnedTemplate_" + text; val5.SetActive(false); HudIconCloneSanitizer.Sanitize(val5, "