Decompiled source of Crawl Further v1.2.1
plugins/CrawlFurther/CrawlFurther.dll
Decompiled 2 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using CrawlFurther.Art; using CrawlFurther.Compat; using CrawlFurther.Content.Bosses; using CrawlFurther.Content.Ghosts; using CrawlFurther.Content.Gods; using CrawlFurther.Content.Gods.BelMora; using CrawlFurther.Content.Gods.Jinx; using CrawlFurther.Content.Gods.Kaurn; using CrawlFurther.Content.Gods.Ossivar; using CrawlFurther.Content.Gods.Sylvene; using CrawlFurther.Content.Gods.Umbrael; using CrawlFurther.Content.Gods.Vhorrul; using CrawlFurther.Content.Gods.Ysveld; using CrawlFurther.Content.Gods.Zhekra; using CrawlFurther.Content.Heroes; using CrawlFurther.Content.Items; using CrawlFurther.Content.Library; using CrawlFurther.Content.Objects; using CrawlFurther.Content.Secrets; using CrawlFurther.Content.Testing; using CrawlFurther.Content.Tips; using CrawlFurther.Content.Weapons; using CrawlFurther.Diagnostics; using CrawlFurther.Game; using CrawlFurther.Ghosts; using CrawlFurther.Gods; using CrawlFurther.Heroes; using CrawlFurther.Items; using CrawlFurther.Monsters; using CrawlFurther.Objects; using CrawlFurther.Testing; using CrawlFurther.UI; using CrawlFurther.Util; using HarmonyLib; using InControl; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyVersion("0.0.0.0")] namespace CrawlFurther.Content { public static class ContentChecks { public static readonly string[] GodNames = new string[9] { "Vhorrul", "Ossivar", "Sylvene", "Umbrael", "Bel'Mora", "Jinx", "Zhekra", "Kaurn", "Ysveld" }; private static void Bad(string msg) { SelfTest.Bad(msg); } private static void Note(string msg) { SelfTest.Note(msg); } public static void AddSections() { SelfTest.AddSection(300, "evolution trees", (Action)CheckTrees); SelfTest.AddSection(400, "gods", (Action)CheckGods); SelfTest.AddSection(500, "shop items", (Action)CheckItems); SelfTest.AddSection(600, "weapons", (Action)CheckWeapons); SelfTest.AddSection(700, "ghost forms, bosses, origins", (Action)CheckOthers); SelfTest.AddSection(800, "slots, unlocks, custom gods", (Action)delegate { FrameworkChecks.SelfCheck(Bad); SlotChallenges.SelfCheck(Bad); }); SelfTest.AddSection(900, "custom heroes", (Action)delegate { HeroCustom.SelfCheck(Bad); }); SelfTest.AddSection(1000, "custom ghosts", (Action)delegate { GhostCustom.SelfCheck(Bad); }); SelfTest.AddSection(1100, "ghost forms", (Action)delegate { GhostV11.SelfCheck(Bad); }); SelfTest.AddSection(1500, "silver uniques", (Action)delegate { SilverPack.SelfCheck(Bad); MonsterSecrets.SelfCheck(Bad); }); SelfTest.AddSection(1600, "secret statues", (Action)delegate { StatuePack.SelfCheck(Bad); }); SelfTest.AddSection(1650, "monster challenges", (Action)delegate { MonsterChallenges.SelfCheck(Bad, Note); }); SelfTest.AddSection(1700, "items wave 3", (Action)delegate { ItemPack3.SelfCheck(Bad); }); SelfTest.AddSection(1800, "room objects A (and ObjectKit)", (Action)delegate { ObjectPack.SelfCheck(Bad); }); SelfTest.AddSection(1900, "room objects B (fun and secret)", (Action)delegate { ObjectPack2.SelfCheck(Bad); }); SelfTest.AddSection(2200, "ghost slots (Ascension, Thralls)", (Action)delegate { GhostSlots.SelfCheck(Bad); }); SelfTest.AddSection(2300, "silver variants", (Action)delegate { SilverVariants.SelfCheck(Bad); }); } private static SpawnGroup StatueGroup() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) SpawnGroup[] array = Resources.FindObjectsOfTypeAll<SpawnGroup>(); foreach (SpawnGroup val in array) { if (((Object)((Component)val).gameObject).name == "EnemyGroupStatue") { Scene scene = ((Component)val).gameObject.scene; if (!((Scene)(ref scene)).IsValid()) { return val; } } } return null; } private static string Name(Player p) { if (!((Object)(object)p == (Object)null)) { return ((Object)((Component)p).gameObject).name; } return "null"; } public static void CheckTrees() { HashSet<Player> hashSet = new HashSet<Player>(MonsterFactory.Built.Values); HashSet<Player> hashSet2 = new HashSet<Player>(); SpawnGroup val = StatueGroup(); List<SpawnItem> list = (((Object)(object)val != (Object)null) ? R.Get<List<SpawnItem>>((object)val, "m_items") : null); if (list == null) { Bad("statue group EnemyGroupStatue not found"); } foreach (string builtName in DeityFactory.BuiltNames) { if (Array.IndexOf(GodNames, builtName) < 0) { continue; } Deity deity = SystemDeity.GetDeity(builtName); if (deity == null) { Bad("god " + builtName + " was built but is not in the god list"); continue; } List<List<Player>> list2 = new List<List<Player>> { new List<Player>() }; GameObject[] array = (GameObject[])(((object)deity.GetStartingMonsters()) ?? ((object)new GameObject[0])); foreach (GameObject val2 in array) { Player val3 = (((Object)(object)val2 != (Object)null) ? val2.GetComponent<Player>() : null); if ((Object)(object)val3 == (Object)null) { Bad(builtName + ": a starting monster is missing"); } else { list2[0].Add(val3); } } Dictionary<string, Player> dictionary = new Dictionary<string, Player>(); Dictionary<Player, Player> dictionary2 = new Dictionary<Player, Player>(); for (int j = 0; j < 2; j++) { List<Player> list3 = new List<Player>(); foreach (Player item in list2[j]) { Player[] array2 = (Player[])(((object)item.GetEvolveTo()) ?? ((object)new Player[0])); List<Player> list4 = new List<Player>(); Player[] array3 = array2; foreach (Player val4 in array3) { if ((Object)(object)val4 != (Object)null && !list4.Contains(val4)) { list4.Add(val4); } } if (array2.Length != 2 || list4.Count != 2) { Bad(builtName + ": " + Name(item) + " (T" + (j + 1) + ") offers " + array2.Length + " evolutions (" + list4.Count + " distinct), must be exactly 2"); } foreach (Player item2 in list4) { if (!hashSet.Contains(item2)) { Bad(builtName + ": " + Name(item) + " evolves into " + Name(item2) + ", which is not a mod monster"); } if (dictionary2.TryGetValue(item2, out var value)) { Bad(builtName + ": " + Name(item2) + " is offered by both " + Name(value) + " and " + Name(item) + " (evolutions must not be shared)"); } else { dictionary2[item2] = item; } if (!list3.Contains(item2)) { list3.Add(item2); } } if (list4.Count == 2) { string text = Name(list4[0]); string text2 = Name(list4[1]); string text3 = ((string.CompareOrdinal(text, text2) < 0) ? (text + "|" + text2) : (text2 + "|" + text)); if (dictionary.TryGetValue(text3, out var value2)) { Bad(builtName + ": " + Name(item) + " and " + Name(value2) + " offer the same pair (" + text3 + ")"); } else { dictionary[text3] = item; } } } list2.Add(list3); } int[] array4 = new int[3] { 3, 6, 12 }; float[] array5 = new float[3] { 0f, 2.5f, 4.5f }; for (int k = 0; k < 3; k++) { if (list2[k].Count != array4[k]) { Bad(builtName + ": T" + (k + 1) + " has " + list2[k].Count + " monsters, the tree rule wants " + array4[k]); } foreach (Player item3 in list2[k]) { hashSet2.Add(item3); for (int l = 0; l < 3; l++) { if (l != k && list2[l].Contains(item3)) { Bad(builtName + ": " + Name(item3) + " sits in two tiers"); } } float num = R.Get<float>((object)item3, "m_evolveCost"); if (k > 0 && Mathf.Abs(num - array5[k]) > 0.01f) { Bad(builtName + ": " + Name(item3) + " (T" + (k + 1) + ") costs " + num + ", expected " + array5[k]); } } } foreach (Player p in list2[2]) { Player[] evolveTo = p.GetEvolveTo(); if (evolveTo != null && evolveTo.Length != 0) { Bad(builtName + ": final " + Name(p) + " still evolves (" + evolveTo.Length + ")"); } exSpriteAnimClip animationStatue = p.GetAnimationStatue(); if ((Object)(object)animationStatue == (Object)null || !((Object)animationStatue).name.StartsWith("ModStatue_")) { Bad(builtName + ": final " + Name(p) + " has no carved statue (" + (((Object)(object)animationStatue == (Object)null) ? "none" : ((Object)animationStatue).name) + ")"); } if (list != null && !list.Exists((SpawnItem val6) => val6 != null && (Object)(object)val6.m_object == (Object)(object)((Component)p).gameObject)) { Bad(builtName + ": final " + Name(p) + " is not in the statue group"); } } Note(builtName + ": T1 " + Names(list2[0]) + " | T2 " + Names(list2[1]) + " | T3 " + Names(list2[2])); } GoldSecretPack.CheckTree(Bad, Note, hashSet2, list); foreach (KeyValuePair<string, int> item4 in MonsterFactory.Tier) { if (item4.Value < 2) { continue; } Player val5 = null; foreach (Player item5 in hashSet) { if ((Object)(object)item5 != (Object)null && ((Object)((Component)item5).gameObject).name == item4.Key) { val5 = item5; break; } } if (!SilverUniques.Ids.Contains(item4.Key) && !SecretStatues.Is(item4.Key) && (Object)(object)val5 != (Object)null && !hashSet2.Contains(val5)) { Bad(item4.Key + " is an evolved tier but no god's tree reaches it"); } } } private static string Names(List<Player> l) { List<string> list = new List<string>(); foreach (Player item in l) { list.Add(Name(item)); } return string.Join(", ", list.ToArray()); } public static void CheckGods() { List<Deity> deities = SystemDeity.GetDeities(); string[] godNames = GodNames; foreach (string text in godNames) { bool flag = false; if (deities != null) { foreach (Deity item in deities) { if (item != null && item.GetName() == text) { flag = true; } } } if (!flag) { Bad("god " + text + " is not in the god list"); } else { Note("god " + text + " ok"); } } int num = 0; foreach (string builtName in DeityFactory.BuiltNames) { if (Array.IndexOf(GodNames, builtName) >= 0) { num++; } } if (num != GodNames.Length) { Bad(num + " Crawl: Further gods registered, expected " + GodNames.Length); } int num2 = 0; if (deities != null) { foreach (string builtName2 in DeityFactory.BuiltNames) { int num3 = 0; foreach (Deity item2 in deities) { if (item2 != null && item2.GetName() == builtName2) { num3++; } } if (num3 > 1) { num2++; } } } if (num2 > 0) { Bad(num2 + " mod god(s) appear more than once in the god list"); } } private static void CheckBubble(string who, exSpriteAnimClip bubble) { if ((Object)(object)bubble == (Object)null || bubble.frameInfos == null || bubble.frameInfos.Count == 0) { Bad(who + " has no shop bubble clip"); } else if (SpriteSheets.ByAtlas(bubble.frameInfos[0].atlas) == null) { Bad(who + " shop bubble is vanilla art (" + ((Object)bubble).name + ")"); } } private static void CheckPedestal(string who, string key, SpriteSheet pedestals) { if (pedestals != null && (key == null || !pedestals.Has(key))) { Bad(who + " has no shop pedestal frame '" + key + "' in ShopPedestals"); } } public static void CheckItems() { SpriteSheet val = SpriteSheets.Get("ShopPedestals"); if (val == null) { Bad("art/ShopPedestals missing: every mod item shows a stand-in on its pedestal"); } HashSet<string> hashSet = new HashSet<string>(); foreach (ItemDef item in ItemPack.Items) { if (!hashSet.Add(item.id)) { Bad("item " + item.id + " is queued twice"); continue; } if (!ItemPack.Built.TryGetValue(item.id, out var value) || (Object)(object)value == (Object)null) { Bad("item " + item.id + " failed to build"); continue; } Note("item " + value.m_displayName + " cost " + value.m_cost); CheckBubble("item " + item.id, R.Get<exSpriteAnimClip>((object)value, "m_animPurchasableBubble")); CheckPedestal("item " + item.id, ShopPedestal.KeyFor((IPurchasable)(object)value), val); } } public static void CheckWeapons() { SpriteSheet pedestals = SpriteSheets.Get("ShopPedestals"); foreach (WeaponDef def in WeaponPack.Defs) { if (!WeaponPack.Built.TryGetValue(def.id, out var value) || (Object)(object)value == (Object)null) { Bad("weapon " + def.id + " failed to build"); continue; } Note("weapon " + value.m_weaponName + " cost " + value.m_cost); CheckBubble("weapon " + def.id, value.m_animationPurchasableBubble); CheckPedestal("weapon " + def.id, "Wpn" + def.id, pedestals); } if (WeaponPack.Built.Count < WeaponPack.Defs.Count) { Note(WeaponPack.Defs.Count - WeaponPack.Built.Count + " weapon(s) missing"); } } public static void CheckOthers() { foreach (GhostFormEntry form in GhostPack.Forms) { SpriteSheet val = SpriteSheets.Get(((GhostFormDef)form).portraitArt); if (val == null || !val.Has("Idle")) { Bad("ghost form " + ((GhostFormDef)form).name + " portrait missing"); } } Player[] array = (Player[])(object)new Player[6] { GhostPack.Mote, GhostPack.Spitter, GhostPack.Gel, GhostPack.Brute, GhostPack.Titan, GhostPack.King }; for (int i = 0; i < array.Length; i++) { if ((Object)(object)array[i] == (Object)null) { Bad("a ghost-form blob monster failed to build"); } } GameObject[] array2 = (GameObject[])(object)new GameObject[4] { GhostPack.KingSlam, GhostPack.KingQuake, GhostPack.KingDrop, GhostPack.KingDropPool }; for (int i = 0; i < array2.Length; i++) { if ((Object)(object)array2[i] == (Object)null) { Bad("a King Blob effect failed to build"); } } GhostBlobs.SelfCheck((Action<string>)Bad); BlobChallenges.SelfCheck(Bad); Note("bosses built: " + BossFactory.Built.Count + (BossPack.Enabled ? "" : " (switched off: Bosses.Enabled = false)")); foreach (Boss item in BossFactory.Built) { Note(" " + item.GetDisplayName()); } if (BossPack.Enabled && BossFactory.Built.Count < 2) { Bad("only " + BossFactory.Built.Count + " of 2 mod bosses built"); } if (!BossPack.Enabled && BossFactory.Built.Count > 0) { Bad("bosses are switched off but " + BossFactory.Built.Count + " were built"); } foreach (OriginDef item2 in HeroClasses.All) { SpriteSheet val2 = SpriteSheets.Get(item2.portraitArt); if (val2 == null || !val2.Has("Idle")) { Bad("origin " + item2.id + " portrait missing"); } } } } public static class ContentSetup { public const string PedestalSheet = "ShopPedestals"; public const string BossTopic = "bosses"; public static void Install() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0010: 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_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown Branding.Set(new BrandingDef { name = "Crawl: Further", version = "1.2.1", wordmark = "BrandFurther", spark = "BrandSpark", menuPip = "BrandPip", menuMote = "BrandMote" }); ModMusic.AddFolder(Path.Combine(Plugin.ModDir, "music")); TierRules.StarterDamage = 1.3f; TierRules.StarterMinHealth = 4f; ContinueGame.Enabled = ((BaseUnityPlugin)Plugin.I).Config.Bind<bool>("Game", "ContinueAfterWin", true, "When the hero beats the boss, offer to keep playing with two more tries at the boss.").Value; ShopPedestal.AddSheet("ShopPedestals"); string[] array = new string[6] { "HeroWanderer", "HeroWanderer_P1", "HeroWanderer_P2", "HeroWanderer_P3", "HeroWanderer_P4", "GhostWisp" }; for (int i = 0; i < array.Length; i++) { ModGem.Exclude(array[i]); } foreach (GhostFormEntry form in GhostPack.Forms) { GhostForms.Register((GhostFormDef)(object)form); } GhostForms.FormOf = GhostPack.DefOf; OriginList.Register(); OriginColours.Register(); Statues.Sheets.Add("ModStatues"); AddTips(); FurtherVault.Register(); SlotChallenges.Register(); BlobChallenges.Register(); MonsterEvents.PlayerAwake += HeroItemHooks.PlayerAwake; ItemRegistry.AddDamageHook((Func<Health, DamageInfo, GameObject, bool>)HeroItemHooks.Damage); MonsterEvents.AttackSpawned += HeroItemHooks.EffectSpawned; ImpactThemes.Register(); Unlocks.EctoRefunding = () => GhostV11.Refunding; HeroClasses.CustomHeroes = (ICustomHeroes)(object)new CustomHeroSlots(); SlotGods.AddEntries = GodSlots.AddItems; SlotGods.HideExtras = GodSlots.HideExtras; SlotGods.Redraw = GodSlots.Invalidate; SlotGods.TierOf = (Deity d) => (SlotTier)(((??)CustomGod.Of(d)?.tier) ?? 0); SlotGods.PageGodsOf = IdolGodNames; SlotGods.PerkGodOf = (Deity d) => CustomGod.Of(d)?.PerkGod; Statues.Exclude = (string id) => SilverUniques.Ids.Contains(id) || GoldSecret.TreeIds.Contains(id) || SecretStatues.Is(id); Further.AddPack("Vhorrul", (Action)VhorrulPack.Register); Further.AddPack("Ossivar", (Action)OssivarPack.Register); Further.AddPack("Sylvene", (Action)SylvenePack.Register); Further.AddPack("Umbrael", (Action)UmbraelPack.Register); Further.AddPack("Bel'Mora", (Action)BelMoraPack.Register); Further.AddPack("Jinx", (Action)JinxPack.Register); Further.AddPack("Zhekra", (Action)ZhekraPack.Register); Further.AddPack("Kaurn", (Action)KaurnPack.Register); Further.AddPack("Ysveld", (Action)YsveldPack.Register); Further.AddPack("Silver", (Action)SilverPack.Register); Further.AddPack("Gold Secret", (Action)GoldSecretPack.Register); Further.AddPack("Secret Statues", (Action)StatuePack.Register); Further.AddPack("Ghosts", (Action)GhostPack.Register); Further.AddPack("Bosses", (Action)BossPack.Register); Further.AddPack("Items", (Action)ItemPack.Register); Further.AddPack("Items2", (Action)ItemPack2.Register); Further.AddPack("Items3", (Action)ItemPack3.Register); Further.AddPack("Weapons", (Action)WeaponPack.Register); Further.AddPack("Objects", (Action)ObjectPack.Register); Further.AddPack("Objects B", (Action)ObjectPack2.Register); Further.AddPack("Monster secrets", (Action)MonsterSecrets.Register); ContentChecks.AddSections(); } private static void AddTips() { //IL_0048: Unknown result type (might be due to invalid IL or missing references) bool enabled = BossPack.Enabled; foreach (KeyValuePair<string, MonsterTip> tip in MonsterTipsData.Tips) { MonsterTipsData.Group.TryGetValue(tip.Key, out var value); if (enabled || !(value == "bosses")) { TipRegistry.Add(tip.Key, tip.Value, value); } } foreach (KeyValuePair<string, string> item in MonsterTipsData.Alias) { TipRegistry.AddAlias(item.Key, item.Value); } foreach (string item2 in MonsterTipsData.VaultOrder) { if (enabled || !MonsterTipsData.Group.TryGetValue(item2, out var value2) || !(value2 == "bosses")) { TipRegistry.AddVaultLine(item2, MonsterTipsData.Vault[item2].Key, MonsterTipsData.Vault[item2].Value); } } PauseTopic[] topics = PauseTipsData.Topics; foreach (PauseTopic val in topics) { if (enabled || val.id != "bosses") { TipRegistry.AddTopic(val); } } TipRegistry.TopicOrder.AddRange(new string[5] { "status", "icons", "ghosts", "slots", "unlocks" }); if (enabled) { TipRegistry.TopicOrder.Add("bosses"); } TipRegistry.GhostFormTopic = "ghosts"; MonsterTips.GhostKey = delegate(Player body) { GhostFormEntry ghostFormEntry = GhostPack.DefOf(body.GetPlayerData()); return (ghostFormEntry == null || GhostForms.IsDefault((GhostFormDef)(object)ghostFormEntry)) ? null : ("ModGhost" + ((GhostFormDef)ghostFormEntry).id); }; } private static List<string> IdolGodNames(Deity d) { CustomGod.Record record = CustomGod.Of(d); if (record == null) { return null; } List<string> list = new List<string> { record.perk }; foreach (string starter in record.starters) { foreach (CustomGod.Starter item in CustomGod.Starters()) { if (((Object)((Component)item.p).gameObject).name == starter) { list.Add(item.god.GetName()); } } } return list; } } [BepInPlugin("com.firefightermate.crawlfurther", "Crawl: Further", "1.2.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public const string GUID = "com.firefightermate.crawlfurther"; public const string NAME = "Crawl: Further"; public const string VERSION = "1.2.1"; public static Plugin I; internal static ManualLogSource Log; internal static string ModDir; private float m_bannerTimer = 12f; private static bool s_started; private static FurtherMod s_mod; private static readonly string[] PatchOrder = new string[34] { "Patch_Items3PlayerAwake", "Patch_Items3HeroChange", "Patch_Items3Kill", "Patch_Items3Damage", "Patch_SilverAwake", "Patch_HeroKill", "Patch_UmbraelHits", "Patch_JinxHeroHits", "Patch_VhorrulHits", "Patch_GhostSlotsNewRun", "Patch_GhostSlotDamage", "Patch_HexBoltHits", "Patch_SylveneHeroHits", "Patch_GoldDamage", "Patch_GoldSecretAwake", "Patch_StatueDamageOut", "Patch_StatueDamageIn", "Patch_StatueAwake", "Patch_WeaponRuntimeAwake", "Patch_WeaponHeroHit", "Patch_WeaponHandsMaterial", "Patch_ItemDamageTag", "Patch_OssHits", "Patch_ZhkHeroHits", "Patch_ZhkHeroStruck", "Patch_ZhekraMantisExecute", "Patch_ZhekraAwake", "Patch_GleanerValue", "Patch_GleanerGathered", "Patch_KaurnAwake", "Patch_BelMoraHits", "Patch_SilverVariantFrames", "Patch_CustomGodInUse", "Patch_CustomPerkEcho" }; private static int s_bossPick; private static string s_note; private static float s_noteTime; private GUIStyle m_lineStyle; private readonly GUIContent m_line = new GUIContent(); private void Awake() { I = this; Log = ((BaseUnityPlugin)this).Logger; ((MonoBehaviour)this).useGUILayout = false; ModDir = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location); s_mod = Further.AddMod((BaseUnityPlugin)(object)this, (Action)OnGameReady); Log.LogInfo((object)("Crawl: Further awake. Unity " + Application.unityVersion + ", dir " + ModDir)); } private void Update() { if (m_bannerTimer > 0f) { m_bannerTimer -= Time.unscaledDeltaTime; } if (s_started) { GameTick(); } } [MethodImpl(MethodImplOptions.NoInlining)] private static void OnGameReady() { s_mod.PatchAll(PatchOrder); SheetScales.Register(); ContentSetup.Install(); if (TestMode.On) { ContentTestActions.Register(); } s_started = true; } [MethodImpl(MethodImplOptions.NoInlining)] private void GameTick() { if (Input.GetKeyDown((KeyCode)291)) { CycleBoss(); } } [MethodImpl(MethodImplOptions.NoInlining)] private static void CycleBoss() { List<Boss> built = BossFactory.Built; if (built.Count != 0) { s_bossPick = (s_bossPick + 1) % (built.Count + 1); BossFactory.Forced = ((s_bossPick == 0) ? null : built[s_bossPick - 1]); s_note = "Next boss: " + (((Object)(object)BossFactory.Forced == (Object)null) ? "random" : BossFactory.Forced.GetDisplayName()); s_noteTime = 4f; Log.LogInfo((object)s_note); } } private void OnGUI() { //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_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) bool flag = s_noteTime > 0f; bool flag2 = m_bannerTimer > 0f; if (flag || flag2) { if (m_lineStyle == null) { m_lineStyle = new GUIStyle(GUI.skin.label) { wordWrap = true, clipping = (TextClipping)0 }; } float y = 6f; float w = Mathf.Min(900f, (float)Screen.width - 16f); if (flag2) { GUI.color = new Color(1f, 0.85f, 0.4f, Mathf.Clamp01(m_bannerTimer)); y = Line("Crawl: Further 1.2.1 loaded: " + (s_started ? StatusText() : "starting") + ((s_started && AnyModBoss()) ? " (F10: force a mod boss)" : ""), y, w); } if (flag) { s_noteTime -= Time.unscaledDeltaTime; GUI.color = new Color(0.8f, 0.9f, 1f, Mathf.Clamp01(s_noteTime)); y = Line("(Crawl: Further) " + s_note, y, w); } string text = ((flag2 && s_started) ? TestBanner() : null); if (text != null) { GUI.color = new Color(1f, 0.85f, 0.4f, Mathf.Clamp01(m_bannerTimer)); Line(text, y, w); } } } private float Line(string text, float y, float w) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) m_line.text = text; float num = Mathf.Max(22f, m_lineStyle.CalcHeight(m_line, w)); GUI.Label(new Rect(8f, y, w, num), m_line, m_lineStyle); return y + num; } [MethodImpl(MethodImplOptions.NoInlining)] private static bool AnyModBoss() { return BossFactory.Built.Count > 0; } [MethodImpl(MethodImplOptions.NoInlining)] private static string TestBanner() { return TestMode.Banner; } [MethodImpl(MethodImplOptions.NoInlining)] private static string StatusText() { return Further.Status; } } internal static class SheetScales { public static void Register() { Dictionary<string, float> bySheet = ArtScale.BySheet; bySheet["BlobMote"] = 0.92f; bySheet["BlobSpitter"] = 0.8f; bySheet["BlobGel"] = 0.8f; bySheet["BlobBrute"] = 0.57f; bySheet["BlobTitan"] = 0.58f; bySheet["BlobKing"] = 0.5f; } } } namespace CrawlFurther.Content.Weapons { public static class WeaponFx { public static GameObject HookJab; public static GameObject Hook; public static GameObject ChainLink; public static GameObject GlaiveSlash; public static GameObject Glaive; public static GameObject RiftSlashA; public static GameObject RiftSlashB; public static GameObject RiftMark; public static GameObject RiftSnap; public static GameObject DiceSwing; public static GameObject Jackpot; public static readonly GameObject[] Dice = (GameObject[])(object)new GameObject[6]; public static GameObject TideCleave; public static GameObject TideCrash; public static GameObject Wave; public static GameObject Splash; public static GameObject LeechStab; public static GameObject LeechSlash; public static GameObject Bead; public static GameObject LeechHeal; public static GameObject BriarArrow; public static GameObject ThornPatch; public static GameObject BellHit; public static GameObject BellRing; public static GameObject BellToll; public static GameObject LanternSwing; public static GameObject SoulBolt; public static GameObject SoulFire; public static GameObject Wisp; public static GameObject ArcBolt; public static GameObject Arc; public static GameObject Spark; public static GameObject FrostSlash; public static GameObject FrostChill; public static GameObject FrostChill2; public static GameObject FrostShatter; public static GameObject MercySlash; public static GameObject MercyX; public static GameObject ReapA; public static GameObject ReapB; public static GameObject ReapSoul; public static GameObject StarSlam; public static GameObject StarWell; public static GameObject HydraArrow; public static GameObject HydraShard; public static GameObject HydraSplit; public static GameObject GuardBash; public static GameObject GuardRing; public static GameObject GuardBlock; public static GameObject HeartBolt; public static GameObject HeartPierce; public static GameObject KrisStab; public static GameObject KrisBack; public static GameObject BlightSwing; public static GameObject BlightBolt; public static GameObject BlightCloud; public static GameObject BlightSpore; public static GameObject OrrerySwing; public static GameObject OrreryBolt; public static GameObject OrreryStar; public static GameObject GrudgeStone; public static GameObject GrudgeBrand; public static GameObject MidasCoin; public static GameObject MidasGold; public static GameObject LanceThrust; public static GameObject LanceCharge; public static GameObject LashBody; public static GameObject LashTip; public static GameObject Kunai; public static GameObject KunaiSlash; public static GameObject KunaiMark; public static GameObject KunaiPop; public const int LayerWall = 9; public const int LayerMonster = 14; public static readonly Dictionary<string, GameObject> ImpactHit = new Dictionary<string, GameObject>(); public static readonly Dictionary<string, GameObject> ImpactWall = new Dictionary<string, GameObject>(); public static readonly GameObject[] ReapStacks = (GameObject[])(object)new GameObject[5]; public static readonly exSpriteAnimClip[] MidasTiers = (exSpriteAnimClip[])(object)new exSpriteAnimClip[3]; public static GameObject LanceReady; private static readonly string[] ImpactIds = new string[12] { "Gravehook", "Moonglaive", "Tidebreaker", "Wickstaff", "Arcbolt", "HydraBow", "Heartseeker", "Blightstaff", "Orrery", "Grudgestone", "Midas", "Kunai" }; internal static void OnSpawn<T>(GameObject tmpl, Action<T> init) where T : Component { if ((Object)(object)tmpl == (Object)null) { return; } FxFactory.OnSpawn.TryGetValue(tmpl, out var prev); FxFactory.OnSpawn[tmpl] = delegate(GameObject i) { if (prev != null) { prev(i); } T obj = i.GetComponent<T>() ?? i.AddComponent<T>(); if (init != null) { init(obj); } }; } internal static void Anchor(GameObject go, Anchor a, Vector2 offset) { //IL_001b: 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) if (!((Object)(object)go == (Object)null)) { exSprite component = go.GetComponent<exSprite>(); if ((Object)(object)component != (Object)null) { ((exPlane)component).anchor = a; ((exPlane)component).offset = offset; } } } private static void ScaleColliders(GameObject go, float k) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: 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_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: 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_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)go == (Object)null || Mathf.Abs(k - 1f) < 0.01f) { return; } CapsuleCollider[] components = go.GetComponents<CapsuleCollider>(); foreach (CapsuleCollider val in components) { val.radius *= k; if (val.direction != 2) { val.height *= k; } val.center = new Vector3(val.center.x * k, val.center.y * k, val.center.z); } BoxCollider[] components2 = go.GetComponents<BoxCollider>(); foreach (BoxCollider val2 in components2) { val2.size = new Vector3(val2.size.x * k, val2.size.y * k, val2.size.z); val2.center = new Vector3(val2.center.x * k, val2.center.y * k, val2.center.z); } } internal static void Box(GameObject go, float w, float h, float cx = 0f, float cy = 0f) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)go == (Object)null)) { BoxCollider[] components = go.GetComponents<BoxCollider>(); foreach (BoxCollider val in components) { val.size = new Vector3(w, h, val.size.z); val.center = new Vector3(cx, cy, val.center.z); } } } internal static GameObject Swipe(string name, string vanilla, string art, string anim, float damage, float knock, Vector2 hitCentre, float colliderScale = 1f, Status status = null, float statusChance = 0f) { //IL_0036: 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_006a: Unknown result type (might be due to invalid IL or missing references) SpriteSheet val = SpriteSheets.Get(art); GameObject val2 = FxFactory.Clone(vanilla, name); if ((Object)(object)val2 == (Object)null || val == null) { return val2; } FxFactory.StripChildren(val2, new string[0]); exSpriteAnimClip val3 = new ClipBuilder(val, anim, name + "Clip").Once().Ev(0, "AnimDamageOn").Ev(2, "AnimDamageOff") .Build(); FxFactory.Reskin(val2, val3, val); Anchor(val2, (Anchor)4, hitCentre * colliderScale); FxFactory.SetEffect(val2, true, 0f, 0f, 0f, (GameObject)null, (GameObject)null, (bool?)null, (float?)null, (bool?)null); FxFactory.SetDamage(val2, damage, -1f, knock, status, statusChance, -1f, (bool?)false, (bool?)null, true); ScaleColliders(val2, colliderScale); FxKit.NoTint(val2); return val2; } internal static GameObject Shot(string name, string vanilla, string art, string anim, float speed, float life, float damage, float knock, bool destroyOnHit = true, float accel = 0f, float speedMax = 0f) { bool flag = destroyOnHit; return FxKit.Projectile(name, vanilla, art, anim, speed, life, damage, knock, (Status)null, 1f, accel, speedMax, true, flag); } internal static GameObject Zone(string name, ClipBuilder cb, SpriteSheet sh, float damage, float rate, float knock, int on, int off, Status status = null, float statusChance = 0f, bool attached = false) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) GameObject val = FxFactory.Clone("DFX_Axe_InvisibleHit", name); if ((Object)(object)val == (Object)null || sh == null) { return val; } FxFactory.StripChildren(val, new string[0]); cb.Ev(on, "AnimDamageOn").Ev(off, "AnimDamageOff"); FxFactory.Reskin(val, cb.Build(), sh); Anchor(val, (Anchor)4, Vector2.zero); if (attached) { FxFactory.SetEffect(val, true, 0f, 0f, 0f, (GameObject)null, (GameObject)null, (bool?)null, (float?)null, (bool?)null); } else { bool? flag = false; bool? flag2 = false; FxFactory.SetEffect(val, true, 0f, 0f, 0f, (GameObject)null, (GameObject)null, flag, (float?)null, flag2); } FxFactory.SetDamage(val, damage, rate, knock, status, statusChance, -1f, (bool?)false, (bool?)null, true); FxKit.NoTint(val); return val; } internal static GameObject Vis(string name, string art, string anim, bool loop = false, float life = 0f, Anchor a = (Anchor)4) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) GameObject obj = FxKit.Visual(name, art, anim, loop, life, new float[0]); Anchor(obj, a, Vector2.zero); return obj; } public static void Build() { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_029c: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Unknown result type (might be due to invalid IL or missing references) //IL_0376: Unknown result type (might be due to invalid IL or missing references) //IL_042b: Unknown result type (might be due to invalid IL or missing references) //IL_049e: Unknown result type (might be due to invalid IL or missing references) //IL_04e0: Unknown result type (might be due to invalid IL or missing references) //IL_059d: Unknown result type (might be due to invalid IL or missing references) //IL_0618: Unknown result type (might be due to invalid IL or missing references) //IL_065a: Unknown result type (might be due to invalid IL or missing references) //IL_0710: Unknown result type (might be due to invalid IL or missing references) //IL_0836: Unknown result type (might be due to invalid IL or missing references) //IL_0892: Unknown result type (might be due to invalid IL or missing references) //IL_08ad: Unknown result type (might be due to invalid IL or missing references) //IL_0915: Unknown result type (might be due to invalid IL or missing references) //IL_0995: Unknown result type (might be due to invalid IL or missing references) //IL_09c0: Unknown result type (might be due to invalid IL or missing references) //IL_0b0d: Unknown result type (might be due to invalid IL or missing references) Status status = FxFactory.GetStatus("StatusDizzy"); Status status2 = FxFactory.GetStatus("StatusStuckToFloor"); Status status3 = FxFactory.GetStatus("StatusBleeding"); HookJab = Swipe("ModWpnHookJab", "SpearSwipe", "FxWpnGravehook", "Jab", 1.05f, 0.5f, new Vector2(1.7f, -2.1f)); Hook = Shot("ModWpnHook", "SpearProjectile", "FxWpnGravehook", "Hook", 340f, 0.5f, 1f, 0f, destroyOnHit: true, 0.04f, 0.1f); if ((Object)(object)Hook != (Object)null) { FxFactory.SetContacts(Hook, (bool?)true, (GameObject)null, false); } WeaponFx.OnSpawn<WpnTetherFx>(Hook, (Action<WpnTetherFx>)null); ChainLink = Vis("ModWpnChainLink", "FxWpnGravehook", "Chain", loop: false, 0f, (Anchor)4); GlaiveSlash = Swipe("ModWpnGlaiveSlash", "1HandedSwordSwipe1", "FxWpnMoonglaive", "Slash", 0.9f, 0.6f, new Vector2(8.4f, 0.4f)); Glaive = Shot("ModWpnGlaive", "SpearProjectile", "FxWpnMoonglaive", "Glaive", 0f, 2.4f, 0.85f, 0.3f, destroyOnHit: false); if ((Object)(object)Glaive != (Object)null) { FxFactory.SetMotion(Glaive, 0f, 0f, 0f, (GameObject)null, 50f, 0f, (bool?)null, -1f, false, -1f); FxFactory.SetDamage(Glaive, 0.85f, 0.35f, 0.3f, (Status)null, -1f, -1f, (bool?)true, (bool?)null, true); GameObject glaive = Glaive; bool? flag = false; bool? flag2 = false; FxFactory.SetEffect(glaive, false, 2.4f, 0f, 0f, (GameObject)null, (GameObject)null, flag, (float?)null, flag2); Box(Glaive, 14f, 14f); Anchor(Glaive, (Anchor)4, Vector2.zero); } WeaponFx.OnSpawn<WpnGlaiveFx>(Glaive, (Action<WpnGlaiveFx>)delegate(WpnGlaiveFx g) { g.Reset(); }); RiftSlashA = Swipe("ModWpnRiftSlashA", "1HandedSwordSwipe2", "FxWpnRiftblade", "SlashA", 0.9f, 0.5f, new Vector2(8.4f, -0.8f)); RiftSlashB = Swipe("ModWpnRiftSlashB", "DamageHeroSwipeSkewed", "FxWpnRiftblade", "SlashB", 0.9f, 0.5f, new Vector2(5.5f, 1.3f)); WeaponFx.OnSpawn<WpnRiftFx>(RiftSlashA, (Action<WpnRiftFx>)null); WeaponFx.OnSpawn<WpnRiftFx>(RiftSlashB, (Action<WpnRiftFx>)null); RiftMark = Vis("ModWpnRiftMark", "FxWpnRiftblade", "Mark", loop: true, 1.1f, (Anchor)4); RiftSnap = Vis("ModWpnRiftSnap", "FxWpnRiftblade", "Snap", loop: false, 0f, (Anchor)4); DiceSwing = Swipe("ModWpnDiceSwing", "1HandedSwordSwipe2", "FxWpnSnakeEyes", "Swing", 1f, 0.9f, new Vector2(8.4f, -0.8f)); WeaponFx.OnSpawn<WpnDiceFx>(DiceSwing, (Action<WpnDiceFx>)delegate(WpnDiceFx d) { d.baseDamage = 1f; }); for (int num = 0; num < 6; num++) { Dice[num] = Vis("ModWpnDie" + (num + 1), "FxWpnSnakeEyes", "Die" + (num + 1), loop: false, 0f, (Anchor)4); } SpriteSheet val = SpriteSheets.Get("FxWpnSnakeEyes"); Jackpot = Zone("ModWpnJackpot", new ClipBuilder(val, "Jackpot", "ModWpnJackpotClip").Once(), val, 0.8f, 0f, 2.2f, 0, 3); Box(Jackpot, 34f, 26f); TideCleave = Swipe("ModWpnTideCleave", "DamageHeroSwipeSkewed", "FxWpnTidebreaker", "Cleave", 1f, 0.8f, new Vector2(5.5f, 1.3f), 1.2f); TideCrash = Swipe("ModWpnTideCrash", "DamageHeroSwipeSkewed", "FxWpnTidebreaker", "Crash", 1.2f, 1f, new Vector2(5.5f, 1.3f), 1.25f); Wave = Shot("ModWpnWave", "SpearProjectile", "FxWpnTidebreaker", "Wave", 150f, 0.65f, 0.4f, 0f, destroyOnHit: false, 0.04f, 0.1f); if ((Object)(object)Wave != (Object)null) { FxFactory.SetDamage(Wave, 0.4f, 0.3f, 0f, (Status)null, -1f, -1f, (bool?)true, (bool?)null, true); Box(Wave, 14f, 26f); Anchor(Wave, (Anchor)4, Vector2.zero); } WeaponFx.OnSpawn<WpnWaveFx>(Wave, (Action<WpnWaveFx>)delegate(WpnWaveFx w) { w.Reset(); }); Splash = Vis("ModWpnSplash", "FxWpnTidebreaker", "Splash", loop: false, 0f, (Anchor)4); LeechStab = Swipe("ModWpnLeechStab", "DaggerDashthrough", "FxWpnLeechfang", "Stab", 0.75f, 0.4f, new Vector2(6.9f, -1.9f), 1f, status3, 0.15f); LeechSlash = Swipe("ModWpnLeechSlash", "1HandedSwordSwipe1", "FxWpnLeechfang", "Slash", 0.75f, 0.5f, new Vector2(8.4f, 0.4f), 1f, status3, 0.15f); WeaponFx.OnSpawn<WpnLeechFx>(LeechStab, (Action<WpnLeechFx>)null); WeaponFx.OnSpawn<WpnLeechFx>(LeechSlash, (Action<WpnLeechFx>)null); Bead = Vis("ModWpnBloodBead", "FxWpnLeechfang", "Bead", loop: true, 1.5f, (Anchor)4); WeaponFx.OnSpawn<WpnBeadFx>(Bead, (Action<WpnBeadFx>)delegate(WpnBeadFx b) { b.Reset(); }); LeechHeal = Vis("ModWpnLeechHeal", "FxWpnLeechfang", "Heal", loop: false, 0f, (Anchor)4); SpriteSheet val2 = SpriteSheets.Get("FxWpnBriarbow"); ThornPatch = Zone("ModWpnThornPatch", new ClipBuilder(val2, "Grow", "ModWpnThornPatchClip").Once().Then("Life", 5).Then("Wilt", 1), val2, 0.2f, 0.5f, 0f, 4, -4, status2, 0.5f); Box(ThornPatch, 30f, 16f); BriarArrow = Shot("ModWpnBriarArrow", "DFX_HeroArrow", "FxWpnBriarbow", "Arrow", 380f, 0.5f, 0.95f, 0.5f); if ((Object)(object)BriarArrow != (Object)null) { GameObject briarArrow = BriarArrow; GameObject thornPatch = ThornPatch; FxFactory.SetContacts(briarArrow, (bool?)null, thornPatch, false); GameObject briarArrow2 = BriarArrow; GameObject thornPatch2 = ThornPatch; bool? flag2 = true; FxFactory.SetEffect(briarArrow2, false, 0.5f, 0f, 0f, thornPatch2, (GameObject)null, (bool?)null, (float?)null, flag2); } SpriteSheet val3 = SpriteSheets.Get("FxWpnDirgeMaul"); BellHit = Zone("ModWpnBellHit", new ClipBuilder(val3, "Clang", "ModWpnBellHitClip").Once(), val3, 1f, 0f, 1f, 0, 2, null, 0f, attached: true); Box(BellHit, 29.5f, 20.9f, 13f); Anchor(BellHit, (Anchor)4, new Vector2(13f, 0f)); BellRing = Zone("ModWpnBellRing", new ClipBuilder(val3, "Ring", "ModWpnBellRingClip").Once(), val3, 0.35f, 0f, 0.7f, 0, 4, status, 1f); Box(BellRing, 52f, 32f); WeaponFx.OnSpawn<WpnBellFx>(BellRing, (Action<WpnBellFx>)null); BellToll = Zone("ModWpnBellToll", new ClipBuilder(val3, "Toll", "ModWpnBellTollClip").Once(), val3, 0.35f, 0f, 0.9f, 0, 4, status, 1f); Box(BellToll, 76f, 46f); SpriteSheet val4 = SpriteSheets.Get("FxWpnWickstaff"); LanternSwing = Swipe("ModWpnLanternSwing", "MagicStaffSwipe", "FxWpnWickstaff", "Swing", 0.2f, 0.8f, new Vector2(5.2f, -1.3f)); SoulFire = Zone("ModWpnSoulFire", new ClipBuilder(val4, "Fire", "ModWpnSoulFireClip").Once().Repeat(6), val4, 0.12f, 0.4f, 0f, 0, -1); Box(SoulFire, 22f, 12f); WeaponFx.OnSpawn<WpnSoulFireFx>(SoulFire, (Action<WpnSoulFireFx>)delegate(WpnSoulFireFx f) { f.Reset(); }); Wisp = Shot("ModWpnWisp", "DFX_HeroArrow", "FxWpnWickstaff", "Wisp", 0f, 1.6f, 0.5f, 0.3f); if ((Object)(object)Wisp != (Object)null) { FxFactory.StripChildren(Wisp, new string[0]); FxFactory.SetMotion(Wisp, 0f, 0f, 0f, (GameObject)null, 50f, 0f, (bool?)null, -1f, false, -1f); GameObject wisp = Wisp; bool? flag3 = false; bool? flag2 = true; FxFactory.SetEffect(wisp, false, 1.6f, 0f, 0f, (GameObject)null, (GameObject)null, flag3, (float?)null, flag2); Anchor(Wisp, (Anchor)4, Vector2.zero); Box(Wisp, 8f, 8f); } WeaponFx.OnSpawn<WpnSeekFx>(Wisp, (Action<WpnSeekFx>)delegate(WpnSeekFx s) { s.Reset(); }); SoulBolt = Shot("ModWpnSoulBolt", "DFX_HeroArrow", "FxWpnWickstaff", "Bolt", 170f, 0.85f, 0.6f, 0.3f); if ((Object)(object)SoulBolt != (Object)null) { GameObject soulBolt = SoulBolt; GameObject thornPatch = SoulFire; FxFactory.SetContacts(soulBolt, (bool?)null, thornPatch, false); GameObject soulBolt2 = SoulBolt; GameObject soulFire = SoulFire; bool? flag2 = true; FxFactory.SetEffect(soulBolt2, false, 0.85f, 0f, 0f, soulFire, (GameObject)null, (bool?)null, (float?)null, flag2); } ArcBolt = Shot("ModWpnArcBolt", "DFX_HeroArrow", "FxWpnArcbolt", "Bolt", 420f, 0.6f, 0.8f, 0.4f); WeaponFx.OnSpawn<WpnChainFx>(ArcBolt, (Action<WpnChainFx>)delegate(WpnChainFx c) { c.Reset(); }); Arc = Vis("ModWpnArc", "FxWpnArcbolt", "Arc", loop: false, 0f, (Anchor)3); Spark = Vis("ModWpnSpark", "FxWpnArcbolt", "Spark", loop: false, 0f, (Anchor)4); Build2(); BuildV08(); Plugin.Log.LogInfo((object)"Weapon FX templates built"); } private static void Pierce(GameObject go) { DamageEffect val = (((Object)(object)go != (Object)null) ? go.GetComponent<DamageEffect>() : null); if ((Object)(object)val == (Object)null || val.m_contactData == null) { return; } foreach (ContactData contactDatum in val.m_contactData) { if (contactDatum != null) { contactDatum.m_destroyOnHit = (((LayerMask)(ref contactDatum.m_layerMask)).value & 0x200) != 0; } } } private static GameObject VisRot(string name, string art, string anim) { GameObject val = Vis(name, art, anim, loop: false, 0f, (Anchor)4); if ((Object)(object)val != (Object)null) { bool? flag = true; bool? flag2 = true; FxFactory.SetEffect(val, true, 0f, 0f, 0f, (GameObject)null, (GameObject)null, flag, (float?)null, flag2); } return val; } private static void Build2() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_02cf: Unknown result type (might be due to invalid IL or missing references) //IL_02e9: Unknown result type (might be due to invalid IL or missing references) //IL_0441: Unknown result type (might be due to invalid IL or missing references) //IL_055e: Unknown result type (might be due to invalid IL or missing references) //IL_05cb: Unknown result type (might be due to invalid IL or missing references) //IL_06ca: Unknown result type (might be due to invalid IL or missing references) //IL_0732: Unknown result type (might be due to invalid IL or missing references) //IL_0936: Unknown result type (might be due to invalid IL or missing references) //IL_099c: Unknown result type (might be due to invalid IL or missing references) //IL_0a1a: Unknown result type (might be due to invalid IL or missing references) //IL_0ad6: Unknown result type (might be due to invalid IL or missing references) Status status = FxFactory.GetStatus("StatusLavaSteveGoo"); Status status2 = FxFactory.GetStatus("StatusDizzy"); FrostSlash = Swipe("ModWpnFrostSlash", "1HandedSwordSwipe1", "FxWpnFrostbrand", "Slash", 1f, 0.6f, new Vector2(8.4f, 0.4f), 1f, status, 0.35f); WeaponFx.OnSpawn<WpnFrostFx>(FrostSlash, (Action<WpnFrostFx>)null); FrostChill = Vis("ModWpnFrostChill", "FxWpnFrostbrand", "Chill", loop: true, 2.7f, (Anchor)4); FrostChill2 = Vis("ModWpnFrostChill2", "FxWpnFrostbrand", "Chill2", loop: true, 2.7f, (Anchor)4); SpriteSheet val = SpriteSheets.Get("FxWpnFrostbrand"); FrostShatter = Zone("ModWpnFrostShatter", new ClipBuilder(val, "Shatter", "ModWpnFrostShatterClip").Once(), val, 0.85f, 0f, 0.8f, 0, 2); Box(FrostShatter, 48f, 30f); MercySlash = Swipe("ModWpnMercySlash", "1HandedSwordSwipe2", "FxWpnMercyblade", "Slash", 1f, 0.6f, new Vector2(8.4f, -0.8f)); WeaponFx.OnSpawn<WpnMercyFx>(MercySlash, (Action<WpnMercyFx>)null); MercyX = Vis("ModWpnMercyX", "FxWpnMercyblade", "Mercy", loop: false, 0f, (Anchor)4); ReapA = Swipe("ModWpnReapA", "DamageHeroSwipeSkewed", "FxWpnReaper", "Reap", 1f, 0.8f, new Vector2(5.5f, 1.3f), 1.25f); ReapB = Swipe("ModWpnReapB", "DamageHeroSwipeSkewed", "FxWpnReaper", "Reap2", 1f, 0.9f, new Vector2(5.5f, 1.3f), 1.25f); WeaponFx.OnSpawn<WpnReapFx>(ReapA, (Action<WpnReapFx>)null); WeaponFx.OnSpawn<WpnReapFx>(ReapB, (Action<WpnReapFx>)null); ReapSoul = Vis("ModWpnReapSoul", "FxWpnReaper", "Soul", loop: true, 1.5f, (Anchor)4); WeaponFx.OnSpawn<WpnBeadFx>(ReapSoul, (Action<WpnBeadFx>)delegate(WpnBeadFx b) { b.Reset(); }); SpriteSheet val2 = SpriteSheets.Get("FxWpnStarfall"); StarSlam = Zone("ModWpnStarSlam", new ClipBuilder(val2, "Slam", "ModWpnStarSlamClip").Once(), val2, 1f, 0f, 1f, 0, 2, null, 0f, attached: true); Box(StarSlam, 29.5f, 20.9f, 13f); Anchor(StarSlam, (Anchor)4, new Vector2(13f, 0f)); StarWell = Zone("ModWpnStarWell", new ClipBuilder(val2, "Well", "ModWpnStarWellClip").Once(), val2, 0.45f, 0f, 1.2f, 6, -1); Box(StarWell, 40f, 26f); WeaponFx.OnSpawn<WpnGravityFx>(StarWell, (Action<WpnGravityFx>)delegate(WpnGravityFx g) { g.Reset(); }); HydraShard = Shot("ModWpnHydraShard", "DFX_HeroArrow", "FxWpnHydraBow", "Shard", 380f, 0.35f, 0.55f, 0.3f); HydraArrow = Shot("ModWpnHydraArrow", "DFX_HeroArrow", "FxWpnHydraBow", "Arrow", 380f, 0.6f, 1.1f, 0.5f); WeaponFx.OnSpawn<WpnSplitFx>(HydraArrow, (Action<WpnSplitFx>)delegate(WpnSplitFx a) { a.Reset(); }); HydraSplit = VisRot("ModWpnHydraSplit", "FxWpnHydraBow", "Split"); GuardBash = Swipe("ModWpnGuardBash", "1HandedSwordSwipe2", "FxWpnBulwark", "Bash", 1f, 1f, new Vector2(8.4f, -0.8f)); WeaponFx.OnSpawn<WpnGuardFx>(GuardBash, (Action<WpnGuardFx>)null); GuardRing = Vis("ModWpnGuardRing", "FxWpnBulwark", "Guard", loop: true, 5.5f, (Anchor)4); GuardBlock = Vis("ModWpnGuardBlock", "FxWpnBulwark", "Block", loop: false, 0f, (Anchor)4); HeartBolt = Shot("ModWpnHeartBolt", "DFX_HeroArrowCrossbow", "FxWpnHeartseeker", "Bolt", 500f, 0.6f, 1.8f, 0.8f); Pierce(HeartBolt); WeaponFx.OnSpawn<WpnPierceFx>(HeartBolt, (Action<WpnPierceFx>)delegate(WpnPierceFx p) { p.Reset(); }); HeartPierce = Vis("ModWpnHeartPierce", "FxWpnHeartseeker", "Pierce", loop: false, 0f, (Anchor)4); KrisStab = Swipe("ModWpnKrisStab", "DaggerDashthrough", "FxWpnKris", "Stab", 1f, 0.5f, new Vector2(6.9f, -1.9f)); WeaponFx.OnSpawn<WpnKrisFx>(KrisStab, (Action<WpnKrisFx>)null); KrisBack = Vis("ModWpnKrisBack", "FxWpnKris", "Backstab", loop: false, 0f, (Anchor)4); BlightSwing = Swipe("ModWpnBlightSwing", "MagicStaffSwipe", "FxWpnBlightstaff", "Swing", 0.2f, 0.8f, new Vector2(5.2f, -1.3f)); BlightBolt = Shot("ModWpnBlightBolt", "DFX_HeroArrow", "FxWpnBlightstaff", "Bolt", 170f, 0.85f, 0.45f, 0.3f); WeaponFx.OnSpawn<WpnBlightBoltFx>(BlightBolt, (Action<WpnBlightBoltFx>)null); BlightCloud = Vis("ModWpnBlightCloud", "FxWpnBlightstaff", "Cloud", loop: true, 2.3f, (Anchor)4); BlightSpore = Vis("ModWpnBlightSpore", "FxWpnBlightstaff", "Spore", loop: true, 1.5f, (Anchor)4); WeaponFx.OnSpawn<WpnBeadFx>(BlightSpore, (Action<WpnBeadFx>)delegate(WpnBeadFx b) { b.Reset(); }); SpriteSheet val3 = SpriteSheets.Get("FxWpnOrrery"); OrrerySwing = Swipe("ModWpnOrrerySwing", "MagicStaffSwipe", "FxWpnOrrery", "Swing", 0.2f, 0.8f, new Vector2(5.2f, -1.3f)); OrreryBolt = Shot("ModWpnOrreryBolt", "DFX_HeroArrow", "FxWpnOrrery", "Bolt", 260f, 0.6f, 0.45f, 0.3f); OrreryStar = Zone("ModWpnOrreryStar", new ClipBuilder(val3, "Star", "ModWpnOrreryStarClip").Once().Repeat(16), val3, 0.2f, 0.5f, 0.4f, 0, -1); Box(OrreryStar, 9f, 9f); WeaponFx.OnSpawn<WpnOrbitFx>(OrreryStar, (Action<WpnOrbitFx>)delegate(WpnOrbitFx o) { o.Reset(); }); GrudgeStone = FxKit.Projectile("ModWpnGrudgeStone", "SlingProjectile", "FxWpnGrudgestone", "Stone", 0f, 0.75f, 0.95f, 0.5f, (Status)null, 1f, 0f, 0f, false, false); if ((Object)(object)GrudgeStone != (Object)null) { FxFactory.SetMotion(GrudgeStone, 0f, 0f, 0f, (GameObject)null, 50f, 0f, (bool?)null, -1f, false, -1f); } WeaponFx.OnSpawn<WpnGrudgeFx>(GrudgeStone, (Action<WpnGrudgeFx>)delegate(WpnGrudgeFx g) { g.Reset(); }); GrudgeBrand = Vis("ModWpnGrudgeBrand", "FxWpnGrudgestone", "Grudge", loop: true, 8.5f, (Anchor)4); MidasCoin = FxKit.Projectile("ModWpnMidasCoin", "SlingProjectile", "FxWpnMidas", "Coin", 210f, 0.9f, 0.55f, 0.5f, (Status)null, 1f, 0.28f, 0.1f, false, false); WeaponFx.OnSpawn<WpnMidasFx>(MidasCoin, (Action<WpnMidasFx>)delegate(WpnMidasFx m) { m.Reset(); }); MidasGold = Vis("ModWpnMidasGold", "FxWpnMidas", "Gold", loop: false, 0f, (Anchor)4); LanceThrust = Swipe("ModWpnLanceThrust", "SpearSwipe", "FxWpnLance", "Thrust", 1f, 0.8f, new Vector2(1.7f, -2.1f)); WeaponFx.OnSpawn<WpnChargeFx>(LanceThrust, (Action<WpnChargeFx>)null); LanceCharge = VisRot("ModWpnLanceCharge", "FxWpnLance", "Charge"); LashBody = Swipe("ModWpnLashBody", "SpearSwipe", "FxWpnLash", "Lash", 0.45f, 0.3f, new Vector2(19f, 0f)); Box(LashBody, 26f, 8f, 19f); WeaponFx.OnSpawn<WpnLashFx>(LashBody, (Action<WpnLashFx>)delegate(WpnLashFx l) { l.Reset(); }); SpriteSheet val4 = SpriteSheets.Get("FxWpnLash"); LashTip = Zone("ModWpnLashTip", new ClipBuilder(val4, "Crack", "ModWpnLashTipClip").Once(), val4, 1.2f, 0f, 1.1f, 0, 2, status2, 0.25f); Box(LashTip, 14f, 12f); Kunai = Shot("ModWpnKunai", "KnivesProjectile", "FxWpnKunai", "Kunai", 320f, 0.4f, 0.8f, 0.3f); WeaponFx.OnSpawn<WpnKunaiFx>(Kunai, (Action<WpnKunaiFx>)null); KunaiSlash = Swipe("ModWpnKunaiSlash", "1HandedSwordSwipe1", "FxWpnKunai", "Slash", 0.9f, 0.6f, new Vector2(8.4f, 0.4f)); WeaponFx.OnSpawn<WpnHuntSlashFx>(KunaiSlash, (Action<WpnHuntSlashFx>)null); KunaiMark = Vis("ModWpnKunaiMark", "FxWpnKunai", "Mark", loop: true, 3.2f, (Anchor)4); KunaiPop = Vis("ModWpnKunaiPop", "FxWpnKunai", "Pop", loop: false, 0f, (Anchor)4); } public static GameObject ImpHit(string id) { if (!ImpactHit.TryGetValue(id, out var value)) { return null; } return value; } public static GameObject ImpWall(string id) { if (!ImpactWall.TryGetValue(id, out var value)) { return null; } return value; } private static void Impacts(GameObject proj, string id, bool wallContact = true) { //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: 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_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_010d: 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_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011c: 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_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0129: 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_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Expected O, but got Unknown DamageEffect val = (((Object)(object)proj != (Object)null) ? proj.GetComponent<DamageEffect>() : null); if ((Object)(object)val == (Object)null || val.m_contactData == null) { return; } GameObject spawnOnHit = ImpHit(id); GameObject val2 = (wallContact ? ImpWall(id) : null); List<ContactData> list = new List<ContactData>(); foreach (ContactData contactDatum in val.m_contactData) { if (contactDatum == null || ((Object)(object)contactDatum.m_spawnOnHit != (Object)null && ((Object)contactDatum.m_spawnOnHit).name.StartsWith("ModWpn", StringComparison.Ordinal) && !ImpactOwn(contactDatum.m_spawnOnHit))) { continue; } int value = ((LayerMask)(ref contactDatum.m_layerMask)).value; if ((value & 0x4000) != 0 && (value & 0x200) != 0) { contactDatum.m_layerMask = LayerMask.op_Implicit(value & -513); contactDatum.m_spawnOnHit = spawnOnHit; if ((Object)(object)val2 != (Object)null) { list.Add(new ContactData { m_layerMask = LayerMask.op_Implicit(512), m_destroyOnHit = contactDatum.m_destroyOnHit, m_spawnOnHit = val2, m_spawnDirection = contactDatum.m_spawnDirection, m_knockbackDirection = contactDatum.m_knockbackDirection, m_spawnAtMiddle = contactDatum.m_spawnAtMiddle, m_hitCorpses = contactDatum.m_hitCorpses, m_hitFriendly = contactDatum.m_hitFriendly }); } } else if ((value & 0x4000) != 0) { contactDatum.m_spawnOnHit = spawnOnHit; } else if ((value & 0x200) != 0) { contactDatum.m_spawnOnHit = val2; } else { contactDatum.m_spawnOnHit = null; } } val.m_contactData.AddRange(list); val.m_spawnOnHit = spawnOnHit; } private static bool ImpactOwn(GameObject go) { foreach (KeyValuePair<string, GameObject> item in ImpactHit) { if ((Object)(object)item.Value == (Object)(object)go) { return true; } } foreach (KeyValuePair<string, GameObject> item2 in ImpactWall) { if ((Object)(object)item2.Value == (Object)(object)go) { return true; } } return false; } private static void SlingShadow(GameObject proj, string sheetId) { Transform val = (((Object)(object)proj != (Object)null) ? proj.transform.Find("Shadow") : null); SpriteSheet val2 = SpriteSheets.Get(sheetId); if ((Object)(object)val == (Object)null || val2 == null || !val2.Has("Shadow")) { Plugin.Log.LogWarning((object)("Weapon shadow: missing for " + sheetId)); return; } exSprite component = ((Component)val).GetComponent<exSprite>(); if (!((Object)(object)component == (Object)null)) { component.SetSprite(val2.atlas, val2.Anim("Shadow").frames[0], false); Renderer component2 = ((Component)val).GetComponent<Renderer>(); if ((Object)(object)component2 != (Object)null && (Object)(object)val2.atlas.material != (Object)null) { component2.sharedMaterial = val2.atlas.material; } exSpriteAnimation component3 = ((Component)val).GetComponent<exSpriteAnimation>(); if ((Object)(object)component3 != (Object)null) { ((Behaviour)component3).enabled = false; } } } private static GameObject WallPuff(string name, SpriteSheet sh, string vanilla) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Expected O, but got Unknown GameObject val = FxFactory.Clone(vanilla, name); if ((Object)(object)val == (Object)null) { return null; } FxFactory.StripChildren(val, new string[0]); FxFactory.Reskin(val, new ClipBuilder(sh, "Wall", name + "Clip").Once().Build(), sh); exSprite component = val.GetComponent<exSprite>(); if ((Object)(object)component != (Object)null) { ((exPlane)component).anchor = (Anchor)4; ((exPlane)component).offset = Vector2.zero; component.color = Color.white; } FxFactory.SetEffect(val, true, 0f, 0f, 0f, (GameObject)null, (GameObject)null, (bool?)true, (float?)0f, (bool?)false); Effect component2 = val.GetComponent<Effect>(); if ((Object)(object)component2 != (Object)null) { R.Set((object)component2, "m_startAngle", (object)new MinMaxRange(0f)); R.Set((object)component2, "m_fadeOutTime", (object)0f); } FxFactory.SetMotion(val, 0f, 0f, 0f, (GameObject)null, 50f, 0f, (bool?)null, -1f, false, -1f); FxKit.NoTint(val); DepthHandler component3 = val.GetComponent<DepthHandler>(); if ((Object)(object)component3 != (Object)null) { component3.m_heightOffset = -4f; } return val; } private static void BuildV08() { //IL_02e5: Unknown result type (might be due to invalid IL or missing references) string[] impactIds = ImpactIds; foreach (string text in impactIds) { string text2 = "FxWpn" + text + "Impact"; SpriteSheet val = SpriteSheets.Get(text2); if (val == null) { Plugin.Log.LogWarning((object)("Weapon impact: missing sheet " + text2)); continue; } GameObject val2 = VisRot("ModWpn" + text + "Hit", text2, "Hit"); DepthHandler val3 = (((Object)(object)val2 != (Object)null) ? val2.GetComponent<DepthHandler>() : null); if ((Object)(object)val3 != (Object)null) { val3.m_heightOffset = -22f; } ImpactHit[text] = val2; object obj; switch (text) { default: obj = "ContactGenericSmall"; break; case "Kunai": case "Moonglaive": case "Grudgestone": obj = "ContactGenericWall"; break; } string vanilla = (string)obj; if (val.Has("Wall")) { ImpactWall[text] = WallPuff("ModWpn" + text + "Wall", val, vanilla); } } Impacts(Hook, "Gravehook"); Impacts(Glaive, "Moonglaive", wallContact: false); Impacts(Wave, "Tidebreaker"); Impacts(Wisp, "Wickstaff"); Impacts(ArcBolt, "Arcbolt"); Impacts(HydraArrow, "HydraBow"); Impacts(HydraShard, "HydraBow"); Impacts(HeartBolt, "Heartseeker"); Impacts(BlightBolt, "Blightstaff"); Impacts(OrreryBolt, "Orrery"); Impacts(GrudgeStone, "Grudgestone", wallContact: false); Impacts(MidasCoin, "Midas"); Impacts(Kunai, "Kunai"); SlingShadow(GrudgeStone, "FxWpnGrudgestone"); SlingShadow(MidasCoin, "FxWpnMidas"); for (int j = 0; j < ReapStacks.Length; j++) { ReapStacks[j] = Vis("ModWpnReapStacks" + (j + 1), "FxWpnReaperStacks", "Stacks" + (j + 1), loop: true, 0f, (Anchor)4); } LanceReady = Vis("ModWpnLanceReady", "FxWpnLance", "Ready", loop: true, 0f, (Anchor)4); SpriteSheet val4 = SpriteSheets.Get("FxWpnMidas"); string[] array = new string[3] { "Coin", "Coin2", "Coin3" }; if (val4 == null) { return; } for (int k = 0; k < array.Length; k++) { if (val4.Has(array[k])) { MidasTiers[k] = new ClipBuilder(val4, array[k], "ModWpnMidas" + array[k] + "Clip").Loop().Build(); } } } } public static class WeaponPack { public static readonly List<WeaponDef> Defs; public static readonly List<WeaponDef> Defs2; public static Dictionary<string, Weapon> Built => ItemRegistry.Weapons; private static DamageEffectData Melee(GameObject o, float ox, float oy, float upX = 0f, float dnX = 0f, bool destroyOnAnimEnd = false, float angle = 0f) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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_003f: Expected O, but got Unknown //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown return new DamageEffectData { m_angle = new MinMaxRange(angle), m_object = o, m_attach = true, m_destroyOnAnimEnd = destroyOnAnimEnd, m_detatchOnAnimEnd = !destroyOnAnimEnd, m_offsetX = new MinMaxRange(ox), m_offsetY = new MinMaxRange(oy), m_offsetAimUp = new Vector2(upX, 0f), m_offsetAimDown = new Vector2(dnX, 0f), m_rotateOffsetX = true }; } private static DamageEffectData Fire(GameObject o, float ox, float oy, Vector2 up = default(Vector2), Vector2 dn = default(Vector2)) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001a: 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_0026: Expected O, but got Unknown //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown return new DamageEffectData { m_object = o, m_attach = false, m_destroyOnAnimEnd = false, m_offsetX = new MinMaxRange(ox), m_offsetY = new MinMaxRange(oy), m_offsetAimUp = up, m_offsetAimDown = dn, m_rotateOffsetX = true }; } private static List<DamageEffectData> L(params DamageEffectData[] e) { return new List<DamageEffectData>(e); } public static void Register() { WeaponFx.Build(); Defs.AddRange(Defs2); foreach (WeaponDef def in Defs) { try { Build(def); } catch (Exception ex) { Plugin.Log.LogError((object)("Weapon " + def.id + " failed: " + ex)); } } try { WeaponLooks.Register(); } catch (Exception ex2) { Plugin.Log.LogError((object)("Weapon in-hand colours failed: " + ex2)); } Plugin.Log.LogInfo((object)("Weapons built: " + Built.Count + "/" + Defs.Count)); } private static void Build(WeaponDef def) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown WeaponHands.Set hands = WeaponHands.For(def.id); def.heroFrames = (HeroFrameMap)delegate(exAtlas atlas, int index, out exAtlas outAtlas, out int outIndex) { WeaponHands.Remap(atlas, index, hands, out outAtlas, out outIndex); }; int unmapped = WeaponHands.Unmapped; ItemRegistry.Register(def); if (WeaponHands.Unmapped > unmapped) { Plugin.Log.LogWarning((object)(def.id + ": " + (WeaponHands.Unmapped - unmapped) + " hero frames have no in-hand redraw (vanilla weapon shows)")); } } static WeaponPack() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Expected O, but got Unknown //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Expected O, but got Unknown //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Expected O, but got Unknown //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Expected O, but got Unknown //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Expected O, but got Unknown //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: 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_02a8: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Expected O, but got Unknown //IL_02da: Unknown result type (might be due to invalid IL or missing references) //IL_02e4: Expected O, but got Unknown //IL_030c: Unknown result type (might be due to invalid IL or missing references) //IL_0316: Expected O, but got Unknown //IL_031d: Unknown result type (might be due to invalid IL or missing references) //IL_0323: Expected O, but got Unknown //IL_03c0: Unknown result type (might be due to invalid IL or missing references) //IL_03ca: Expected O, but got Unknown //IL_03f2: Unknown result type (might be due to invalid IL or missing references) //IL_03fc: Expected O, but got Unknown //IL_0403: Unknown result type (might be due to invalid IL or missing references) //IL_0409: Expected O, but got Unknown //IL_04a6: Unknown result type (might be due to invalid IL or missing references) //IL_04b0: Expected O, but got Unknown //IL_04d8: Unknown result type (might be due to invalid IL or missing references) //IL_04e2: Expected O, but got Unknown //IL_051c: Unknown result type (might be due to invalid IL or missing references) //IL_0526: Expected O, but got Unknown //IL_052d: Unknown result type (might be due to invalid IL or missing references) //IL_0533: Expected O, but got Unknown //IL_05d0: Unknown result type (might be due to invalid IL or missing references) //IL_05da: Expected O, but got Unknown //IL_0602: Unknown result type (might be due to invalid IL or missing references) //IL_060c: Expected O, but got Unknown //IL_0634: Unknown result type (might be due to invalid IL or missing references) //IL_063e: Expected O, but got Unknown //IL_0645: Unknown result type (might be due to invalid IL or missing references) //IL_064b: Expected O, but got Unknown //IL_06e8: Unknown result type (might be due to invalid IL or missing references) //IL_06f2: Expected O, but got Unknown //IL_06f9: Unknown result type (might be due to invalid IL or missing references) //IL_06ff: Expected O, but got Unknown //IL_07ad: Unknown result type (might be due to invalid IL or missing references) //IL_07b7: Expected O, but got Unknown //IL_07be: Unknown result type (might be due to invalid IL or missing references) //IL_07c4: Expected O, but got Unknown //IL_0872: Unknown result type (might be due to invalid IL or missing references) //IL_087c: Expected O, but got Unknown //IL_0883: Unknown result type (might be due to invalid IL or missing references) //IL_0889: Expected O, but got Unknown //IL_0926: Unknown result type (might be due to invalid IL or missing references) //IL_0930: Expected O, but got Unknown //IL_0958: Unknown result type (might be due to invalid IL or missing references) //IL_0962: Expected O, but got Unknown //IL_0975: Unknown result type (might be due to invalid IL or missing references) //IL_097b: Expected O, but got Unknown //IL_0a18: Unknown result type (might be due to invalid IL or missing references) //IL_0a22: Expected O, but got Unknown //IL_0a4a: Unknown result type (might be due to invalid IL or missing references) //IL_0a54: Expected O, but got Unknown //IL_0a7c: Unknown result type (might be due to invalid IL or missing references) //IL_0a86: Expected O, but got Unknown //IL_0a8d: Unknown result type (might be due to invalid IL or missing references) //IL_0a93: Expected O, but got Unknown //IL_0b30: Unknown result type (might be due to invalid IL or missing references) //IL_0b3a: Expected O, but got Unknown //IL_0b62: Unknown result type (might be due to invalid IL or missing references) //IL_0b6c: Expected O, but got Unknown //IL_0b94: Unknown result type (might be due to invalid IL or missing references) //IL_0b9e: Expected O, but got Unknown //IL_0ba5: Unknown result type (might be due to invalid IL or missing references) //IL_0bab: Expected O, but got Unknown //IL_0c48: Unknown result type (might be due to invalid IL or missing references) //IL_0c52: Expected O, but got Unknown //IL_0c7a: Unknown result type (might be due to invalid IL or missing references) //IL_0c84: Expected O, but got Unknown //IL_0cbd: Unknown result type (might be due to invalid IL or missing references) //IL_0cc7: Expected O, but got Unknown //IL_0cce: Unknown result type (might be due to invalid IL or missing references) //IL_0cd4: Expected O, but got Unknown //IL_0d82: Unknown result type (might be due to invalid IL or missing references) //IL_0d8c: Expected O, but got Unknown //IL_0d93: Unknown result type (might be due to invalid IL or missing references) //IL_0d99: Expected O, but got Unknown //IL_0e36: Unknown result type (might be due to invalid IL or missing references) //IL_0e40: Expected O, but got Unknown //IL_0e47: Unknown result type (might be due to invalid IL or missing references) //IL_0e4d: Expected O, but got Unknown //IL_0eea: Unknown result type (might be due to invalid IL or missing references) //IL_0ef4: Expected O, but got Unknown //IL_0f1c: Unknown result type (might be due to invalid IL or missing references) //IL_0f26: Expected O, but got Unknown //IL_0f2d: Unknown result type (might be due to invalid IL or missing references) //IL_0f33: Expected O, but got Unknown //IL_0fd0: Unknown result type (might be due to invalid IL or missing references) //IL_0fda: Expected O, but got Unknown //IL_0fe1: Unknown result type (might be due to invalid IL or missing references) //IL_0fe7: Expected O, but got Unknown //IL_1084: Unknown result type (might be due to invalid IL or missing references) //IL_108e: Expected O, but got Unknown //IL_10b6: Unknown result type (might be due to invalid IL or missing references) //IL_10c0: Expected O, but got Unknown //IL_10e8: Unknown result type (might be due to invalid IL or missing references) //IL_10f2: Expected O, but got Unknown //IL_10f9: Unknown result type (might be due to invalid IL or missing references) //IL_10ff: Expected O, but got Unknown //IL_11ad: Unknown result type (might be due to invalid IL or missing references) //IL_11b7: Expected O, but got Unknown //IL_11be: Unknown result type (might be due to invalid IL or missing references) //IL_11c4: Expected O, but got Unknown //IL_1283: Unknown result type (might be due to invalid IL or missing references) //IL_128d: Expected O, but got Unknown //IL_1294: Unknown result type (might be due to invalid IL or missing references) //IL_129a: Expected O, but got Unknown //IL_1326: Unknown result type (might be due to invalid IL or missing references) //IL_1330: Expected O, but got Unknown //IL_1358: Unknown result type (might be due to invalid IL or missing references) //IL_1362: Expected O, but got Unknown //IL_1369: Unknown result type (might be due to invalid IL or missing references) //IL_136f: Expected O, but got Unknown //IL_13fb: Unknown result type (might be due to invalid IL or missing references) //IL_1405: Expected O, but got Unknown //IL_142d: Unknown result type (might be due to invalid IL or missing references) //IL_1437: Expected O, but got Unknown //IL_143e: Unknown result type (might be due to invalid IL or missing references) //IL_1444: Expected O, but got Unknown //IL_14e1: Unknown result type (might be due to invalid IL or missing references) //IL_14eb: Expected O, but got Unknown //IL_1513: Unknown result type (might be due to invalid IL or missing references) //IL_151d: Expected O, but got Unknown //IL_1524: Unknown result type (might be due to invalid IL or missing references) //IL_152a: Expected O, but got Unknown //IL_15c7: Unknown result type (might be due to invalid IL or missing references) //IL_15d1: Expected O, but got Unknown //IL_15f9: Unknown result type (might be due to invalid IL or missing references) //IL_1603: Expected O, but got Unknown //IL_162b: Unknown result type (might be due to invalid IL or missing references) //IL_1635: Expected O, but got Unknown //IL_163c: Unknown result type (might be due to invalid IL or missing references) //IL_1642: Expected O, but got Unknown //IL_16df: Unknown result type (might be due to invalid IL or missing references) //IL_16e9: Expected O, but got Unknown //IL_1711: Unknown result type (might be due to invalid IL or missing references) //IL_171b: Expected O, but got Unknown //IL_1743: Unknown result type (might be due to invalid IL or missing references) //IL_174d: Expected O, but got Unknown List<WeaponDef> list = new List<WeaponDef>(); List<WeaponDef> list2 = list; WeaponDef val = new WeaponDef(); val.id = "Gravehook"; val.name = "Gravehook"; val.family = "Tether"; val.baseWeapon = "WeaponSpear"; val.baseCombo = 1; val.cost = 85f; val.damageMult = 0.95f; val.comboCooldown = 0.4f; val.description = "Jab, then hook a monster and drag it to you"; val.effects = () => L(Melee(WeaponFx.HookJab, 14f, 2f, 3f, 3f), Fire(WeaponFx.Hook, 0f, -2f)); val.attacks.Add(new WeaponAttack(0, 0.33f, 1f, new object[2] { "a1", 0 })); val.attacks.Add(new WeaponAttack(1, 0.4f, 0.95f, new object[2] { "a1", 0 })); val.attacks.Add(new WeaponAttack(5, 0.55f, 1.1f, new object[2] { "a0", 1 })); list2.Add(val); List<WeaponDef> list3 = list; val = new WeaponDef(); val.id = "Moonglaive"; val.name = "Moonglaive"; val.family = "Returning"; val.baseWeapon = "WeaponThrowingKnives"; val.baseCombo = 0; val.cost = 70f; val.damageMult = 1f; val.comboCooldown = 0.3f; val.description = "Slash, then throw a glaive that comes back to you"; val.effects = () => L(Melee(WeaponFx.GlaiveSlash, 0f, -1f, 2f, 2f), Fire(WeaponFx.Glaive, 6f, -2f)); val.attacks.Add(new WeaponAttack(0, 0.35f, 1f, new object[2] { "a1", 0 })); val.attacks.Add(new WeaponAttack(1, 0.45f, 1f, new object[2] { "a0", 1 })); list3.Add(val); List<WeaponDef> list4 = list; val = new WeaponDef(); val.id = "Riftblade"; val.name = "Riftblade"; val.family = "Rift"; val.baseWeapon = "Weapon1HandedSword"; val.baseCombo = 1; val.cost = 60f; val.damageMult = 0.75f; val.comboCooldown = 0.35f; val.description = "Quick cuts open a rift that snaps shut on your foes"; val.effects = () => L(Melee(WeaponFx.RiftSlashA, 0f, 0f, 3f, 2f), Melee(WeaponFx.RiftSlashB, 0f, 0f, 4f, 3f)); val.attacks.Add(new WeaponAttack(0, 0.3f, 0.9f, new object[2] { "a1", 0 })); val.attacks.Add(new WeaponAttack(1, 0.34f, 0.9f, new object[2] { "a0", 1 })); val.attacks.Add(new WeaponAttack(2, 0.36f, 0.95f, new object[2] { "a1", 0 })); list4.Add(val); List<WeaponDef> list5 = list; val = new WeaponDef(); val.id = "SnakeEyes"; val.name = "Snake-Eyes"; val.family = "Chance"; val.baseWeapon = "WeaponClub"; val.baseCombo = 0; val.cost = 45f; val.damageMult = 1.1f; val.comboCooldown = 0.25f; val.description = "Every blow rolls a die. Roll high to hit hard"; val.effects = () => L(Melee(WeaponFx.DiceSwing, 0f, -1f, 3f, 6f)); val.attacks.Add(new WeaponAttack(0, 0.55f, 1f, new object[2] { "a1", 0 })); val.attacks.Add(new WeaponAttack(2, 0.45f, 1f, new object[2] { "a0", 0 })); list5.Add(val); List<WeaponDef> list6 = list; val = new WeaponDef(); val.id = "Tidebreaker"; val.name = "Tidebreaker"; val.family = "Tide"; val.baseWeapon = "Weapon2HandedSword"; val.baseCombo = 1; val.cost = 90f; val.damageMult = 0.92f; val.comboCooldown = 0.35f; val.description = "Every third swing sends a wave that sweeps monsters away"; val.effects = () => L(Melee(WeaponFx.TideCleave, 4f, 0f), Melee(WeaponFx.TideCrash, 0f, 1f), Fire(WeaponFx.Wave, 10f, -4f)); val.attacks.Add(new WeaponAttack(4, 0.32f, 1f, new object[2] { "a1", 0 })); val.attacks.Add(new WeaponAttack(2, 0.39f, 1f, new object[2] { "a1", 0 })); val.attacks.Add(new WeaponAttack(9, 0.45f, 1.05f, new object[4] { "a12", 1, "a16", 2 })); list6.Add(val); List<WeaponDef> list7 = list; val = new WeaponDef(); val.id = "Leechfang"; val.name = "Leechfang"; val.family = "Siphon"; val.baseWeapon = "WeaponDagger"; val.baseCombo = 2; val.cost = 55f; val.damageMult = 0.95f; val.comboCooldown = 0.2f; val.description = "Fast stabs that bleed foes and heal you"; val.effects = () => L(Melee(WeaponFx.LeechStab, 5f, 0f, 5f, 5f), Melee(WeaponFx.LeechSlash, 0f, 0f, 5f, 2f)); val.attacks.Add(new WeaponAttack(2, 0.29f, 1f, new object[2] { "a0", 1 })); val.attacks.Add(new WeaponAttack(3, 0.29f, 1f, new object[2] { "a2", 0 })); val.attacks.Add(new WeaponAttack(4, 0.3f, 1f, new object[2] { "a3", 1 })); list7.Add(val); List<WeaponDef> list8 = list; val = new WeaponDef(); val.id = "Briarbow"; val.name = "Briarbow"; val.family = "Seed"; val.baseWeapon = "WeaponBow"; val.baseCombo = 0; val.cost = 65f; val.damageMult = 1f; val.comboCooldown = 0f; val.description = "Arrows plant thorny briars where they land"; val.effects = () => L(Fire(WeaponFx.BriarArrow, 0f, -2f)); val.attacks.Add(new WeaponAttack(0, 1f, 1f, new object[2] { "a0", 0 })); list8.Add(val); List<WeaponDef> list9 = list; val = new WeaponDef(); val.id = "DirgeMaul"; val.name = "Dirge Maul"; val.family = "Bell"; val.baseWeapon = "WeaponBattleAxe"; val.baseCombo = 0; val.cost = 80f; val.damageMult = 1.55f; val.comboCooldown = 0f; val.description = "Each slam rings a bell that stuns nearby monsters"; val.effects = () => L(Melee(WeaponFx.BellHit, 2f, -9f, 0f, 0f, destroyOnAnimEnd: true), Fire(WeaponFx.BellRing, 18f, -10f, new Vector2(0f, -8f), new Vector2(0f, 8f))); val.attacks.Add(new WeaponAttack(0, 1.1f, 1f, new object[4] { "a3", 0, "a2", 1 })); list9.Add(val); List<WeaponDef> list10 = list; val = new WeaponDef(); val.id = "Wickstaff"; val.name = "Wickstaff"; val.family = "Lantern"; val.baseWeapon = "WeaponMagicStaff"; val.baseCombo = -1; val.cost = 85f; val.damageMult = 1f; val.comboCooldown = 0f; val.description = "Lantern bolts leave soul fire that spawns seeking wisps"; val.effects = () => L(Melee(WeaponFx.LanternSwing, 0f, 1f), Fire(WeaponFx.SoulBolt, 4f, -2f)); val.attacks.Add(new WeaponAttack(0, 1.1f, 1f, new object[4] { "a0", 0, "mprj", 1 })); list10.Add(val); List<WeaponDef> list11 = list; val = new WeaponDef(); val.id = "Arcbolt"; val.name = "Arcbolt"; val.family = "Storm"; val.baseWeapon = "WeaponCrossbow"; val.baseCombo = 1; val.cost = 75f; val.damageMult = 1f; val.comboCooldown = 0.5f; val.description = "Bolts that arc lightning between foes"; val.effects = () => L(Fire(WeaponFx.ArcBolt, 5f, 0f)); val.attacks.Add(new WeaponAttack(0, 0.6f, 1f, new object[2] { "a1", 0 })); val.attacks.Add(new WeaponAttack(1, 0.6f, 1f, new object[2] { "a1", 0 })); list11.Add(val); Defs = list; list = new List<WeaponDef>(); List<WeaponDef> list12 = list; val = new WeaponDef(); val.id = "Frostbrand"; val.name = "Frostbrand"; val.family = "Frost"; val.baseWeapon = "Weapon1HandedSword"; val.baseCombo = 1; val.cost = 60f; val.damageMult = 0.7f; val.comboCooldown = 0.3f; val.description = "Chilling cuts that slow, then shatter frozen foes"; val.effects = () => L(Melee(WeaponFx.FrostSlash, 0f, 0f, 3f, 2f)); val.attacks.Add(new WeaponAttack(3, 0.46f, 1f, new object[2] { "a3", 0 })); val.attacks.Add(new WeaponAttack(4, 0.28f, 1f, new object[2] { "a2", 0 })); val.attacks.Add(new WeaponAttack(5, 0.2f, 1f, new object[2] { "a3", 0 })); list12.Add(val); List<WeaponDef> list13 = list; val = new WeaponDef(); val.id = "Mercyblade"; val.name = "Mercyblade"; val.family = "Execute"; val.baseWeapon = "Weapon1HandedSword"; val.baseCombo = 0; val.cost = 50f; val.damageMult = 0.75f; val.comboCooldown = 0.3f; val.description = "Strikes twice against badly hurt foes"; val.effects = () => L(Melee(WeaponFx.MercySlash, 0f, 0f, 4f, 3f)); val.attacks.Add(new WeaponAttack(0, 0.33f, 1f, new object[2] { "a1", 0 })); val.attacks.Add(new WeaponAttack(1, 0.38f, 1f, new object[2] { "a0", 0 })); val.attacks.Add(new WeaponAttack(2, 0.36f, 1f, new object[2] { "a1", 0 })); list13.Add(val); List<WeaponDef> list14 = list; val = new WeaponDef(); val.id = "Reaper"; val.name = "Reaper"; val.family = "Harvest"; val.baseWeapon = "Weapon2HandedSword"; val.baseCombo = 2; val.cost = 90f; val.damageMult = 0.8f; val.comboCooldown = 0.35f; val.description = "Each kill sharpens the scythe, until you are hit"; val.effects = () => L(Melee(WeaponFx.ReapA, 4f, 0f), Melee(WeaponFx.ReapB, 0f, 1f, 0f, 0f, destroyOnAnimEnd: false, 15f), Melee(WeaponFx.ReapB, 0f, 1f, 0f, 0f, destroyOnAnimEnd: false, -15f)); val.attacks.Add(new WeaponAttack(4, 0.3f, 1f, new object[2] { "a1", 0 })); val.attacks.Add(new WeaponAttack(1, 0.32f, 1f, new object[2] { "a1", 0 })); val.attacks.Add(new WeaponAttack(6, 0.48f, 1f, new object[4] { "a9", 1, "a10", 2 })); list14.Add(val); List<WeaponDef> list15 = list; val = new WeaponDef(); val.id = "Starfall"; val.name = "Starfall Maul"; val.family = "Gravity"; val.baseWeapon = "WeaponBattleAxe"; val.baseCombo = 0; val.cost = 85f; val.damageMult = 1.45f; val.comboCooldown = 0f; val.description = "Slams open a star well that drags foes in"; val.effects = () => L(Melee(WeaponFx.StarSlam, 2f, -9f, 0f, 0f, destroyOnAnimEnd: true), Fire(WeaponFx.StarWell, 18f, -10f, new Vector2(0f, -8f), new Vector2(0f, 8f))); val.attacks.Add(new WeaponAttack(0, 1.1f, 1f, new object[4] { "a3", 0, "a2", 1 })); list15.Add(val); List<WeaponDef> list16 = list; val = new WeaponDef(); val.id = "HydraBow"; val.name = "Hydra Bow"; val.family = "Split"; val.baseWeapon = "WeaponBow"; val.baseCombo = 0; val.cost = 70f; val.damageMult = 1f; val.comboCooldown = 0f; val.description = "Arrows that split into three fangs"; val.effects = () => L(Fire(WeaponFx.HydraArrow, 0f, -2f)); val.attacks.Add(new WeaponAttack(0, 1f, 1f, new object[2] { "a0", 0 })); list16.Add(val); List<WeaponDef> list17 = list; val = new WeaponDef(); val.id = "Bulwark"; val.name = "Bulwark Mace"; val.family = "Guard"; val.baseWeapon = "WeaponClub"; val.baseCombo = 0; val.cost = 50f; val.damageMult = 1.15f; val.comboCooldown = 0.3f; val.description = "Every third hit raises a ward that blocks a blow"; val.effects = () => L(Melee(WeaponFx.GuardBash, 0f, -1f, 3f, 6f)); val.attacks.Add(new WeaponAttack(1, 0.39f, 1f, new object[2] { "a1", 0 })); val.attacks.Add(new WeaponAttack(6, 0.46f, 1f, new object[2] { "a1", 0 })); list17.Add(val); List<WeaponDef> list18 = list; val = new WeaponDef(); val.id = "Heartseeker"; val.name = "Heartseeker"; val.family = "Pierce"; val.baseWeapon = "WeaponCrossbow"; val.baseCombo = 0; val.cost = 70f; val.damageMult = 1f; val.comboCooldown = 1.3f; val.description = "Heavy bolts that pierce through foes, hitting harder as they go"; val.effects = () => L(Fire(WeaponFx.HeartBolt, 5f, 0f)); val.attacks.Add(new WeaponAttack(3, 0.7f, 1f, new object[2] { "a0", 0 })); list18.Add(val); List<WeaponDef> list19 = list; val = new WeaponDef(); val.id = "Kris"; val.name = "Shadow Kris"; val.family = "Backstab"; val.baseWeapon = "WeaponDagger"; val.baseCombo = 0; val.cost = 50f; val.damageMult = 0.7f; val.comboCooldown = 0.2f; val.description = "Quick stabs that hit harder from behind"; val.effects = () => L(Melee(WeaponFx.KrisStab, 5f, 0f, 5f, 5f)); val.attacks.Add(new WeaponAttack(0, 0.27f, 1f, new object[2] { "a1", 0 })); val.attacks.Add(new WeaponAttack(1, 0.32f, 1f, new object[2] { "a1", 0 })); val.attacks.Add(new WeaponAttack(2, 0.31f, 1f, new object[2] { "a0", 0 })); list19.Add(val); List<WeaponDef> list20 = list; val = new WeaponDef(); val.id = "Blightstaff"; val.name = "Blightstaff"; val.family = "Contagion"; val.baseWeapon = "WeaponMagicStaff"; val.baseCombo = -1; val.cost = 80f; val.damageMult = 1f; val.comboCooldown = 0f; val.description = "Plague bolts that spread sickness from foe to foe"; val.effects = () => L(Melee(WeaponFx.BlightSwing, 0f, 1f), Fire(WeaponFx.BlightBolt, 4f, -2f)); val.attacks.Add(new WeaponAttack(0, 1.1f, 1f, new object[4] { "a0", 0, "mprj", 1 })); list20.Add(val); List<WeaponDef> list21 = list; val = new WeaponDef(); val.id = "Orrery"; val.name = "Orrery Staff"; val.family = "Orbit"; val.baseWeapon = "WeaponMagicStaff"; val.baseCombo = -1; val.cost = 80f; val.damageMult = 1f; val.comboCooldown = 0f; val.description = "Shoots star bolts and gathers stars that circle you"; val.effects = () => L(Melee(WeaponFx.OrrerySwing, 0f, 1f), Fire(WeaponFx.OrreryBolt, 4f, -2f), Fire(WeaponFx.OrreryStar, 0f, -2f)); val.attacks.Add(new WeaponAttack(0, 1.1f, 1f, new object[6] { "a0", 0, "mprj", 1, "msmn1", 2 })); list21.Add(val); List<WeaponDef> list22 = list; val = new WeaponDef(); val.id = "Grudgestone"; val.name = "Grudgestone"; val.family = "Vendetta"; val.baseWeapon = "WeaponSling"; val.baseCombo = 0; val.cost = 35f; val.damageMult = 1f; val.comboCooldown = 0f; val.description = "Stones seek out the last monster that hurt you"; val.effects = () => L(Fire(WeaponFx.GrudgeStone, 0f, -9f)); val.attacks.Add(new WeaponAttack(0, 0.3f, 1f, new object[0])); val.attacks.Add(new WeaponAttack(1, 0.86f, 1f, new object[2] { "a0", 0 })); list22.Add(val); List<WeaponDef> list23 = list; val = new WeaponDef(); val.id = "Midas"; val.name = "Midas Sling"; val.family = "Wealth"; val.baseWeapon = "WeaponSling"; val.baseCombo = 0; val.cost = 40f; val.damageMult = 1f; val.comboCooldown = 0f; val.description = "Throws coins that hit harder the richer you are"; val.effects = () => L(Fire(WeaponFx.MidasCoin, 0f, -9f)); val.attacks.Add(new WeaponAttack(0, 0.3f, 1f, new object[0])); val.attacks.Add(new WeaponAttack(1, 0.86f, 1f, new object[2] { "a0", 0 })); list23.Add(val); List<WeaponDef> list24 = list; val = new WeaponDef(); val.id = "Lance"; val.name = "Charger Lance"; val.family = "Momentum"; val.baseWeapon = "WeaponSpear"; val.baseCombo = 0; val.cost = 80f; val.damageMult = 1f; val.comboCooldown = 0.3f; val.description = "Run, then charge to bowl monsters over"; val.effects = () => L(Melee(WeaponFx.LanceThrust, 14f, 2f, 3f, 3f)); val.attacks.Add(new WeaponAttack(0, 0.35f, 1f, new object[2] { "a1", 0 })); val.attacks.Add(new WeaponAttack(1, 0.46f, 1f, new object[2] { "a1", 0 })); list24.Add(val); List<WeaponDef> list25 = list; val = new WeaponDef(); val.id = "Lash"; val.name = "Viper Lash"; val.family = "Sweet spot"; val.baseWeapon = "WeaponThrowingKnives"; val.baseCombo = 0; val.cost = 65f; val.damageMult = 1f; val.comboCooldown = 0.3f; val.description = "A long whip. Its tip cracks hardest"; val.effects = () => L(Melee(WeaponFx.LashBody, 0f, -1f, 2f, 2f)); val.attacks.Add(new WeaponAttack(0, 0.35f, 1f, new object[2] { "a1", 0 })); val.attacks.Add(new WeaponAttack(2, 0.35f, 1f, new object[2] { "a0", 0 })); val.attacks.Add(new WeaponAttack(3, 0.45f, 1f, new object[2] { "a2", 0 })); list25.Add(val); List<WeaponDef> list26 = list; val = new WeaponDef(); val.id = "Kunai"; val.name = "Hunter's Kunai"; val.family = "Mark"; val.baseWeapon = "WeaponThrowingKnives"; val.baseCombo = 1; val.cost = 65f; val.damageMult = 1f; val.comboCooldown = 0.4f; val.description = "Throw a kunai to mark a foe, then slash it for extra damage"; val.effects = () => L(Fire(WeaponFx.Kunai, 0f, -2f), Melee(WeaponFx.KunaiSlash, 0f, -1f, 2f, 2f)); val.attacks.Add(new WeaponAttack(1, 0.35f, 1f, new object[2] { "a0", 0 })); val.attacks.Add(new WeaponAttack(3, 0.45f, 1f, new object[2] { "a2", 1 })); val.attacks.Add(new WeaponAttack(4, 0.25f, 1f, new object[2] { "a3", 1 })); list26.Add(val); Defs2 = list; } } public class WeaponRuntime : MonoBehaviour { public int leechHits; public int bellSlams; public int reapStacks; public int guardHits; public float guardUntil; public float runTime; public float idleTime; public float grudgeTime; public GameObject grudge; public GameObject guardFx; private GameObject m_grudgeShown; public ValueModifierStack guardMod; public readonly List<GameObject> stars = new List<GameObject>(); private PlayerMovement m_move; private GameObject m_readyFx; private int m_reapShown; private static StatusOverlayDef[] s_reapInd; private static StatusOverlayDef s_grudgeInd; public bool GuardUp => Time.time <= guardUntil; private static void BuildInd() { if (s_reapInd == null) { s_reapInd = (StatusOverlayDef[])(object)new StatusOverlayDef[5]; for (int i = 0; i < s_reapInd.Length; i++) { s_reapInd[i] = ModStatus.Indicator("ModIndWpnReap" + (i + 1), "FxWpnReaperStacks", "Stacks" + (i + 1), 0f, (OverlayAt)0, false); } s_grudgeInd = ModStatus.Indicator("ModIndWpnGrudge", "FxWpnGrudgestone", "Grudge", -6f, (OverlayAt)0, false); } } private void BrandGrudge(GameObject on) { BuildInd(); if (!((Object)(object)m_grudgeShown == (Object)(object)on)) { if ((Object)(object)m_grudgeShown != (Object)null) { ModInd.Set(m_grudgeShown, s_grudgeInd, false, 0f); } m_grudgeShown = on; if ((Object)(object)on != (Object)null) { ModInd.Set(on, s_grudgeInd, true, 0f); } } } public string HeldId() { PlayerData heroPlayerData = SystemPlayers.GetHeroPlayerData(); if (heroPlayerData == null || (Object)(object)heroPlayerData.GameObject != (Object)(object)((Component)this).gameObject || heroPlayerData.GameData == null) { return null; } Weapon val = heroPlayerData.GameData.GetWeaponData()?.m_weapon; if ((Object)(object)val == (Object)null) { return null; } string name = ((Object)((Component)val).gameObject).name; if (!name.StartsWith("ModWeapon", StringComparison.Ordinal)) { return null; } return name.Substring(9); } public static void EnsureOnHero(Component c) { GameObject val = ModUtil.Hero(); if (!((Object)(object)val == (Object)null) && !((Object)(object)c == (Object)null) && (!((Object)(object)c.gameObject != (Object)(object)val) || c.transform.IsChildOf(val.transform)) && (Object)(object)val.GetComponent<WeaponRuntime>() == (Object)null) { val.AddComponent<WeaponRuntime>(); } } private void UpdateIndicators() { //IL_00a9: Unknown result type (might be due to invalid IL or missing references) string text = HeldId(); int num = ((text == "Reaper") ? Mathf.Clamp(reapStacks, 0, 5) : 0); if (num != m_reapShown || num > 0) { BuildInd(); ModInd.Count(((Component)this).gameObject, s_reapInd, num); m_reapShown = num; } bool flag = text == "Lance" && runTime >= 0.5f; if (flag && (Object)(object)WeaponFx.LanceReady != (Object)null && !WpnFollowFx.Follows(m_readyFx, ((Component)this).gameObject)) { m_readyFx = WpnFollowFx.Attach(WeaponFx.LanceReady, ((Component)this).gameObject, new Vector2(0f, 1f)); } else if (!flag && (Object)(object)m_readyFx != (Object)null) { WpnFollowFx.Drop(m_readyFx, ((Component)this).gameObject); m_readyFx = null; } if ((Object)(object)m_grudgeShown != (Object)null && text != "Grudgestone") { BrandGrudge(null); } } private void Update() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)m_move == (Object)null) { m_move = ((Component)this).GetComponent<PlayerMovement>(); } if ((Object)(object)m_move != (Object)null) { Vector2 velocity = m_move.GetVelocity(); if (((Vector2)(ref velocity)).magnitude >= m_move.GetSpeedMax() * 0.6f) { runTime += Time.deltaTime; idleTime = 0f; } else if ((idleTime += Time.deltaTime) > 0.3f) { runTime = 0f; } } if ((Object)(object)guardFx != (Object)null && (Time.time > guardUntil || !guardFx.activeInHierarchy)) { if (guardFx.activeInHierarchy) { SystemPool.Despawn(guardFx); } guardFx = null; } if ((Object)(object)grudge != (Object)null && (Time.time - grudgeTime > 8f || !WpnUtil.Alive(grudge))) { ClearGrudge(); } UpdateIndicators(); } public void RaiseGuard(ValueModifierStack mod) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) guardUntil = Time.time + 5f; guardMod = mod; guardFx = WpnFollowFx.Refresh(guardFx, WeaponFx.GuardRing, ((Component)this).gameObject, new Vector2(0f, 8f)); } public void Block(GameObject attacker) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: 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_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: U
plugins/CrawlFurther/CrawlFurther.Core.dll
Decompiled 2 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using CrawlFurther.Art; using CrawlFurther.Compat; using CrawlFurther.Diagnostics; using CrawlFurther.Game; using CrawlFurther.Ghosts; using CrawlFurther.Gods; using CrawlFurther.Heroes; using CrawlFurther.Items; using CrawlFurther.Monsters; using CrawlFurther.Objects; using CrawlFurther.Testing; using CrawlFurther.UI; using CrawlFurther.Util; using HarmonyLib; using InControl; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyVersion("0.0.0.0")] namespace CrawlFurther { internal static class ContentManager { internal static string Status = "waiting for game systems"; private static int s_tries; private static readonly List<KeyValuePair<string, Action>> s_packs = new List<KeyValuePair<string, Action>>(); internal static readonly List<string> FailedPacks = new List<string>(); internal static bool Registered { get; private set; } internal static void AddPack(string name, Action register) { s_packs.Add(new KeyValuePair<string, Action>(name, register)); } internal static void Tick() { if (Registered || !Singleton<SystemDeity>.HasInstance() || !Singleton<Constants>.HasInstance() || !Singleton<SystemUnlocks>.HasInstance() || SystemDeity.GetDeities() == null || ++s_tries % 30 != 0) { return; } if (!MonsterFactory.TryIndexVanilla()) { if (s_tries % 300 == 0) { FurtherCore.Log.LogInfo((object)"Monster prefabs not loaded yet..."); } return; } Registered = true; KeyValuePair<string, Action>[] array = s_packs.ToArray(); int num = 0; List<string> failedPacks = FailedPacks; failedPacks.Clear(); KeyValuePair<string, Action>[] array2 = array; for (int i = 0; i < array2.Length; i++) { KeyValuePair<string, Action> keyValuePair = array2[i]; try { keyValuePair.Value(); num++; FurtherCore.Log.LogInfo((object)("Pack registered: " + keyValuePair.Key)); } catch (Exception ex) { failedPacks.Add(keyValuePair.Key); FurtherCore.Log.LogError((object)("Pack " + keyValuePair.Key + " failed: " + ex)); } } try { Strike.KeepAllScales(); } catch (Exception ex2) { FurtherCore.Log.LogError((object)("KeepAllScales: " + ex2)); } try { LibraryEntries.Register(); } catch (Exception ex3) { FurtherCore.Log.LogError((object)("Library entries: " + ex3)); } try { Statues.Register(); } catch (Exception ex4) { FurtherCore.Log.LogError((object)("Statues: " + ex4)); } try { ModInd.Build(); } catch (Exception ex5) { FurtherCore.Log.LogError((object)("Indicators: " + ex5)); } Status = num + "/" + array.Length + " packs, " + MonsterFactory.Built.Count + " monsters" + ((failedPacks.Count > 0) ? (" FAILED: " + string.Join(", ", failedPacks.ToArray())) : ""); FurtherCore.Log.LogInfo((object)Status); GameEvents.RaiseGameReady(); try { SelfTest.Run(); } catch (Exception ex6) { FurtherCore.Log.LogError((object)("Self-test crashed: " + ex6)); } } } [HarmonyPatch(typeof(SystemGame), "OnStartGame")] internal static class Patch_EventRunStart { private static void Postfix() { ContinueGame.Reset(); GameEvents.RaiseRunStart(); } } [HarmonyPatch(typeof(SystemPlayers), "OnLevelStart")] internal static class Patch_EventFloorStart { private static void Postfix() { GameEvents.RaiseFloorStart(); } } [HarmonyPatch(typeof(SystemLevel), "OnEnteredRoom")] internal static class Patch_EventRoomChanged { private static void Postfix(Room room) { if (GameEvents.HasRoomChanged) { GameEvents.RaiseRoomChanged(room); } } } [HarmonyPatch(typeof(SystemLevel), "OnMonsterSpawned")] internal static class Patch_EventMonsterSpawned { private static void Postfix(GameObject monster) { if (GameEvents.HasMonsterSpawned && !((Object)(object)monster == (Object)null)) { Player component = monster.GetComponent<Player>(); if ((Object)(object)component != (Object)null) { GameEvents.RaiseMonsterSpawned(component); } } } } [HarmonyPatch(typeof(Health), "Damage", new Type[] { typeof(DamageInfo), typeof(bool) })] internal static class Patch_EventHeroDamaged { private static void Postfix(Health __instance, DamageInfo damage, bool __result) { if (__result && GameEvents.HasHeroDamaged && (Object)(object)((Component)__instance).gameObject == (Object)(object)ModUtil.Hero()) { GameEvents.RaiseHeroDamaged(damage); } } } public static class Further { private static readonly Dictionary<string, ConfigFile> s_configs = new Dictionary<string, ConfigFile>(StringComparer.OrdinalIgnoreCase); public static bool IsReady => ContentManager.Registered; public static string Status => ContentManager.Status; public static FurtherMod AddMod(BaseUnityPlugin plugin, Action start) { FurtherMod furtherMod = new FurtherMod(plugin, start); FurtherCore.Register(furtherMod); return furtherMod; } public static void AddPack(string name, Action register) { ContentManager.AddPack(name, register); } public static ConfigFile Config(string fileName) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown //IL_0048: Expected O, but got Unknown if (!fileName.EndsWith(".cfg", StringComparison.OrdinalIgnoreCase)) { fileName += ".cfg"; } if (!s_configs.TryGetValue(fileName, out var value)) { Dictionary<string, ConfigFile> dictionary = s_configs; string key = fileName; ConfigFile val = new ConfigFile(Path.Combine(Paths.ConfigPath, fileName), true); value = val; dictionary[key] = val; } return value; } } [BepInPlugin("com.firefightermate.crawlfurther.core", "Crawl Further Core", "1.2.1")] public class FurtherCore : BaseUnityPlugin { public const string GUID = "com.firefightermate.crawlfurther.core"; public const string NAME = "Crawl Further Core"; public const string VERSION = "1.2.1"; internal static ManualLogSource Log; internal static string ModDir; internal static readonly List<string> FailedStarts = new List<string>(); internal static readonly List<string> FailedPatches = new List<string>(); private static readonly List<FurtherMod> s_mods = new List<FurtherMod>(); private bool m_started; private int m_frames; private static readonly string[] PatchOrder = new string[40] { "Patch_StrikeSpawnOffset", "Patch_ObjectsGameStart", "Patch_ObjectsHeroChange", "Patch_ObjectsTrapEnter", "Patch_TipsInitAsPlayer", "Patch_TipsTrap", "Patch_StatusAdd", "Patch_StatusRemove", "Patch_UnlockEcto", "Patch_HeroGearInitAsPlayer", "Patch_PlayerAwake", "Patch_HealthDamage", "Patch_SpawnEffectEcho", "Patch_PlayerDataSetDeity", "Patch_HeroLooksSetDeity", "Patch_HeroLooksInitAsPlayer", "Patch_HeroLooksRemoveStatus", "Patch_MenuRefresh", "Patch_BrandTitle", "Patch_LibraryCellAction", "Patch_LibraryItemText", "Patch_VaultUpdateItem", "Patch_LibraryChallengeStart", "Patch_LibraryChallengeSummary", "Patch_ChallengeNoAchievements", "Patch_VaultCellAction", "Patch_VaultPortraitGem", "Patch_EvolvePanelFonts", "Patch_TestWipeKeys", "Patch_TestPanelMouse", "Patch_TestUnlocked", "Patch_TestNoVaultFinds", "Patch_TestNoChallengeScores", "Patch_TestFreezeAI", "Patch_TestFreezeAIMove", "Patch_TestFreezeAIAttack", "Patch_TestFreezeBot", "Patch_TestFreezeBotMove", "Patch_OnlineRehello", "Patch_HeroHandover" }; internal static IEnumerable<Assembly> Assemblies { get { yield return typeof(FurtherCore).Assembly; foreach (FurtherMod s_mod in s_mods) { yield return s_mod.Assembly; } } } internal static void Register(FurtherMod mod) { s_mods.Add(mod); } internal static bool IsOurHarmonyId(string id) { if (id == "com.firefightermate.crawlfurther.core") { return true; } foreach (FurtherMod s_mod in s_mods) { if (s_mod.Id == id) { return true; } } return false; } private void Awake() { Log = ((BaseUnityPlugin)this).Logger; ((MonoBehaviour)this).useGUILayout = false; ModDir = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location); Log.LogInfo((object)("Crawl Further Core awake. Unity " + Application.unityVersion + ", dir " + ModDir)); } private void Update() { if (!m_started) { if (++m_frames >= 10) { m_started = true; StartGameHooks(); } } else { GameTick(); } } [MethodImpl(MethodImplOptions.NoInlining)] private void StartGameHooks() { //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Expected O, but got Unknown SpriteSheets.AddFolder(ModDir); TestMode.Start(); FailedStarts.Clear(); foreach (FurtherMod s_mod in s_mods) { SpriteSheets.AddFolder(s_mod.Dir); try { if (s_mod.Start != null) { s_mod.Start(); } } catch (Exception ex) { FailedStarts.Add(s_mod.Id + ": " + ex.GetType().Name + " " + ex.Message); Log.LogError((object)("Starting " + s_mod.Id + " failed: " + ex)); } } PatchAll(typeof(FurtherCore).Assembly, new Harmony("com.firefightermate.crawlfurther.core"), PatchOrder, Log); } internal static void PatchAll(Assembly assembly, Harmony harmony, IList<string> order, ManualLogSource log) { List<Type> list = new List<Type>(); Type[] types = assembly.GetTypes(); foreach (Type type in types) { if (type.GetCustomAttributes(typeof(HarmonyPatch), inherit: false).Length != 0) { list.Add(type); } } Func<Type, int> rank = delegate(Type t) { int num3 = ((order != null) ? order.IndexOf(t.Name) : (-1)); return (num3 >= 0) ? num3 : int.MaxValue; }; list.Sort(delegate(Type a, Type b) { int num3 = rank(a); int num4 = rank(b); return (num3 == num4) ? string.CompareOrdinal(a.FullName, b.FullName) : num3.CompareTo(num4); }); int num = 0; int num2 = 0; foreach (Type item in list) { try { harmony.CreateClassProcessor(item).Patch(); num++; } catch (Exception ex) { num2++; log.LogError((object)("Patch " + item.Name + " failed: " + ex.Message)); FailedPatches.Add(assembly.GetName().Name + ": " + item.Name + ": " + ex.Message); } } log.LogInfo((object)("Harmony patches applied (" + assembly.GetName().Name + "): " + num + " ok, " + num2 + " failed")); } [MethodImpl(MethodImplOptions.NoInlining)] private void GameTick() { ContentManager.Tick(); DevKeys.Tick(); } } public sealed class FurtherMod { private Harmony m_harmony; internal Action Start; public string Id { get; private set; } public string Name { get; private set; } public string Dir { get; private set; } public Assembly Assembly { get; private set; } public ManualLogSource Log { get; private set; } public ConfigFile Config { get; private set; } public Harmony Harmony { get { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown //IL_001d: Expected O, but got Unknown Harmony obj = m_harmony; if (obj == null) { Harmony val = new Harmony(Id); Harmony val2 = val; m_harmony = val; obj = val2; } return obj; } } internal FurtherMod(BaseUnityPlugin plugin, Action start) { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Expected O, but got Unknown BepInPlugin metadata = MetadataHelper.GetMetadata((object)plugin); Id = metadata.GUID; Name = metadata.Name; Assembly = ((object)plugin).GetType().Assembly; Dir = Path.GetDirectoryName(Assembly.Location); Log = (ManualLogSource)AccessTools.Property(typeof(BaseUnityPlugin), "Logger").GetValue(plugin, null); Config = plugin.Config; Start = start; } public void PatchAll(params string[] order) { FurtherCore.PatchAll(Assembly, Harmony, order, Log); } } public static class GameEvents { internal static bool HasRoomChanged => GameEvents.RoomChanged != null; internal static bool HasMonsterSpawned => GameEvents.MonsterSpawned != null; internal static bool HasHeroDamaged => GameEvents.HeroDamaged != null; public static event Action GameReady; public static event Action RunStart; public static event Action FloorStart; public static event Action<Room> RoomChanged; public static event Action<Player> MonsterSpawned; public static event Action<DamageInfo> HeroDamaged; public static event Action<int> GameContinued; internal static void RaiseGameReady() { Raise(GameEvents.GameReady, "GameReady"); } internal static void RaiseRunStart() { Raise(GameEvents.RunStart, "RunStart"); } internal static void RaiseFloorStart() { Raise(GameEvents.FloorStart, "FloorStart"); } internal static void RaiseRoomChanged(Room room) { Raise(GameEvents.RoomChanged, room, "RoomChanged"); } internal static void RaiseMonsterSpawned(Player p) { Raise(GameEvents.MonsterSpawned, p, "MonsterSpawned"); } internal static void RaiseHeroDamaged(DamageInfo d) { Raise(GameEvents.HeroDamaged, d, "HeroDamaged"); } internal static void RaiseGameContinued(int n) { Raise(GameEvents.GameContinued, n, "GameContinued"); } private static void Raise(Action handlers, string name) { if (handlers == null) { return; } Delegate[] invocationList = handlers.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { Action action = (Action)invocationList[i]; try { action(); } catch (Exception ex) { FurtherCore.Log.LogError((object)(name + " handler " + Describe(action) + " failed: " + ex)); } } } private static void Raise<T>(Action<T> handlers, T arg, string name) { if (handlers == null) { return; } Delegate[] invocationList = handlers.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { Action<T> action = (Action<T>)invocationList[i]; try { action(arg); } catch (Exception ex) { FurtherCore.Log.LogError((object)(name + " handler " + Describe(action) + " failed: " + ex)); } } } private static string Describe(Delegate d) { if ((object)d.Method.DeclaringType != null) { return d.Method.DeclaringType.FullName + "." + d.Method.Name; } return d.Method.Name; } } } namespace CrawlFurther.Util { public static class MiniJson { public static object Parse(string s) { int i = 0; return Value(s, ref i); } public static string Write(object value, bool indent = true) { StringBuilder stringBuilder = new StringBuilder(); Write(stringBuilder, value, indent, 0); return stringBuilder.ToString(); } private static void Ws(string s, ref int i) { while (i < s.Length && char.IsWhiteSpace(s[i])) { i++; } } private static bool At(string s, int i, string word) { return string.CompareOrdinal(s, i, word, 0, word.Length) == 0; } private static object Value(string s, ref int i) { Ws(s, ref i); if (i >= s.Length) { throw new FormatException("unexpected end of JSON"); } char c = s[i]; switch (c) { case '{': return Obj(s, ref i); case '[': return Arr(s, ref i); case '"': return Str(s, ref i); default: { if (At(s, i, "true")) { i += 4; return true; } if (At(s, i, "false")) { i += 5; return false; } if (At(s, i, "null")) { i += 4; return null; } int num = i; while (i < s.Length && "+-0123456789.eE".IndexOf(s[i]) >= 0) { i++; } if (i == num) { throw new FormatException("unexpected '" + c + "' at " + i); } return double.Parse(s.Substring(num, i - num), CultureInfo.InvariantCulture); } } } private static Dictionary<string, object> Obj(string s, ref int i) { Dictionary<string, object> dictionary = new Dictionary<string, object>(); i++; Ws(s, ref i); if (s[i] == '}') { i++; return dictionary; } while (true) { Ws(s, ref i); string key = Str(s, ref i); Ws(s, ref i); i++; dictionary[key] = Value(s, ref i); Ws(s, ref i); if (s[i] != ',') { break; } i++; } i++; return dictionary; } private static List<object> Arr(string s, ref int i) { List<object> list = new List<object>(); i++; Ws(s, ref i); if (s[i] == ']') { i++; return list; } while (true) { list.Add(Value(s, ref i)); Ws(s, ref i); if (s[i] != ',') { break; } i++; } i++; return list; } private static string Str(string s, ref int i) { StringBuilder stringBuilder = new StringBuilder(); i++; while (s[i] != '"') { if (s[i] == '\\') { i++; char c = s[i]; switch (c) { case 'n': stringBuilder.Append('\n'); break; case 't': stringBuilder.Append('\t'); break; case 'r': stringBuilder.Append('\r'); break; case 'b': stringBuilder.Append('\b'); break; case 'f': stringBuilder.Append('\f'); break; case 'u': stringBuilder.Append((char)Convert.ToInt32(s.Substring(i + 1, 4), 16)); i += 4; break; default: stringBuilder.Append(c); break; } } else { stringBuilder.Append(s[i]); } i++; } i++; return stringBuilder.ToString(); } private static void Write(StringBuilder sb, object v, bool indent, int depth) { if (v == null) { sb.Append("null"); } else if (v is string || v is Enum || v is char) { Quote(sb, v.ToString()); } else if (v is bool) { sb.Append(((bool)v) ? "true" : "false"); } else if (v is float) { sb.Append(((float)v).ToString("R", CultureInfo.InvariantCulture)); } else if (v is double) { sb.Append(((double)v).ToString("R", CultureInfo.InvariantCulture)); } else if (v is IConvertible) { sb.Append(Convert.ToString(v, CultureInfo.InvariantCulture)); } else if (v is IDictionary dictionary) { sb.Append('{'); bool flag = true; foreach (DictionaryEntry item in dictionary) { if (!flag) { sb.Append(','); } flag = false; Break(sb, indent, depth + 1); Quote(sb, Convert.ToString(item.Key, CultureInfo.InvariantCulture)); sb.Append(indent ? ": " : ":"); Write(sb, item.Value, indent, depth + 1); } if (!flag) { Break(sb, indent, depth); } sb.Append('}'); } else if (v is IEnumerable enumerable) { bool flag2 = true; foreach (object item2 in enumerable) { if (item2 is string || item2 is Enum || (item2 != null && !(item2 is IConvertible))) { flag2 = false; break; } } sb.Append('['); bool flag3 = true; foreach (object item3 in enumerable) { if (!flag3) { sb.Append((flag2 && indent) ? ", " : ","); } flag3 = false; if (!flag2) { Break(sb, indent, depth + 1); } Write(sb, item3, indent, depth + 1); } if (!flag3 && !flag2) { Break(sb, indent, depth); } sb.Append(']'); } else { Quote(sb, v.ToString()); } } private static void Break(StringBuilder sb, bool indent, int depth) { if (indent) { sb.Append('\n'); sb.Append(' ', depth * 2); } } private static void Quote(StringBuilder sb, string s) { sb.Append('"'); foreach (char c in s) { switch (c) { case '"': sb.Append("\\\""); continue; case '\\': sb.Append("\\\\"); continue; case '\n': sb.Append("\\n"); continue; case '\r': sb.Append("\\r"); continue; case '\t': sb.Append("\\t"); continue; } if (c < ' ') { StringBuilder stringBuilder = sb.Append("\\u"); int num = c; stringBuilder.Append(num.ToString("x4")); } else { sb.Append(c); } } sb.Append('"'); } } public static class ModUtil { public static readonly Dictionary<string, MonsterTraits> Traits = new Dictionary<string, MonsterTraits>(); private static readonly FieldRef<Player, bool> s_isGhost = AccessTools.FieldRefAccess<Player, bool>("m_isGhost"); public static GameObject Hero() { PlayerData heroPlayerData = SystemPlayers.GetHeroPlayerData(); if (heroPlayerData == null) { return null; } return heroPlayerData.GameObject; } public static DamageSource HeroSource() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown PlayerData heroPlayerData = SystemPlayers.GetHeroPlayerData(); if (heroPlayerData == null || !((Object)(object)heroPlayerData.GameObject != (Object)null)) { return null; } return new DamageSource(heroPlayerData.GameObject, heroPlayerData.GameObject, heroPlayerData); } public static DamageSource MonsterSource(GameObject body) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown if ((Object)(object)body == (Object)null) { return null; } Player component = body.GetComponent<Player>(); return new DamageSource(body, body, ((Object)(object)component != (Object)null) ? component.GetAttackSpawnerPlayer() : null, -1, -1, ((Object)(object)component != (Object)null) ? component.GetDamageModifierStack(false) : null, false) { m_sourceOwnerPlayer = body }; } public static DamageSource HandOn(DamageSource from, GameObject effect, bool keepAttack = false) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown if (from == null) { return null; } DamageSource val = new DamageSource(effect, from.m_sourceOwner, from.m_sourcePlayer, keepAttack ? from.m_sourceAttack : (-1), keepAttack ? from.m_sourceAttackUId : (-1), from.m_damageMod, false); GameObject sourceOwner = from.m_sourceOwner; Player val2 = (((Object)(object)sourceOwner != (Object)null && (Object)(object)from.m_sourceOwnerPlayer == (Object)(object)sourceOwner) ? sourceOwner.GetComponent<Player>() : null); if ((Object)(object)val2 != (Object)null && val2.GetIsAI()) { val.m_sourceOwnerPlayer = sourceOwner; } return val; } public static PlayerData CreditFor(DamageSource source) { if (source == null) { return null; } if (source.m_sourcePlayer != null) { return source.m_sourcePlayer; } GameObject[] array = (GameObject[])(object)new GameObject[3] { source.m_sourceOwnerPlayer, source.m_sourceOwner, source.m_source }; foreach (GameObject val in array) { Player val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<Player>() : null); PlayerData val3 = (((Object)(object)val2 != (Object)null) ? val2.GetAttackSpawnerPlayer() : null); if (val3 != null) { return val3; } } return null; } public static bool IsGhost(Player p) { if ((Object)(object)p != (Object)null) { return s_isGhost.Invoke(p); } return false; } public static Collider Hurtbox(GameObject who) { if ((Object)(object)who == (Object)null) { return null; } int num = LayerMask.NameToLayer("DamagablePlayer"); Collider[] componentsInChildren = who.GetComponentsInChildren<Collider>(); foreach (Collider val in componentsInChildren) { if ((Object)(object)((Component)val).transform != (Object)(object)who.transform && ((Component)val).gameObject.layer == num && val.enabled) { return val; } } return null; } public static string PrefabName(GameObject go) { string name = ((Object)go).name; int num = name.IndexOf("(Clone)"); if (num < 0) { return name; } return name.Substring(0, num).Trim(); } public static bool Clear(Vector2 a, Vector2 b) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) Vector2 val = b - a; if (((Vector2)(ref val)).sqrMagnitude < 0.01f) { return true; } Vector3 val2 = new Vector3(a.x, a.y, 0f); Vector3 val3 = new Vector3(val.x, val.y, 0f); return !Physics.Raycast(val2, ((Vector3)(ref val3)).normalized, ((Vector2)(ref val)).magnitude, Constants.COL_MASK_WALLS); } public static Vector2 SafePoint(Vector2 from, Vector2 to, float margin = 6f) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_005e: 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_007b: Unknown result type (might be due to invalid IL or missing references) Vector2 val = to - from; float magnitude = ((Vector2)(ref val)).magnitude; if (magnitude < 0.01f) { return from; } RaycastHit val2 = default(RaycastHit); if (Physics.Raycast(new Vector3(from.x, from.y, 0f), new Vector3(val.x, val.y, 0f) / magnitude, ref val2, magnitude, Constants.COL_MASK_WALLS)) { return from + val / magnitude * Mathf.Max(0f, ((RaycastHit)(ref val2)).distance - margin); } return to; } public static void Teleport(GameObject go, Vector2 p) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) float z = go.transform.position.z; go.transform.position = new Vector3(p.x, p.y, z); Rigidbody component = go.GetComponent<Rigidbody>(); if ((Object)(object)component != (Object)null) { component.position = go.transform.position; component.velocity = Vector3.zero; } } public static void Pull(GameObject who, Vector2 toward, float strength) { //IL_001b: 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) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)who == (Object)null) { return; } PlayerMovement component = who.GetComponent<PlayerMovement>(); if (!((Object)(object)component == (Object)null)) { Vector2 val = toward - Vector2.op_Implicit(who.transform.position); if (!(((Vector2)(ref val)).sqrMagnitude < 36f)) { component.AddImpulse(((Vector2)(ref val)).normalized * Mathf.Min(strength, ((Vector2)(ref val)).magnitude * 6f)); } } } public static bool DoorsLocked() { SystemLevel get = Singleton<SystemLevel>.Get; Room val = (((Object)(object)get != (Object)null) ? R.Get<Room>(get, "m_currentRoom") : null); if ((Object)(object)val != (Object)null) { return val.GetDoorsLocked(); } return false; } } public static class R { private delegate bool Mapper(Object from, out Object to); private static readonly Dictionary<Type, Dictionary<string, FieldInfo>> s_fields = new Dictionary<Type, Dictionary<string, FieldInfo>>(); private static readonly MethodInfo s_memberwiseClone = typeof(object).GetMethod("MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic); internal static FieldInfo F(Type t, string name) { if (!s_fields.TryGetValue(t, out var value)) { value = (s_fields[t] = new Dictionary<string, FieldInfo>()); } if (value.TryGetValue(name, out var value2)) { return value2; } value2 = AccessTools.Field(t, name); if ((object)value2 == null) { throw new MissingFieldException(t.Name, name); } value[name] = value2; return value2; } public static T Get<T>(object o, string field) { return (T)F(o.GetType(), field).GetValue(o); } public static void Set(object o, string field, object value) { F(o.GetType(), field).SetValue(o, value); } public static T Clone<T>(T o) where T : class { if (o != null) { return (T)s_memberwiseClone.Invoke(o, null); } return null; } internal static int RemapReferences(GameObject root, Dictionary<Object, Object> map) { return Walk(root, map.TryGetValue); } internal static int VisitReferences(GameObject root, Func<Object, Object> visit) { return Walk(root, delegate(Object k, out Object v) { v = visit(k); return v != (Object)null && v != k; }); } private static int Walk(GameObject root, Mapper map) { int num = 0; HashSet<object> visited = new HashSet<object>(); Component[] componentsInChildren = root.GetComponentsInChildren<Component>(true); foreach (Component val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !(val is Transform)) { num += RemapObject(val, map, visited, 0); } } return num; } private static int RemapObject(object o, Mapper map, HashSet<object> visited, int depth) { //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Expected O, but got Unknown //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Expected O, but got Unknown //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Expected O, but got Unknown if (o == null || depth > 6) { return 0; } if (!(o is Object) && !visited.Add(o)) { return 0; } int num = 0; Type type = o.GetType(); if ((object)type.Assembly == typeof(GameObject).Assembly && !(o is MonoBehaviour)) { return 0; } Type type2 = type; while ((object)type2 != null && (object)type2 != typeof(MonoBehaviour) && (object)type2 != typeof(object)) { FieldInfo[] fields = type2.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { if (fieldInfo.IsNotSerialized || fieldInfo.IsLiteral || fieldInfo.IsInitOnly) { continue; } Type fieldType = fieldInfo.FieldType; object value; try { value = fieldInfo.GetValue(o); } catch { continue; } if (value == null) { continue; } Object to; if (typeof(Object).IsAssignableFrom(fieldType)) { if (map((Object)value, out to)) { fieldInfo.SetValue(o, to); num++; } } else if (fieldType.IsArray) { Array array = (Array)value; Type elementType = fieldType.GetElementType(); for (int j = 0; j < array.Length; j++) { object value2 = array.GetValue(j); if (value2 == null) { continue; } if (typeof(Object).IsAssignableFrom(elementType)) { if (map((Object)value2, out to)) { array.SetValue(to, j); num++; } } else if (IsPlainSerializable(elementType)) { num += RemapObject(value2, map, visited, depth + 1); } } } else if (value is IList && fieldType.IsGenericType) { IList list = (IList)value; Type type3 = fieldType.GetGenericArguments()[0]; for (int k = 0; k < list.Count; k++) { object obj2 = list[k]; if (obj2 == null) { continue; } if (typeof(Object).IsAssignableFrom(type3)) { if (map((Object)obj2, out to)) { list[k] = to; num++; } } else if (IsPlainSerializable(type3)) { num += RemapObject(obj2, map, visited, depth + 1); } } } else if (IsPlainSerializable(fieldType)) { num += RemapObject(value, map, visited, depth + 1); } } type2 = type2.BaseType; } return num; } private static bool IsPlainSerializable(Type t) { if (t.IsClass && !t.IsPrimitive && (object)t != typeof(string) && !typeof(Object).IsAssignableFrom(t)) { return t.IsDefined(typeof(SerializableAttribute), inherit: false); } return false; } } } namespace CrawlFurther.UI { public static class Branding { private static BrandingDef s_def; private static SpriteSheet s_wordmark; private static SpriteSheet s_spark; public static string DisplayName { get { if (s_def == null || string.IsNullOrEmpty(s_def.name)) { return "Crawl Further Core"; } return s_def.name; } } public static string Version { get { if (s_def == null || string.IsNullOrEmpty(s_def.version)) { return "1.2.1"; } return s_def.version; } } public static string Versioned => DisplayName + " " + Version; internal static SpriteSheet Wordmark { get { if (s_wordmark == null && s_def != null && s_def.wordmark != null) { s_wordmark = SpriteSheets.Get(s_def.wordmark); } return s_wordmark; } } internal static SpriteSheet Spark { get { if (s_spark == null && s_def != null && s_def.spark != null) { s_spark = SpriteSheets.Get(s_def.spark); } return s_spark; } } internal static SpriteSheet MenuPip { get { if (s_def == null || s_def.menuPip == null) { return null; } return SpriteSheets.Get(s_def.menuPip); } } internal static SpriteSheet MenuMote { get { if (s_def == null || s_def.menuMote == null) { return null; } return SpriteSheets.Get(s_def.menuMote); } } internal static bool HasVersionLine { get { if (s_def != null) { return !string.IsNullOrEmpty(s_def.name); } return false; } } public static void Set(BrandingDef def) { s_def = def; s_wordmark = null; s_spark = null; } public static void SelfCheck(Action<string> bad) { List<KeyValuePair<string, string[]>> list = new List<KeyValuePair<string, string[]>>(); if (s_def != null) { if (s_def.wordmark != null) { list.Add(new KeyValuePair<string, string[]>(s_def.wordmark, new string[4] { "Idle", "Glitch", "In", "Out" })); } if (s_def.spark != null) { list.Add(new KeyValuePair<string, string[]>(s_def.spark, new string[1] { "Rise" })); } if (s_def.menuPip != null) { list.Add(new KeyValuePair<string, string[]>(s_def.menuPip, new string[1] { "Burn" })); } if (s_def.menuMote != null) { list.Add(new KeyValuePair<string, string[]>(s_def.menuMote, MenuRefresh.MoteAnims)); } } list.Add(new KeyValuePair<string, string[]>("VaultIcons", new string[3] { "Undiscovered", "NoArt", "Locked" })); foreach (VaultCategory category in Vault.Categories) { if (!string.IsNullOrEmpty(category.stamp)) { list.Add(new KeyValuePair<string, string[]>(category.stamp, new string[0])); } } foreach (KeyValuePair<string, string[]> item in list) { SpriteSheet spriteSheet = SpriteSheets.Get(item.Key); if (spriteSheet == null) { bad(item.Key + " art missing"); continue; } string[] value = item.Value; foreach (string text in value) { if (!spriteSheet.Has(text)) { bad(item.Key + " has no " + text + " anim"); } } } if ((object)AccessTools.Field(typeof(MenuMain), "m_menuMain") == null) { bad("MenuMain.m_menuMain not found"); } if ((object)AccessTools.Field(typeof(MenuCredits), "m_scrollContainer") == null) { bad("MenuCredits.m_scrollContainer not found"); } LibraryEntries.SelfCheck(bad); NoModTags(bad); ModMusic.SelfCheck(bad); Secrets.SelfCheck(bad); ModMark.SelfCheck(bad); } public static void NoModTags(Action<string> bad) { Func<string, bool> func = (string t) => !string.IsNullOrEmpty(t) && (t.Contains("(MOD)") || t.Contains("[MOD]")); foreach (KeyValuePair<string, Powerup> item in ItemRegistry.Items) { if ((Object)(object)item.Value != (Object)null && (func(item.Value.GetDisplayName()) || func(item.Value.GetDescription()))) { bad("item " + item.Key + " still tagged"); } } foreach (KeyValuePair<string, Weapon> weapon in ItemRegistry.Weapons) { Weapon value = weapon.Value; if ((Object)(object)value == (Object)null) { continue; } if (func(value.m_weaponName) || func(value.m_weaponDescription)) { bad("weapon " + weapon.Key + " still tagged"); } if (value.m_combos == null) { continue; } foreach (Combo combo in value.m_combos) { if (combo != null && (func(combo.m_name) || func(combo.m_description))) { bad("weapon " + weapon.Key + " combo still tagged"); } } } foreach (string builtName in DeityFactory.BuiltNames) { Deity deity = SystemDeity.GetDeity(builtName); if (deity != null && func(R.Get<string>(deity, "m_text"))) { bad("god " + builtName + " text still tagged"); } } if (Singleton<SystemLibrary>.HasInstance()) { foreach (LibraryEntry item2 in R.Get<List<LibraryEntry>>(Singleton<SystemLibrary>.Instance, "m_entryList")) { if (item2 != null && (func(item2.m_name) || func(item2.m_description))) { bad("vault entry " + ((object)item2)?.ToString() + " still tagged"); } } } foreach (string item3 in TipRegistry.VaultOrder) { if (TipRegistry.TryGet(item3, out var tip) && (func(tip.name) || func(tip.attack) || func(tip.special) || func(tip.passive))) { bad("tip " + item3 + " still tagged"); } } } public static exSprite MakeSprite(string name, Transform parent, SpriteSheet sheet, Vector3 localPos) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_002b: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.layer = ((Component)parent).gameObject.layer; val.transform.SetParent(parent, false); val.transform.localPosition = localPos; val.AddComponent<MeshFilter>(); val.AddComponent<MeshRenderer>(); exSprite obj = val.AddComponent<exSprite>(); ((exPlane)obj).anchor = (Anchor)4; obj.useTextureOffset = false; obj.SetSprite(sheet.atlas, 0, false); val.GetComponent<Renderer>().sharedMaterial = sheet.atlas.material; return obj; } } [HarmonyPatch(typeof(MenuMain), "Start")] internal static class Patch_BrandTitle { private static void Postfix(MenuMain __instance) { if (!UiSettings.Wordmark || Branding.Wordmark == null) { return; } try { Transform val = ((Component)__instance).transform.Find("Title"); exSprite val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<exSprite>() : null); if ((Object)(object)val2 != (Object)null) { TitleWordmark.AttachTitle(val2); } else { FurtherCore.Log.LogWarning((object)"Branding: MenuMain has no Title sprite"); } } catch (Exception ex) { FurtherCore.Log.LogError((object)("Branding title: " + ex)); } } } [HarmonyPatch(typeof(MenuCredits), "OnEnable")] internal static class Patch_BrandCredits { private static void Postfix(MenuCredits __instance) { //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) if (!UiSettings.Wordmark || Branding.Wordmark == null) { return; } try { GameObject val = R.Get<GameObject>(__instance, "m_scrollContainer"); if ((Object)(object)val == (Object)null) { return; } exSprite[] componentsInChildren = val.GetComponentsInChildren<exSprite>(true); foreach (exSprite val2 in componentsInChildren) { if (!((Object)(object)val2.atlas == (Object)null) && !(((Object)val2.atlas).name != "AtlasMenuMain") && val2.index >= 347 && val2.index <= 391 && !((Object)(object)((Component)val2).GetComponent<TitleWordmark>() != (Object)null)) { float x = ((exSpriteBase)val2).scale.x; TitleWordmark.AttachStatic(((Component)val2).transform, new Vector3(33f * x, -8.5f * x, -0.5f), 0.8f * x); } } } catch (Exception ex) { FurtherCore.Log.LogError((object)("Branding credits: " + ex)); } } } public class BrandingDef { public string name; public string version; public string wordmark; public string spark; public string menuPip; public string menuMote; } public enum GemCorner { Art, Cell } internal class HudTimerView : MonoBehaviour { private sealed class Item { public GameObject root; public exSprite icon; public Renderer iconR; public TextMesh text; public TextMesh shadow; public Renderer textR; public Renderer shadowR; public SpriteSheet sheet; public int shown = -1; public float alpha = -1f; public bool measured; public int tries; } private sealed class Panel { public GUIPlayer gp; public GameObject root; public readonly List<Item> items = new List<Item>(); public Bounds bounds; public bool hasBounds; public float limitRight; } private const int Players = 4; private const float LookEvery = 0.5f; private const float PausedAlpha = 0.45f; private static HudTimerView s_inst; private readonly Panel[] m_panels = new Panel[4]; private float m_nextLook; private bool m_shown; private TextMesh m_nameRef; private exSprite m_iconRef; public static void Ensure() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown if (!((Object)(object)s_inst != (Object)null)) { GameObject val = new GameObject("CrawlFurther.HudTimers"); Object.DontDestroyOnLoad((Object)val); s_inst = val.AddComponent<HudTimerView>(); } } private static bool Paused() { if (Time.timeScale <= 0f) { return true; } try { return Singleton<SystemTime>.HasInstance() && SystemTime.Paused; } catch { return false; } } private void LateUpdate() { if (!HudTimers.Any || Paused()) { if (m_shown) { HideAll(); } return; } try { if (Time.unscaledTime >= m_nextLook) { m_nextLook = Time.unscaledTime + 0.5f; Look(); } for (int i = 0; i < 4; i++) { Draw(i); } m_shown = true; } catch (Exception ex) { FurtherCore.Log.LogWarning((object)("HUD timers: " + ex.Message)); m_nextLook = Time.unscaledTime + 5f; } } private void HideAll() { m_shown = false; Panel[] panels = m_panels; foreach (Panel panel in panels) { if (panel == null) { continue; } foreach (Item item in panel.items) { Show(item, on: false); } } } private void Look() { //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) GUIPlayer[] array = (GUIPlayer[])(object)new GUIPlayer[4]; GUIPlayer[] array2 = Object.FindObjectsOfType<GUIPlayer>(); foreach (GUIPlayer val in array2) { int playerId = val.GetPlayerId(); if (playerId >= 0 && playerId < 4 && ((Component)val).gameObject.activeInHierarchy) { array[playerId] = val; } } for (int j = 0; j < 4; j++) { Panel panel = m_panels[j]; if (panel != null && (Object)(object)panel.gp != (Object)(object)array[j]) { if ((Object)(object)panel.root != (Object)null) { Object.Destroy((Object)(object)panel.root); } panel = (m_panels[j] = null); } if (panel == null && (Object)(object)array[j] != (Object)null && HudTimers.Players[j].Count > 0) { Panel[] panels = m_panels; int num = j; Panel obj = new Panel { gp = array[j] }; panel = obj; panels[num] = obj; } if (panel != null) { panel.hasBounds = Measure(panel.gp, panel.root, out panel.bounds); } } Camera val2 = Camera(); float limitRight = (((Object)(object)val2 != (Object)null) ? val2.ViewportToWorldPoint(new Vector3(1f, 0.5f, val2.nearClipPlane + 1f)).x : float.MaxValue); for (int k = 0; k < 4; k++) { Panel panel2 = m_panels[k]; if (panel2 == null || !panel2.hasBounds) { continue; } panel2.limitRight = limitRight; for (int l = 0; l < 4; l++) { if (l != k && !((Object)(object)array[l] == (Object)null)) { Panel panel3 = m_panels[l]; Bounds bounds; if (panel3 != null && panel3.hasBounds) { bounds = panel3.bounds; } else if (!Measure(array[l], null, out bounds)) { continue; } if (((Bounds)(ref bounds)).min.x > ((Bounds)(ref panel2.bounds)).center.x) { panel2.limitRight = Mathf.Min(panel2.limitRight, ((Bounds)(ref bounds)).min.x); } } } } } private Camera Camera() { Panel[] panels = m_panels; foreach (Panel panel in panels) { ScreenAlign val = ((panel != null && (Object)(object)panel.gp != (Object)null) ? ((Component)panel.gp).GetComponent<ScreenAlign>() : null); if ((Object)(object)val != (Object)null && (Object)(object)val.m_camera != (Object)null) { return val.m_camera; } } try { return Singleton<SystemLevel>.HasInstance() ? SystemLevel.GetCameraGUI() : null; } catch { return null; } } private static bool Measure(GUIPlayer gp, GameObject skip, out Bounds bounds) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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_0087: Unknown result type (might be due to invalid IL or missing references) //IL_007b: 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) bounds = default(Bounds); bool flag = false; Renderer[] componentsInChildren = ((Component)gp).GetComponentsInChildren<Renderer>(); foreach (Renderer val in componentsInChildren) { if (!val.enabled || !((Component)val).gameObject.activeInHierarchy || ((Object)(object)skip != (Object)null && ((Component)val).transform.IsChildOf(skip.transform))) { continue; } Bounds bounds2 = val.bounds; if (!(((Bounds)(ref bounds2)).size.x <= 0f) || !(((Bounds)(ref bounds2)).size.y <= 0f)) { if (!flag) { bounds = bounds2; flag = true; } else { ((Bounds)(ref bounds)).Encapsulate(bounds2); } } } return flag; } private void Draw(int id) { //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_02be: 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_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0170: 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_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_0368: Unknown result type (might be due to invalid IL or missing references) //IL_0312: 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_0215: 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_021e: 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_0244: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) Panel panel = m_panels[id]; List<HudTimers.Entry> list = HudTimers.Players[id]; if (panel == null) { return; } if ((Object)(object)panel.gp == (Object)null || !((Component)panel.gp).gameObject.activeInHierarchy || !panel.hasBounds || list.Count == 0) { foreach (Item item3 in panel.items) { Show(item3, on: false); } return; } if ((Object)(object)panel.root == (Object)null && !Build(panel)) { return; } while (panel.items.Count < list.Count) { panel.items.Add(MakeItem(panel)); } for (int i = list.Count; i < panel.items.Count; i++) { Show(panel.items[i], on: false); } float num = 0f; float num2 = 0f; float num3 = 0f; bool flag = true; Bounds bounds; for (int j = 0; j < list.Count; j++) { Item item = panel.items[j]; Fill(item, list[j]); if (!item.measured) { flag = false; continue; } bounds = item.textR.bounds; Vector3 size = ((Bounds)(ref bounds)).size; Vector3 val; if (!((Behaviour)item.icon).enabled) { val = Vector3.zero; } else { bounds = item.iconR.bounds; val = ((Bounds)(ref bounds)).size; } Vector3 val2 = val; num3 = Mathf.Max(num3, size.y * 0.25f); num = Mathf.Max(num, Mathf.Max(size.y, val2.y)); num2 = Mathf.Max(num2, val2.x + size.x); } if (!flag) { for (int k = 0; k < list.Count; k++) { Item item2 = panel.items[k]; if (item2.measured) { continue; } int measured; if (item2.root.activeSelf) { bounds = item2.textR.bounds; if (((Bounds)(ref bounds)).size.x > 0f) { if (((Behaviour)item2.icon).enabled) { bounds = item2.iconR.bounds; if (!(((Bounds)(ref bounds)).size.x > 0f)) { measured = ((++item2.tries > 10) ? 1 : 0); goto IL_027d; } } measured = 1; goto IL_027d; } } measured = 0; goto IL_027d; IL_027d: item2.measured = (byte)measured != 0; if (!item2.measured) { SetAlpha(item2, 0f); Show(item2, on: true); } } return; } num2 += num3; Bounds bounds2 = panel.bounds; float z = ((Bounds)(ref bounds2)).center.z - 0.5f; bool flag2 = ((Bounds)(ref bounds2)).max.x + num3 + num2 <= panel.limitRight - num3; for (int l = 0; l < list.Count; l++) { Item it = panel.items[l]; float x; float y; if (flag2) { x = ((Bounds)(ref bounds2)).max.x + num3; y = ((Bounds)(ref bounds2)).center.y + (float)(list.Count - 1) * 0.5f * (num + num3 * 0.5f) - (float)l * (num + num3 * 0.5f); } else { float num4 = ItemWidth(it, num3); float num5 = ((Bounds)(ref bounds2)).max.x; for (int m = 0; m < l; m++) { num5 -= ItemWidth(panel.items[m], num3) + num3; } x = num5 - num4; y = ((Bounds)(ref bounds2)).max.y + num3 + num * 0.5f; } Place(it, x, y, z); SetAlpha(it, list[l].paused ? 0.45f : 1f); Show(it, on: true); } } private static float ItemWidth(Item it, float gap) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: 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) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) float num; Bounds bounds; if (!((Behaviour)it.icon).enabled) { num = 0f; } else { bounds = it.iconR.bounds; num = ((Bounds)(ref bounds)).size.x; } float num2 = num + ((num > 0f) ? (gap * 0.5f) : 0f); bounds = it.textR.bounds; return num2 + ((Bounds)(ref bounds)).size.x; } private static void Place(Item it, float x, float y, float z) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: 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) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_009a: 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_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) float num; Bounds bounds; if (!((Behaviour)it.icon).enabled) { num = 0f; } else { bounds = it.iconR.bounds; num = ((Bounds)(ref bounds)).size.x; } float num2 = num; if (((Behaviour)it.icon).enabled) { ((Component)it.icon).transform.position = new Vector3(x + num2 * 0.5f, y, z); } float num3 = x + num2; float num4; if (!(num2 > 0f)) { num4 = 0f; } else { bounds = it.textR.bounds; num4 = ((Bounds)(ref bounds)).size.y * 0.15f; } float num5 = num3 + num4; ((Component)it.text).transform.position = new Vector3(num5, y, z); bounds = it.textR.bounds; float num6 = ((Bounds)(ref bounds)).size.y / 9f; ((Component)it.shadow).transform.position = new Vector3(num5 + num6, y - num6, z + 0.05f); } private void Fill(Item it, HudTimers.Entry e) { int num = HudTimers.Shown(e.seconds); if (num != it.shown) { it.shown = num; string text = num.ToString(); it.text.text = text; it.shadow.text = text; } if (e.icon == it.sheet) { return; } it.sheet = e.icon; bool flag = e.icon != null && (Object)(object)e.icon.atlas != (Object)null && e.icon.atlas.elements != null && e.icon.atlas.elements.Length != 0; ((Behaviour)it.icon).enabled = flag; it.iconR.enabled = flag; it.measured = false; it.tries = 0; if (flag) { SheetAnim sheetAnim = e.icon.Anim("Idle"); int num2 = ((sheetAnim != null && sheetAnim.frames != null && sheetAnim.frames.Length != 0) ? sheetAnim.frames[0] : 0); it.icon.SetSprite(e.icon.atlas, num2, false); if ((Object)(object)e.icon.atlas.material != (Object)null) { it.iconR.sharedMaterial = e.icon.atlas.material; } } } private static void SetAlpha(Item it, float a) { //IL_0032: 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_0085: Unknown result type (might be due to invalid IL or missing references) if (!(Mathf.Abs(a - it.alpha) < 0.004f)) { it.alpha = a; it.text.color = new Color(1f, 0.96f, 0.86f, a); it.shadow.color = new Color(0f, 0f, 0f, a * 0.85f); if (((Behaviour)it.icon).enabled) { it.icon.color = new Color(1f, 1f, 1f, a); } } } private static void Show(Item it, bool on) { if (it.root.activeSelf != on) { it.root.SetActive(on); } } private bool Build(Panel p) { //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Expected O, but got Unknown m_nameRef = R.Get<TextMesh>(p.gp, "m_name"); GameObject val = R.Get<GameObject>(p.gp, "m_goldIcon"); m_iconRef = (((Object)(object)val != (Object)null) ? val.GetComponentInChildren<exSprite>(true) : null); if ((Object)(object)m_iconRef == (Object)null) { m_iconRef = R.Get<exSprite>(p.gp, "m_portrait"); } if ((Object)(object)m_nameRef == (Object)null || (Object)(object)m_nameRef.font == (Object)null) { return false; } p.root = new GameObject("CrawlFurther.HudTimers"); p.root.layer = ((Component)p.gp).gameObject.layer; p.root.transform.SetParent(((Component)p.gp).transform, false); return true; } private Item MakeItem(Panel p) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Expected O, but got Unknown //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) Item item = new Item { root = new GameObject("Countdown") }; item.root.layer = p.root.layer; item.root.transform.SetParent(p.root.transform, false); Renderer component = ((Component)m_nameRef).GetComponent<Renderer>(); item.shadow = MakeText(item.root.transform, "Shadow", component, 4, out item.shadowR); item.text = MakeText(item.root.transform, "Text", component, 5, out item.textR); GameObject val = new GameObject("Picture"); val.layer = item.root.layer; val.transform.SetParent(item.root.transform, false); val.AddComponent<MeshFilter>(); item.iconR = (Renderer)(object)val.AddComponent<MeshRenderer>(); item.icon = val.AddComponent<exSprite>(); ((exPlane)item.icon).anchor = (Anchor)4; if ((Object)(object)m_iconRef != (Object)null) { MatchScale(val.transform, ((Component)m_iconRef).transform); ((exSpriteBase)item.icon).scale = ((exSpriteBase)m_iconRef).scale; ((exSpriteBase)item.icon).ppfScale = ((exSpriteBase)m_iconRef).ppfScale; Camera renderCamera = ((exPlane)m_iconRef).renderCamera; if ((Object)(object)renderCamera != (Object)null) { ((exPlane)item.icon).renderCamera = renderCamera; } } ((Behaviour)item.icon).enabled = false; item.iconR.enabled = false; item.root.SetActive(false); return item; } private TextMesh MakeText(Transform parent, string name, Renderer like, int sortAdd, out Renderer rend) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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) GameObject val = new GameObject(name) { layer = ((Component)parent).gameObject.layer }; val.transform.SetParent(parent, false); MatchScale(val.transform, ((Component)m_nameRef).transform); MeshRenderer val2 = val.AddComponent<MeshRenderer>(); TextMesh obj = val.AddComponent<TextMesh>(); obj.font = m_nameRef.font; obj.fontSize = m_nameRef.fontSize; obj.characterSize = m_nameRef.characterSize; obj.anchor = (TextAnchor)3; obj.alignment = (TextAlignment)0; obj.richText = false; ((Renderer)val2).sharedMaterial = (((Object)(object)like != (Object)null && (Object)(object)like.sharedMaterial != (Object)null) ? like.sharedMaterial : m_nameRef.font.material); if ((Object)(object)like != (Object)null) { ((Renderer)val2).sortingLayerID = like.sortingLayerID; ((Renderer)val2).sortingOrder = like.sortingOrder + sortAdd; } ((Renderer)val2).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)val2).receiveShadows = false; rend = (Renderer)(object)val2; return obj; } private static void MatchScale(Transform t, Transform like) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: 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) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: 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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) Vector3 lossyScale = like.lossyScale; Vector3 val = (((Object)(object)t.parent != (Object)null) ? t.parent.lossyScale : Vector3.one); t.localScale = new Vector3(Div(lossyScale.x, val.x), Div(lossyScale.y, val.y), 1f); } private static float Div(float a, float b) { if (!(Mathf.Abs(b) > 0.0001f)) { return 1f; } return Mathf.Abs(a / b); } } public static class HudTimers { internal sealed class Entry { public string key; public float seconds; public SpriteSheet icon; public bool paused; } internal static readonly List<Entry>[] Players = new List<Entry>[4] { new List<Entry>(), new List<Entry>(), new List<Entry>(), new List<Entry>() }; internal static int Version; public static bool Any { get { List<Entry>[] players = Players; for (int i = 0; i < players.Length; i++) { if (players[i].Count > 0) { return true; } } return false; } } public static void Set(int playerId, string key, float secondsLeft, SpriteSheet icon = null, bool paused = false) { if (playerId < 0 || playerId >= Players.Length || string.IsNullOrEmpty(key)) { return; } if (secondsLeft <= 0f) { Clear(playerId, key); return; } List<Entry> list = Players[playerId]; Entry entry = list.Find((Entry x) => x.key == key); if (entry == null) { entry = new Entry { key = key }; list.Add(entry); Version++; } if (entry.icon != icon || entry.paused != paused || Shown(entry.seconds) != Shown(secondsLeft)) { Version++; } entry.seconds = secondsLeft; entry.icon = icon; entry.paused = paused; HudTimerView.Ensure(); } public static void Clear(int playerId, string key) { if (playerId >= 0 && playerId < Players.Length && Players[playerId].RemoveAll((Entry x) => x.key == key) > 0) { Version++; } } public static void Clear(int playerId) { if (playerId >= 0 && playerId < Players.Length && Players[playerId].Count != 0) { Players[playerId].Clear(); Version++; } } public static void ClearAll() { for (int i = 0; i < Players.Length; i++) { Clear(i); } } internal static int Shown(float seconds) { return Mathf.CeilToInt(seconds); } } public static class LibraryEntries { private class Info { public string name; public string desc; public Info(string n, string d) { name = n; desc = d; } } private struct SavedRec { public bool found; public bool isNew; public int high; public int last; } private class PageInfo { public VaultCategory cat; public VaultPage page; public string text; } private class Extra { public GameObject prefab; public string name; public string desc; public exSpriteAnimClip portrait; public Vector2 offset; public bool obj; } public const string OldTag = " (MOD)"; private static SystemLibrary s_registeredInto; private static readonly HashSet<LibraryEntry> s_mod = new HashSet<LibraryEntry>(); private static readonly Dictionary<string, LibraryEntry> s_keys = new Dictionary<string, LibraryEntry>(); private static readonly HashSet<GameObject> s_summoned = new HashSet<GameObject>(); private static readonly HashSet<LibraryEntry> s_challenge = new HashSet<LibraryEntry>(); private static readonly Dictionary<string, Dictionary<string, SavedRec>> s_pending = new Dictionary<string, Dictionary<string, SavedRec>>(); private static List<LibraryEntry> s_lists; private static Dictionary<string, LibraryEntry> s_dict; private static List<string> s_users; private static SystemLibrary s_lib; private static GameObject s_vaultHolder; public const string NoChallengeText = "No challenge available"; private static readonly Dictionary<VaultCategory, List<LibraryEntry>> s_pages = new Dictionary<VaultCategory, List<LibraryEntry>>(); private static readonly Dictionary<LibraryEntry, PageInfo> s_pageInfo = new Dictionary<LibraryEntry, PageInfo>(); private static readonly List<LibraryEntry> s_none = new List<LibraryEntry>(); private static readonly List<Extra> s_extra = new List<Extra>(); public static readonly List<LibraryEntry> SecretList = new List<LibraryEntry>(); private static readonly Dictionary<LibraryEntry, string> s_secretOf = new Dictionary<LibraryEntry, string>(); private static readonly Dictionary<string, LibraryEntry> s_pageOf = new Dictionary<string, LibraryEntry>(); private static readonly Dictionary<string, exSpriteAnimClip> s_secretClip = new Dictionary<string, exSpriteAnimClip>(); private static MethodInfo s_getStats; private static FieldInfo s_fRatio; private static FieldInfo s_fRatioW; private static FieldInfo s_fRatioC; private static FieldInfo s_fCountC; public static bool HasModEntries => s_mod.Count > 0; public static int ExtraObjects { get { int num = 0; foreach (Extra item in s_extra) { if (item.obj) { num++; } } return num; } } public static bool IsMod(LibraryEntry e) { if (e != null) { return s_mod.Contains(e); } return false; } public static bool IsSummoned(GameObject prefab) { if ((Object)(object)prefab != (Object)null) { return s_summoned.Contains(prefab); } return false; } public static bool HasChallenge(LibraryEntry e) { if (e != null) { return s_challenge.Contains(e); } return false; } internal static List<KeyValuePair<int, string>> NoChallengeLines() { return new List<KeyValuePair<int, string>> { new KeyValuePair<int, string>(2, "No challenge available") }; } public static bool NoChallenge(LibraryEntry e) { if (IsMod(e) && e is LibraryEntryMonster) { return !s_challenge.Contains(e); } return false; } public static void Register() { if (!Singleton<SystemLibrary>.HasInstance()) { FurtherCore.Log.LogWarning((object)"Library: SystemLibrary not up yet; entries will be added when the vault opens"); } else { EnsureRegistered(); } } public static void EnsureRegistered() { if (!ContentManager.Registered || !Singleton<SystemLibrary>.HasInstance()) { return; } SystemLibrary instance = Singleton<SystemLibrary>.Instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance == (Object)(object)s_registeredInto) { return; } s_registeredInto = instance; s_mod.Clear(); s_keys.Clear(); s_summoned.Clear(); s_challenge.Clear(); s_pages.Clear(); s_pageInfo.Clear(); SecretList.Clear(); s_secretOf.Clear(); s_pageOf.Clear(); try { AddAll(instance); } catch (Exception ex) { FurtherCore.Log.LogError((object)("Library entries failed: " + ex)); } } private static void AddAll(SystemLibrary lib) { //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Expected O, but got Unknown //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Expected O, but got Unknown //IL_02c3: Unknown result type (might be due to invalid IL or missing references) //IL_02ca: Expected O, but got Unknown //IL_031a: Unknown result type (might be due to invalid IL or missing references) //IL_031f: Unknown result type (might be due to invalid IL or missing references) //IL_032c: Unknown result type (might be due to invalid IL or missing references) //IL_0338: Expected O, but got Unknown //IL_033a: Unknown result type (might be due to invalid IL or missing references) //IL_033f: Unknown result type (might be due to invalid IL or missing references) //IL_034c: Unknown result type (might be due to invalid IL or missing references) //IL_035f: Expected O, but got Unknown List<LibraryEntry> list = R.Get<List<LibraryEntry>>(lib, "m_entryList"); Dictionary<string, LibraryEntry> dictionary = R.Get<Dictionary<string, LibraryEntry>>(lib, "m_entries"); if (list == null || dictionary == null || lib.m_monsters == null || lib.m_items == null || lib.m_weapons == null) { FurtherCore.Log.LogError((object)"Library: SystemLibrary has not built its lists; no mod entries added"); return; } List<string> list2 = KnownUsers(lib); int num = 0; int num2 = 0; int num3 = 0; HashSet<GameObject> hashSet = Reachable(); foreach (string item in MonsterOrder()) { Player val = MonsterFactory.Built[item]; if ((Object)(object)val == (Object)null) { continue; } Info info = Lookup(item); LibraryEntryMonster val2 = new LibraryEntryMonster { m_prefab = ((Component)val).gameObject, m_type = string.Empty, m_name = info.name, m_description = info.name + "\n" + info.desc, m_portraitOffset = PortraitOffset(val), m_startFound = false, m_targetScore = 9999 }; if (Add(list, dictionary, (LibraryEntry)(object)val2, list2)) { lib.m_monsters.Add(val2); if (!hashSet.Contains(((Component)val).gameObject)) { s_summoned.Add(((Component)val).gameObject); } num++; } } foreach (KeyValuePair<string, Powerup> item2 in ItemRegistry.Items) { Powerup value = item2.Value; if (!((Object)(object)value == (Object)null)) { string text = Strip(value.GetDisplayName()); if (string.IsNullOrEmpty(text)) { text = Words(item2.Key); } LibraryEntry val3 = new LibraryEntry { m_prefab = ((Component)value).gameObject, m_type = string.Empty, m_name = text, m_description = Strip(value.GetDescription()), m_startFound = false }; if (Add(list, dictionary, val3, list2)) { lib.m_items.Add(val3); num2++; } } } foreach (KeyValuePair<string, Weapon> weapon in ItemRegistry.Weapons) { Weapon value2 = weapon.Value; if (!((Object)(object)value2 == (Object)null)) { string text2 = ((value2.m_combos != null && value2.m_combos.Count > 0) ? value2.m_combos[0].m_name : string.Empty); string text3 = Strip((!string.IsNullOrEmpty(text2)) ? text2 : value2.m_weaponName); if (string.IsNullOrEmpty(text3)) { text3 = Words(weapon.Key); } LibraryEntry val4 = new LibraryEntry(); val4.m_prefab = ((Component)value2).gameObject; val4.m_type = text2 ?? string.Empty; val4.m_name = text3; val4.m_description = string.Empty; val4.m_startFound = false; val4.m_otherPrefabs = (LibraryEntryAdditional[])(object)(string.IsNullOrEmpty(text2) ? null : new LibraryEntryAdditional[2] { new LibraryEntryAdditional { m_prefab = ((Component)value2).gameObject, m_type = string.Empty }, new LibraryEntryAdditional { m_prefab = ((Component)value2).gameObject, m_type = text2 + " (MOD)" } }); LibraryEntry val5 = val4; if (Add(list, dictionary, val5, list2)) { lib.m_weapons.Add(val5); num3++; } } } int num4 = 0; try { num4 = AddPages(list, dictionary, list2); } catch (Exception ex) { FurtherCore.Log.LogError((object)("Library category pages: " + ex)); } s_lists = list; s_dict = dictionary; s_users = list2; s_lib = lib; foreach (Extra item3 in s_extra) { try { AddExtra(lib, item3); } catch (Exception ex2) { FurtherCore.Log.LogError((object)("Library extra page " + item3.name + ": " + ex2.Message)); } } try { SyncSecrets(); } catch (Exception ex3) { FurtherCore.Log.LogError((object)("Library SECRETS entries: " + ex3)); } FurtherCore.Log.LogInfo((object)("Library: " + SecretList.Count + " secret pages (" + Secrets.All.Count + " registered)")); ApplyPending(); try { RefreshChallenges(); } catch (Exception ex4) { FurtherCore.Log.LogError((object)("Library challenges: " + ex4)); } try { SystemLibrary.UpdateHasNewEntries(); } catch (Exception ex5) { FurtherCore.Log.LogWarning((object)("Library: UpdateHasNewEntries: " + ex5.Message)); } FurtherCore.Log.LogInfo((object)("Library: added " + num + " monsters (" + s_summoned.Count + " summoned-only), " + num2 + " items, " + num3 + " weapons, " + num4 + " category pages for " + list2.Count + " user(s). Vanilla: " + (lib.m_monsters.Count - num) + "/" + (lib.m_items.Count - num2) + "/" + (lib.m_weapons.Count - num3))); } public static string Key(GameObject obj, string type) { string text = (((Object)(object)obj != (Object)null) ? ((Object)obj).name : null); if (text != null && text.EndsWith(")") && text.Length >= 7) { text = text.Substring(0, text.Length - 7); } if (!string.IsNullOrEmpty(type)) { return (text ?? string.Empty) + type; } return text ?? string.Empty; } private static bool Add(List<LibraryEntry> list, Dictionary<string, LibraryEntry> dict, LibraryEntry e, List<string> users) { string text = Key(e.m_prefab, e.m_type); if (string.IsNullOrEmpty(text) || dict.ContainsKey(text)) { FurtherCore.Log.LogWarning((object)("Library: skipped '" + text + "' (empty or already in the library)")); return false; } foreach (string user in users) { e.CreateSyncData(user); } dict.Add(text, e); s_keys[text] = e; if (e.m_otherPrefabs != null) { LibraryEntryAdditional[] otherPrefabs = e.m_otherPrefabs; foreach (LibraryEntryAdditional val in otherPrefabs) { string text2 = Key(val.m_prefab, val.m_type); if (!string.IsNullOrEmpty(text2) && !dict.ContainsKey(text2)) { dict.Add(text2, e); s_keys[text2] = e; } } } list.Add(e); s_mod.Add(e); return true; } private static List<string> KnownUsers(SystemLibrary lib) { List<string> list = new List<string>(); try { if (Singleton<SystemUsers>.HasInstance()) { foreach (UserData user in Singleton<SystemUsers>.Get.GetUsers()) { if (user != null && !string.IsNullOrEmpty(user.GetUid()) && !list.Contains(user.GetUid())) { list.Add(user.GetUid()); } } } if (R.Get<object>(lib, "m_usersCompletionStats") is IDictionary dictionary) { foreach (object key in dictionary.Keys) { string text = key as string; if (!string.IsNullOrEmpty(text) && !list.Contains(text)) { list.Add(text); } } } foreach (string key2 in s_pending.Keys) { if (!list.Contains(key2)) { list.Add(key2); } } } catch (Exception ex) { FurtherCore.Log.LogWarning((object)("Library: user scan: " + ex.Message)); } return list; } private static HashSet<GameObject> Reachable() { HashSet<GameObject> hashSet = new HashSet<GameObject>(); Stack<Player> stack = new Stack<Player>(); try { List<Deity> deities = SystemDeity.GetDeities(); if (deities != null) { foreach (Deity item in deities) { GameObject[] array = ((item != null) ? item.GetStartingMonsters() : null); if (array == null) { continue; } GameObject[] array2 = array; foreach (GameObject val in array2) { if ((Object)(object)val != (Object)null) { Player component = val.GetComponent<Player>(); if ((Object)(object)component != (Object)null) { stack.Push(component); } } } } } } catch (Exception ex) { FurtherCore.Log.LogWarning((object)("Library: roster scan: " + ex.Message)); } while (stack.Count > 0) { Player val2 = stack.Pop(); if ((Object)(object)val2 == (Object)null || !hashSet.Add(((Component)val2).gameObject)) { continue; } Player[] evolveTo = val2.GetEvolveTo(); if (evolveTo == null) { continue; } Player[] array3 = evolveTo; foreach (Player val3 in array3) { if ((Object)(object)val3 != (Object)null && !hashSet.Contains(((Component)val3).gameObject)) { stack.Push(val3); } } } return hashSet; } private static HashSet<GameObject> Playable() { HashSet<GameObject> hashSet = Reachable(); Stack<Player> stack = new Stack<Player>(); foreach (SecretDef item in Secrets.All) { Player val = SecretMonster(item); if ((Object)(object)val != (Object)null) { stack.Push(val); } } while (stack.Count > 0) { Player val2 = stack.Pop(); if ((Object)(object)val2 == (Object)null || !hashSet.Add(((Component)val2).gameObject)) { continue; } Player[] evolveTo = val2.GetEvolveTo(); if (evolveTo == null) { continue; } Player[] array = evolveTo; foreach (Player val3 in array) { if ((Object)(object)val3 != (Object)null && !hashSet.Contains(((Component)val3).gameObject)) { stack.Push(val3); } } } return hashSet; } public static Player SecretMonster(SecretDef se) { if (se == null || string.IsNullOrEmpty(se.id)) { return null; } bool flag = se.id.StartsWith("Mod", StringComparison.Ordinal); if (!se.monster && !flag) { return null; } if (!MonsterFactory.Built.TryGetValue(flag ? se.id.Substring(3) : se.id, out var value)) { return null; } return value; } public static void RefreshChallenges() { if ((Object)(object)s_lib == (Object)null) { return; } HashSet<GameObject> hashSet = Playable(); s_challenge.Clear(); foreach (LibraryEntryMonster monster in s_lib.m_monsters) { if (monster != null && s_mod.Contains((LibraryEntry)(object)monster) && !((Object)(object)((LibraryEntry)monster).m_prefab == (Object)null)) { int num = Challenges.GoalOf(((LibraryEntry)monster).m_prefab.GetComponent<Player>(), hashSet.Contains(((LibraryEntry)monster).m_prefab)); monster.m_targetScore = ((num > 0) ? num : 9999); if (num > 0) { s_challenge.Add((LibraryEntry)(object)monster); } } } } internal static int ModChallengesPassed() { int num = 0; foreach (LibraryEntry item in s_challenge) { LibraryEntryMonster val = (LibraryEntryMonster)(object)((item is LibraryEntryMonster) ? item : null); if (val != null && val.GetHighScore(string.Empty) >= val.m_targetScore) { num++; } } return num; } internal static List<KeyValuePair<int, string>> ChallengeLines(MenuLibrary lib, LibraryEntryMonster e) { List<KeyValuePair<int, string>> list = new List<KeyValuePair<int, string>>(); if ((Object)(object)lib == (Object)null || !HasChallenge((LibraryEntry)(object)e)) { return list; } int highScore = e.GetHighScore(string.Empty); bool flag = (!Singleton<SystemDebug>.HasInstance() || !Singleton<SystemDebug>.Get.m_challengeModeHidePassedFeature) && highScore > 0 && highScore >= e.m_targetScore; string text; if (highScore == 0) { text = R.Get<string>(lib, "m_stringHeroChallengeNotAttempted"); } else { string text2 = R.Get<string>(lib, "m_stringHeroChallenge") ?? string.Empty; try { text = string.Format(text2, e.GetLastScore(), highScore); } catch (FormatException) { text = text2; } } List<string> list2 = new List<string>(); string[] array = (text ?? string.Empty).Replace("\r", string.Empty).Split(new char[1] { '\n' }); foreach (string text3 in array) { if (text3.Trim().Length > 0) { list2.Add(text3.Trim()); } } if (list2.Count > 0) { list.Add(new KeyValuePair<int, string>(2 + list2.Count - 1, list2[list2.Count - 1])); } List<string> list3 = Headings(R.Get<GUIText>(lib, "m_textDescriptionMonster")); if (flag) { foreach (string item in Headings(R.Get<GUIText>(lib, "m_textDescriptionMonsterPassed"))) { if (!list3.Contains(item)) { list.Add(new KeyValuePair<int, string>(1, item)); } } } for (int j = 0; j < list2.Count - 1; j++) { list.Add(new KeyValuePair<int, string>(2 + j, list2[j])); } if (list3.Count > 0) { list.Add(new KeyValuePair<int, string>(0, list3[0])); } return list; } private static List<string> Headings(GUIText holder) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) List<KeyValuePair<float, string>> list = new List<KeyValuePair<float, string>>(); if ((Object)(object)holder != (Object)null) { TextMesh[] componentsInChildren = ((Component)holder).GetComponentsInChildren<TextMesh>(true); foreach (TextMesh val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).gameObject == (Object)(object)((Component)holder).gameObject) && !string.IsNullOrEmpty(val.text)) { float y = ((Component)holder).transform.InverseTransformPoint(((Component)val).transform.position).y; list.Add(new KeyValuePair<float, string>(y, val.text.Replace("\r", string.Empty).Trim())); } } } list.Sort((KeyValuePair<float, string> a, KeyValuePair<float, string> b) => b.Key.CompareTo(a.Key)); List<string> list2 = new List<string>(); foreach (KeyValuePair<float, string> item in list) { if (item.Value.Length > 0) { list2.Add(item.Value); } } return list2; } public static void ChallengeSelfCheck(Action<string> bad, Action<string> note) { string[] array = new string[7] { "m_stringHeroChallenge", "m_stringHeroChallengeNotAttempted", "m_stringMonstersCategorySummary", "m_textDescriptionMonster", "m_textDescriptionMonsterPassed", "m_selectedCategory", "m_menuItemsMonster" }; foreach (string text in array) { if ((object)AccessTools.Field(typeof(MenuLibrary), text) == null) { bad("MenuLibrary." + text + " not found (mod monster challenge pages)"); } } if ((object)AccessTools.Method(typeof(MenuLibrary), "StartChallenge", (Type[])null, (Type[])null) == null) { bad("MenuLibrary.StartChallenge not found"); } if ((object)AccessTools.Method(typeof(AchievementBase), "Unlock", (Type[])null, (Type[])null) == null) { bad("AchievementBase.Unlock not found (no achievements in mod challenges)"); } if ((object)AccessTools.Field(typeof(Player), "m_evolveCost") == null) { bad("Player.m_evolveCost not found (challenge goals by cost)"); } if ((Object)(object)s_lib == (Object)null || !Singleton<SystemLibrary>.HasInstance()) { note("the vault is not built yet: challenges are given when it is"); return; } HashSet<GameObject> hashSet = Playable(); int num = 0; int num2 = 0; SortedDictionary<int, int> sortedDictionary = new SortedDictionary<int, int>(); foreach (KeyValuePair<string, Player> item in MonsterFactory.Built) { Player value = item.Value; if ((Object)(object)value == (Object)null) { continue; } string name = ((Object)((Component)value).gameObject).name; if (!name.StartsWith("Mod", StringComparison.Ordinal)) { bad(name + ": prefab name does not start with Mod (its save key would not be a mod key)"); } LibraryEntryMonster monsterEntry = SystemLibrary.GetMonsterEntry(((Component)value).gameObject); if (monsterEntry == null) { bad(name + ": no vault entry, so no challenge"); continue; } if (!IsMod((LibraryEntry)(object)monsterEntry)) { bad(name + ": its vault entry is not a mod entry"); } if ((Object)(object)((LibraryEntry)monsterEntry).m_prefab == (Object)null || (Object)(object)((LibraryEntry)monsterEntry).m_prefab.GetComponent<Player>() != (Object)(object)value) { bad(name + ": its vault entry does not resolve to its prefab"); } if ((object)SystemLibrary.GetLibraryEntry(((Component)value).gameObject, (string)null) != monsterEntry) { bad(name + ": its save key does not find its vault entry"); } bool flag = Challenges.GoalOf(value, hashSet.Contains(((Component)value).gameObject)) > 0; if (flag != HasChallenge((LibraryEntry)(object)monsterEntry)) { bad(name + (flag ? ": should have a challenge but has none" : ": has a challenge it should not have")); } if (HasChallenge((LibraryEntry)(object)monsterEntry)) { num++; if (monsterEntry.m_targetScore < 1 || monsterEntry.m_targetScore > 30) { bad(name + ": challenge goal " + monsterEntry.m_targetScore + " is out of range"); } sortedDictionary.TryGetValue(monsterEntry.m_targetScore, out var value2); sortedDictionary[monsterEntry.m_targetScore] = value2 + 1; } else { num2++; if (monsterEntry.m_targetScore != 9999) { bad(name + ": no challenge, but its goal is " + monsterEntry.m_targetScore); } } } List<string> list = new List<string>(); foreach (KeyValuePair<int, int> item2 in sortedDictionary) { list.Add("level " + item2.Key + " x" + item2.Value); } note(num + " mod monsters have a challenge (" + string.Join(", ", list.ToArray()) + "), " + num2 + " have none (minions and blobs)"); } private static List<string> MonsterOrder() { List<string> list = new List<string>(); HashSet<string> hashSet = new HashSet<string>(); string text = null; foreach (Vault.MonsterLine monsterLine in Vault.MonsterLines) { string text2 = GroupOf(monsterLine.id); if (text2 != text) { if (text != null) { AddFromTips(list, hashSet, text); } text = text2; } if (MonsterFactory.Built.ContainsKey(monsterLine.id) && hashSet.Add(monsterLine.id)) { list.Add(monsterLine.id); } } if (text != null) { AddFromTips(list, hashSet, text); } AddFromTips(list, hashSet, null); foreach (string key in MonsterFactory.Built.Keys) { if (hashSet.Add(key)) { list.Add(key); } } return list; } private static string GroupOf(string id) { if (!TipRegistry.Group.TryGetValue("Mod" + id, out var value)) { return null; } return value; } private static void AddFromTips(List<string> order, HashSet<string> seen, string group) { foreach (string item in TipRegistry.VaultOrder) { if (item != null && item.StartsWith("Mod", StringComparison.Ordinal) && (group == null || (TipRegistry.Group.TryGetValue(item, out var value) && !(value != group)))) { string text = item.Substring(3); if (MonsterFactory.Built.ContainsKey(text) && seen.Add(text)) { order.Add(text); } } } } private static Info Lookup(string id) { foreach (Vault.MonsterLine monsterLine in Vault.MonsterLines) { if (monsterLine.id == id) { return new Info(monsterLine.name, monsterLine.line); } } VaultRegistry.Entry entry = Registered("Monsters", id); if (entry != null && !string.IsNullOrEmpty(entry.name)) { return new Info(entry.name, entry.text ?? string.Empty); } if (TipRegistry.Vault.TryGetValue("Mod" + id, out var value) && !string.IsNullOrEmpty(value.Key)) { return new Info(value.Key, value.Value); } if (TipRegistry.TryGet("Mod" + id, out var tip) && !string.IsNullOrEmpty(tip.name)) { FurtherCore.Log.LogWarning((object)("Library: no vault text for " + id + ", using its monster tip")); string d = tip.attack + ((string.IsNullOrEmpty(tip.special) || tip.special.StartsWith("none")) ? "" : (". " + tip.special)); return new Info(tip.name, d); } FurtherCore.Log.LogWarning((object)("Library: no vault text for " + id)); return new Info(Words(id), string.Empty); } public static string PictureAnim(SpriteSheet sh) { if (sh == null) { return null; } string[] array = new string[3] { "Portrait", "Vault", "Idle" }; foreach (string text in array) { if (sh.Has(text)) { return text; } } return null; } public static void MonsterInfo(string id, out string name, out string text) { Info info = Lookup(id); name = info.name; text = info.desc; } private static VaultRegistry.Entry Registered(string category, string id) { foreach (VaultRegistry.Entry entry in VaultRegistry.Entries) { if (entry != null && entry.category == category && (entry.id == id || entry.id == "Mod" + id)) { return entry; } } return null; } public static List<LibraryEntry> EntriesOf(VaultCategory c) { if (c == null) { return s_none; } if (c.secrets) { return SecretList; } if (!s_pages.TryGetValue(c, out var value)) { return s_none; } return value; } public static List<KeyValuePair<VaultPage, LibraryEntry>> PagesOf(VaultCategory c) { List<KeyValuePair<VaultPage, LibraryEntry>> list = new List<KeyValuePair<VaultPage, LibraryEntry>>(); foreach (LibraryEntry item in EntriesOf(c)) { if (s_pageInfo.TryGetValue(item, out var value)) { list.Add(new KeyValuePair<VaultPage, LibraryEntry>(value.page, item)); } } return list; } private static int AddPages(List<LibraryEntry> list, Dictionary<string, LibraryEntry> dict, List<string> users) { int num = 0; foreach (VaultCategory category in Vault.Categories) { if (category.secrets || category.pages == null) { continue; } List<LibraryEntry> list2 = new List<LibraryEntry>(); s_pages[category] = list2; HashSet<string> names = new HashSet<string>(StringComparer.OrdinalIgnoreCase); IEnumerable<VaultPage> enumerable; try { enumerable = category.pages(); } catch (Exception ex) { FurtherCore.Log.LogError((object)("Vault " + category.label + " pages: " + ex)); continue; } if (enumerable == null) { continue; } foreach (VaultPage item in enumerable) { LibraryEntry val = AddPage(list, dict, users, names, category, item); if (val != null) { list2.Add(val); num++; } } } return num; } private static LibraryEntry AddPage(List<LibraryEntry> list, Dictionary<string, LibraryEntry> dict, List<string> users, HashSet<string> names, VaultCategory cat, VaultPage p) { //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_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Expected O, but got Unknown if (p == null || string.IsNullOrEmpty(p.id) || string.IsNullOrEmpty(p.name) || !names.Add(p.name)) { return null; } GameObject val = Holder(KeyName("ModVault" + p.kind, p.id)); LibraryEntry val2 = new LibraryEntry { m_prefab = val, m_type = string.Empty, m_name = p.name, m_description = (p.text ?? string.Empty), m_portrait = PageClip(p.art, "ModVault_" + ((Object)val).name), m_startFound = true }; if (!Add(list, dict, val2, users)) { return null; } s_pageInfo[val2] = new PageInfo { cat = cat, page = p, text = val2.m_description }; return val2; } private static string KeyName(string prefix, string id) { StringBuilder stringBuilder = new StringBuilder(prefix); foreach (char c in id) { if (char.IsLetterOrDigit(c)) { stringBuilder.Append(c); } } return stringBuilder.ToString(); } private static GameObject Holder(string name) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown if ((Object)(object)s_vaultHolder == (Object)null) { s_vaultHolder = new GameObject("CrawlMod_VaultEntries"); s_vaultHolder.SetActive(false); Object.DontDestroyOnLoad((Object)(object)s_vaultHolder); } GameObject val = new GameObject(name); val.transform.SetParent(s_vaultHolder.transform, false); return val; } private static exSpriteAnimClip PageClip(string art, string clipName) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) SpriteSheet spriteSheet = (string.IsNullOrEmpty(art) ? null : SpriteSheets.Get(art)); if (spriteSheet == null || (Object)(object)spriteSheet.atlas == (Object)null || (Object)(object)spriteSheet.atlas.texture == (Object)null) { return null; } string text = PictureAnim(spriteSheet); exSpriteAnimClip val = ((text != null) ? SpriteSheets.MakeClip(spriteSheet, text, null, clipName) : null); if ((Object)(object)val != (Object)null) { val.wrapMode = (WrapMode)2; } return val; } public static bool IsLocked(LibraryEntry e) { if (e == null || !s_pageInfo.TryGetValue(e, out var value)) { return false; } if (value.page.locked != null) { try { return value.page.locked(); } catch { return false; } } if (value.page.unlock != null) { return !Unlocks.IsUnlocked(value.page.unlock); } return false; } public static void RefreshPages(VaultCategory c) { foreach (LibraryEntry item in EntriesOf(c)) { if (s_pageInfo.TryGetValue(item, out var value)) { if (!VaultGrid.Alive(item.m_portrait)) { item.m_portrait = PageClip(value.page.art, "ModVault_" + value.page.kind + value.page.id); } string text = value.text; if (IsLocked(item) && value.page.unlock != null) { UnlockDef unlockDef = Unlocks.Find(value.page.unlock); text = "LOCKED" + ((unlockDef != null && !string.IsNullOrEmpty(unlockDef.title)) ? (": " + unlockDef.title) : "") + "\n" + Unlocks.ProgressText(value.page.unlock) + "\n" + text; } item.m_description = text; } } } public static bool HasNew(VaultCategory c) { if (c != null && c.secrets) { return SecretsHaveNew(); } try { foreach (LibraryEntry item in EntriesOf(c)) { if (item.IsNew(string.Empty)) { return true; } } } catch { } return false; } public static void Se