Decompiled source of Broken Ruunes Gallant Knight Set v1.0.1

plugins/GallantKnightBlade.dll

Decompiled 4 days ago
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using SideLoader;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: CompilationRelaxations(8)]
[assembly: AssemblyVersion("0.0.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("local.dylan.gallantknightblade", "Gallant Knight Blade", "1.0.6")]
public sealed class GallantKnightBlade : BaseUnityPlugin
{
	private const string PluginId = "local.dylan.gallantknightblade";

	private const int BladeId = -847390;

	private const int IronSwordId = 2000010;

	private const int ShopPrice = 10000;

	private const float BladeDamage = 30f;

	private const float FireDamage = 10f;

	private const string BlacksmithId = "3Rx_R0XDLUmYaNWm66SVCQ";

	private const string TokugaNormalPriceId = "EYhBqM653UGhDd5kcdMFXg";

	private const string HowardBrockId = "Zdg-qTDRa0-qOzzNSbtvzg";

	private const string SalDumasId = "QyJwLKySB0epxpEG3EBICQ";

	private const string MaterialName = "mat_itm_longsword";

	private const string GallantMaterialName = "mat_itm_GallantKnightBlade";

	private static ConfigEntry<string> seededInventories;

	private static HashSet<string> seededInventoryKeys;

	private static readonly int MainTex = Shader.PropertyToID("_MainTex");

	private static readonly int GenTex = Shader.PropertyToID("_GenTex");

	private static readonly int NormTex = Shader.PropertyToID("_NormTex");

	private static Texture2D albedo;

	private static Texture2D surface;

	private static Texture2D normals;

	private static ManualLogSource log;

	private void Awake()
	{
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Expected O, but got Unknown
		//IL_00df: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ec: Expected O, but got Unknown
		//IL_012c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0132: Expected O, but got Unknown
		//IL_0182: Unknown result type (might be due to invalid IL or missing references)
		//IL_018f: Expected O, but got Unknown
		//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f2: Expected O, but got Unknown
		//IL_0243: Unknown result type (might be due to invalid IL or missing references)
		//IL_0258: Unknown result type (might be due to invalid IL or missing references)
		//IL_0265: Expected O, but got Unknown
		//IL_0265: Expected O, but got Unknown
		//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c0: Expected O, but got Unknown
		log = ((BaseUnityPlugin)this).Logger;
		seededInventories = ((BaseUnityPlugin)this).Config.Bind<string>("Blacksmiths", "SeededStock", "", "Internal record of saves where the initial Gallant Knight Blade stock has been added.");
		seededInventoryKeys = new HashSet<string>(seededInventories.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries), StringComparer.Ordinal);
		Type type = AccessTools.TypeByName("SideLoader.CustomItemVisuals");
		MethodInfo methodInfo = AccessTools.Method(type, "CloneAndSetVisuals", (Type[])null, (Type[])null);
		if (methodInfo == null)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)"Could not find SideLoader's visual cloning method.");
			return;
		}
		albedo = LoadTexture("GallantKnightAlbedo", linear: false);
		surface = LoadTexture("GallantKnightSurface", linear: true);
		normals = LoadTexture("GallantKnightNormal", linear: true);
		Harmony val = new Harmony("local.dylan.gallantknightblade");
		val.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(GallantKnightBlade), "RecolorClone", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		MethodInfo methodInfo2 = AccessTools.Method(typeof(VisualSlot), "PositionVisuals", new Type[1] { typeof(Item) }, (Type[])null);
		HarmonyMethod val2 = new HarmonyMethod(typeof(GallantKnightBlade), "CheckEquippedVisual", (Type[])null);
		val2.priority = 0;
		val.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		val.Patch((MethodBase)AccessTools.Method(typeof(SL_MeleeWeapon), "ApplyToItem", new Type[1] { typeof(Item) }, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(GallantKnightBlade), "ApplyBladeDamage", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		MethodInfo methodInfo3 = AccessTools.Method(typeof(Item), "GetBuyValue", new Type[3]
		{
			typeof(Character),
			typeof(Merchant),
			typeof(bool)
		}, (Type[])null);
		HarmonyMethod val3 = new HarmonyMethod(typeof(GallantKnightBlade), "SetBlacksmithPrice", (Type[])null);
		val3.priority = 0;
		val.Patch((MethodBase)methodInfo3, (HarmonyMethod)null, val3, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		val.Patch((MethodBase)AccessTools.Method(typeof(MerchantPouch), "RefreshInventory", new Type[1] { typeof(Dropable) }, (Type[])null), new HarmonyMethod(typeof(GallantKnightBlade), "BeforeRestock", (Type[])null), new HarmonyMethod(typeof(GallantKnightBlade), "AfterRestock", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		val.Patch((MethodBase)AccessTools.Method(typeof(Merchant), "OnReceiveConfirmStartShopping", new Type[2]
		{
			typeof(bool),
			typeof(Character)
		}, (Type[])null), new HarmonyMethod(typeof(GallantKnightBlade), "SeedExistingStock", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
	}

	private static Texture2D LoadTexture(string resource, bool linear)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Expected O, but got Unknown
		Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true, linear);
		((Object)val).name = resource;
		((Texture)val).anisoLevel = 4;
		Texture2D val2 = val;
		using Stream stream = typeof(GallantKnightBlade).Assembly.GetManifestResourceStream(resource);
		using MemoryStream memoryStream = new MemoryStream();
		stream.CopyTo(memoryStream);
		if (!ImageConversion.LoadImage(val2, memoryStream.ToArray(), true))
		{
			throw new InvalidDataException("Could not decode " + resource);
		}
		return val2;
	}

	private static void RecolorClone(Item __0, GameObject __1, GameObject __result)
	{
		if (!Object.op_Implicit((Object)(object)__0) || !Object.op_Implicit((Object)(object)__result) || (Object)(object)__result == (Object)(object)__1)
		{
			return;
		}
		int itemID = __0.ItemID;
		if (itemID != -847390)
		{
			return;
		}
		string name = ((Object)__result).name;
		string text = name.Substring(name.IndexOf('_') + 1);
		((Object)__result).name = itemID.ToString(CultureInfo.InvariantCulture) + "_" + text.Replace("IronSword", "GallantKnightBlade").Replace("(Clone)", "");
		ItemVisual component = __result.GetComponent<ItemVisual>();
		if (!Object.op_Implicit((Object)(object)component) || component.GetItemIDFromName() != itemID)
		{
			log.LogError((object)"Could not assign the Gallant Knight Blade model to its own visual pool.");
			return;
		}
		int num = ApplyBladeMaterial(__result);
		if (num == 0)
		{
			log.LogWarning((object)("No Iron Sword material found on " + ((Object)__result).name));
			return;
		}
		log.LogInfo((object)("Assigned " + num + " private Gallant Knight Blade material(s) to item " + itemID + " on " + ((Object)__result).name + " (visual pool " + component.GetItemIDFromName() + ")"));
	}

	private static int ApplyBladeMaterial(GameObject model)
	{
		//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f1: Expected O, but got Unknown
		int num = 0;
		Renderer[] componentsInChildren = model.GetComponentsInChildren<Renderer>(true);
		foreach (Renderer val in componentsInChildren)
		{
			Material[] sharedMaterials = val.sharedMaterials;
			bool flag = false;
			for (int j = 0; j < sharedMaterials.Length; j++)
			{
				Material val2 = sharedMaterials[j];
				if (Object.op_Implicit((Object)(object)val2) && val2.HasProperty(MainTex) && val2.HasProperty(GenTex) && val2.HasProperty(NormTex))
				{
					if ((Object)(object)val2.GetTexture(MainTex) == (Object)(object)albedo && (Object)(object)val2.GetTexture(GenTex) == (Object)(object)surface && (Object)(object)val2.GetTexture(NormTex) == (Object)(object)normals)
					{
						num++;
					}
					else if (((Object)val2).name.StartsWith("mat_itm_longsword", StringComparison.OrdinalIgnoreCase) || ((Object)val2).name.StartsWith("mat_itm_GallantKnightBlade", StringComparison.OrdinalIgnoreCase))
					{
						Material val3 = new Material(val2);
						((Object)val3).name = "mat_itm_GallantKnightBlade";
						Material val4 = val3;
						val4.SetTexture(MainTex, (Texture)(object)albedo);
						val4.SetTexture(GenTex, (Texture)(object)surface);
						val4.SetTexture(NormTex, (Texture)(object)normals);
						sharedMaterials[j] = val4;
						flag = true;
						num++;
					}
				}
			}
			if (flag)
			{
				val.sharedMaterials = sharedMaterials;
			}
		}
		return num;
	}

	private static void CheckEquippedVisual(VisualSlot __instance, Item __0)
	{
		if (!Object.op_Implicit((Object)(object)__0) || __0.ItemID != -847390)
		{
			return;
		}
		ItemVisual currentVisual = __instance.CurrentVisual;
		if (Object.op_Implicit((Object)(object)currentVisual))
		{
			if (currentVisual.GetItemIDFromName() != -847390)
			{
				log.LogWarning((object)("Gallant Knight Blade was equipped with a different visual pool: " + ((Object)currentVisual).name));
				return;
			}
			int num = ApplyBladeMaterial(((Component)currentVisual).gameObject);
			log.LogInfo((object)("Gallant Knight Blade equip check: " + ((Object)currentVisual).name + " has " + num + " blade material(s) with its custom color, reflection and normal maps."));
		}
	}

	private static void ApplyBladeDamage(Item __0)
	{
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c5: Expected O, but got Unknown
		//IL_0193: Unknown result type (might be due to invalid IL or missing references)
		//IL_019a: Expected O, but got Unknown
		Weapon val = (Weapon)(object)((__0 is Weapon) ? __0 : null);
		if (!Object.op_Implicit((Object)(object)val) || ((Item)val).ItemID != -847390)
		{
			return;
		}
		WeaponStats component = ((Component)val).GetComponent<WeaponStats>();
		Item itemPrefab = ResourcesPrefabManager.Instance.GetItemPrefab(2000010);
		WeaponStats val2 = (Object.op_Implicit((Object)(object)itemPrefab) ? ((Component)itemPrefab).GetComponent<WeaponStats>() : null);
		if (!Object.op_Implicit((Object)(object)component) || !Object.op_Implicit((Object)(object)val2) || val2.BaseDamage == null || val2.BaseDamage.TotalDamage <= 0f || val2.Attacks == null)
		{
			log.LogWarning((object)"Could not find the Iron Sword damage data for Gallant Knight Blade.");
			return;
		}
		float totalDamage = val2.BaseDamage.TotalDamage;
		float num = 30f / totalDamage;
		DamageList val3 = val2.BaseDamage.Clone() * num;
		val3.Add(new DamageType((Types)5, 10f));
		component.BaseDamage = val3;
		AttackData[] array = (AttackData[])val2.Attacks.Clone();
		for (int i = 0; i < array.Length; i++)
		{
			AttackData val4 = array[i];
			if (val4 == null || val4.Damage == null || val4.Damage.Count == 0)
			{
				continue;
			}
			List<float> list = new List<float>(val4.Damage);
			for (int j = 0; j < list.Count; j++)
			{
				if (list[j] >= 0f)
				{
					list[j] *= num;
				}
			}
			float num2 = val4.Damage[0];
			list.Add((num2 < 0f) ? num2 : (10f * num2 / totalDamage));
			int num3 = i;
			AttackData val5 = new AttackData();
			val5.Damage = list;
			val5.Knockback = val4.Knockback;
			val5.StamCost = val4.StamCost;
			val5.AttackSpeed = val4.AttackSpeed;
			array[num3] = val5;
		}
		component.Attacks = array;
		((Item)val).InitCachedInfos();
		log.LogInfo((object)("Gallant Knight Blade base damage: " + val.GetBaseDamageOfType((Types)0) + " physical + " + val.GetBaseDamageOfType((Types)5) + " fire. Impact: " + component.Impact + ". Attack speed: " + component.AttackSpeed + "."));
	}

	private static string TargetBlacksmith(Merchant merchant)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		if (!Object.op_Implicit((Object)(object)merchant))
		{
			return null;
		}
		string text = UID.op_Implicit(merchant.HolderUID);
		Scene scene = ((Component)merchant).gameObject.scene;
		switch (((Scene)(ref scene)).name)
		{
		case "CierzoNewTerrain":
			if (!(text == "3Rx_R0XDLUmYaNWm66SVCQ"))
			{
				return null;
			}
			return "Loud-Hammer";
		case "Berg":
			if (!(text == "3Rx_R0XDLUmYaNWm66SVCQ"))
			{
				return null;
			}
			return "Quikiza";
		case "Levant":
			if (!(text == "3Rx_R0XDLUmYaNWm66SVCQ") && !(text == "EYhBqM653UGhDd5kcdMFXg"))
			{
				return null;
			}
			return "Tokuga";
		case "Monsoon":
			if (!(text == "3Rx_R0XDLUmYaNWm66SVCQ"))
			{
				return null;
			}
			return "Vyzyrinthrix";
		case "Harmattan":
			if (!(text == "Zdg-qTDRa0-qOzzNSbtvzg"))
			{
				return null;
			}
			return "Howard Brock";
		case "NewSirocco":
		{
			Transform val = ((Component)merchant).transform;
			while (Object.op_Implicit((Object)(object)val))
			{
				if (((Object)val).name == "BlacksmithMerchant_Dialog")
				{
					return "Sal Dumas";
				}
				val = val.parent;
			}
			if (!(text == "QyJwLKySB0epxpEG3EBICQ"))
			{
				return null;
			}
			return "Sal Dumas";
		}
		default:
			return null;
		}
	}

	private static void SetBlacksmithPrice(Item __instance, Character __0, Merchant __1, bool __2, ref int __result)
	{
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		if (__instance.ItemID == -847390 && TargetBlacksmith(__1) != null && (__2 || !Object.op_Implicit((Object)(object)__0) || !(EnvironmentConditions.GameTime < __instance.RebuyLimitTime) || !(__instance.PreviousOwnerUID == UID.op_Implicit(__0.UID))))
		{
			__result = 10000;
		}
	}

	private static void BeforeRestock(MerchantPouch __instance, double ___m_nextRefreshTime, out string __state)
	{
		__state = ((!PhotonNetwork.isNonMasterClientInRoom && EnvironmentConditions.GameTime >= ___m_nextRefreshTime) ? TargetBlacksmith(__instance.Merchant) : null);
	}

	private static Item FindStock(MerchantPouch pouch)
	{
		return ((ItemContainer)pouch).GetItemsFromID(-847390).Find((Item item) => Object.op_Implicit((Object)(object)item) && !item.IsPendingDestroy);
	}

	private static Item EnsureStock(MerchantPouch pouch)
	{
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Expected O, but got Unknown
		Item val = FindStock(pouch);
		if (Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)ResourcesPrefabManager.Instance.GetItemPrefab(-847390)))
		{
			return val;
		}
		SL_ItemDrop val2 = new SL_ItemDrop();
		val2.DroppedItemID = -847390;
		val2.MinQty = 1;
		val2.MaxQty = 1;
		val2.GenerateDrop(((Component)pouch).transform);
		return FindStock(pouch);
	}

	private static void AfterRestock(MerchantPouch __instance, string __state)
	{
		if (__state != null && Object.op_Implicit((Object)(object)EnsureStock(__instance)))
		{
			log.LogInfo((object)(__state + " restocked Gallant Knight Blade."));
		}
	}

	private static void SeedExistingStock(Merchant __instance, bool __0, Character __1)
	{
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		if (!__0 || !Object.op_Implicit((Object)(object)__1) || PhotonNetwork.isNonMasterClientInRoom)
		{
			return;
		}
		string text = TargetBlacksmith(__instance);
		if (text == null)
		{
			return;
		}
		ItemContainer merchantPouch = __instance.MerchantPouch;
		MerchantPouch val = (MerchantPouch)(object)((merchantPouch is MerchantPouch) ? merchantPouch : null);
		Character worldHostCharacter = CharacterManager.Instance.GetWorldHostCharacter();
		if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)worldHostCharacter))
		{
			return;
		}
		string[] array = new string[5]
		{
			UID.op_Implicit(worldHostCharacter.UID),
			":",
			null,
			null,
			null
		};
		Scene scene = ((Component)__instance).gameObject.scene;
		array[2] = ((Scene)(ref scene)).name;
		array[3] = ":";
		array[4] = UID.op_Implicit(__instance.HolderUID);
		string item = string.Concat(array);
		if (!seededInventoryKeys.Contains(item))
		{
			Item val2 = EnsureStock(val);
			if (!Object.op_Implicit((Object)(object)val2))
			{
				log.LogWarning((object)(text + " did not receive Gallant Knight Blade."));
				return;
			}
			log.LogInfo((object)(text + " shop confirmed " + val2.Name + " (" + -847390 + ") at " + val2.GetBuyValue(__1, __instance, true) + " silver."));
			seededInventoryKeys.Add(item);
			seededInventories.Value = string.Join(",", seededInventoryKeys);
		}
	}
}

plugins/GallantKnightSet.dll

Decompiled 4 days ago
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using SideLoader;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: CompilationRelaxations(8)]
[assembly: AssemblyVersion("0.0.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("local.dylan.gallantknightset", "Gallant Knight Set", "1.0.20")]
public sealed class GallantKnightSet : BaseUnityPlugin
{
	private sealed class Finish
	{
		public readonly string DonorMaterial;

		public readonly string MaterialName;

		public readonly Texture2D Albedo;

		public readonly Texture2D Surface;

		public readonly Texture2D Normal;

		public Finish(string part, string donorMaterial, Texture2D sharedNormal = null)
		{
			DonorMaterial = donorMaterial;
			MaterialName = "mat_GallantKnight" + part;
			Albedo = LoadTexture(part + "Albedo", linear: false);
			Surface = LoadTexture(part + "Surface", linear: true);
			Normal = sharedNormal ?? LoadTexture(part + "Normal", linear: true);
		}
	}

	private const string PluginId = "local.dylan.gallantknightset";

	private const int ArmorId = -847391;

	private const int HelmetId = -847392;

	private const int BootsId = -847393;

	private const int ShieldId = -847394;

	private const int ArmorPrice = 7000;

	private const int ShieldPrice = 10000;

	private const int WeatherDefense = 100;

	private const string BlacksmithId = "3Rx_R0XDLUmYaNWm66SVCQ";

	private const string TokugaNormalPriceId = "EYhBqM653UGhDd5kcdMFXg";

	private const string HowardBrockId = "Zdg-qTDRa0-qOzzNSbtvzg";

	private const string SalDumasId = "QyJwLKySB0epxpEG3EBICQ";

	private static readonly int[] ShopItems = new int[4] { -847391, -847392, -847393, -847394 };

	private static readonly int MainTex = Shader.PropertyToID("_MainTex");

	private static readonly int GenTex = Shader.PropertyToID("_GenTex");

	private static readonly int NormTex = Shader.PropertyToID("_NormTex");

	private static readonly int EmissionTex = Shader.PropertyToID("_EmissionTex");

	private static readonly FieldInfo BaseProtection = AccessTools.Field(typeof(EquipmentStats), "m_damageProtection");

	private static ConfigEntry<string> seededInventories;

	private static HashSet<string> seededInventoryKeys;

	private static ManualLogSource log;

	private static Finish armorFinish;

	private static Finish helmetFinish;

	private static Finish shieldFinish;

	private static Mesh sourceArmorMesh;

	private static Mesh straplessArmorMesh;

	private void Awake()
	{
		//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e6: Expected O, but got Unknown
		//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Expected O, but got Unknown
		//IL_0146: Unknown result type (might be due to invalid IL or missing references)
		//IL_014c: Expected O, but got Unknown
		//IL_019c: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a9: Expected O, but got Unknown
		//IL_0205: Unknown result type (might be due to invalid IL or missing references)
		//IL_020b: Expected O, but got Unknown
		//IL_025a: Unknown result type (might be due to invalid IL or missing references)
		//IL_026f: Unknown result type (might be due to invalid IL or missing references)
		//IL_027c: Expected O, but got Unknown
		//IL_027c: Expected O, but got Unknown
		//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d7: Expected O, but got Unknown
		log = ((BaseUnityPlugin)this).Logger;
		seededInventories = ((BaseUnityPlugin)this).Config.Bind<string>("Blacksmiths", "SeededStock", "", "Internal record of saves where the initial Gallant Knight set stock has been added.");
		seededInventoryKeys = new HashSet<string>(seededInventories.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries), StringComparer.Ordinal);
		MethodInfo methodInfo = AccessTools.Method(AccessTools.TypeByName("SideLoader.CustomItemVisuals"), "CloneAndSetVisuals", (Type[])null, (Type[])null);
		if (methodInfo == null)
		{
			log.LogError((object)"Could not find SideLoader's visual cloning method.");
			return;
		}
		armorFinish = new Finish("Armor", "mat_cha_blueSandArmor");
		helmetFinish = new Finish("Helmet", armorFinish.DonorMaterial, armorFinish.Normal);
		shieldFinish = new Finish("Shield", "mat_itm_boneWeapons");
		Harmony val = new Harmony("local.dylan.gallantknightset");
		val.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(GallantKnightSet), "RecolorClone", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		MethodInfo methodInfo2 = AccessTools.Method(typeof(VisualSlot), "PositionVisuals", new Type[1] { typeof(Item) }, (Type[])null);
		HarmonyMethod val2 = new HarmonyMethod(typeof(GallantKnightSet), "CheckEquippedVisual", (Type[])null);
		val2.priority = 0;
		val.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		val.Patch((MethodBase)AccessTools.Method(typeof(SL_Armor), "ApplyToItem", new Type[1] { typeof(Item) }, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(GallantKnightSet), "ApplyArmorStats", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		MethodInfo methodInfo3 = AccessTools.Method(typeof(Item), "GetBuyValue", new Type[3]
		{
			typeof(Character),
			typeof(Merchant),
			typeof(bool)
		}, (Type[])null);
		HarmonyMethod val3 = new HarmonyMethod(typeof(GallantKnightSet), "SetBlacksmithPrice", (Type[])null);
		val3.priority = 0;
		val.Patch((MethodBase)methodInfo3, (HarmonyMethod)null, val3, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		val.Patch((MethodBase)AccessTools.Method(typeof(MerchantPouch), "RefreshInventory", new Type[1] { typeof(Dropable) }, (Type[])null), new HarmonyMethod(typeof(GallantKnightSet), "BeforeRestock", (Type[])null), new HarmonyMethod(typeof(GallantKnightSet), "AfterRestock", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		val.Patch((MethodBase)AccessTools.Method(typeof(Merchant), "OnReceiveConfirmStartShopping", new Type[2]
		{
			typeof(bool),
			typeof(Character)
		}, (Type[])null), new HarmonyMethod(typeof(GallantKnightSet), "SeedExistingStock", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
	}

	private static Texture2D LoadTexture(string resource, bool linear)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Expected O, but got Unknown
		Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true, linear);
		((Object)val).name = "GallantKnight" + resource;
		((Texture)val).anisoLevel = 4;
		Texture2D val2 = val;
		using Stream stream = typeof(GallantKnightSet).Assembly.GetManifestResourceStream(resource);
		using MemoryStream memoryStream = new MemoryStream();
		stream.CopyTo(memoryStream);
		if (!ImageConversion.LoadImage(val2, memoryStream.ToArray(), true))
		{
			throw new InvalidDataException("Could not decode " + resource);
		}
		return val2;
	}

	private static void RecolorClone(Item __0, GameObject __1, GameObject __result)
	{
		if (Object.op_Implicit((Object)(object)__0) && Object.op_Implicit((Object)(object)__result) && !((Object)(object)__result == (Object)(object)__1) && Array.IndexOf(ShopItems, __0.ItemID) >= 0)
		{
			int itemID = __0.ItemID;
			string text = ((Object)__result).name.Substring(((Object)__result).name.IndexOf('_') + 1);
			((Object)__result).name = itemID.ToString(CultureInfo.InvariantCulture) + "_" + text.Replace("BlueSandArmor", "GallantKnightArmor").Replace("ShieldLegion", "GallantKnightShield").Replace("(Clone)", "");
			CheckVisual(itemID, __result.GetComponent<ItemVisual>(), "prefab");
		}
	}

	private static void CheckEquippedVisual(VisualSlot __instance, Item __0)
	{
		if (Object.op_Implicit((Object)(object)__0) && Array.IndexOf(ShopItems, __0.ItemID) >= 0 && Object.op_Implicit((Object)(object)__instance.CurrentVisual))
		{
			CheckVisual(__0.ItemID, __instance.CurrentVisual, "equip");
		}
	}

	private static void CheckVisual(int id, ItemVisual visual, string stage)
	{
		if (!Object.op_Implicit((Object)(object)visual) || visual.GetItemIDFromName() != id)
		{
			log.LogWarning((object)("Gallant Knight " + stage + " check: unexpected visual pool for item " + id + "."));
			return;
		}
		Finish finish = id switch
		{
			-847392 => helmetFinish, 
			-847394 => shieldFinish, 
			_ => armorFinish, 
		};
		if (id == -847391)
		{
			ApplyStraplessMesh(visual);
		}
		int num = ApplyFinish(((Component)visual).gameObject, finish);
		if (num == 0)
		{
			log.LogWarning((object)("Gallant Knight " + stage + " check: no donor material on " + ((Object)visual).name + "."));
		}
		else
		{
			log.LogInfo((object)("Gallant Knight " + stage + " check: " + ((Object)visual).name + " has " + num + " private material(s) with custom color, reflection and normal maps."));
		}
	}

	private static void ApplyStraplessMesh(ItemVisual visual)
	{
		SkinnedMeshRenderer[] componentsInChildren = ((Component)visual).GetComponentsInChildren<SkinnedMeshRenderer>(true);
		foreach (SkinnedMeshRenderer val in componentsInChildren)
		{
			Mesh sharedMesh = val.sharedMesh;
			if (!Object.op_Implicit((Object)(object)sharedMesh) || (Object)(object)sharedMesh == (Object)(object)straplessArmorMesh || !((Object)sharedMesh).name.StartsWith("mdl_cha_blueSandArmor", StringComparison.Ordinal))
			{
				continue;
			}
			if ((Object)(object)sharedMesh != (Object)(object)sourceArmorMesh)
			{
				Mesh val2 = RemoveChestStrap(sharedMesh);
				if (!Object.op_Implicit((Object)(object)val2))
				{
					log.LogWarning((object)"Gallant Knight Armor strap mesh signature did not match.");
					continue;
				}
				sourceArmorMesh = sharedMesh;
				straplessArmorMesh = val2;
			}
			val.sharedMesh = straplessArmorMesh;
			log.LogInfo((object)"Gallant Knight Armor uses its private strapless chest mesh.");
		}
	}

	private static Mesh RemoveChestStrap(Mesh source)
	{
		using Stream input = typeof(GallantKnightSet).Assembly.GetManifestResourceStream("ArmorStrapMask");
		using BinaryReader binaryReader = new BinaryReader(input);
		int num = binaryReader.ReadInt32();
		int num2 = binaryReader.ReadInt32();
		uint num3 = binaryReader.ReadUInt32();
		if (!source.isReadable || source.vertexCount != num || source.subMeshCount != 1 || source.GetIndexCount(0) != num2)
		{
			return null;
		}
		int[] triangles = source.GetTriangles(0);
		uint num4 = 2166136261u;
		int[] array = triangles;
		foreach (int num5 in array)
		{
			num4 = (num4 ^ (uint)num5) * 16777619;
		}
		if (num4 != num3)
		{
			return null;
		}
		int num6 = binaryReader.ReadInt32();
		HashSet<int> hashSet = new HashSet<int>();
		for (int j = 0; j < num6; j++)
		{
			hashSet.Add(binaryReader.ReadInt32());
		}
		List<int> list = new List<int>(triangles.Length - num6 * 3);
		for (int k = 0; k < triangles.Length; k += 3)
		{
			if (!hashSet.Contains(k / 3))
			{
				list.Add(triangles[k]);
				list.Add(triangles[k + 1]);
				list.Add(triangles[k + 2]);
			}
		}
		Mesh val = Object.Instantiate<Mesh>(source);
		((Object)val).name = "mdl_GallantKnightArmor_Strapless";
		val.SetTriangles(list, 0, false);
		return val;
	}

	private static int ApplyFinish(GameObject model, Finish finish)
	{
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f9: Expected O, but got Unknown
		//IL_0203: Unknown result type (might be due to invalid IL or missing references)
		int num = 0;
		Renderer[] componentsInChildren = model.GetComponentsInChildren<Renderer>(true);
		foreach (Renderer val in componentsInChildren)
		{
			Material[] sharedMaterials = val.sharedMaterials;
			bool flag = false;
			for (int j = 0; j < sharedMaterials.Length; j++)
			{
				Material val2 = sharedMaterials[j];
				if (!Object.op_Implicit((Object)(object)val2) || !val2.HasProperty(MainTex) || !val2.HasProperty(GenTex) || !val2.HasProperty(NormTex))
				{
					continue;
				}
				if ((Object)(object)val2.GetTexture(MainTex) == (Object)(object)finish.Albedo && (Object)(object)val2.GetTexture(GenTex) == (Object)(object)finish.Surface && (Object)(object)val2.GetTexture(NormTex) == (Object)(object)finish.Normal)
				{
					num++;
				}
				else
				{
					if (!((Object)val2).name.StartsWith(finish.DonorMaterial, StringComparison.OrdinalIgnoreCase) && !((Object)val2).name.StartsWith(finish.MaterialName, StringComparison.OrdinalIgnoreCase))
					{
						continue;
					}
					Material val3 = new Material(val2);
					((Object)val3).name = finish.MaterialName;
					Material val4 = val3;
					val4.SetTexture(MainTex, (Texture)(object)finish.Albedo);
					val4.SetTexture(GenTex, (Texture)(object)finish.Surface);
					val4.SetTexture(NormTex, (Texture)(object)finish.Normal);
					if (val4.HasProperty(EmissionTex))
					{
						val4.SetTexture(EmissionTex, (Texture)(object)Texture2D.blackTexture);
					}
					val4.DisableKeyword("_DETAIL");
					val4.DisableKeyword("_DETAIL_ALBEDO");
					val4.DisableKeyword("_DETAIL_TEXTURED");
					val4.EnableKeyword("_NORMALMAP");
					val4.EnableKeyword("_SPECGLOSSMAP");
					val4.SetFloat("_SpecBoost", 0.015f);
					val4.SetFloat("_GlossMin", 0.035f);
					val4.SetFloat("_SmoothMin", 0.035f);
					if (finish == shieldFinish)
					{
						val4.DisableKeyword("_EMISSION");
						val4.DisableKeyword("_EMISSION_TEXTURED");
						if (val4.HasProperty("_EmissionColor"))
						{
							val4.SetColor("_EmissionColor", Color.black);
						}
					}
					sharedMaterials[j] = val4;
					flag = true;
					num++;
				}
			}
			if (flag)
			{
				val.sharedMaterials = sharedMaterials;
			}
		}
		return num;
	}

	private static void ApplyArmorStats(Item __0)
	{
		//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0104: Expected O, but got Unknown
		if (!Object.op_Implicit((Object)(object)__0))
		{
			return;
		}
		int num = Array.IndexOf(ShopItems, __0.ItemID);
		if (num >= 0 && num < 3)
		{
			int num2 = 3100080 + num;
			Item itemPrefab = ResourcesPrefabManager.Instance.GetItemPrefab(num2);
			EquipmentStats val = (Object.op_Implicit((Object)(object)itemPrefab) ? ((Component)itemPrefab).GetComponent<EquipmentStats>() : null);
			EquipmentStats component = ((Component)__0).GetComponent<EquipmentStats>();
			int num3 = 0;
			float[] array = (Object.op_Implicit((Object)(object)val) ? ((float[])BaseProtection.GetValue(val)) : null);
			float[] array2 = (Object.op_Implicit((Object)(object)component) ? ((float[])BaseProtection.GetValue(component)) : null);
			if (array == null || array.Length <= num3 || array2 == null || array2.Length <= num3)
			{
				log.LogWarning((object)("Could not set Gallant Knight Protection for item " + __0.ItemID + "."));
				return;
			}
			float num4 = array[num3];
			float[] array3 = (float[])array2.Clone();
			array3[num3] = num4 + 2f;
			BaseProtection.SetValue(component, array3);
			SL_EquipmentStats val2 = new SL_EquipmentStats();
			val2.Heat_Protection = 100f;
			val2.Cold_Protection = 100f;
			((SL_ItemStats)val2).ApplyToItem((ItemStats)(object)component);
			__0.InitCachedInfos();
			log.LogInfo((object)("Gallant Knight item " + __0.ItemID + " physical Protection " + num4 + " -> " + array3[num3] + ", Hot Weather Defense " + component.HeatProtection + ", Cold Weather Defense " + component.ColdProtection + "."));
		}
	}

	private static string TargetBlacksmith(Merchant merchant)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		if (!Object.op_Implicit((Object)(object)merchant))
		{
			return null;
		}
		string text = UID.op_Implicit(merchant.HolderUID);
		Scene scene = ((Component)merchant).gameObject.scene;
		switch (((Scene)(ref scene)).name)
		{
		case "CierzoNewTerrain":
			if (!(text == "3Rx_R0XDLUmYaNWm66SVCQ"))
			{
				return null;
			}
			return "Loud-Hammer";
		case "Berg":
			if (!(text == "3Rx_R0XDLUmYaNWm66SVCQ"))
			{
				return null;
			}
			return "Quikiza";
		case "Levant":
			if (!(text == "3Rx_R0XDLUmYaNWm66SVCQ") && !(text == "EYhBqM653UGhDd5kcdMFXg"))
			{
				return null;
			}
			return "Tokuga";
		case "Monsoon":
			if (!(text == "3Rx_R0XDLUmYaNWm66SVCQ"))
			{
				return null;
			}
			return "Vyzyrinthrix";
		case "Harmattan":
			if (!(text == "Zdg-qTDRa0-qOzzNSbtvzg"))
			{
				return null;
			}
			return "Howard Brock";
		case "NewSirocco":
		{
			Transform val = ((Component)merchant).transform;
			while (Object.op_Implicit((Object)(object)val))
			{
				if (((Object)val).name == "BlacksmithMerchant_Dialog")
				{
					return "Sal Dumas";
				}
				val = val.parent;
			}
			if (!(text == "QyJwLKySB0epxpEG3EBICQ"))
			{
				return null;
			}
			return "Sal Dumas";
		}
		default:
			return null;
		}
	}

	private static void SetBlacksmithPrice(Item __instance, Character __0, Merchant __1, bool __2, ref int __result)
	{
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		int itemID = __instance.ItemID;
		if (Array.IndexOf(ShopItems, itemID) >= 0 && TargetBlacksmith(__1) != null && (__2 || !Object.op_Implicit((Object)(object)__0) || !(EnvironmentConditions.GameTime < __instance.RebuyLimitTime) || !(__instance.PreviousOwnerUID == UID.op_Implicit(__0.UID))))
		{
			__result = ((itemID == -847394) ? 10000 : 7000);
		}
	}

	private static void BeforeRestock(MerchantPouch __instance, double ___m_nextRefreshTime, out string __state)
	{
		__state = ((!PhotonNetwork.isNonMasterClientInRoom && EnvironmentConditions.GameTime >= ___m_nextRefreshTime) ? TargetBlacksmith(__instance.Merchant) : null);
	}

	private static Item FindStock(MerchantPouch pouch, int id)
	{
		return ((ItemContainer)pouch).GetItemsFromID(id).Find((Item item) => Object.op_Implicit((Object)(object)item) && !item.IsPendingDestroy);
	}

	private static Item EnsureStock(MerchantPouch pouch, int id)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Expected O, but got Unknown
		Item val = FindStock(pouch, id);
		if (Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)ResourcesPrefabManager.Instance.GetItemPrefab(id)))
		{
			return val;
		}
		SL_ItemDrop val2 = new SL_ItemDrop();
		val2.DroppedItemID = id;
		val2.MinQty = 1;
		val2.MaxQty = 1;
		val2.GenerateDrop(((Component)pouch).transform);
		return FindStock(pouch, id);
	}

	private static void AfterRestock(MerchantPouch __instance, string __state)
	{
		if (__state == null)
		{
			return;
		}
		int[] shopItems = ShopItems;
		foreach (int num in shopItems)
		{
			if (Object.op_Implicit((Object)(object)EnsureStock(__instance, num)))
			{
				log.LogInfo((object)(__state + " restocked Gallant Knight item " + num + "."));
			}
		}
	}

	private static void SeedExistingStock(Merchant __instance, bool __0, Character __1)
	{
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		if (!__0 || !Object.op_Implicit((Object)(object)__1) || PhotonNetwork.isNonMasterClientInRoom)
		{
			return;
		}
		string text = TargetBlacksmith(__instance);
		if (text == null)
		{
			return;
		}
		ItemContainer merchantPouch = __instance.MerchantPouch;
		MerchantPouch val = (MerchantPouch)(object)((merchantPouch is MerchantPouch) ? merchantPouch : null);
		Character worldHostCharacter = CharacterManager.Instance.GetWorldHostCharacter();
		if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)worldHostCharacter))
		{
			return;
		}
		string[] array = new string[5]
		{
			UID.op_Implicit(worldHostCharacter.UID),
			":",
			null,
			null,
			null
		};
		Scene scene = ((Component)__instance).gameObject.scene;
		array[2] = ((Scene)(ref scene)).name;
		array[3] = ":";
		array[4] = UID.op_Implicit(__instance.HolderUID);
		string item = string.Concat(array);
		if (seededInventoryKeys.Contains(item))
		{
			return;
		}
		bool flag = true;
		int[] shopItems = ShopItems;
		foreach (int num in shopItems)
		{
			Item val2 = EnsureStock(val, num);
			if (!Object.op_Implicit((Object)(object)val2))
			{
				flag = false;
				log.LogWarning((object)(text + " did not receive Gallant Knight item " + num + "."));
			}
			else
			{
				log.LogInfo((object)(text + " shop confirmed " + val2.Name + " (" + num + ") at " + val2.GetBuyValue(__1, __instance, true) + " silver."));
			}
		}
		if (flag)
		{
			seededInventoryKeys.Add(item);
			seededInventories.Value = string.Join(",", seededInventoryKeys);
		}
	}
}

plugins/GallantKnightWeapons.dll

Decompiled 4 days ago
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using SideLoader;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: CompilationRelaxations(8)]
[assembly: AssemblyVersion("0.0.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("local.dylan.gallantknightweapons", "Gallant Knight Weapons", "1.0.5")]
public sealed class GallantKnightWeapons : BaseUnityPlugin
{
	private sealed class WeaponDesign
	{
		public readonly int BaseItemId;

		public readonly string ModelName;

		public readonly float Physical;

		public readonly float Fire;

		public readonly int Price;

		public readonly Finish[] Finishes;

		public WeaponDesign(int baseItemId, string modelName, float physical, float fire, int price, params Finish[] finishes)
		{
			BaseItemId = baseItemId;
			ModelName = modelName;
			Physical = physical;
			Fire = fire;
			Price = price;
			Finishes = finishes;
		}
	}

	private sealed class Finish
	{
		public readonly string DonorMaterial;

		public readonly string MaterialName;

		public readonly Texture2D Albedo;

		public readonly Texture2D Surface;

		public readonly Texture2D Normal;

		public Finish(string resource, string donorMaterial)
		{
			DonorMaterial = donorMaterial;
			MaterialName = "mat_GallantKnight" + resource;
			Albedo = LoadTexture(resource + "Albedo", linear: false);
			Surface = LoadTexture(resource + "Surface", linear: true);
			Normal = LoadTexture(resource + "Normal", linear: true);
		}

		public bool Matches(Material material)
		{
			if (!((Object)material).name.StartsWith(DonorMaterial, StringComparison.OrdinalIgnoreCase))
			{
				return ((Object)material).name.StartsWith(MaterialName, StringComparison.OrdinalIgnoreCase);
			}
			return true;
		}
	}

	private const string PluginId = "local.dylan.gallantknightweapons";

	private const int AxeId = -847395;

	private const int GreatswordId = -847396;

	private const int MaceId = -847397;

	private const int SpearId = -847398;

	private const int BowId = -847399;

	private const int PistolId = -847400;

	private const int FireReloadSkillId = 8200600;

	private const string BlacksmithId = "3Rx_R0XDLUmYaNWm66SVCQ";

	private const string TokugaNormalPriceId = "EYhBqM653UGhDd5kcdMFXg";

	private const string HowardBrockId = "Zdg-qTDRa0-qOzzNSbtvzg";

	private const string SalDumasId = "QyJwLKySB0epxpEG3EBICQ";

	private static readonly int MainTex = Shader.PropertyToID("_MainTex");

	private static readonly int GenTex = Shader.PropertyToID("_GenTex");

	private static readonly int NormTex = Shader.PropertyToID("_NormTex");

	private static readonly Dictionary<int, WeaponDesign> Designs = new Dictionary<int, WeaponDesign>();

	private static ConfigEntry<string> seededInventories;

	private static HashSet<string> seededInventoryKeys;

	private static ManualLogSource log;

	private void Awake()
	{
		//IL_0262: Unknown result type (might be due to invalid IL or missing references)
		//IL_0268: Expected O, but got Unknown
		//IL_027b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0288: Expected O, but got Unknown
		//IL_02c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ce: Expected O, but got Unknown
		//IL_031e: Unknown result type (might be due to invalid IL or missing references)
		//IL_032b: Expected O, but got Unknown
		//IL_036b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0378: Expected O, but got Unknown
		//IL_03d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_03da: Expected O, but got Unknown
		//IL_0429: Unknown result type (might be due to invalid IL or missing references)
		//IL_043e: Unknown result type (might be due to invalid IL or missing references)
		//IL_044b: Expected O, but got Unknown
		//IL_044b: Expected O, but got Unknown
		//IL_0498: Unknown result type (might be due to invalid IL or missing references)
		//IL_04a6: Expected O, but got Unknown
		//IL_051d: Unknown result type (might be due to invalid IL or missing references)
		//IL_052b: Expected O, but got Unknown
		log = ((BaseUnityPlugin)this).Logger;
		seededInventories = ((BaseUnityPlugin)this).Config.Bind<string>("Blacksmiths", "SeededStock", "", "Internal record of saves where the initial Gallant Knight weapon stock has been added.");
		seededInventoryKeys = new HashSet<string>(seededInventories.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries), StringComparer.Ordinal);
		MethodInfo methodInfo = AccessTools.Method(AccessTools.TypeByName("SideLoader.CustomItemVisuals"), "CloneAndSetVisuals", (Type[])null, (Type[])null);
		if (methodInfo == null)
		{
			log.LogError((object)"Could not find SideLoader's visual cloning method.");
			return;
		}
		Designs.Add(-847395, new WeaponDesign(2010000, "GallantKnightAxe", 34f, 10f, 12000, new Finish("Axe", "mat_itm_hugeSword")));
		Designs.Add(-847396, new WeaponDesign(2100080, "GallantKnightGreatsword", 42f, 12f, 15000, new Finish("GreatswordBlade", "mat_itm_hugeSword"), new Finish("GreatswordHilt", "mat_env_atlasCommonObjects")));
		Designs.Add(-847397, new WeaponDesign(2020010, "GallantKnightMace", 35f, 9f, 11000, new Finish("Mace", "mat_itm_hugeSword")));
		Designs.Add(-847398, new WeaponDesign(2130110, "GallantKnightSpear", 36f, 8f, 11500, new Finish("Spear", "mat_env_atlasCommonObjects")));
		Designs.Add(-847399, new WeaponDesign(2200135, "GallantKnightBow", 41f, 9f, 15000, new Finish("Bow", "mat_itm_WeaponDamasceneLegacy")));
		Designs.Add(-847400, new WeaponDesign(5110100, "GallantKnightPistol", 60f, 16f, 14500, new Finish("Pistol", "mat_itm_atlasPistolA")));
		Harmony val = new Harmony("local.dylan.gallantknightweapons");
		val.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(GallantKnightWeapons), "RecolorClone", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		MethodInfo methodInfo2 = AccessTools.Method(typeof(VisualSlot), "PositionVisuals", new Type[1] { typeof(Item) }, (Type[])null);
		HarmonyMethod val2 = new HarmonyMethod(typeof(GallantKnightWeapons), "CheckEquippedVisual", (Type[])null);
		val2.priority = 0;
		val.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		val.Patch((MethodBase)AccessTools.Method(typeof(SL_MeleeWeapon), "ApplyToItem", new Type[1] { typeof(Item) }, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(GallantKnightWeapons), "ApplyDamage", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		val.Patch((MethodBase)AccessTools.Method(typeof(SL_ProjectileWeapon), "ApplyToItem", new Type[1] { typeof(Item) }, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(GallantKnightWeapons), "ApplyDamage", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		MethodInfo methodInfo3 = AccessTools.Method(typeof(Item), "GetBuyValue", new Type[3]
		{
			typeof(Character),
			typeof(Merchant),
			typeof(bool)
		}, (Type[])null);
		HarmonyMethod val3 = new HarmonyMethod(typeof(GallantKnightWeapons), "SetBlacksmithPrice", (Type[])null);
		val3.priority = 0;
		val.Patch((MethodBase)methodInfo3, (HarmonyMethod)null, val3, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		val.Patch((MethodBase)AccessTools.Method(typeof(MerchantPouch), "RefreshInventory", new Type[1] { typeof(Dropable) }, (Type[])null), new HarmonyMethod(typeof(GallantKnightWeapons), "BeforeRestock", (Type[])null), new HarmonyMethod(typeof(GallantKnightWeapons), "AfterRestock", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		val.Patch((MethodBase)AccessTools.Method(typeof(Merchant), "OnReceiveConfirmStartShopping", new Type[2]
		{
			typeof(bool),
			typeof(Character)
		}, (Type[])null), new HarmonyMethod(typeof(GallantKnightWeapons), "SeedExistingStock", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		val.Patch((MethodBase)AccessTools.Method(typeof(Character), "CastSpell", new Type[5]
		{
			typeof(SpellCastType),
			typeof(GameObject),
			typeof(SpellCastModifier),
			typeof(int),
			typeof(float)
		}, (Type[])null), new HarmonyMethod(typeof(GallantKnightWeapons), "InstantPistolReload", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
	}

	private static bool InstantPistolReload(Character __instance, SpellCastType __0, GameObject __1, SpellCastModifier __2, int ___m_nextAttackAllowed, ref bool __result)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Invalid comparison between Unknown and I4
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Invalid comparison between Unknown and I4
		if ((int)__0 != 755 || !Object.op_Implicit((Object)(object)__1))
		{
			return true;
		}
		Weapon leftHandWeapon = __instance.LeftHandWeapon;
		ProjectileWeapon val = (ProjectileWeapon)(object)((leftHandWeapon is ProjectileWeapon) ? leftHandWeapon : null);
		if (!Object.op_Implicit((Object)(object)val) || ((Item)val).ItemID != -847400)
		{
			return true;
		}
		PistolSkill component = __1.GetComponent<PistolSkill>();
		if (!Object.op_Implicit((Object)(object)component) || ((Item)component).ItemID != 8200600)
		{
			return true;
		}
		if (__instance.IsCasting || ((!__instance.InLocomotion || !__instance.NextIsLocomotion || __instance.PreparingToSleep) && ((int)__2 != 2 || ___m_nextAttackAllowed <= 0)) || !((Weapon)val).NeedReload || !val.CanBeLoaded())
		{
			__instance.LastUsedSkill = null;
			__result = false;
			return false;
		}
		((Weapon)val).InstantLoadWeapon();
		__result = !((Weapon)val).IsEmpty;
		__instance.LastUsedSkill = null;
		if (__result)
		{
			log.LogInfo((object)"Gallant Knight Pistol reloaded instantly through Fire/Reload.");
		}
		return false;
	}

	private static Texture2D LoadTexture(string resource, bool linear)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Expected O, but got Unknown
		Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true, linear);
		((Object)val).name = "GallantKnight" + resource;
		((Texture)val).anisoLevel = 4;
		Texture2D val2 = val;
		using Stream stream = typeof(GallantKnightWeapons).Assembly.GetManifestResourceStream(resource);
		using MemoryStream memoryStream = new MemoryStream();
		stream.CopyTo(memoryStream);
		if (!ImageConversion.LoadImage(val2, memoryStream.ToArray(), true))
		{
			throw new InvalidDataException("Could not decode " + resource);
		}
		return val2;
	}

	private static void RecolorClone(Item __0, GameObject __1, GameObject __result)
	{
		if (Object.op_Implicit((Object)(object)__0) && Object.op_Implicit((Object)(object)__result) && !((Object)(object)__result == (Object)(object)__1) && Designs.TryGetValue(__0.ItemID, out var value))
		{
			((Object)__result).name = __0.ItemID.ToString(CultureInfo.InvariantCulture) + "_" + value.ModelName + "_v";
			CheckVisual(__0.ItemID, __result.GetComponent<ItemVisual>(), value, "prefab");
		}
	}

	private static void CheckEquippedVisual(VisualSlot __instance, Item __0)
	{
		if (Object.op_Implicit((Object)(object)__0) && Object.op_Implicit((Object)(object)__instance.CurrentVisual) && Designs.TryGetValue(__0.ItemID, out var value))
		{
			CheckVisual(__0.ItemID, __instance.CurrentVisual, value, "equip");
		}
	}

	private static void CheckVisual(int id, ItemVisual visual, WeaponDesign design, string stage)
	{
		if (!Object.op_Implicit((Object)(object)visual) || visual.GetItemIDFromName() != id)
		{
			log.LogWarning((object)(design.ModelName + " " + stage + " check: unexpected visual pool."));
			return;
		}
		int num = ApplyFinish(((Component)visual).gameObject, design);
		if (num < design.Finishes.Length)
		{
			log.LogWarning((object)(design.ModelName + " " + stage + " check: missing a weapon material on " + ((Object)visual).name + "."));
		}
		else
		{
			log.LogInfo((object)(design.ModelName + " " + stage + " check: " + ((Object)visual).name + " has " + num + " private material(s) with custom color, reflection and normal maps."));
		}
	}

	private static int ApplyFinish(GameObject model, WeaponDesign design)
	{
		//IL_011b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0122: Expected O, but got Unknown
		int num = 0;
		Renderer[] componentsInChildren = model.GetComponentsInChildren<Renderer>(true);
		foreach (Renderer val in componentsInChildren)
		{
			Material[] sharedMaterials = val.sharedMaterials;
			bool flag = false;
			for (int j = 0; j < sharedMaterials.Length; j++)
			{
				Material original = sharedMaterials[j];
				if (!Object.op_Implicit((Object)(object)original) || !original.HasProperty(MainTex) || !original.HasProperty(GenTex) || !original.HasProperty(NormTex))
				{
					continue;
				}
				Finish finish = Array.Find(design.Finishes, (Finish entry) => entry.Matches(original));
				if (finish == null)
				{
					continue;
				}
				num++;
				if (!((Object)(object)original.GetTexture(MainTex) == (Object)(object)finish.Albedo) || !((Object)(object)original.GetTexture(GenTex) == (Object)(object)finish.Surface) || !((Object)(object)original.GetTexture(NormTex) == (Object)(object)finish.Normal))
				{
					Material val2 = new Material(original);
					((Object)val2).name = finish.MaterialName;
					Material val3 = val2;
					val3.SetTexture(MainTex, (Texture)(object)finish.Albedo);
					val3.SetTexture(GenTex, (Texture)(object)finish.Surface);
					val3.SetTexture(NormTex, (Texture)(object)finish.Normal);
					val3.DisableKeyword("_DETAIL");
					val3.DisableKeyword("_DETAIL_ALBEDO");
					val3.DisableKeyword("_DETAIL_TEXTURED");
					val3.DisableKeyword("_SPEC_COLOR");
					if ((design.BaseItemId == 2200135 || design.BaseItemId == 5110100) && val3.HasProperty("_EmissionTex"))
					{
						val3.SetTexture("_EmissionTex", (Texture)(object)Texture2D.blackTexture);
						val3.DisableKeyword("_EMISSION");
						val3.DisableKeyword("_EMISSION_TEXTURED");
					}
					val3.EnableKeyword("_NORMALMAP");
					val3.EnableKeyword("_SPECGLOSSMAP");
					val3.SetFloat("_SpecBoost", 0.015f);
					val3.SetFloat("_GlossMin", 0.035f);
					val3.SetFloat("_SmoothMin", 0.035f);
					sharedMaterials[j] = val3;
					flag = true;
				}
			}
			if (flag)
			{
				val.sharedMaterials = sharedMaterials;
			}
		}
		return num;
	}

	private static void ApplyDamage(Item __0)
	{
		//IL_0085: 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)
		//IL_0109: Expected O, but got Unknown
		//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c1: Expected O, but got Unknown
		Weapon val = (Weapon)(object)((__0 is Weapon) ? __0 : null);
		if (!Object.op_Implicit((Object)(object)val) || !Designs.TryGetValue(((Item)val).ItemID, out var value))
		{
			return;
		}
		WeaponStats component = ((Component)val).GetComponent<WeaponStats>();
		Item itemPrefab = ResourcesPrefabManager.Instance.GetItemPrefab(value.BaseItemId);
		WeaponStats val2 = (Object.op_Implicit((Object)(object)itemPrefab) ? ((Component)itemPrefab).GetComponent<WeaponStats>() : null);
		if (!Object.op_Implicit((Object)(object)component) || !Object.op_Implicit((Object)(object)val2) || val2.BaseDamage == null || val2.BaseDamage.Count != 1 || (int)val2.BaseDamage[0].Type != 0 || val2.BaseDamage.TotalDamage <= 0f || val2.Attacks == null)
		{
			log.LogWarning((object)("Could not find the base weapon damage data for " + value.ModelName + "."));
			return;
		}
		float totalDamage = val2.BaseDamage.TotalDamage;
		float num = value.Physical / totalDamage;
		DamageList val3 = val2.BaseDamage.Clone() * num;
		val3.Add(new DamageType((Types)5, value.Fire));
		component.BaseDamage = val3;
		AttackData[] array = (AttackData[])val2.Attacks.Clone();
		for (int i = 0; i < array.Length; i++)
		{
			AttackData val4 = array[i];
			if (val4 != null && val4.Damage != null && val4.Damage.Count != 0)
			{
				float num2 = val4.Damage[0];
				List<float> list2;
				if (!(num2 < 0f))
				{
					List<float> list = new List<float>();
					list.Add(num2 * num);
					list.Add(value.Fire * num2 / totalDamage);
					list2 = list;
				}
				else
				{
					List<float> list3 = new List<float>();
					list3.Add(num2);
					list3.Add(num2);
					list2 = list3;
				}
				List<float> damage = list2;
				int num3 = i;
				AttackData val5 = new AttackData();
				val5.Damage = damage;
				val5.Knockback = val4.Knockback;
				val5.StamCost = val4.StamCost;
				val5.AttackSpeed = val4.AttackSpeed;
				array[num3] = val5;
			}
		}
		component.Attacks = array;
		((Item)val).InitCachedInfos();
		log.LogInfo((object)(((Item)val).Name + " base damage: " + val.GetBaseDamageOfType((Types)0) + " physical + " + val.GetBaseDamageOfType((Types)5) + " fire. Impact: " + component.Impact + ". Attack speed: " + component.AttackSpeed + "."));
	}

	private static string TargetBlacksmith(Merchant merchant)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		if (!Object.op_Implicit((Object)(object)merchant))
		{
			return null;
		}
		string text = UID.op_Implicit(merchant.HolderUID);
		Scene scene = ((Component)merchant).gameObject.scene;
		switch (((Scene)(ref scene)).name)
		{
		case "CierzoNewTerrain":
			if (!(text == "3Rx_R0XDLUmYaNWm66SVCQ"))
			{
				return null;
			}
			return "Loud-Hammer";
		case "Berg":
			if (!(text == "3Rx_R0XDLUmYaNWm66SVCQ"))
			{
				return null;
			}
			return "Quikiza";
		case "Levant":
			if (!(text == "3Rx_R0XDLUmYaNWm66SVCQ") && !(text == "EYhBqM653UGhDd5kcdMFXg"))
			{
				return null;
			}
			return "Tokuga";
		case "Monsoon":
			if (!(text == "3Rx_R0XDLUmYaNWm66SVCQ"))
			{
				return null;
			}
			return "Vyzyrinthrix";
		case "Harmattan":
			if (!(text == "Zdg-qTDRa0-qOzzNSbtvzg"))
			{
				return null;
			}
			return "Howard Brock";
		case "NewSirocco":
		{
			Transform val = ((Component)merchant).transform;
			while (Object.op_Implicit((Object)(object)val))
			{
				if (((Object)val).name == "BlacksmithMerchant_Dialog")
				{
					return "Sal Dumas";
				}
				val = val.parent;
			}
			if (!(text == "QyJwLKySB0epxpEG3EBICQ"))
			{
				return null;
			}
			return "Sal Dumas";
		}
		default:
			return null;
		}
	}

	private static void SetBlacksmithPrice(Item __instance, Character __0, Merchant __1, bool __2, ref int __result)
	{
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		int itemID = __instance.ItemID;
		if (Designs.ContainsKey(itemID) && TargetBlacksmith(__1) != null && (__2 || !Object.op_Implicit((Object)(object)__0) || !(EnvironmentConditions.GameTime < __instance.RebuyLimitTime) || !(__instance.PreviousOwnerUID == UID.op_Implicit(__0.UID))))
		{
			__result = Designs[itemID].Price;
		}
	}

	private static void BeforeRestock(MerchantPouch __instance, double ___m_nextRefreshTime, out string __state)
	{
		__state = ((!PhotonNetwork.isNonMasterClientInRoom && EnvironmentConditions.GameTime >= ___m_nextRefreshTime) ? TargetBlacksmith(__instance.Merchant) : null);
	}

	private static Item FindStock(MerchantPouch pouch, int id)
	{
		return ((ItemContainer)pouch).GetItemsFromID(id).Find((Item item) => Object.op_Implicit((Object)(object)item) && !item.IsPendingDestroy);
	}

	private static Item EnsureStock(MerchantPouch pouch, int id)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Expected O, but got Unknown
		Item val = FindStock(pouch, id);
		if (Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)ResourcesPrefabManager.Instance.GetItemPrefab(id)))
		{
			return val;
		}
		SL_ItemDrop val2 = new SL_ItemDrop();
		val2.DroppedItemID = id;
		val2.MinQty = 1;
		val2.MaxQty = 1;
		val2.GenerateDrop(((Component)pouch).transform);
		return FindStock(pouch, id);
	}

	private static void AfterRestock(MerchantPouch __instance, string __state)
	{
		if (__state == null)
		{
			return;
		}
		foreach (int key in Designs.Keys)
		{
			if (Object.op_Implicit((Object)(object)EnsureStock(__instance, key)))
			{
				log.LogInfo((object)(__state + " restocked Gallant Knight weapon " + key + "."));
			}
		}
	}

	private static void SeedExistingStock(Merchant __instance, bool __0, Character __1)
	{
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		if (!__0 || !Object.op_Implicit((Object)(object)__1) || PhotonNetwork.isNonMasterClientInRoom)
		{
			return;
		}
		string text = TargetBlacksmith(__instance);
		if (text == null)
		{
			return;
		}
		ItemContainer merchantPouch = __instance.MerchantPouch;
		MerchantPouch val = (MerchantPouch)(object)((merchantPouch is MerchantPouch) ? merchantPouch : null);
		Character worldHostCharacter = CharacterManager.Instance.GetWorldHostCharacter();
		if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)worldHostCharacter))
		{
			return;
		}
		string[] array = new string[5]
		{
			UID.op_Implicit(worldHostCharacter.UID),
			":",
			null,
			null,
			null
		};
		Scene scene = ((Component)__instance).gameObject.scene;
		array[2] = ((Scene)(ref scene)).name;
		array[3] = ":";
		array[4] = UID.op_Implicit(__instance.HolderUID);
		string text2 = string.Concat(array);
		bool flag = seededInventoryKeys.Contains(text2);
		bool flag2 = false;
		foreach (int key in Designs.Keys)
		{
			string item = text2 + ":" + key.ToString(CultureInfo.InvariantCulture);
			if (!seededInventoryKeys.Contains(item) && (!flag || (key != -847395 && key != -847396)))
			{
				Item val2 = EnsureStock(val, key);
				if (!Object.op_Implicit((Object)(object)val2))
				{
					log.LogWarning((object)(text + " did not receive Gallant Knight weapon " + key + "."));
					continue;
				}
				log.LogInfo((object)(text + " shop confirmed " + val2.Name + " (" + key + ") at " + val2.GetBuyValue(__1, __instance, true) + " silver."));
				seededInventoryKeys.Add(item);
				flag2 = true;
			}
		}
		if (flag2)
		{
			seededInventories.Value = string.Join(",", seededInventoryKeys);
		}
	}
}

plugins/SuperAdventurerPack.dll

Decompiled 4 days ago
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using SideLoader;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("local.dylan.superadventurerpack", "Super Adventurer Pack", "1.0.1")]
public sealed class SuperAdventurerPack : BaseUnityPlugin
{
	private const string PluginId = "local.dylan.superadventurerpack";

	private const int PackId = -847380;

	private const int ShopPrice = 5000;

	private const string BlacksmithId = "3Rx_R0XDLUmYaNWm66SVCQ";

	private const string TokugaNormalPriceId = "EYhBqM653UGhDd5kcdMFXg";

	private const string DonorMaterial = "mat_itm_backpackAdventurer";

	private const string PackMaterial = "mat_itm_SuperAdventurerPack";

	private static readonly int MainTex = Shader.PropertyToID("_MainTex");

	private static Texture2D plaid;

	private static ConfigEntry<string> seededStock;

	private static HashSet<string> seededShops;

	private static ManualLogSource log;

	private void Awake()
	{
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Expected O, but got Unknown
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bc: Expected O, but got Unknown
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: Expected O, but got Unknown
		//IL_0132: Unknown result type (might be due to invalid IL or missing references)
		//IL_0138: Expected O, but got Unknown
		//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01aa: Expected O, but got Unknown
		//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_020e: Unknown result type (might be due to invalid IL or missing references)
		//IL_021b: Expected O, but got Unknown
		//IL_021b: Expected O, but got Unknown
		//IL_0268: Unknown result type (might be due to invalid IL or missing references)
		//IL_0276: Expected O, but got Unknown
		log = ((BaseUnityPlugin)this).Logger;
		seededStock = ((BaseUnityPlugin)this).Config.Bind<string>("Blacksmiths", "SeededStock", "", "Internal record of saves and shops that received the initial Super Adventurer Pack stock.");
		seededShops = new HashSet<string>(seededStock.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries), StringComparer.Ordinal);
		plaid = LoadPlaid();
		Harmony val = new Harmony("local.dylan.superadventurerpack");
		val.Patch((MethodBase)AccessTools.Method(typeof(SL_Bag), "ApplyToItem", new Type[1] { typeof(Item) }, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(SuperAdventurerPack), "CheckCapacity", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		val.Patch((MethodBase)AccessTools.Method(AccessTools.TypeByName("SideLoader.CustomItemVisuals"), "CloneAndSetVisuals", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(SuperAdventurerPack), "RecolorVisualClone", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		MethodInfo methodInfo = AccessTools.Method(typeof(VisualSlot), "PositionVisuals", new Type[1] { typeof(Item) }, (Type[])null);
		HarmonyMethod val2 = new HarmonyMethod(typeof(SuperAdventurerPack), "CheckEquippedVisual", (Type[])null);
		val2.priority = 0;
		val.Patch((MethodBase)methodInfo, (HarmonyMethod)null, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		MethodInfo methodInfo2 = AccessTools.Method(typeof(Item), "GetBuyValue", new Type[3]
		{
			typeof(Character),
			typeof(Merchant),
			typeof(bool)
		}, (Type[])null);
		HarmonyMethod val3 = new HarmonyMethod(typeof(SuperAdventurerPack), "SetBlacksmithPrice", (Type[])null);
		val3.priority = 0;
		val.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, val3, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		val.Patch((MethodBase)AccessTools.Method(typeof(MerchantPouch), "RefreshInventory", new Type[1] { typeof(Dropable) }, (Type[])null), new HarmonyMethod(typeof(SuperAdventurerPack), "BeforeRestock", (Type[])null), new HarmonyMethod(typeof(SuperAdventurerPack), "AfterRestock", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		val.Patch((MethodBase)AccessTools.Method(typeof(Merchant), "OnReceiveConfirmStartShopping", new Type[2]
		{
			typeof(bool),
			typeof(Character)
		}, (Type[])null), new HarmonyMethod(typeof(SuperAdventurerPack), "SeedExistingStock", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
	}

	private static void CheckCapacity(Item __0)
	{
		Bag val = (Bag)(object)((__0 is Bag) ? __0 : null);
		if (Object.op_Implicit((Object)(object)val) && ((Item)val).ItemID == -847380)
		{
			((Item)val).InitCachedInfos();
			log.LogInfo((object)("Super Adventurer Pack capacity: " + val.BagCapacity + "; restrict dodge: " + val.RestrictDodge + "."));
		}
	}

	private static Texture2D LoadPlaid()
	{
		//IL_0004: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Expected O, but got Unknown
		Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true);
		((Object)val).name = "SuperAdventurerAlbedo";
		((Texture)val).anisoLevel = 4;
		Texture2D val2 = val;
		using Stream stream = typeof(SuperAdventurerPack).Assembly.GetManifestResourceStream(((Object)val2).name);
		using MemoryStream memoryStream = new MemoryStream();
		stream.CopyTo(memoryStream);
		if (!ImageConversion.LoadImage(val2, memoryStream.ToArray(), true))
		{
			throw new InvalidDataException("Could not decode the Super Adventurer Pack plaid texture.");
		}
		return val2;
	}

	private static void RecolorVisualClone(Item __0, GameObject __1, GameObject __result)
	{
		if (Object.op_Implicit((Object)(object)__0) && __0.ItemID == -847380 && Object.op_Implicit((Object)(object)__result) && !((Object)(object)__result == (Object)(object)__1))
		{
			string name = ((Object)__result).name;
			string text = name.Substring(name.IndexOf('_') + 1);
			((Object)__result).name = (-847380).ToString(CultureInfo.InvariantCulture) + "_" + text.Replace("AdventurerBackpack", "SuperAdventurerPack").Replace("(Clone)", "");
			ApplyPlaid(__result.GetComponent<ItemVisual>(), "prefab");
		}
	}

	private static void CheckEquippedVisual(VisualSlot __instance, Item __0)
	{
		if (Object.op_Implicit((Object)(object)__0) && __0.ItemID == -847380 && Object.op_Implicit((Object)(object)__instance.CurrentVisual))
		{
			ApplyPlaid(__instance.CurrentVisual, "equip");
		}
	}

	private static void ApplyPlaid(ItemVisual visual, string stage)
	{
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: Expected O, but got Unknown
		if (!Object.op_Implicit((Object)(object)visual) || visual.GetItemIDFromName() != -847380)
		{
			log.LogWarning((object)("Super Adventurer Pack " + stage + " check: unexpected visual pool."));
			return;
		}
		int num = 0;
		Renderer[] componentsInChildren = ((Component)visual).GetComponentsInChildren<Renderer>(true);
		foreach (Renderer val in componentsInChildren)
		{
			Material[] sharedMaterials = val.sharedMaterials;
			bool flag = false;
			for (int j = 0; j < sharedMaterials.Length; j++)
			{
				Material val2 = sharedMaterials[j];
				if (Object.op_Implicit((Object)(object)val2) && val2.HasProperty(MainTex))
				{
					if ((Object)(object)val2.GetTexture(MainTex) == (Object)(object)plaid)
					{
						num++;
					}
					else if (((Object)val2).name.StartsWith("mat_itm_backpackAdventurer", StringComparison.OrdinalIgnoreCase) || ((Object)val2).name.StartsWith("mat_itm_SuperAdventurerPack", StringComparison.OrdinalIgnoreCase))
					{
						Material val3 = new Material(val2);
						((Object)val3).name = "mat_itm_SuperAdventurerPack";
						Material val4 = val3;
						val4.SetTexture(MainTex, (Texture)(object)plaid);
						sharedMaterials[j] = val4;
						flag = true;
						num++;
					}
				}
			}
			if (flag)
			{
				val.sharedMaterials = sharedMaterials;
			}
		}
		if (num == 0)
		{
			log.LogWarning((object)("Super Adventurer Pack " + stage + " check: no backpack material found."));
			return;
		}
		log.LogInfo((object)("Super Adventurer Pack " + stage + " check: " + ((Object)visual).name + " uses the private plaid material."));
	}

	private static string TargetBlacksmith(Merchant merchant)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		if (!Object.op_Implicit((Object)(object)merchant))
		{
			return null;
		}
		string text = UID.op_Implicit(merchant.HolderUID);
		Scene scene = ((Component)merchant).gameObject.scene;
		switch (((Scene)(ref scene)).name)
		{
		case "Berg":
			if (!(text == "3Rx_R0XDLUmYaNWm66SVCQ"))
			{
				return null;
			}
			return "Quikiza";
		case "CierzoNewTerrain":
			if (!(text == "3Rx_R0XDLUmYaNWm66SVCQ"))
			{
				return null;
			}
			return "Loud-Hammer";
		case "Levant":
			if (!(text == "3Rx_R0XDLUmYaNWm66SVCQ") && !(text == "EYhBqM653UGhDd5kcdMFXg"))
			{
				return null;
			}
			return "Tokuga";
		default:
			return null;
		}
	}

	private static void SetBlacksmithPrice(Item __instance, Character __0, Merchant __1, bool __2, ref int __result)
	{
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		if (__instance.ItemID == -847380 && TargetBlacksmith(__1) != null && (__2 || !Object.op_Implicit((Object)(object)__0) || !(EnvironmentConditions.GameTime < __instance.RebuyLimitTime) || !(__instance.PreviousOwnerUID == UID.op_Implicit(__0.UID))))
		{
			__result = 5000;
		}
	}

	private static void BeforeRestock(MerchantPouch __instance, double ___m_nextRefreshTime, out string __state)
	{
		__state = ((!PhotonNetwork.isNonMasterClientInRoom && EnvironmentConditions.GameTime >= ___m_nextRefreshTime) ? TargetBlacksmith(__instance.Merchant) : null);
	}

	private static void AfterRestock(MerchantPouch __instance, string __state)
	{
		if (__state != null && Object.op_Implicit((Object)(object)EnsureStock(__instance)))
		{
			log.LogInfo((object)(__state + " restocked Super Adventurer Pack."));
		}
	}

	private static Item FindStock(MerchantPouch pouch)
	{
		return ((ItemContainer)pouch).GetItemsFromID(-847380).Find((Item item) => Object.op_Implicit((Object)(object)item) && !item.IsPendingDestroy);
	}

	private static Item EnsureStock(MerchantPouch pouch)
	{
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Expected O, but got Unknown
		Item val = FindStock(pouch);
		if (Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)ResourcesPrefabManager.Instance.GetItemPrefab(-847380)))
		{
			return val;
		}
		SL_ItemDrop val2 = new SL_ItemDrop();
		val2.DroppedItemID = -847380;
		val2.MinQty = 1;
		val2.MaxQty = 1;
		val2.GenerateDrop(((Component)pouch).transform);
		return FindStock(pouch);
	}

	private static void SeedExistingStock(Merchant __instance, bool __0, Character __1)
	{
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		if (!__0 || !Object.op_Implicit((Object)(object)__1) || PhotonNetwork.isNonMasterClientInRoom)
		{
			return;
		}
		string text = TargetBlacksmith(__instance);
		if (text == null)
		{
			return;
		}
		ItemContainer merchantPouch = __instance.MerchantPouch;
		MerchantPouch val = (MerchantPouch)(object)((merchantPouch is MerchantPouch) ? merchantPouch : null);
		Character worldHostCharacter = CharacterManager.Instance.GetWorldHostCharacter();
		if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)worldHostCharacter))
		{
			return;
		}
		string[] array = new string[5]
		{
			UID.op_Implicit(worldHostCharacter.UID),
			":",
			null,
			null,
			null
		};
		Scene scene = ((Component)__instance).gameObject.scene;
		array[2] = ((Scene)(ref scene)).name;
		array[3] = ":";
		array[4] = UID.op_Implicit(__instance.HolderUID);
		string item = string.Concat(array);
		if (!seededShops.Contains(item))
		{
			Item val2 = EnsureStock(val);
			if (!Object.op_Implicit((Object)(object)val2))
			{
				log.LogWarning((object)(text + " did not receive Super Adventurer Pack."));
				return;
			}
			log.LogInfo((object)(text + " shop confirmed Super Adventurer Pack at " + val2.GetBuyValue(__1, __instance, true) + " silver."));
			seededShops.Add(item);
			seededStock.Value = string.Join(",", seededShops);
		}
	}
}