using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Threading;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("NoSkillLoss")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+bf2bc9f88d199faeb3495278be834c45b0c1cf83")]
[assembly: AssemblyProduct("NoSkillLoss")]
[assembly: AssemblyTitle("NoSkillLoss")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace CustomSkillLoss;
[BepInPlugin("CustomSkillLoss", "Custom Skill Loss", "1.0.0")]
public class CustomSkillLossPlugin : BaseUnityPlugin
{
public const string PluginGUID = "CustomSkillLoss";
public const string PluginName = "Custom Skill Loss";
public const string PluginVersion = "1.0.0";
private static CustomSkillLossPlugin _instance;
private Harmony _harmony;
private DateTime _lastConfigWriteTime;
private DateTime _lastConfigReloadTime = DateTime.MinValue;
private float _configCheckTimer = 0f;
private const float CONFIG_CHECK_INTERVAL = 2f;
private const double CONFIG_RELOAD_DEBOUNCE_SECONDS = 3.0;
private static Dictionary<SkillType, ConfigEntry<float>> _skillLossConfig;
private void Awake()
{
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Expected O, but got Unknown
_instance = this;
InitializeConfig();
SetupConfigMonitoring();
_harmony = new Harmony("CustomSkillLoss");
_harmony.PatchAll();
((BaseUnityPlugin)this).Logger.LogInfo((object)"Custom Skill Loss 1.0.0 loaded!");
}
private void Update()
{
_configCheckTimer += Time.deltaTime;
if (_configCheckTimer >= 2f)
{
_configCheckTimer = 0f;
CheckConfigFileForChanges();
}
}
private void SetupConfigMonitoring()
{
try
{
if (File.Exists(((BaseUnityPlugin)this).Config.ConfigFilePath))
{
_lastConfigWriteTime = File.GetLastWriteTime(((BaseUnityPlugin)this).Config.ConfigFilePath);
}
else
{
_lastConfigWriteTime = DateTime.MinValue;
}
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogError((object)("Error setting up config monitoring: " + ex.Message));
}
}
private void CheckConfigFileForChanges()
{
try
{
if (!File.Exists(((BaseUnityPlugin)this).Config.ConfigFilePath))
{
return;
}
DateTime lastWriteTime = File.GetLastWriteTime(((BaseUnityPlugin)this).Config.ConfigFilePath);
if (lastWriteTime > _lastConfigWriteTime)
{
if ((DateTime.Now - _lastConfigReloadTime).TotalSeconds < 3.0)
{
_lastConfigWriteTime = lastWriteTime;
return;
}
_lastConfigWriteTime = lastWriteTime;
_lastConfigReloadTime = DateTime.Now;
Thread.Sleep(100);
((BaseUnityPlugin)this).Config.Reload();
((BaseUnityPlugin)this).Logger.LogInfo((object)"Config file reloaded successfully!");
}
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogError((object)("Error checking config file: " + ex.Message));
}
}
private void OnDestroy()
{
Harmony harmony = _harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
}
private void InitializeConfig()
{
//IL_0261: Unknown result type (might be due to invalid IL or missing references)
//IL_0266: Unknown result type (might be due to invalid IL or missing references)
//IL_0282: Unknown result type (might be due to invalid IL or missing references)
//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
//IL_02d0: Expected O, but got Unknown
_skillLossConfig = new Dictionary<SkillType, ConfigEntry<float>>();
Dictionary<SkillType, (string, string)> dictionary = new Dictionary<SkillType, (string, string)>
{
{
(SkillType)1,
("Combat Skills", "Swords")
},
{
(SkillType)2,
("Combat Skills", "Knives")
},
{
(SkillType)3,
("Combat Skills", "Clubs")
},
{
(SkillType)4,
("Combat Skills", "Polearms")
},
{
(SkillType)5,
("Combat Skills", "Spears")
},
{
(SkillType)6,
("Combat Skills", "Blocking")
},
{
(SkillType)7,
("Combat Skills", "Axes")
},
{
(SkillType)8,
("Combat Skills", "Bows")
},
{
(SkillType)14,
("Combat Skills", "Crossbows")
},
{
(SkillType)9,
("Combat Skills", "Elemental Magic")
},
{
(SkillType)10,
("Combat Skills", "Blood Magic")
},
{
(SkillType)11,
("Combat Skills", "Unarmed")
},
{
(SkillType)12,
("Utility Skills", "Pickaxes")
},
{
(SkillType)13,
("Utility Skills", "Woodcutting")
},
{
(SkillType)104,
("Utility Skills", "Fishing")
},
{
(SkillType)105,
("Crafting Skills", "Cooking")
},
{
(SkillType)107,
("Crafting Skills", "Crafting")
},
{
(SkillType)106,
("Crafting Skills", "Farming")
},
{
(SkillType)100,
("Movement Skills", "Jump")
},
{
(SkillType)102,
("Movement Skills", "Run")
},
{
(SkillType)101,
("Movement Skills", "Sneak")
},
{
(SkillType)103,
("Movement Skills", "Swim")
},
{
(SkillType)110,
("Movement Skills", "Ride")
},
{
(SkillType)108,
("Movement Skills", "Dodge")
}
};
foreach (KeyValuePair<SkillType, (string, string)> item in dictionary)
{
SkillType key = item.Key;
var (text, text2) = item.Value;
_skillLossConfig[key] = ((BaseUnityPlugin)this).Config.Bind<float>(text, text2 + " Loss %", 5f, new ConfigDescription("Percentage of " + text2.ToLower() + " skill lost on death (0-100)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>()));
}
}
public static float GetSkillLossPercentage(SkillType skillType)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
if (_skillLossConfig.TryGetValue(skillType, out var value))
{
return value.Value / 100f;
}
return 0.05f;
}
}
[HarmonyPatch(typeof(Skills), "OnDeath")]
public static class SkillsOnDeathPatch
{
private static bool Prefix(Skills __instance)
{
//IL_0099: Unknown result type (might be due to invalid IL or missing references)
//IL_009e: 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)
FieldInfo field = typeof(Skills).GetField("m_skillData", BindingFlags.Instance | BindingFlags.NonPublic);
if (field == null)
{
Debug.LogError((object)"CustomSkillLoss: Could not find skill data field");
return true;
}
object value = field.GetValue(__instance);
if (!(value is IDictionary dictionary))
{
Debug.LogError((object)"CustomSkillLoss: Skill data is not a dictionary");
return true;
}
int num = 0;
foreach (DictionaryEntry item in dictionary)
{
if (item.Key is SkillType skillType && item.Value != null && ProcessSkillData(item.Value, skillType))
{
num++;
}
}
if ((Object)(object)Player.m_localPlayer != (Object)null && num > 0)
{
((Character)Player.m_localPlayer).Message((MessageType)1, "$msg_skills_lowered", 0, (Sprite)null);
}
return false;
}
private static bool ProcessSkillData(object skillData, SkillType skillType)
{
//IL_00b8: 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)
try
{
Type type = skillData.GetType();
FieldInfo field = type.GetField("m_level", BindingFlags.Instance | BindingFlags.Public);
FieldInfo field2 = type.GetField("m_accumulator", BindingFlags.Instance | BindingFlags.Public);
if (field == null)
{
return false;
}
float num = (float)field.GetValue(skillData);
float skillLossPercentage = CustomSkillLossPlugin.GetSkillLossPercentage(skillType);
if (skillLossPercentage > 0f && num > 0f)
{
float num2 = num * skillLossPercentage;
float num3 = Mathf.Max(0f, num - num2);
field.SetValue(skillData, num3);
field2?.SetValue(skillData, 0f);
return true;
}
return false;
}
catch (Exception ex)
{
Debug.LogError((object)$"CustomSkillLoss: Error processing {skillType}: {ex.Message}");
return false;
}
}
}