Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ChallengingUnlocks v1.0.7
ChallengingUnlocks.dll
Decompiled 4 hours agousing System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using EnemiesReturns.ModdedEntityStates.Judgement.Mission; using EntityStates; using EntityStates.Captain.Weapon; using EntityStates.TimedChest; using EntityStates.VoidSurvivor.CorruptMode; using HG.Reflection; using HarmonyLib; using RoR2; using RoR2.Achievements; using RoR2.ContentManagement; using RoR2.Projectile; using RoR2.Skills; using RoR2.Stats; using RoR2.UI; using UnityEngine; using UnityEngine.Networking; [assembly: OptIn] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyVersion("0.0.0.0")] namespace ChallengingUnlocks; [BepInPlugin("binma.challengingunlocks", "Challenging Unlocks", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public const string Guid = "binma.challengingunlocks"; internal static ManualLogSource Log; internal static ConfigEntry<bool> AnointedEnabled; internal static readonly Dictionary<string, UnlockableDef> Unlockables = new Dictionary<string, UnlockableDef>(); internal static readonly Dictionary<string, string> SkinToAchievement = new Dictionary<string, string>(); internal static readonly Dictionary<string, string> Tokens = new Dictionary<string, string>(); internal static readonly Dictionary<string, string> JudgementBodies = new Dictionary<string, string>(); internal static readonly Dictionary<string, string> VoidRunBodies = new Dictionary<string, string>(); internal static readonly Dictionary<string, string> NoirBodies = new Dictionary<string, string>(); internal static event Action<CharacterMaster> OnSeedRevive; internal static event Action OnVoidRunComplete; internal static void RaiseSeedRevive(CharacterMaster m) { Plugin.OnSeedRevive?.Invoke(m); } internal static void RaiseVoidRunComplete() { Plugin.OnVoidRunComplete?.Invoke(); } internal static void Define(string id, string name, string desc, params string[] skinTokens) { UnlockableDef val = ScriptableObject.CreateInstance<UnlockableDef>(); val.cachedName = "Skins.Binma." + id; val.nameToken = ((skinTokens.Length <= 0) ? "" : skinTokens[0]); Unlockables[id] = val; foreach (string key in skinTokens) { SkinToAchievement[key] = id; } string text = id.ToUpperInvariant(); Tokens["ACHIEVEMENT_" + text + "_NAME"] = name; Tokens["ACHIEVEMENT_" + text + "_DESCRIPTION"] = desc; } private void Awake() { //IL_05bb: Unknown result type (might be due to invalid IL or missing references) //IL_05c5: Expected O, but got Unknown //IL_0605: Unknown result type (might be due to invalid IL or missing references) //IL_060b: Expected O, but got Unknown //IL_065f: Unknown result type (might be due to invalid IL or missing references) //IL_0674: Unknown result type (might be due to invalid IL or missing references) //IL_0681: Expected O, but got Unknown //IL_0681: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; AnointedEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("EnemiesReturns", "Enable Anointed Skins", false, "EnemiesReturns' generated Anointed skins. Off by default. This mod controls EnemiesReturns' own Anointed setting, so change it here."); ApplyAnointedSetting(); Define("BinmaMechaFiendDecompile", "「V??oid Fiend』: Leaked Memory", "As 「V??oid Fiend』, accept the offering of the Collective.", "KRONONCONPSIRATOR_SKIN_MECHAFIENDSKINDEF_NAME"); Define("BinmaZenithFalseSon", "False Son: Zenith", "As False Son, survive The Judgement.", "CRAZYHAMSTER_SKIN_ZENITH_NAME"); JudgementBodies["BinmaZenithFalseSon"] = "FalseSonBody"; Define("BinmaBiomassFalseSon", "False Son: Second Bloom", "As False Son, return from death with a Seed of Life.", "ORBITAL_SKIN_FALSESON_NAME"); Define("BinmaShackledAcrid", "Acrid: Shackled", "As Acrid, clear the Void Fields, pass through the Void Locus, and escape the Planetarium in a single run.", "ORBITAL_SKIN_SHACKLED_NAME"); VoidRunBodies["BinmaShackledAcrid"] = "CrocoBody"; Define("BinmaLunarVoidRex", "REX: Lunar Void", "As REX, clear the Void Fields, pass through the Void Locus, and escape the Planetarium in a single run.", "HILLIURN_SKIN_LUNARVOID_REX_SKIN_NAME"); VoidRunBodies["BinmaLunarVoidRex"] = "TreebotBody"; DefineNoir("BinmaNoirBandit", "Bandit", "Bandit2Body", "Hidden in Plain Sight", "open 3 Cloaked Chests in a single run.", "BIGBADPIGEON_SKIN_NOIRBANDIT_NAME"); DefineNoir("BinmaNoirCommando", "Commando", "CommandoBody", "The Scoop", "open the Timed Security Chest.", "BIGBADPIGEON_SKIN_NOIRCOMMANDO_NAME"); DefineNoir("BinmaNoirEngi", "Engineer", "EngiBody", "Surveillance", "use a Radar Scanner on 3 different stages in a single run.", "BIGBADPIGEON_SKIN_NOIRENGI_NAME"); DefineNoir("BinmaNoirRex", "REX", "TreebotBody", "Stakeout", "ping 30 enemies in a single run.", "BIGBADPIGEON_SKIN_NOIRREX_NAME"); DefineNoir("BinmaNoirHuntress", "Huntress", "HuntressBody", "On the Trail", "activate 3 Newt Altars in a single run.", "BIGBADPIGEON_SKIN_NOIRHUNTRESS_NAME"); DefineNoir("BinmaNoirCaptain", "Captain", "CaptainBody", "The Family", "have 5 allies alive at once.", "BIGBADPIGEON_SKIN_NOIRCAPTAIN_NAME"); DefineNoir("BinmaNoirLoader", "Loader", "LoaderBody", "Protection Detail", "finish a teleporter event without an ally dying.", "BIGBADPIGEON_SKIN_NOIRLOADER_NAME"); DefineNoir("BinmaNoirMage", "Artificer", "MageBody", "Infiltration", "visit 2 hidden realms in a single run.", "BIGBADPIGEON_SKIN_NOIRMAGE_NAME"); DefineNoir("BinmaNoirVoidfiend", "「V??oid Fiend』", "VoidSurvivorBody", "Unmasked", "stay corrupted for 60 seconds straight.", "BIGBADPIGEON_SKIN_NOIRVOIDFIEND_NAME"); DefineNoir("BinmaNoirMerc", "Mercenary", "MercBody", "No Witnesses", "kill 20 enemies within 5 seconds.", "BIGBADPIGEON_SKIN_NOIRMERC_NAME"); DefineNoir("BinmaNoirDrifter", "Drifter", "DrifterBody", "Sticky Fingers", "scrap 10 items in a single run.", "BIGBADPIGEON_SKIN_NOIRDRIFTER_NAME"); DefineNoir("BinmaNoirDronetech", "Operator", "DroneTechBody", "Stolen Clearance", "buy or repair 5 drones in a single run.", "BIGBADPIGEON_SKIN_NOIRDRONETECH_NAME"); DefineNoir("BinmaNoirToolbot", "MUL-T", "ToolbotBody", "Paper Trail", "open 3 Rusted Lockboxes in a single run.", "BIGBADPIGEON_SKIN_NOIRTOOLBOT_NAME"); DefineNoir("BinmaNoirSeeker", "Seeker", "SeekerBody", "Second Sight", "use a Lunar Seer in the Bazaar Between Time.", "BIGBADPIGEON_SKIN_NOIRSEEKER_NAME"); DefineNoir("BinmaNoirRailgunner", "Railgunner", "RailgunnerBody", "Long Lens", "kill a boss from over 100m away.", "BIGBADPIGEON_SKIN_NOIRRAILGUNNER_NAME"); DefineNoir("BinmaNoirFalseson", "False Son", "FalseSonBody", "Examine the Evidence", "inspect 25 different items.", "BIGBADPIGEON_SKIN_NOIRFALSESON_NAME"); DefineNoir("BinmaNoirAcrid", "Acrid", "CrocoBody", "Sniffing Around", "discover 5 environment logs.", "BIGBADPIGEON_SKIN_NOIRACRID_NAME"); DefineNoir("BinmaNoirChef", "CHEF", "ChefBody", "Secret Recipe", "cook 3 meals in a single run.", "BIGBADPIGEON_SKIN_NOIRCHEF_NAME"); Define("BinmaFenrisCaptainAtlas", "Captain: Fire for Effect", "As Captain, kill Mithrix with an orbital strike."); Define("BinmaFenrisRailPyro", "Railgunner: Trial by Fire", "As Railgunner, kill a boss that is burning."); Define("BinmaFenrisRailKinetic", "Railgunner: Kinetic Impact", "As Railgunner, kill a boss while airborne."); Define("BinmaSummerRailgunner", "Railgunner: Beach Day", "As Railgunner, open a Legendary Chest.", "BIGBADPIGEON_SKIN_SUMMERRAILGUNNER_NAME"); Define("BinmaSummerVoidFiend", "「V??oid Fiend』: Beach Day", "As 「V??oid Fiend』, open a Legendary Chest.", "BIGBADPIGEON_SKIN_SUMMERVOIDFIEND_NAME"); Define("BinmaSolusRailgunnerPurge", "Railgunner: Purge", "As Railgunner, reject the offering of the Collective.", "KRONONCONSPIRATOR_SKIN_SOLUSGUNNER_NAME"); Define("BinmaSteelConvictionCaptain", "Captain: Steel Conviction", "As Captain, fight a Solus Control Unit or Alloy Worship Unit, an Alloy Hunter and a Solus Amalgamator in a single run.", "SHEPD_SKIN_TANIKSCAPTIAN_NAME"); DefineJudgement("BinmaJudgementCommando", "Commando", "CommandoBody", "ORBITAL_SKIN_MKII_NAME"); DefineJudgement("BinmaJudgementHuntress", "Huntress", "HuntressBody", "ORBITAL_SKIN_URBAN_NAME"); DefineJudgement("BinmaJudgementAcrid", "Acrid", "CrocoBody", "ORBITAL_SKIN_CHIMAERA_NAME"); DefineJudgement("BinmaJudgementLoader", "Loader", "LoaderBody", "ORBITAL_SKIN_REFURBISHED_NAME"); DefineJudgement("BinmaJudgementEngi", "Engineer", "EngiBody", "ORBITAL_SKIN_CHRONTECH_NAME"); DefineJudgement("BinmaJudgementMerc", "Mercenary", "MercBody", "ORBITAL_SKIN_HONOR_NAME", "ORBITAL_SKIN_MALICE_NAME"); DefineJudgement("BinmaJudgementBandit", "Bandit", "Bandit2Body", "ORBITAL_SKIN_INFAMY_NAME"); DefineJudgement("BinmaJudgementArtificer", "Artificer", "MageBody", "ORBITAL_SKIN_AMBER_NAME"); DefineJudgement("BinmaJudgementDrifter", "Drifter", "DrifterBody", "ORBITAL_SKIN_VAGABOND_NAME"); VoidRunTracker.Init(); Noir.Init(); FenrisLocks.Init(); Summer.Init(); ContentManager.collectContentPackProviders += (CollectContentPackProvidersDelegate)delegate(AddContentPackProviderDelegate add) { add.Invoke((IContentPackProvider)(object)new ContentProvider()); }; RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(AttachToSkins)); Harmony val = new Harmony("binma.challengingunlocks"); val.PatchAll(typeof(Plugin).Assembly); Type type = AccessTools.Inner(typeof(EquipmentSlot), "HealAndReviveLock"); if (type != null) { val.Patch((MethodBase)AccessTools.Method(type, "FixedUpdate", (Type[])null, (Type[])null), new HarmonyMethod(typeof(SeedPatches), "LockPrefix", (Type[])null), new HarmonyMethod(typeof(SeedPatches), "LockPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } else { Log.LogWarning((object)"Couldn't find HealAndReviveLock; ally Seed of Life revives won't count."); } } private static void DefineNoir(string id, string survivor, string body, string title, string desc, string skin) { Define(id, survivor + ": " + title, "As " + survivor + ", " + desc, skin); NoirBodies[id] = body; } private static void ApplyAnointedSetting() { try { if (!Chainloader.PluginInfos.TryGetValue("com.Viliger.EnemiesReturns", out var value) || (Object)(object)value.Instance == (Object)null) { return; } foreach (ConfigDefinition key in value.Instance.Config.Keys) { if (!(key.Key != "Enable Anointed Skins") && value.Instance.Config[key] is ConfigEntry<bool> val && val.Value != AnointedEnabled.Value) { val.Value = AnointedEnabled.Value; Log.LogInfo((object)("EnemiesReturns Anointed skins " + ((!AnointedEnabled.Value) ? "disabled." : "enabled."))); } } } catch (Exception ex) { Log.LogWarning((object)("Couldn't change the Anointed skins setting: " + ex.Message)); } } private static void DefineJudgement(string id, string survivor, string body, params string[] skins) { Define(id, survivor + ": Returned", "As " + survivor + ", survive The Judgement.", skins); JudgementBodies[id] = body; } private static void AttachToSkins() { bool flag = Chainloader.PluginInfos.ContainsKey("Wolfo.WolfoQoL_Client"); int num = 0; for (int i = 0; i < BodyCatalog.bodyCount; i++) { SkinDef[] bodySkins = BodyCatalog.GetBodySkins((BodyIndex)i); if (bodySkins == null) { continue; } SkinDef[] array = bodySkins; foreach (SkinDef val in array) { if ((Object)(object)val == (Object)null || val.nameToken == null || !SkinToAchievement.TryGetValue(val.nameToken, out var value)) { continue; } UnlockableDef val2 = (val.unlockableDef = Unlockables[value]); if (val.nameToken == "ORBITAL_SKIN_MALICE_NAME" && flag && !((Object)val).name.EndsWith("Red")) { ((Object)val).name = ((Object)val).name + "Red"; } if ((Object)(object)val2.achievementIcon == (Object)null && (Object)(object)val.icon != (Object)null) { val2.achievementIcon = val.icon; AchievementDef achievementDef = AchievementManager.GetAchievementDef(value); if (achievementDef != null) { achievementDef.SetAchievedIcon(val.icon); } } num++; } } foreach (KeyValuePair<string, UnlockableDef> unlockable in Unlockables) { string text = unlockable.Key.ToUpperInvariant(); string nameTok = "ACHIEVEMENT_" + text + "_NAME"; string descTok = "ACHIEVEMENT_" + text + "_DESCRIPTION"; UnlockableDef value2 = unlockable.Value; value2.getHowToUnlockString = () => Language.GetStringFormatted("UNLOCK_VIA_ACHIEVEMENT_FORMAT", new object[2] { Language.GetString(nameTok), Language.GetString(descTok) }); value2.getUnlockedString = () => Language.GetStringFormatted("UNLOCKED_FORMAT", new object[2] { Language.GetString(nameTok), Language.GetString(descTok) }); } Log.LogInfo((object)("Locked " + num + " skins behind achievements.")); FenrisLocks.Attach(); Summer.DetectTropics(); } } internal static class Ids { public const string MechaFiend = "BinmaMechaFiendDecompile"; public const string Zenith = "BinmaZenithFalseSon"; public const string Biomass = "BinmaBiomassFalseSon"; public const string Shackled = "BinmaShackledAcrid"; public const string LunarVoidRex = "BinmaLunarVoidRex"; public const string CaptainAtlas = "BinmaFenrisCaptainAtlas"; public const string RailPyro = "BinmaFenrisRailPyro"; public const string RailKinetic = "BinmaFenrisRailKinetic"; public const string SummerRail = "BinmaSummerRailgunner"; public const string SummerVoid = "BinmaSummerVoidFiend"; public const string SolusRail = "BinmaSolusRailgunnerPurge"; public const string SteelCaptain = "BinmaSteelConvictionCaptain"; public const string JCommando = "BinmaJudgementCommando"; public const string JHuntress = "BinmaJudgementHuntress"; public const string JAcrid = "BinmaJudgementAcrid"; public const string JLoader = "BinmaJudgementLoader"; public const string JEngi = "BinmaJudgementEngi"; public const string JMerc = "BinmaJudgementMerc"; public const string JBandit = "BinmaJudgementBandit"; public const string JArtificer = "BinmaJudgementArtificer"; public const string JDrifter = "BinmaJudgementDrifter"; } internal class ContentProvider : IContentPackProvider { private readonly ContentPack pack = new ContentPack(); public string identifier => "binma.challengingunlocks"; public IEnumerator LoadStaticContentAsync(LoadStaticContentAsyncArgs args) { pack.unlockableDefs.Add(new List<UnlockableDef>(Plugin.Unlockables.Values).ToArray()); args.ReportProgress(1f); yield break; } public IEnumerator GenerateContentPackAsync(GetContentPackAsyncArgs args) { ContentPack.Copy(pack, args.output); args.ReportProgress(1f); yield break; } public IEnumerator FinalizeAsync(FinalizeAsyncArgs args) { args.ReportProgress(1f); yield break; } } [HarmonyPatch(typeof(Language), "GetLocalizedStringByToken")] internal static class LanguagePatch { private static void Postfix(string __0, ref string __result) { if (__0 != null && (__result == null || __result == __0) && Plugin.Tokens.TryGetValue(__0, out var value)) { __result = value; } } } internal static class Util2 { internal static bool PlaysAs(NetworkUser user, string bodyName) { //IL_000f: 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) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Invalid comparison between Unknown and I4 //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_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) if ((Object)(object)user == (Object)null) { return false; } BodyIndex val = BodyCatalog.FindBodyIndex(bodyName); if ((int)val == -1) { return false; } CharacterBody currentBody = user.GetCurrentBody(); if ((Object)(object)currentBody != (Object)null) { return currentBody.bodyIndex == val; } return user.bodyIndexPreference == val; } } [RegisterAchievement("BinmaMechaFiendDecompile", "Skins.Binma.BinmaMechaFiendDecompile", "CompleteVoidEnding", 5u, null)] public class MechaFiendAchievement : BasePerSurvivorDecompileAchievement { protected override BodyIndex LookUpRequiredBodyIndex() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) return BodyCatalog.FindBodyIndex("VoidSurvivorBody"); } } [RegisterAchievement("BinmaZenithFalseSon", "Skins.Binma.BinmaZenithFalseSon", "UnlockFalseSon", 5u, typeof(JudgementServer))] public class ZenithAchievement : ServerTrackedAchievement { } public abstract class ServerTrackedAchievement : BaseAchievement { public override void OnInstall() { ((BaseAchievement)this).OnInstall(); ((BaseAchievement)this).SetServerTracked(true); } public override void OnUninstall() { ((BaseAchievement)this).SetServerTracked(false); ((BaseAchievement)this).OnUninstall(); } } [RegisterAchievement("BinmaBiomassFalseSon", "Skins.Binma.BinmaBiomassFalseSon", "UnlockFalseSon", 5u, typeof(BiomassServer))] public class BiomassAchievement : ServerTrackedAchievement { } public class BiomassServer : BaseServerAchievement { public override void OnInstall() { ((BaseServerAchievement)this).OnInstall(); Plugin.OnSeedRevive += Handle; } public override void OnUninstall() { Plugin.OnSeedRevive -= Handle; ((BaseServerAchievement)this).OnUninstall(); } private void Handle(CharacterMaster master) { if (!((Object)(object)master == (Object)null) && !((Object)(object)((BaseServerAchievement)this).networkUser == (Object)null) && !((Object)(object)((BaseServerAchievement)this).networkUser.master != (Object)(object)master) && Util2.PlaysAs(((BaseServerAchievement)this).networkUser, "FalseSonBody")) { ((BaseServerAchievement)this).Grant(); } } } internal static class SeedPatches { internal static void LockPrefix(MonoBehaviour __instance, out bool __state) { __state = false; try { Traverse val = Traverse.Create((object)__instance); float value = val.Field("age").GetValue<float>(); float value2 = val.Field("delayDuration").GetValue<float>(); __state = value + Time.fixedDeltaTime > value2; } catch { } } internal static void LockPostfix(MonoBehaviour __instance, bool __state) { if (!__state || !NetworkServer.active) { return; } try { CharacterMaster component = ((Component)__instance).GetComponent<CharacterMaster>(); if ((Object)(object)component != (Object)null && component.hasBody) { Plugin.RaiseSeedRevive(component); } } catch (Exception ex) { Plugin.Log.LogError((object)ex); } } } [HarmonyPatch] internal static class SeedSelfPatchHost { [HarmonyPatch(typeof(CharacterMaster), "RespawnExtraLifeHealAndRevive")] [HarmonyPostfix] private static void Postfix(CharacterMaster __instance) { try { if (NetworkServer.active) { Plugin.RaiseSeedRevive(__instance); } } catch (Exception ex) { Plugin.Log.LogError((object)ex); } } } internal static class Noir { private static readonly Dictionary<string, Dictionary<CharacterMaster, int>> counts = new Dictionary<string, Dictionary<CharacterMaster, int>>(); private static readonly Dictionary<CharacterMaster, HashSet<string>> scannerStages = new Dictionary<CharacterMaster, HashSet<string>>(); private static readonly Dictionary<CharacterMaster, HashSet<int>> pingedEnemies = new Dictionary<CharacterMaster, HashSet<int>>(); private static readonly Dictionary<CharacterMaster, Queue<float>> recentKills = new Dictionary<CharacterMaster, Queue<float>>(); private static readonly HashSet<string> realmsVisited = new HashSet<string>(); private static readonly HashSet<string> hiddenRealms = new HashSet<string> { "bazaar", "goldshores", "mysteryspace", "limbo", "arena" }; private static bool teleporterCharging; private static bool allyDiedDuringTeleporter; internal static event Action<string, CharacterMaster> OnGrant; internal static void Grant(string id, CharacterMaster m) { Noir.OnGrant?.Invoke(id, m); } internal static void Count(string id, CharacterMaster m, int needed) { if (!((Object)(object)m == (Object)null) && NetworkServer.active) { if (!counts.TryGetValue(id, out var value)) { value = (counts[id] = new Dictionary<CharacterMaster, int>()); } value.TryGetValue(m, out var value2); value2 = (value[m] = value2 + 1); if (value2 >= needed) { Grant(id, m); } } } internal static CharacterMaster MasterOf(Interactor i) { if ((Object)(object)i == (Object)null) { return null; } CharacterBody component = ((Component)i).GetComponent<CharacterBody>(); return (!((Object)(object)component != (Object)null)) ? null : component.master; } private static string CurrentScene() { SceneDef mostRecentSceneDef = SceneCatalog.mostRecentSceneDef; return (!((Object)(object)mostRecentSceneDef != (Object)null)) ? "" : mostRecentSceneDef.cachedName; } internal static void Init() { Run.onRunStartGlobal += delegate { counts.Clear(); scannerStages.Clear(); pingedEnemies.Clear(); recentKills.Clear(); realmsVisited.Clear(); teleporterCharging = false; }; GlobalEventManager.OnInteractionsGlobal += delegate(Interactor interactor, IInteractable interactable, GameObject obj) { if (NetworkServer.active && !((Object)(object)obj == (Object)null)) { CharacterMaster val = MasterOf(interactor); if (!((Object)(object)val == (Object)null)) { string text = ((Object)obj).name ?? ""; if (text.Contains("Stealthed")) { Count("BinmaNoirBandit", val, 3); } if ((Object)(object)obj.GetComponent<PortalStatueBehavior>() != (Object)null) { Count("BinmaNoirHuntress", val, 3); } if ((Object)(object)obj.GetComponent<SummonMasterBehavior>() != (Object)null) { Count("BinmaNoirDronetech", val, 5); } if (text.StartsWith("Lockbox") && !text.Contains("Void")) { Count("BinmaNoirToolbot", val, 3); } if ((Object)(object)obj.GetComponent<SeerStationController>() != (Object)null && CurrentScene() == "bazaar") { Grant("BinmaNoirSeeker", val); } } } }; Opening.onOpened += delegate { if (NetworkServer.active) { Grant("BinmaNoirCommando", null); } }; Stage.onServerStageBegin += delegate(Stage stage) { if (!((Object)(object)stage == (Object)null) && !((Object)(object)stage.sceneDef == (Object)null)) { string text = stage.sceneDef.cachedName ?? ""; if (text.StartsWith("artifactworld")) { text = "artifactworld"; } if (hiddenRealms.Contains(text) || !(text != "artifactworld")) { realmsVisited.Add(text); if (realmsVisited.Count >= 2) { Grant("BinmaNoirMage", null); } } } }; TeleporterInteraction.onTeleporterBeginChargingGlobal += delegate { teleporterCharging = true; allyDiedDuringTeleporter = false; }; TeleporterInteraction.onTeleporterChargedGlobal += delegate { if (NetworkServer.active && teleporterCharging && !allyDiedDuringTeleporter) { Grant("BinmaNoirLoader", null); } teleporterCharging = false; }; GlobalEventManager.onDeathProcServer += delegate(DamageReport report) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Invalid comparison between Unknown and I4 //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) if (NetworkServer.active && report != null) { if (teleporterCharging && (int)report.victimTeamIndex == 1) { allyDiedDuringTeleporter = true; } CharacterMaster attackerMaster = report.attackerMaster; if (!((Object)(object)attackerMaster == (Object)null) && (int)report.victimTeamIndex != 1) { if (!recentKills.TryGetValue(attackerMaster, out var value)) { value = (recentKills[attackerMaster] = new Queue<float>()); } float time = Time.time; value.Enqueue(time); while (value.Count > 0 && time - value.Peek() > 5f) { value.Dequeue(); } if (value.Count >= 20) { Grant("BinmaNoirMerc", attackerMaster); } if (report.victimIsBoss && (Object)(object)report.attackerBody != (Object)null && (Object)(object)report.victimBody != (Object)null && Vector3.Distance(report.attackerBody.corePosition, report.victimBody.corePosition) >= 100f) { Grant("BinmaNoirRailgunner", attackerMaster); } } } }; CharacterBody.onBodyStartGlobal += delegate(CharacterBody body) { if (NetworkServer.active && !((Object)(object)body == (Object)null) && !((Object)(object)body.master == (Object)null)) { MinionOwnership minionOwnership = body.master.minionOwnership; CharacterMaster val = ((!((Object)(object)minionOwnership != (Object)null)) ? null : minionOwnership.ownerMaster); if (!((Object)(object)val == (Object)null)) { int num = 0; foreach (CharacterMaster readOnlyInstances in CharacterMaster.readOnlyInstancesList) { if (!((Object)(object)readOnlyInstances == (Object)null) && !((Object)(object)readOnlyInstances.minionOwnership == (Object)null) && !((Object)(object)readOnlyInstances.minionOwnership.ownerMaster != (Object)(object)val)) { CharacterBody body2 = readOnlyInstances.GetBody(); if ((Object)(object)body2 != (Object)null && (Object)(object)body2.healthComponent != (Object)null && body2.healthComponent.alive) { num++; } } } if (num >= 5) { Grant("BinmaNoirCaptain", val); } } } }; } internal static void ScannerUsed(CharacterMaster m) { if (!((Object)(object)m == (Object)null)) { if (!scannerStages.TryGetValue(m, out var value)) { value = (scannerStages[m] = new HashSet<string>()); } value.Add(CurrentScene()); if (value.Count >= 3) { Grant("BinmaNoirEngi", m); } } } internal static void EnemyPinged(CharacterMaster m, CharacterBody target) { if (!((Object)(object)m == (Object)null) && !((Object)(object)target == (Object)null)) { if (!pingedEnemies.TryGetValue(m, out var value)) { value = (pingedEnemies[m] = new HashSet<int>()); } value.Add(((Object)((Component)target).gameObject).GetInstanceID()); if (value.Count >= 30) { Grant("BinmaNoirRex", m); } } } } public class NoirServer : BaseServerAchievement { public override void OnInstall() { ((BaseServerAchievement)this).OnInstall(); Noir.OnGrant += Handle; } public override void OnUninstall() { Noir.OnGrant -= Handle; ((BaseServerAchievement)this).OnUninstall(); } private void Handle(string id, CharacterMaster master) { if (base.achievementDef != null && !(id != base.achievementDef.identifier) && !((Object)(object)((BaseServerAchievement)this).networkUser == (Object)null) && (!((Object)(object)master != (Object)null) || !((Object)(object)((BaseServerAchievement)this).networkUser.master != (Object)(object)master)) && Plugin.NoirBodies.TryGetValue(id, out var value) && Util2.PlaysAs(((BaseServerAchievement)this).networkUser, value)) { ((BaseServerAchievement)this).Grant(); } } } [RegisterAchievement("BinmaNoirBandit", "Skins.Binma.BinmaNoirBandit", null, 5u, typeof(NoirServer))] public class NoirBandit : ServerTrackedAchievement { } [RegisterAchievement("BinmaNoirCommando", "Skins.Binma.BinmaNoirCommando", null, 5u, typeof(NoirServer))] public class NoirCommando : ServerTrackedAchievement { } [RegisterAchievement("BinmaNoirEngi", "Skins.Binma.BinmaNoirEngi", null, 5u, typeof(NoirServer))] public class NoirEngi : ServerTrackedAchievement { } [RegisterAchievement("BinmaNoirRex", "Skins.Binma.BinmaNoirRex", null, 5u, typeof(NoirServer))] public class NoirRex : ServerTrackedAchievement { } [RegisterAchievement("BinmaNoirHuntress", "Skins.Binma.BinmaNoirHuntress", null, 5u, typeof(NoirServer))] public class NoirHuntress : ServerTrackedAchievement { } [RegisterAchievement("BinmaNoirCaptain", "Skins.Binma.BinmaNoirCaptain", null, 5u, typeof(NoirServer))] public class NoirCaptain : ServerTrackedAchievement { } [RegisterAchievement("BinmaNoirLoader", "Skins.Binma.BinmaNoirLoader", null, 5u, typeof(NoirServer))] public class NoirLoader : ServerTrackedAchievement { } [RegisterAchievement("BinmaNoirMage", "Skins.Binma.BinmaNoirMage", null, 5u, typeof(NoirServer))] public class NoirMage : ServerTrackedAchievement { } [RegisterAchievement("BinmaNoirVoidfiend", "Skins.Binma.BinmaNoirVoidfiend", null, 5u, typeof(NoirServer))] public class NoirVoidfiend : ServerTrackedAchievement { } [RegisterAchievement("BinmaNoirMerc", "Skins.Binma.BinmaNoirMerc", null, 5u, typeof(NoirServer))] public class NoirMerc : ServerTrackedAchievement { } [RegisterAchievement("BinmaNoirDrifter", "Skins.Binma.BinmaNoirDrifter", null, 5u, typeof(NoirServer))] public class NoirDrifter : ServerTrackedAchievement { } [RegisterAchievement("BinmaNoirDronetech", "Skins.Binma.BinmaNoirDronetech", null, 5u, typeof(NoirServer))] public class NoirDronetech : ServerTrackedAchievement { } [RegisterAchievement("BinmaNoirToolbot", "Skins.Binma.BinmaNoirToolbot", null, 5u, typeof(NoirServer))] public class NoirToolbot : ServerTrackedAchievement { } [RegisterAchievement("BinmaNoirSeeker", "Skins.Binma.BinmaNoirSeeker", null, 5u, typeof(NoirServer))] public class NoirSeeker : ServerTrackedAchievement { } [RegisterAchievement("BinmaNoirRailgunner", "Skins.Binma.BinmaNoirRailgunner", null, 5u, typeof(NoirServer))] public class NoirRailgunner : ServerTrackedAchievement { } [RegisterAchievement("BinmaNoirChef", "Skins.Binma.BinmaNoirChef", null, 5u, typeof(NoirServer))] public class NoirChef : ServerTrackedAchievement { } [HarmonyPatch(typeof(EquipmentSlot), "FireScanner")] internal static class ScannerPatch { private static void Postfix(EquipmentSlot __instance, bool __result) { try { if (__result && NetworkServer.active && (Object)(object)__instance.characterBody != (Object)null) { Noir.ScannerUsed(__instance.characterBody.master); } } catch (Exception ex) { Plugin.Log.LogError((object)ex); } } } [HarmonyPatch(typeof(PingerController), "CmdPing")] internal static class PingPatch { private static void Postfix(PingerController __instance, PingInfo __0) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Invalid comparison between Unknown and I4 try { if (!NetworkServer.active) { return; } GameObject targetGameObject = ((PingInfo)(ref __0)).targetGameObject; if (!((Object)(object)targetGameObject == (Object)null)) { CharacterBody component = targetGameObject.GetComponent<CharacterBody>(); if (!((Object)(object)component == (Object)null) && !((Object)(object)component.teamComponent == (Object)null) && (int)component.teamComponent.teamIndex != 1) { Noir.EnemyPinged(((Component)__instance).GetComponent<CharacterMaster>(), component); } } } catch (Exception ex) { Plugin.Log.LogError((object)ex); } } } [HarmonyPatch(typeof(ScrapperController), "BeginScrapping")] internal static class ScrapPatch { private static void Postfix(ScrapperController __instance) { try { if (NetworkServer.active) { Interactor value = Traverse.Create((object)__instance).Field("interactor").GetValue<Interactor>(); Noir.Count("BinmaNoirDrifter", Noir.MasterOf(value), 10); } } catch (Exception ex) { Plugin.Log.LogError((object)ex); } } } [HarmonyPatch(typeof(MealPrepController), "BeginCookingServer")] internal static class CookPatch { private static void Postfix(Interactor __0) { try { if (NetworkServer.active) { Noir.Count("BinmaNoirChef", Noir.MasterOf(__0), 3); } } catch (Exception ex) { Plugin.Log.LogError((object)ex); } } } [HarmonyPatch(typeof(CorruptMode), "FixedUpdate")] internal static class CorruptTimePatch { private static readonly HashSet<EntityState> done = new HashSet<EntityState>(); private static void Postfix(CorruptMode __instance) { try { if (!NetworkServer.active || done.Contains((EntityState)(object)__instance)) { return; } float value = Traverse.Create((object)__instance).Property("fixedAge", (object[])null).GetValue<float>(); if (!(value < 60f)) { done.Add((EntityState)(object)__instance); CharacterBody value2 = Traverse.Create((object)__instance).Property("characterBody", (object[])null).GetValue<CharacterBody>(); if ((Object)(object)value2 != (Object)null) { Noir.Grant("BinmaNoirVoidfiend", value2.master); } } } catch (Exception ex) { Plugin.Log.LogError((object)ex); } } } [RegisterAchievement("BinmaNoirAcrid", "Skins.Binma.BinmaNoirAcrid", null, 5u, null)] public class NoirAcrid : BaseAchievement { protected override BodyIndex LookUpRequiredBodyIndex() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) return BodyCatalog.FindBodyIndex("CrocoBody"); } protected override void OnBodyRequirementMet() { ((BaseAchievement)this).OnBodyRequirementMet(); UserProfile.onUnlockableGranted += OnUnlock; } protected override void OnBodyRequirementBroken() { UserProfile.onUnlockableGranted -= OnUnlock; ((BaseAchievement)this).OnBodyRequirementBroken(); } private void OnUnlock(UserProfile profile, UnlockableDef def) { if (profile != ((BaseAchievement)this).userProfile || (Object)(object)def == (Object)null || def.cachedName == null || !def.cachedName.StartsWith("Logs.Stages.")) { return; } StatSheet statSheet = ((BaseAchievement)this).userProfile.statSheet; int num = 0; for (int i = 0; i < statSheet.GetUnlockableCount(); i++) { UnlockableDef unlockable = statSheet.GetUnlockable(i); if ((Object)(object)unlockable != (Object)null && unlockable.cachedName != null && unlockable.cachedName.StartsWith("Logs.Stages.")) { num++; } } if (num >= 5) { ((BaseAchievement)this).Grant(); } } } [RegisterAchievement("BinmaNoirFalseson", "Skins.Binma.BinmaNoirFalseson", "UnlockFalseSon", 5u, null)] public class NoirFalseSon : BaseAchievement { internal static event Action<PickupIndex> OnInspect; internal static void RaiseInspect(PickupIndex p) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) NoirFalseSon.OnInspect?.Invoke(p); } protected override BodyIndex LookUpRequiredBodyIndex() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) return BodyCatalog.FindBodyIndex("FalseSonBody"); } protected override void OnBodyRequirementMet() { ((BaseAchievement)this).OnBodyRequirementMet(); OnInspect += Handle; } protected override void OnBodyRequirementBroken() { OnInspect -= Handle; ((BaseAchievement)this).OnBodyRequirementBroken(); } private string SavePath() { string text = ((((BaseAchievement)this).userProfile == null || ((BaseAchievement)this).userProfile.fileName == null) ? "default" : ((BaseAchievement)this).userProfile.fileName); char[] invalidFileNameChars = Path.GetInvalidFileNameChars(); foreach (char oldChar in invalidFileNameChars) { text = text.Replace(oldChar, '_'); } return Path.Combine(Paths.ConfigPath, "binma.challengingunlocks.inspected." + text + ".txt"); } private void Handle(PickupIndex p) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Invalid comparison between Unknown and I4 try { PickupDef pickupDef = PickupCatalog.GetPickupDef(p); if (pickupDef != null && ((int)pickupDef.itemIndex != -1 || (int)pickupDef.equipmentIndex != -1)) { string path = SavePath(); HashSet<string> hashSet = new HashSet<string>((!File.Exists(path)) ? ((IEnumerable<string>)new string[0]) : ((IEnumerable<string>)File.ReadAllLines(path))); if (hashSet.Add(pickupDef.internalName)) { File.WriteAllLines(path, new List<string>(hashSet).ToArray()); } if (hashSet.Count >= 25) { ((BaseAchievement)this).Grant(); } } } catch (Exception ex) { Plugin.Log.LogError((object)ex); } } } [HarmonyPatch] internal static class InspectPatch { private static IEnumerable<MethodBase> TargetMethods() { foreach (MethodInfo m in AccessTools.GetDeclaredMethods(typeof(InspectPanelController))) { ParameterInfo[] ps = m.GetParameters(); if (m.Name == "Show" && ps.Length > 0 && ps[0].ParameterType == typeof(InspectInfo)) { yield return m; } } } private static void Postfix(InspectInfo __0) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) try { if (__0 != null && __0.isDynamicInspectInfo) { NoirFalseSon.RaiseInspect(__0.dynamicInspectPickupIndex); } } catch (Exception ex) { Plugin.Log.LogError((object)ex); } } } internal static class VoidRunTracker { private static bool clearedArena; private static bool visitedLocus; internal static void Init() { Run.onRunStartGlobal += delegate { clearedArena = false; visitedLocus = false; }; ArenaMissionController.onBeatArena += delegate { if (NetworkServer.active) { clearedArena = true; } }; Stage.onServerStageBegin += delegate(Stage stage) { if ((Object)(object)stage != (Object)null && (Object)(object)stage.sceneDef != (Object)null && stage.sceneDef.cachedName == "voidstage") { visitedLocus = true; } }; Run.onServerGameOver += delegate(Run run, GameEndingDef ending) { if ((Object)(object)ending != (Object)null && ending.cachedName == "VoidEnding" && clearedArena && visitedLocus) { Plugin.RaiseVoidRunComplete(); } }; } } [RegisterAchievement("BinmaShackledAcrid", "Skins.Binma.BinmaShackledAcrid", "BeatArena", 5u, typeof(ShackledServer))] public class ShackledAchievement : ServerTrackedAchievement { } public class ShackledServer : BaseServerAchievement { public override void OnInstall() { ((BaseServerAchievement)this).OnInstall(); Plugin.OnVoidRunComplete += Handle; } public override void OnUninstall() { Plugin.OnVoidRunComplete -= Handle; ((BaseServerAchievement)this).OnUninstall(); } private void Handle() { if (base.achievementDef != null && Plugin.VoidRunBodies.TryGetValue(base.achievementDef.identifier, out var value) && Util2.PlaysAs(((BaseServerAchievement)this).networkUser, value)) { ((BaseServerAchievement)this).Grant(); } } } [RegisterAchievement("BinmaLunarVoidRex", "Skins.Binma.BinmaLunarVoidRex", null, 5u, typeof(ShackledServer))] public class LunarVoidRexAchievement : ServerTrackedAchievement { } internal static class FenrisLocks { private static readonly HashSet<string> probePrefabs = new HashSet<string>(); internal static event Action<string, CharacterMaster> OnGrant; internal static void NoteProbePrefab(GameObject prefab) { if ((Object)(object)prefab != (Object)null) { probePrefabs.Add(((Object)prefab).name); } } private static void Grant(string id, CharacterMaster m) { FenrisLocks.OnGrant?.Invoke(id, m); } private static void Lock(string bodyName, Func<Type, bool> match, string id) { GameObject val = BodyCatalog.FindBodyPrefab(bodyName); if ((Object)(object)val == (Object)null) { return; } GenericSkill[] components = val.GetComponents<GenericSkill>(); foreach (GenericSkill val2 in components) { SkillFamily skillFamily = val2.skillFamily; if ((Object)(object)skillFamily == (Object)null || skillFamily.variants == null) { continue; } for (int j = 0; j < skillFamily.variants.Length; j++) { SkillDef skillDef = skillFamily.variants[j].skillDef; if ((Object)(object)skillDef == (Object)null) { continue; } Type stateType = ((SerializableEntityStateType)(ref skillDef.activationState)).stateType; if (stateType == null || stateType.Namespace == null || !stateType.Namespace.StartsWith("FenrisSkills") || !match(stateType)) { continue; } UnlockableDef val3 = Plugin.Unlockables[id]; val3.nameToken = skillDef.skillNameToken; skillFamily.variants[j].unlockableDef = val3; if ((Object)(object)skillDef.icon != (Object)null) { val3.achievementIcon = skillDef.icon; AchievementDef achievementDef = AchievementManager.GetAchievementDef(id); if (achievementDef != null) { achievementDef.SetAchievedIcon(skillDef.icon); } } Plugin.Log.LogInfo((object)("Locked skill " + skillDef.skillName + " on " + bodyName + ".")); } } } internal static void Attach() { try { Lock("CaptainBody", (Type t) => true, "BinmaFenrisCaptainAtlas"); Lock("RailgunnerBody", (Type t) => t.Name == "FireMineExplosive", "BinmaFenrisRailKinetic"); Lock("RailgunnerBody", (Type t) => t.Name != "FireMineExplosive", "BinmaFenrisRailPyro"); } catch (Exception ex) { Plugin.Log.LogError((object)ex); } } internal static void Init() { GlobalEventManager.onDeathProcServer += delegate(DamageReport report) { try { if (NetworkServer.active && report != null && !((Object)(object)report.attackerMaster == (Object)null) && !((Object)(object)report.victimBody == (Object)null)) { CharacterMaster attackerMaster = report.attackerMaster; if (((Object)report.victimBody).name.StartsWith("BrotherHurtBody") && report.damageInfo != null && (Object)(object)report.damageInfo.inflictor != (Object)null) { string name = ((Object)report.damageInfo.inflictor).name; bool flag = name.Contains("Airstrike"); foreach (string probePrefab in probePrefabs) { if (name.StartsWith(probePrefab)) { flag = true; } } if (flag) { Grant("BinmaFenrisCaptainAtlas", attackerMaster); } } if (report.victimIsBoss) { CharacterBody victimBody = report.victimBody; if (victimBody.HasBuff(Buffs.OnFire) || ((Object)(object)Buffs.StrongerBurn != (Object)null && victimBody.HasBuff(Buffs.StrongerBurn))) { Grant("BinmaFenrisRailPyro", attackerMaster); } CharacterBody attackerBody = report.attackerBody; if ((Object)(object)attackerBody != (Object)null && (Object)(object)attackerBody.characterMotor != (Object)null && !attackerBody.characterMotor.isGrounded) { Grant("BinmaFenrisRailKinetic", attackerMaster); } } } } catch (Exception ex) { Plugin.Log.LogError((object)ex); } }; } } public class FenrisServer : BaseServerAchievement { private static readonly Dictionary<string, string> bodies = new Dictionary<string, string> { { "BinmaFenrisCaptainAtlas", "CaptainBody" }, { "BinmaFenrisRailPyro", "RailgunnerBody" }, { "BinmaFenrisRailKinetic", "RailgunnerBody" } }; public override void OnInstall() { ((BaseServerAchievement)this).OnInstall(); FenrisLocks.OnGrant += Handle; } public override void OnUninstall() { FenrisLocks.OnGrant -= Handle; ((BaseServerAchievement)this).OnUninstall(); } private void Handle(string id, CharacterMaster master) { if (base.achievementDef != null && !(id != base.achievementDef.identifier) && !((Object)(object)((BaseServerAchievement)this).networkUser == (Object)null) && !((Object)(object)((BaseServerAchievement)this).networkUser.master != (Object)(object)master) && bodies.TryGetValue(id, out var value) && Util2.PlaysAs(((BaseServerAchievement)this).networkUser, value)) { ((BaseServerAchievement)this).Grant(); } } } [RegisterAchievement("BinmaFenrisCaptainAtlas", "Skins.Binma.BinmaFenrisCaptainAtlas", "CompleteMainEnding", 5u, typeof(FenrisServer))] public class CaptainAtlasAchievement : ServerTrackedAchievement { } [RegisterAchievement("BinmaFenrisRailPyro", "Skins.Binma.BinmaFenrisRailPyro", null, 5u, typeof(FenrisServer))] public class RailPyroAchievement : ServerTrackedAchievement { } [RegisterAchievement("BinmaFenrisRailKinetic", "Skins.Binma.BinmaFenrisRailKinetic", null, 5u, typeof(FenrisServer))] public class RailKineticAchievement : ServerTrackedAchievement { } [HarmonyPatch(typeof(CallAirstrikeBase), "ModifyProjectile")] internal static class ProbePrefabPatch { private static void Postfix(ref FireProjectileInfo __0) { try { FenrisLocks.NoteProbePrefab(__0.projectilePrefab); } catch { } } } internal static class Summer { internal static bool TropicsInstalled; private static readonly HashSet<string> tropicsScenes = new HashSet<string> { "tropics_wormsworms", "tropicsnight_wormsworms" }; internal static event Action<CharacterMaster> OnLegendaryOpened; internal static void DetectTropics() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Invalid comparison between Unknown and I4 foreach (string tropicsScene in tropicsScenes) { if ((int)SceneCatalog.FindSceneIndex(tropicsScene) != -1) { TropicsInstalled = true; } } if (TropicsInstalled) { Plugin.Tokens["ACHIEVEMENT_" + "BinmaSummerRailgunner".ToUpperInvariant() + "_DESCRIPTION"] = "As Railgunner, open a Legendary Chest on Sunset Tropics or Midnight Tropics."; Plugin.Tokens["ACHIEVEMENT_" + "BinmaSummerVoidFiend".ToUpperInvariant() + "_DESCRIPTION"] = "As 「V??oid Fiend』, open a Legendary Chest on Sunset Tropics or Midnight Tropics."; Plugin.Log.LogInfo((object)"Sunset Tropics detected; Summer skins require the Tropics."); } } private static bool StageCounts() { if (TropicsInstalled) { SceneDef mostRecentSceneDef = SceneCatalog.mostRecentSceneDef; return (Object)(object)mostRecentSceneDef != (Object)null && tropicsScenes.Contains(mostRecentSceneDef.cachedName); } return true; } internal static void Init() { GlobalEventManager.OnInteractionsGlobal += delegate(Interactor interactor, IInteractable interactable, GameObject obj) { try { if (NetworkServer.active && !((Object)(object)obj == (Object)null) && !((Object)(object)obj.GetComponent<PurchaseInteraction>() == (Object)null) && ((Object)obj).name.Contains("GoldChest") && StageCounts()) { CharacterMaster val = Noir.MasterOf(interactor); Action<CharacterMaster> onLegendaryOpened = Summer.OnLegendaryOpened; if ((Object)(object)val != (Object)null) { onLegendaryOpened?.Invoke(val); } } } catch (Exception ex) { Plugin.Log.LogError((object)ex); } }; } } public class SummerServer : BaseServerAchievement { public override void OnInstall() { ((BaseServerAchievement)this).OnInstall(); Summer.OnLegendaryOpened += Handle; } public override void OnUninstall() { Summer.OnLegendaryOpened -= Handle; ((BaseServerAchievement)this).OnUninstall(); } private void Handle(CharacterMaster master) { if (!((Object)(object)((BaseServerAchievement)this).networkUser == (Object)null) && !((Object)(object)((BaseServerAchievement)this).networkUser.master != (Object)(object)master)) { string bodyName = ((base.achievementDef == null || !(base.achievementDef.identifier == "BinmaSummerRailgunner")) ? "VoidSurvivorBody" : "RailgunnerBody"); if (Util2.PlaysAs(((BaseServerAchievement)this).networkUser, bodyName)) { ((BaseServerAchievement)this).Grant(); } } } } [RegisterAchievement("BinmaSummerRailgunner", "Skins.Binma.BinmaSummerRailgunner", null, 5u, typeof(SummerServer))] public class SummerRailAchievement : ServerTrackedAchievement { } [RegisterAchievement("BinmaSummerVoidFiend", "Skins.Binma.BinmaSummerVoidFiend", "CompleteVoidEnding", 5u, typeof(SummerServer))] public class SummerVoidAchievement : ServerTrackedAchievement { } [RegisterAchievement("BinmaSolusRailgunnerPurge", "Skins.Binma.BinmaSolusRailgunnerPurge", null, 5u, typeof(KillSolusHeartServer))] public class SolusRailAchievement : BasePerSurvivorPurgeAchievement { protected class KillSolusHeartServer : BasePerSurvivorKillSolusHeartServerAchievement { } protected override BodyIndex LookUpRequiredBodyIndex() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) return BodyCatalog.FindBodyIndex("RailgunnerBody"); } } [RegisterAchievement("BinmaSteelConvictionCaptain", "Skins.Binma.BinmaSteelConvictionCaptain", "CompleteMainEnding", 5u, null)] public class SteelCaptainAchievement : BaseAchievement { internal static readonly string[] Bosses = new string[4] { "RoboBallBossBody", "SuperRoboBallBossBody", "VultureHunterBody", "SolusAmalgamatorBody" }; private static readonly Dictionary<UserProfile, HashSet<string>> thisRun = new Dictionary<UserProfile, HashSet<string>>(); private static bool hooked; internal static event Action<UserProfile, StatSheet> OnStatDelta; internal static void RaiseDelta(UserProfile p, StatSheet d) { SteelCaptainAchievement.OnStatDelta?.Invoke(p, d); } protected override BodyIndex LookUpRequiredBodyIndex() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) return BodyCatalog.FindBodyIndex("CaptainBody"); } protected override void OnBodyRequirementMet() { ((BaseAchievement)this).OnBodyRequirementMet(); if (!hooked) { hooked = true; Run.onRunStartGlobal += delegate { thisRun.Clear(); }; } OnStatDelta += Handle; } protected override void OnBodyRequirementBroken() { OnStatDelta -= Handle; ((BaseAchievement)this).OnBodyRequirementBroken(); } private static double Get(StatSheet sheet, PerBodyStatDef def, string body) { StatDef val = def.FindStatDef(body); return (val == null) ? 0.0 : sheet.GetStatValueAsDouble(val); } private void Handle(UserProfile profile, StatSheet delta) { try { if (profile != ((BaseAchievement)this).userProfile || delta == null) { return; } if (!thisRun.TryGetValue(profile, out var value)) { value = (thisRun[profile] = new HashSet<string>()); } string[] bosses = Bosses; foreach (string text in bosses) { if (Get(delta, PerBodyStatDef.damageDealtTo, text) > 0.0 || Get(delta, PerBodyStatDef.killsAgainst, text) > 0.0) { value.Add(text); } } if ((value.Contains("RoboBallBossBody") || value.Contains("SuperRoboBallBossBody")) && value.Contains("VultureHunterBody") && value.Contains("SolusAmalgamatorBody")) { ((BaseAchievement)this).Grant(); } } catch (Exception ex) { Plugin.Log.LogError((object)ex); } } } [HarmonyPatch(typeof(UserProfile), "ApplyDeltaStatSheet")] internal static class StatDeltaPatch { private static void Postfix(UserProfile __instance, StatSheet __0) { try { SteelCaptainAchievement.RaiseDelta(__instance, __0); } catch (Exception ex) { Plugin.Log.LogError((object)ex); } } } public abstract class JudgementAchievement : ServerTrackedAchievement { } public class JudgementServer : BaseServerAchievement { public override void OnInstall() { ((BaseServerAchievement)this).OnInstall(); Ending.onArraignDefeated += Handle; } public override void OnUninstall() { Ending.onArraignDefeated -= Handle; ((BaseServerAchievement)this).OnUninstall(); } private void Handle() { if (base.achievementDef != null && Plugin.JudgementBodies.TryGetValue(base.achievementDef.identifier, out var value) && Util2.PlaysAs(((BaseServerAchievement)this).networkUser, value)) { ((BaseServerAchievement)this).Grant(); } } } [RegisterAchievement("BinmaJudgementCommando", "Skins.Binma.BinmaJudgementCommando", null, 5u, typeof(JudgementServer))] public class JudgementCommando : JudgementAchievement { } [RegisterAchievement("BinmaJudgementHuntress", "Skins.Binma.BinmaJudgementHuntress", null, 5u, typeof(JudgementServer))] public class JudgementHuntress : JudgementAchievement { } [RegisterAchievement("BinmaJudgementAcrid", "Skins.Binma.BinmaJudgementAcrid", null, 5u, typeof(JudgementServer))] public class JudgementAcrid : JudgementAchievement { } [RegisterAchievement("BinmaJudgementLoader", "Skins.Binma.BinmaJudgementLoader", null, 5u, typeof(JudgementServer))] public class JudgementLoader : JudgementAchievement { } [RegisterAchievement("BinmaJudgementEngi", "Skins.Binma.BinmaJudgementEngi", null, 5u, typeof(JudgementServer))] public class JudgementEngi : JudgementAchievement { } [RegisterAchievement("BinmaJudgementMerc", "Skins.Binma.BinmaJudgementMerc", null, 5u, typeof(JudgementServer))] public class JudgementMerc : JudgementAchievement { } [RegisterAchievement("BinmaJudgementBandit", "Skins.Binma.BinmaJudgementBandit", null, 5u, typeof(JudgementServer))] public class JudgementBandit : JudgementAchievement { } [RegisterAchievement("BinmaJudgementArtificer", "Skins.Binma.BinmaJudgementArtificer", null, 5u, typeof(JudgementServer))] public class JudgementArtificer : JudgementAchievement { } [RegisterAchievement("BinmaJudgementDrifter", "Skins.Binma.BinmaJudgementDrifter", null, 5u, typeof(JudgementServer))] public class JudgementDrifter : JudgementAchievement { }