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.3.0
SkillsReworked.dll
Decompiled 2 days 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.Bootstrap; using SkillsReworked.Commands; using SkillsReworked.Infrastructure.Networking; using SkillsReworked.Integration.Groups; using SkillsReworked.Integration.SkillManager; 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+da0c81f704e40697f68447d9ff0f7bb4db43ec87")] [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] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace SkillsReworked.UI.SkillPanel { public class SkillRowController : MonoBehaviour { public static readonly List<SkillRowController> ActiveControllers = new List<SkillRowController>(); public SkillType SkillType; public Text CounterText; 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_0018: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)CounterText != (Object)null) { CounterText.text = SkillUiController.GetAllocated(SkillType).ToString(); } } 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_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Expected O, but got Unknown //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: 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 = GUIManager.Instance.CreateText("0", (Transform)(object)row, val3, val3, new Vector2(25f, 0f), GUIManager.Instance.AveriaSerifBold, 16, GUIManager.Instance.ValheimOrange, true, Color.black, 30f, 20f, false); skillRowController.CounterText = val6.GetComponent<Text>(); 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.RefreshUnspentLabel(); } }); ((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.RefreshUnspentLabel(); } }); } } 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 UnspentText; public static Text PrestigeText; 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 Button PrestigeButton; public static SkillTab CurrentTab = SkillTab.Active; public static Button ActiveTabButton; public static Button PassiveTabButton; public static Button ApplyButton; public static Button ResetButton; public static Button RebirthButton; public static void Initialize(Player player, Text unspentText) { CurrentPlayer = player; UnspentText = unspentText; BaseAvailablePoints = ((!((Object)(object)player == (Object)null)) ? SkillPointService.GetAvailablePoints(player) : 0); ResetAllocated(); RefreshUnspentLabel(); 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; } } public static void ResetAllocated() { _pendingAllocations.Clear(); foreach (SkillRowController activeController in SkillRowController.ActiveControllers) { activeController.RefreshCounter(); } } public static int GetTotalAllocated() { return _pendingAllocations.Values.Sum(); } public static int GetCurrentUnspent() { int num = BaseAvailablePoints - GetTotalAllocated(); return Mathf.Max(0, num); } public static void RefreshUnspentLabel() { if (!((Object)(object)UnspentText == (Object)null)) { string format = Localization.instance.Localize("$m2_sr_unspent_points"); UnspentText.text = string.Format(format, GetCurrentUnspent()); } } 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 RefreshTabButtons() { SetTabButtonSelected(ActiveTabButton, CurrentTab == SkillTab.Active); SetTabButtonSelected(PassiveTabButton, CurrentTab == SkillTab.Passive); bool flag = CurrentTab == SkillTab.Active; if ((Object)(object)ApplyButton != (Object)null) { ((Component)ApplyButton).gameObject.SetActive(flag); } if ((Object)(object)ResetButton != (Object)null) { ((Component)ResetButton).gameObject.SetActive(flag); } if ((Object)(object)RebirthButton != (Object)null) { ((Component)RebirthButton).gameObject.SetActive(flag); } if ((Object)(object)PrestigeButton != (Object)null) { ((Component)PrestigeButton).gameObject.SetActive(flag && ModConfig.PrestigeEnabled); } if ((Object)(object)UnspentText != (Object)null) { ((Component)UnspentText).gameObject.SetActive(flag); } } public static void RefreshTabVisibility(int activeCount, int passiveCount) { bool active = activeCount > 0 && passiveCount > 0; if ((Object)(object)ActiveTabButton != (Object)null) { ((Component)ActiveTabButton).gameObject.SetActive(active); } if ((Object)(object)PassiveTabButton != (Object)null) { ((Component)PassiveTabButton).gameObject.SetActive(active); } } private static void SetTabButtonSelected(Button button, bool selected) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)button == (Object)null)) { Text componentInChildren = ((Component)button).GetComponentInChildren<Text>(); if ((Object)(object)componentInChildren != (Object)null) { ((Graphic)componentInChildren).color = (selected ? GUIManager.Instance.ValheimOrange : Color.white); } } } 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); 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(); RefreshUnspentLabel(); 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); } 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; } RefreshUnspentLabel(); 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(); RefreshUnspentLabel(); 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); } } 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() { FlowExecutionResult flowExecutionResult = PrestigeFlow.Execute(CurrentPlayer); HideDialog(_prestigeDialogRoot); DispatchFlowResult(flowExecutionResult); if (flowExecutionResult.Success) { RefreshAfterProgressionChange(CurrentPlayer); } } 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; 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 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 BlueWidth = 260f; private const float BlueHeight = 25f; private const float Margin = 3f; private const float XOffset = -20f; private const float YOffset = -65f; 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 RefreshForLocalPlayer() { //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) Hud instance = Hud.instance; if ((Object)(object)instance == (Object)null) { return; } if (!Bars.TryGetValue(instance, out var value) || (Object)(object)value.Root == (Object)null) { CreateBarForHud(instance); if (!Bars.TryGetValue(instance, out value) || (Object)(object)value.Root == (Object)null) { return; } } if (!instance.IsVisible()) { SetActiveSafe(value, active: false); return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { SetActiveSafe(value, active: false); return; } Skills skills = ((Character)localPlayer).GetSkills(); Skill val = ((skills != null) ? skills.GetSkill(SkillsReworkedPlugin.LevelSkillType) : null); if (val == null) { SetActiveSafe(value, 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) { value.FastFraction = 0f; SnapSlowTo(value, 0f); if ((Object)(object)value.FastFill != (Object)null) { value.FastFill.sizeDelta = new Vector2(0f, value.FastFill.sizeDelta.y); } if ((Object)(object)value.Label != (Object)null) { value.Label.text = string.Empty; } SetActiveSafe(value, active: false); return; } bool flag = (Object)(object)value.Root != (Object)null && ((Component)value.Root).gameObject.activeSelf; float fastFraction = value.FastFraction; int previousLevel = value.PreviousLevel; SetActiveSafe(value, active: true); if ((Object)(object)instance.m_healthBarRoot != (Object)null) { Vector2 anchoredPosition = instance.m_healthBarRoot.anchoredPosition; value.Root.anchoredPosition = anchoredPosition + new Vector2(-20f, -65f); } else { value.Root.anchoredPosition = new Vector2(0f, -80f); } value.PreviousLevel = num; if (value.LevelUpAnimating) { if ((Object)(object)value.Label != (Object)null) { value.Label.text = $"Level {num}"; } return; } value.FastFraction = num2; ApplyFillWidth(value.FastFill, value.MaxWidth, value.FastFraction); if (!flag) { SnapSlowTo(value, num2); } else if (!Mathf.Approximately(fastFraction, num2)) { bool flag2 = num > previousLevel; bool flag3 = num < previousLevel; if (flag2) { value.FastFraction = 1f; ApplyFillWidth(value.FastFill, value.MaxWidth, 1f); value.LevelUpFinalTarget = num2; value.LevelUpAnimating = true; BeginSlowAnimation(value, 1f, 0.18f); } else if (flag3) { value.SlowFraction = 1f; ApplyFillWidth(value.SlowFill, value.MaxWidth, 1f); BeginSlowAnimation(value, num2, 0f); } else if (num2 < fastFraction || num2 < value.SlowFraction) { BeginSlowAnimation(value, num2, 0f); } else { BeginSlowAnimation(value, num2, 0.18f); } } if ((Object)(object)value.Label != (Object)null) { value.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_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Expected O, but got Unknown //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_0270: 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_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02c8: Unknown result type (might be due to invalid IL or missing references) //IL_0305: Unknown result type (might be due to invalid IL or missing references) //IL_030c: Expected O, but got Unknown //IL_032b: Unknown result type (might be due to invalid IL or missing references) //IL_0342: 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_0370: Unknown result type (might be due to invalid IL or missing references) //IL_0387: Unknown result type (might be due to invalid IL or missing references) //IL_03b1: Unknown result type (might be due to invalid IL or missing references) //IL_0411: Unknown result type (might be due to invalid IL or missing references) //IL_0428: Unknown result type (might be due to invalid IL or missing references) //IL_048e: Unknown result type (might be due to invalid IL or missing references) //IL_0495: Expected O, but got Unknown //IL_04a1: Unknown result type (might be due to invalid IL or missing references) //IL_04b8: Unknown result type (might be due to invalid IL or missing references) //IL_04c5: Unknown result type (might be due to invalid IL or missing references) //IL_04d2: 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); } float num = 266f; float num2 = 31f; component.sizeDelta = new Vector2(num, num2); component.anchoredPosition = Vector2.zero; 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); component3.sizeDelta = new Vector2(0f, 25f); 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); component5.sizeDelta = new Vector2(0f, 25f); 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, MaxWidth = 260f, 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 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); DialogReferences result = default(DialogReferences); result.Root = val; result.Label = component2; return result; } } } namespace SkillsReworked.Systems.Rewards { internal static class KillCreditResolver { 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; } public static bool TryResolveKillerPeerId(Character victim, HitData lastHit, out long killerPeerId) { killerPeerId = ZNetView.Everybody; if ((Object)(object)victim == (Object)null) { return false; } if (TryResolveKillerPlayer(lastHit, out var killer) && (Object)(object)killer != (Object)null) { ZNetView nview = ((Character)killer).m_nview; ZDO val = ((nview != null) ? nview.GetZDO() : null); if (val != null) { killerPeerId = val.GetOwner(); return killerPeerId != ZNetView.Everybody; } } if (LastPlayerDamageTracker.TryGet(victim, 10f, out var credit)) { killerPeerId = credit.PeerId; return killerPeerId != ZNetView.Everybody; } return false; } } internal static class KillRewardFlow { internal const string MobDeathEventRpcName = "SkillsReworked_RPC_MobDeathEvent"; public static void BroadcastKillXp(Character victim, long killerPeerId, float totalXp, Biome biome) { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected I4, but got Unknown if (!((Object)(object)victim == (Object)null) && Object.op_Implicit((Object)(object)victim.m_nview) && killerPeerId != ZNetView.Everybody && !(totalXp <= 0f)) { victim.m_nview.InvokeRPC(killerPeerId, "SkillsReworked_RPC_MobDeathEvent", new object[3] { killerPeerId, totalXp, (int)biome }); } } public static void AwardLocalKillXp(Player localPlayer, float totalXp, int biomeInt) { //IL_001f: 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_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)localPlayer) && !(totalXp <= 0f)) { Biome biome = (Biome)biomeInt; float num = LevelXpCalculator.ApplyLevelScaling(localPlayer, biome, totalXp); if (!(num <= 0f)) { ((Character)localPlayer).RaiseSkill(SkillsReworkedPlugin.LevelSkillType, num); GroupXpIntegration.TryBroadcastGroupShareFromKiller(localPlayer.GetPlayerName(), ((Component)localPlayer).transform.position, num, biomeInt); } } } } internal static class KillXpCalculator { public static float CalculateRawXp(float victimMaxHealth, bool isBoss) { if (victimMaxHealth <= 0f) { return 0f; } float num = victimMaxHealth * 0.1f; float xpMultiplier = ModConfig.XpMultiplier; float num2 = num * xpMultiplier + 5f; if (isBoss) { float bossXpMultiplier = ModConfig.BossXpMultiplier; num2 *= bossXpMultiplier; } return Mathf.Max(0f, num2); } } internal static class LastPlayerDamageTracker { internal struct Credit { public long PeerId; public float Time; } private static readonly Dictionary<ZDOID, Credit> Map = new Dictionary<ZDOID, Credit>(); public static void Store(Character victim, Player attacker) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) object obj; if (victim == null) { obj = null; } else { ZNetView nview = victim.m_nview; obj = ((nview != null) ? nview.GetZDO() : null); } ZDO val = (ZDO)obj; object obj2; if (attacker == null) { obj2 = null; } else { ZNetView nview2 = ((Character)attacker).m_nview; obj2 = ((nview2 != null) ? nview2.GetZDO() : null); } ZDO val2 = (ZDO)obj2; if (val != null && val2 != null) { Map[val.m_uid] = new Credit { PeerId = val2.GetOwner(), Time = Time.time }; } } public static bool TryGet(Character victim, float maxAgeSeconds, out Credit credit) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) credit = default(Credit); 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; } if (Map.TryGetValue(val.m_uid, out var value) && Time.time - value.Time <= maxAgeSeconds) { credit = value; return true; } return false; } public static void Remove(Character victim) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) 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) { Map.Remove(val.m_uid); } } } 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); } } } namespace SkillsReworked.Systems.Rebirth { public enum RebirthCostMode { None, LevelOnly, ItemOnly, Both } public static class RebirthFlow { 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."); return flowExecutionResult.AddNotification((MessageType)1, message); } } } namespace SkillsReworked.Systems.Progression { public static class LevelProgressionService { 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); } } } 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 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 (((Humanoid)player).HaveUniqueKey("defeated_fader")) { return ClampCap(capAfterFader); } if (((Humanoid)player).HaveUniqueKey("defeated_queen")) { return ClampCap(capAfterQueen); } if (((Humanoid)player).HaveUniqueKey("defeated_goblinking")) { return ClampCap(capAfterYagluth); } if (((Humanoid)player).HaveUniqueKey("defeated_dragon")) { return ClampCap(capAfterModer); } if (((Humanoid)player).HaveUniqueKey("defeated_bonemass")) { return ClampCap(capAfterBonemass); } if (((Humanoid)player).HaveUniqueKey("defeated_gdking")) { return ClampCap(capAfterElder); } if (((Humanoid)player).HaveUniqueKey("defeated_eikthyr")) { return ClampCap(capAfterEikthyr); } return ClampCap(capBeforeEikthyr); } 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; public static void InvalidateCache() { _activeCache = null; _passiveXpCache = 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> GetPassiveXpSet() { //IL_0088: 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 value = text.Trim(); if (!string.IsNullOrEmpty(value) && Enum.TryParse<SkillType>(value, ignoreCase: true, out SkillType result)) { _passiveXpCache.Add(result); } } return _passiveXpCache; } private static HashSet<SkillType> GetActiveSet() { //IL_0088: 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 value = text.Trim(); if (!string.IsNullOrEmpty(value) && Enum.TryParse<SkillType>(value, ignoreCase: true, out SkillType result)) { _activeCache.Add(result); } } return _activeCache; } } 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 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) { return false; } int prestigeRequiredLevel = ModConfig.PrestigeRequiredLevel; int level = LevelSkillService.GetLevel(skills); if (level < prestigeRequiredLevel) { string format = Localization.instance.Localize("$m2_sr_prestige_need_level"); failureMessage = string.Format(format, prestigeRequiredLevel); return false; } int prestigeMaxRank = ModConfig.PrestigeMaxRank; int prestigeRank = PlayerProgressionStore.GetPrestigeRank(player); if (prestigeRank >= prestigeMaxRank) { failureMessage = Localization.instance.Localize("$m2_sr_prestige_max_rank"); return false; } return true; } public static FlowExecutionResult Execute(Player player) { if (!CanStart(player, out var failureMessage)) { return FlowExecutionResult.Failed().AddNotification((MessageType)2, failureMessage); } Skills skills = ((Character)player).GetSkills(); bool prestigeItemCostEnabled = ModConfig.PrestigeItemCostEnabled; string prestigeItemName = ModConfig.PrestigeItemName; int prestigeItemAmount = ModConfig.PrestigeItemAmount; if (prestigeItemCostEnabled && prestigeItemAmount > 0 && !string.IsNullOrEmpty(prestigeItemName) && !ItemCostService.HasRequiredItems(player, prestigeItemName, prestigeItemAmount)) { string format = Localization.instance.Localize("$m2_sr_prestige_need_items"); string itemDisplayName = ItemCostService.GetItemDisplayName(prestigeItemName); return FlowExecutionResult.Failed().AddNotification((MessageType)2, string.Format(format, prestigeItemAmount, itemDisplayName)); } FlowExecutionResult flowExecutionResult = FlowExecutionResult.Succeeded(); if (prestigeItemCostEnabled && prestigeItemAmount > 0 && !string.IsNullOrEmpty(prestigeItemName) && ItemCostService.TryConsumeItems(player, prestigeItemName, prestigeItemAmount)) { string format2 = Localization.instance.Localize("$m2_sr_prestige_cost_items"); string itemDisplayName2 = ItemCostService.GetItemDisplayName(prestigeItemName); flowExecutionResult.AddNotification((MessageType)1, string.Format(format2, prestigeItemAmount, itemDisplayName2)); } PlayerProgressionStore.AddPrestigeRank(player, 1); ProgressionResetService.ResetLevelSkill(skills); ProgressionResetService.ResetActiveSkills(skills); ProgressionResetService.ResetSpentPoints(player); int prestigeRank = PlayerProgressionStore.GetPrestigeRank(player); string format3 = Localization.instance.Localize("$m2_sr_prestige_done"); return flowExecutionResult.AddNotification((MessageType)1, string.Format(format3, prestigeRank)); } } } namespace SkillsReworked.Systems.Costs { public static class ItemCostService { public static string GetItemDisplayName(string prefabName) { string itemSharedName = GetItemSharedName(prefabName); if (string.IsNullOrEmpty(itemSharedName)) { return prefabName ?? string.Empty; } return Localization.instance.Localize(itemSharedName); } public static bool HasRequiredItems(Player player, string prefabName, int amount) { if ((Object)(object)player == (Object)null || amount <= 0 || string.IsNullOrEmpty(prefabName)) { return true; } Inventory inventory = ((Humanoid)player).GetInventory(); string itemSharedName = GetItemSharedName(prefabName); return inventory != null && !string.IsNullOrEmpty(itemSharedName) && inventory.CountItems(itemSharedName, -1, true) >= amount; } public static bool TryConsumeItems(Player player, string prefabName, int amount) { if (!HasRequiredItems(player, prefabName, amount)) { return false; } Inventory inventory = ((Humanoid)player).GetInventory(); string itemSharedName = GetItemSharedName(prefabName); if (inventory == null || string.IsNullOrEmpty(itemSharedName)) { return false; } inventory.RemoveItem(itemSharedName, amount, -1, true); return true; } private static string GetItemSharedName(string prefabName) { if (string.IsNullOrEmpty(prefabName)) { return null; } ObjectDB instance = ObjectDB.instance; if ((Object)(object)instance == (Object)null) { return null; } GameObject itemPrefab = instance.GetItemPrefab(prefabName); if ((Object)(object)itemPrefab == (Object)null) { return null; } ItemDrop component = itemPrefab.GetComponent<ItemDrop>(); if ((Object)(object)component == (Object)null) { return null; } return component.m_itemData.m_shared.m_name; } } } namespace SkillsReworked.Systems.Common { public sealed class FlowExecutionResult { private readonly List<FlowNotification> _notifications = new List<FlowNotification>(); public bool Success { get; } public IReadOnlyList<FlowNotification> Notifications => _notifications; private FlowExecutionResult(bool success) { Success = success; } public static FlowExecutionResult Succeeded() { return new FlowExecutionResult(success: true); } public static FlowExecutionResult Failed() { return new FlowExecutionResult(success: false); } public FlowExecutionResult AddNotification(MessageType messageType, string message) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) if (!string.IsNullOrEmpty(message)) { _notifications.Add(new FlowNotification(messageType, message)); } return this; } } public struct FlowNotification { public MessageType MessageType { get; } public string Message { get; } public FlowNotification(MessageType messageType, string message) { //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) MessageType = messageType; Message = message; } } } namespace SkillsReworked.Persistence { internal static class PlayerCustomDataKeys { public const string SpentSkillPoints = "SkillsReworked.SpentSkillPoints"; public const string PrestigeRank = "SkillsReworked.PrestigeRank"; } public static class PlayerCustomDataStore { public static int GetInt(Player player, string key, int defaultValue = 0) { if ((Object)(object)player == (Object)null || player.m_customData == null || string.IsNullOrEmpty(key)) { return defaultValue; } if (player.m_customData.TryGetValue(key, out var value) && int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result)) { return result; } return defaultValue; } public static int GetNonNegativeInt(Player player, string key, int defaultValue = 0) { return Mathf.Max(0, GetInt(player, key, defaultValue)); } public static void SetInt(Player player, string key, int value) { if (!((Object)(object)player == (Object)null) && !string.IsNullOrEmpty(key)) { EnsureStore(player); player.m_customData[key] = value.ToString(CultureInfo.InvariantCulture); } } public static void SetNonNegativeInt(Player player, string key, int value) { SetInt(player, key, Mathf.Max(0, value)); } public static void EnsureStore(Player player) { if (!((Object)(object)player == (Object)null) && player.m_customData == null) { player.m_customData = new Dictionary<string, string>(); } } } public static class PlayerProgressionStore { public static int GetPrestigeRank(Player player) { return PlayerCustomDataStore.GetNonNegativeInt(player, "SkillsReworked.PrestigeRank"); } public static void SetPrestigeRank(Player player, int newRank) { if (!((Object)(object)player == (Object)null)) { int prestigeMaxRank = ModConfig.PrestigeMaxRank; PlayerCustomDataStore.SetNonNegativeInt(player, "SkillsReworked.PrestigeRank", Mathf.Clamp(newRank, 0, prestigeMaxRank)); } } public static void AddPrestigeRank(Player player, int amount) { if (!((Object)(object)player == (Object)null) && amount != 0) { int newRank = GetPrestigeRank(player) + amount; SetPrestigeRank(player, newRank); } } public static int GetSpentSkillPoints(Player player) { return PlayerCustomDataStore.GetNonNegativeInt(player, "SkillsReworked.SpentSkillPoints"); } public static void SetSpentSkillPoints(Player player, int spentPoints) { PlayerCustomDataStore.SetNonNegativeInt(player, "SkillsReworked.SpentSkillPoints", spentPoints); } public static void ResetSpentSkillPoints(Player player) { SetSpentSkillPoints(player, 0); } } } namespace SkillsReworked.Patches.UI { [HarmonyPatch] public static class HudPatch { [HarmonyPostfix] [HarmonyPatch(typeof(Hud), "Update")] private static void Hud_Update_Postfix() { LevelXpHudController.Update(Time.deltaTime); } [HarmonyPostfix] [HarmonyPatch(typeof(Hud), "OnDestroy")] private static void Hud_OnDestroy_Postfix(Hud __instance) { LevelXpHudController.OnHudDestroy(__instance); } } [HarmonyPatch(typeof(SkillsDialog), "SelectFirstEntry")] public static class SkillsDialogSelectFirstEntryPatch { [CompilerGenerated] private sealed class <EmptyEnumerator>d__1 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <EmptyEnumerator>d__1(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { if (<>1__state != 0) { return false; } <>1__state = -1; return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static bool Prefix(ref IEnumerator __result) { if (SkillUiController.SuppressAutoScroll) { __result = EmptyEnumerator(); return false; } return true; } [IteratorStateMachine(typeof(<EmptyEnumerator>d__1))] private static IEnumerator EmptyEnumerator() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <EmptyEnumerator>d__1(0); } } [HarmonyPatch(typeof(SkillsDialog), "Setup")] public static class SkillsDialogSetupPatch { [CompilerGenerated] private static class <>O { public static UnityAction <0>__OnPrestigeRequested; public static UnityAction <1>__OnRebirthRequested; public static UnityAction <2>__OnApplyRequested; public static UnityAction <3>__OnResetClicked; } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Func<Skill, bool> <>9__0_0; public static Func<Skill, bool> <>9__0_1; public static UnityAction <>9__0_2; public static UnityAction <>9__0_3; internal bool <Postfix>b__0_0(Skill s) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) return s?.m_info != null && s.m_info.m_skill != SkillsReworkedPlugin.LevelSkillType && SkillCategoryService.IsActiveSkill(s.m_info.m_skill); } internal bool <Postfix>b__0_1(Skill s) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) return s?.m_info != null && s.m_info.m_skill != SkillsReworkedPlugin.LevelSkillType && !SkillCategoryService.IsActiveSkill(s.m_info.m_skill); } internal void <Postfix>b__0_2() { SkillUiController.OnTabChanged(SkillUiController.SkillTab.Active); } internal void <Postfix>b__0_3() { SkillUiController.OnTabChanged(SkillUiController.SkillTab.Passive); } } private static void Postfix(SkillsDialog __instance, Player player) { //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0110: 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_0121: 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_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_03a2: Unknown result type (might be due to invalid IL or missing references) //IL_03a4: Unknown result type (might be due to invalid IL or missing references) //IL_03b0: Unknown result type (might be due to invalid IL or missing references) //IL_03c1: Unknown result type (might be due to invalid IL or missing references) //IL_03c7: Unknown result type (might be due to invalid IL or missing references) //IL_0413: Unknown result type (might be due to invalid IL or missing references) //IL_041a: Expected O, but got Unknown //IL_0430: Unknown result type (might be due to invalid IL or missing references) //IL_043a: Unknown result type (might be due to invalid IL or missing references) //IL_044e: Unknown result type (might be due to invalid IL or missing references) //IL_0465: Unknown result type (might be due to invalid IL or missing references) //IL_047c: Unknown result type (might be due to invalid IL or missing references) //IL_04ae: Unknown result type (might be due to invalid IL or missing references) //IL_04bd: Unknown result type (might be due to invalid IL or missing references) //IL_04c2: Unknown result type (might be due to invalid IL or missing references) //IL_04d3: Unknown result type (might be due to invalid IL or missing references) //IL_04d9: Unknown result type (might be due to invalid IL or missing references) //IL_052a: Unknown result type (might be due to invalid IL or missing references) //IL_052c: Unknown result type (might be due to invalid IL or missing references) //IL_0538: Unknown result type (might be due to invalid IL or missing references) //IL_0599: Unknown result type (might be due to invalid IL or missing references) //IL_059b: Unknown result type (might be due to invalid IL or missing references) //IL_05a7: Unknown result type (might be due to invalid IL or missing references) //IL_056e: Unknown result type (might be due to invalid IL or missing references) //IL_0573: Unknown result type (might be due to invalid IL or missing references) //IL_0579: Expected O, but got Unknown //IL_0608: Unknown result type (might be due to invalid IL or missing references) //IL_060a: Unknown result type (might be due to invalid IL or missing references) //IL_0616: Unknown result type (might be due to invalid IL or missing references) //IL_05dd: Unknown result type (might be due to invalid IL or missing references) //IL_05e2: Unknown result type (might be due to invalid IL or missing references) //IL_05e8: Expected O, but got Unknown //IL_0677: Unknown result type (might be due to invalid IL or missing references) //IL_0679: Unknown result type (might be due to invalid IL or missing references) //IL_0685: Unknown result type (might be due to invalid IL or missing references) //IL_064c: Unknown result type (might be due to invalid IL or missing references) //IL_0651: Unknown result type (might be due to invalid IL or missing references) //IL_0657: Expected O, but got Unknown //IL_0714: Unknown result type (might be due to invalid IL or missing references) //IL_0716: Unknown result type (might be due to invalid IL or missing references) //IL_0722: Unknown result type (might be due to invalid IL or missing references) //IL_06bb: Unknown result type (might be due to invalid IL or missing references) //IL_06c0: Unknown result type (might be due to invalid IL or missing references) //IL_06c6: Expected O, but got Unknown //IL_0780: Unknown result type (might be due to invalid IL or missing references) //IL_0782: Unknown result type (might be due to invalid IL or missing references) //IL_078e: Unknown result type (might be due to invalid IL or missing references) //IL_075c: Unknown result type (might be due to invalid IL or missing references) //IL_0761: Unknown result type (might be due to invalid IL or missing references) //IL_0767: Expected O, but got Unknown //IL_07c8: Unknown result type (might be due to invalid IL or missing references) //IL_07cd: Unknown result type (might be due to invalid IL or missing references) //IL_07d3: Expected O, but got Unknown if ((Object)(object)__instance == (Object)null || (Object)(object)player == (Object)null) { return; } Skills skills = ((Character)player).GetSkills(); if ((Object)(object)skills == (Object)null) { return; } List<Skill> skillList = skills.GetSkillList(); int num = skillList.Count((Skill s) => s?.m_info != null && s.m_info.m_skill != SkillsReworkedPlugin.LevelSkillType && SkillCategoryService.IsActiveSkill(s.m_info.m_skill)); int num2 = skillList.Count((Skill s) => s?.m_info != null && s.m_info.m_skill != SkillsReworkedPlugin.LevelSkillType && !SkillCategoryService.IsActiveSkill(s.m_info.m_skill)); if (SkillUiController.CurrentTab == SkillUiController.SkillTab.Active && num == 0 && num2 > 0) { SkillUiController.CurrentTab = SkillUiController.SkillTab.Passive; } else if (SkillUiController.CurrentTab == SkillUiController.SkillTab.Passive && num2 == 0 && num > 0) { SkillUiController.CurrentTab = SkillUiController.SkillTab.Active; } SkillRowController.DestroyAll(); for (int i = 0; i < skillList.Count && i < __instance.m_elements.Count; i++) { Skill val = skillList[i]; GameObject val2 = __instance.m_elements[i]; if ((Object)(object)val2 == (Object)null) { continue; } SkillType skill = val.m_info.m_skill; if (skill != SkillsReworkedPlugin.LevelSkillType && SkillCategoryService.IsActiveSkill(skill)) { Transform transform = val2.transform; RectTransform val3 = (RectTransform)(object)((transform is RectTransform) ? transform : null); if ((Object)(object)val3 != (Object)null) { SkillRowDecorator.AddButtons(val3, skill); } } } int num3 = 0; for (int j = 0; j < skillList.Count && j < __instance.m_elements.Count; j++) { SkillType skill2 = skillList[j].m_info.m_skill; GameObject val4 = __instance.m_elements[j]; if ((Object)(object)val4 == (Object)null) { continue; } bool flag; if (skill2 == SkillsReworkedPlugin.LevelSkillType) { flag = true; } else { bool flag2 = SkillCategoryService.IsActiveSkill(skill2); flag = ((SkillUiController.CurrentTab == SkillUiController.SkillTab.Active) ? flag2 : (!flag2)); } val4.SetActive(flag); if (flag) { Transform transform2 = val4.transform; RectTransform val5 = (RectTransform)(object)((transform2 is RectTransform) ? transform2 : null); if ((Object)(object)val5 != (Object)null) { val5.anchoredPosition = new Vector2(0f, (0f - (float)num3) * __instance.m_spacing); } num3++; } } float value = Traverse.Create((object)__instance).Field("m_baseListSize").GetValue<float>(); __instance.m_listRoot.SetSizeWithCurrentAnchors((Axis)1, Mathf.Max(value, (float)num3 * __instance.m_spacing)); RectTransform val6 = null; Transform parent = ((Transform)__instance.m_listRoot).parent; RectTransform val7 = (RectTransform)(object)((parent is RectTransform) ? parent : null); if ((Object)(object)val7 != (Object)null) { Transform parent2 = ((Transform)val7).parent; val6 = (RectTransform)(object)((parent2 is RectTransform) ? parent2 : null); } if ((Object)(object)val6 == (Object)null) { Transform transform3 = ((Component)__instance).transform; val6 = (RectTransform)(object)((transform3 is RectTransform) ? transform3 : null); } SkillUiController.RootPanel = val6; SkillUiController.CurrentDialog = __instance; if ((Object)(object)SkillUiController.UnspentText == (Object)null || (Object)(object)((Component)SkillUiController.UnspentText).gameObject == (Object)null) { Vector2 val8 = default(Vector2); ((Vector2)(ref val8))..ctor(0f, 0f); Vector2 val9 = default(Vector2); ((Vector2)(ref val9))..ctor(1f, 0f); Vector2 val10 = default(Vector2); ((Vector2)(ref val10))..ctor(1f, 1f); Vector2 val11 = default(Vector2); ((Vector2)(ref val11))..ctor(0f, 1f); string format = Localization.instance.Localize("$m2_sr_unspent_points"); string text = string.Format(format, 0); GameObject val12 = GUIManager.Instance.CreateText(text, (Transform)(object)val6, val10, val10, new Vector2(-30f, 25f), GUIManager.Instance.AveriaSerifBold, 16, Color.white, true, Color.black, 220f, 25f, true); Text component = val12.GetComponent<Text>(); SkillUiController.UnspentText = component; GameObject val13 = new GameObject("SkillsReworked_PrestigeIcon", new Type[2] { typeof(RectTransform), typeof(Image) }); RectTransform component2 = val13.GetComponent<RectTransform>(); ((Transform)component2).SetParent((Transform)(object)val6, false); component2.anchorMin = val11; component2.anchorMax = val11; component2.pivot = new Vector2(0f, 1f); component2.anchoredPosition = new Vector2(5f, 40f); component2.sizeDelta = new Vector2(32f, 32f); Image component3 = val13.GetComponent<Image>(); UiSpriteHelper.ApplyWorkbenchLevelStar(component3); GameObject val14 = GUIManager.Instance.CreateText("0", (Transform)(object)component2, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, GUIManager.Instance.AveriaSerifBold, 16, Color.black, true, Color.white, 32f, 32f, false); Text component4 = val14.GetComponent<Text>(); component4.alignment = (TextAnchor)4; SkillUiController.PrestigeText = component4; SkillUiController.PrestigeIconRoot = val13; string text2 = Localization.instance.Localize("$m2_sr_btn_prestige"); GameObject val15 = GUIManager.Instance.CreateButton(text2, (Transform)(object)val6, val9, val9, new Vector2(-40f, -20f), 80f, 28f); Button component5 = val15.GetComponent<Button>(); ButtonClickedEvent onClick = component5.onClick; object obj = <>O.<0>__OnPrestigeRequested; if (obj == null) { UnityAction val16 = SkillUiController.OnPrestigeRequested; <>O.<0>__OnPrestigeRequested = val16; obj = (object)val16; } ((UnityEvent)onClick).AddListener((UnityAction)obj); string text3 = Localization.instance.Localize("$m2_sr_btn_rebirth"); GameObject val17 = GUIManager.Instance.CreateButton(text3, (Transform)(object)val6, val8, val8, new Vector2(40f, -20f), 80f, 28f); Button component6 = val17.GetComponent<Button>(); ButtonClickedEvent onClick2 = component6.onClick; objec