Decompiled source of ValkreamPlus v1.0.3

ValkreamPlus.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using HarmonyLib;
using Jewelcrafting;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using SimpleJson;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("ValkreamPlus")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ValkreamPlus")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: AssemblyFileVersion("1.0.3")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.3.0")]
[module: UnverifiableCode]
namespace ValkreamPlus;

[BepInPlugin("com.jotunn.ValkreamPlus", "ValkreamPlus", "1.0.3")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
internal class ValkreamPlus : BaseUnityPlugin
{
	public class SE_CollierValkream : StatusEffect
	{
		public float m_eitr;

		public float m_skillup;

		public float m_regenModifier;

		public void SetEitr(float eitr)
		{
			m_eitr = eitr;
		}

		public void SetSkill(float skill)
		{
			m_skillup = skill;
		}

		public void SetRegenModifier(float regenModifier)
		{
			m_regenModifier = regenModifier;
		}

		public override void ModifyEitrRegen(ref float regen)
		{
			regen *= m_regenModifier;
		}

		public override void ModifySkillLevel(SkillType skill, ref float value)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			if ((int)skill == 10 || (int)skill == 9)
			{
				value += m_skillup;
			}
		}
	}

	[HarmonyPatch(typeof(Player), "GetTotalFoodValue")]
	public static class EitrFromItemsPatch
	{
		[HarmonyPostfix]
		private static void Postfix(Player __instance, ref float eitr)
		{
			if (((Character)(__instance?)).m_seman == null)
			{
				return;
			}
			foreach (StatusEffect statusEffect in ((Character)__instance).m_seman.m_statusEffects)
			{
				if (statusEffect is SE_CollierValkream sE_CollierValkream && sE_CollierValkream.m_eitr != 0f)
				{
					eitr += sE_CollierValkream.m_eitr;
				}
			}
		}
	}

	[HarmonyPatch]
	public static class Patch_IsNeckItem
	{
		private static MethodBase TargetMethod()
		{
			if (!Chainloader.PluginInfos.TryGetValue("org.bepinex.plugins.jewelcrafting", out var value))
			{
				return null;
			}
			Assembly assembly = ((object)value.Instance).GetType().Assembly;
			Type type = assembly.GetType("Jewelcrafting.Visual");
			if (type == null)
			{
				return null;
			}
			return AccessTools.Method(type, "IsNeckItem", (Type[])null, (Type[])null);
		}

		private static void Postfix(ItemData item, ref bool __result)
		{
			object obj;
			if (item == null)
			{
				obj = null;
			}
			else
			{
				GameObject dropPrefab = item.m_dropPrefab;
				obj = ((dropPrefab != null) ? ((Object)dropPrefab).name : null);
			}
			if ((string?)obj == "JC_Necklace_Valkream")
			{
				__result = true;
			}
		}
	}

	[HarmonyPatch(typeof(Player), "GetBodyArmor")]
	public static class AddNecklaceArmorPatch
	{
		public static void Postfix(Player __instance, ref float __result)
		{
			if (!((Object)(object)__instance == (Object)null) && TryGetEquippedNeckItem(__instance, out var neck) && (Object)(object)neck?.m_dropPrefab != (Object)null && ((Object)neck.m_dropPrefab).name == "JC_Necklace_Valkream")
			{
				__result += CalcArmor(neck);
			}
		}

		private static float CalcArmor(ItemData item)
		{
			SharedData shared = item.m_shared;
			int num = Mathf.Max(1, item.m_quality);
			return shared.m_armor + shared.m_armorPerLevel * (float)(num - 1);
		}

		private static bool TryGetEquippedNeckItem(Player p, out ItemData neck)
		{
			neck = null;
			Type type = AccessTools.TypeByName("Jewelcrafting.Visual");
			if (type == null)
			{
				return false;
			}
			FieldInfo fieldInfo = AccessTools.Field(type, "visuals");
			if (fieldInfo == null)
			{
				return false;
			}
			object value = fieldInfo.GetValue(null);
			if (value == null)
			{
				return false;
			}
			MethodInfo method = value.GetType().GetMethod("TryGetValue");
			if (method == null)
			{
				return false;
			}
			object[] array = new object[2]
			{
				((Humanoid)p).m_visEquipment,
				null
			};
			if (!(bool)method.Invoke(value, array) || array[1] == null)
			{
				return false;
			}
			object obj = array[1];
			FieldInfo fieldInfo2 = AccessTools.Field(obj.GetType(), "equippedNeckItem");
			if (fieldInfo2 == null)
			{
				return false;
			}
			object? value2 = fieldInfo2.GetValue(obj);
			neck = (ItemData)((value2 is ItemData) ? value2 : null);
			return neck != null;
		}
	}

	[HarmonyPatch(typeof(ItemData), "GetTooltip", new Type[]
	{
		typeof(ItemData),
		typeof(int),
		typeof(bool),
		typeof(float),
		typeof(int)
	})]
	public static class NecklaceArmorTooltipPatch
	{
		[HarmonyPostfix]
		public static void Postfix(ItemData item, int qualityLevel, float worldLevel, ref string __result)
		{
			if ((Object)(object)item?.m_dropPrefab == (Object)null || ((Object)item.m_dropPrefab).name != "JC_Necklace_Valkream")
			{
				return;
			}
			string text = Localization.instance.Localize("$item_armor");
			string value = Localization.instance.Localize("$item_quality");
			if (__result.IndexOf(text, StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return;
			}
			float num = item.m_shared.m_armor + item.m_shared.m_armorPerLevel * (float)Mathf.Max(0, qualityLevel - 1);
			string text2 = $"\n{text}: <color=orange>{num:0}</color>";
			int num2 = __result.IndexOf(value, StringComparison.OrdinalIgnoreCase);
			if (num2 >= 0)
			{
				int num3 = __result.IndexOf('\n', num2);
				if (num3 < 0)
				{
					num3 = __result.Length;
				}
				__result = __result.Insert(num3, text2);
			}
			else
			{
				__result = text2 + "\n" + __result;
			}
		}
	}

	public const string PluginGUID = "com.jotunn.ValkreamPlus";

	public const string PluginName = "ValkreamPlus";

	public const string PluginVersion = "1.0.3";

	public static CustomLocalization Localization = LocalizationManager.Instance.GetLocalization();

	private void Awake()
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		AddLocalizations();
		PrefabManager.OnVanillaPrefabsAvailable += AddCollierValkream;
		new Harmony("com.jotunn.ValkreamPlus").PatchAll();
		AddJetonsValkream();
	}

	public static Sprite LoadEmbeddedSprite(string resourcePath)
	{
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Expected O, but got Unknown
		//IL_009d: 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)
		Assembly assembly = typeof(ValkreamPlus).Assembly;
		using Stream stream = assembly.GetManifestResourceStream(resourcePath);
		if (stream == null)
		{
			Logger.LogWarning((object)("Embedded resource '" + resourcePath + "' not found."));
			return null;
		}
		byte[] array;
		using (MemoryStream memoryStream = new MemoryStream())
		{
			stream.CopyTo(memoryStream);
			array = memoryStream.ToArray();
		}
		Texture2D val = new Texture2D(2, 2);
		if (!ImageConversion.LoadImage(val, array))
		{
			Logger.LogWarning((object)"Failed to load texture from embedded resource.");
			return null;
		}
		Rect val2 = default(Rect);
		((Rect)(ref val2))..ctor(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height);
		return Sprite.Create(val, val2, new Vector2(0.5f, 0.5f));
	}

	private void AddCollierValkream()
	{
		//IL_001c: 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_0043: Expected O, but got Unknown
		//IL_015e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0165: Expected O, but got Unknown
		PrefabManager.OnVanillaPrefabsAvailable -= AddCollierValkream;
		GameObject val = API.CreateNecklaceFromTemplate("Red", Color.red);
		API.MarkJewelry(val);
		((Object)val).name = "JC_Necklace_Valkream";
		ItemConfig collierValkreamConfig = new ItemConfig();
		collierValkreamConfig.Name = "$item_colliervalkream";
		collierValkreamConfig.Description = "$item_colliervalkream_desc";
		Sprite val2 = LoadEmbeddedSprite("ValkreamPlus.Assets.CollierValkreamIcon6.png");
		collierValkreamConfig.Icon = val2;
		collierValkreamConfig.AddRequirement("ValkreamCoinsV2", 20, 10);
		collierValkreamConfig.CraftingStation = "piece_workbench";
		collierValkreamConfig.RepairStation = "piece_workbench";
		SharedData shared = val.GetComponent<ItemDrop>().m_itemData.m_shared;
		shared.m_icons = (Sprite[])(object)new Sprite[1] { val2 };
		shared.m_armor = 1f;
		shared.m_armorPerLevel = 1f;
		RegisterAsUpgradeableJewelry(shared.m_name);
		SE_CollierValkream sE_CollierValkream = ScriptableObject.CreateInstance<SE_CollierValkream>();
		((Object)sE_CollierValkream).name = "SE_CollierValkream";
		((StatusEffect)sE_CollierValkream).m_name = "Collier Valkream";
		((StatusEffect)sE_CollierValkream).m_icon = shared.m_icons[0];
		((StatusEffect)sE_CollierValkream).m_tooltip = "Le pouvoir des dieux de Valkream vous imprègne. Cela vous offre +10 aux skills de magie, +30% de regen d'eitr et +50 d'eitr maximal.";
		sE_CollierValkream.SetEitr(50f);
		sE_CollierValkream.SetSkill(11f);
		sE_CollierValkream.SetRegenModifier(1.3f);
		shared.m_equipStatusEffect = (StatusEffect)(object)sE_CollierValkream;
		CustomItem val3 = new CustomItem(val, false, collierValkreamConfig);
		ItemManager.Instance.AddItem(val3);
		ItemManager.OnItemsRegistered += delegate
		{
			GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("JC_Necklace_Valkream");
			ItemDrop val4 = ((itemPrefab != null) ? itemPrefab.GetComponent<ItemDrop>() : null);
			if ((Object)(object)val4 != (Object)null)
			{
				val4.m_itemData.m_shared.m_icons = (Sprite[])(object)new Sprite[1] { collierValkreamConfig.Icon };
			}
		};
	}

	private static void RegisterAsUpgradeableJewelry(string sharedName)
	{
		try
		{
			if (!Chainloader.PluginInfos.TryGetValue("org.bepinex.plugins.jewelcrafting", out var value))
			{
				Logger.LogWarning((object)"Jewelcrafting not found; skip jewelry registration.");
				return;
			}
			Assembly assembly = ((object)value.Instance).GetType().Assembly;
			Type[] types = assembly.GetTypes();
			foreach (Type type in types)
			{
				FieldInfo field = type.GetField("upgradeableJewelry", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null && typeof(HashSet<string>).IsAssignableFrom(field.FieldType))
				{
					HashSet<string> hashSet = (HashSet<string>)field.GetValue(null);
					if (hashSet.Add(sharedName))
					{
						Logger.LogInfo((object)("[ValkreamPlus] Registered '" + sharedName + "' as upgradeable jewelry via " + type.FullName + ".upgradeableJewelry"));
					}
					return;
				}
			}
			Logger.LogWarning((object)"Could not find 'upgradeableJewelry' field in Jewelcrafting assembly.");
		}
		catch (Exception arg)
		{
			Logger.LogError((object)$"Failed to register upgradeable jewelry: {arg}");
		}
	}

	private void AddJetonsValkream()
	{
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Expected O, but got Unknown
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Expected O, but got Unknown
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Expected O, but got Unknown
		string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
		AssetBundle val = AssetUtils.LoadAssetBundleFromResources("customcoins");
		GameObject val2 = val.LoadAsset<GameObject>("assets/custombb/admincoinsv2.prefab");
		GameObject val3 = val.LoadAsset<GameObject>("assets/custombb/lordscoinsv2.prefab");
		GameObject val4 = val.LoadAsset<GameObject>("assets/custombb/valkreamcoinsv2.prefab");
		CustomItem val5 = new CustomItem(val2, true);
		ItemManager.Instance.AddItem(val5);
		CustomItem val6 = new CustomItem(val3, true);
		ItemManager.Instance.AddItem(val6);
		CustomItem val7 = new CustomItem(val4, true);
		ItemManager.Instance.AddItem(val7);
	}

	private void AddLocalizations()
	{
		CustomLocalization localization = LocalizationManager.Instance.GetLocalization();
		string configPath = Paths.ConfigPath;
		if (!Directory.Exists(configPath))
		{
			Logger.LogWarning((object)("Config path not found: " + configPath));
			return;
		}
		List<string> list = (from x in (from dir in Directory.EnumerateDirectories(configPath, "*", SearchOption.AllDirectories)
				where string.Equals(Path.GetFileName(dir), "ValkreamPlus", StringComparison.OrdinalIgnoreCase)
				select new
				{
					Path = dir,
					Depth = dir.TrimEnd(new char[1] { Path.DirectorySeparatorChar }).Count((char c) => c == Path.DirectorySeparatorChar)
				} into x
				orderby x.Depth
				select x).ThenBy(x => x.Path, StringComparer.OrdinalIgnoreCase)
			select x.Path).ToList();
		if (list.Count == 0)
		{
			Logger.LogWarning((object)("No 'ValkreamPlus' directory for translations found anywhere under: " + configPath));
			return;
		}
		HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
		foreach (string item in list)
		{
			foreach (string item2 in Directory.EnumerateFiles(item, "*.json", SearchOption.AllDirectories).OrderBy<string, string>((string f) => f, StringComparer.OrdinalIgnoreCase))
			{
				if (!hashSet.Add(item2))
				{
					continue;
				}
				string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(item2);
				try
				{
					string text = File.ReadAllText(item2);
					Dictionary<string, string> dictionary = SimpleJson.DeserializeObject<Dictionary<string, string>>(text);
					if (dictionary == null)
					{
						Logger.LogWarning((object)("Empty or invalid JSON in " + item2));
						continue;
					}
					int num = 0;
					foreach (KeyValuePair<string, string> item3 in dictionary)
					{
						try
						{
							string key = item3.Key;
							localization.AddTranslation(ref fileNameWithoutExtension, ref key, item3.Value);
							num++;
						}
						catch (Exception ex)
						{
							Logger.LogWarning((object)("Could not add key '" + item3.Key + "' from " + item2 + ": " + ex.Message));
						}
					}
				}
				catch (Exception ex2)
				{
					Logger.LogError((object)("Failed to load localization from " + item2 + ": " + ex2.Message));
				}
			}
		}
	}
}