Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of SkillsReworked v1.8.2
SkillsReworked.dll
Decompiled 19 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using Groups; using HarmonyLib; using JetBrains.Annotations; using Jotunn; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Extensions; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using SkillsReworked.Api; using SkillsReworked.Bootstrap; using SkillsReworked.Commands; using SkillsReworked.Infrastructure.Networking; using SkillsReworked.Integration.Groups; using SkillsReworked.Integration.Party; using SkillsReworked.Integration.SkillManager; using SkillsReworked.Integration.SocialSystem; using SkillsReworked.Persistence; using SkillsReworked.Systems.Common; using SkillsReworked.Systems.Costs; using SkillsReworked.Systems.Prestige; using SkillsReworked.Systems.Progression; using SkillsReworked.Systems.Rebirth; using SkillsReworked.Systems.Reset; using SkillsReworked.Systems.Rewards; using SkillsReworked.UI.Dialogs; using SkillsReworked.UI.LevelHud; using SkillsReworked.UI.SkillPanel; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: IgnoresAccessChecksTo("assembly_guiutils")] [assembly: IgnoresAccessChecksTo("assembly_utils")] [assembly: IgnoresAccessChecksTo("assembly_valheim")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("SkillsReworked")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+1bc49e5795a1c1b6d926f4996658c5029ad19805")] [assembly: AssemblyProduct("SkillsReworked")] [assembly: AssemblyTitle("SkillsReworked")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [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 SkillsReworked.UI.SkillPanel { public class BlinkingTextEffect : MonoBehaviour { public Text Target; public Color ColorA = Color.white; public Color ColorB = Color.white; public float Speed = 2f; private void Update() { //IL_0038: 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_0044: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)Target == (Object)null)) { float num = (Mathf.Sin(Time.unscaledTime * Speed) + 1f) * 0.5f; ((Graphic)Target).color = Color.Lerp(ColorA, ColorB, num); } } public static Color Darken(Color c, float factor) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) return new Color(c.r * factor, c.g * factor, c.b * factor, c.a); } public static void SetActive(Text target, bool active, Color colorA, Color colorB, Color restColor, float speed = 5f) { //IL_0066: 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_006d: 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_0034: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)target == (Object)null) { return; } if (!active) { BlinkingTextEffect component = ((Component)target).GetComponent<BlinkingTextEffect>(); if ((Object)(object)component != (Object)null) { ((Behaviour)component).enabled = false; } ((Graphic)target).color = restColor; return; } BlinkingTextEffect blinkingTextEffect = ((Component)target).GetComponent<BlinkingTextEffect>(); if ((Object)(object)blinkingTextEffect == (Object)null) { blinkingTextEffect = ((Component)target).gameObject.AddComponent<BlinkingTextEffect>(); } blinkingTextEffect.Target = target; blinkingTextEffect.ColorA = colorA; blinkingTextEffect.ColorB = colorB; blinkingTextEffect.Speed = speed; ((Behaviour)blinkingTextEffect).enabled = true; } } public class SkillRowController : MonoBehaviour { public static readonly List<SkillRowController> ActiveControllers = new List<SkillRowController>(); public SkillType SkillType; public Text CounterText; public InputField CounterInput; internal GameObject PlusButtonObj; internal GameObject MinusButtonObj; internal GameObject CounterTextObj; private void Awake() { ActiveControllers.Add(this); } private void OnDestroy() { ActiveControllers.Remove(this); } public void RefreshCounter() { //IL_008b: 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_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)CounterText == (Object)null) { return; } bool flag = IsSkillMaxed(); if ((Object)(object)PlusButtonObj != (Object)null) { PlusButtonObj.SetActive(!flag); } if ((Object)(object)MinusButtonObj != (Object)null) { MinusButtonObj.SetActive(!flag); } if ((Object)(object)CounterTextObj != (Object)null) { CounterTextObj.SetActive(!flag); } if (!flag) { int allocated = SkillUiController.GetAllocated(SkillType); if ((Object)(object)CounterInput != (Object)null) { CounterInput.text = allocated.ToString(); } else { CounterText.text = allocated.ToString(); } BlinkingTextEffect.SetActive(CounterText, allocated > 0, BlinkingTextEffect.Darken(SkillUiController.PlannedColor, 0.55f), SkillUiController.PlannedColor, Color.white); } } private bool IsSkillMaxed() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) Player val = SkillUiController.CurrentPlayer ?? Player.m_localPlayer; if ((Object)(object)val == (Object)null) { return false; } Skills skills = ((Character)val).GetSkills(); Skill val2 = ((skills != null) ? skills.GetSkill(SkillType) : null); if (val2 == null) { return false; } float currentSkillCap = SkillCapPolicy.GetCurrentSkillCap(val); return val2.m_level >= currentSkillCap; } public static void DestroyAll() { List<SkillRowController> list = new List<SkillRowController>(ActiveControllers); ActiveControllers.Clear(); foreach (SkillRowController item in list) { if (!((Object)(object)item == (Object)null)) { if ((Object)(object)item.PlusButtonObj != (Object)null) { Object.Destroy((Object)(object)item.PlusButtonObj); } if ((Object)(object)item.MinusButtonObj != (Object)null) { Object.Destroy((Object)(object)item.MinusButtonObj); } if ((Object)(object)item.CounterTextObj != (Object)null) { Object.Destroy((Object)(object)item.CounterTextObj); } Object.Destroy((Object)(object)item); } } } } public static class SkillRowDecorator { public static void AddButtons(RectTransform row, SkillType skillType) { //IL_00c1: 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_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0120: 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_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Expected O, but got Unknown //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Expected O, but got Unknown //IL_0039: 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_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0070: 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_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) if ((Object)(object)row == (Object)null) { return; } Transform val = Utils.FindChild((Transform)(object)row, "name", (IterativeSearchType)0); RectTransform val2 = (RectTransform)(object)((val is RectTransform) ? val : null); if (val2 != null) { Rect rect = val2.rect; float width = ((Rect)(ref rect)).width; float num = Mathf.Min(width, 100f); if (num < width) { float num2 = val2.anchoredPosition.x - val2.pivot.x * width; val2.SetSizeWithCurrentAnchors((Axis)0, num); val2.anchoredPosition = new Vector2(num2 + val2.pivot.x * num, val2.anchoredPosition.y); } } SkillRowController skillRowController = ((Component)row).gameObject.AddComponent<SkillRowController>(); skillRowController.SkillType = skillType; Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(0.5f, 0.5f); GameObject val4 = GUIManager.Instance.CreateButton("+", (Transform)(object)row, val3, val3, new Vector2(-10f, 0f), 24f, 24f); GameObject val5 = GUIManager.Instance.CreateButton("-", (Transform)(object)row, val3, val3, new Vector2(-35f, 0f), 24f, 24f); GameObject val6 = CreateCounterInputField(row, val3); skillRowController.CounterInput = val6.GetComponent<InputField>(); skillRowController.CounterText = skillRowController.CounterInput.textComponent; skillRowController.PlusButtonObj = val4; skillRowController.MinusButtonObj = val5; skillRowController.CounterTextObj = val6; skillRowController.RefreshCounter(); SkillRowController ctrl = skillRowController; ((UnityEvent)val4.GetComponent<Button>().onClick).AddListener((UnityAction)delegate { //IL_0047: 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_0069: Unknown result type (might be due to invalid IL or missing references) Player val7 = SkillUiController.CurrentPlayer ?? Player.m_localPlayer; if (!((Object)(object)val7 == (Object)null) && SkillUiController.GetCurrentUnspent() > 0) { Skills skills = ((Character)val7).GetSkills(); Skill val8 = ((skills != null) ? skills.GetSkill(ctrl.SkillType) : null); if (val8 != null) { float num3 = val8.m_level + (float)SkillUiController.GetAllocated(ctrl.SkillType) + 1f; if (num3 > SkillCapPolicy.GetCurrentSkillCap(val7)) { return; } } SkillUiController.ChangeAllocated(ctrl.SkillType, 1); ctrl.RefreshCounter(); SkillUiController.RefreshPointsBadge(); } }); ((UnityEvent)val5.GetComponent<Button>().onClick).AddListener((UnityAction)delegate { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) if (SkillUiController.GetAllocated(ctrl.SkillType) > 0) { SkillUiController.ChangeAllocated(ctrl.SkillType, -1); ctrl.RefreshCounter(); SkillUiController.RefreshPointsBadge(); } }); bool suppressCounterInputEvent = false; ((UnityEvent<string>)(object)skillRowController.CounterInput.onValueChanged).AddListener((UnityAction<string>)delegate(string value) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) if (!suppressCounterInputEvent) { int.TryParse(value, out var result); int maxAllocatable = SkillUiController.GetMaxAllocatable(ctrl.SkillType); int num3 = Mathf.Clamp(result, 0, maxAllocatable); suppressCounterInputEvent = true; try { SkillUiController.SetAllocated(ctrl.SkillType, num3); ctrl.RefreshCounter(); if (num3 != result) { ctrl.CounterInput.caretPosition = ctrl.CounterInput.text.Length; } } finally { suppressCounterInputEvent = false; } SkillUiController.RefreshPointsBadge(); } }); ((UnityEvent<string>)(object)skillRowController.CounterInput.onEndEdit).AddListener((UnityAction<string>)delegate(string value) { //IL_0010: 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) int.TryParse(value, out var result); int maxAllocatable = SkillUiController.GetMaxAllocatable(ctrl.SkillType); int value2 = Mathf.Clamp(result, 0, maxAllocatable); SkillUiController.SetAllocated(ctrl.SkillType, value2); ctrl.RefreshCounter(); SkillUiController.RefreshPointsBadge(); }); } private static GameObject CreateCounterInputField(RectTransform row, Vector2 center) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005c: 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) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Expected O, but got Unknown //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Expected O, but got Unknown //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Counter", new Type[3] { typeof(RectTransform), typeof(Image), typeof(InputField) }); val.transform.SetParent((Transform)(object)row, false); RectTransform val2 = (RectTransform)val.transform; val2.anchorMin = center; val2.anchorMax = center; val2.pivot = center; val2.anchoredPosition = new Vector2(19f, 0f); val2.sizeDelta = new Vector2(30f, 20f); Image component = val.GetComponent<Image>(); component.sprite = GUIManager.Instance.GetSprite("text_field"); component.type = (Type)1; ((Graphic)component).color = new Color(1f, 1f, 1f, 0.15f); ((Graphic)component).raycastTarget = true; InputField component2 = val.GetComponent<InputField>(); component2.lineType = (LineType)0; component2.contentType = (ContentType)2; component2.characterLimit = 3; GameObject val3 = new GameObject("Text", new Type[2] { typeof(RectTransform), typeof(Text) }); val3.transform.SetParent(val.transform, false); RectTransform val4 = (RectTransform)val3.transform; val4.anchorMin = Vector2.zero; val4.anchorMax = Vector2.one; val4.offsetMin = Vector2.zero; val4.offsetMax = Vector2.zero; Text component3 = val3.GetComponent<Text>(); component3.text = "0"; component3.font = GUIManager.Instance.AveriaSerifBold; component3.fontSize = 16; ((Graphic)component3).color = Color.white; component3.alignment = (TextAnchor)4; component3.supportRichText = false; Outline val5 = val3.AddComponent<Outline>(); ((Shadow)val5).effectColor = Color.black; component2.textComponent = component3; return val; } } public static class SkillUiController { public enum SkillTab { Active, Passive } [CompilerGenerated] private static class <>O { public static UnityAction <0>__OnApplyConfirm; public static UnityAction <1>__OnApplyCancel; public static UnityAction <2>__OnRebirthConfirm; public static UnityAction <3>__OnRebirthCancel; public static UnityAction <4>__OnPrestigeConfirm; public static UnityAction <5>__OnPrestigeCancel; } public static Player CurrentPlayer; public static int BaseAvailablePoints; public static Text PointsText; public static Text PrestigeText; public static readonly Color PlannedColor = new Color(0.561f, 0.773f, 0.941f, 1f); private static readonly Dictionary<SkillType, int> _pendingAllocations = new Dictionary<SkillType, int>(); public static float LastScrollPos = 1f; public static bool SuppressAutoScroll = false; public static RectTransform RootPanel; public static SkillsDialog CurrentDialog; private static GameObject _rebirthDialogRoot; private static GameObject _applyDialogRoot; private static GameObject _prestigeDialogRoot; private static Text _applyDialogLabel; private static Text _prestigeDialogLabel; public static GameObject PrestigeIconRoot; public static GameObject PointsBadgeRoot; public static Button PrestigeButton; public static SkillTab CurrentTab = SkillTab.Active; public static Button TabToggleButton; public static Button ApplyButton; public static Button RebirthButton; public static void Initialize(Player player, Text pointsText) { CurrentPlayer = player; PointsText = pointsText; BaseAvailablePoints = ((!((Object)(object)player == (Object)null)) ? SkillPointService.GetAvailablePoints(player) : 0); ResetAllocated(); RefreshPointsBadge(); RefreshPrestigeLabel(); RefreshTabButtons(); } public static int GetAllocated(SkillType type) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) int value; return _pendingAllocations.TryGetValue(type, out value) ? value : 0; } public static void ChangeAllocated(SkillType type, int delta) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) int num = Mathf.Max(0, GetAllocated(type) + delta); if (num == 0) { _pendingAllocations.Remove(type); } else { _pendingAllocations[type] = num; } RefreshRebirthResetButton(); } public static void SetAllocated(SkillType type, int value) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) int num = Mathf.Max(0, value); if (num == 0) { _pendingAllocations.Remove(type); } else { _pendingAllocations[type] = num; } RefreshRebirthResetButton(); } public static int GetMaxAllocatable(SkillType type) { //IL_0029: 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) if ((Object)(object)CurrentPlayer == (Object)null) { return 0; } Skills skills = ((Character)CurrentPlayer).GetSkills(); Skill val = ((skills != null) ? skills.GetSkill(type) : null); if (val == null) { return 0; } float currentSkillCap = SkillCapPolicy.GetCurrentSkillCap(CurrentPlayer); int num = Mathf.Max(0, Mathf.FloorToInt(currentSkillCap - val.m_level)); int num2 = GetCurrentUnspent() + GetAllocated(type); return Mathf.Min(num, num2); } public static void ResetAllocated() { _pendingAllocations.Clear(); foreach (SkillRowController activeController in SkillRowController.ActiveControllers) { activeController.RefreshCounter(); } RefreshRebirthResetButton(); } public static int GetTotalAllocated() { return _pendingAllocations.Values.Sum(); } public static int GetCurrentUnspent() { int num = BaseAvailablePoints - GetTotalAllocated(); return Mathf.Max(0, num); } public static void RefreshPointsBadge() { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)PointsText == (Object)null)) { PointsText.text = GetCurrentUnspent().ToString(); BlinkingTextEffect.SetActive(PointsText, GetTotalAllocated() > 0, BlinkingTextEffect.Darken(PlannedColor, 0.55f), PlannedColor, Color.white); } } public static void RefreshPrestigeLabel() { if (!((Object)(object)PrestigeText == (Object)null) && !((Object)(object)CurrentPlayer == (Object)null)) { int num = (ModConfig.PrestigeEnabled ? PlayerProgressionStore.GetPrestigeRank(CurrentPlayer) : 0); PrestigeText.text = num.ToString(); } } public static void OnTabChanged(SkillTab tab) { CurrentTab = tab; RefreshDialogSoft(); if ((Object)(object)CurrentDialog != (Object)null) { ScrollRect skillListScrollRect = CurrentDialog.skillListScrollRect; if ((Object)(object)skillListScrollRect != (Object)null) { skillListScrollRect.verticalNormalizedPosition = 1f; LastScrollPos = 1f; } } } public static void OnTabToggled() { OnTabChanged((CurrentTab == SkillTab.Active) ? SkillTab.Passive : SkillTab.Active); } public static void OnRebirthOrResetClicked() { if (GetTotalAllocated() > 0) { OnResetClicked(); } else { OnRebirthRequested(); } } public static void RefreshRebirthResetButton() { if (!((Object)(object)RebirthButton == (Object)null)) { Text componentInChildren = ((Component)RebirthButton).GetComponentInChildren<Text>(); if (!((Object)(object)componentInChildren == (Object)null)) { componentInChildren.text = Localization.instance.Localize((GetTotalAllocated() > 0) ? "$m2_sr_btn_reset" : "$m2_sr_btn_rebirth"); } } } public static void RefreshTabButtons() { if ((Object)(object)TabToggleButton != (Object)null) { Text componentInChildren = ((Component)TabToggleButton).GetComponentInChildren<Text>(); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.text = Localization.instance.Localize((CurrentTab == SkillTab.Active) ? "$m2_sr_tab_active" : "$m2_sr_tab_passive"); } } bool flag = CurrentTab == SkillTab.Active; if ((Object)(object)ApplyButton != (Object)null) { ((Component)ApplyButton).gameObject.SetActive(flag); } if ((Object)(object)RebirthButton != (Object)null) { ((Component)RebirthButton).gameObject.SetActive(flag); } string failureMessage; bool active = flag && ModConfig.PrestigeEnabled && (Object)(object)CurrentPlayer != (Object)null && PrestigeFlow.CanStart(CurrentPlayer, out failureMessage); if ((Object)(object)PrestigeButton != (Object)null) { ((Component)PrestigeButton).gameObject.SetActive(active); } if ((Object)(object)PointsBadgeRoot != (Object)null) { PointsBadgeRoot.SetActive(flag); } } public static void RefreshTabVisibility(int activeCount, int passiveCount) { bool active = activeCount > 0 && passiveCount > 0; if ((Object)(object)TabToggleButton != (Object)null) { ((Component)TabToggleButton).gameObject.SetActive(active); } } public static void RefreshLocalizedButtons() { RefreshPointsBadge(); RefreshRebirthResetButton(); RefreshTabButtons(); if ((Object)(object)ApplyButton != (Object)null) { Text componentInChildren = ((Component)ApplyButton).GetComponentInChildren<Text>(); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.text = Localization.instance.Localize("$m2_sr_btn_apply"); } } if ((Object)(object)PrestigeButton != (Object)null) { Text componentInChildren2 = ((Component)PrestigeButton).GetComponentInChildren<Text>(); if ((Object)(object)componentInChildren2 != (Object)null) { componentInChildren2.text = Localization.instance.Localize("$m2_sr_btn_prestige"); } } GameObject[] array = new GameObject[3]; Button applyButton = ApplyButton; array[0] = ((applyButton != null) ? ((Component)applyButton).gameObject : null); Button rebirthButton = RebirthButton; array[1] = ((rebirthButton != null) ? ((Component)rebirthButton).gameObject : null); Button prestigeButton = PrestigeButton; array[2] = ((prestigeButton != null) ? ((Component)prestigeButton).gameObject : null); AdjustButtonWidths((GameObject[])(object)array); } internal static void AdjustButtonWidths(params GameObject[] buttons) { if (buttons == null || buttons.Length == 0) { return; } float num = 20f; float num2 = 0f; Canvas.ForceUpdateCanvases(); foreach (GameObject val in buttons) { if ((Object)(object)val == (Object)null) { continue; } Text componentInChildren = val.GetComponentInChildren<Text>(); if (!((Object)(object)componentInChildren == (Object)null)) { float num3 = componentInChildren.preferredWidth + num; if (num3 > num2) { num2 = num3; } } } num2 = Mathf.Max(num2, 80f); foreach (GameObject val2 in buttons) { if (!((Object)(object)val2 == (Object)null)) { Transform transform = val2.transform; RectTransform val3 = (RectTransform)(object)((transform is RectTransform) ? transform : null); if (!((Object)(object)val3 == (Object)null)) { val3.SetSizeWithCurrentAnchors((Axis)0, num2); } } } } public static void OnApplyRequested() { if ((Object)(object)CurrentPlayer == (Object)null) { return; } int totalAllocated = GetTotalAllocated(); if (totalAllocated <= 0) { string text = Localization.instance.Localize("$m2_sr_no_points_allocated"); ((Character)CurrentPlayer).Message((MessageType)2, text, 0, (Sprite)null, false); return; } EnsureApplyDialog(); if ((Object)(object)_applyDialogLabel != (Object)null) { string format = Localization.instance.Localize("$m2_sr_apply_dialog_text"); _applyDialogLabel.text = string.Format(format, totalAllocated, BaseAvailablePoints); } ShowDialog(_applyDialogRoot); } public static void OnResetClicked() { ResetAllocated(); RefreshPointsBadge(); RefreshDialogSoft(); } public static void OnRebirthRequested() { if (!((Object)(object)CurrentPlayer == (Object)null)) { EnsureRebirthDialog(); ShowDialog(_rebirthDialogRoot); } } public static void OnPrestigeRequested() { if ((Object)(object)CurrentPlayer == (Object)null) { return; } if (!PrestigeFlow.CanStart(CurrentPlayer, out var failureMessage)) { if (!string.IsNullOrEmpty(failureMessage)) { ((Character)CurrentPlayer).Message((MessageType)2, failureMessage, 0, (Sprite)null, false); } return; } EnsurePrestigeDialog(); if ((Object)(object)_prestigeDialogLabel != (Object)null) { int num = PlayerProgressionStore.GetPrestigeRank(CurrentPlayer) + 1; int prestigePointsPerRank = ModConfig.PrestigePointsPerRank; string format = Localization.instance.Localize("$m2_sr_prestige_confirm_text"); _prestigeDialogLabel.text = string.Format(format, num, prestigePointsPerRank); } ShowDialog(_prestigeDialogRoot); } public static void RefreshDialogSoft() { if (!((Object)(object)CurrentDialog == (Object)null) && !((Object)(object)CurrentPlayer == (Object)null) && ((Component)CurrentDialog).gameObject.activeInHierarchy) { ScrollRect skillListScrollRect = CurrentDialog.skillListScrollRect; if ((Object)(object)skillListScrollRect != (Object)null) { LastScrollPos = skillListScrollRect.verticalNormalizedPosition; } SuppressAutoScroll = true; CurrentDialog.Setup(CurrentPlayer); SuppressAutoScroll = false; if ((Object)(object)skillListScrollRect != (Object)null) { skillListScrollRect.verticalNormalizedPosition = LastScrollPos; } RefreshPointsBadge(); RefreshPrestigeLabel(); } } private static void ApplyAllocatedPoints() { if (!((Object)(object)CurrentPlayer == (Object)null)) { List<SkillAllocationFlow.SkillPointAllocation> pendingAllocations = GetPendingAllocations(); if (SkillAllocationFlow.Apply(CurrentPlayer, pendingAllocations).Changed) { RefreshAfterProgressionChange(CurrentPlayer); } } } private static List<SkillAllocationFlow.SkillPointAllocation> GetPendingAllocations() { //IL_0039: 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) List<SkillAllocationFlow.SkillPointAllocation> list = new List<SkillAllocationFlow.SkillPointAllocation>(); foreach (KeyValuePair<SkillType, int> pendingAllocation in _pendingAllocations) { if (pendingAllocation.Value > 0) { list.Add(new SkillAllocationFlow.SkillPointAllocation { SkillType = pendingAllocation.Key, Points = pendingAllocation.Value }); } } return list; } public static void RefreshAfterProgressionChange(Player player) { if (!((Object)(object)player == (Object)null)) { CurrentPlayer = player; BaseAvailablePoints = SkillPointService.GetAvailablePoints(player); ResetAllocated(); RefreshPointsBadge(); RefreshPrestigeLabel(); RefreshDialogSoft(); if ((Object)(object)player == (Object)(object)Player.m_localPlayer) { LevelXpHudController.RefreshForLocalPlayer(); } } } private static void DispatchFlowResult(FlowExecutionResult result) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)CurrentPlayer == (Object)null || result == null) { return; } foreach (FlowNotification notification in result.Notifications) { ((Character)CurrentPlayer).Message(notification.MessageType, notification.Message, 0, (Sprite)null, false); } } private static RectTransform GetDialogParent() { return (RectTransform)(((object)RootPanel) ?? ((object)/*isinst with value type is only supported in some contexts*/)); } private static void ShowDialog(GameObject dialogRoot) { if ((Object)(object)dialogRoot != (Object)null) { dialogRoot.SetActive(true); } } private static void HideDialog(GameObject dialogRoot) { if ((Object)(object)dialogRoot != (Object)null) { dialogRoot.SetActive(false); } } private static void EnsureApplyDialog() { //IL_002a: 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_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected O, but got Unknown //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Expected O, but got Unknown if (!((Object)(object)_applyDialogRoot != (Object)null)) { RectTransform dialogParent = GetDialogParent(); Vector2 size = new Vector2(400f, 150f); string initialText = Localization.instance.Localize("$m2_sr_apply_dialog_title"); object obj = <>O.<0>__OnApplyConfirm; if (obj == null) { UnityAction val = OnApplyConfirm; <>O.<0>__OnApplyConfirm = val; obj = (object)val; } object obj2 = <>O.<1>__OnApplyCancel; if (obj2 == null) { UnityAction val2 = OnApplyCancel; <>O.<1>__OnApplyCancel = val2; obj2 = (object)val2; } ConfirmationDialogFactory.DialogReferences dialogReferences = ConfirmationDialogFactory.Create("SkillsReworked_ApplyDialog", dialogParent, size, initialText, 320f, 80f, (UnityAction)obj, (UnityAction)obj2); _applyDialogRoot = dialogReferences.Root; _applyDialogLabel = dialogReferences.Label; } } private static void EnsureRebirthDialog() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown //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_007b: Expected O, but got Unknown if (!((Object)(object)_rebirthDialogRoot != (Object)null)) { RectTransform dialogParent = GetDialogParent(); Vector2 size = new Vector2(400f, 150f); string initialText = Localization.instance.Localize("$m2_sr_rebirth_confirm_text"); object obj = <>O.<2>__OnRebirthConfirm; if (obj == null) { UnityAction val = OnRebirthConfirm; <>O.<2>__OnRebirthConfirm = val; obj = (object)val; } object obj2 = <>O.<3>__OnRebirthCancel; if (obj2 == null) { UnityAction val2 = OnRebirthCancel; <>O.<3>__OnRebirthCancel = val2; obj2 = (object)val2; } _rebirthDialogRoot = ConfirmationDialogFactory.Create("SkillsReworked_RebirthDialog", dialogParent, size, initialText, 280f, 80f, (UnityAction)obj, (UnityAction)obj2).Root; } } private static void EnsurePrestigeDialog() { //IL_002a: 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_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected O, but got Unknown //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Expected O, but got Unknown if (!((Object)(object)_prestigeDialogRoot != (Object)null)) { RectTransform dialogParent = GetDialogParent(); Vector2 size = new Vector2(420f, 170f); string initialText = Localization.instance.Localize("$m2_sr_prestige_confirm_text"); object obj = <>O.<4>__OnPrestigeConfirm; if (obj == null) { UnityAction val = OnPrestigeConfirm; <>O.<4>__OnPrestigeConfirm = val; obj = (object)val; } object obj2 = <>O.<5>__OnPrestigeCancel; if (obj2 == null) { UnityAction val2 = OnPrestigeCancel; <>O.<5>__OnPrestigeCancel = val2; obj2 = (object)val2; } ConfirmationDialogFactory.DialogReferences dialogReferences = ConfirmationDialogFactory.Create("SkillsReworked_PrestigeDialog", dialogParent, size, initialText, 320f, 90f, (UnityAction)obj, (UnityAction)obj2); _prestigeDialogRoot = dialogReferences.Root; _prestigeDialogLabel = dialogReferences.Label; } } private static void OnApplyConfirm() { ApplyAllocatedPoints(); HideDialog(_applyDialogRoot); } private static void OnApplyCancel() { HideDialog(_applyDialogRoot); } private static void OnRebirthConfirm() { FlowExecutionResult flowExecutionResult = RebirthFlow.Execute(CurrentPlayer); HideDialog(_rebirthDialogRoot); DispatchFlowResult(flowExecutionResult); if (flowExecutionResult.Success) { RefreshAfterProgressionChange(CurrentPlayer); } } private static void OnRebirthCancel() { HideDialog(_rebirthDialogRoot); } private static void OnPrestigeConfirm() { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) FlowExecutionResult flowExecutionResult = PrestigeFlow.Execute(CurrentPlayer); HideDialog(_prestigeDialogRoot); DispatchFlowResult(flowExecutionResult); if (flowExecutionResult.Success) { RefreshAfterProgressionChange(CurrentPlayer); CurrentPlayer.StartEmote("roar", true); Vector3 centerPoint = ((Character)CurrentPlayer).GetCenterPoint(); Vector3 position = ((Component)CurrentPlayer).transform.position; GameObject prefab = ZNetScene.instance.GetPrefab("vfx_MeadHasty"); GameObject prefab2 = ZNetScene.instance.GetPrefab("sfx_gdking_scream"); if ((Object)(object)prefab != (Object)null) { ZNetScene.instance.SpawnObject(centerPoint, Quaternion.identity, prefab); } if ((Object)(object)prefab2 != (Object)null) { ZNetScene.instance.SpawnObject(position, Quaternion.identity, prefab2); } } } private static void OnPrestigeCancel() { HideDialog(_prestigeDialogRoot); } } public static class UiSpriteHelper { private static bool _cached; private static Sprite _workbenchStarSprite; private static Type _workbenchStarType; private static float _workbenchStarPPU; private static bool _workbenchStarPreserveAspect; private static Material _workbenchStarMaterial; private static Sprite _circleSprite; public static Sprite GetCircleSprite() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_circleSprite != (Object)null) { return _circleSprite; } Texture2D val = new Texture2D(128, 128, (TextureFormat)4, false); ((Texture)val).filterMode = (FilterMode)1; float num = 63.5f; float num2 = num - 1f; for (int i = 0; i < 128; i++) { for (int j = 0; j < 128; j++) { float num3 = (float)j - num; float num4 = (float)i - num; float num5 = Mathf.Sqrt(num3 * num3 + num4 * num4); float num6 = Mathf.Clamp01(num2 + 1.5f - num5); val.SetPixel(j, i, new Color(1f, 1f, 1f, num6)); } } val.Apply(false, true); _circleSprite = Sprite.Create(val, new Rect(0f, 0f, 128f, 128f), new Vector2(0.5f, 0.5f), 100f); return _circleSprite; } public static void ApplyWorkbenchLevelStar(Image target) { //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)target == (Object)null)) { CacheWorkbenchStarOnce(); if ((Object)(object)_workbenchStarSprite != (Object)null) { target.sprite = _workbenchStarSprite; target.type = _workbenchStarType; target.pixelsPerUnitMultiplier = _workbenchStarPPU; target.preserveAspect = _workbenchStarPreserveAspect; ((Graphic)target).material = _workbenchStarMaterial; ((Graphic)target).color = Color.white; } else { target.sprite = null; target.type = (Type)1; target.preserveAspect = false; ((Graphic)target).color = GUIManager.Instance.ValheimOrange; } } } private static void CacheWorkbenchStarOnce() { //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) if (_cached) { return; } _cached = true; InventoryGui instance = InventoryGui.instance; if ((Object)(object)instance == (Object)null) { Logger.LogWarning((object)"[SkillsReworked.UI.SkillPanel.UiSpriteHelper] InventoryGui.instance is null"); return; } RectTransform crafting = instance.m_crafting; if ((Object)(object)crafting == (Object)null) { Logger.LogWarning((object)"[SkillsReworked.UI.SkillPanel.UiSpriteHelper] InventoryGui.m_crafting is null"); return; } Transform val = ((Transform)crafting).Find("Level"); if ((Object)(object)val == (Object)null) { Transform[] componentsInChildren = ((Component)crafting).GetComponentsInChildren<Transform>(true); foreach (Transform val2 in componentsInChildren) { if (((Object)val2).name == "Level") { val = val2; break; } } } if ((Object)(object)val == (Object)null) { Logger.LogWarning((object)"[SkillsReworked.UI.SkillPanel.UiSpriteHelper] Could not find 'Level' under InventoryGui.m_crafting"); return; } Image component = ((Component)val).GetComponent<Image>(); if ((Object)(object)component == (Object)null) { Logger.LogWarning((object)"[SkillsReworked.UI.SkillPanel.UiSpriteHelper] 'Level' does not have an Image component"); return; } _workbenchStarSprite = component.sprite; _workbenchStarType = component.type; _workbenchStarPPU = component.pixelsPerUnitMultiplier; _workbenchStarPreserveAspect = component.preserveAspect; _workbenchStarMaterial = ((Graphic)component).material; } } } namespace SkillsReworked.UI.LevelHud { public static class LevelXpHudController { private class HudData { public RectTransform Root; public RectTransform FastFill; public RectTransform SlowFill; public TMP_Text Label; public float LabelBaseFontSize; public float MaxWidth; public float FastFraction; public float SlowFraction; public float SlowAnimStart; public float SlowAnimTarget; public float SlowAnimElapsed; public float SlowAnimDuration; public float SlowDelayRemaining; public bool SlowAnimationActive; public int PreviousLevel; public bool LevelUpAnimating; public float LevelUpFinalTarget; } private static readonly Dictionary<Hud, HudData> Bars = new Dictionary<Hud, HudData>(); private const float Margin = 3f; private const float SlowStartDelay = 0.18f; private const float SlowMinDuration = 0.22f; private const float SlowMaxDuration = 1.82f; private const float SlowDurationScale = 1.6f; public static void Register() { LevelProgressionService.OnLevelChanged += RefreshForLocalPlayer; } public static void RefreshForLocalPlayer() { //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) Hud instance = Hud.instance; if ((Object)(object)instance == (Object)null) { return; } if (!ModConfig.XpBarEnabled) { if (Bars.TryGetValue(instance, out var value)) { SetActiveSafe(value, active: false); } return; } if (!Bars.TryGetValue(instance, out var value2) || (Object)(object)value2.Root == (Object)null) { CreateBarForHud(instance); if (!Bars.TryGetValue(instance, out value2) || (Object)(object)value2.Root == (Object)null) { return; } } if (!instance.IsVisible()) { SetActiveSafe(value2, active: false); return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { SetActiveSafe(value2, active: false); return; } Skills skills = ((Character)localPlayer).GetSkills(); Skill val = ((skills != null) ? skills.GetSkill(SkillsReworkedPlugin.LevelSkillType) : null); if (val == null) { SetActiveSafe(value2, active: false); return; } int num = Mathf.FloorToInt(val.m_level); float currentLevelFraction = LevelXpCalculator.GetCurrentLevelFraction(val); float num2 = Mathf.Clamp01(currentLevelFraction); if (num <= 0 && num2 <= 0f) { value2.FastFraction = 0f; SnapSlowTo(value2, 0f); if ((Object)(object)value2.FastFill != (Object)null) { value2.FastFill.sizeDelta = new Vector2(0f, value2.FastFill.sizeDelta.y); } if ((Object)(object)value2.Label != (Object)null) { value2.Label.text = string.Empty; } SetActiveSafe(value2, active: false); return; } bool flag = (Object)(object)value2.Root != (Object)null && ((Component)value2.Root).gameObject.activeSelf; float fastFraction = value2.FastFraction; int previousLevel = value2.PreviousLevel; SetActiveSafe(value2, active: true); ApplyLayout(instance, value2); value2.PreviousLevel = num; if (value2.LevelUpAnimating) { if ((Object)(object)value2.Label != (Object)null) { value2.Label.text = $"Level {num}"; } return; } value2.FastFraction = num2; ApplyFillWidth(value2.FastFill, value2.MaxWidth, value2.FastFraction); if (!flag) { SnapSlowTo(value2, num2); } else if (!Mathf.Approximately(fastFraction, num2)) { bool flag2 = num > previousLevel; bool flag3 = num < previousLevel; if (flag2) { value2.FastFraction = 1f; ApplyFillWidth(value2.FastFill, value2.MaxWidth, 1f); value2.LevelUpFinalTarget = num2; value2.LevelUpAnimating = true; BeginSlowAnimation(value2, 1f, 0.18f); } else if (flag3) { value2.SlowFraction = 1f; ApplyFillWidth(value2.SlowFill, value2.MaxWidth, 1f); BeginSlowAnimation(value2, num2, 0f); } else if (num2 < fastFraction || num2 < value2.SlowFraction) { BeginSlowAnimation(value2, num2, 0f); } else { BeginSlowAnimation(value2, num2, 0.18f); } } if ((Object)(object)value2.Label != (Object)null) { value2.Label.text = $"Level {num}"; } } public static void Update(float dt) { if (Bars.Count == 0) { return; } foreach (KeyValuePair<Hud, HudData> bar in Bars) { HudData value = bar.Value; if (value != null && !((Object)(object)value.Root == (Object)null) && ((Component)value.Root).gameObject.activeSelf && !((Object)(object)value.SlowFill == (Object)null) && value.SlowAnimationActive && TickSlowAnimation(value, dt) && value.SlowAnimationActive) { TickSlowAnimation(value, 0f); } } } private static bool TickSlowAnimation(HudData data, float dt) { if (data.SlowDelayRemaining > 0f) { data.SlowDelayRemaining = Mathf.Max(0f, data.SlowDelayRemaining - dt); if (data.SlowDelayRemaining > 0f) { return false; } } data.SlowAnimElapsed += dt; float num = Mathf.Max(0.0001f, data.SlowAnimDuration); float num2 = Mathf.Clamp01(data.SlowAnimElapsed / num); float num3 = 1f - Mathf.Pow(1f - num2, 3f); ApplyFillWidth(fraction: data.SlowFraction = Mathf.Lerp(data.SlowAnimStart, data.SlowAnimTarget, num3), fill: data.SlowFill, maxWidth: data.MaxWidth); if (num2 >= 1f) { data.SlowFraction = data.SlowAnimTarget; ApplyFillWidth(data.SlowFill, data.MaxWidth, data.SlowFraction); ClearSlowAnimation(data); if (data.LevelUpAnimating) { data.LevelUpAnimating = false; data.FastFraction = data.LevelUpFinalTarget; ApplyFillWidth(data.FastFill, data.MaxWidth, data.LevelUpFinalTarget); data.SlowFraction = 0f; ApplyFillWidth(data.SlowFill, data.MaxWidth, 0f); BeginSlowAnimation(data, data.LevelUpFinalTarget, 0f); return true; } } return false; } private static void CreateBarForHud(Hud hud) { //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Expected O, but got Unknown //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_013b: 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_00e3: 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_0163: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Expected O, but got Unknown //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Unknown result type (might be due to invalid IL or missing references) //IL_02cb: Expected O, but got Unknown //IL_02ea: Unknown result type (might be due to invalid IL or missing references) //IL_0301: Unknown result type (might be due to invalid IL or missing references) //IL_0318: Unknown result type (might be due to invalid IL or missing references) //IL_032f: Unknown result type (might be due to invalid IL or missing references) //IL_0359: Unknown result type (might be due to invalid IL or missing references) //IL_03b9: Unknown result type (might be due to invalid IL or missing references) //IL_03d0: Unknown result type (might be due to invalid IL or missing references) //IL_0436: Unknown result type (might be due to invalid IL or missing references) //IL_043d: Expected O, but got Unknown //IL_0449: Unknown result type (might be due to invalid IL or missing references) //IL_0460: Unknown result type (might be due to invalid IL or missing references) //IL_046d: Unknown result type (might be due to invalid IL or missing references) //IL_047a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)hud == (Object)null || Bars.ContainsKey(hud)) { return; } RectTransform val = (RectTransform)(((Object)(object)hud.m_healthBarRoot != (Object)null) ? /*isinst with value type is only supported in some contexts*/: /*isinst with value type is only supported in some contexts*/); if (!((Object)(object)val == (Object)null)) { GameObject val2 = new GameObject("SkillsReworked_LevelXpBar", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); RectTransform component = val2.GetComponent<RectTransform>(); ((Transform)component).SetParent((Transform)(object)val, false); if ((Object)(object)hud.m_healthBarRoot != (Object)null) { component.anchorMin = hud.m_healthBarRoot.anchorMin; component.anchorMax = hud.m_healthBarRoot.anchorMax; component.pivot = hud.m_healthBarRoot.pivot; } else { component.anchorMin = new Vector2(0f, 1f); component.anchorMax = new Vector2(0f, 1f); component.pivot = new Vector2(0f, 1f); } Image component2 = val2.GetComponent<Image>(); ((Graphic)component2).color = new Color(0f, 0f, 0f, 0.65f); Image val3 = null; if ((Object)(object)hud.m_staminaBar2Fast != (Object)null) { val3 = ((Component)hud.m_staminaBar2Fast).GetComponentInChildren<Image>(); } if ((Object)(object)val3 == (Object)null && (Object)(object)hud.m_healthBarFast != (Object)null) { val3 = ((Component)hud.m_healthBarFast).GetComponentInChildren<Image>(); } GameObject val4 = new GameObject("FillFast", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); RectTransform component3 = val4.GetComponent<RectTransform>(); ((Transform)component3).SetParent((Transform)(object)component, false); component3.anchorMin = new Vector2(0f, 0.5f); component3.anchorMax = new Vector2(0f, 0.5f); component3.pivot = new Vector2(0f, 0.5f); component3.anchoredPosition = new Vector2(3f, 0f); Image component4 = val4.GetComponent<Image>(); ((Graphic)component4).color = new Color(1f, 0.86f, 0.25f, 0.95f); GameObject val5 = new GameObject("FillSlow", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); RectTransform component5 = val5.GetComponent<RectTransform>(); ((Transform)component5).SetParent((Transform)(object)component, false); component5.anchorMin = new Vector2(0f, 0.5f); component5.anchorMax = new Vector2(0f, 0.5f); component5.pivot = new Vector2(0f, 0.5f); component5.anchoredPosition = new Vector2(3f, 0f); Image component6 = val5.GetComponent<Image>(); ((Graphic)component6).color = new Color(0.16f, 0.6f, 0.95f, 0.95f); if ((Object)(object)val3 != (Object)null && (Object)(object)val3.sprite != (Object)null) { CopySpriteSettings(val3, component4); CopySpriteSettings(val3, component6); } Shadow val6 = val5.AddComponent<Shadow>(); val6.effectColor = new Color(0f, 0f, 0f, 0.85f); val6.effectDistance = new Vector2(0f, -2f); val6.useGraphicAlpha = true; TMP_Text val7 = null; TMP_Text val8 = hud.m_staminaText ?? hud.m_healthText; if ((Object)(object)val8 != (Object)null) { val7 = Object.Instantiate<TMP_Text>(val8, (Transform)(object)component); ((Object)val7).name = "LevelXpLabel"; val7.alignment = (TextAlignmentOptions)514; RectTransform val9 = (RectTransform)val7.transform; val9.anchorMin = new Vector2(0f, 0f); val9.anchorMax = new Vector2(1f, 1f); val9.offsetMin = Vector2.zero; val9.offsetMax = Vector2.zero; val7.enableAutoSizing = false; val7.fontSize = val8.fontSize; val7.text = string.Empty; } Bars[hud] = new HudData { Root = component, FastFill = component3, SlowFill = component5, Label = val7, LabelBaseFontSize = (((Object)(object)val8 != (Object)null) ? val8.fontSize : 0f), FastFraction = 0f, SlowFraction = 0f, SlowAnimStart = 0f, SlowAnimTarget = 0f, SlowAnimElapsed = 0f, SlowAnimDuration = 0f, SlowDelayRemaining = 0f, SlowAnimationActive = false }; ((Component)component).gameObject.SetActive(false); } } public static void OnHudDestroy(Hud hud) { if (!((Object)(object)hud == (Object)null) && Bars.TryGetValue(hud, out var value)) { if ((Object)(object)value.Root != (Object)null) { Object.Destroy((Object)(object)((Component)value.Root).gameObject); } Bars.Remove(hud); } } private static void ApplyLayout(Hud hud, HudData data) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0089: 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_006d: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)data?.Root == (Object)null)) { float xpBarWidth = ModConfig.XpBarWidth; float xpBarHeight = ModConfig.XpBarHeight; data.MaxWidth = xpBarWidth; data.Root.sizeDelta = new Vector2(xpBarWidth + 6f, xpBarHeight + 6f); data.Root.anchoredPosition = (Vector2)(((Object)(object)hud.m_healthBarRoot != (Object)null) ? (hud.m_healthBarRoot.anchoredPosition + new Vector2(ModConfig.XpBarOffsetX, ModConfig.XpBarOffsetY)) : new Vector2(0f, -80f)); if ((Object)(object)data.FastFill != (Object)null) { data.FastFill.sizeDelta = new Vector2(data.FastFill.sizeDelta.x, xpBarHeight); } if ((Object)(object)data.SlowFill != (Object)null) { data.SlowFill.sizeDelta = new Vector2(data.SlowFill.sizeDelta.x, xpBarHeight); } ApplyFillWidth(data.FastFill, data.MaxWidth, data.FastFraction); ApplyFillWidth(data.SlowFill, data.MaxWidth, data.SlowFraction); if ((Object)(object)data.Label != (Object)null && data.LabelBaseFontSize > 0f) { data.Label.fontSize = data.LabelBaseFontSize * (xpBarHeight / 25f); } } } private static void SetActiveSafe(HudData data, bool active) { if (!((Object)(object)data?.Root == (Object)null)) { GameObject gameObject = ((Component)data.Root).gameObject; if (gameObject.activeSelf != active) { gameObject.SetActive(active); } } } private static void BeginSlowAnimation(HudData data, float targetFraction, float delay) { if (data != null) { float num = Mathf.Clamp01(targetFraction); float num2 = Mathf.Clamp01(data.SlowFraction); if (Mathf.Approximately(num2, num)) { SnapSlowTo(data, num); return; } float num3 = Mathf.Abs(num - num2); data.SlowAnimStart = num2; data.SlowAnimTarget = num; data.SlowAnimElapsed = 0f; data.SlowAnimDuration = Mathf.Clamp(0.22f + num3 * 1.6f, 0.22f, 1.82f); data.SlowDelayRemaining = Mathf.Max(0f, delay); data.SlowAnimationActive = true; } } private static void SnapSlowTo(HudData data, float fraction) { if (data != null) { ApplyFillWidth(fraction: data.SlowFraction = Mathf.Clamp01(fraction), fill: data.SlowFill, maxWidth: data.MaxWidth); ClearSlowAnimation(data); } } private static void ClearSlowAnimation(HudData data) { if (data != null) { data.SlowAnimStart = data.SlowFraction; data.SlowAnimTarget = data.SlowFraction; data.SlowAnimElapsed = 0f; data.SlowAnimDuration = 0f; data.SlowDelayRemaining = 0f; data.SlowAnimationActive = false; } } private static void ApplyFillWidth(RectTransform fill, float maxWidth, float fraction) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)fill == (Object)null)) { float num = Mathf.Clamp01(fraction); fill.sizeDelta = new Vector2(maxWidth * num, fill.sizeDelta.y); } } private static void CopySpriteSettings(Image from, Image to) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) to.sprite = from.sprite; to.type = from.type; to.pixelsPerUnitMultiplier = from.pixelsPerUnitMultiplier; to.preserveAspect = from.preserveAspect; } } } namespace SkillsReworked.UI.Dialogs { public static class ConfirmationDialogFactory { public struct DialogReferences { public GameObject Root; public Text Label; } public static DialogReferences Create(string name, RectTransform parent, Vector2 size, string initialText, float textWidth, float textHeight, UnityAction onConfirm, UnityAction onCancel) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); RectTransform component = val.GetComponent<RectTransform>(); val.transform.SetParent((Transform)(object)parent, false); component.anchorMin = new Vector2(0.5f, 0.5f); component.anchorMax = new Vector2(0.5f, 0.5f); component.anchoredPosition = Vector2.zero; component.sizeDelta = size; Image val2 = val.AddComponent<Image>(); GUIManager.Instance.ApplyWoodpanelStyle(((Component)val2).transform); GameObject val3 = GUIManager.Instance.CreateText(initialText, (Transform)(object)component, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -40f), GUIManager.Instance.AveriaSerifBold, 16, Color.white, true, Color.black, textWidth, textHeight, false); Text component2 = val3.GetComponent<Text>(); if ((Object)(object)component2 != (Object)null) { component2.alignment = (TextAnchor)4; } string text = Localization.instance.Localize("$menu_yes"); string text2 = Localization.instance.Localize("$menu_no"); GameObject val4 = GUIManager.Instance.CreateButton(text, (Transform)(object)component, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(60f, 30f), 100f, 30f); ((UnityEvent)val4.GetComponent<Button>().onClick).AddListener(onConfirm); GameObject val5 = GUIManager.Instance.CreateButton(text2, (Transform)(object)component, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(-60f, 30f), 100f, 30f); ((UnityEvent)val5.GetComponent<Button>().onClick).AddListener(onCancel); return new DialogReferences { Root = val, Label = component2 }; } } } namespace SkillsReworked.Systems.Rewards { internal static class KillCreditResolver { internal const float CreditMaxAgeSeconds = 30f; internal static bool TryResolveKillerPlayer(HitData hit, out Player killer) { killer = null; if (hit == null) { return false; } Character attacker = hit.GetAttacker(); if ((Object)(object)attacker == (Object)null) { return false; } Player val = (Player)(object)((attacker is Player) ? attacker : null); if (val != null) { killer = val; return true; } MonsterAI val2 = default(MonsterAI); if (((Component)attacker).TryGetComponent<MonsterAI>(ref val2) && (Object)(object)val2 != (Object)null) { GameObject followTarget = val2.GetFollowTarget(); if (Object.op_Implicit((Object)(object)followTarget)) { killer = followTarget.GetComponent<Player>(); return (Object)(object)killer != (Object)null; } } return false; } internal static bool TryResolveAttackerPeerId(HitData hit, out long attackerPeerId) { //IL_008f: Unknown result type (might be due to invalid IL or missing references) attackerPeerId = ZNetView.Everybody; if (hit == null) { return false; } if (TryResolveKillerPlayer(hit, out var killer) && (Object)(object)killer != (Object)null) { ZNetView nview = ((Character)killer).m_nview; ZDO val = ((nview != null) ? nview.GetZDO() : null); if (val != null) { attackerPeerId = val.GetOwner(); return attackerPeerId != ZNetView.Everybody; } } if (((ZDOID)(ref hit.m_attacker)).IsNone()) { return false; } ZDOMan instance = ZDOMan.instance; ZDO val2 = ((instance != null) ? instance.GetZDO(hit.m_attacker) : null); if (val2 == null) { return false; } if (val2.GetLong(ZDOVars.s_playerID, 0L) == 0) { return false; } attackerPeerId = val2.GetOwner(); return attackerPeerId != ZNetView.Everybody; } public static bool TryResolveKillerPeerId(Character victim, HitData lastHit, out long killerPeerId) { killerPeerId = ZNetView.Everybody; if ((Object)(object)victim == (Object)null) { return false; } if (TryResolveAttackerPeerId(lastHit, out killerPeerId)) { return true; } return KillCreditStore.TryGet(victim, 30f, out killerPeerId); } } internal static class KillCreditStore { private static readonly int LastAttackerKey = StringExtensionMethods.GetStableHashCode("SkillsReworked_lastAttacker"); private static readonly int LastAttackerAtKey = StringExtensionMethods.GetStableHashCode("SkillsReworked_lastAttackerAt"); public static void Store(Character victim, long attackerPeerId) { if (attackerPeerId != ZNetView.Everybody) { object obj; if (victim == null) { obj = null; } else { ZNetView nview = victim.m_nview; obj = ((nview != null) ? nview.GetZDO() : null); } ZDO val = (ZDO)obj; if (val != null) { val.Set(LastAttackerKey, attackerPeerId); val.Set(LastAttackerAtKey, CurrentTime()); } } } public static bool TryGet(Character victim, float maxAgeSeconds, out long attackerPeerId) { attackerPeerId = ZNetView.Everybody; object obj; if (victim == null) { obj = null; } else { ZNetView nview = victim.m_nview; obj = ((nview != null) ? nview.GetZDO() : null); } ZDO val = (ZDO)obj; if (val == null) { return false; } long num = val.GetLong(LastAttackerKey, 0L); if (num == ZNetView.Everybody) { return false; } long num2 = val.GetLong(LastAttackerAtKey, 0L); if (CurrentTime() - num2 > (long)maxAgeSeconds) { return false; } attackerPeerId = num; return true; } private static long CurrentTime() { return ((Object)(object)ZNet.instance != (Object)null) ? ((long)ZNet.instance.GetTimeSeconds()) : 0; } } internal static class KillRewardFlow { internal const string CharacterDiedRpcName = "SkillsReworked_RPC_CharacterDied"; private const float BossKeyMaxDistance = 300f; public static void AnnounceDeath(Character victim, long killerPeerId, float baseXp, Biome biome, string defeatKey, bool isBoss) { //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Expected I4, but got Unknown //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) if (ZRoutedRpc.instance != null) { bool flag = !string.IsNullOrEmpty(defeatKey); bool flag2 = killerPeerId != ZNetView.Everybody && baseXp > 0f; if (flag || flag2) { bool flag3 = flag2 && ModConfig.PartyShareRadius > 0f && ModConfig.PartyShareFactor > 0f; long num = ((flag || flag3) ? 0 : killerPeerId); ZRoutedRpc.instance.InvokeRoutedRPC(num, "SkillsReworked_RPC_CharacterDied", new object[6] { killerPeerId, baseXp, (int)biome, defeatKey ?? string.Empty, isBoss, ((Object)(object)victim != (Object)null) ? ((Component)victim).transform.position : Vector3.zero }); } } } internal static void RPC_OnCharacterDied(long sender, long killerPeerId, float baseXp, int biomeInt, string defeatKey, bool isBoss, Vector3 victimPos) { //IL_003e: 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_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer)) { return; } bool flag = killerPeerId != ZNetView.Everybody && ZNet.GetUID() == killerPeerId; bool flag2 = false; if (!string.IsNullOrEmpty(defeatKey) && (flag || RpcRangeUtil.IsLocalPlayerWithinRange(victimPos, 300f))) { flag2 = !((Humanoid)localPlayer).HaveUniqueKey(defeatKey); if (flag2) { ((Humanoid)localPlayer).AddUniqueKey(defeatKey); } } if (!(baseXp <= 0f)) { float xp = baseXp; if (isBoss && (!ModConfig.BossXpMultiplierFirstKillOnly || flag2)) { xp = KillXpCalculator.ApplyBossMultiplier(xp); } Biome biome = (Biome)biomeInt; if (flag) { AwardXp(localPlayer, biome, xp); } else { PartyXpIntegration.TryAwardPartyShare(localPlayer, killerPeerId, biome, xp); } } } internal static void AwardXp(Player player, Biome biome, float xp) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) float num = LevelXpCalculator.ApplyLevelScaling(player, biome, xp); if (!(num <= 0f)) { ((Character)player).RaiseSkill(SkillsReworkedPlugin.LevelSkillType, num); } } } internal static class KillXpCalculator { public static float CalculateRawXp(float victimMaxHealth) { if (victimMaxHealth <= 0f) { return 0f; } float num = victimMaxHealth * 0.1f; float xpMultiplier = ModConfig.XpMultiplier; float num2 = num * xpMultiplier + 5f; return Mathf.Max(0f, num2); } public static float ApplyBossMultiplier(float xp) { return Mathf.Max(0f, xp * ModConfig.BossXpMultiplier); } } public class MobBiomeTracker : MonoBehaviour { public Biome SpawnBiome; } } namespace SkillsReworked.Systems.Reset { public static class ProgressionResetService { public static void ResetActiveSkills(Skills skills) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0051: 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_005c: Invalid comparison between Unknown and I4 //IL_006a: 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_0090: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)skills == (Object)null) { return; } List<Skill> skillList = skills.GetSkillList(); foreach (Skill item in skillList) { if (item?.m_info != null) { SkillType skill = item.m_info.m_skill; if ((int)skill != 0 && (int)skill != 999 && skill != SkillsReworkedPlugin.LevelSkillType && SkillCategoryService.IsActiveSkill(skill)) { skills.ResetSkill(skill); } } } } public static void ResetLevelSkill(Skills skills) { LevelProgressionService.Reset(skills); } public static void ResetSpentPoints(Player player) { PlayerProgressionStore.ResetSpentSkillPoints(player); } public static void ResyncSpentPointsFromSkillLevels(Player player, Skills skills) { //IL_0056: 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_005d: 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) //IL_0068: Invalid comparison between Unknown and I4 //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || (Object)(object)skills == (Object)null) { return; } int num = 0; foreach (Skill skill2 in skills.GetSkillList()) { if (skill2?.m_info != null) { SkillType skill = skill2.m_info.m_skill; if ((int)skill != 0 && (int)skill != 999 && skill != SkillsReworkedPlugin.LevelSkillType && SkillCategoryService.IsActiveSkill(skill)) { num += Mathf.RoundToInt(skill2.m_level); } } } PlayerProgressionStore.SetSpentSkillPoints(player, num); } } } namespace SkillsReworked.Systems.Rebirth { public enum RebirthCostMode { None, LevelOnly, ItemOnly, Both } public static class RebirthFlow { public static event Action<Player> OnExecuted; public static FlowExecutionResult Execute(Player player) { if ((Object)(object)player == (Object)null) { return FlowExecutionResult.Failed(); } Skills skills = ((Character)player).GetSkills(); if ((Object)(object)skills == (Object)null) { return FlowExecutionResult.Failed(); } bool rebirthCostEnabled = ModConfig.RebirthCostEnabled; RebirthCostMode rebirthCostModeSetting = ModConfig.RebirthCostModeSetting; bool flag = rebirthCostEnabled && (rebirthCostModeSetting == RebirthCostMode.LevelOnly || rebirthCostModeSetting == RebirthCostMode.Both); bool flag2 = rebirthCostEnabled && (rebirthCostModeSetting == RebirthCostMode.ItemOnly || rebirthCostModeSetting == RebirthCostMode.Both); int rebirthLevelLoss = ModConfig.RebirthLevelLoss; string rebirthItemName = ModConfig.RebirthItemName; int rebirthItemAmount = ModConfig.RebirthItemAmount; if (flag && rebirthLevelLoss > 0) { int level = LevelSkillService.GetLevel(skills); if (level < rebirthLevelLoss) { string format = Localization.instance.Localize("$m2_sr_rebirth_need_levels"); return FlowExecutionResult.Failed().AddNotification((MessageType)2, string.Format(format, rebirthLevelLoss)); } } if (flag2 && rebirthItemAmount > 0 && !string.IsNullOrEmpty(rebirthItemName) && !ItemCostService.HasRequiredItems(player, rebirthItemName, rebirthItemAmount)) { string format2 = Localization.instance.Localize("$m2_sr_rebirth_need_items"); string itemDisplayName = ItemCostService.GetItemDisplayName(rebirthItemName); return FlowExecutionResult.Failed().AddNotification((MessageType)2, string.Format(format2, rebirthItemAmount, itemDisplayName)); } FlowExecutionResult flowExecutionResult = FlowExecutionResult.Succeeded(); if (flag && rebirthLevelLoss > 0) { if (LevelProgressionService.TryConsumeWholeLevels(skills, rebirthLevelLoss)) { string format3 = Localization.instance.Localize("$m2_sr_rebirth_cost_levels"); flowExecutionResult.AddNotification((MessageType)1, string.Format(format3, rebirthLevelLoss)); } else { Logger.LogWarning((object)"[SkillsReworked] Rebirth level cost could not be applied because the Level skill was missing."); } } if (flag2 && rebirthItemAmount > 0 && !string.IsNullOrEmpty(rebirthItemName) && ItemCostService.TryConsumeItems(player, rebirthItemName, rebirthItemAmount)) { string format4 = Localization.instance.Localize("$m2_sr_rebirth_cost_items"); string itemDisplayName2 = ItemCostService.GetItemDisplayName(rebirthItemName); flowExecutionResult.AddNotification((MessageType)1, string.Format(format4, rebirthItemAmount, itemDisplayName2)); } ProgressionResetService.ResetActiveSkills(skills); ProgressionResetService.ResetSpentPoints(player); string message = Localization.instance.Localize("$m2_sr_rebirth_done"); Logger.LogInfo((object)"[SkillsReworked] Rebirth executed: non-level skills reset and spent points cleared."); RebirthFlow.OnExecuted?.Invoke(player); return flowExecutionResult.AddNotification((MessageType)1, message); } } } namespace SkillsReworked.Systems.Progression { public static class BossProgressionService { public static readonly string[] DefeatKeys = new string[7] { "defeated_eikthyr", "defeated_gdking", "defeated_bonemass", "defeated_dragon", "defeated_goblinking", "defeated_queen", "defeated_fader" }; public static bool HasDefeated(Player player, string defeatKey) { if ((Object)(object)player == (Object)null || string.IsNullOrEmpty(defeatKey)) { return false; } if (ModConfig.UseGlobalBossKeys) { return (Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetGlobalKey(defeatKey); } return ((Humanoid)player).HaveUniqueKey(defeatKey); } public static int GetDefeatedCount(Player player) { if ((Object)(object)player == (Object)null) { return 0; } int num = 0; string[] defeatKeys = DefeatKeys; foreach (string defeatKey in defeatKeys) { if (HasDefeated(player, defeatKey)) { num++; } } return num; } } public static class LevelProgressionService { public static event Action OnLevelChanged; public static void Reset(Skills skills) { Skill skill = LevelSkillService.GetSkill(skills); if (skill != null) { SetLevelAndAccumulator(skill, 0f, 0f); } } public static bool TryConsumeWholeLevels(Skills skills, int levelLoss) { if ((Object)(object)skills == (Object)null || levelLoss <= 0) { return false; } Skill skill = LevelSkillService.GetSkill(skills); if (skill == null) { return false; } SetLevelAndAccumulator(skill, Mathf.Max(0f, skill.m_level - (float)levelLoss), 0f); return true; } public static bool ApplyDeathFractionLoss(Skills skills, float fraction) { if ((Object)(object)skills == (Object)null) { return false; } Skill skill = LevelSkillService.GetSkill(skills); if (skill == null) { return false; } fraction = Mathf.Clamp01(fraction); if (fraction <= 0f) { return true; } int num = Mathf.FloorToInt(skill.m_level); float requirementForLevel = LevelXpCalculator.GetRequirementForLevel(num); if (requirementForLevel <= 0f) { return true; } float num2 = Mathf.Clamp01(skill.m_accumulator / requirementForLevel); if (num2 >= fraction) { float num3 = num2 - fraction; SetLevelAndAccumulator(skill, skill.m_level, num3 * requirementForLevel); return true; } float num4 = fraction - num2; if (num > 0) { int num5 = num - 1; float requirementForLevel2 = LevelXpCalculator.GetRequirementForLevel(num5); float num6 = 1f - num4; if (num6 <= 0f) { SetLevelAndAccumulator(skill, num5, 0f); } else { SetLevelAndAccumulator(skill, num5, num6 * requirementForLevel2); } } else { SetLevelAndAccumulator(skill, 0f, 0f); } return true; } public static int AddXp(Skills skills, float factor) { if ((Object)(object)skills == (Object)null || factor <= 0f) { return 0; } Skill skill = LevelSkillService.GetSkill(skills); if (skill == null || skill.m_info == null) { return 0; } if (skill.m_level >= 100f) { SetLevelAndAccumulator(skill, 100f, 0f); return 0; } float num = skill.m_info.m_increseStep * factor * Game.m_skillGainRate; if (num <= 0f) { return 0; } float num2 = Mathf.Max(0f, skill.m_accumulator) + num; float num3 = skill.m_level; int num4 = 0; while (num3 < 100f) { int levelIndex = Mathf.FloorToInt(num3); float requirementForLevel = LevelXpCalculator.GetRequirementForLevel(levelIndex); if (requirementForLevel <= 0f || num2 + 0.0001f < requirementForLevel) { break; } num2 -= requirementForLevel; num3 = Mathf.Min(num3 + 1f, 100f); num4++; if (num3 >= 100f) { num2 = 0f; break; } } SetLevelAndAccumulator(skill, num3, num2); return num4; } private static void SetLevelAndAccumulator(Skill levelSkill, float level, float accumulator) { if (levelSkill != null) { levelSkill.m_level = Mathf.Clamp(level, 0f, 100f); levelSkill.m_accumulator = Mathf.Max(0f, accumulator); LevelProgressionService.OnLevelChanged?.Invoke(); } } } public static class LevelSkillService { public static Skill GetSkill(Player player) { if ((Object)(object)player == (Object)null) { return null; } return GetSkill(((Character)player).GetSkills()); } public static Skill GetSkill(Skills skills) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)skills == (Object)null) { return null; } return skills.GetSkill(SkillsReworkedPlugin.LevelSkillType); } public static int GetLevel(Player player) { return GetLevel((player != null) ? ((Character)player).GetSkills() : null); } public static int GetLevel(Skills skills) { Skill skill = GetSkill(skills); return (skill != null) ? Mathf.FloorToInt(skill.m_level) : 0; } public static float GetCurrentLevelFraction(Player player) { return GetCurrentLevelFraction(GetSkill(player)); } public static float GetCurrentLevelFraction(Skills skills) { return GetCurrentLevelFraction(GetSkill(skills)); } public static float GetCurrentLevelFraction(Skill levelSkill) { return LevelXpCalculator.GetCurrentLevelFraction(levelSkill); } } public static class LevelXpCalculator { public static float GetRequirementForLevel(int levelIndex) { float num = Mathf.Floor((float)levelIndex + 1f); return Mathf.Pow(num, 1.5f) * 0.5f + 0.5f; } public static float GetCurrentLevelFraction(Skill levelSkill) { if (levelSkill == null) { return 0f; } int levelIndex = Mathf.FloorToInt(levelSkill.m_level); float requirementForLevel = GetRequirementForLevel(levelIndex); if (requirementForLevel <= 0f) { return 0f; } return Mathf.Clamp01(levelSkill.m_accumulator / requirementForLevel); } public static int GetPlayerLevel(Player player) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return 0; } Skills skills = ((Character)player).GetSkills(); if ((Object)(object)skills == (Object)null) { return 0; } Skill skill = skills.GetSkill(SkillsReworkedPlugin.LevelSkillType); if (skill == null) { return 0; } return Mathf.FloorToInt(skill.m_level); } private static int GetOptimalLevelForBiome(Biome biome) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Invalid comparison between Unknown and I4 //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected I4, but got Unknown //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Invalid comparison between Unknown and I4 //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Invalid comparison between Unknown and I4 //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Invalid comparison between Unknown and I4 //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Invalid comparison between Unknown and I4 if ((int)biome <= 16) { switch (biome - 1) { default: if ((int)biome != 8) { if ((int)biome != 16) { break; } return ModConfig.PlainsOptimalLevel; } return ModConfig.BlackForestOptimalLevel; case 0: return ModConfig.MeadowsOptimalLevel; case 1: return ModConfig.SwampOptimalLevel; case 3: return ModConfig.MountainOptimalLevel; case 2: break; } } else { if ((int)biome == 32) { return ModConfig.AshlandsOptimalLevel; } if ((int)biome == 64) { return ModConfig.DeepNorthOptimalLevel; } if ((int)biome == 512) { return ModConfig.MistlandsOptimalLevel; } } return ModConfig.MeadowsOptimalLevel; } public static Biome GetMobBiome(Character mob) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Invalid comparison between Unknown and I4 //IL_004d: 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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: 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_0037: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)mob == (Object)null) { return (Biome)1; } MobBiomeTracker component = ((Component)mob).GetComponent<MobBiomeTracker>(); if ((Object)(object)component != (Object)null && (int)component.SpawnBiome > 0) { return component.SpawnBiome; } return Heightmap.FindBiome(((Component)mob).transform.position); } public static float GetLevelBasedXpFactor(Player player, Character mob) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || (Object)(object)mob == (Object)null) { return 1f; } return GetLevelBasedXpFactor(player, GetMobBiome(mob)); } public static float GetLevelBasedXpFactor(Player player, Biome biome) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return 1f; } int playerLevel = GetPlayerLevel(player); int optimalLevelForBiome = GetOptimalLevelForBiome(biome); if (optimalLevelForBiome <= 0) { return 1f; } if (playerLevel <= optimalLevelForBiome) { return 1f; } int num = playerLevel - optimalLevelForBiome; int num2 = ModConfig.XpMaxOverLevel; if (num2 <= 0) { num2 = 1; } float xpMinFactor = ModConfig.XpMinFactor; xpMinFactor = Mathf.Clamp(xpMinFactor, 0.01f, 1f); float num3 = Mathf.Clamp01((float)num / (float)num2); float num4 = Mathf.Lerp(1f, xpMinFactor, num3); return Mathf.Clamp(num4, xpMinFactor, 1f); } public static float ApplyLevelScaling(Player player, Character mob, float xp) { if (xp <= 0f) { return 0f; } float levelBasedXpFactor = GetLevelBasedXpFactor(player, mob); return xp * levelBasedXpFactor; } public static float ApplyLevelScaling(Player player, Biome biome, float xp) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) if (xp <= 0f) { return 0f; } float levelBasedXpFactor = GetLevelBasedXpFactor(player, biome); return xp * levelBasedXpFactor; } } public static class ProgressionZdoSync { private static readonly int LevelHash = StringExtensionMethods.GetStableHashCode("SkillsReworked_Level"); private static readonly int PrestigeHash = StringExtensionMethods.GetStableHashCode("SkillsReworked_Prestige"); public static void Register() { LevelProgressionService.OnLevelChanged += SyncLocalPlayer; PlayerProgressionStore.OnPrestigeChanged += Sync; } public static void SyncLocalPlayer() { Sync(Player.m_localPlayer); } public static void Sync(Player player) { if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer || (Object)(object)((Character)player).m_nview == (Object)null) { return; } ZDO zDO = ((Character)player).m_nview.GetZDO(); if (zDO != null && zDO.IsOwner()) { zDO.Set(LevelHash, SkillsReworkedApi.GetLevel(player), false); int prestigeLevel = SkillsReworkedApi.GetPrestigeLevel(player); int num = default(int); if (prestigeLevel > 0) { zDO.Set(PrestigeHash, prestigeLevel, false); } else if (zDO.GetInt(PrestigeHash, ref num) && num != 0) { zDO.Set(PrestigeHash, 0, false); } } } } public static class SkillAllocationFlow { public struct SkillPointAllocation { public SkillType SkillType; public int Points; } public struct SkillAllocationResult { public int AvailableBefore; public int EffectiveSpent; public bool Changed => EffectiveSpent > 0; } private struct PlannedAllocation { public Skill Skill; public int Points; } public static SkillAllocationResult Apply(Player player, IList<SkillPointAllocation> allocations) { //IL_00c2: Unknown result type (might be due to invalid IL or missing references) SkillAllocationResult result = default(SkillAllocationResult); if ((Object)(object)player == (Object)null || allocations == null || allocations.Count == 0) { return result; } Skills skills = ((Character)player).GetSkills(); if ((Object)(object)skills == (Object)null) { return result; } int num = (result.AvailableBefore = SkillPointService.GetAvailablePoints(player)); if (num <= 0) { return result; } float currentSkillCap = SkillCapPolicy.GetCurrentSkillCap(player); int num2 = num; int num3 = 0; List<PlannedAllocation> list = new List<PlannedAllocation>(); foreach (SkillPointAllocation allocation in allocations) { if (allocation.Points <= 0 || num2 <= 0) { continue; } Skill skill = skills.GetSkill(allocation.SkillType); if (skill != null && !(skill.m_level >= currentSkillCap)) { int num4 = Mathf.Max(0, Mathf.CeilToInt(currentSkillCap - skill.m_level)); int num5 = Mathf.Min(allocation.Points, Mathf.Min(num2, num4)); if (num5 > 0) { list.Add(new PlannedAllocation { Skill = skill, Points = num5 }); num2 -= num5; num3 += num5; } } } if (num3 <= 0) { return result; } if (!SkillPointService.TrySpendPoints(player, num3)) { Logger.LogWarning((object)$"[SkillsReworked] TrySpendPoints({num3}) failed before applying queued allocations."); return result; } foreach (PlannedAllocation item in list) { Skill skill2 = item.Skill; skill2.m_level += (float)item.Points; item.Skill.m_accumulator = 0f; } result.EffectiveSpent = num3; return result; } } public static class SkillCapPolicy { public static float GetCurrentSkillCap(Player player) { if ((Object)(object)player == (Object)null) { return 100f; } if (!ModConfig.SkillCapsEnabled) { return 100f; } int capBeforeEikthyr = ModConfig.CapBeforeEikthyr; int capAfterEikthyr = ModConfig.CapAfterEikthyr; int capAfterElder = ModConfig.CapAfterElder; int capAfterBonemass = ModConfig.CapAfterBonemass; int capAfterModer = ModConfig.CapAfterModer; int capAfterYagluth = ModConfig.CapAfterYagluth; int capAfterQueen = ModConfig.CapAfterQueen; int capAfterFader = ModConfig.CapAfterFader; if (Defeated("defeated_fader")) { return ClampCap(capAfterFader); } if (Defeated("defeated_queen")) { return ClampCap(capAfterQueen); } if (Defeated("defeated_goblinking")) { return ClampCap(capAfterYagluth); } if (Defeated("defeated_dragon")) { return ClampCap(capAfterModer); } if (Defeated("defeated_bonemass")) { return ClampCap(capAfterBonemass); } if (Defeated("defeated_gdking")) { return ClampCap(capAfterElder); } if (Defeated("defeated_eikthyr")) { return ClampCap(capAfterEikthyr); } return ClampCap(capBeforeEikthyr); bool Defeated(string key) { return BossProgressionService.HasDefeated(player, key); } } private static float ClampCap(int cap) { return Mathf.Clamp((float)cap, 0f, 100f); } } public static class SkillCategoryService { private static HashSet<SkillType> _activeCache; private static HashSet<SkillType> _passiveXpCache; private static Dictionary<string, SkillType> _nameLookupMap; public static void InvalidateCache() { _activeCache = null; _passiveXpCache = null; } public unsafe static void BuildNameLookup(Skills skillsInstance) { //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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Invalid comparison between Unknown and I4 //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) if (_nameLookupMap != null || skillsInstance?.m_skills == null) { return; } _nameLookupMap = new Dictionary<string, SkillType>(StringComparer.OrdinalIgnoreCase); foreach (SkillDef skill2 in skillsInstance.m_skills) { SkillType skill = skill2.m_skill; if ((int)skill != 0 && (int)skill != 999) { _nameLookupMap[((object)(*(SkillType*)(&skill))/*cast due to .constrained prefix*/).ToString()] = skill; string text = "$skill_" + ((object)(*(SkillType*)(&skill))/*cast due to .constrained prefix*/).ToString().ToLower(); Localization instance = Localization.instance; string text2 = ((instance != null) ? instance.Localize(text) : null); if (!string.IsNullOrWhiteSpace(text2) && !text2.StartsWith("$")) { _nameLookupMap[text2] = skill; } } } _activeCache = null; } public static bool IsActiveSkill(SkillType skillType) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Invalid comparison between Unknown and I4 //IL_002c: 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) if (skillType == SkillsReworkedPlugin.LevelSkillType) { return false; } if ((int)skillType == 0 || (int)skillType == 999) { return false; } if (GetActiveSet().Contains(skillType)) { return true; } if (Enum.IsDefined(typeof(SkillType), skillType)) { return false; } return ModConfig.UnknownSkillsDefaultActive; } public static bool IsPassiveXpSkill(SkillType skillType) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return GetPassiveXpSet().Contains(skillType); } private static HashSet<SkillType> GetActiveSet() { //IL_0093: Unknown result type (might be due to invalid IL or missing references) if (_activeCache != null) { return _activeCache; } _activeCache = new HashSet<SkillType>(); string activeSkillNames = ModConfig.ActiveSkillNames; if (string.IsNullOrWhiteSpace(activeSkillNames)) { return _activeCache; } string[] array = activeSkillNames.Split(new char[1] { ',' }); foreach (string text in array) { string text2 = text.Trim(); if (!string.IsNullOrEmpty(text2)) { SkillType? val = TryResolveSkillName(text2); if (val.HasValue) { _activeCache.Add(val.Value); } else { Logger.LogWarning((object)("[SkillCategoryService] Could not resolve skill name: '" + text2 + "'")); } } } return _activeCache; } private static HashSet<SkillType> GetPassiveXpSet() { //IL_0090: Unknown result type (might be due to invalid IL or missing references) if (_passiveXpCache != null) { return _passiveXpCache; } _passiveXpCache = new HashSet<SkillType>(); string passiveXpSkillNames = ModConfig.PassiveXpSkillNames; if (string.IsNullOrWhiteSpace(passiveXpSkillNames)) { return _passiveXpCache; } string[] array = passiveXpSkillNames.Split(new char[1] { ',' }); foreach (string text in array) { string text2 = text.Trim(); if (!string.IsNullOrEmpty(text2)) { SkillType? val = TryResolveSkillName(text2); if (val.HasValue) { _passiveXpCache.Add(val.Value); } } } return _passiveXpCache; } private static SkillType? TryResolveSkillName(string name) { //IL_000e: 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 (Enum.TryParse<SkillType>(name, ignoreCase: true, out SkillType result)) { return result; } if (int.TryParse(name, out var result2)) { return (SkillType)result2; } if (_nameLookupMap != null && _nameLookupMap.TryGetValue(name, out var value)) { return value; } return null; } } public static class SkillPointService { private static int BasePoints => ModConfig.BasePoints; private static int PointsPerLevel => ModConfig.PointsPerLevel; public static int GetTotalPoints(Player player) { if ((Object)(object)player == (Object)null) { return 0; } int num = Mathf.Max(0, LevelSkillService.GetLevel(player)); int basePoints = BasePoints; int pointsPerLevel = PointsPerLevel; int num2 = (ModConfig.PrestigeEnabled ? PlayerProgressionStore.GetPrestigeRank(player) : 0); int prestigePointsPerRank = ModConfig.PrestigePointsPerRank; int num3 = Mathf.Max(0, pointsPerLevel + num2 * prestigePointsPerRank); int num4 = basePoints + num * num3; return Mathf.Max(0, num4); } public static int GetAvailablePoints(Player player) { int totalPoints = GetTotalPoints(player); int spentSkillPoints = PlayerProgressionStore.GetSpentSkillPoints(player); return Mathf.Max(0, totalPoints - spentSkillPoints); } public static bool TrySpendPoints(Player player, int amount) { if ((Object)(object)player == (Object)null) { return false; } if (amount <= 0) { return true; } int availablePoints = GetAvailablePoints(player); if (availablePoints < amount) { return false; } int spentSkillPoints = PlayerProgressionStore.GetSpentSkillPoints(player); PlayerProgressionStore.SetSpentSkillPoints(player, spentSkillPoints + amount); return true; } } } namespace SkillsReworked.Systems.Prestige { public static class PrestigeFlow { public static event Action<Player> OnExecuted; public static bool CanStart(Player player, out string failureMessage) { failureMessage = null; if ((Object)(object)player == (Object)null) { return false; } if (!ModConfig.PrestigeEnabled) { return false; } Skills skills = ((Character)player).GetSkills(); if ((Object)(object)skills == (Object)null)