using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using WeaponSkillsSync;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("WeaponSkillsLevelTogether")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("WeaponSkillsLevelTogether")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("07cd1074-d4f3-4ba1-9f82-d9cf6f5159ab")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
[HarmonyPatch(typeof(Skills), "RaiseSkill")]
public static class SkillPatch
{
private static readonly FieldInfo skillDataField = AccessTools.Field(typeof(Skills), "m_skillData");
private static bool isSyncing = false;
private static double lastSyncTime = 0.0;
private static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
private static readonly List<SkillType> combatSkills = new List<SkillType>();
private static void Postfix(Skills __instance)
{
//IL_0358: Unknown result type (might be due to invalid IL or missing references)
//IL_0368: Unknown result type (might be due to invalid IL or missing references)
//IL_036d: Unknown result type (might be due to invalid IL or missing references)
//IL_0372: Unknown result type (might be due to invalid IL or missing references)
//IL_040b: Unknown result type (might be due to invalid IL or missing references)
//IL_0417: Unknown result type (might be due to invalid IL or missing references)
//IL_03d3: Unknown result type (might be due to invalid IL or missing references)
//IL_03d5: Unknown result type (might be due to invalid IL or missing references)
//IL_042f: Unknown result type (might be due to invalid IL or missing references)
//IL_043f: Unknown result type (might be due to invalid IL or missing references)
//IL_0441: Unknown result type (might be due to invalid IL or missing references)
//IL_0249: Unknown result type (might be due to invalid IL or missing references)
double totalSeconds = (DateTime.UtcNow - UnixEpoch).TotalSeconds;
if (totalSeconds - lastSyncTime < 1.0)
{
return;
}
lastSyncTime = totalSeconds;
if (isSyncing)
{
return;
}
isSyncing = true;
combatSkills.Clear();
if (SkillSyncConfig.SyncSwords.Value)
{
combatSkills.Add((SkillType)1);
}
if (SkillSyncConfig.SyncKnives.Value)
{
combatSkills.Add((SkillType)2);
}
if (SkillSyncConfig.SyncClubs.Value)
{
combatSkills.Add((SkillType)3);
}
if (SkillSyncConfig.SyncPolearms.Value)
{
combatSkills.Add((SkillType)4);
}
if (SkillSyncConfig.SyncSpears.Value)
{
combatSkills.Add((SkillType)5);
}
if (SkillSyncConfig.SyncAxes.Value)
{
combatSkills.Add((SkillType)7);
}
if (SkillSyncConfig.SyncBows.Value)
{
combatSkills.Add((SkillType)8);
}
if (SkillSyncConfig.SyncUnarmed.Value)
{
combatSkills.Add((SkillType)11);
}
if (SkillSyncConfig.SyncCrossbows.Value)
{
combatSkills.Add((SkillType)14);
}
if (SkillSyncConfig.SyncBloodMagic.Value)
{
combatSkills.Add((SkillType)10);
}
if (SkillSyncConfig.SyncElementalMagic.Value)
{
combatSkills.Add((SkillType)9);
}
List<List<SkillType>> list = new List<List<SkillType>>();
if (SkillSyncConfig.SkillGroups.Value.Length > 0)
{
string value = SkillSyncConfig.SkillGroups.Value;
string[] array = value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries);
string[] array2 = array;
foreach (string text in array2)
{
string text2 = text.Trim('(', ')');
string[] array3 = text2.Split(new char[1] { ';' });
List<SkillType> list2 = new List<SkillType>();
string[] array4 = array3;
foreach (string text3 in array4)
{
if (Enum.TryParse<SkillType>(text3.Trim(), out SkillType result))
{
list2.Add(result);
}
}
list.Add(list2);
}
}
list.Add(combatSkills);
try
{
float num = 1f;
int value2 = SkillSyncConfig.SyncStrength.Value;
try
{
value2 = Math.Max(0, Math.Min(100, value2));
num = (float)value2 / 100f;
}
catch
{
num = 1f;
}
float num2 = 1f;
int value3 = SkillSyncConfig.ExtraSyncStrength.Value;
try
{
value3 = Math.Max(0, Math.Min(100, value3));
num2 = (float)value3 / 100f;
if (value3 == 0)
{
num2 = num;
}
}
catch
{
num2 = 1f;
}
foreach (List<SkillType> item in list)
{
Dictionary<SkillType, Skill> dictionary = (Dictionary<SkillType, Skill>)skillDataField.GetValue(__instance);
int num3 = 0;
float num4 = 0f;
float num5 = 0f;
SkillType val = (SkillType)0;
foreach (SkillType item2 in item)
{
if (dictionary.TryGetValue(item2, out var value4))
{
int num6 = (int)Math.Floor(value4.m_level);
if (num3 < num6 || (num3 == num6 && num5 < value4.m_accumulator))
{
num3 = num6;
num5 = value4.m_accumulator;
num4 = getTotal(num6, value4.m_accumulator);
val = item2;
}
}
}
SkillType[] array5 = item.ToArray();
foreach (SkillType val2 in array5)
{
float num7 = num;
if (!combatSkills.Contains(val2))
{
num = num2;
}
if (dictionary.TryGetValue(val2, out var value5) && val2 != val)
{
int num8 = getLevel(num4 * num);
if (value5.m_level < (float)num8)
{
value5.m_level = num8;
}
float accumulator = num4 * num - getTotal(num8, 0f);
value5.m_accumulator = accumulator;
}
num = num7;
}
}
}
finally
{
isSyncing = false;
}
static int getLevel(float total)
{
int num9 = 0;
float num10 = 0f;
while (true)
{
float xpReq = getXpReq(num9);
if (num10 + xpReq > total)
{
break;
}
num10 += xpReq;
num9++;
}
return num9;
}
static float getTotal(int level, float xp)
{
float num11 = 0f;
for (int l = 0; l < level; l++)
{
num11 += getXpReq(l);
}
return num11 + xp;
}
static float getXpReq(int level)
{
return (float)(Math.Pow(level + 1, 1.5) / 2.0 + 0.5);
}
}
}
namespace WeaponSkillsSync;
[BepInPlugin("grat.WeaponSkillsSync", "Weapon Skills Sync", "1.2.6")]
public class SkillSyncConfig : BaseUnityPlugin
{
public static ConfigEntry<int> SyncStrength;
public static ConfigEntry<bool> SyncSwords;
public static ConfigEntry<bool> SyncKnives;
public static ConfigEntry<bool> SyncClubs;
public static ConfigEntry<bool> SyncPolearms;
public static ConfigEntry<bool> SyncSpears;
public static ConfigEntry<bool> SyncAxes;
public static ConfigEntry<bool> SyncBows;
public static ConfigEntry<bool> SyncUnarmed;
public static ConfigEntry<bool> SyncCrossbows;
public static ConfigEntry<bool> SyncBloodMagic;
public static ConfigEntry<bool> SyncElementalMagic;
public static ConfigEntry<int> ExtraSyncStrength;
public static ConfigEntry<string> SkillGroups;
public static readonly List<List<SkillType>> ParsedGroups = new List<List<SkillType>>();
private void Awake()
{
//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
//IL_01d1: Expected O, but got Unknown
SyncStrength = ((BaseUnityPlugin)this).Config.Bind<int>("General", "Sync Strength", 100, "How strong the syncing effect is as a percentage between 0 and 100. Also affects additional sync groups.\nWorks based off of total XP gained in a skill, rather than raw level amount. \nDefault value is 100. Lowering this config will not lower any currently synced skill levels.");
SyncSwords = ((BaseUnityPlugin)this).Config.Bind<bool>("Toggle Skills", "Swords", true, "Enable syncing Swords skill");
SyncKnives = ((BaseUnityPlugin)this).Config.Bind<bool>("Toggle Skills", "Knives", true, "Enable syncing Knives skill");
SyncClubs = ((BaseUnityPlugin)this).Config.Bind<bool>("Toggle Skills", "Clubs", true, "Enable syncing Clubs skill");
SyncPolearms = ((BaseUnityPlugin)this).Config.Bind<bool>("Toggle Skills", "Polearms", true, "Enable syncing Polearms skill");
SyncSpears = ((BaseUnityPlugin)this).Config.Bind<bool>("Toggle Skills", "Spears", true, "Enable syncing Spears skill");
SyncAxes = ((BaseUnityPlugin)this).Config.Bind<bool>("Toggle Skills", "Axes", true, "Enable syncing Axes skill");
SyncBows = ((BaseUnityPlugin)this).Config.Bind<bool>("Toggle Skills", "Bows", true, "Enable syncing Bows skill");
SyncUnarmed = ((BaseUnityPlugin)this).Config.Bind<bool>("Toggle Skills", "Unarmed", true, "Enable syncing Unarmed skill");
SyncCrossbows = ((BaseUnityPlugin)this).Config.Bind<bool>("Toggle Skills", "Crossbows", true, "Enable syncing Crossbows skill");
SyncBloodMagic = ((BaseUnityPlugin)this).Config.Bind<bool>("Toggle Skills", "BloodMagic", true, "Enable syncing Blood Magic skill");
SyncElementalMagic = ((BaseUnityPlugin)this).Config.Bind<bool>("Toggle Skills", "ElementalMagic", true, "Enable syncing Elemental Magic skill");
ExtraSyncStrength = ((BaseUnityPlugin)this).Config.Bind<int>("Extra", "Extra Sync Strength", 0, "Works exactly the same as Sync Strength, but applies only to additional sync groups. \nSetting this value to anything other than 0 will cause additional sync groups to use this value rather than the regular Sync Strength.. \nLeave at 0 to use the regular Sync Strength for additional sync groups. \nThis applies to all additional sync groups, and does not affect the weapon skills.");
SkillGroups = ((BaseUnityPlugin)this).Config.Bind<string>("Extra", "Additional Sync Groups:", "", "Add additional skill groups here if you want to sync more skills than just weapon skills.\n\nThis is seperate from the main default functionality of the mod, and groups will have seperate levels and will not sync with eachother.\n\nFormat: (Skill1;Skill2...),(Skill1;Skill2...)\nExample: (Run;Swim),(Blocking;Sneak;Dodge)\nIn the example above, the Running and Swimming skills will sync, and the Blocking, Sneaking, and Dodging skills will sync.\n\nSkill names must match the internal skill IDs. Valid skills:\nAxes, Blocking, BloodMagic, Bows, Clubs, Cooking, Crafting, Crossbows, Dodge, ElementalMagic, Farming, Fishing, Jump, Knives, Pickaxes, Polearms, Ride, Run, Sneak, Spears, Swim, Swords, Unarmed, WoodCutting.");
Harmony val = new Harmony("gratalat.WeaponSkillsSync");
val.PatchAll();
((BaseUnityPlugin)this).Logger.LogInfo((object)"Weapon Skills Sync loaded successfully.");
}
}