Decompiled source of SkillEXPBoost v1.3.0

plugins/SkillEXPBoost.dll

Decompiled 5 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyFileVersion("1.3.0.0")]
[assembly: AssemblyTitle("SkillEXPBoost - Skill XP and progress display for Valheim")]
[assembly: AssemblyDescription("Client-side Valheim mod for configurable skill XP and HUD progress display.")]
[assembly: AssemblyCompany("Rollstuhltreter")]
[assembly: AssemblyProduct("SkillEXPBoost")]
[assembly: AssemblyCopyright("Copyright (c) Rollstuhltreter")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.3.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
[BepInPlugin("kann.valheim.skillmultiplier", "SkillEXPBoost", "1.3.0")]
public sealed class SkillExperiencePlugin : BaseUnityPlugin
{
	public const string PluginGuid = "kann.valheim.skillmultiplier";

	public const string PluginName = "SkillEXPBoost";

	public const string PluginVersion = "1.3.0";

	internal static ConfigEntry<bool> Enable;

	internal static ConfigEntry<float> CombatSkillsMultiplier;

	internal static ConfigEntry<float> NormalSkillsMultiplier;

	internal static ConfigEntry<float> FarmSkillsMultiplier;

	internal static ConfigEntry<bool> ShowSkillProgress;

	internal static ConfigEntry<float> SkillProgressAggregationWindow;

	internal static ConfigEntry<float> SkillProgressDuration;

	private static SkillExperiencePlugin Instance;

	private readonly Dictionary<SkillType, float> _pendingSkillXp = new Dictionary<SkillType, float>();

	private Skills _pendingSkills;

	private float _nextProgressFlush;

	private float _progressVisibleUntil;

	private string _progressText;

	private void Awake()
	{
		//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
		Instance = this;
		Enable = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enable", true, "Enable the skill experience multiplier for the local player. Changes apply immediately.");
		CombatSkillsMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Multipliers", "CombatSkillsMultiplier", 2f, "Combat skills: Swords, Knives, Clubs, Polearms, Spears, Blocking, Axes, Bows, Crossbows, Unarmed, ElementalMagic and BloodMagic.");
		NormalSkillsMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Multipliers", "NormalSkillsMultiplier", 2f, "Normal skills: Jump, Sneak, Run, Swim, Dodge, Ride, Cooking and Crafting.");
		FarmSkillsMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Multipliers", "FarmSkillsMultiplier", 2f, "Farm and gathering skills: Pickaxes, WoodCutting, Fishing and Farming.");
		ShowSkillProgress = ((BaseUnityPlugin)this).Config.Bind<bool>("Display", "ShowSkillProgress", false, "Show a compact custom XP display. XP gains are combined instead of being queued with loot messages. Disabled by default.");
		SkillProgressAggregationWindow = ((BaseUnityPlugin)this).Config.Bind<float>("Display", "SkillProgressAggregationWindow", 0.75f, "Seconds used to combine repeated XP gains for the same skill into one display update.");
		SkillProgressDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Display", "SkillProgressDuration", 1.25f, "Seconds the combined skill progress display stays visible.");
		new Harmony("kann.valheim.skillmultiplier").PatchAll();
	}

	private void OnDestroy()
	{
		if ((Object)(object)Instance == (Object)(object)this)
		{
			Instance = null;
		}
	}

	private void Update()
	{
		if (ShowSkillProgress == null || !ShowSkillProgress.Value)
		{
			_pendingSkillXp.Clear();
			_progressText = null;
		}
		else if (_pendingSkillXp.Count != 0 && !(Time.unscaledTime < _nextProgressFlush))
		{
			_progressText = BuildProgressText();
			_pendingSkillXp.Clear();
			_progressVisibleUntil = Time.unscaledTime + SanitizeDisplayTime(SkillProgressDuration.Value, 1.25f);
		}
	}

	private void OnGUI()
	{
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Expected O, but got Unknown
		//IL_004e: 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)
		if (!string.IsNullOrEmpty(_progressText) && !(Time.unscaledTime >= _progressVisibleUntil))
		{
			GUIStyle val = new GUIStyle(GUI.skin.label)
			{
				alignment = (TextAnchor)0,
				fontSize = 16,
				fontStyle = (FontStyle)1,
				wordWrap = true
			};
			val.normal.textColor = Color.white;
			GUI.Label(new Rect(24f, 64f, 520f, 160f), _progressText, val);
		}
	}

	internal static void RecordSkillGain(Skills skills, SkillType skillType, float amount)
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)Instance != (Object)null)
		{
			Instance.QueueSkillGain(skills, skillType, amount);
		}
	}

	private void QueueSkillGain(Skills skills, SkillType skillType, float amount)
	{
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		if (!(amount <= 0f) && !float.IsNaN(amount) && !float.IsInfinity(amount))
		{
			if (_pendingSkillXp.Count == 0)
			{
				_nextProgressFlush = Time.unscaledTime + SanitizeDisplayTime(SkillProgressAggregationWindow.Value, 0.75f);
			}
			_pendingSkills = skills;
			_pendingSkillXp.TryGetValue(skillType, out var value);
			_pendingSkillXp[skillType] = value + amount;
		}
	}

	private string BuildProgressText()
	{
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_pendingSkills == (Object)null)
		{
			return string.Empty;
		}
		StringBuilder stringBuilder = new StringBuilder("XP gained");
		foreach (KeyValuePair<SkillType, float> item in _pendingSkillXp)
		{
			int num = (int)Math.Floor(_pendingSkills.GetSkillLevel(item.Key));
			float skillProgressPercent = GetSkillProgressPercent(_pendingSkills, item.Key);
			stringBuilder.Append('\n');
			stringBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0}: +{1:0.##} XP | Level {2} ({3:0.##}%)", item.Key, item.Value, num, skillProgressPercent);
		}
		return stringBuilder.ToString();
	}

	private static float GetSkillProgressPercent(Skills skills, SkillType skillType)
	{
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		foreach (Skill skill in skills.GetSkillList())
		{
			if (skill != null && skill.m_info != null && skill.m_info.m_skill == skillType)
			{
				return Math.Max(0f, Math.Min(100f, skill.GetLevelPercentage() * 100f));
			}
		}
		return 0f;
	}

	private static float SanitizeDisplayTime(float value, float fallback)
	{
		if (float.IsNaN(value) || float.IsInfinity(value))
		{
			return fallback;
		}
		return Math.Max(0.1f, Math.Min(10f, value));
	}

	internal static float GetMultiplier(SkillType skillType)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0003: Unknown result type (might be due to invalid IL or missing references)
		//IL_0009: Invalid comparison between Unknown and I4
		//IL_0011: 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_0051: Expected I4, but got Unknown
		//IL_0051: 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_0086: Expected I4, but got Unknown
		if ((int)skillType == 0 || (int)skillType == 999)
		{
			return 1f;
		}
		switch (skillType - 1)
		{
		default:
			switch (skillType - 100)
			{
			case 0:
			case 1:
			case 2:
			case 3:
			case 5:
			case 7:
			case 8:
			case 10:
				return Sanitize(NormalSkillsMultiplier.Value);
			case 4:
			case 6:
				break;
			default:
				return 1f;
			}
			break;
		case 0:
		case 1:
		case 2:
		case 3:
		case 4:
		case 5:
		case 6:
		case 7:
		case 8:
		case 9:
		case 10:
		case 13:
			return Sanitize(CombatSkillsMultiplier.Value);
		case 11:
		case 12:
			break;
		}
		return Sanitize(FarmSkillsMultiplier.Value);
	}

	private static float Sanitize(float value)
	{
		if (float.IsNaN(value) || float.IsInfinity(value))
		{
			return 1f;
		}
		return Math.Max(0f, value);
	}
}
[HarmonyPatch(typeof(Skills), "RaiseSkill")]
internal static class SkillsRaiseSkillMultiplierPatch
{
	private static void Prefix(Skills __instance, SkillType __0, ref float __1)
	{
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		if (SkillExperiencePlugin.Enable != null && SkillExperiencePlugin.Enable.Value && !((Object)(object)Player.m_localPlayer == (Object)null) && !((Object)(object)((Character)Player.m_localPlayer).GetSkills() != (Object)(object)__instance))
		{
			__1 *= SkillExperiencePlugin.GetMultiplier(__0);
		}
	}
}
[HarmonyPatch(typeof(Skills), "RaiseSkill")]
internal static class SkillsRaiseSkillDisplayPatch
{
	private static void Postfix(Skills __instance, SkillType __0, float __1)
	{
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		if (SkillExperiencePlugin.ShowSkillProgress != null && SkillExperiencePlugin.ShowSkillProgress.Value && !(__1 <= 0f) && !((Object)(object)Player.m_localPlayer == (Object)null) && !((Object)(object)((Character)Player.m_localPlayer).GetSkills() != (Object)(object)__instance))
		{
			SkillExperiencePlugin.RecordSkillGain(__instance, __0, __1);
		}
	}
}