Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of LongBo v1.1.33
plugins/BatBoys-LongBo/LongBo.dll
Decompiled 10 hours agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("LongBo")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.1.33.0")] [assembly: AssemblyInformationalVersion("1.1.33")] [assembly: AssemblyProduct("LongBo")] [assembly: AssemblyTitle("LongBo")] [assembly: AssemblyVersion("1.1.33.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace LongBo { [BepInPlugin("dev.longbo.polearms", "Long Bō", "1.1.33")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class LongBoPlugin : BaseUnityPlugin { private class Req { public string Item; public int Amount; public int PerLevel; public Req(string item, int amount, int perLevel) { Item = item; Amount = amount; PerLevel = perLevel; } } private class BoDef { public string Id; public string Name; public string Description; public string Group; public int MinLevel; public float Blunt; public float BluntPer; public float Pierce; public float PiercePer; public float Stamina; public float Durability; public float DurabilityPer; public float Block; public float Knockback; public float Weight; public bool SkipIfShogunBo; public Color Tint; public bool UseTint; public string Extra; public float ExtraAmt; public float ExtraPer; public Req[] Reqs; } private class Made { public GameObject Prefab; public object Recipe; public BoDef Def; } public const string Guid = "dev.longbo.polearms"; private static ManualLogSource Log; private static ConfigFile Cfg; private static ConfigEntry<float> DamageMultiplier; private static bool Patched; private static bool ItemsReady; private static bool WorldReady; private static bool LoggedItemList; private static bool WarnedWait; private static bool WarnedStations; private static bool InRegisters; private static bool ItemsMade; private static bool FromShogun; private static bool LatePass; private static GameObject PrefabRoot; private static readonly List<Made> MadeItems = new List<Made>(); private static readonly Dictionary<string, GameObject> Prefabs = new Dictionary<string, GameObject>(); private static readonly BoDef[] Defs = new BoDef[8] { new BoDef { Id = "BBL_BoWood", Name = "Traveler's Bō", Description = "A long staff of plain wood. Someone walked a long road with it.", Group = "wood", MinLevel = 1, Blunt = 18f, BluntPer = 3f, Pierce = 13f, PiercePer = 2f, Stamina = 9f, Durability = 170f, DurabilityPer = 40f, Block = 12f, Knockback = 30f, Weight = 2.2f, SkipIfShogunBo = true, UseTint = false, Extra = "", ExtraAmt = 0f, ExtraPer = 0f, Reqs = new Req[3] { new Req("Wood", 20, 10), new Req("Resin", 5, 0), new Req("LeatherScraps", 4, 0) } }, new BoDef { Id = "BBL_BoBronze", Name = "Bronze Bō", Description = "Bronze caps the wood, and a thin ring sits back from the tip. The first metal a clan will trust.", Group = "clan", MinLevel = 2, Blunt = 28f, BluntPer = 3f, Pierce = 12f, PiercePer = 1.5f, Stamina = 12f, Durability = 220f, DurabilityPer = 50f, Block = 16f, Knockback = 35f, Weight = 2.5f, UseTint = true, Tint = new Color(0.72f, 0.48f, 0.22f, 1f), Extra = "", ExtraAmt = 0f, ExtraPer = 0f, Reqs = new Req[3] { new Req("FineWood", 8, 0), new Req("Bronze", 10, 5), new Req("LeatherScraps", 2, 0) } }, new BoDef { Id = "BBL_BoIron", Name = "Iron Bō", Description = "Iron on the ends, and a cord the swamp has stained. The poison in it deepens as the staff is raised.", Group = "clan", MinLevel = 3, Blunt = 40f, BluntPer = 4f, Pierce = 15f, PiercePer = 1.5f, Stamina = 12f, Durability = 250f, DurabilityPer = 50f, Block = 28f, Knockback = 40f, Weight = 2.6f, UseTint = true, Tint = new Color(0.42f, 0.44f, 0.46f, 1f), Extra = "Poison", ExtraAmt = 10f, ExtraPer = 2f, Reqs = new Req[3] { new Req("RoundLog", 8, 0), new Req("Iron", 16, 8), new Req("DeerHide", 2, 0) } }, new BoDef { Id = "BBL_BoSilver", Name = "Silver Bō", Description = "A thread of silver set into the bare wood. Spirits know it, and it bites harder when the staff is raised.", Group = "clan", MinLevel = 4, Blunt = 45f, BluntPer = 3f, Pierce = 15f, PiercePer = 2f, Stamina = 12f, Durability = 300f, DurabilityPer = 50f, Block = 36f, Knockback = 45f, Weight = 2.5f, UseTint = true, Tint = new Color(0.78f, 0.8f, 0.84f, 1f), Extra = "Spirit", ExtraAmt = 15f, ExtraPer = 2f, Reqs = new Req[3] { new Req("RoundLog", 6, 0), new Req("Silver", 12, 6), new Req("WolfFang", 2, 0) } }, new BoDef { Id = "BBL_BoBlackmetal", Name = "Blackmetal Bō", Description = "Dark metal on the ends. The light, such as it is, stays in the cord.", Group = "clan", MinLevel = 4, Blunt = 65f, BluntPer = 5f, Pierce = 25f, PiercePer = 2f, Stamina = 13f, Durability = 350f, DurabilityPer = 50f, Block = 48f, Knockback = 50f, Weight = 2.4f, UseTint = true, Tint = new Color(0.28f, 0.24f, 0.32f, 1f), Extra = "", ExtraAmt = 0f, ExtraPer = 0f, Reqs = new Req[3] { new Req("FineWood", 8, 0), new Req("BlackMetal", 16, 8), new Req("LinenThread", 2, 0) } }, new BoDef { Id = "BBL_BoStorm", Name = "Storm Bō", Description = "Pale wood of Yggdrasil. The wind on a blow sweeps a foe off their feet.", Group = "dragon", MinLevel = 1, Blunt = 75f, BluntPer = 4f, Pierce = 30f, PiercePer = 2f, Stamina = 14f, Durability = 400f, DurabilityPer = 50f, Block = 58f, Knockback = 75f, Weight = 2.4f, UseTint = true, Tint = new Color(0.28f, 0.55f, 0.5f, 1f), Extra = "Lightning", ExtraAmt = 20f, ExtraPer = 2f, Reqs = new Req[3] { new Req("YggdrasilWood", 8, 0), new Req("Carapace", 12, 6), new Req("Eitr", 4, 0) } }, new BoDef { Id = "BBL_BoInfernal", Name = "Infernal Bō", Description = "Charred wood and copper caps. The cord still holds the fire.", Group = "dragon", MinLevel = 1, Blunt = 90f, BluntPer = 5f, Pierce = 35f, PiercePer = 2f, Stamina = 15f, Durability = 500f, DurabilityPer = 50f, Block = 70f, Knockback = 55f, Weight = 2.5f, UseTint = true, Tint = new Color(0.75f, 0.32f, 0.14f, 1f), Extra = "Fire", ExtraAmt = 20f, ExtraPer = 2f, Reqs = new Req[3] { new Req("Blackwood", 8, 0), new Req("FlametalNew", 16, 8), new Req("CharredBone", 4, 0) } }, new BoDef { Id = "BBL_BoRime", Name = "Rime Bō", Description = "Frozen wood, ice at the tips, and frost that caught on the cord and stayed.", Group = "dragon", MinLevel = 1, Blunt = 120f, BluntPer = 5f, Pierce = 45f, PiercePer = 2f, Stamina = 15f, Durability = 500f, DurabilityPer = 50f, Block = 84f, Knockback = 60f, Weight = 2.5f, UseTint = true, Tint = new Color(0.62f, 0.74f, 0.8f, 1f), Extra = "Frost", ExtraAmt = 20f, ExtraPer = 2f, Reqs = new Req[3] { new Req("Frostwood", 10, 0), new Req("Gold", 16, 8), new Req("FrozenFuel", 2, 0) } } }; private static object TargetDb; private static string Claimed; private static object ClaimedStationRef; private static Component ClanKnown; private static Component DragonKnown; private static bool LearnedOnce; private static readonly HashSet<string> SeenStations = new HashSet<string>(); private static object BoundDb; private static object BoundScene; private static bool Announced; private static MethodInfo HashMethodInfo; private static bool HashLooked; private static bool WarnedStatus; private static string WearFor; private static readonly Dictionary<string, object> WearCache = new Dictionary<string, object>(); private const BindingFlags Flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; [Conditional("LONGBO_TRACE")] private static void Trace(string message) { Log.LogInfo((object)message); } private void Awake() { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; Cfg = ((BaseUnityPlugin)this).Config; DamageMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Damage multiplier", 1f, "Scales blunt, pierce, elemental damage, and every per-level gain. 1 is the atgeir sheet. Use the same value on the server and every client."); if (!Patched) { Patched = true; Harmony val = new Harmony("dev.longbo.polearms"); PatchObjectList(val); PatchShutdown(val); PatchAwake(val, "ZNetScene", "AfterZNetScene"); PatchAwake(val, "ZNet", "AfterZNetScene"); PatchVnei(val); PatchCraftingUi(val); Type type = AccessTools.TypeByName("ItemDrop"); MethodInfo methodInfo = ((type == null) ? null : AccessTools.Method(type, "Awake", (Type[])null, (Type[])null)); if (methodInfo != null) { val.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(LongBoPlugin), "AfterItemDropAwake", (Type[])null, (Type[])null)) { priority = 0 }, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } } private static void PatchObjectList(Harmony harmony) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Expected O, but got Unknown //IL_00ab: Expected O, but got Unknown Type type = AccessTools.TypeByName("ObjectDB"); if (type == null) { return; } string[] array = new string[2] { "CopyOtherDB", "UpdateRegisters" }; foreach (string name in array) { MethodInfo methodInfo = FindMethod(type, name); if (!(methodInfo == null)) { harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(AccessTools.Method(typeof(LongBoPlugin), "BeforeItemList", (Type[])null, (Type[])null)) { priority = 800 }, new HarmonyMethod(AccessTools.Method(typeof(LongBoPlugin), "AfterItemList", (Type[])null, (Type[])null)) { priority = 0 }, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } } private static void PatchShutdown(Harmony harmony) { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Expected O, but got Unknown Type type = AccessTools.TypeByName("ZNet"); MethodInfo methodInfo = FindMethod(type, "Shutdown"); if (methodInfo == null) { methodInfo = FindMethod(type, "OnDestroy"); } if (methodInfo == null) { Log.LogError((object)"Could not patch ZNet.Shutdown"); return; } harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(AccessTools.Method(typeof(LongBoPlugin), "BeforeShutdown", (Type[])null, (Type[])null)) { priority = 800 }, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } public static void BeforeItemList(object __instance) { try { DropDead(__instance); } catch (Exception ex) { Log.LogError((object)("Long Bō could not clean the item list: " + ex.Message)); } } public static void BeforeShutdown() { try { UnhookWorld(); } catch (Exception ex) { Log.LogError((object)("Long Bō could not leave the world cleanly: " + ex.Message)); } } private static void UnhookWorld() { object obj = Db(); DropDead(obj); IList list = ((obj == null) ? null : (Get(obj, "m_items") as IList)); IList list2 = ((obj == null) ? null : (Get(obj, "m_recipes") as IList)); foreach (Made madeItem in MadeItems) { if (madeItem.Def != null) { RemoveNamed(list, madeItem.Def.Id); RemoveNamed(list2, "Recipe_" + madeItem.Def.Id); } } object obj2 = ZNet(); IList list3 = ((obj2 == null) ? null : (Get(obj2, "m_prefabs") as IList)); IDictionary dictionary = ((obj2 == null) ? null : (Get(obj2, "m_namedPrefabs") as IDictionary)); foreach (Made madeItem2 in MadeItems) { if (madeItem2.Prefab == null) { continue; } if (list3 != null) { for (int num = list3.Count - 1; num >= 0; num--) { if (list3[num] == madeItem2.Prefab) { list3.RemoveAt(num); } } } if (dictionary != null) { object obj3 = RealHash(((Object)madeItem2.Prefab).name); if (obj3 != null && dictionary.Contains(obj3) && dictionary[obj3] == madeItem2.Prefab) { dictionary.Remove(obj3); } } } ItemsReady = false; WorldReady = false; BoundDb = null; BoundScene = null; Announced = false; } private static void DropDead(object db) { if (db != null) { DropDeadList(Get(db, "m_items") as IList); DropDeadList(Get(db, "m_recipes") as IList); } } private static void DropDeadList(IList list) { if (list == null) { return; } for (int num = list.Count - 1; num >= 0; num--) { if (!Alive(list[num])) { list.RemoveAt(num); } } } private static bool Alive(object obj) { Object val = (Object)((obj is Object) ? obj : null); if (val == null) { return false; } try { return val.name != null; } catch { return false; } } private static MethodInfo FindMethod(Type type, string name) { if (type == null) { return null; } MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { if (methodInfo.Name == name) { return methodInfo; } } return null; } public static void AfterItemList(object __instance) { if (InRegisters) { return; } try { if (!Playing()) { ShowOnMenu(__instance ?? Db()); } else { Publish(); } } catch (Exception ex) { Log.LogError((object)("Long Bō item list pass failed: " + ex)); } } private static object ItemDb() { return TargetDb ?? Db(); } private static void ShowOnMenu(object db) { if (db == null || !VanillaReady()) { return; } TargetDb = db; try { if (MadeItems.Count == 0 || !AttachExisting(db)) { EnsureItems(finalChance: true); } ApplyAllHitStatus(); RefreshItemHashes(); } finally { TargetDb = null; } } private static bool AttachExisting(object db) { if (db == null || MadeItems.Count == 0) { return false; } IList list = Get(db, "m_items") as IList; IList list2 = Get(db, "m_recipes") as IList; if (list == null) { return false; } foreach (Made madeItem in MadeItems) { if (madeItem.Def == null || !Alive(madeItem.Prefab)) { return false; } if (FindInList(list, madeItem.Def.Id) == null) { list.Add(madeItem.Prefab); } if (list2 != null && Alive(madeItem.Recipe) && !ListHas(list2, "Recipe_" + madeItem.Def.Id)) { list2.Add(madeItem.Recipe); } } return true; } private static void PatchCraftingUi(Harmony harmony) { //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Expected O, but got Unknown //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Expected O, but got Unknown //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Expected O, but got Unknown Type type = AccessTools.TypeByName("InventoryGui"); if (type != null) { string[] array = new string[2] { "UpdateRecipeList", "UpdateCraftingPanel" }; foreach (string text in array) { MethodInfo methodInfo = AccessTools.Method(type, text, (Type[])null, (Type[])null); if (!(methodInfo == null)) { harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(AccessTools.Method(typeof(LongBoPlugin), "BeforeRecipeList", (Type[])null, (Type[])null)) { priority = 800 }, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); break; } } } Type type2 = AccessTools.TypeByName("Player"); MethodInfo methodInfo2 = ((type2 == null) ? null : AccessTools.Method(type2, "SetCraftingStation", (Type[])null, (Type[])null)); if (methodInfo2 != null) { harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(LongBoPlugin), "AfterSetStation", (Type[])null, (Type[])null)) { priority = 0 }, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } else { Log.LogWarning((object)"Player.SetCraftingStation was not found. The Shogun forges may not list the staffs."); } Type type3 = AccessTools.TypeByName("CraftingStation"); MethodInfo methodInfo3 = ((type3 == null) ? null : type3.GetMethod("Start", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)); if (methodInfo3 != null) { harmony.Patch((MethodBase)methodInfo3, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(LongBoPlugin), "AfterCraftingStationAwake", (Type[])null, (Type[])null)) { priority = 0 }, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } public static void AfterCraftingStationAwake(Component __instance) { try { if (__instance != null && __instance.gameObject != null) { PropertyInfo property = ((object)__instance.gameObject).GetType().GetProperty("activeInHierarchy"); if (!(property != null) || !(property.GetValue(__instance.gameObject, null) is bool flag) || flag) { AdoptStation(__instance); } } } catch (Exception ex) { Log.LogError((object)("Long Bō forge claim failed: " + ex)); } } public static void BeforeRecipeList() { try { Type type = AccessTools.TypeByName("Player"); object obj = ((type == null) ? null : AccessTools.Field(type, "m_localPlayer")?.GetValue(null)); if (obj != null) { AdoptStation(Get(obj, "m_currentStation")); } } catch (Exception ex) { Log.LogError((object)("Long Bō station claim failed: " + ex)); } } public static void AfterSetStation(object __0) { try { AdoptStation(__0); } catch (Exception ex) { Log.LogError((object)("Long Bō station claim failed: " + ex)); } } private static void AdoptStation(object station) { if (station == null || MadeItems.Count == 0) { return; } Component val = (Component)((station is Component) ? station : null); if (val == null || val.gameObject == null || ClaimedStationRef == val) { return; } string text = StationPrefabName(val.gameObject); if (text == null) { text = MatchLearned(station); } if (text == null) { NoteStation(val, claimed: false); return; } ClaimedStationRef = val; bool flag = text == "Forgeshogun_black"; string text2 = text + ":" + MadeItems.Count; if (Claimed != text2) { Claimed = text2; } NoteStation(val, claimed: true); foreach (Made madeItem in MadeItems) { if (madeItem.Def.Group == "dragon" == flag) { Set(madeItem.Recipe, "m_craftingStation", station); Set(madeItem.Recipe, "m_repairStation", station); } } Teach(station); } private static string MatchLearned(object station) { LearnFromShogun(); string text = Convert.ToString(Get(station, "m_name")); if (string.IsNullOrEmpty(text)) { return null; } if (ClanKnown != null && text == Convert.ToString(Get(ClanKnown, "m_name"))) { return "Forgeshogun_stone"; } if (DragonKnown != null && text == Convert.ToString(Get(DragonKnown, "m_name"))) { return "Forgeshogun_black"; } return null; } private static void LearnFromShogun() { //IL_005f: Unknown result type (might be due to invalid IL or missing references) if ((LearnedOnce && ClanKnown != null) || !(Get(Db(), "m_recipes") is IList list)) { return; } foreach (object item in list) { string text = ((!(item is Object)) ? "" : ((Object)item).name); if (text != null && text.StartsWith("Recipe_BBL_")) { continue; } object obj = Get(item, "m_craftingStation"); Component val = (Component)((obj is Component) ? obj : null); if (val != null && val.gameObject != null) { object obj2 = Get(item, "m_item"); Component val2 = (Component)((obj2 is Component) ? obj2 : null); string text2 = ((val2 != null && val2.gameObject != null) ? ((Object)val2.gameObject).name : ""); string text3 = StationPrefabName(val.gameObject); if (text3 == "Forgeshogun_black") { DragonKnown = val; } else if (text3 == "Forgeshogun_stone") { ClanKnown = val; } else if (text2.StartsWith("SER_") && ClanKnown == null) { ClanKnown = val; } } } if (ClanKnown != null || DragonKnown != null) { LearnedOnce = true; if (ClanKnown != null) { } if (DragonKnown == null) { } } } private static void Teach(object station) { Type type = AccessTools.TypeByName("Player"); object obj = ((type == null) ? null : AccessTools.Field(type, "m_localPlayer")?.GetValue(null)); if (obj == null) { return; } Remember(Get(obj, "m_knownStations"), Convert.ToString(Get(station, "m_name"))); foreach (Made madeItem in MadeItems) { if (!(Get(madeItem.Recipe, "m_resources") is Array array)) { continue; } foreach (object item in array) { object obj2 = Get(item, "m_resItem"); Component val = (Component)((obj2 is Component) ? obj2 : null); if (val != null) { object target = Get(Get(val, "m_itemData"), "m_shared"); Remember(Get(obj, "m_knownMaterial"), Convert.ToString(Get(target, "m_name"))); } } } } private static void Remember(object collection, string value) { if (collection == null || string.IsNullOrEmpty(value)) { return; } Type type = collection.GetType(); MethodInfo method = type.GetMethod("Contains"); bool flag = default(bool); int num; if (method != null) { object obj = method.Invoke(collection, new object[1] { value }); if (obj is bool) { flag = (bool)obj; num = 1; } else { num = 0; } } else { num = 0; } if (((uint)num & (flag ? 1u : 0u)) == 0) { MethodInfo method2 = type.GetMethod("Add"); if (method2 != null) { method2.Invoke(collection, new object[1] { value }); } } } private static void NoteStation(Component station, bool claimed) { string item = (claimed ? "claimed " : "ignored ") + StationChain(station.gameObject) + " name=" + Get(station, "m_name"); if (SeenStations.Add(item)) { } } private static string StationChain(GameObject go) { List<string> list = new List<string>(); Transform val = go.transform; for (int i = 0; i < 6; i++) { if (val == null) { break; } list.Add(((Object)val).name); PropertyInfo property = ((object)val).GetType().GetProperty("parent"); val = (Transform)((property == null) ? null : /*isinst with value type is only supported in some contexts*/); } return string.Join(" / ", list.ToArray()); } private static string StationPrefabName(GameObject go) { Transform val = go.transform; while (val != null) { string text = ((Object)val).name; int num = text.IndexOf('('); if (num >= 0) { text = text.Substring(0, num); } if (text == "Forgeshogun_stone" || text == "Forgeshogun_black") { return text; } PropertyInfo property = ((object)val).GetType().GetProperty("parent"); val = (Transform)((property == null) ? null : /*isinst with value type is only supported in some contexts*/); } return null; } private static void PatchAwake(Harmony harmony, string typeName, string postfix) { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown Type type = AccessTools.TypeByName(typeName); MethodInfo methodInfo = ((type == null) ? null : AccessTools.Method(type, "Awake", (Type[])null, (Type[])null)); if (methodInfo == null) { Log.LogError((object)("Could not patch " + typeName + ".Awake")); return; } MethodInfo methodInfo2 = AccessTools.Method(typeof(LongBoPlugin), postfix, (Type[])null, (Type[])null); HarmonyMethod val = new HarmonyMethod(methodInfo2) { priority = 0 }; harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } private static void PatchVnei(Harmony harmony) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown Type type = QuietType("Indexing", "VNEI.Logic"); MethodInfo methodInfo = ((type == null) ? null : AccessTools.Method(type, "IndexAll", (Type[])null, (Type[])null)); if (!(methodInfo == null)) { MethodInfo methodInfo2 = AccessTools.Method(typeof(LongBoPlugin), "BeforeVneiIndex", (Type[])null, (Type[])null); harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo2) { priority = 800 }, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } public static void BeforeVneiIndex() { try { Publish(); } catch (Exception ex) { Log.LogError((object)("Long Bō VNEI pass failed: " + ex)); } } private static void Publish() { if (!Playing()) { return; } object obj = Db(); object obj2 = ZNet(); if (obj != BoundDb) { ItemsReady = false; } if (obj2 != BoundScene) { WorldReady = false; } if (ItemsReady && WorldReady) { return; } if (!ItemsReady) { if (!VanillaReady() && !LatePass) { return; } EnsureItems(finalChance: true); if (!VanillaReady()) { return; } FillRecipes(); RefreshItemHashes(); ItemsReady = Listed(); if (ItemsReady) { BoundDb = obj; } } if (!WorldReady && StationsReady()) { BindStations(); RegisterWorldPrefabs(); WorldReady = true; BoundScene = obj2; } ApplyAllHitStatus(); if (ItemsReady && WorldReady && !Announced) { Announced = true; Log.LogInfo((object)("Registered " + MadeItems.Count + " staffs.")); } } public static void AfterZNetScene() { if (!Playing()) { return; } LatePass = true; try { Publish(); } catch (Exception ex) { Log.LogError((object)("Long Bō world pass failed: " + ex)); } } private static bool Playing() { Type type = AccessTools.TypeByName("ZNet"); PropertyInfo propertyInfo = ((type == null) ? null : AccessTools.Property(type, "instance")); object obj = ((propertyInfo == null) ? null : propertyInfo.GetValue(null, null)); if (obj == null || type == null) { return false; } if (Get(obj, "m_world") != null) { return true; } MethodInfo method = type.GetMethod("GetWorldName", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method != null && method.GetParameters().Length == 0) { string value = method.Invoke(obj, null) as string; if (!string.IsNullOrEmpty(value)) { return true; } } return false; } private static void EnsureItems(bool finalChance) { GameObject val = FindBo(); bool flag = val != null; if (ItemsMade) { if (flag && !FromShogun) { ForgetItems(); } else { if (Listed() || AttachExisting(ItemDb())) { return; } ForgetItems(); } } if (!flag && !LatePass) { if (!finalChance) { } return; } if (!flag) { string[] array = new string[4] { "StaffFireball", "StaffIce", "StaffSkeleton", "StaffShield" }; foreach (string name in array) { val = FindPrefab(name); if (val != null) { NoteMissingBo(); break; } } } if (val == null) { Log.LogError((object)"No staff prefab to clone. Long Bō added nothing."); NoteMissingBo(); return; } BoDef[] defs = Defs; foreach (BoDef boDef in defs) { if (!(boDef.SkipIfShogunBo && flag)) { try { MakeOne(val, boDef, flag); } catch (Exception ex) { Log.LogError((object)("Failed to add " + boDef.Name + ": " + ex)); } } } FromShogun = flag; ItemsMade = MadeItems.Count > 0; if (ItemsMade) { RefreshItemHashes(); } } private static void FillRecipes() { if (MadeItems.Count == 0) { return; } int num = 0; int num2 = 0; foreach (Made madeItem in MadeItems) { if (madeItem.Def != null && madeItem.Recipe != null && RecipeMissing(madeItem)) { Array value = BuildReqs(madeItem.Def); Set(madeItem.Recipe, "m_resources", value); if (RecipeMissing(madeItem)) { num2++; } else { num++; } } } if (num > 0) { } if (num2 > 0) { NoteItemList(); } } private static bool RecipeMissing(Made made) { Req[] reqs = made.Def.Reqs; foreach (Req req in reqs) { if (FindPrefab(ResolveItem(req.Item)) == null) { return true; } } if (!(Get(made.Recipe, "m_resources") is Array { Length: not 0 } array)) { return made.Def.Reqs.Length != 0; } foreach (object item in array) { if (Get(item, "m_resItem") == null) { return true; } } return false; } private static void NoteItemList() { if (LoggedItemList) { return; } LoggedItemList = true; IList list = Get(Db(), "m_items") as IList; int num = list?.Count ?? 0; Log.LogWarning((object)("Materials are still missing. The item list has " + num + " entries.")); if (list == null) { return; } int num2 = 0; foreach (object item in list) { GameObject val = (GameObject)((item is GameObject) ? item : null); if (val != null && ((Object)val).name != null) { string name = ((Object)val).name; if ((name.IndexOf("Wood", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("Bronze", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("Iron", StringComparison.OrdinalIgnoreCase) >= 0) && ++num2 >= 12) { break; } } } } private static GameObject FindBo() { string[] array = new string[3] { "SER_Bo", "SER_BO", "Ser_Bo" }; foreach (string name in array) { GameObject val = FindPrefab(name); if (val != null) { return val; } } foreach (GameObject item in AllPrefabs()) { if (item == null || string.IsNullOrEmpty(((Object)item).name)) { continue; } if (((Object)item).name.Equals("SER_Bo", StringComparison.OrdinalIgnoreCase)) { return item; } if (((Object)item).name.StartsWith("SER", StringComparison.OrdinalIgnoreCase) && ((Object)item).name.IndexOf("bokken", StringComparison.OrdinalIgnoreCase) < 0 && ((Object)item).name.IndexOf("kanobo", StringComparison.OrdinalIgnoreCase) < 0) { if (((Object)item).name.EndsWith("_Bo", StringComparison.OrdinalIgnoreCase)) { return item; } Type type = AccessTools.TypeByName("ItemDrop"); Component val2 = ((type == null) ? null : item.GetComponent(type)); object target = ((val2 == null) ? null : Get(Get(val2, "m_itemData"), "m_shared")); string text = (Get(target, "m_description") as string) ?? ""; string text2 = (Get(target, "m_name") as string) ?? ""; if (text.IndexOf("long wooden staff", StringComparison.OrdinalIgnoreCase) >= 0) { return item; } if (text2.IndexOf("Bō", StringComparison.Ordinal) >= 0) { return item; } } } return null; } private static List<GameObject> AllPrefabs() { List<GameObject> seen = new List<GameObject>(); object obj = Db(); if (obj != null) { Take(Get(obj, "m_items") as IList); } object obj2 = ZNet(); if (obj2 != null) { Take(Get(obj2, "m_prefabs") as IList); } return seen; void Take(IList list) { if (list == null) { return; } foreach (object item in list) { GameObject val = (GameObject)((item is GameObject) ? item : null); if (val != null) { seen.Add(val); } } } } private static void NoteMissingBo() { object obj = ZNet(); IList list = ((obj == null) ? null : (Get(obj, "m_prefabs") as IList)); if (list == null) { return; } int num = 0; foreach (object item in list) { GameObject val = (GameObject)((item is GameObject) ? item : null); if (val == null || ((Object)val).name == null || ((Object)val).name.IndexOf("bo", StringComparison.OrdinalIgnoreCase) < 0 || ((Object)val).name.IndexOf("SER", StringComparison.OrdinalIgnoreCase) < 0 || ++num < 12) { continue; } break; } if (num != 0) { } } private static bool Listed() { if (MadeItems.Count == 0) { return false; } if (!(Get(ItemDb(), "m_items") is IList list)) { return false; } foreach (Made madeItem in MadeItems) { if (madeItem.Def == null) { return false; } if (FindInList(list, madeItem.Def.Id) == null) { return false; } } return true; } private static void ForgetItems() { object obj = Db(); IList list = ((obj == null) ? null : (Get(obj, "m_items") as IList)); IList list2 = ((obj == null) ? null : (Get(obj, "m_recipes") as IList)); object obj2 = ZNet(); IList list3 = ((obj2 == null) ? null : (Get(obj2, "m_prefabs") as IList)); IDictionary dictionary = ((obj2 == null) ? null : (Get(obj2, "m_namedPrefabs") as IDictionary)); foreach (Made madeItem in MadeItems) { if (madeItem.Def != null) { RemoveNamed(list, madeItem.Def.Id); RemoveNamed(list2, "Recipe_" + madeItem.Def.Id); } if (list3 != null && madeItem.Prefab != null) { for (int num = list3.Count - 1; num >= 0; num--) { if (list3[num] == madeItem.Prefab) { list3.RemoveAt(num); } } } if (dictionary != null && madeItem.Prefab != null) { object obj3 = RealHash(((Object)madeItem.Prefab).name); if (obj3 != null && dictionary.Contains(obj3) && dictionary[obj3] == madeItem.Prefab) { dictionary.Remove(obj3); } } if (madeItem.Prefab != null) { Object.Destroy((Object)(object)madeItem.Prefab); } if (madeItem.Recipe != null) { object recipe = madeItem.Recipe; Object.Destroy((Object)((recipe is Object) ? recipe : null)); } } MadeItems.Clear(); Prefabs.Clear(); ItemsMade = false; FromShogun = false; ItemsReady = false; WorldReady = false; BoundDb = null; BoundScene = null; Announced = false; ClaimedStationRef = null; ClanKnown = null; DragonKnown = null; LearnedOnce = false; } public static void AfterItemDropAwake(Component __instance) { try { if (__instance != null && __instance.gameObject != null) { string text = ((Object)__instance.gameObject).name; int num = text.IndexOf('('); if (num >= 0) { text = text.Substring(0, num); } text = text.Trim(); if (Prefabs.TryGetValue(text, out var value) && value != null) { object target = Get(__instance, "m_itemData"); Set(target, "m_dropPrefab", value); } } } catch (Exception) { } } private static void MakeOne(GameObject source, BoDef def, bool realBo) { if (Cfg.Bind<bool>(def.Id, "Enabled", true, "Craft and spawn " + def.Name + ".").Value) { float num = MathfClamp(DamageMultiplier.Value, 0.05f, 10f); float blunt = Cfg.Bind<float>(def.Id, "Blunt", def.Blunt, "Quality 1 blunt.").Value * num; float blunt2 = Cfg.Bind<float>(def.Id, "Blunt per quality", def.BluntPer, "Blunt added for each quality above 1.").Value * num; float pierce = Cfg.Bind<float>(def.Id, "Pierce", def.Pierce, "Quality 1 pierce, added on top of blunt.").Value * num; float pierce2 = Cfg.Bind<float>(def.Id, "Pierce per quality", def.PiercePer, "Pierce added for each quality above 1.").Value * num; string text = ExtraField(def.Extra); float extra = 0f; float extra2 = 0f; if (text != null) { extra = Cfg.Bind<float>(def.Id, def.Extra, def.ExtraAmt, "Quality 1 " + def.Extra.ToLower() + ", added on top of blunt.").Value * num; extra2 = Cfg.Bind<float>(def.Id, def.Extra + " per quality", def.ExtraPer, def.Extra + " added for each quality above 1.").Value * num; } GameObject val = CloneInactive(source, def.Id); Type type = AccessTools.TypeByName("ItemDrop"); Component component = val.GetComponent(type); object target = Get(component, "m_itemData"); object obj = Get(target, "m_shared"); Set(obj, "m_name", def.Name); Set(obj, "m_description", def.Description); Set(obj, "m_dlc", ""); Set(obj, "m_maxQuality", 4); Set(obj, "m_weight", def.Weight); Set(obj, "m_maxDurability", def.Durability); Set(obj, "m_durabilityPerLevel", def.DurabilityPer); Set(obj, "m_blockPower", def.Block); Set(obj, "m_blockPowerPerLevel", 0f); Set(obj, "m_timedBlockBonus", 2f); Set(obj, "m_attackForce", def.Knockback); Set(target, "m_durability", def.Durability); Set(target, "m_quality", 1); Set(target, "m_dropPrefab", val); WriteDamages(obj, "m_damages", blunt, pierce, text, extra); WriteDamages(obj, "m_damagesPerLevel", blunt2, pierce2, text, extra2); FieldInfo field = obj.GetType().GetField("m_icons", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); Component component2 = source.GetComponent(type); object target2 = ((component2 == null) ? null : Get(Get(component2, "m_itemData"), "m_shared")); object obj2 = Get(target2, "m_icons"); if (field != null && obj2 != null) { field.SetValue(obj, obj2); } else if (field != null && field.GetValue(obj) == null && field.FieldType.IsArray) { field.SetValue(obj, Array.CreateInstance(field.FieldType.GetElementType(), 0)); } SetStamina(Get(obj, "m_attack"), def.Stamina); SetStamina(Get(obj, "m_secondaryAttack"), def.Stamina * 2f); ApplyHitStatus(obj, def.Extra); if (!realBo) { StripMagic(val); } ShowMesh(val); StripMagic(val); ParkPrefab(val); Dress(val, def); Prefabs[def.Id] = val; Component val2 = FindChild(val, "attach"); Type type2 = AccessTools.TypeByName("Recipe"); ScriptableObject val3 = ScriptableObject.CreateInstance(type2); ((Object)val3).name = "Recipe_" + def.Id; Set(val3, "m_item", component); Set(val3, "m_amount", 1); Set(val3, "m_enabled", true); Set(val3, "m_minStationLevel", 1); Set(val3, "m_resources", BuildReqs(def)); object target3 = ItemDb(); IList list = (IList)Get(target3, "m_items"); RemoveNamed(list, def.Id); list.Add(val); IList list2 = (IList)Get(target3, "m_recipes"); RemoveNamed(list2, "Recipe_" + def.Id); list2.Add(val3); MadeItems.Add(new Made { Prefab = val, Recipe = val3, Def = def }); string text2 = ((text == null) ? "" : (" " + def.Extra.ToLower() + " " + extra + " +" + extra2)); } } private static void RefreshItemHashes() { object obj = ItemDb(); if (obj == null) { return; } MethodInfo methodInfo = FindMethod(obj.GetType(), "UpdateRegisters"); if (methodInfo == null) { methodInfo = FindMethod(obj.GetType(), "UpdateItemHashes"); } if (methodInfo != null && methodInfo.GetParameters().Length == 0 && !InRegisters) { InRegisters = true; try { methodInfo.Invoke(obj, null); } finally { InRegisters = false; } } if (!(Get(obj, "m_itemByHash") is IDictionary dictionary)) { return; } foreach (KeyValuePair<string, GameObject> prefab in Prefabs) { object obj2 = RealHash(prefab.Key); if (obj2 != null && prefab.Value != null) { dictionary[obj2] = prefab.Value; } } } private static Component FindChild(GameObject go, string name) { if (go == null) { return null; } Transform[] componentsInChildren = go.GetComponentsInChildren<Transform>(true); if (componentsInChildren == null) { return null; } Transform[] array = componentsInChildren; foreach (Transform val in array) { if (val != null && ((Component)val).gameObject != null && ((Object)((Component)val).gameObject).name == name) { return (Component)(object)val; } } return null; } private static Array BuildReqs(BoDef def) { Type type = AccessTools.TypeByName("Piece"); Type nestedType = type.GetNestedType("Requirement"); List<object> list = new List<object>(); Req[] reqs = def.Reqs; foreach (Req req in reqs) { string name = ResolveItem(req.Item); GameObject val = FindPrefab(name); if (val == null) { if (VanillaReady()) { Log.LogWarning((object)(def.Name + " is missing material " + req.Item + ". That part of the recipe was skipped.")); } else if (!WarnedWait) { WarnedWait = true; } } else { Component component = val.GetComponent(AccessTools.TypeByName("ItemDrop")); object obj = Activator.CreateInstance(nestedType); Set(obj, "m_resItem", component); Set(obj, "m_amount", req.Amount); Set(obj, "m_amountPerLevel", req.PerLevel); Set(obj, "m_recover", true); list.Add(obj); } } Array array = Array.CreateInstance(nestedType, list.Count); for (int j = 0; j < list.Count; j++) { array.SetValue(list[j], j); } return array; } private static bool VanillaReady() { return FindPrefab("Wood") != null || FindPrefab("FineWood") != null; } private static string ResolveItem(string name) { if (FindPrefab(name) != null) { return name; } if (name == "FlametalNew" && FindPrefab("Flametal") != null) { return "Flametal"; } return name; } private static void BindStations() { if (MadeItems.Count == 0) { return; } if (!StationsReady()) { if (!WarnedStations) { WarnedStations = true; } return; } foreach (Made madeItem in MadeItems) { bool preferred; GameObject val = PickStation(madeItem.Def, out preferred); int num = ((!preferred) ? 1 : madeItem.Def.MinLevel); num = Cfg.Bind<int>(madeItem.Def.Id, "Station level", num, preferred ? "Minimum station level. Defaults to the Shogun table's level for this tier." : "Shogun table was missing, so this crafts at station level 1 on the fallback bench.").Value; if (val == null) { Log.LogWarning((object)(madeItem.Def.Name + " has no crafting station. It will craft from the inventory.")); Set(madeItem.Recipe, "m_minStationLevel", 1); continue; } Component val2 = StationOn(val, AccessTools.TypeByName("CraftingStation")); Set(madeItem.Recipe, "m_craftingStation", val2); Set(madeItem.Recipe, "m_repairStation", val2); Set(madeItem.Recipe, "m_minStationLevel", Math.Max(1, num)); string text = ((val2 == null) ? ((Object)val).name : Convert.ToString(Get(val2, "m_name"))); } LearnFromShogun(); if (ClanKnown != null) { PointGroup(ClanKnown, dragon: false); } if (DragonKnown != null) { PointGroup(DragonKnown, dragon: true); } } private static bool StationsReady() { return FindPrefab("forge") != null || FindPrefab("piece_workbench") != null || FindPrefab("Forgeshogun_stone") != null || FindPrefab("Forgeshogun_black") != null; } private static void PointGroup(object station, bool dragon) { foreach (Made madeItem in MadeItems) { if (madeItem.Def.Group == "dragon" == dragon) { Set(madeItem.Recipe, "m_craftingStation", station); Set(madeItem.Recipe, "m_repairStation", station); } } } private static GameObject PickStation(BoDef def, out bool preferred) { string value = Cfg.Bind<string>(def.Id, "Station prefabs", "", "Optional comma-separated prefab names. First one that exists wins. Empty uses the default list.").Value; string[] array = (string.IsNullOrEmpty(value) ? DefaultStations(def.Group) : value.Split(new char[1] { ',' })); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.Length != 0) { GameObject val = FindPrefab(text); Type craftingType = AccessTools.TypeByName("CraftingStation"); if (val != null && StationOn(val, craftingType) != null) { preferred = (string.IsNullOrEmpty(value) ? (text == DefaultStations(def.Group)[0]) : (i == 0)); return val; } } } preferred = false; return null; } private static string[] DefaultStations(string group) { if (group == "dragon") { return new string[3] { "Forgeshogun_black", "blackforge", "forge" }; } if (group == "clan") { return new string[2] { "Forgeshogun_stone", "forge" }; } return new string[2] { "Forgeshogun_stone", "piece_workbench" }; } private static Component StationOn(GameObject prefab, Type craftingType) { if (prefab == null || craftingType == null) { return null; } Component component = prefab.GetComponent(craftingType); if (component != null) { return component; } MethodInfo method = typeof(GameObject).GetMethod("GetComponentInChildren", new Type[2] { typeof(Type), typeof(bool) }); if (method != null) { object? obj = method.Invoke(prefab, new object[2] { craftingType, true }); return (Component)((obj is Component) ? obj : null); } method = typeof(GameObject).GetMethod("GetComponentInChildren", new Type[1] { typeof(Type) }); if (method == null) { return null; } object? obj2 = method.Invoke(prefab, new object[1] { craftingType }); return (Component)((obj2 is Component) ? obj2 : null); } private static GameObject CloneInactive(GameObject source, string name) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown if (PrefabRoot == null) { PrefabRoot = new GameObject("LongBoPrefabs"); PrefabRoot.SetActive(false); Object.DontDestroyOnLoad((Object)(object)PrefabRoot); } GameObject val = (GameObject)Object.Instantiate((Object)(object)source, PrefabRoot.transform); ((Object)val).name = name; return val; } private static void RegisterWorldPrefabs() { object obj = ZNet(); if (obj == null) { return; } IList list = Get(obj, "m_prefabs") as IList; IDictionary dictionary = Get(obj, "m_namedPrefabs") as IDictionary; foreach (Made madeItem in MadeItems) { if (madeItem.Prefab == null) { continue; } if (list != null && !ContainsGo(list, madeItem.Prefab)) { list.Add(madeItem.Prefab); } if (dictionary == null) { continue; } object obj2 = RealHash(((Object)madeItem.Prefab).name); if (obj2 == null) { Log.LogError((object)(((Object)madeItem.Prefab).name + " was not added to the spawn list. Valheim's hash method was not found, and a guessed hash could replace a vanilla prefab.")); continue; } if (dictionary.Contains(obj2)) { object? obj3 = dictionary[obj2]; GameObject val = (GameObject)((obj3 is GameObject) ? obj3 : null); if (val != null && val != madeItem.Prefab && ((Object)val).name != ((Object)madeItem.Prefab).name) { Log.LogError((object)("Refusing to replace " + ((Object)val).name + " with " + ((Object)madeItem.Prefab).name + ".")); continue; } } dictionary[obj2] = madeItem.Prefab; } } private static object RealHash(string text) { MethodInfo methodInfo = HashMethod(); if (methodInfo == null || string.IsNullOrEmpty(text)) { return null; } return methodInfo.Invoke(null, new object[1] { text }); } private static MethodInfo HashMethod() { if (HashLooked) { return HashMethodInfo; } HashLooked = true; string[] array = new string[2] { "StringExtensionMethods", "StringExtension" }; foreach (string name in array) { Type type = QuietType(name, null); if (!(type == null)) { HashMethodInfo = AccessTools.Method(type, "GetStableHashCode", new Type[1] { typeof(string) }, (Type[])null); if (HashMethodInfo != null) { return HashMethodInfo; } } } Log.LogError((object)"GetStableHashCode was not found. Staff spawn registration was skipped so a bad hash cannot overwrite Wood or any other vanilla prefab."); return null; } private static Type QuietType(string name, string ns) { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { Type[] types; try { types = assembly.GetTypes(); } catch (ReflectionTypeLoadException ex) { types = ex.Types; } catch { continue; } if (types == null) { continue; } Type[] array = types; foreach (Type type in array) { if (!(type == null) && !(type.Name != name) && (ns == null || !(type.Namespace != ns))) { return type; } } } return null; } private static string ExtraField(string extra) { return extra switch { "Poison" => "m_poison", "Pierce" => "m_pierce", "Spirit" => "m_spirit", "Lightning" => "m_lightning", "Fire" => "m_fire", "Frost" => "m_frost", _ => null, }; } private static string StatusName(string extra) { return extra switch { "Poison" => "Poison", "Fire" => "Burning", "Frost" => "Frost", "Lightning" => "Lightning", _ => null, }; } private static void ApplyAllHitStatus() { if (MadeItems.Count == 0) { return; } Type type = AccessTools.TypeByName("ItemDrop"); foreach (Made madeItem in MadeItems) { if (madeItem.Def != null && madeItem.Prefab != null && !(type == null)) { Component component = madeItem.Prefab.GetComponent(type); ApplyHitStatus(Get(Get(component, "m_itemData"), "m_shared"), madeItem.Def.Extra); } } } private static void ApplyHitStatus(object shared, string extra) { string text = StatusName(extra); if (shared == null || text == null) { return; } object obj = FindStatus(text); if (obj == null) { if (!WarnedStatus) { WarnedStatus = true; Log.LogWarning((object)("Could not find the " + text + " status effect yet. The hit will still carry the damage.")); } } else { Set(Get(shared, "m_attack"), "m_attackStatusEffect", obj); Set(Get(shared, "m_secondaryAttack"), "m_attackStatusEffect", obj); } } private static object FindStatus(string name) { object obj = Db(); if (obj == null) { return null; } string[] array = new string[2] { "m_StatusEffects", "m_statusEffects" }; foreach (string field in array) { if (!(Get(obj, field) is IList list)) { continue; } foreach (object item in list) { Object val = (Object)((item is Object) ? item : null); if (val != null && val.name == name) { return item; } } } return null; } private static void WriteDamages(object shared, string field, float blunt, float pierce, string extraField, float extra) { object obj = Get(shared, field); if (obj == null) { FieldInfo field2 = shared.GetType().GetField(field, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field2 == null) { return; } obj = Activator.CreateInstance(field2.FieldType); } object obj2 = obj; FieldInfo[] fields = obj2.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { if (!(fieldInfo.FieldType != typeof(float))) { float num = 0f; if (fieldInfo.Name == "m_blunt") { num = blunt; } else if (fieldInfo.Name == "m_pierce") { num = pierce; } else if (extraField != null && fieldInfo.Name == extraField) { num = extra; } fieldInfo.SetValue(obj2, num); } } Set(shared, field, obj2); } private static void SetStamina(object attack, float stamina) { if (attack != null) { FieldInfo field = attack.GetType().GetField("m_attackStamina", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { field.SetValue(attack, stamina); } } } private static void Tint(GameObject go, Color color) { //IL_00a4: Unknown result type (might be due to invalid IL or missing references) Renderer[] componentsInChildren = go.GetComponentsInChildren<Renderer>(true); if (componentsInChildren == null) { return; } Renderer[] array = componentsInChildren; foreach (Renderer val in array) { if (val == null || (!(val is MeshRenderer) && !(val is SkinnedMeshRenderer))) { continue; } Material[] materials = val.materials; if (materials == null) { continue; } Material[] array2 = materials; foreach (Material val2 in array2) { if (val2 != null && val2.HasProperty("_Color")) { val2.SetColor("_Color", color); } } val.materials = materials; } } private static void ParkPrefab(GameObject go) { go.SetActive(true); Transform transform = go.transform; PropertyInfo property = ((object)transform).GetType().GetProperty("localPosition"); PropertyInfo property2 = ((object)transform).GetType().GetProperty("localRotation"); if (property != null && property.CanWrite) { property.SetValue(transform, Activator.CreateInstance(property.PropertyType), null); } if (property2 != null && property2.CanWrite) { object obj = Activator.CreateInstance(property2.PropertyType); FieldInfo field = property2.PropertyType.GetField("w"); if (field != null) { field.SetValue(obj, 1f); } property2.SetValue(transform, obj, null); } } private static void Dress(GameObject clone, BoDef def) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Unknown result type (might be due to invalid IL or missing references) //IL_02a6: Unknown result type (might be due to invalid IL or missing references) //IL_02b6: Unknown result type (might be due to invalid IL or missing references) //IL_02c2: Unknown result type (might be due to invalid IL or missing references) //IL_02fa: Unknown result type (might be due to invalid IL or missing references) //IL_0306: Unknown result type (might be due to invalid IL or missing references) //IL_0323: Unknown result type (might be due to invalid IL or missing references) //IL_032f: Unknown result type (might be due to invalid IL or missing references) //IL_0338: Unknown result type (might be due to invalid IL or missing references) //IL_036b: Unknown result type (might be due to invalid IL or missing references) //IL_0370: Unknown result type (might be due to invalid IL or missing references) //IL_0383: Unknown result type (might be due to invalid IL or missing references) //IL_0388: Unknown result type (might be due to invalid IL or missing references) //IL_03a5: Unknown result type (might be due to invalid IL or missing references) //IL_03b0: Unknown result type (might be due to invalid IL or missing references) //IL_03cd: Unknown result type (might be due to invalid IL or missing references) //IL_03d8: Unknown result type (might be due to invalid IL or missing references) //IL_03e1: Unknown result type (might be due to invalid IL or missing references) //IL_040e: Unknown result type (might be due to invalid IL or missing references) //IL_0413: Unknown result type (might be due to invalid IL or missing references) //IL_0423: Unknown result type (might be due to invalid IL or missing references) //IL_0428: Unknown result type (might be due to invalid IL or missing references) //IL_045b: Unknown result type (might be due to invalid IL or missing references) //IL_0460: Unknown result type (might be due to invalid IL or missing references) //IL_0473: Unknown result type (might be due to invalid IL or missing references) //IL_0478: Unknown result type (might be due to invalid IL or missing references) //IL_04b0: Unknown result type (might be due to invalid IL or missing references) //IL_04bc: Unknown result type (might be due to invalid IL or missing references) //IL_04d9: Unknown result type (might be due to invalid IL or missing references) //IL_04e5: Unknown result type (might be due to invalid IL or missing references) //IL_0502: Unknown result type (might be due to invalid IL or missing references) //IL_050e: Unknown result type (might be due to invalid IL or missing references) //IL_0517: Unknown result type (might be due to invalid IL or missing references) Component obj = FindChild(clone, "Staff"); Transform val = (Transform)(object)((obj is Transform) ? obj : null); if (val == null) { Log.LogWarning((object)(def.Name + " has no Staff mesh to dress.")); return; } Look(def.Id, out var wood, out var metal, out var wrap, out var glow, out var metalness, out var gloss, out var capLen); TintStaff(val, wood, wrap); WearFor = def.Id; Color glow2 = default(Color); ((Color)(ref glow2))..ctor(0f, 0f, 0f, 1f); if (def.Id == "BBL_BoBronze") { EndCap(val, 0.2606f, capLen, metal, metalness, gloss, glow2); EndCap(val, -0.2606f, capLen, metal, metalness, gloss, glow2); Band(val, "ring_tip", 0.2f, 0.012f, 0.0064f, metal, metalness, gloss, glow2); Band(val, "ring_butt", -0.2f, 0.012f, 0.0064f, metal, metalness, gloss, glow2); } else if (def.Id == "BBL_BoIron") { EndCap(val, 0.2606f, capLen, metal, metalness, gloss, glow2); EndCap(val, -0.2606f, capLen, metal, metalness, gloss, glow2); } else if (def.Id == "BBL_BoSilver") { Color glow3 = default(Color); ((Color)(ref glow3))..ctor(glow.r * 0.35f, glow.g * 0.35f, glow.b * 0.35f, 1f); EndCap(val, 0.2606f, capLen, metal, metalness, gloss, glow3); EndCap(val, -0.2606f, capLen, metal, metalness, gloss, glow3); Color color = default(Color); ((Color)(ref color))..ctor(0.42f, 0.55f, 0.98f, 1f); Color glow4 = default(Color); ((Color)(ref glow4))..ctor(0.16f, 0.24f, 0.5f, 1f); Band(val, "inlay_tip", 0.175f, 0.01f, 0.006f, color, 0.95f, 0.8f, glow4); Band(val, "inlay_butt", -0.175f, 0.01f, 0.006f, color, 0.95f, 0.8f, glow4); } else if (def.Id == "BBL_BoBlackmetal") { Color color2 = default(Color); ((Color)(ref color2))..ctor(0.26f, 0.2f, 0.32f, 1f); EndCap(val, 0.2606f, capLen, color2, 0.7f, 0.35f, glow2); EndCap(val, -0.2606f, capLen, color2, 0.7f, 0.35f, glow2); Color color3 = default(Color); ((Color)(ref color3))..ctor(0.64f, 0.42f, 0.8f, 1f); Band(val, "collar_a", 0.04f, 0.012f, 0.0082f, color3, 0.85f, 0.6f, glow); Band(val, "collar_b", -0.04f, 0.012f, 0.0082f, color3, 0.85f, 0.6f, glow); GlowCord(val, glow); } else if (def.Id == "BBL_BoStorm") { EndCap(val, 0.2606f, 0.04f, metal, metalness, gloss, glow2); EndCap(val, -0.2606f, 0.04f, metal, metalness, gloss, glow2); Band(val, "band_a", -0.17f, 0.024f, 0.0082f, metal, 0.35f, 0.4f, glow); Band(val, "band_b", 0.08f, 0.016f, 0.0082f, metal, 0.35f, 0.4f, glow); GlowCord(val, glow); } else if (def.Id == "BBL_BoInfernal") { EndCap(val, 0.2606f, capLen, metal, metalness, gloss, glow); EndCap(val, -0.2606f, capLen, metal, metalness, gloss, glow); } else if (def.Id == "BBL_BoRime") { EndCap(val, 0.2606f, 0.04f, metal, metalness, gloss, glow); EndCap(val, -0.2606f, 0.04f, metal, metalness, gloss, glow); Color color4 = default(Color); ((Color)(ref color4))..ctor(0.9f, 0.97f, 1f, 1f); Band(val, "frost_tip", 0.19f, 0.01f, 0.0062f, color4, 0.4f, 0.6f, glow); Band(val, "frost_butt", -0.19f, 0.01f, 0.0062f, color4, 0.4f, 0.6f, glow); Band(val, "frost_ring", 0.044f, 0.014f, 0.0072f, color4, 0.35f, 0.55f, glow); GlowCord(val, glow); } } private static void Look(string id, out Color wood, out Color metal, out Color wrap, out Color glow, out float metalness, out float gloss, out float capLen) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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_0079: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Unknown result type (might be due to invalid IL or missing references) //IL_027f: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Unknown result type (might be due to invalid IL or missing references) //IL_02c9: Unknown result type (might be due to invalid IL or missing references) //IL_02e3: Unknown result type (might be due to invalid IL or missing references) //IL_02e8: Unknown result type (might be due to invalid IL or missing references) //IL_0302: Unknown result type (might be due to invalid IL or missing references) //IL_0307: Unknown result type (might be due to invalid IL or missing references) //IL_0322: Unknown result type (might be due to invalid IL or missing references) //IL_0327: Unknown result type (might be due to invalid IL or missing references) //IL_036c: Unknown result type (might be due to invalid IL or missing references) //IL_0371: Unknown result type (might be due to invalid IL or missing references) //IL_038b: Unknown result type (might be due to invalid IL or missing references) //IL_0390: Unknown result type (might be due to invalid IL or missing references) //IL_03aa: Unknown result type (might be due to invalid IL or missing references) //IL_03af: Unknown result type (might be due to invalid IL or missing references) //IL_03ca: Unknown result type (might be due to invalid IL or missing references) //IL_03cf: Unknown result type (might be due to invalid IL or missing references) //IL_0414: Unknown result type (might be due to invalid IL or missing references) //IL_0419: Unknown result type (might be due to invalid IL or missing references) //IL_0433: Unknown result type (might be due to invalid IL or missing references) //IL_0438: Unknown result type (might be due to invalid IL or missing references) //IL_0452: Unknown result type (might be due to invalid IL or missing references) //IL_0457: Unknown result type (might be due to invalid IL or missing references) //IL_0472: Unknown result type (might be due to invalid IL or missing references) //IL_0477: Unknown result type (might be due to invalid IL or missing references) wood = new Color(1f, 1f, 1f, 1f); metal = new Color(0.72f, 0.48f, 0.22f, 1f); wrap = new Color(0.4f, 0.24f, 0.14f, 1f); glow = new Color(0f, 0f, 0f, 1f); metalness = 0.85f; gloss = 0.55f; capLen = 0.0525f; switch (id) { case "BBL_BoWood": wrap = new Color(0.45f, 0.28f, 0.16f, 1f); break; case "BBL_BoIron": wood = new Color(0.55f, 0.46f, 0.36f, 1f); metal = new Color(0.78f, 0.8f, 0.82f, 1f); wrap = new Color(0.46f, 0.58f, 0.32f, 1f); metalness = 0.92f; gloss = 0.62f; break; case "BBL_BoSilver": wood = new Color(0.58f, 0.42f, 0.26f, 1f); metal = new Color(0.62f, 0.72f, 0.95f, 1f); wrap = new Color(0.38f, 0.48f, 0.78f, 1f); glow = new Color(0.08f, 0.12f, 0.28f, 1f); metalness = 0.92f; gloss = 0.7f; break; case "BBL_BoBlackmetal": wood = new Color(0.2f, 0.18f, 0.22f, 1f); metal = new Color(0.58f, 0.46f, 0.72f, 1f); wrap = new Color(0.52f, 0.34f, 0.62f, 1f); glow = new Color(0.16f, 0.06f, 0.24f, 1f); metalness = 0.88f; gloss = 0.62f; break; case "BBL_BoStorm": wood = new Color(0.78f, 0.84f, 0.62f, 1f); metal = new Color(0.22f, 0.48f, 0.42f, 1f); wrap = new Color(0.28f, 0.62f, 0.54f, 1f); glow = new Color(0.05f, 0.22f, 0.16f, 1f); metalness = 0.4f; gloss = 0.4f; break; case "BBL_BoInfernal": wood = new Color(0.16f, 0.14f, 0.13f, 1f); metal = new Color(0.75f, 0.32f, 0.14f, 1f); wrap = new Color(0.62f, 0.2f, 0.08f, 1f); glow = new Color(0.45f, 0.1f, 0.02f, 1f); metalness = 0.8f; gloss = 0.45f; break; case "BBL_BoRime": wood = new Color(0.74f, 0.78f, 0.84f, 1f); metal = new Color(0.9f, 0.96f, 1f, 1f); wrap = new Color(0.55f, 0.78f, 0.95f, 1f); glow = new Color(0.28f, 0.48f, 0.7f, 1f); metalness = 0.72f; gloss = 0.58f; break; } } private static void EndCap(Transform staff, float z, float length, Color color, float metalness, float gloss, Color glow) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) GameObject val = Band(staff, (z >= 0f) ? "cap_tip" : "cap_butt", z, length, 0.0069f, color, metalness, gloss, glow); if (val != null) { ApplyWear(val, WearFor, (z >= 0f) ? 1 : 2); } } private static void GlowCord(Transform staff, Color glow) { //IL_00cd: Unknown result type (might be due to invalid IL or missing references) MeshRenderer component = ((Component)staff).GetComponent<MeshRenderer>(); if (component == null || ((Renderer)component).materials == null) { return; } Material[] materials = ((Renderer)component).materials; for (int i = 0; i < materials.Length; i++) { if (materials[i] == null) { continue; } string text = ((((Object)materials[i]).name == null) ? "" : ((Object)materials[i]).name.ToLowerInvariant()); if (text.Contains("handle") || text.Contains("wrap") || (i > 0 && !text.Contains("wood"))) { materials[i].EnableKeyword("_EMISSION"); if (materials[i].HasProperty("_EmissionColor")) { materials[i].SetColor("_EmissionColor", glow); } } } ((Renderer)component).materials = materials; } private static void TintStaff(Transform staff, Color wood, Color wrap) { //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) MeshRenderer component = ((Component)staff).GetComponent<MeshRenderer>(); if (component == null || ((Renderer)component).materials == null) { return; } Material[] materials = ((Renderer)component).materials; for (int i = 0; i < materials.Length; i++) { if (materials[i] != null && materials[i].HasProperty("_Color")) { string text = ((((Object)materials[i]).name == null) ? "" : ((Object)materials[i]).name.ToLowerInvariant()); Color val = ((text.Contains("handle") || text.Contains("wrap") || (i > 0 && !text.Contains("wood"))) ? wrap : wood); materials[i].SetColor("_Color", val); materials[i].color = val; } } ((Renderer)component).materials = materials; } private static GameObject Band(Transform parent, string name, float z, float length, float radius, Color color, float metalness, float gloss, Color glow) { //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) GameObject val = NewCylinder(name); if (val == null) { return null; } val.transform.SetParent(parent, false); SetVec(val.transform, "localPosition", 0f, 0f, z); SetVec(val.transform, "localScale", radius / 0.5f, length / 2f, radius / 0.5f); SetRotX(val.transform, 90f); MeshRenderer component = val.GetComponent<MeshRenderer>(); if (component == null) { return val; } MeshRenderer component2 = ((Component)parent).GetComponent<MeshRenderer>(); Material donor = ((component2 != null && ((Renderer)component2).materials != null && ((Renderer)component2).materials.Length != 0) ? ((Renderer)component2).materials[0] : null); Material val2 = CopyMaterial(donor); if (val2 == null) { return val; } if (val2.HasProperty("_Color")) { val2.SetColor("_Color", color); } val2.color = color; SetFloat(val2, "_Metallic", metalness); SetFloat(val2, "_Glossiness", gloss); if (glow.r + glow.g + glow.b > 0.01f) { val2.EnableKeyword("_EMISSION"); if (val2.HasProperty("_EmissionColor")) { val2.SetColor("_EmissionColor", glow); } } PropertyInfo property = ((object)component).GetType().GetProperty("sharedMaterial"); if (property != null && property.CanWrite) { property.SetValue(component, val2, null); } return val; } private static void ApplyWear(GameObject piece, string id, int salt) { if (piece == null || string.IsNullOrEmpty(id)) { return; } object obj = WearTexture(id, salt); if (obj == null) { return; } MeshRenderer component = piece.GetComponent<MeshRenderer>(); if (component == null) { return; } PropertyInfo property = ((object)component).GetType().GetProperty("sharedMaterial"); object obj2 = ((property == null) ? null : property.GetValue(component, null)); if (obj2 == null) { return; } MethodInfo methodInfo = null; MethodInfo[] methods = obj2.GetType().GetMethods(); foreach (MethodInfo methodInfo2 in methods) { if (!(methodInfo2.Name != "SetTexture")) { ParameterInfo[] parameters = methodInfo2.GetParameters(); if (parameters.Length == 2 && parameters[0].ParameterType == typeof(string)) { methodInfo = methodInfo2; break; } } } if (!(methodInfo == null)) { methodInfo.Invoke(obj2, new object[2] { "_MainTex", obj }); } } private static object WearTexture(string id, int salt) { string text = id + ":" + salt; if (WearCache.TryGetValue(text, out var value)) { return value; } Type type = QuietType("Texture2D", "UnityEngine"); Type type2 = QuietType("TextureFormat", "UnityEngine"); Type type3 = QuietType("Color", "UnityEngine"); if (type == null || type2 == null || type3 == null) { return null; } ConstructorInfo constructor = type.GetConstructor(new Type[4] { typeof(int), typeof(int), type2, typeof(bool) }); if (constructor == null) { return null; } object obj = constructor.Invoke(new object[4] { 128, 128, Enum.Parse(type2, "RGBA32"), false }); if (obj == null) { return null; } type.GetProperty("name")?.SetValue(obj, "wear_" + text, null); float[] rgb = new float[49152]; for (int i = 0; i < rgb.Length; i++) { rgb[i] = 1f; } int num = StableHash(id) + salt * 97; Random rng = new Random((num == int.MinValue) ? 1 : Math.Abs(num)); Action<int, int, float> action = delegate(int x, int y, float keep) { if ((uint)y < 128u) { x %= 128; if (x < 0) { x += 128; } int num7 = (y * 128 + x) * 3; rgb[num7] = ClampWear(rgb[num7] * keep); rgb[num7 + 1] = ClampWear(rgb[num7 + 1] * keep); rgb[num7 + 2] = ClampWear(rgb[num7 + 2] * keep); } }; for (int num2 = 0; num2 < 3; num2++) { for (int num3 = 0; num3 < 128; num3++) { float arg = 0.68f - 0.12f * (float)((num3 * 13 + num2 + salt) & 3) / 3f; action(num3, num2, arg); action(num3, 127 - num2, arg); } } switch (id) { case "BBL_BoIron": Scratches(rng, 128, action, 5, 16, 34, 0.48f, 1); Patches(rng, 128, action, 2, 0.55f, 4); break; case "BBL_BoSilver": Scratches(rng, 128, action, 10, 12, 30, 0.58f, 0); break; case "BBL_BoBlackmetal": Scratches(rng, 128, action, 6, 10, 24, 1.5f, 0); break; case "BBL_BoStorm": Scratches(rng, 128, action, 7, 6, 16, 0.5f, 0); break; case "BBL_BoInfernal": Patches(rng, 128, action, 4, 0.45f, 6); Scratches(rng, 128, action, 3, 10, 18, 0.52f, 1); break; case "BBL_BoRime": Scratches(rng, 128, action, 4, 8, 18, 1.45f, 0); Patches(rng, 128, action, 2, 0.55f, 3); break; default: Scratches(rng, 128, action, 6, 14, 28, 0.5f, 1); Patches(rng, 128, action, 2, 0.58f, 4); break; } ConstructorInfo constructor2 = type3.GetConstructor(new Type[4] { typeof(float), typeof(float), typeof(float), typeof(float) }); if (constructor2 == null) { return null; } Array array = Array.CreateInstance(type3, 16384); for (int num4 = 0; num4 < 16384; num4++) { array.SetValue(constructor2.Invoke(new object[4] { rgb[num4 * 3], rgb[num4 * 3 + 1], rgb[num4 * 3 + 2], 1f }), num4); } MethodInfo methodInfo = null; MethodInfo[] methods = type.GetMethods(); foreach (MethodInfo methodInfo2 in methods) { if (!(methodInfo2.Name != "SetPixels")) { ParameterInfo[] parameters = methodInfo2.GetParameters(); if (parameters.Length == 1 && parameters[0].ParameterType.IsArray) { methodInfo = methodInfo2; break; } } } if (methodInfo == null) { return null; } methodInfo.Invoke(obj, new object[1] { array }); MethodInfo[] methods2 = type.GetMethods(); foreach (MethodInfo methodInfo3 in methods2) { if (methodInfo3.Name == "Apply" && methodInfo3.GetParameters().Length == 0) { methodInfo3.Invoke(obj, null); break; } } SetEnum(obj, "filterMode", "FilterMode", "Bilinear"); SetEnum(obj, "wrapMode", "TextureWrapMode", "Repeat"); WearCache[text] = obj; return obj; } private static void Scratches(Random rng, int n, Action<int, int, float> ink, int count, int minLen, int maxLen, float keep, int width) { for (int i = 0; i < count; i++) { int num = rng.Next(n); int num2 = rng.Next(8, n - 8); int num3 = rng.Next(minLen, maxLen); int num4 = rng.Next(3) - 1; int num5 = rng.Next(3) - 1; if (num4 == 0 && num5 == 0) { num4 = 1; } for (int j = 0; j < num3; j++) { for (int k = -width; k <= width; k++) { ink(num + num4 * j + k, num2 + num5 * j, keep); } } } } private static void Patches(Random rng, int n, Action<int, int, float> ink, int count, float keep, int rad) { for (int i = 0; i < count; i++) { int num = rng.Next(n); int num2 = rng.Next(10, n - 10); for (int j = -rad; j <= rad; j++) { for (int k = -rad; k <= rad; k++) { if (k * k + j * j <= rad * rad) { ink(num + k, num2 + j, keep); } } } } } private static float ClampWear(float value) { if (value < 0.4f) { return 0.4f; } if (value > 1.5f) { return 1.5f; } return value; } private static int StableHash(string text) { int num = 23; for (int i = 0; i < text.Length; i++) { num = num * 31 + text[i]; } return num; } private static void SetEnum(object target, string prop, string enumName, string value) { PropertyInfo property = target.GetType().GetProperty(prop); Type type = QuietType(enumName, "UnityEngine"); if (!(property == null) && !(type == null) && property.CanWrite) { property.SetValue(target, Enum.Parse(type, value), null); } } private static GameObject NewCylinder(string name) { Type type = QuietType("PrimitiveType", "UnityEngine"); if (type == null) { return null; } MethodInfo method = typeof(GameObject).GetMethod("CreatePrimitive", new Type[1] { type }); if (method == null) { return null; } object obj = Enum.Parse(type, "Cylinder"); object? obj2 = method.Invoke(null, new object[1] { obj }); GameObject val = (GameObject)((obj2 is GameObject) ? obj2 : null); if (val == null) { return null; } ((Object)val).name = name; Type type2 = QuietType("Collider", "UnityEngine"); Component val2 = ((type2 == null) ? null : val.GetComponent(type2)); if (val2 != null) { DestroyNow(val2); } return val; } private static void DestroyNow(object obj) { MethodInfo methodInfo = null; MethodInfo[] methods = typeof(Object).GetMethods(BindingFlags.Static | BindingFlags.Public); foreach (MethodInfo methodInfo2 in methods) { if (!(methodInfo2.Name != "DestroyImmediate")) { ParameterInfo[] parameters = methodInfo2.GetParameters(); if (parameters.Length >= 1 && typeof(Object).IsAssignableFrom(parameters[0].ParameterType)) { methodInfo = methodInfo2; break; } } } if (!(methodInfo == null)) { if (methodInfo.GetParameters().Length == 1) { methodInfo.Invoke(null, new object[1] { obj }); } else { methodInfo.Invoke(null, new object[2] { obj, false }); } } } private static Material CopyMaterial(Material donor) { ConstructorInfo constructor = typeof(Material).GetConstructor(new Type[1] { typeof(Material) }); if (constructor != null && donor != null) { object obj = constructor.Invoke(new object[1] { donor }); return (Material)((obj is Material) ? obj : null); } constructor = typeof(Material).GetConstructor(new Type[1] { QuietType("Shader", "UnityEngine") ?? typeof(object) }); return null; } private static void SetFloat(Material mat, string name, float value) { if (mat != null && mat.HasProperty(name)) { MethodInfo method = typeof(Material).GetMethod("SetFloat", new Type[2] { typeof(string), typeof(float) }); if (method != null) { method.Invoke(mat, new object[2] { name, value }); } } } private static void SetVec(object transform, string prop, float x, float y, float z) { PropertyInfo property = transform.GetType().GetProperty(prop); if (!(property == null) && property.CanWrite) { object obj = Activator.CreateInstance(property.PropertyType); Type propertyType = property.PropertyType; propertyType.GetField("x").SetValue(obj, x); propertyType.GetField("y").SetValue(obj, y); propertyType.GetField("z").SetValue(obj, z); property.SetValue(transform, obj, null); } } private static void SetRotX(object transform, float degrees) { PropertyInfo property = transform.GetType().GetProperty("localRotation"); if (!(property == null) && property.CanWrite) { object obj = Activator.CreateInstance(property.PropertyType); Type propertyType = property.PropertyType; float num = degrees * 0.5f * (float)Math.PI / 180f; propertyType.GetField("x").SetValue(obj, (float)Math.Sin(num)); propertyType.GetField("y").SetValue(obj, 0f); propertyType.GetField("z").SetValue(obj, 0f); propertyType.GetField("w").SetValue(obj, (float)Math.Cos(num)); property.SetValue(transform, obj, null); } } private static void StripMagic(GameObject go) { string[] array = new string[4] { "ParticleSystem", "Light", "TrailRenderer", "AudioSource" }; foreach (string name in array) { Type type = QuietType(name, "UnityEngine"); if (type == null) { continue; } Component[] array2 = Kids(go, type); foreach (Component val in array2) { if (val != null && val.gameObject != null && val.gameObject != go) { val.gameObject.SetActive(false); } } } } private static void ShowMesh(GameObject go) { Renderer[] componentsInChildren = go.GetComponentsInChildren<Renderer>(true); if (componentsInChildren == null) { return; } Renderer[] array = componentsInChildren; foreach (Renderer val in array) { if (val == null) { continue; } string name = ((object)val).GetType().Name; if (name == "ParticleSystemRenderer" || name == "TrailRenderer") { ((Component)val).gameObject.SetActive(false); continue; } WakeChain(go, ((Component)val).gameObject); PropertyInfo property = ((object)val).GetType().GetProperty("enabled"); if (property != null && property.CanWrite) { property.SetValue(val, true, null); } if (name == "SkinnedMeshRenderer") { PropertyInfo property2 = ((object)val).GetType().GetProperty("updateWhenOffscreen"); if (property2 != null && property2.CanWrite) { property2.SetValue(val, false, null); } } } } private static void WakeChain(GameObject root, GameObject node) { while (node != null) { node.SetActive(true); if (node == root) { break; } PropertyInfo property = ((object)node.transform).GetType().GetProperty("parent"); Transform val = (Transform)((property == null) ? null : /*isinst with value type is only supported in some contexts*/); node = ((val == null) ? null : ((Component)val).gameObject); } } private static Component[] Kids(GameObject go, Type type) { if (go == null || type == null) { return (Component[])(object)new Component[0]; } MethodInfo methodInfo = null; MethodInfo[] methods = typeof(GameObject).GetMethods(); foreach (MethodInfo methodInfo2 in methods) { if (!(methodInfo2.Name != "GetComponentsInChildren") && !methodInfo2.IsGenericMethod) { ParameterInfo[] parameters = methodInfo2.GetParameters(); if (parameters.Length == 2 && parameters[0].ParameterType == typeof(Type) && parameters[1].ParameterType == typeof(bool)) { methodInfo = methodInfo2; break; } } } IEnumerable enumerable = ((methodInfo == null) ? null : (methodInfo.Invoke(go, new object[2] { type, true }) as IEnumerable)); if (enumerable == null) { return (Component[])(object)new Component[0]; } List<Component> list = new List<Component>(); foreach (object item in enumerable) { Component val = (Component)((item is Component) ? item : null); if (val != null) { list.Add(val); } } return list.ToArray(); } private static object Db() { Type type = AccessTools.TypeByName("ObjectDB"); return AccessTools.Property(type, "instance").GetValue(null, null); } private static object ZNet() { Type type = AccessTools.TypeByName("ZNetScene"); PropertyInfo propertyInfo = ((type == null) ? null : AccessTools.Property(type, "instance")); return (propertyInfo == null) ? null : propertyInfo.GetValue(null, null); } private static GameObject FindPrefab(string name) { if (string.IsNullOrEmpty(name)) { return null; } Type type = AccessTools.TypeByName("ObjectDB"); object obj = ((type == null) ? null : AccessTools.Property(type, "instance")?.GetValue(null, null)); if (obj != null) { MethodInfo methodInfo = AccessTools.Method(type, "GetItemPrefab", new Type[1] { typeof(string) }, (Type[])null); if (methodInfo != null) { object? obj2 = methodInfo.Invoke(obj, new object[1] { name }); GameObject val = (GameObject)((obj2 is GameObject) ? obj2 : null); if (val != null) { return val; } } IList list = Get(obj, "m_items") as IList; GameObject val2 = FindInList(list, name); if (val2 != null) { return val2; } } object obj3 = ZNet(); if (obj3 != null) { if (Get(obj3, "m_namedPrefabs") is IDictionary dictionary) { object obj4 = RealHash(name); if (obj4 != null && dictionary.Contains(obj4)) { object? obj5 = dictionary[obj4]; return (GameObject)((obj5 is GameObject) ? obj5 : null); } foreach (object value in dictionary.Values) { GameObject val3 = (GameObject)((value is GameObject) ? value : null); if (val3 != null && string.Equals(((Object)val3).name, name, StringComparison.OrdinalIgnoreCase)) { return val3; } } } GameObject val4 = FindInList(Get(obj3, "m_prefabs") as IList, name); if (val4 != null) { return val4; } } return null; } private static bool ListHas(IList list, string name) { if (list == null || string.IsNullOrEmpty(name)) { return false; } foreach (object item in list) { Object val = (Object)((item is Object) ? item : null); if (!Alive(val) || !(val.name == name)) { continue; } return true; } return false; } private static GameObject FindInList(IList list, string name) { if (list == null) { return null; } foreach (object item in list) { GameObject val = (GameObject)((item is GameObject) ? item : null); if (val != null && string.Equals(((Object)val).name, name, StringComparison.OrdinalIgnoreCase)) { return val; } } return null; } private static bool ContainsGo(IList list, GameObject go) { foreach (object item in list) { if (item == go) { return true; } } return false; } private static void RemoveNamed(IList list, string name) { if (list == null) { return; } for (int num = list.Count - 1; num >= 0; num--) { object? obj = list[num]; Object val = (Object)((obj is Object) ? obj : null); if (val != null && val.name == name) { list.RemoveAt(num); } } } private static object Get(object target, string field) { if (target == null) { return null; } FieldInfo field2 = target.GetType().GetField(field, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); return (field2 == null) ? null : field2.GetValue(target); } private static void Set(object target, string field, object value) { if (target != null) { FieldInfo field2 = target.GetType().GetField(field, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(field2 == null)) { field2.SetValue(target, value); } } } private static float MathfClamp(float v, float a, float b) { if (v < a) { return a; } if (v > b) { return b; } return v; } } }