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 Mayheim v0.3.4
plugins\ValheimMMO.dll
Decompiled 9 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Splatform; using TMPro; using UnityEngine; using UnityEngine.UI; using ValheimMMO.Cities; using ValheimMMO.Config; using ValheimMMO.Drops; using ValheimMMO.Dungeons; using ValheimMMO.Hunger; using ValheimMMO.InventorySlots; using ValheimMMO.Items; using ValheimMMO.Merchant; using ValheimMMO.Progression; using ValheimMMO.Pvp; using ValheimMMO.Quests; using ValheimMMO.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("assembly_guiutils")] [assembly: IgnoresAccessChecksTo("assembly_utils")] [assembly: IgnoresAccessChecksTo("assembly_valheim")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("ValheimMMO")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.3.4.0")] [assembly: AssemblyInformationalVersion("0.3.4")] [assembly: AssemblyProduct("ValheimMMO")] [assembly: AssemblyTitle("ValheimMMO")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.3.4.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ValheimMMO { [BepInPlugin("com.lucas.valheimmmo", "Mayheim", "0.3.4")] public class Plugin : BaseUnityPlugin { public const string PluginId = "com.lucas.valheimmmo"; public const string PluginName = "Mayheim"; public const string PluginVersion = "0.3.4"; internal static ManualLogSource Log; internal static Plugin Instance; private Harmony _harmony; private void Awake() { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; ModConfig.Bind(((BaseUnityPlugin)this).Config); ((Component)this).gameObject.AddComponent<MmoUI>(); ((Component)this).gameObject.AddComponent<MerchantSellUI>(); ((Component)this).gameObject.AddComponent<QuestNpcUI>(); ((Component)this).gameObject.AddComponent<QuestTracker>(); _harmony = new Harmony("com.lucas.valheimmmo"); PatchIsolated(); Log.LogInfo((object)"Mayheim v0.3.4 carregado."); } private void PatchIsolated() { int num = 0; int num2 = 0; Type[] typesFromAssembly = AccessTools.GetTypesFromAssembly(typeof(Plugin).Assembly); foreach (Type type in typesFromAssembly) { if (type.GetCustomAttributes(typeof(HarmonyPatch), inherit: true).Length != 0) { try { _harmony.CreateClassProcessor(type).Patch(); num++; } catch (Exception ex) { num2++; Log.LogError((object)("Falha ao aplicar patch " + type.FullName + ": " + ex.Message)); } } } Log.LogInfo((object)($"Patches aplicados: {num} classes" + ((num2 > 0) ? $", {num2} com falha (ver acima)" : "."))); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } } namespace ValheimMMO.UI { [HarmonyPatch(typeof(GameCamera), "UpdateMouseCapture")] internal static class GameCamera_UpdateMouseCapture_Patch { private static void Postfix() { if (QuestNpcUI.IsOpen || MmoUI.PanelOpen) { Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; } } } internal sealed class ClonedBar { public GameObject Root; public RectTransform Rect; public GuiBar[] Bars; public TMP_Text Text; public Animator Animator; public bool Alive => (Object)(object)Root != (Object)null; public static ClonedBar From(RectTransform source, string name, bool fixedText) { //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: 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_0105: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)source == (Object)null) { return null; } GameObject val = Object.Instantiate<GameObject>(((Component)source).gameObject, ((Transform)source).parent); ((Object)val).name = name; ClonedBar clonedBar = new ClonedBar { Root = val, Rect = val.GetComponent<RectTransform>(), Bars = val.GetComponentsInChildren<GuiBar>(true), Text = val.GetComponentInChildren<TMP_Text>(true), Animator = (val.GetComponent<Animator>() ?? val.GetComponentInChildren<Animator>(true)) }; if ((Object)(object)clonedBar.Text != (Object)null && fixedText) { TMP_Text text = clonedBar.Text; text.enableAutoSizing = false; text.fontSize = 15f; text.textWrappingMode = (TextWrappingModes)0; text.overflowMode = (TextOverflowModes)0; text.alignment = (TextAlignmentOptions)514; ((Graphic)text).color = Color.white; text.fontStyle = (FontStyles)(text.fontStyle | 1); RectTransform rectTransform = text.rectTransform; rectTransform.anchorMin = Vector2.zero; rectTransform.anchorMax = Vector2.one; rectTransform.offsetMin = new Vector2(8f, 0f); rectTransform.offsetMax = new Vector2(-8f, 0f); } val.SetActive(true); return clonedBar; } public void SetVisible(bool visible) { if (Alive) { if (Root.activeSelf != visible) { Root.SetActive(visible); } if (visible && (Object)(object)Animator != (Object)null) { Animator.SetBool("Visible", true); } } } public void SetLength(float size, float borderBuffer) { if (Alive) { size = Mathf.Ceil(size); Rect.SetSizeWithCurrentAnchors((Axis)0, size + borderBuffer); GuiBar[] bars = Bars; for (int i = 0; i < bars.Length; i++) { bars[i].SetWidth(size); } } } public void SetValue(float value, float max, Color color) { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) if (Alive) { for (int i = 0; i < Bars.Length; i++) { Bars[i].SetMaxValue(max); Bars[i].SetValue(Mathf.Clamp(value, 0f, max)); Bars[i].SetColor((i == 0) ? color : (color * new Color(0.55f, 0.55f, 0.55f, 1f))); } } } } internal static class HudBars { private static ClonedBar _xp; private static readonly Color XpColor = new Color(0.42f, 0.55f, 0.95f); internal static void Update(Hud hud) { //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)hud == (Object)null || (Object)(object)localPlayer == (Object)null) { return; } PlayerProgress playerProgress = PlayerProgress.Get(localPlayer); if (playerProgress == null) { return; } bool flag = ModConfig.ShowXpBar.Value && !InventoryGui.IsVisible(); if (_xp == null || !_xp.Alive) { if (!flag) { return; } _xp = ClonedBar.From(hud.m_staminaBar2Root, "MMO_XpBar", fixedText: true); if (_xp == null) { return; } } _xp.SetVisible(flag); if (flag) { _xp.Rect.anchoredPosition = new Vector2(ModConfig.XpBarOffsetX.Value, ModConfig.XpBarOffsetY.Value); _xp.SetLength(Mathf.Max(120f, ModConfig.XpBarWidth.Value), 16f); bool flag2 = playerProgress.Level >= ModConfig.MaxLevel.Value; float num = (flag2 ? 1f : playerProgress.LevelProgress); _xp.SetValue(num, 1f, XpColor); if ((Object)(object)_xp.Text != (Object)null) { _xp.Text.text = (flag2 ? $"Lv {playerProgress.Level} MAX" : $"Lv {playerProgress.Level} {playerProgress.Xp} / {playerProgress.XpForNextLevel} {num * 100f:0}%"); } } } } internal static class HudHungerBar { private static ClonedBar _bar; internal static void Update(Hud hud, Player player) { //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: 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_017d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)hud == (Object)null || (Object)(object)player == (Object)null || (Object)(object)hud.m_healthBarRoot == (Object)null) { return; } PlayerProgress playerProgress = PlayerProgress.Get(player); if (!ModConfig.ShowHungerBar.Value || !ModConfig.HungerEnabled.Value || playerProgress == null || !(playerProgress.Satiety >= 0f)) { if (_bar != null) { _bar.SetVisible(visible: false); } return; } HideFoodUi(hud); if (_bar == null || !_bar.Alive) { _bar = ClonedBar.From(hud.m_healthBarRoot, "MMO_HungerBar", fixedText: false); if (_bar == null) { return; } } _bar.SetVisible(visible: true); if ((Object)(object)hud.m_foodBarRoot != (Object)null) { ((Transform)_bar.Rect).position = ((Transform)hud.m_foodBarRoot).position; ((Transform)_bar.Rect).rotation = ((Transform)hud.m_foodBarRoot).rotation; } float max = HungerSystem.Max; HungerState s = HungerSystem.StateOf(playerProgress.Satiety); _bar.SetLength(max / 25f * 32f, 0f); _bar.SetValue(playerProgress.Satiety, max, HungerSystem.ColorOf(s)); if ((Object)(object)_bar.Text != (Object)null) { _bar.Text.text = Mathf.CeilToInt(playerProgress.Satiety).ToString(); } if ((Object)(object)hud.m_foodIcon != (Object)null) { ((Graphic)hud.m_foodIcon).color = HungerSystem.ColorOf(s); } } private static void HideFoodUi(Hud hud) { if (hud.m_foodBars != null) { Image[] foodBars = hud.m_foodBars; foreach (Image val in foodBars) { if ((Object)(object)val == (Object)null) { continue; } if (((Behaviour)val).enabled) { ((Behaviour)val).enabled = false; } Graphic[] componentsInChildren = ((Component)val).GetComponentsInChildren<Graphic>(true); foreach (Graphic val2 in componentsInChildren) { if ((Object)(object)val2 != (Object)null && ((Behaviour)val2).enabled) { ((Behaviour)val2).enabled = false; } } } } if (hud.m_foodIcons != null) { Image[] foodBars = hud.m_foodIcons; foreach (Image val3 in foodBars) { if ((Object)(object)val3 != (Object)null && ((Component)val3).gameObject.activeSelf) { ((Component)val3).gameObject.SetActive(false); } } } if (hud.m_foodTime != null) { TMP_Text[] foodTime = hud.m_foodTime; foreach (TMP_Text val4 in foodTime) { if ((Object)(object)val4 != (Object)null && ((Component)val4).gameObject.activeSelf) { ((Component)val4).gameObject.SetActive(false); } } } if ((Object)(object)hud.m_foodBaseBar != (Object)null && ((Component)hud.m_foodBaseBar).gameObject.activeSelf) { ((Component)hud.m_foodBaseBar).gameObject.SetActive(false); } if ((Object)(object)hud.m_foodText != (Object)null && ((Component)hud.m_foodText).gameObject.activeSelf) { ((Component)hud.m_foodText).gameObject.SetActive(false); } if ((Object)(object)hud.m_foodBarRoot != (Object)null && ((Component)hud.m_foodBarRoot).gameObject.activeSelf) { ((Component)hud.m_foodBarRoot).gameObject.SetActive(false); } object obj2; if (!((Object)(object)hud.m_healthPanel != (Object)null)) { RectTransform healthBarRoot = hud.m_healthBarRoot; Transform obj = ((healthBarRoot != null) ? ((Transform)healthBarRoot).parent : null); obj2 = ((obj is RectTransform) ? obj : null); } else { obj2 = hud.m_healthPanel; } RectTransform val5 = (RectTransform)obj2; if ((Object)(object)val5 != (Object)null) { for (int k = 0; k < ((Transform)val5).childCount; k++) { Transform child = ((Transform)val5).GetChild(k); string name = ((Object)child).name; bool num = name.Length == 5 && name.StartsWith("food", StringComparison.OrdinalIgnoreCase) && char.IsDigit(name[4]); bool flag = name.StartsWith("foodicon (", StringComparison.OrdinalIgnoreCase); if ((num || flag) && ((Component)child).gameObject.activeSelf) { ((Component)child).gameObject.SetActive(false); } } } if ((Object)(object)hud.m_foodIcon != (Object)null) { if (!((Component)hud.m_foodIcon).gameObject.activeSelf) { ((Component)hud.m_foodIcon).gameObject.SetActive(true); } if (!((Behaviour)hud.m_foodIcon).enabled) { ((Behaviour)hud.m_foodIcon).enabled = true; } } } } [HarmonyPatch(typeof(Hud), "Update")] internal static class Hud_Update_BarsPatch { private static void Postfix(Hud __instance) { HudBars.Update(__instance); } } [HarmonyPatch(typeof(Hud), "UpdateFood")] internal static class Hud_UpdateFood_HungerPatch { private static void Postfix(Hud __instance, Player player) { HudHungerBar.Update(__instance, player); } } public class MmoUI : MonoBehaviour { internal static MmoUI Instance; internal static bool PanelOpen; private const float PanelWidth = 470f; private Rect _window = new Rect(80f, 80f, 470f, 0f); private Vector2 _equipScroll; private bool _showEquipList = true; private string _respecReason; private static readonly Color BgColor = new Color(0.075f, 0.06f, 0.045f, 0.94f); private static readonly Color BorderColor = new Color(0.72f, 0.58f, 0.3f, 1f); private static readonly Color TextColor = new Color(0.92f, 0.86f, 0.7f, 1f); private static readonly Color GoldColor = new Color(0.95f, 0.78f, 0.4f, 1f); private static readonly Color MutedColor = new Color(0.65f, 0.6f, 0.5f, 1f); private static readonly Color ItemBonusColor = new Color(1f, 0.62f, 0.2f, 1f); private static readonly Color ButtonColor = new Color(0.22f, 0.17f, 0.11f, 1f); private static readonly Color ButtonHover = new Color(0.32f, 0.25f, 0.15f, 1f); private static readonly Color BarBg = new Color(0f, 0f, 0f, 0.6f); private static readonly Color XpFill = new Color(0.42f, 0.55f, 0.95f, 1f); private static GUISkin _skin; private static Texture2D _white; private static Font _norse; private static bool _fontSearched; private static string Gold => ColorUtility.ToHtmlStringRGB(GoldColor); private static string Muted => ColorUtility.ToHtmlStringRGB(MutedColor); private static string Bonus => ColorUtility.ToHtmlStringRGB(ItemBonusColor); private static Texture2D White { get { //IL_000d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_white == (Object)null) { _white = Solid(Color.white); } return _white; } } private static Font NorseFont { get { if (_fontSearched) { return _norse; } _fontSearched = true; try { Font[] array = Resources.FindObjectsOfTypeAll<Font>(); foreach (Font val in array) { if ((Object)(object)val != (Object)null && ((Object)val).name.IndexOf("norse", StringComparison.OrdinalIgnoreCase) >= 0) { _norse = val; break; } } } catch { } return _norse; } } internal static Texture2D WhiteTex => White; internal static Color GoldC => GoldColor; internal static Color MutedC => MutedColor; internal static Color BorderC => BorderColor; internal static Color BonusC => ItemBonusColor; internal static GUISkin Skin { get { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown //IL_0060: 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_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Expected O, but got Unknown //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Expected O, but got Unknown //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Expected O, but got Unknown //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Expected O, but got Unknown //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Expected O, but got Unknown //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Expected O, but got Unknown //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Expected O, but got Unknown //IL_025e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_skin != (Object)null) { return _skin; } GUISkin val = ScriptableObject.CreateInstance<GUISkin>(); ((Object)val).hideFlags = (HideFlags)61; GUISkin skin = GUI.skin; Font norseFont = NorseFont; val.window = new GUIStyle(skin.window) { padding = new RectOffset(16, 16, 28, 14), fontSize = 16, alignment = (TextAnchor)1 }; Texture2D background = Bordered(BgColor, BorderColor); val.window.normal.background = background; val.window.onNormal.background = background; val.window.normal.textColor = GoldColor; val.window.onNormal.textColor = GoldColor; val.window.border = new RectOffset(3, 3, 3, 3); if ((Object)(object)norseFont != (Object)null) { val.window.font = norseFont; } val.label = new GUIStyle(skin.label) { fontSize = 14, richText = true }; val.label.normal.textColor = TextColor; if ((Object)(object)norseFont != (Object)null) { val.label.font = norseFont; } val.button = new GUIStyle(skin.button) { fontSize = 14, richText = true }; val.button.normal.background = Bordered(ButtonColor, BorderColor, 12, 1); val.button.hover.background = Bordered(ButtonHover, GoldColor, 12, 1); val.button.active.background = Bordered(ButtonHover, GoldColor, 12, 1); val.button.normal.textColor = TextColor; val.button.hover.textColor = GoldColor; val.button.active.textColor = GoldColor; val.button.border = new RectOffset(2, 2, 2, 2); if ((Object)(object)norseFont != (Object)null) { val.button.font = norseFont; } val.scrollView = new GUIStyle(skin.scrollView); val.verticalScrollbar = new GUIStyle(skin.verticalScrollbar); val.verticalScrollbarThumb = new GUIStyle(skin.verticalScrollbarThumb); val.verticalScrollbarThumb.normal.background = Solid(BorderColor); _skin = val; return _skin; } } private static bool AttachedToInventory { get { if (ModConfig.PanelOpensWithInventory.Value && InventoryGui.IsVisible()) { return !PanelOpen; } return false; } } internal static bool Visible { get { if ((Object)(object)Player.m_localPlayer != (Object)null) { if (!PanelOpen) { return AttachedToInventory; } return true; } return false; } } private static Texture2D Solid(Color c) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown Texture2D val = new Texture2D(1, 1, (TextureFormat)4, false); val.SetPixel(0, 0, c); val.Apply(); ((Object)val).hideFlags = (HideFlags)61; return val; } private static Texture2D Bordered(Color fill, Color border, int size = 12, int thickness = 2) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Expected O, but got Unknown //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(size, size, (TextureFormat)4, false); for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { bool flag = j < thickness || i < thickness || j >= size - thickness || i >= size - thickness; val.SetPixel(j, i, flag ? border : fill); } } val.Apply(); ((Object)val).hideFlags = (HideFlags)61; return val; } private void Awake() { Instance = this; } private void Update() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut value = ModConfig.OpenPanelKey.Value; if (((KeyboardShortcut)(ref value)).IsDown() && CanShowUi()) { PanelOpen = !PanelOpen; } if (PanelOpen && (Object)(object)Player.m_localPlayer == (Object)null) { PanelOpen = false; } } private static bool CanShowUi() { if ((Object)(object)Player.m_localPlayer == (Object)null) { return false; } if ((Object)(object)Chat.instance != (Object)null && Chat.instance.HasFocus()) { return false; } if (Console.IsVisible() || TextInput.IsVisible()) { return false; } if (Menu.IsVisible() || InventoryGui.IsVisible()) { return false; } return true; } private void OnGUI() { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Expected O, but got Unknown //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Expected O, but got Unknown //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) if (Visible) { GUISkin skin = GUI.skin; Matrix4x4 matrix = GUI.matrix; GUI.skin = Skin; float num = Mathf.Clamp((float)Screen.height / 1080f, 0.75f, 2.5f); GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(num, num, 1f)); float num2 = (float)Screen.width / num; if (AttachedToInventory) { Rect val = default(Rect); ((Rect)(ref val))..ctor((num2 - 470f) * 0.5f, 34f, 470f, 0f); GUILayout.Window(((Object)this).GetInstanceID(), val, new WindowFunction(DrawPanel), "PERSONAGEM", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(470f) }); } else { _window = GUILayout.Window(((Object)this).GetInstanceID(), _window, new WindowFunction(DrawPanel), "PERSONAGEM", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(470f) }); } GUI.matrix = matrix; GUI.skin = skin; } } private void DrawPanel(int id) { //IL_027e: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; PlayerProgress playerProgress = PlayerProgress.Get(localPlayer); if (playerProgress == null) { return; } bool flag = playerProgress.Level >= ModConfig.MaxLevel.Value; GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label("<size=15>" + localPlayer.GetPlayerName() + "</size>", Array.Empty<GUILayoutOption>()); GUILayout.FlexibleSpace(); GUILayout.Label($"<size=20><b><color=#{Gold}>Level {playerProgress.Level}</color></b></size>" + (flag ? "" : $"<size=12><color=#{Muted}> / {ModConfig.MaxLevel.Value}</color></size>"), Array.Empty<GUILayoutOption>()); GUILayout.EndHorizontal(); GUILayout.Space(6f); DrawXpBar(playerProgress, flag); if (ModConfig.PvpEnabled.Value) { float num = Karma.Local(localPlayer); string arg = ((num >= ModConfig.WantedThreshold.Value) ? "E04A3A" : Muted); GUILayout.Label($"<size=12><color=#{arg}>Karma {num:0.0} · {Karma.StatusName(num)}</color></size>", Array.Empty<GUILayoutOption>()); } GUILayout.Space(12f); Separator(); GUILayout.Space(8f); DrawAttributes(localPlayer, playerProgress); GUILayout.Space(10f); Separator(); GUILayout.Space(8f); DrawEquipment(localPlayer); GUILayout.Space(10f); Separator(); GUILayout.Space(8f); string reason; bool flag2 = PlayerProgress.CanRespec(localPlayer, out reason); GUI.enabled = ModConfig.RespecEnabled.Value && playerProgress.SpentPoints > 0 && flag2; if (GUILayout.Button("Redistribuir todos os pontos", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(26f) })) { if (playerProgress.RespecAll(localPlayer, out _respecReason)) { RefreshStats(localPlayer); ((Character)localPlayer).Message((MessageType)2, "Pontos redistribuidos", 0, (Sprite)null); } else { ((Character)localPlayer).Message((MessageType)2, _respecReason, 0, (Sprite)null); } } GUI.enabled = true; if (!flag2 && ModConfig.RespecEnabled.Value) { GUILayout.Label("<size=12><color=#" + Muted + "><i>" + reason + "</i></color></size>", Array.Empty<GUILayoutOption>()); } if (PanelOpen) { GUILayout.Space(6f); if (GUILayout.Button("Fechar", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(24f) })) { PanelOpen = false; } GUI.DragWindow(new Rect(0f, 0f, 10000f, 26f)); } } private void DrawAttributes(Player player, PlayerProgress prog) { int unspentPoints = prog.UnspentPoints; GUILayout.Label((unspentPoints > 0) ? string.Format("<color=#{0}><b>{1}</b></color> ponto{2} para distribuir", Gold, unspentPoints, (unspentPoints == 1) ? "" : "s") : ("<color=#" + Muted + ">Nenhum ponto disponivel</color>"), Array.Empty<GUILayoutOption>()); GUILayout.Space(4f); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label("<size=11><color=#" + Muted + ">ATRIBUTO</color></size>", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(126f) }); GUILayout.Label("<size=11><color=#" + Muted + ">PONTOS</color></size>", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) }); GUILayout.Space(62f); GUILayout.Label("<size=11><color=#" + Muted + ">ITENS</color></size>", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(48f) }); GUILayout.FlexibleSpace(); GUILayout.Label("<size=11><color=#" + Muted + ">EFEITO</color></size>", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(130f) }); GUILayout.EndHorizontal(); prog.ComputeStats(player, out var hp, out var stamina, out var eitr); float maxCarryWeight = player.GetMaxCarryWeight(); int[] array = ItemBonuses.TotalEquipped((Humanoid)(object)player); Attr[] all = AttrInfo.All; foreach (Attr attr in all) { int num = (int)attr; GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) }); GUILayout.Label("<b>" + AttrInfo.DisplayName(attr) + "</b>", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(126f) }); GUILayout.Label($"<size=16>{prog.Spent[num]}</size>", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) }); GUI.enabled = unspentPoints > 0; if (GUILayout.Button("+", (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(28f), GUILayout.Height(24f) })) { prog.TrySpend(attr, player); RefreshStats(player); } GUI.enabled = prog.Spent[num] > 0 && ModConfig.RespecEnabled.Value; if (GUILayout.Button("-", (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(28f), GUILayout.Height(24f) })) { if (!prog.TryRefund(attr, player, out _respecReason)) { ((Character)player).Message((MessageType)2, _respecReason, 0, (Sprite)null); } else { RefreshStats(player); } } GUI.enabled = true; GUILayout.Label((array[num] > 0) ? $"<color=#{Bonus}>+{array[num]}</color>" : ("<color=#" + Muted + ">-</color>"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(48f) }); GUILayout.FlexibleSpace(); GUILayout.Label("<color=#" + Muted + ">" + AttrInfo.Effect(attr) + "</color> <b>" + ValueFor(attr, hp, stamina, eitr, maxCarryWeight) + "</b>", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(130f) }); GUILayout.EndHorizontal(); } } private void DrawEquipment(Player player) { //IL_04f5: Unknown result type (might be due to invalid IL or missing references) //IL_0525: 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) Inventory inventory = ((Humanoid)player).GetInventory(); if (inventory == null) { return; } List<ItemData> equippedItems = inventory.GetEquippedItems(); GUILayout.Label(string.Format("<b>Equipamento</b> <size=12><color=#{0}>{1} peca{2}</color></size>", Muted, equippedItems.Count, (equippedItems.Count == 1) ? "" : "s"), Array.Empty<GUILayoutOption>()); GUILayout.Space(2f); EquipmentRow.Slot[] slots = EquipmentRow.Slots; foreach (EquipmentRow.Slot slot in slots) { ItemData val = EquipmentRow.ItemIn(inventory, slot); GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(26f) }); GUILayout.Label("<size=12><color=#" + Muted + ">" + slot.Name + "</color></size>", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(78f) }); if (val == null) { GUILayout.Label("<size=12><color=#" + Muted + ">vazio</color></size>", Array.Empty<GUILayoutOption>()); GUILayout.EndHorizontal(); continue; } DrawIcon(val, 24f); GUILayout.Space(6f); string text = Localization.instance.Localize(val.m_shared.m_name); string text2 = ((val.m_shared.m_maxQuality > 1) ? $" <size=11><color=#{Muted}>q{val.m_quality}</color></size>" : ""); string text3 = ((val.m_stack > 1) ? $" <size=11><color=#{Muted}>x{val.m_stack}</color></size>" : ""); GUILayout.Label(text + text2 + text3, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(190f) }); int[] bonuses = ItemBonuses.For(val); GUILayout.Label(ItemBonuses.Any(bonuses) ? ("<size=12><color=#" + Bonus + ">" + ItemBonuses.Describe(bonuses) + "</color></size>") : ("<size=12><color=#" + Muted + ">-</color></size>"), Array.Empty<GUILayoutOption>()); GUILayout.FlexibleSpace(); if (GUILayout.Button("Tirar", (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(52f), GUILayout.Height(22f) })) { ((Humanoid)player).UnequipItem(val, true); RefreshStats(player); } GUILayout.EndHorizontal(); } List<ItemData> list = EquipmentRow.OverflowItems(inventory); if (list.Count > 0) { GUILayout.Space(4f); GUILayout.Label($"<size=12><color=#{Muted}>Sem espaco na mochila ({list.Count}): abra espaco e clique em Guardar.</color></size>", Array.Empty<GUILayoutOption>()); foreach (ItemData item in list) { GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(26f) }); DrawIcon(item, 22f); GUILayout.Space(6f); GUILayout.Label(Localization.instance.Localize(item.m_shared.m_name), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(190f) }); GUILayout.FlexibleSpace(); if (GUILayout.Button("Guardar", (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(70f), GUILayout.Height(22f) }) && !EquipmentRow.TryStore(inventory, item)) { ((Character)player).Message((MessageType)2, "Mochila cheia.", 0, (Sprite)null); } if (GUILayout.Button("Equipar", (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(70f), GUILayout.Height(22f) })) { ((Humanoid)player).EquipItem(item, true); RefreshStats(player); } GUILayout.EndHorizontal(); } } GUILayout.Space(6f); List<ItemData> list2 = new List<ItemData>(); foreach (ItemData allItem in inventory.GetAllItems()) { if (allItem != null && allItem.IsEquipable() && !allItem.m_equipped) { list2.Add(allItem); } } list2.Sort(delegate(ItemData a, ItemData b) { int num = SlotOrder(a).CompareTo(SlotOrder(b)); return (num == 0) ? string.Compare(a.m_shared.m_name, b.m_shared.m_name, StringComparison.Ordinal) : num; }); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if (GUILayout.Button(_showEquipList ? "▾ Equipar da mochila" : "▸ Equipar da mochila", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(22f) })) { _showEquipList = !_showEquipList; } GUILayout.Label(string.Format("<size=12><color=#{0}>{1} disponivel{2}</color></size>", Muted, list2.Count, (list2.Count == 1) ? "" : "is"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(110f) }); GUILayout.EndHorizontal(); if (!_showEquipList || list2.Count == 0) { return; } _equipScroll = GUILayout.BeginScrollView(_equipScroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(Mathf.Min(160f, 28f * (float)list2.Count + 6f)) }); foreach (ItemData item2 in list2) { GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(26f) }); DrawIcon(item2, 22f); GUILayout.Space(6f); string text4 = Localization.instance.Localize(item2.m_shared.m_name); string text5 = ((item2.m_shared.m_maxQuality > 1) ? $" <size=11><color=#{Muted}>q{item2.m_quality}</color></size>" : ""); int[] bonuses2 = ItemBonuses.For(item2); string text6 = (ItemBonuses.Any(bonuses2) ? (" <size=12><color=#" + Bonus + ">" + ItemBonuses.Describe(bonuses2) + "</color></size>") : ""); if (GUILayout.Button("<size=13>" + text4 + text5 + text6 + "</size>", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(24f) })) { ((Humanoid)player).EquipItem(item2, true); RefreshStats(player); } GUILayout.EndHorizontal(); } GUILayout.EndScrollView(); } private static void DrawXpBar(PlayerProgress prog, bool atCap) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_001f: 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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Expected O, but got Unknown //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) Rect rect = GUILayoutUtility.GetRect(1f, 20f, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); GUI.color = BorderColor; GUI.DrawTexture(new Rect(((Rect)(ref rect)).x - 1f, ((Rect)(ref rect)).y - 1f, ((Rect)(ref rect)).width + 2f, ((Rect)(ref rect)).height + 2f), (Texture)(object)White); GUI.color = BarBg; GUI.DrawTexture(rect, (Texture)(object)White); float num = (atCap ? 1f : prog.LevelProgress); GUI.color = XpFill; GUI.DrawTexture(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y, ((Rect)(ref rect)).width * num, ((Rect)(ref rect)).height), (Texture)(object)White); GUI.color = Color.white; GUIStyle val = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)4, fontSize = 12, fontStyle = (FontStyle)1 }; val.normal.textColor = Color.white; string text = (atCap ? "LEVEL MAXIMO" : $"{prog.Xp} / {prog.XpForNextLevel} XP ({num * 100f:0}%)"); GUI.Label(rect, text, val); } private static void Separator() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) Rect rect = GUILayoutUtility.GetRect(1f, 1f, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); GUI.color = new Color(BorderColor.r, BorderColor.g, BorderColor.b, 0.5f); GUI.DrawTexture(rect, (Texture)(object)White); GUI.color = Color.white; } private static void DrawIcon(ItemData item, float size) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) Rect rect = GUILayoutUtility.GetRect(size, size, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(size), GUILayout.Height(size) }); Sprite val = null; try { val = item.GetIcon(); } catch { } if (!((Object)(object)val == (Object)null) && !((Object)(object)val.texture == (Object)null)) { Texture2D texture = val.texture; Rect textureRect = default(Rect); try { textureRect = val.textureRect; } catch { ((Rect)(ref textureRect))..ctor(0f, 0f, (float)((Texture)texture).width, (float)((Texture)texture).height); } Rect val2 = default(Rect); ((Rect)(ref val2))..ctor(((Rect)(ref textureRect)).x / (float)((Texture)texture).width, ((Rect)(ref textureRect)).y / (float)((Texture)texture).height, ((Rect)(ref textureRect)).width / (float)((Texture)texture).width, ((Rect)(ref textureRect)).height / (float)((Texture)texture).height); GUI.DrawTextureWithTexCoords(rect, (Texture)(object)texture, val2, true); } } private static int SlotOrder(ItemData item) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: 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_000e: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected I4, but got Unknown ItemType itemType = item.m_shared.m_itemType; return (itemType - 3) switch { 0 => 0, 11 => 0, 19 => 0, 1 => 0, 2 => 1, 3 => 2, 4 => 3, 8 => 4, 14 => 5, 15 => 6, 21 => 7, 12 => 8, 16 => 9, _ => 20, }; } private static string SlotName(ItemData item) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: 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_000e: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected I4, but got Unknown ItemType itemType = item.m_shared.m_itemType; return (itemType - 3) switch { 0 => "Arma", 11 => "Arma 2M", 19 => "Arma 2M", 1 => "Arco", 2 => "Escudo", 3 => "Cabeca", 4 => "Peito", 8 => "Pernas", 14 => "Capa", 15 => "Utilidade", 21 => "Amuleto", 12 => "Tocha", 16 => "Ferramenta", 6 => "Municao", _ => ((object)Unsafe.As<ItemType, ItemType>(ref item.m_shared.m_itemType)/*cast due to .constrained prefix*/).ToString(), }; } private static string ValueFor(Attr attr, float hp, float stam, float eitr, float carry) { return attr switch { Attr.Vitality => $"{hp:0}", Attr.Endurance => $"{stam:0}", Attr.Spirit => $"{eitr:0}", Attr.Conditioning => $"{carry:0} kg", _ => "", }; } internal static void RefreshStats(Player player) { if (!((Object)(object)player == (Object)null)) { player.UpdateFood(0f, true); } } } [HarmonyPatch(typeof(Player), "TakeInput")] internal static class Player_TakeInput_Patch { private static void Postfix(ref bool __result) { if (MmoUI.PanelOpen) { __result = false; } } } } namespace ValheimMMO.Quests { internal static class QuestListUI { public static void Draw(Player player, int tier, string header) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) string text = ColorUtility.ToHtmlStringRGB(MmoUI.MutedC); string text2 = ColorUtility.ToHtmlStringRGB(MmoUI.GoldC); string text3 = ColorUtility.ToHtmlStringRGB(MmoUI.BonusC); GUILayout.Label("<size=12><color=#" + text + ">" + header + "</color></size>", Array.Empty<GUILayoutOption>()); GUILayout.Space(6f); List<Quest> list = QuestSystem.TodayFor(player, tier); if (list.Count == 0) { GUILayout.Label("<color=#" + text + ">Sem missoes hoje.</color>", Array.Empty<GUILayoutOption>()); } foreach (Quest item in list) { GUILayout.BeginVertical(Array.Empty<GUILayoutOption>()); string text4 = (item.Claimed ? ("<color=#" + text + ">feita hoje</color>") : ((!item.Accepted) ? ("<color=#" + text + ">disponivel</color>") : (item.Complete ? ("<color=#" + text2 + ">completa - fale comigo</color>") : $"<color=#{text2}>{item.Progress}/{item.Required}</color>"))); GUILayout.Label("<size=14><b>" + item.Title + "</b></size> <size=12>" + text4 + "</size>", Array.Empty<GUILayoutOption>()); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label($"<size=12><color=#{text}>Recompensa:</color> <color=#{text3}>{item.GoldReward}</color> moedas, <color=#{text3}>{item.XpReward}</color> XP</size>", Array.Empty<GUILayoutOption>()); GUILayout.FlexibleSpace(); string message = null; if (item.Claimed) { GUI.enabled = false; GUILayout.Button("Feita hoje", (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(110f), GUILayout.Height(22f) }); GUI.enabled = true; } else if (!item.Accepted) { if (GUILayout.Button("Aceitar", (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(110f), GUILayout.Height(22f) })) { QuestSystem.Accept(player, item, out message); } } else if (item.Complete) { if (GUILayout.Button("Concluir", (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(110f), GUILayout.Height(22f) })) { QuestSystem.Claim(player, item, out message); } } else { if (item.Kind == QuestKind.Deliver && GUILayout.Button("Entregar", (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(110f), GUILayout.Height(22f) })) { QuestSystem.Deliver(player, item, out message); } if (GUILayout.Button("Abandonar", (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(90f), GUILayout.Height(22f) })) { QuestSystem.Abandon(player, item, out message); } } if (message != null) { ((Character)player).Message((MessageType)2, message, 0, (Sprite)null); } GUILayout.EndHorizontal(); GUILayout.Space(8f); GUILayout.EndVertical(); } } } public class QuestNpcUI : MonoBehaviour { internal static bool IsOpen; private static int _tier; private const float W = 560f; public static void Open(int tier) { _tier = tier; IsOpen = true; } private void Update() { if (IsOpen && ((Object)(object)Player.m_localPlayer == (Object)null || Input.GetKeyDown((KeyCode)27))) { IsOpen = false; } } private void OnGUI() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //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_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Expected O, but got Unknown //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) if (IsOpen && !((Object)(object)Player.m_localPlayer == (Object)null)) { GUISkin skin = GUI.skin; Matrix4x4 matrix = GUI.matrix; GUI.skin = MmoUI.Skin; float num = Mathf.Clamp((float)Screen.height / 1080f, 0.75f, 2.5f); GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(num, num, 1f)); float num2 = (float)Screen.width / num; CityDef cityDef = CitySystem.ByTier(_tier); string text = ((cityDef != null) ? ("MISSOES - " + cityDef.Name.ToUpperInvariant()) : "MISSOES"); GUILayout.Window(((Object)this).GetInstanceID(), new Rect((num2 - 560f) * 0.5f, 120f, 560f, 0f), new WindowFunction(Draw), text, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(560f) }); GUI.matrix = matrix; GUI.skin = skin; } } private void Draw(int id) { QuestListUI.Draw(Player.m_localPlayer, _tier, $"Dia {QuestSystem.CurrentDay()} · aceite, cumpra e volte aqui para concluir. Cada missao vale uma vez por dia; amanha troca. Recompensa sempre em ouro."); GUILayout.Space(4f); if (GUILayout.Button("Fechar", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(24f) })) { IsOpen = false; } } } [HarmonyPatch(typeof(Player), "TakeInput")] internal static class Player_TakeInput_QuestNpcPatch { private static void Postfix(ref bool __result) { if (QuestNpcUI.IsOpen) { __result = false; } } } internal enum QuestKind { Kill, Deliver, DungeonBoss } internal sealed class Quest { public int Tier; public int Index; public QuestKind Kind; public string Target; public string TargetName; public int Required; public int Progress; public bool Accepted; public bool Claimed; public int GoldReward; public long XpReward; public bool Complete => Progress >= Required; public bool Active { get { if (Accepted) { return !Claimed; } return false; } } public string Title => Kind switch { QuestKind.Kill => $"Mate {Required}x {TargetName}", QuestKind.Deliver => $"Entregue {Required}x {TargetName}", QuestKind.DungeonBoss => "Derrote o boss de dungeon: " + TargetName, _ => "", }; public string ShortTitle => Kind switch { QuestKind.Kill => TargetName ?? "", QuestKind.Deliver => "Entregar " + TargetName, QuestKind.DungeonBoss => "Boss: " + TargetName, _ => "", }; } internal static class QuestSystem { private sealed class DayCache { public int Day; public List<Quest> List; } public const int MaxTier = 7; private static readonly string[][] KillPools = new string[7][] { new string[4] { "Greyling", "Boar", "Neck", "Deer" }, new string[5] { "Greydwarf", "Skeleton", "Greydwarf_Shaman", "Troll", "Ghost" }, new string[6] { "Draugr", "Blob", "Leech", "Wraith", "Abomination", "Surtling" }, new string[5] { "Wolf", "Fenring", "Hatchling", "StoneGolem", "Ulv" }, new string[5] { "Goblin", "Deathsquito", "Lox", "GoblinShaman", "GoblinBrute" }, new string[5] { "Seeker", "Tick", "Gjall", "Dverger", "SeekerBrute" }, new string[5] { "Charred_Melee", "Charred_Archer", "Asksvin", "Morgen", "Volture" } }; private static readonly string[][] DeliverPools = new string[7][] { new string[6] { "Wood", "Stone", "Resin", "LeatherScraps", "RawMeat", "Raspberry" }, new string[6] { "FineWood", "CopperOre", "TinOre", "Bronze", "TrollHide", "Coal" }, new string[6] { "IronScrap", "Guck", "Bloodbag", "Entrails", "Turnip", "Ooze" }, new string[6] { "WolfPelt", "Silver", "Obsidian", "FreezeGland", "Crystal", "Onion" }, new string[6] { "BlackMetalScrap", "Barley", "Flax", "LoxPelt", "Needle", "Tar" }, new string[6] { "Carapace", "YggdrasilWood", "Sap", "Softtissue", "BlackMarble", "Mandible" }, new string[5] { "FlametalOreNew", "CharredBone", "Grausten", "Blackwood", "AskHide" } }; private static readonly Dictionary<int, DayCache> Cache = new Dictionary<int, DayCache>(); public static int CurrentDay() { if (!((Object)(object)EnvMan.instance != (Object)null)) { return 0; } return EnvMan.instance.GetDay(); } private static string KeyFor(int tier) { return $"mmo.quests.{tier}"; } public static List<Quest> TodayFor(Player player, int tier) { if (!ModConfig.QuestsEnabled.Value || (Object)(object)player == (Object)null) { return new List<Quest>(); } tier = Mathf.Clamp(tier, 1, KillPools.Length); int num = tier - 1; int num2 = CurrentDay(); if (Cache.TryGetValue(tier, out var value) && value.Day == num2) { if (value.List.Count > 0 && value.List[0].Progress == 0 && !value.List[0].Accepted) { LoadProgress(player, tier, value.List); } return value.List; } Random random = new Random((int)((((Object)(object)ZNet.instance != (Object)null) ? ZNet.instance.GetWorldUID() : 0) ^ ((long)num2 * 7919L) ^ ((long)tier * 104729L))); List<Quest> list = new List<Quest>(); string text = PickExisting(random, KillPools[num], IsCreature); if (text != null) { Character component = ZNetScene.instance.GetPrefab(text).GetComponent<Character>(); float num3 = Mathf.Max(1f, component.m_health); int num4 = 8 + random.Next(0, 8); int num5 = Mathf.CeilToInt(Mathf.Pow(num3, 0.6f) * (float)num4 * 1.5f * ModConfig.QuestRewardMultiplier.Value); list.Add(new Quest { Tier = tier, Index = 0, Kind = QuestKind.Kill, Target = text, TargetName = Localization.instance.Localize(component.m_name), Required = num4, GoldReward = num5, XpReward = (long)num5 * 3L }); } string text2 = PickExisting(random, DeliverPools[num], IsItem); if (text2 != null) { int num6 = 10 + random.Next(0, 11); int num7 = Mathf.CeilToInt((float)(MerchantPricing.PriceOf(text2) * num6) * 1.5f * ModConfig.QuestRewardMultiplier.Value); list.Add(new Quest { Tier = tier, Index = 1, Kind = QuestKind.Deliver, Target = text2, TargetName = Localization.instance.Localize(ObjectDB.instance.GetItemPrefab(text2).GetComponent<ItemDrop>().m_itemData.m_shared.m_name), Required = num6, GoldReward = num7, XpReward = (long)num7 * 3L }); } DungeonTier dungeonTier = DungeonBosses.TierById(Mathf.Clamp(tier, 1, DungeonBosses.Tiers.Length)); if (dungeonTier != null) { int num8 = Mathf.CeilToInt((float)DungeonBosses.GoldFor(dungeonTier) * 0.5f * ModConfig.QuestRewardMultiplier.Value); list.Add(new Quest { Tier = tier, Index = 2, Kind = QuestKind.DungeonBoss, Target = dungeonTier.Id.ToString(), TargetName = dungeonTier.Title, Required = 1, GoldReward = num8, XpReward = (long)num8 * 3L }); } Cache[tier] = new DayCache { Day = num2, List = list }; LoadProgress(player, tier, list); return list; } public static List<Quest> Active(Player player) { List<Quest> list = new List<Quest>(); if ((Object)(object)player == (Object)null || !ModConfig.QuestsEnabled.Value) { return list; } for (int i = 1; i <= 7; i++) { foreach (Quest item in TodayFor(player, i)) { if (item.Active) { list.Add(item); } } } return list; } public static void ClearCache() { Cache.Clear(); } private static bool IsCreature(string name) { ZNetScene instance = ZNetScene.instance; object obj; if (instance == null) { obj = null; } else { GameObject prefab = instance.GetPrefab(name); obj = ((prefab != null) ? prefab.GetComponent<Character>() : null); } return (Object)obj != (Object)null; } private static bool IsItem(string name) { ObjectDB instance = ObjectDB.instance; object obj; if (instance == null) { obj = null; } else { GameObject itemPrefab = instance.GetItemPrefab(name); obj = ((itemPrefab != null) ? itemPrefab.GetComponent<ItemDrop>() : null); } return (Object)obj != (Object)null; } private static string PickExisting(Random rng, string[] pool, Func<string, bool> exists) { List<string> list = new List<string>(); foreach (string text in pool) { if (exists(text)) { list.Add(text); } } if (list.Count != 0) { return list[rng.Next(list.Count)]; } return null; } private static void LoadProgress(Player player, int tier, List<Quest> quests) { foreach (Quest quest in quests) { quest.Progress = 0; quest.Claimed = false; quest.Accepted = false; } if (!player.m_customData.TryGetValue(KeyFor(tier), out var value) || string.IsNullOrEmpty(value)) { return; } string[] array = value.Split('|'); if (array.Length < 1 || !int.TryParse(array[0], out var result) || result != CurrentDay()) { return; } foreach (Quest quest2 in quests) { int num = 1 + quest2.Index * 3; if (num + 2 < array.Length) { quest2.Accepted = array[num] == "1"; int.TryParse(array[num + 1], out quest2.Progress); quest2.Claimed = array[num + 2] == "1"; } } } private static void SaveProgress(Player player, int tier) { if (!Cache.TryGetValue(tier, out var value)) { return; } List<Quest> list = value.List; List<string> list2 = new List<string> { CurrentDay().ToString(CultureInfo.InvariantCulture) }; int idx; for (idx = 0; idx < 3; idx++) { Quest quest = list.Find((Quest x) => x.Index == idx); list2.Add((quest != null && quest.Accepted) ? "1" : "0"); list2.Add((quest?.Progress ?? 0).ToString(CultureInfo.InvariantCulture)); list2.Add((quest != null && quest.Claimed) ? "1" : "0"); } player.m_customData[KeyFor(tier)] = string.Join("|", list2); } public static bool Accept(Player player, Quest q, out string message) { message = null; if (q.Accepted || q.Claimed) { return false; } int count = Active(player).Count; int num = Mathf.Max(1, ModConfig.QuestMaxActive.Value); if (count >= num) { message = $"Voce ja tem {count} missoes em andamento (maximo {num})."; return false; } q.Accepted = true; SaveProgress(player, q.Tier); message = "Missao aceita: " + q.Title; return true; } public static bool Abandon(Player player, Quest q, out string message) { message = null; if (!q.Active) { return false; } q.Accepted = false; q.Progress = 0; SaveProgress(player, q.Tier); message = "Missao abandonada."; return true; } public static void OnKill(string victimPrefab, int dungeonTier) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || !ModConfig.QuestsEnabled.Value) { return; } for (int i = 1; i <= KillPools.Length; i++) { List<Quest> list = TodayFor(localPlayer, i); bool flag = false; foreach (Quest item in list) { if (item.Active && !item.Complete && ((item.Kind == QuestKind.Kill && item.Target == victimPrefab) || (item.Kind == QuestKind.DungeonBoss && dungeonTier > 0 && item.Target == dungeonTier.ToString()))) { item.Progress++; flag = true; if (item.Complete) { ((Character)localPlayer).Message((MessageType)2, "Missao completa: " + item.Title + ". Volte ao emissario.", 0, (Sprite)null); } else { ((Character)localPlayer).Message((MessageType)1, $"{item.ShortTitle}: {item.Progress}/{item.Required}", 0, (Sprite)null); } } } if (flag) { SaveProgress(localPlayer, i); } } } public static bool Deliver(Player player, Quest q, out string message) { message = null; if (q.Kind != QuestKind.Deliver || !q.Active) { return false; } Inventory inventory = ((Humanoid)player).GetInventory(); GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(q.Target); ItemDrop val = ((itemPrefab != null) ? itemPrefab.GetComponent<ItemDrop>() : null); if ((Object)(object)val == (Object)null) { return false; } string name = val.m_itemData.m_shared.m_name; int num = Mathf.Min(inventory.CountItems(name, -1, true), q.Required - q.Progress); if (num <= 0) { message = "Voce nao tem esse item na mochila."; return false; } inventory.RemoveItem(name, num, -1, true); q.Progress += num; SaveProgress(player, q.Tier); if (q.Complete) { return Claim(player, q, out message); } message = $"Entregue {num}. Faltam {q.Required - q.Progress}."; return true; } public static bool Claim(Player player, Quest q, out string message) { message = null; if (q.Claimed || !q.Accepted || !q.Complete) { message = "Missao ainda nao concluida."; return false; } Inventory inventory = ((Humanoid)player).GetInventory(); GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("Coins"); ItemDrop val = ((itemPrefab != null) ? itemPrefab.GetComponent<ItemDrop>() : null); if ((Object)(object)val == (Object)null) { message = "Moeda indisponivel."; return false; } int num = q.GoldReward; int num2 = Mathf.Max(1, val.m_itemData.m_shared.m_maxStackSize); while (num > 0) { int num3 = Mathf.Min(num2, num); if (inventory.AddItem(((Object)((Component)val).gameObject).name, num3, val.m_itemData.m_quality, val.m_itemData.m_variant, 0L, "", false) == null) { message = "Sem espaco na mochila para a recompensa."; return false; } num -= num3; } KillXpNetwork.Award(player, q.XpReward, null); q.Claimed = true; SaveProgress(player, q.Tier); message = $"Missao concluida! {q.GoldReward} moedas e {q.XpReward} XP"; return true; } } [HarmonyPatch(typeof(Player), "Load")] internal static class Player_Load_QuestCachePatch { private static void Postfix() { QuestSystem.ClearCache(); } } public class QuestTracker : MonoBehaviour { private const float W = 250f; private float _refresh; private List<Quest> _active = new List<Quest>(); private void Update() { _refresh -= Time.unscaledDeltaTime; if (!(_refresh > 0f)) { _refresh = 1f; Player localPlayer = Player.m_localPlayer; _active = (((Object)(object)localPlayer != (Object)null && ModConfig.QuestTrackerEnabled.Value) ? QuestSystem.Active(localPlayer) : new List<Quest>()); } } private void OnGUI() { //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_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: 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_0103: 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) if (!ModConfig.QuestTrackerEnabled.Value || _active.Count == 0 || (Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)Hud.instance == (Object)null || !Hud.instance.m_rootObject.activeSelf || Menu.IsVisible() || InventoryGui.IsVisible() || StoreGui.IsVisible() || Minimap.IsOpen() || Console.IsVisible()) { return; } GUISkin skin = GUI.skin; Matrix4x4 matrix = GUI.matrix; GUI.skin = MmoUI.Skin; float num = Mathf.Clamp((float)Screen.height / 1080f, 0.75f, 2.5f); GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(num, num, 1f)); float num2 = (float)Screen.width / num; string text = ColorUtility.ToHtmlStringRGB(MmoUI.MutedC); string text2 = ColorUtility.ToHtmlStringRGB(MmoUI.GoldC); GUILayout.BeginArea(new Rect(num2 - 250f - ModConfig.QuestTrackerOffsetX.Value, ModConfig.QuestTrackerOffsetY.Value, 250f, 0f)); GUILayout.Label("<size=12><color=#" + text2 + "><b>MISSOES</b></color></size>", Array.Empty<GUILayoutOption>()); foreach (Quest item in _active) { string text3 = CitySystem.ByTier(item.Tier)?.Name ?? BiomeTiers.Name(item.Tier); string text4 = (item.Complete ? ("<color=#" + text2 + ">completa</color>") : $"{item.Progress}/{item.Required}"); GUILayout.Label("<size=12>" + item.ShortTitle + " <color=#" + text2 + ">" + text4 + "</color></size>\n<size=10><color=#" + text + ">" + text3 + "</color></size>", Array.Empty<GUILayoutOption>()); } GUILayout.EndArea(); GUI.matrix = matrix; GUI.skin = skin; } } } namespace ValheimMMO.Pvp { internal static class Karma { private const string Key = "mmo.karma"; public const string ZdoKey = "mmo_karma"; private const string RpcKill = "ValheimMMO_KarmaKill"; private static float _syncTimer; private static float _lastSynced = -1f; public static float Of(Player p) { if ((Object)(object)p == (Object)null) { return 0f; } if ((Object)(object)p == (Object)(object)Player.m_localPlayer) { return Local(p); } ZDO obj = (((Object)(object)((Character)p).m_nview != (Object)null && ((Character)p).m_nview.IsValid()) ? ((Character)p).m_nview.GetZDO() : null); if (obj == null) { return 0f; } return obj.GetFloat("mmo_karma", 0f); } public static float Local(Player p) { if (p.m_customData.TryGetValue("mmo.karma", out var value) && float.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) { return result; } return 0f; } public static bool IsWanted(Player p) { if (ModConfig.PvpEnabled.Value) { return Of(p) >= ModConfig.WantedThreshold.Value; } return false; } public static bool IsOutlaw(Player p) { if (ModConfig.PvpEnabled.Value) { return Of(p) >= ModConfig.OutlawThreshold.Value; } return false; } public static string StatusName(float k) { if (k >= ModConfig.OutlawThreshold.Value) { return "Fora da lei"; } if (k >= ModConfig.WantedThreshold.Value) { return "Procurado"; } return "Limpo"; } public static void Set(Player p, float value, bool announce = true) { if ((Object)(object)p == (Object)null) { return; } float num = Local(p); value = Mathf.Clamp(value, 0f, ModConfig.KarmaMax.Value); p.m_customData["mmo.karma"] = value.ToString("R", CultureInfo.InvariantCulture); Sync(p, force: true); if (announce) { bool num2 = num >= ModConfig.WantedThreshold.Value; bool flag = value >= ModConfig.WantedThreshold.Value; if (!num2 && flag) { ((Character)p).Message((MessageType)2, "Voce agora e PROCURADO. Guardas vao atacar e as cidades fecham para voce.", 0, (Sprite)null); } if (num2 && !flag) { ((Character)p).Message((MessageType)2, "Seu nome foi limpo.", 0, (Sprite)null); } } } public static void Add(Player p, float delta, bool announce = true) { Set(p, Local(p) + delta, announce); } private static void Sync(Player p, bool force) { if (!((Object)(object)((Character)p).m_nview == (Object)null) && ((Character)p).m_nview.IsValid() && ((Character)p).m_nview.IsOwner()) { float num = Local(p); if (force || !(Mathf.Abs(num - _lastSynced) < 0.05f)) { ((Character)p).m_nview.GetZDO().Set("mmo_karma", num); _lastSynced = num; } } } internal static void Tick(Player p, float dt) { if (!ModConfig.PvpEnabled.Value || (Object)(object)p == (Object)null) { return; } float num = Local(p); if (num > 0f) { float num2 = Mathf.Max(0f, num - ModConfig.KarmaDecayPerMinute.Value / 60f * dt); if (num2 != num) { bool num3 = num >= ModConfig.WantedThreshold.Value && num2 < ModConfig.WantedThreshold.Value; p.m_customData["mmo.karma"] = num2.ToString("R", CultureInfo.InvariantCulture); if (num3) { ((Character)p).Message((MessageType)2, "Seu nome foi limpo.", 0, (Sprite)null); } } } _syncTimer += dt; if (_syncTimer >= 2f) { _syncTimer = 0f; Sync(p, force: false); } } internal static void OnMonsterKill(float victimMaxHp, bool boss) { Player localPlayer = Player.m_localPlayer; if (ModConfig.PvpEnabled.Value && !((Object)(object)localPlayer == (Object)null) && !(Local(localPlayer) <= 0f)) { float num = ModConfig.KarmaMonsterFactor.Value * Mathf.Pow(Mathf.Max(1f, victimMaxHp), 0.6f) * (boss ? 5f : 1f); Add(localPlayer, 0f - num); } } internal static void Register() { if (ZRoutedRpc.instance != null) { ZRoutedRpc.instance.Register<string, float>("ValheimMMO_KarmaKill", (Action<long, string, float>)OnKillCredit); } } internal static void OnPlayerDied(Player victim) { if (!ModConfig.PvpEnabled.Value || (Object)(object)victim == (Object)null) { return; } float num = Local(victim); if (num > 0f) { Add(victim, 0f - ModConfig.KarmaDeathLoss.Value, announce: false); } HitData lastHit = ((Character)victim).m_lastHit; Character obj = ((lastHit != null) ? lastHit.GetAttacker() : null); Player val = (Player)(object)((obj is Player) ? obj : null); if ((Object)(object)val == (Object)null || (Object)(object)val == (Object)(object)victim) { return; } ZDO val2 = (((Object)(object)((Character)val).m_nview != (Object)null && ((Character)val).m_nview.IsValid()) ? ((Character)val).m_nview.GetZDO() : null); if (val2 == null) { return; } long owner = val2.GetOwner(); if ((Object)(object)val == (Object)(object)Player.m_localPlayer) { OnKillCredit(0L, victim.GetPlayerName(), num); return; } ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null) { instance.InvokeRoutedRPC(owner, "ValheimMMO_KarmaKill", new object[2] { victim.GetPlayerName(), num }); } } private static void OnKillCredit(long sender, string victimName, float victimKarma) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || !ModConfig.PvpEnabled.Value) { return; } if (victimKarma >= ModConfig.WantedThreshold.Value) { int num = Mathf.RoundToInt(victimKarma * ModConfig.BountyPerKarma.Value); if (num > 0) { KillXpNetwork.GiveGoldPublic(localPlayer, num, $"Recompensa por {victimName}: {num} moedas"); } } else { Add(localPlayer, ModConfig.KarmaPerKill.Value); ((Character)localPlayer).Message((MessageType)1, $"Assassinato de {victimName}: +{ModConfig.KarmaPerKill.Value:0} karma", 0, (Sprite)null); } } } [HarmonyPatch(typeof(Game), "Start")] internal static class Game_Start_KarmaPatch { private static void Postfix() { Karma.Register(); } } [HarmonyPatch(typeof(Player), "UpdateStats", new Type[] { typeof(float) })] internal static class Player_UpdateStats_KarmaPatch { private static void Postfix(Player __instance, float dt) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer) { Karma.Tick(__instance, dt); } } } [HarmonyPatch(typeof(Player), "OnDeath")] internal static class Player_OnDeath_KarmaPatch { private static void Prefix(Player __instance) { if ((Object)(object)__instance != (Object)null && (Object)(object)((Character)__instance).m_nview != (Object)null && ((Character)__instance).m_nview.IsOwner()) { Karma.OnPlayerDied(__instance); } } } [HarmonyPatch(typeof(Player), "GetHoverName")] [HarmonyPriority(200)] internal static class Player_GetHoverName_KarmaPatch { private static void Postfix(Player __instance, ref string __result) { if (ModConfig.PvpEnabled.Value && Karma.IsWanted(__instance)) { __result = "<color=#E04A3A>☠ " + __result + "</color>"; } } } [HarmonyPatch(typeof(StoreGui), "Show")] internal static class StoreGui_Show_KarmaPatch { private static bool Prefix(Trader trader) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || !Karma.IsWanted(localPlayer)) { return true; } if (!MerchantSpawner.IsMerchant(trader)) { return true; } ((Character)localPlayer).Message((MessageType)2, "O mercador nao negocia com procurados.", 0, (Sprite)null); return false; } } [HarmonyPatch(typeof(TeleportWorld), "Teleport")] internal static class TeleportWorld_Teleport_KarmaPatch { private static bool Prefix(TeleportWorld __instance, Player player) { if ((Object)(object)player == (Object)null || !Karma.IsWanted(player)) { return true; } ZNetView component = ((Component)__instance).GetComponent<ZNetView>(); ZDO val = (((Object)(object)component != (Object)null && component.IsValid()) ? component.GetZDO() : null); if (val == null || !val.GetBool("mmo_city_portal", false)) { return true; } ((Character)player).Message((MessageType)2, "O portal da cidade rejeita procurados.", 0, (Sprite)null); return false; } } [HarmonyPatch(typeof(EnemyHud), "TestShow")] internal static class EnemyHud_TestShow_StealthPatch { private static void Postfix(Character c, ref bool __result) { if (__result && ModConfig.StealthHidesName.Value) { Player val = (Player)(object)((c is Player) ? c : null); if (val != null && (Object)(object)val != (Object)(object)Player.m_localPlayer && ((Character)val).IsCrouching()) { __result = false; } } } } } namespace ValheimMMO.Progression { public enum Attr { Vitality, Endurance, Spirit, Conditioning } public static class AttrInfo { public const int Count = 4; public static readonly Attr[] All = new Attr[4] { Attr.Vitality, Attr.Endurance, Attr.Spirit, Attr.Conditioning }; public static string DisplayName(Attr a) { return a switch { Attr.Vitality => "Vitalidade", Attr.Endurance => "Resistencia", Attr.Spirit => "Espirito", Attr.Conditioning => "Condicionamento", _ => a.ToString(), }; } public static string Short(Attr a) { return a switch { Attr.Vitality => "VIT", Attr.Endurance => "RES", Attr.Spirit => "ESP", Attr.Conditioning => "CON", _ => "?", }; } public static string Effect(Attr a) { return a switch { Attr.Vitality => "Vida maxima", Attr.Endurance => "Stamina maxima", Attr.Spirit => "Eitr maximo", Attr.Conditioning => "Peso maximo", _ => "", }; } } public static class ItemBonuses { public static bool Enabled => ModConfig.ItemBonusesEnabled.Value; public static int[] For(ItemData item) { if (item != null) { return For(item, item.m_quality, item.m_worldLevel); } return new int[4]; } public static int[] For(ItemData item, int quality, float worldLevel) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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) //IL_0079: Expected I4, but got Unknown //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Invalid comparison between Unknown and I4 //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Invalid comparison between Unknown and I4 //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Invalid comparison between Unknown and I4 //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Invalid comparison between Unknown and I4 //IL_013c: 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_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Invalid comparison between Unknown and I4 //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) int[] result = new int[4]; if (!Enabled || item?.m_shared == null) { return result; } SharedData shared = item.m_shared; quality = Mathf.Max(1, quality); ItemType itemType = shared.m_itemType; switch (itemType - 3) { default: if ((int)itemType != 22) { break; } goto case 0; case 3: case 4: case 8: { float armor2 = item.GetArmor(quality, worldLevel); Add(result, ArmorAttribute(shared), armor2 * ModConfig.ArmorToAttribute.Value); break; } case 14: { float armor = item.GetArmor(quality, worldLevel); Add(result, Attr.Conditioning, armor * ModConfig.ArmorToAttribute.Value); break; } case 2: { float blockPower = item.GetBlockPower(quality, 0f); Add(result, Attr.Vitality, blockPower * ModConfig.BlockToAttribute.Value); break; } case 0: case 1: case 11: { SkillType skillType = shared.m_skillType; DamageTypes damage; if ((int)skillType == 9 || (int)skillType == 10) { float value = ModConfig.MagicStaffBase.Value + ModConfig.MagicStaffPerQuality.Value * (float)(quality - 1); Add(result, Attr.Spirit, value); } else if ((int)skillType == 8 || (int)skillType == 14) { damage = item.GetDamage(quality, worldLevel); float totalDamage = ((DamageTypes)(ref damage)).GetTotalDamage(); Add(result, Attr.Endurance, totalDamage * ModConfig.RangedDamageToAttribute.Value); } else { damage = item.GetDamage(quality, worldLevel); float totalDamage2 = ((DamageTypes)(ref damage)).GetTotalDamage(); Add(result, Attr.Endurance, totalDamage2 * ModConfig.MeleeDamageToAttribute.Value); } break; } case 5: case 6: case 7: case 9: case 10: case 12: case 13: break; } return result; } private static void Add(int[] result, Attr attr, float value) { int num = Mathf.RoundToInt(value); if (num > 0) { result[(int)attr] += num; } } public static Attr ArmorAttribute(SharedData shared) { if (shared.m_eitrRegenModifier > 0f) { return Attr.Spirit; } if (shared.m_movementModifier <= ModConfig.HeavyArmorMovementThreshold.Value) { return Attr.Vitality; } return Attr.Endurance; } public static int[] TotalEquipped(Humanoid humanoid) { int[] array = new int[4]; if (!Enabled || (Object)(object)humanoid == (Object)null) { return array; } Inventory inventory = humanoid.GetInventory(); if (inventory == null) { return array; } foreach (ItemData equippedItem in inventory.GetEquippedItems()) { int[] array2 = For(equippedItem); for (int i = 0; i < array.Length; i++) { array[i] += array2[i]; } } return array; } public static bool Any(int[] bonuses) { if (bonuses == null) { return false; } for (int i = 0; i < bonuses.Length; i++) { if (bonuses[i] != 0) { return true; } } return false; } public static string Describe(int[] bonuses, bool shortNames = true) { List<string> list = new List<string>(); for (int i = 0; i < bonuses.Length; i++) { if (bonuses[i] != 0) { Attr a = (Attr)i; list.Add($"+{bonuses[i]} {(shortNames ? AttrInfo.Short(a) : AttrInfo.DisplayName(a))}"); } } return string.Join(", ", list); } } [HarmonyPatch(typeof(ItemData), "GetTooltip", new Type[] { typeof(ItemData), typeof(int), typeof(bool), typeof(float), typeof(int) })] internal static class ItemData_GetTooltip_Patch { private static void Postfix(ItemData item, int qualityLevel, float worldLevel, ref string __result) { if (!ModConfig.ShowItemBonusTooltip.Value || !ItemBonuses.Enabled) { return; } int[] array = ItemBonuses.For(item, qualityLevel, worldLevel); if (!ItemBonuses.Any(array)) { return; } StringBuilder stringBuilder = new StringBuilder(__result); stringBuilder.Append("\n"); for (int i = 0; i < array.Length; i++) { if (array[i] != 0) { Attr a = (Attr)i; stringBuilder.Append($"\n{AttrInfo.DisplayName(a)}: <color=orange>+{array[i]}</color>"); } } __result = stringBuilder.ToString(); } } [HarmonyPatch(typeof(Humanoid), "EquipItem")] internal static class Humanoid_EquipItem_Patch { private static void Postfix(Humanoid __instance, bool __result) { if (__result) { RefreshIfLocal(__instance); } } internal static void RefreshIfLocal(Humanoid humanoid) { Player val = (Player)(object)((humanoid is Player) ? humanoid : null); if (val != null && (Object)(object)val == (Object)(object)Player.m_localPlayer) { val.UpdateFood(0f, true); } } } [HarmonyPatch(typeof(Humanoid), "UnequipItem")] internal static class Humanoid_UnequipItem_Patch { private static void Postfix(Humanoid __instance) { Humanoid_EquipItem_Patch.RefreshIfLocal(__instance); } } [HarmonyPatch(typeof(Player), "GetMaxCarryWeight")] internal static class Player_GetMaxCarryWeight_Patch { private static void Postfix(Player __instance, ref float __result) { PlayerProgress playerProgress = PlayerProgress.Get(__instance); if (playerProgress != null) { __result += playerProgress.CarryBonusKg(__instance); } } } public static class LevelCurve { public static long XpToNext(int level) { if (level < 1) { level = 1; } if (level >= ModConfig.MaxLevel.Value) { return 0L; } return (long)Math.Round((double)ModConfig.XpCurveFactor.Value * Math.Pow(level, ModConfig.XpCurveExponent.Value)); } public static long TotalXpForLevel(int level) { long num = 0L; for (int i = 1; i < level; i++) { num += XpToNext(i); } return num; } public static int PointsGrantedAt(int level) { return Math.Max(0, (level - 1) * ModConfig.PointsPerLevel.Value); } public static long XpForKill(Character victim) { if ((Object)(object)victim == (Object)null) { return 0L; } float num = 0f; try { num = victim.GetMaxHealth(); } catch { } if (num <= 0f) { num = victim.GetMaxHealthBase(); } if (num <= 0f) { return 0L; } int num2 = Math.Max(0, victim.GetLevel() - 1); double num3 = 1.0 + (double)(ModConfig.XpStarBonus.Value * (float)num2); double num4 = 1.0; if (victim.IsBoss()) { num4 = (DungeonBosses.IsDungeonBoss(victim, out var _) ? ModConfig.XpDungeonBossMultiplier.Value : ModConfig.XpBossMultiplier.Value); } return (long)Math.Ceiling((double)ModConfig.XpKillFactor.Value * Math.Pow(num, ModConfig.XpKillExponent.Value) * num3 * num4); } } internal static class LevelDisplay { public const string ZdoKey = "mmo_level"; public static void Sync(Player player, int level) { if (!((Object)(object)player == (Object)null) && !((Object)(object)((Character)player).m_nview == (Object)null) && ((Character)player).m_nview.IsValid() && ((Character)player).m_nview.IsOwner()) { ZDO zDO = ((Character)player).m_nview.GetZDO(); if (zDO.GetInt("mmo_level", -1) != level) { zDO.Set("mmo_level", level); } } } public static int LevelOf(Player player) { if ((Object)(object)player == (Object)null) { return 0; } if ((Object)(object)player == (Object)(object)Player.m_localPlayer) { return PlayerProgress.Get(player)?.Level ?? 0; } ZDO obj = (((Object)(object)((Character)player).m_nview != (Object)null && ((Character)player).m_nview.IsValid()) ? ((Character)player).m_nview.GetZDO() : null); if (obj == null) { return 0; } return obj.GetInt("mmo_level", 0); } } [HarmonyPatch(typeof(Player), "GetHoverName")] internal static class Player_GetHoverName_LevelPatch { private static void Postfix(Player __instance, ref string __result) { if (ModConfig.ShowPlayerLevels.Value) { int num = LevelDisplay.LevelOf(__instance); if (num > 0) { __result = $"{__result} <color=#F2C766>Lv {num}</color>"; } } } } public class PlayerProgress { private const string CustomDataKey = "mmo.progression"; private const int Format = 2; public int Level = 1; public long Xp; public readonly int[] Spent = new int[4]; public float Satiety = -1f; private static readonly ConditionalWeakTable<Player, PlayerProgress> Cache = new ConditionalWeakTable<Player, PlayerProgress>(); public static PlayerProgress Local { get { if (!((Object)(object)Player.m_localPlayer != (Object)null)) { return null; } return Get(Player.m_localPlayer); } } public int TotalPoints => LevelCurve.PointsGrantedAt(Level); public int SpentPoints { get { int num = 0; for (int i = 0; i < Spent.Length; i++) { num += Spent[i]; } return num; } } public int UnspentPoints => Math.Max(0, TotalPoints - SpentPoints); public long XpForNextLevel => LevelCurve.XpToNext(Level); public float LevelProgress { get { long xpForNextLevel = XpForNextLevel; if (xpForNextLevel > 0) { return Math.Min(1f, (float)Xp / (float)xpForNextLevel); } return 1f; } } public static PlayerProgress Get(Player player) { if ((Object)(object)player == (Object)null) { return null; } if (Cache.TryGetValue(player, out var value)) { return value; } PlayerProgress playerProgress = new PlayerProgress(); playerProgress.LoadFrom(player); Cache.Add(player, playerProgress); return playerProgress; } public static void ClearCache(Player player) { if ((Object)(object)player != (Object)null) { Cache.Remove(player); } } public bool TrySpend(Attr attr, Player owner) { if (UnspentPoints <= 0) { return false; } Spent[(int)attr]++; SaveTo(owner); return true; } public bool TryRefund(Attr attr, Player owner, out string reason) { reason = null; if (!ModConfig.RespecEnabled.Value) { reason = "Respec esta desativado neste servidor."; return false; } if (Spent[(int)attr] <= 0) { reason = "Nenhum ponto investido nesse atributo."; return false; } if (!CanRespec(owner, out reason)) { return false; } Spent[(int)attr]--; SaveTo(owner); return true; } public bool RespecAll(Player owner, out string reason) { reason = null; if (!ModConfig.RespecEnabled.Value) { reason = "Respec esta desativado neste servidor."; return false; } if (SpentPoints == 0) { reason = "Nao ha pontos para redistribuir."; return false; } if (!CanRespec(owner, out reason)) { return false; } Array.Clear(Spent, 0, Spent.Length); SaveTo(owner); return true; } public static bool CanRespec(Player player, out string reason) { reason = null; if ((Object)(object)player == (Object)null) { reason = "Jogador invalido."; return false; } if (ModConfig.RespecRequiresShelter.Value && !player.InShelter()) { reason = "Voce precisa estar sob abrigo para redistribuir pontos."; return false; } int value = ModConfig.RespecMinComfort.Value; if (value > 0 && player.GetComfortLevel() < value) { reason = $"Conforto insuficiente ({player.GetComfortLevel()}/{value}). " + "Aproxime-se de uma fogueira e de moveis."; return false; } return true; } public int AddXp(long amount, Player owner) { if (amount <= 0) { return 0; } int value = ModConfig.MaxLevel.Value; if (Level >= value) { return 0; } Xp += amount; int num = 0; while (Level < value) { long num2 = LevelCurve.XpToNext(Level); if (num2 <= 0 || Xp < num2) { break; } Xp -= num2; Level++; num++; } if (Level >= value) { Xp = 0L; } SaveTo(owner); return num; } public int ApplyDeathPenalty(Player owner) { float num = ModConfig.DeathXpLossPercent.Value / 100f; if (num <= 0f) { return 0; } long num2 = (long)Math.Round((float)LevelCurve.XpToNext(Level) * num); if (num2 <= 0) { return 0; } Xp -= num2; int num3 = 0; if (ModConfig.DeathCanDelevel.Value) { while (Xp < 0 && Level > 1) { Level--; num3++; Xp += LevelCurve.XpToNext(Level); } } if (Xp < 0) { Xp = 0L; } if (num3 > 0) { ReclaimExcessPoints(); } SaveTo(owner); return num3; } private void ReclaimExcessPoints() { int num = SpentPoints - TotalPoints; while (num > 0) { int num2 = 0; for (int i = 1; i < Spent.Length; i++) { if (Spent[i] > Spent[num2]) { num2 = i; } } if (Spent[num2] > 0) { Spent[num2]--; num--; continue; } break; } } public int EffectivePoints(Attr attr, Player player) { int num = ItemBonuses.TotalEquipped((Humanoid)(object)player)[(int)attr]; return Spent[(int)attr] + num; } public void ComputeStats(Player player, out float hp, out float stamina, out float eitr) { int num = Math.Max(0, Level - 1); float num2 = (((Object)(object)player != (Object)null) ? player.m_baseHP : 25f); float num3 = (((Object)(object)player != (Object)null) ? player.m_baseStamina : 50f); int[] array = ItemBonuses.TotalEquipped((Humanoid)(object)player); hp = num2 + (float)num * ModConfig.GrowthHealthPerLevel.Value + (float)(Spent[0] + array[0]) * ModConfig.HealthPerVitality.Value; stamina = num3 + (float)num * ModConfig.GrowthStaminaPerLevel.Value + (float)(Spent[1] + array[1]) * ModConfig.StaminaPerEndurance.Value; eitr = (float)num * ModConfig.GrowthEitrPerLevel.Value + (float)(Spent[2] + array[2]) * ModConfig.EitrPerSpirit.Value; if (hp < 1f) { hp = 1f; } if (stamina < 1f) { stamina = 1f; } if (eitr < 0f) { eitr = 0f; } } public float CarryBonusKg(Player player) { int num = Math.Max(0, Level - 1); int num2 = Spent[3] + ItemBonuses.TotalEquipped((Humanoid)(object)player)[3]; return (float)num * ModConfig.GrowthCarryPerLevel.Value + (float)num2 * ModConfig.CarryPerConditioning.Value; } public void SaveTo(Player player) { if (!((Object)(object)player == (Object)null)) { CultureInfo invariantCulture = CultureInfo.InvariantCulture; List<string> list = new List<string> { 2.ToString(invariantCulture), Level.ToString(invariantCulture), Xp.ToString(invariantCulture) }; for (int i = 0; i < 4; i++) { list.Add(Spent[i].ToString(invariantCulture)); } list.Add(Satiety.ToString("R", invariantCulture)); player.m_customData["mmo.progression"] = string.Join("|", list); LevelDisplay.Sync(player, Level); } } public void LoadFrom(Player player) { if ((Object)(object)player == (Object)null) { return; } if (!player.m_customData.TryGetValue("mmo.progression", out var value) || string.IsNullOrEmpty(value)) { Reset(); return; } try { CultureInfo invariantCulture = CultureInfo.InvariantCulture; string[] array = value.Split('|'); int num = int.Parse(array[0], invariantCulture); Level = Math.Max(1, int.Parse(array[1], invariantCulture)); Xp = Math.Max(0L, long.Parse(array[2], invariantCulture)); int num2 = ((num >= 2) ? 4 : 3); Array.Clear(Spent, 0, Spent.Length); for (int i = 0; i < num2 && i < 4; i++) { Spent[i] = Math.Max(0, int.Parse(array[3 + i], invariantCulture)); } int num3 = 3 + num2; Satiety = ((array.Length > num3) ? float.Parse(array[num3], NumberStyles.Float, invariantCulture) : (-1f)); Clamp(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Nao foi possivel ler a progressao de " + player.GetPlayerName() + ", resetando. Dado bruto: '" + value + "'. Erro: " + ex.Message)); Reset(); } } private void Clamp() { if (Level > ModConfig.MaxLevel.Value) { Level = ModConfig.MaxLevel.Value; } if (SpentPoints > TotalPoints) { ReclaimExcessPoints(); } } public void Reset() { Level = 1; Xp = 0L; Array.Clear(Spent, 0, Spent.Length); Satiety = -1f; } public override string ToString() { return $"lvl {Level} ({Xp}/{XpForNextLevel} xp) " + $"VIT {Spent[0]} RES {Spent[1]} ESP {Spent[2]} CON {Spent[3]} " + $"livres {UnspentPoints}"; } } [HarmonyPatch(typeof(Player), "GetTotalFoodValue")] internal static class Player_GetTotalFoodValue_Patch { private static void Postfix(Player __instance, ref float hp, ref float stamina, ref float eitr) { PlayerProgress playerProgress = PlayerProgress.Get(__instance); if (playerProgress != null) { playerProgress.ComputeStats(__instance, out var hp2, out var stamina2, out var eitr2); if (ModConfig.FoodGivesNoStats.Value) { hp = hp2; stamina = stamina2; eitr = eitr2; } else { hp += hp2 - __instance.m_baseHP; stamina += stamina2 - __instance.m_baseStamina; eitr += eitr2; } } } } internal static class KillXpNetwork { private const string RpcName = "ValheimMMO_KillXp"; private static readonly ConditionalWeakTable<Character, HashSet<ZDOID>> Contributors = new ConditionalWeakTable<Character, HashSet<ZDOID>>(); internal static void Register() { if (ZRoutedRpc.instance != null) { ZRoutedRpc.instance.Register<ZPackage>("ValheimMMO_KillXp", (Action<long, ZPackage>)OnKillXp); Plugin.Log.LogInfo((object)"RPC de XP registrado."); } } internal static void RecordHit(Character victim, HitData hit) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)victim == (Object)null) && hit != null && !victim.IsPlayer() && !((ZDOID)(ref hit.m_attacker)).IsNone() && hit.GetAttacker() is Player && !(hit.GetTotalDamage() <= 0f)) { Contributors.GetOrCreateValue(victim).Add(hit.m_attacker); } } internal static void BroadcastKill(Character victim) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)victim == (Object)null || ZRoutedRpc.instance == null) { return; } HashSet<ZDOID> value; bool flag = Contributors.TryGetValue(victim, out value) && value.Count > 0; bool flag2 = !ModConfig.XpRequiresOwnDamage.Value; if (!flag && !flag2) { Contributors.Remove(victim); return; } long num = LevelCurve.XpForKill(victim); num = (long)((float)num * ModConfig.XpGlobalRate.Value); if (num <= 0) { Contributors.Remove(victim); return; } ZPackage val = new ZPackage(); val.Write(num); val.Write(victim.m_name ?? ""); val.Write(((Component)victim).transform.position); val.Write(flag2); val.Write(flag ? value.Count : 0); if (flag) { foreach (ZDOID item in value) { val.Write(item); } } val.Write(((Object)((Component)victim).gameObject).name.Replace("(Clone)", "")); val.Write(DungeonBosses.IsDungeonBoss(victim, out var tier) ? tier.Id : 0); val.Write(WorldBoss.IsWorldBoss(victim, out var def) ? WorldBoss.GoldFor(def) : 0); ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "ValheimMMO_KillXp", new object[1] { val }); Contributors.Remove(victim); } private static void OnKillXp(long sender, ZPackage pkg) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || pkg == null) { return; } long num = pkg.ReadLong(); string victimName = pkg.ReadString(); Vector3 val = pkg.ReadVector3(); bool flag = pkg.ReadBool(); int num2 = pkg.ReadInt(); ZDOID zDOID = ((Character)localPlayer).GetZDOID(); bool flag2 = false; for (int i = 0; i < num2; i++) { if (pkg.ReadZDOID() == zDOID) { flag2 = true; } } string victimPrefab = pkg.ReadString(); int num3 = pkg.ReadInt(); int num4 = pkg.ReadInt(); if (!flag2 && flag) { float num5 = Mathf.Max(1f, ModConfig.XpNearbyRadius.Value); flag2 = Vector3.Distance(((Component)localPlayer).transform.position, val) <= num5; } if (flag2) { Award(localPlayer, num, victimName); QuestSystem.OnKill(victimPrefab, num3); if (num4 > 0) { GiveGold(localPlayer, num4); } Karma.OnMonsterKill(Mathf.Pow(Mathf.Max(1f, (float)num / Mathf.Max(0.1f, ModConfig.XpKillFactor.Value * ModConfig.XpGlobalRate.Value)), 1.3333334f), num3 > 0 || num4 > 0); } } public static void GiveGoldPublic(Player player, int amount, string message) { GiveGold(player, amount, message); } private static void GiveGold(Player player, int amount, string message = null) { //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) ObjectDB instance = ObjectDB.instance; object obj; if (instance == null) { obj = null; } else { GameObject itemPrefab = instance.GetItemPrefab("Coins"); obj = ((itemPrefab != null) ? itemPrefab.GetComponent<ItemDrop>() : null); } ItemDrop val = (ItemDrop)obj; if ((Object)(object)val == (Object)null) { return; } Inventory inventory = ((Humanoid)player).GetInventory(); int num = Mathf.Max(1, val.m_itemData.m_shared.m_maxStackSize); int num2 = amount; while (num2 > 0) { int num3 = Mathf.Min(num, num2); if (inventory.AddItem(((Object)((Component)val).gameObject).name, num3, val.m_itemData.m_quality, val.m_itemData.m_variant, 0L, "", false) == null) { CharacterDrop.DropItems(new List<KeyValuePair<GameObject, int>> { new KeyValuePair<GameObject, int>(((Component)val).gameObject, 1) }, ((Component)player).transform.position + Vector3.up, 0.3f); break; } num2 -= num3; } ((Character)player).Message((MessageType)2, message ?? $"Recompensa do chefe mundial: {amount} moedas", 0, (Sprite)null); } internal static void Award(Player player, long xp, string victimName) { PlayerProgress playerProgress = PlayerProgress.Get(player); if (playerProgress != null && xp > 0) { int level = playerProgress.Level; int num = playerProgress.AddXp(xp, player); string arg = (string.IsNullOrEmpty(victimName) ? "" : (" (" + Localization.instance.Localize(victimName) + ")")); if (num > 0) { ((Character)player).Message((MessageType)2, $"Level {playerProgress.Level}! +{num * ModConfig.PointsPerLevel.Value} pontos", 0, (Sprite)null); Plugin.Log.LogInfo((object)$"Level up: {level} -> {playerProgress.Level} ({playerProgress})"); } else if (ModConfig.ShowXpGainMessages.Value) { ((Character)playe