using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("RacesOfValheimAzuEPICompat")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1")] [assembly: AssemblyProduct("RacesOfValheimAzuEPICompat")] [assembly: AssemblyTitle("RacesOfValheimAzuEPICompat")] [assembly: AssemblyVersion("1.0.1.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace RacesOfValheimAzuEPICompat { [BepInPlugin("danii.RacesOfValheimAzuEPICompat", "Races of Valheim - AzuEPI Compatibility", "1.0.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { public const string PluginGuid = "danii.RacesOfValheimAzuEPICompat"; public const string PluginName = "Races of Valheim - AzuEPI Compatibility"; public const string PluginVersion = "1.0.1"; private const float ProgressionCheckInterval = 0.25f; internal static Plugin Instance; internal static ManualLogSource Log; private Harmony _harmony; private float _nextProgressionCheck; private string _displayedRace; private int _displayedProgression = -1; private static Type _panelType; private static FieldInfo _playerPreviewField; private static FieldInfo _playerPreviewCompField; private static FieldInfo _panelInstanceField; private static FieldInfo _cameraField; private static MethodInfo _progressionMethod; private static MethodInfo _updateColorsMethod; private static MethodInfo _updateVisualsMethod; private void Awake() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; CacheReflection(); _harmony = new Harmony("danii.RacesOfValheimAzuEPICompat"); _harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Races of Valheim - AzuEPI Compatibility 1.0.1 loaded"); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private void Update() { if (Time.unscaledTime < _nextProgressionCheck) { return; } _nextProgressionCheck = Time.unscaledTime + 0.25f; if (IsPreviewVisible()) { string localRace = GetLocalRace(); int currentProgression = GetCurrentProgression(); if ((!(localRace == _displayedRace) || currentProgression != _displayedProgression) && ApplyRaceToPreview()) { _displayedRace = localRace; _displayedProgression = currentProgression; } } } internal void RefreshOnOpen() { ((MonoBehaviour)this).StopCoroutine("RefreshAfterOpen"); ((MonoBehaviour)this).StartCoroutine("RefreshAfterOpen"); } private IEnumerator RefreshAfterOpen() { RefreshAndRememberState(); yield return null; RefreshAndRememberState(); } private void RefreshAndRememberState() { if (ApplyRaceToPreview()) { _displayedRace = GetLocalRace(); _displayedProgression = GetCurrentProgression(); } } internal static bool ApplyRaceToPreview() { //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) try { if (!IsPreviewVisible()) { return false; } Player localPlayer = Player.m_localPlayer; Player previewPlayer = GetPreviewPlayer(); if ((Object)(object)localPlayer == (Object)null || (Object)(object)previewPlayer == (Object)null || (Object)(object)localPlayer == (Object)(object)previewPlayer) { return false; } previewPlayer.m_customData.Clear(); foreach (KeyValuePair customDatum in localPlayer.m_customData) { previewPlayer.m_customData[customDatum.Key] = customDatum.Value; } ((Component)previewPlayer).transform.localScale = ((Component)localPlayer).transform.localScale; Transform val = ((Component)localPlayer).transform.Find("Visual"); Transform val2 = ((Component)previewPlayer).transform.Find("Visual"); if ((Object)(object)val != (Object)null && (Object)(object)val2 != (Object)null) { val2.localScale = val.localScale; } VisEquipment component = ((Component)previewPlayer).GetComponent(); if ((Object)(object)component == (Object)null) { return false; } component.m_isPlayer = true; _updateColorsMethod?.Invoke(component, null); _updateVisualsMethod?.Invoke(component, null); ApplyPeriodicRaceVisuals(previewPlayer); SetLayerRecursively(((Component)previewPlayer).gameObject, LayerMask.NameToLayer("UI")); Camera previewCamera = GetPreviewCamera(); if (previewCamera != null) { previewCamera.Render(); } return true; } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogError((object)("Failed to apply race to AzuEPI preview: " + ex)); } return false; } } private static string GetLocalRace() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null && localPlayer.m_customData != null && localPlayer.m_customData.TryGetValue("Race", out var value)) { return value; } return "Human"; } private static int GetCurrentProgression() { if (!(_progressionMethod == null)) { return (int)_progressionMethod.Invoke(null, null); } return -1; } private static bool IsPreviewVisible() { object? obj = _playerPreviewField?.GetValue(null); GameObject val = (GameObject)((obj is GameObject) ? obj : null); Camera previewCamera = GetPreviewCamera(); if ((Object)(object)val != (Object)null && val.activeInHierarchy && (Object)(object)previewCamera != (Object)null) { return ((Behaviour)previewCamera).enabled; } return false; } private static Camera GetPreviewCamera() { object obj = _panelInstanceField?.GetValue(null); if (obj != null) { object? obj2 = _cameraField?.GetValue(obj); return (Camera)((obj2 is Camera) ? obj2 : null); } return null; } private static Player GetPreviewPlayer() { object? obj = _playerPreviewCompField?.GetValue(null); return (Player)((obj is Player) ? obj : null); } private static void CacheReflection() { _panelType = AccessTools.TypeByName("AzuEPI.Game.PlayerPreview.AzuEPICharacterPanel"); _playerPreviewField = AccessTools.Field(_panelType, "playerPreview"); _playerPreviewCompField = AccessTools.Field(_panelType, "playerPreviewComp"); _panelInstanceField = AccessTools.Field(_panelType, "instance"); _cameraField = AccessTools.Field(_panelType, "cam"); _progressionMethod = AccessTools.Method(AccessTools.TypeByName("RacesOfValheim.BossProgressionManager"), "GetCurrentProgressionState", (Type[])null, (Type[])null); _updateColorsMethod = AccessTools.Method(typeof(VisEquipment), "UpdateColors", (Type[])null, (Type[])null); _updateVisualsMethod = AccessTools.Method(typeof(VisEquipment), "UpdateVisuals", (Type[])null, (Type[])null); } private static void ApplyPeriodicRaceVisuals(Player preview) { if (!preview.m_customData.TryGetValue("Race", out var value)) { value = "Human"; } switch (value) { case "Dvergar": InvokeRaceVisual("RacesOfValheim.DvergarVisuals", "ApplyScale", preview, true); InvokeRaceVisual("RacesOfValheim.DvergarVisuals", "ApplyEyes", preview); InvokeRaceVisual("RacesOfValheim.DvergarVisuals", "ApplyHood", preview); break; case "Sverm": InvokeRaceVisual("RacesOfValheim.SvermVisuals", "ApplyScale", preview, true); InvokeRaceVisual("RacesOfValheim.SvermVisuals", "ApplyEyes", preview); InvokeRaceVisual("RacesOfValheim.SvermVisuals", "ApplyClaws", preview); InvokeRaceVisual("RacesOfValheim.SvermVisuals", "ApplySpines", preview); InvokeRaceVisual("RacesOfValheim.SvermVisuals", "ApplyCarapace", preview); break; case "Trenta": InvokeRaceVisual("RacesOfValheim.TrentaVisuals", "ApplyCrown", preview); break; } } private static void InvokeRaceVisual(string typeName, string methodName, params object[] arguments) { AccessTools.Method(AccessTools.TypeByName(typeName), methodName, (Type[])null, (Type[])null)?.Invoke(null, arguments); } private static void SetLayerRecursively(GameObject root, int layer) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)root == (Object)null) { return; } root.layer = layer; foreach (Transform item in root.transform) { SetLayerRecursively(((Component)item).gameObject, layer); } } } [HarmonyPatch] internal static class AzuEPIShowPreviewPatch { private static MethodBase TargetMethod() { return AccessTools.Method(AccessTools.TypeByName("AzuEPI.Game.PlayerPreview.PlayerPreviewManager"), "ShowPlayerPreview", (Type[])null, (Type[])null); } private static void Postfix() { Plugin.Instance?.RefreshOnOpen(); } } }