using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Obeliskial_Essentials;
using SeedSearcher;
using TMPro;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("com.binbin.SeedSearcher")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.2.1.0")]
[assembly: AssemblyInformationalVersion("1.2.1+90a59480a5955f0298d8545d002e28e90e726953")]
[assembly: AssemblyProduct("SeedSearcher")]
[assembly: AssemblyTitle("com.binbin.SeedSearcher")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
public static class EssentialsCompatibility
{
private static bool? _enabled;
public static bool Enabled
{
get
{
bool valueOrDefault = _enabled.GetValueOrDefault();
if (!_enabled.HasValue)
{
valueOrDefault = Chainloader.PluginInfos.ContainsKey("com.stiffmeds.obeliskialessentials");
_enabled = valueOrDefault;
}
return _enabled.Value;
}
}
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
public static void EssentialsRegister()
{
Essentials.RegisterMod(Plugin.PluginName, "binbin", "Seed Searcher", Plugin.PluginVersion, Plugin.ModDate, "https://github.com/binbinmods/SeedSearcher", (string[])null, "", 100, (string[])null, "", true);
Plugin.LogInfo(Plugin.PluginGUID + " " + Plugin.PluginVersion + " has loaded with Essentials!");
}
}
[Serializable]
public class ItemObject
{
public string Id { get; set; }
public string Name { get; set; }
public bool Droponly { get; set; }
public string CardUpgraded { get; set; }
public string UpgradesToRareId { get; set; }
public int PercentRetentionEndGame { get; set; }
public int PercentDiscountShop { get; set; }
public string CardRarity { get; set; }
public string CardType { get; set; }
public ItemObject(string name, CardData cardData)
{
//IL_0026: 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_0083: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_009d: Unknown result type (might be due to invalid IL or missing references)
//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
Id = name;
Name = cardData.CardName;
Droponly = cardData.Item.DropOnly;
CardUpgraded cardUpgraded = cardData.CardUpgraded;
CardUpgraded = ((object)(CardUpgraded)(ref cardUpgraded)).ToString();
CardData upgradesToRare = cardData.UpgradesToRare;
UpgradesToRareId = ((upgradesToRare != null) ? upgradesToRare.Id : null) ?? "";
PercentRetentionEndGame = cardData.Item.PercentRetentionEndGame;
PercentDiscountShop = cardData.Item.PercentDiscountShop;
CardRarity cardRarity = cardData.CardRarity;
CardRarity = ((object)(CardRarity)(ref cardRarity)).ToString();
CardType cardType = cardData.CardType;
CardType = ((object)(CardType)(ref cardType)).ToString();
base..ctor();
}
}
namespace SeedSearcher
{
[BepInPlugin("com.binbin.SeedSearcher", "SeedSearcher", "1.2.1")]
[BepInProcess("AcrossTheObelisk.exe")]
public class Plugin : BaseUnityPlugin
{
public static string PluginName;
public static string PluginVersion;
public static string PluginGUID;
internal static int ModDate = int.Parse(DateTime.Today.ToString("yyyyMMdd"));
private readonly Harmony harmony = new Harmony("com.binbin.SeedSearcher");
internal static ManualLogSource Log;
public static string debugBase = "com.binbin.SeedSearcher ";
public static ConfigEntry<bool> EnableMod { get; set; }
public static ConfigEntry<bool> SearchForItemsOnStartup { get; set; }
public static ConfigEntry<int> MadnessLevel { get; set; }
public static ConfigEntry<int> CorruptorCount { get; set; }
public static ConfigEntry<bool> PovertyEnabled { get; set; }
public static ConfigEntry<bool> StopSearchOnSeedFound { get; set; }
public static ConfigEntry<bool> SaveSeedToGame { get; set; }
public static ConfigEntry<bool> BypassMadnessRandomization { get; set; }
public static ConfigEntry<int> NumberOfSeeds { get; set; }
public static ConfigEntry<string> LocationToSearchForItem1 { get; set; }
public static ConfigEntry<string> LocationToSearchForItem2 { get; set; }
public static ConfigEntry<string> LocationToSearchForItem3 { get; set; }
public static ConfigEntry<string> LocationToSearchForItem4 { get; set; }
public static ConfigEntry<string> ItemToSearchFor1 { get; set; }
public static ConfigEntry<string> ItemToSearchFor2 { get; set; }
public static ConfigEntry<string> ItemToSearchFor3 { get; set; }
public static ConfigEntry<string> ItemToSearchFor4 { get; set; }
public static ConfigEntry<bool> SearchForItemsOnChange { get; set; }
public static ConfigEntry<bool> WriteItemsToTextFile { get; set; }
public static ConfigEntry<string> WriteItemsToTextFilePath { get; set; }
private void Awake()
{
//IL_002e: 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_0049: Expected O, but got Unknown
//IL_0049: Expected O, but got Unknown
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: Expected O, but got Unknown
//IL_0076: Expected O, but got Unknown
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_0099: Unknown result type (might be due to invalid IL or missing references)
//IL_00a3: Expected O, but got Unknown
//IL_00a3: Expected O, but got Unknown
//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
//IL_00d0: Expected O, but got Unknown
//IL_00d0: Expected O, but got Unknown
//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
//IL_00fd: Expected O, but got Unknown
//IL_00fd: Expected O, but got Unknown
//IL_010f: Unknown result type (might be due to invalid IL or missing references)
//IL_0120: Unknown result type (might be due to invalid IL or missing references)
//IL_012a: Expected O, but got Unknown
//IL_012a: Expected O, but got Unknown
//IL_013c: 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_0157: Expected O, but got Unknown
//IL_0157: Expected O, but got Unknown
//IL_0169: Unknown result type (might be due to invalid IL or missing references)
//IL_017a: Unknown result type (might be due to invalid IL or missing references)
//IL_0184: Expected O, but got Unknown
//IL_0184: Expected O, but got Unknown
//IL_0196: 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_01b5: Expected O, but got Unknown
//IL_01b5: Expected O, but got Unknown
//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
//IL_0206: Expected O, but got Unknown
//IL_0206: Expected O, but got Unknown
//IL_0218: Unknown result type (might be due to invalid IL or missing references)
//IL_022d: Unknown result type (might be due to invalid IL or missing references)
//IL_0237: Expected O, but got Unknown
//IL_0237: Expected O, but got Unknown
//IL_0249: Unknown result type (might be due to invalid IL or missing references)
//IL_025e: Unknown result type (might be due to invalid IL or missing references)
//IL_0268: Expected O, but got Unknown
//IL_0268: Expected O, but got Unknown
//IL_027a: Unknown result type (might be due to invalid IL or missing references)
//IL_028f: Unknown result type (might be due to invalid IL or missing references)
//IL_0299: Expected O, but got Unknown
//IL_0299: Expected O, but got Unknown
//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
//IL_02ca: Expected O, but got Unknown
//IL_02ca: Expected O, but got Unknown
//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
//IL_02f1: Unknown result type (might be due to invalid IL or missing references)
//IL_02fb: Expected O, but got Unknown
//IL_02fb: Expected O, but got Unknown
//IL_030d: Unknown result type (might be due to invalid IL or missing references)
//IL_0322: Unknown result type (might be due to invalid IL or missing references)
//IL_032c: Expected O, but got Unknown
//IL_032c: Expected O, but got Unknown
//IL_033e: Unknown result type (might be due to invalid IL or missing references)
//IL_0353: Unknown result type (might be due to invalid IL or missing references)
//IL_035d: Expected O, but got Unknown
//IL_035d: Expected O, but got Unknown
//IL_036f: Unknown result type (might be due to invalid IL or missing references)
//IL_0380: Unknown result type (might be due to invalid IL or missing references)
//IL_038a: Expected O, but got Unknown
//IL_038a: Expected O, but got Unknown
//IL_039c: Unknown result type (might be due to invalid IL or missing references)
//IL_03ad: Unknown result type (might be due to invalid IL or missing references)
//IL_03b7: Expected O, but got Unknown
//IL_03b7: Expected O, but got Unknown
//IL_03c9: Unknown result type (might be due to invalid IL or missing references)
//IL_03de: Unknown result type (might be due to invalid IL or missing references)
//IL_03e8: Expected O, but got Unknown
//IL_03e8: Expected O, but got Unknown
Log = ((BaseUnityPlugin)this).Logger;
Log.LogInfo((object)"com.binbin.SeedSearcher 1.2.1 has loaded!");
string text = "SeedSearcher";
EnableMod = ((BaseUnityPlugin)this).Config.Bind<bool>(new ConfigDefinition(text, "EnableMod"), true, new ConfigDescription("If false, disables the mod. Restart the game upon changing this setting.", (AcceptableValueBase)null, Array.Empty<object>()));
SearchForItemsOnStartup = ((BaseUnityPlugin)this).Config.Bind<bool>(new ConfigDefinition(text, "SearchForItemsOnStartup"), false, new ConfigDescription("Has the game search through seeds on startup for a predefined list of items. Items are stored in the LogOutput.log file. To execute, set this value to true and then restart your game. ", (AcceptableValueBase)null, Array.Empty<object>()));
MadnessLevel = ((BaseUnityPlugin)this).Config.Bind<int>(new ConfigDefinition(text, "MadnessLevel"), 1, new ConfigDescription("Madness level to search through. 0 - 9. Purple items cannot spawn if Madness Level is 0.", (AcceptableValueBase)null, Array.Empty<object>()));
CorruptorCount = ((BaseUnityPlugin)this).Config.Bind<int>(new ConfigDefinition(text, "CorruptorCount"), 0, new ConfigDescription("Corruptor count to search through. 0 - 9. Purple items are more common at higher corruptor counts.", (AcceptableValueBase)null, Array.Empty<object>()));
PovertyEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>(new ConfigDefinition(text, "PovertyEnabled"), false, new ConfigDescription("If true, will search through seeds with poverty enabled.", (AcceptableValueBase)null, Array.Empty<object>()));
StopSearchOnSeedFound = ((BaseUnityPlugin)this).Config.Bind<bool>(new ConfigDefinition(text, "StopSearchOnSeedFound"), false, new ConfigDescription("If true, will stop searching through seeds when a seed with the items set in the menu is found.", (AcceptableValueBase)null, Array.Empty<object>()));
SaveSeedToGame = ((BaseUnityPlugin)this).Config.Bind<bool>(new ConfigDefinition(text, "SaveSeedToGame"), true, new ConfigDescription("If true, will save the seed to the game. Only works if StopSearchOnSeedFound is true.", (AcceptableValueBase)null, Array.Empty<object>()));
BypassMadnessRandomization = ((BaseUnityPlugin)this).Config.Bind<bool>(new ConfigDefinition(text, "BypassMadnessRandomization"), true, new ConfigDescription("If true, will bypass the seed randomization on High Madness. Works for any seed, not just ones found by this mod.", (AcceptableValueBase)null, Array.Empty<object>()));
NumberOfSeeds = ((BaseUnityPlugin)this).Config.Bind<int>(new ConfigDefinition(text, "Seeds to Search"), 200000, new ConfigDescription("Maximum number of seeds to search through (I believe it takes around 2 minutes to search through 1 million seeds)", (AcceptableValueBase)null, Array.Empty<object>()));
AcceptableValueList<string> val = new AcceptableValueList<string>(GetItemList().ToArray());
AcceptableValueList<string> val2 = new AcceptableValueList<string>(GetLocationList().ToArray());
LocationToSearchForItem1 = ((BaseUnityPlugin)this).Config.Bind<string>(new ConfigDefinition(text, "LocationToSearchForItem1"), "caravanshop", new ConfigDescription("Location to search for the first item", (AcceptableValueBase)(object)val2, Array.Empty<object>()));
ItemToSearchFor1 = ((BaseUnityPlugin)this).Config.Bind<string>(new ConfigDefinition(text, "ItemToSearchFor1"), "cheese", new ConfigDescription("First item to search for in the caravanshop", (AcceptableValueBase)(object)val, Array.Empty<object>()));
LocationToSearchForItem2 = ((BaseUnityPlugin)this).Config.Bind<string>(new ConfigDefinition(text, "LocationToSearchForItem2"), "caravanshop", new ConfigDescription("Location to search for the second item", (AcceptableValueBase)(object)val2, Array.Empty<object>()));
ItemToSearchFor2 = ((BaseUnityPlugin)this).Config.Bind<string>(new ConfigDefinition(text, "ItemToSearchFor2"), "cheese", new ConfigDescription("Second item to search for in the caravanshop", (AcceptableValueBase)(object)val, Array.Empty<object>()));
LocationToSearchForItem3 = ((BaseUnityPlugin)this).Config.Bind<string>(new ConfigDefinition(text, "LocationToSearchForItem3"), "caravanshop", new ConfigDescription("Location to search for the third item", (AcceptableValueBase)(object)val2, Array.Empty<object>()));
ItemToSearchFor3 = ((BaseUnityPlugin)this).Config.Bind<string>(new ConfigDefinition(text, "ItemToSearchFor3"), "cheese", new ConfigDescription("Third item to search for in the caravanshop", (AcceptableValueBase)(object)val, Array.Empty<object>()));
LocationToSearchForItem4 = ((BaseUnityPlugin)this).Config.Bind<string>(new ConfigDefinition(text, "LocationToSearchForItem4"), "caravanshop", new ConfigDescription("Location to search for the fourth item", (AcceptableValueBase)(object)val2, Array.Empty<object>()));
ItemToSearchFor4 = ((BaseUnityPlugin)this).Config.Bind<string>(new ConfigDefinition(text, "ItemToSearchFor4"), "cheese", new ConfigDescription("Fourth item to search for in the caravanshop", (AcceptableValueBase)(object)val, Array.Empty<object>()));
SearchForItemsOnChange = ((BaseUnityPlugin)this).Config.Bind<bool>(new ConfigDefinition(text, "SearchForItemsOnChange"), false, new ConfigDescription("When clicked, will search through seeds for the items. May cause the game to temporarily freeze.", (AcceptableValueBase)null, Array.Empty<object>()));
WriteItemsToTextFile = ((BaseUnityPlugin)this).Config.Bind<bool>(new ConfigDefinition(text, "WriteItemsToTextFile"), false, new ConfigDescription("If true, when this config is saved, write the items to a text file. File will be saved according to the file path set in the next setting.", (AcceptableValueBase)null, Array.Empty<object>()));
WriteItemsToTextFilePath = ((BaseUnityPlugin)this).Config.Bind<string>(new ConfigDefinition(text, "WriteItemsToTextFilePath"), "AllItems.txt", new ConfigDescription("File path to the text file to write the items to. Default is in the BepInEx/logs folder. Use a relative path to the BepInEx/logs folder.", (AcceptableValueBase)null, Array.Empty<object>()));
WriteItemsToTextFilePath.SettingChanged += delegate
{
if (WriteItemsToTextFile.Value)
{
LogInfo("Writing items to text file");
SeedSearcherFunctions.WriteItemsToText();
WriteItemsToTextFile.Value = false;
}
};
SearchForItemsOnChange.SettingChanged += delegate
{
if (SearchForItemsOnChange.Value)
{
LogInfo("Searching for items on change");
SeedSearcherFunctions.ExecuteSearch();
SearchForItemsOnChange.Value = false;
}
};
PluginName = "SeedSearcher";
PluginVersion = "1.2.1";
PluginGUID = "com.binbin.SeedSearcher";
if (EnableMod.Value)
{
if (EssentialsCompatibility.Enabled)
{
EssentialsCompatibility.EssentialsRegister();
}
else
{
LogInfo(PluginGUID + " " + PluginVersion + " has loaded!");
}
harmony.PatchAll();
}
}
internal static void LogDebug(string msg)
{
Log.LogDebug((object)(debugBase + msg));
}
internal static void LogInfo(string msg)
{
Log.LogInfo((object)(debugBase + msg));
}
internal static void LogError(string msg)
{
Log.LogError((object)(debugBase + msg));
}
public static List<string> GetItemList()
{
if ((Object)(object)Globals.Instance != (Object)null)
{
return Globals.Instance.CardListByClass[(CardClass)8];
}
return new List<string>
{
"acolytetunic", "acolytetunicrare", "advancedhandbook", "advancedhandbookrare", "aegis", "aegisrare", "agateamulet", "agateamuletrare", "alarmbell", "alarmbellrare",
"albatrosspendant", "albatrosspendantrare", "alchemypot", "alchemypotrare", "allseeingamulet", "allseeingamuletrare", "amberamulet", "amberamuletrare", "amethystring", "amethystringrare",
"amuletofprotection", "amuletofprotectionrare", "amuletofspeed", "amuletofspeedrare", "amuletofthorns", "amuletofthornsrare", "ankhoflife", "ankhofliferare", "antiquefigurine", "antiquefigurinerare",
"aquamarinebracelet", "aquamarinebraceletrare", "architectsring", "architectsringrare", "archmagebook", "archmagebookrare", "asmody", "asmodyrare", "assassintools", "assassintoolsrare",
"avoidancecollar", "avoidancecollarrare", "ballofwool", "ballofwoolrare", "bandages", "bandagesrare", "bastion", "bastionrare", "batsy", "batsyrare",
"battleaxe", "battleaxerare", "beermug", "beermugrare", "bell", "bellrare", "belphyorpipe", "belphyorpiperare", "berserkerclaw", "berserkerclawrare",
"berserkpotion", "berserkpotionrare", "betty", "bettyrare", "blackdeck", "blackdeckrare", "blackguard", "blackguardrare", "blackpyramid", "blackpyramidrare",
"bloodamulet", "bloodamuleta", "bloodamuletb", "bloodamuletrare", "bloodblobpet", "bloodblobpetrare", "blooddguard", "blooddguardrare", "bloodgoblet", "bloodgobletrare",
"bloodlettersfang", "bloodlettersfangrare", "bloodseeker", "bloodseekerrare", "bloodstone", "bloodstonerare", "blowgun", "blowgunrare", "bluefeather", "bluefeatherrare",
"blueprints", "blueprintsrare", "blunderbluss", "blunderblussrare", "boneclaws", "boneclawsa", "boneclawsb", "boneclawsrare", "bonering", "boneringrare",
"bonkhammer", "bonkhammerrare", "bootsofswiftness", "bootsofswiftnessrare", "brassamulet", "brassamuletrare", "brasslantern", "brasslanternrare", "breastplate", "breastplaterare",
"brigandarmor", "brigandarmorrare", "brokenitem", "bronzegear", "bronzegearrare", "bucket", "bucketrare", "bunny", "bunnyrare", "burialmask",
"burialmaskrare", "burneditem", "burningorb", "burningorbrare", "butcherblock", "butcherblockrare", "butchersknife", "butcherskniferare", "cauldron", "cauldronrare",
"chaliceofkings", "chaliceofkingsrare", "chaliceofqueens", "chaliceofqueensrare", "champy", "champyrare", "chaosblobpet", "chaosblobpetrare", "chaoticspear", "chaoticspearrare",
"chargedtrident", "chargedtridentrare", "cheese", "cheeserare", "chompy", "chompyrare", "chumpy", "chumpyrare", "clairvoyantscroll", "clairvoyantscrollrare",
"clergyamulet", "clergyamuletrare", "cloackofevasion", "cloackofevasionrare", "cloackofspeed", "cloackofspeedrare", "cloudsong", "cloudsongrare", "club", "clubrare",
"coldbonegoblet", "coldbonegobletrare", "coldbook", "coldbookrare", "coldrune", "coldrunerare", "combatbandages", "combatbandagesa", "combatbandagesb", "combatbandagesrare",
"compass", "compassrare", "continuumblade", "continuumbladerare", "coolingservos", "coolingservosrare", "corruptedplate", "corruptedplatea", "corruptedplateb", "corruptedplaterare",
"corsairhat", "corsairhatrare", "countsamulet", "countsamuletrare", "countscloak", "countscloakrare", "crankcrossbow", "crankcrossbowrare", "crescentmoon", "crescentmoonrare",
"crimsonraiment", "crimsonraimentrare", "crossbow", "crossbowrare", "crusaderhelmet", "crusaderhelmetrare", "crystalball", "crystalballrare", "cuby", "cubyd",
"cubydrare", "cubyrare", "cupcake", "cupcakerare", "cupofdeath", "cupofdeathrare", "curseddagger", "curseddaggerrare", "cursedjewelersring", "dagger",
"daggerrare", "daley", "daleyrare", "darkblobpet", "darkblobpetrare", "darkflamering", "darkflameringrare", "darkhood", "darkhoodrare", "dartpouch",
"dartpouchrare", "deformeditem", "desertjam", "desertjamrare", "dessert", "dessertrare", "destiny", "destinyrare", "destroyergauntlets", "destroyergauntletsrare",
"detoxpotion", "detoxpotionrare", "diamondring", "diamondringrare", "dimensionalcrystal", "dimensionalcrystalrare", "dirtybandages", "dirtybandagesrare", "divinationorb", "divinationorbrare",
"divinghelmet", "divinghelmetrare", "dracomancerstaff", "dracomancerstaffrare", "dreamcatcher", "dreamcatcherrare", "dreamsphere", "dreamsphererare", "druidicamulet", "druidicamuletrare",
"dryadmask", "dryadmaskrare", "durandal", "durandalrare", "duskforgedarmor", "duskforgedarmora", "duskforgedarmorb", "duskforgedarmorrare", "dwarvenhelmet", "dwarvenhelmetrare",
"dynamite", "dynamiterare", "edgeoffury", "edgeoffuryrare", "eeriering", "eerieringrare", "eldritchcloak", "eldritchcloakrare", "eldritchring", "eldritchringrare",
"eldritchsword", "eldritchswordrare", "eldritchwand", "eldritchwandrare", "electricblobpet", "electricblobpetrare", "elvencuirass", "elvencuirassrare", "elvenquiver", "elvenquiverrare",
"emeraldnecklace", "emeraldnecklacerare", "emeraldstaff", "emeraldstaffrare", "endlessbag", "endlessbagrare", "energyshield", "energyshieldrare", "eternalcandle", "eternalcandlerare",
"exoticspices", "exoticspicesrare", "faeborgscale", "faeborgscalerare", "faithring", "faithringrare", "familyjewels", "familyjewelsa", "familyjewelsb", "familyjewelsrare",
"featherearring", "featherearringrare", "fenny", "fennyrare", "ferventring", "ferventringrare", "fierywand", "fierywandrare", "firebook", "firebookrare",
"firerune", "firerunerare", "fishbonesoup", "fishbonesouprare", "fishcage", "fishcagerare", "fishingrod", "fishingrodrare", "fistofthedamned", "fistofthedamnedrare",
"flail", "flailrare", "flamingsword", "flamingswordrare", "flamy", "flamyrare", "floaty", "floatyrare", "flute", "fluterare",
"forestbanner", "forestbannera", "forestbannerb", "forestbannerrare", "forestcrown", "forestcrownrare", "fork", "forkrare", "fountainpen", "fountainpenrare",
"fourleafclover", "fourleafcloverrare", "freelover", "freeloverrare", "freezingink", "freezinginkrare", "frostaxe", "frostaxerare", "frostfirering", "frostfireringrare",
"frostguard", "frostguardrare", "frozenarrows", "frozenarrowsrare", "frozenheirloom", "frozenheirloomrare", "frozenorb", "frozenorbrare", "frozentear", "frozentearrare",
"garnetearrings", "garnetearringsrare", "gauntlets", "gauntletsrare", "gihlrunestone", "gihlrunestonerare", "gildedplate", "gildedplatea", "gildedplateb", "gildedplaterare",
"glacialhammer", "glacialhammerrare", "gladiatorhelmet", "gladiatorhelmetrare", "gloves", "glovesofagility", "glovesofagilityrare", "glovesrare", "goblinamulet", "goblinamuletrare",
"goggles", "gogglesrare", "goldchain", "goldchainrare", "goldenbell", "goldenbellrare", "goldenchalice", "goldenchalicerare", "goldencloak", "goldencloakrare",
"goldencross", "goldencrossrare", "goldenharp", "goldenharprare", "goldenlaurel", "goldenlaurelrare", "goldring", "goldringrare", "greaterhealthpotion", "greaterhealthpotionrare",
"greatermanapotion", "greatermanapotionrare", "handbook", "handbookrare", "harbingerofdeath", "harbingerofdeathrare", "healingbook", "healingbookrare", "healthpotion", "healthpotionrare",
"heartamulet", "heartamuletrare", "heartofthorns", "heartofthornsrare", "heavybelt", "heavybeltrare", "heavypackage", "hellblade", "hellbladerare", "helmet",
"helmetrare", "hightchancellorstaff", "hightchancellorstaffa", "hightchancellorstaffb", "hightchancellorstaffrare", "holyblobpet", "holyblobpetrare", "holybook", "holybookrare", "holygrail",
"holygrailrare", "holyhammer", "holyhammerrare", "holyrune", "holyrunerare", "hornethelmet", "hornethelmetrare", "hourglassofdeath", "hourglassofdeathrare", "hunterscharm",
"hunterscharmrare", "hunterswhip", "hunterswhiprare", "huntingring", "huntingringrare", "hydraegg", "hydraeggrare", "hypnoshell", "hypnoshellrare", "icebreaker",
"icebreakerrare", "iceorb", "iceorbrare", "icyblobpet", "icyblobpetrare", "icywand", "icywandrare", "ignidohscore", "ignidohscorerare", "igniscloack",
"igniscloackrare", "impstatuette", "impstatuetterare", "infusedgem", "infusedgemrare", "inky", "inkyrare", "ironfortress", "ironfortressrare", "ironkanabo",
"ironkanaborare", "ironwand", "ironwandrare", "jadering", "jaderingrare", "jelly", "jellyrare", "jewelersring", "jewelersringrare", "jinglebell",
"jinglebella", "jinglebellb", "jinglebellrare", "jollyroger", "jollyrogerrare", "justicarring", "justicarringrare", "kingmaker", "kingmakerrare", "kiteshield",
"kiteshieldrare", "krakensushi", "krakensushirare", "lapisnecklace", "lapisnecklacerare", "largepouch", "largepouchrare", "largeshield", "largeshieldrare", "lavablobpet",
"lavablobpetrare", "lavacrystal", "lavacrystalrare", "lavaorb", "lavaorbrare", "lavapotion", "lavapotionrare", "leatherarmor", "leatherarmorrare", "leatherboots",
"leatherbootsrare", "leathergloves", "leatherglovesrare", "liante", "lianterare", "lifebindersashes", "lifebindersashesrare", "lifeessence", "lifeessencerare", "lightbringer",
"lightbringerrare", "lightningbook", "lightningbookrare", "lightningrune", "lightningrunerare", "lightningspear", "lightningspearrare", "lockpicks", "lockpicksrare", "longbow",
"longbowrare", "longevitypotion", "longevitypotiona", "longevitypotionb", "longevitypotionrare", "lostmail", "lostmailrare", "luckypaw", "luckypawrare", "lunaring",
"lunaringrare", "lychee", "lycheerare", "machineoil", "machineoilrare", "madnessring", "madnessringrare", "magictome", "magictomerare", "magusstaff",
"magusstaffrare", "manaloop", "manalooprare", "manapotion", "manapotionrare", "maskofanger", "maskofangerrare", "maskofjoy", "maskofjoyrare", "maskoftolerance",
"maskoftolerancerare", "matey", "mateyrare", "matriarchsclaw", "matriarchsclawrare", "megaphone", "megaphonerare", "merchantbadge", "merchantbadgerare", "metalblobpet",
"metalblobpetrare", "midnightgloves", "midnightglovesrare", "mildbroth", "mildbrothrare", "mimy", "mimyrare", "mindbook", "mindbookrare", "minotaurhorn",
"minotaurhornrare", "mirrorofkalandra", "mirrorofkalandrarare", "mixedsalad", "mixedsaladrare", "mjolnir", "mjolnirrare", "mnemrunestone", "mnemrunestonerare", "morningstar",
"morningstarrare", "mortarandpestle", "mortarandpestlerare", "mountainking", "mountainkingrare", "mozzy", "mozzyrare", "mysticstaff", "mysticstaffrare", "necromancerrobe",
"necromancerroberare", "netherblade", "netherbladerare", "neverfrost", "neverfrostrare", "nightveil", "nightveilrare", "ninjascroll", "ninjascrollrare", "nobleshield",
"nobleshieldrare", "nullifier", "nullifierrare", "obeliskscroll", "obeliskscrollrare", "obsidiandagger", "obsidiandaggerrare", "obsidianring", "obsidianringrare", "obsidianrod",
"obsidianrodrare", "oculy", "oculyrare", "oldhorseshoe", "oldhorseshoerare", "onyxamulet", "onyxamuletrare", "opalring", "opalringrare", "orbofstorms",
"orbofstormsrare", "orby", "orbyrare", "osmiumfeet", "osmiumfeetrare", "paladingauntlets", "paladingauntletsrare", "pancakes", "pancakesrare", "pandorasbox",
"pandorasboxrare", "pearlbelt", "pearlbeltrare", "penitencering", "penitenceringrare", "piggybank", "piousring", "piousringrare", "pirategrog", "pirategrograre",
"piratehat", "piratehatrare", "platemail", "platemailrare", "platinumring", "platinumringrare", "pointyhat", "pointyhatrare", "poisoneddagger", "poisoneddaggerrare",
"powdercask", "powdercaskrare", "powercoil", "powercoilrare", "powerglove", "powerglovea", "powergloveb", "powergloverare", "primalnecklace", "primalnecklacerare",
"prophetstaff", "prophetstaffa", "prophetstaffb", "prophetstaffrare", "purpletentacle", "purpletentaclerare", "pyromancerrobe", "pyromancerroberare", "quill", "quillrare",
"raggeddoll", "raggeddolla", "raggeddollb", "raggeddollrare", "raiderslicer", "raiderslicerrare", "raincoat", "raincoatrare", "rangerarmor", "rangerarmora",
"rangerarmorb", "rangerarmorrare", "ravenstaff", "ravenstaffrare", "razor", "razorrare", "redcape", "redcaperare", "redfeather", "redfeatherrare",
"redsteelcloack", "redsteelcloackrare", "reforgedcore", "reforgedcorea", "reforgedcoreb", "reforgedcorerare", "reinforcedarmor", "reinforcedarmorrare", "rejuvenationpotion", "rejuvenationpotionrare",
"retaliator", "retaliatorrare", "riftshard", "riftshardrare", "riftshield", "riftshieldrare", "rifty", "riftyrare", "ringoffire", "ringoffirerare",
"ringofhope", "ringofhoperare", "ringofprotection", "ringofprotectionrare", "ritualdagger", "ritualdaggerrare", "rocketboots", "rocketbootsa", "rocketbootsb", "rocketbootsrare",
"rocky", "rockyrare", "roundshield", "roundshieldrare", "royalcoin", "royalcoinrare", "rubyamulet", "rubyamuletrare", "rubycuirass", "rubycuirassrare",
"rudder", "rudderrare", "runicdice", "runicdicerare", "runicring", "runicringrare", "rustyarmor", "rustyarmorrare", "rustyboots", "rustybootsrare",
"rustyhook", "rustyhookrare", "rustyring", "rustyringrare", "sacredaxe", "sacredaxerare", "sacredtablet", "sacredtabletrare", "sahtipendant", "sahtipendantrare",
"salt", "saltrare", "samuraiarmor", "samuraiarmorrare", "sapphireamulet", "sapphireamuletrare", "sapphirering", "sapphireringrare", "savantrobe", "savantroberare",
"scarabshield", "scarabshieldrare", "scaraby", "scarabyrare", "scholarrobe", "scholarroberare", "screwdriver", "screwdriverrare", "scrollofresurrection", "scrollofresurrectionrare",
"scryerstaff", "scryerstaffrare", "searingdagger", "searingdaggerrare", "seashell", "seashellamulet", "seashellamuletrare", "seashellrare", "seashellring", "seashellringrare",
"serenityring", "serenityringrare", "sextant", "sextantrare", "shacklesofwar", "shacklesofwarrare", "shadowbook", "shadowbookrare", "shadowcloack", "shadowcloackrare",
"shadoworb", "shadoworbrare", "shadowrune", "shadowrunerare", "sharpscimitar", "sharpscimitarrare", "sharpy", "sharpyrare", "shieldofthorns", "shieldofthornsrare",
"shortsword", "shortswordrare", "shoulderplate", "shoulderplaterare", "sidearm", "sidearmrare", "silverchalice", "silverchalicerare", "silverring", "silverringrare",
"simplehat", "simplehatrare", "singingsword", "singingswordrare", "slimy", "slimyrare", "slingshot", "slingshotrare", "slippers", "slippersrare",
"smallchest", "smallchestrare", "smallpouch", "smallpouchrare", "soap", "soaprare", "solring", "solringrare", "soullantern", "soullanterna",
"soullanternb", "soullanternrare", "soulreaver", "soulreaverrare", "spear", "spearrare", "spicydish", "spicydishrare", "spiderqueeneye", "spiderqueeneyerare",
"spikedbracers", "spikedbracersrare", "spikedshoulderpads", "spikedshoulderpadsrare", "spikygauntlets", "spikygauntletsrare", "spooky", "spookyrare", "spyglass", "spyglassrare",
"squidtoken", "stainlesscuirass", "stainlesscuirassrare", "steadfastboots", "steadfastbootsrare", "steadfastshield", "steadfastshieldrare", "steelrod", "steelrodrare", "stimulantpills",
"stimulantpillsrare", "stoneamulet", "stoneamuletrare", "stonemaul", "stonemaulrare", "stormcallerfeather", "stormcallerfeatherrare", "storminabottle", "storminabottlerare", "stormtiara",
"stormtiararare", "stormy", "stormyrare", "strawhat", "strawhatrare", "strongmojo", "strongmojorare", "suppressionhelmet", "suppressionhelmetrare", "surprisebox",
"surpriseboxrare", "surprisegiftbox", "surprisegiftboxrare", "taintedrod", "taintedrodrare", "tempest", "tempestrare", "templeamulet", "templeamuletrare", "terrorring",
"terrorringrare", "tesseract", "tesseractrare", "theanvil", "theanvilrare", "thedarkone", "thedarkonerare", "thedefiler", "thedefilerrare", "thejuggernaut",
"thejuggernautrare", "theone", "theonerare", "thepolluter", "thepolluterrare", "theporcupine", "theporcupinerare", "theproficient", "theproficientrare", "thermalamulet",
"thermalamuletrare", "thermalring", "thermalringrare", "thewall", "thewallrare", "thewolfslayer", "thewolfslayera", "thewolfslayerb", "thewolfslayerrare", "thorimsrod",
"thornyring", "thornyringrare", "tikimask", "tikimaskrare", "timepiece", "timepiecea", "timepieceb", "timepiecerare", "tinycannon", "tinycannonrare",
"titangauntlets", "titangauntletsrare", "topazring", "topazringrare", "torch", "torchrare", "touristmap", "touristmaprare", "toxicblobpet", "toxicblobpetrare",
"turban", "turbanrare", "turboboots", "turbobootsrare", "twinblades", "twinbladesrare", "tyrantnecklace", "tyrantnecklacerare", "undeathichor", "undeathichorrare",
"unholyhammer", "unholyhammerrare", "uselessitem", "veiledbonds", "veiledbondsrare", "venomamulet", "venomamuletrare", "venomfang", "venomfangrare", "venomflask",
"venomflaska", "venomflaskb", "venomflaskrare", "veteranarmor", "veteranarmorrare", "vilering", "vileringrare", "viperring", "viperringrare", "virulentring",
"virulentringrare", "visionring", "visionringrare", "volcanicaxe", "volcanicaxerare", "voodoodoll", "voodoodollrare", "warbanner", "warbannerrare", "wardrum",
"wardrumrare", "warhammer", "warhammerrare", "warriorcode", "warriorcoderare", "waterblobpet", "waterblobpetrare", "waterskin", "waterskinrare", "watervase",
"watervaserare", "weaponpouch", "weaponpouchrare", "winebottle", "winebottlerare", "wingblade", "wingbladerare", "wingedhelmet", "wingedhelmeta", "wingedhelmetb",
"wingedhelmetrare", "wingedwand", "wingedwandrare", "wolfskincloack", "wolfskincloackrare", "wolfy", "wolfyrare", "woodencrosier", "woodencrosiera", "woodencrosierb",
"woodencrosierrare", "woollyhat", "woollyhatrare", "xulrunestone", "xulrunestonerare", "yellowfeather", "yellowfeatherrare", "yggdrasilroot", "yggdrasilrootrare", "yinyangbadge",
"yinyangbadgerare", "ylmerbranch", "ylmerbranchrare", "yoggercleaver", "yoggercleaverrare"
};
}
public static List<string> GetLocationList()
{
return new List<string>
{
"apothecaryhigh", "apothecarylow", "apprentince", "aquarvendor", "bakerson_a", "bakerson_b", "balanceblack", "balanceboth", "balancewhite", "Basthet",
"battlefield", "Behindwaterfall", "belphyor", "belphyorquest", "betty", "blobbleed", "blobcold", "blobdire", "blobholy", "bloblightning",
"blobmetal", "blobmind", "blobpoison", "blobselem", "blobshadow", "blobsmyst", "blobsphys", "blobwater", "bridge", "burninghand",
"burninghouse_a", "burninghouse_b", "caravanshop", "challenge_boss_fisher", "challenge_boss_high", "challenge_boss_hydra", "challenge_boss_low", "challenge_chest_final", "challenge_chest_high", "challenge_chest_low",
"challenge_start", "chappel", "courtcraftobsidian", "crane", "crocoloot", "crocosmugglers", "crossroads_a", "crossroads_b", "crossroads_c", "cuby",
"cubyd", "daley", "daleyrare", "desertreliquary", "dreadcosme", "dreadcuthbert", "dreadfrancis", "dreadhalfman", "dreadhoratio", "dreadjack",
"dreadmimic", "dreadpurser", "dreadpurserstash", "dreadrhodogor", "dream_13_loot", "dream_6_loot", "dream_9_loot", "Dryad_a", "Dryad_b", "eeriechest_a",
"eeriechest_b", "elvenarmory", "elvenarmoryplus", "elvenemporium", "exoticshop_tier0", "exoticshop_tier1", "exoticshop_tier2", "exoticshop_tier3", "Faeborg", "felineshop",
"fenny", "fennyrare", "firebazaar", "fishermanchest", "fishlava", "fishlavarare", "franky", "FrozenSewersElves", "FrozenSewersMix", "FrozenSewersRatmen",
"gobletsmerchant", "goblinchest", "goblintown", "Goblintown_a", "Goblintown_b", "Goblintown_c", "harpychest", "harpyfight", "heronshop", "Hydra",
"Ignidoh", "inky", "Jelly", "Jeweler", "Jewelerrings", "khazakdhum", "kingrat", "laircocoon", "lavacascade", "lavacascadepet",
"liante", "lootedarmory", "Mansionleft", "Mansionleftplus", "Mansionright", "matey", "mateyrare", "Merchantwares", "mimy", "minotaurcave",
"Mortis", "mutatedcocoon", "nagashop", "nagavendor", "obechampy", "obechompy", "obechumpy", "obeliskash", "obeliskdelivery", "obeliskgirl",
"obeliskshophigh", "obeliskshoplow", "obelisktreasure", "obsidianall", "obsidiananvil", "obsidiananvilrare", "obsidianboots", "obsidianbootsrare", "obsidianrings", "obsidianringsrare",
"obsidianrods", "obsidianrodsrare", "oculy", "petshop", "rareshop_tier0", "rareshop_tier1", "rareshop_tier2", "rareshop_tier3", "reverie", "rift",
"riftsen", "Rocky", "rubychest", "rubyrefuges", "ruinedplaza", "ruinedplaza_crit", "ruinedplaza_fail", "sahtibernardstash", "sahtibernardstashshop", "sahtidaleshop",
"sahtidomedesert", "sahtidomeice", "sahtidomemain", "sahtidomemountain", "sahtidomeswamp", "sahtifishingshop", "sahtikraken", "sahtikrakenmjolmir", "sahtipiratearsenal", "sahtipiratewarehouse",
"sahtiplaguecot", "sahtirustkingtreasure", "sahtisurgeonarsenal", "sahtisurgeonstash", "sahtitreasurechamber", "sahtivalkyriestash", "Sailor", "Shady", "sharpy", "slimy",
"spiderqueen", "Stolenitems", "stormy", "Sunkenblooddelighted", "Sunkenblooddisrespected", "Sunkenbloodpleased", "sunkenholelab", "sunkenmineslave", "sunkenofferingroom", "Sunkensaflamedelighted",
"Sunkensaflamedisrespected", "Sunkensaflamepleased", "sunkenspidershrine", "Sunkenthunderdelighted", "Sunkenthunderdisrespected", "Sunkenthunderpleased", "Sylviehome", "thorimsrod", "towntier0", "towntier0_a",
"towntier0_b", "towntier1", "towntier1_a", "towntier1_b", "towntier2", "towntier2_a", "towntier2_b", "towntier3", "towntier3_a", "towntier3_b",
"tradeship1", "tradeship10", "tradeship2", "tradeship3", "tradeship4", "tradeship5", "tradeship6", "tradeship7", "tradeship8", "tradeship9",
"treasureaquarfall", "Tulah", "tyrant", "tyrantbeavers", "tyrantchampy", "tyrantchompy", "tyrantchumpy", "uprienergy", "uprimagma", "upripreboss",
"upriprebossnenukill", "voidasmody", "voidcraftemerald", "voidcraftgolden", "voidcraftobsidian", "voidcraftpearl", "voidcraftring", "voidcraftruby", "voidcraftsapphire", "voidcrafttopaz",
"voidshop", "voidtreasure", "voidtreasurejade", "voidtsnemo", "voidtwins", "voodooshop", "wareacc0", "wareacc1", "wareacc2", "warearm0",
"warearm1", "warearm2", "warejew0", "warejew1", "warejew2", "warenavalea", "wareweap0", "wareweap1", "wareweap2", "watermill",
"weekly1", "weekly10", "weekly11", "weekly12", "weekly13", "weekly2", "weekly3", "weekly4", "weekly5", "weekly6",
"weekly7", "weekly8", "weekly9", "weeklychristmas", "weeklyhalloween", "weeklylunar", "werewolfstall_a", "werewolfstall_b", "wolfy", "woodsshop",
"woodstreasurechest", "Ylmer", "yogger"
};
}
public static string DictToString(Dictionary<string, List<string>> dict)
{
if (dict == null)
{
throw new ArgumentNullException("dict");
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append('{');
List<string> list = dict.Keys.OrderBy((string k) => k).ToList();
for (int i = 0; i < list.Count; i++)
{
string text = list[i];
List<string> list2 = dict[text];
stringBuilder.Append("\"" + text + "\":[");
for (int j = 0; j < list2.Count; j++)
{
stringBuilder.Append("\"" + list2[j] + "\"");
if (j < list2.Count - 1)
{
stringBuilder.Append(',');
}
}
stringBuilder.Append(']');
if (i < list.Count - 1)
{
stringBuilder.Append(',');
}
}
stringBuilder.Append('}');
return stringBuilder.ToString();
}
}
[HarmonyPatch]
public class SeedSearcherFunctions
{
public static Dictionary<string, string> allLootLocations = new Dictionary<string, string>
{
{ "FrozenSewersElves", "sewers_11" },
{ "towntier0_b", "sen_41" },
{ "chappel", "sen_21" },
{ "voidtsnemo", "voidlow_24" },
{ "voidshop", "voidlow_8" },
{ "rubychest", "aqua_20" },
{ "rubyrefuges", "aqua_20" },
{ "caravanshop", "sen_44" },
{ "Basthet", "pyr_7" },
{ "Dryad_a", "sen_31" },
{ "Dryad_b", "sen_32" },
{ "Faeborg", "faen_38" },
{ "Hydra", "aqua_35" },
{ "Ignidoh", "velka_32" },
{ "Mansionright", "faen_35" },
{ "Mortis", "ulmin_56" },
{ "Tulah", "spider_8" },
{ "Ylmer", "sen_33" },
{ "belphyor", "secta_5" },
{ "belphyorquest", "velka_8" },
{ "burninghand", "velka_25" },
{ "dreadhalfman", "dread_11" },
{ "elvenarmory", "faen_29" },
{ "elvenarmoryplus", "faen_29" },
{ "goblintown", "velka_6" },
{ "harpychest", "velka_27" },
{ "harpyfight", "velka_27" },
{ "khazakdhum", "velka_29" },
{ "kingrat", "sewers_8" },
{ "minotaurcave", "velka_9" },
{ "sahtikraken", "sahti_65" },
{ "sahtikrakenmjolmir", "sahti_65" },
{ "sahtirustkingtreasure", "sahti_62" },
{ "spiderqueen", "sen_1" },
{ "tyrant", "faen_25" },
{ "tyrantbeavers", "faen_25" },
{ "tyrantchampy", "faen_25" },
{ "tyrantchompy", "faen_25" },
{ "tyrantchumpy", "faen_25" },
{ "upripreboss", "uprising_13" },
{ "yogger", "sen_27" },
{ "voidtwins", "voidlow_25" },
{ "voidtreasurejade", "voidlow_16" }
};
public static Dictionary<string, string> guaranteedDropNodeMap = new Dictionary<string, string>
{
{ "rubychest", "aqua_20" },
{ "rubyrefuges", "aqua_20" },
{ "FrozenSewersElves", "sewers_11" },
{ "FrozenSewersMix", "sewers_11" },
{ "FrozenSewersRatmen", "sewers_11" },
{ "Jewelerrings", "sen_35" },
{ "Mansionleft", "faen_35" },
{ "Mansionleftplus", "faen_35" },
{ "Sailor", "faen_4" },
{ "Stolenitems", "faen_10" },
{ "apprentince", "sen_24" },
{ "balanceblack", "ulmin_52" },
{ "balanceboth", "ulmin_52" },
{ "balancewhite", "ulmin_52" },
{ "battlefield", "aqua_6" },
{ "bridge", "sen_17" },
{ "chappel", "sen_21" },
{ "crane", "velka_21" },
{ "crocoloot", "aqua_7" },
{ "crocosmugglers", "aqua_48" },
{ "desertreliquary", "ulmin_58" },
{ "dreadcosme", "dread_2" },
{ "dreadcuthbert", "dread_2" },
{ "dreadfrancis", "dread_2" },
{ "dreadhoratio", "dread_2" },
{ "dreadjack", "dread_2" },
{ "dreadmimic", "dread_10" },
{ "dreadrhodogor", "dread_2" },
{ "eeriechest_a", "sen_6" },
{ "eeriechest_b", "sen_6" },
{ "lavacascade", "velka_22" },
{ "lootedarmory", "pyr_10" },
{ "obsidianall", "forge_3" },
{ "obsidiananvil", "forge_3" },
{ "obsidianboots", "forge_3" },
{ "obsidianrings", "forge_3" },
{ "obsidianrods", "forge_3" },
{ "rift", "velka_40" },
{ "riftsen", "sen_48" },
{ "sahtibernardstash", "sahti_52" },
{ "sahtidomedesert", "sahti_49" },
{ "sahtidomeice", "sahti_49" },
{ "sahtidomemain", "sahti_49" },
{ "sahtidomemountain", "sahti_49" },
{ "sahtidomeswamp", "sahti_49" },
{ "sahtipiratearsenal", "sahti_25" },
{ "sahtipiratewarehouse", "sahti_25" },
{ "sahtiplaguecot", "sahti_11" },
{ "sahtisurgeonarsenal", "sahti_13" },
{ "sahtisurgeonstash", "sahti_13" },
{ "sahtitreasurechamber", "sahti_25" },
{ "sahtivalkyriestash", "sahti_19" },
{ "thorimsrod", "forge_8" },
{ "treasureaquarfall", "aqua_28" },
{ "uprienergy", "uprising_5" },
{ "uprimagma", "uprising_4" },
{ "voidcraftemerald", "voidlow_14" },
{ "voidcraftgolden", "voidlow_14" },
{ "voidcraftobsidian", "voidlow_14" },
{ "voidcraftpearl", "voidlow_14" },
{ "voidcraftring", "voidlow_14" },
{ "voidcraftruby", "voidlow_14" },
{ "voidcraftsapphire", "voidlow_14" },
{ "voidcrafttopaz", "voidlow_14" },
{ "voidtreasurejade", "voidlow_16" },
{ "watermill", "sen_15" }
};
public static Dictionary<string, string> MythicLocations = new Dictionary<string, string>
{
{ "towntier3", "voidlow_1" },
{ "towntier3_a", "voidlow_1" },
{ "towntier3_b", "voidlow_1" },
{ "ruinedplaza", "voidlow_5" },
{ "ruinedplaza_crit", "voidlow_5" },
{ "voidasmody", "voidhigh_6" },
{ "voidshop", "voidlow_8" },
{ "voidtreasure", "voidlow_16" },
{ "voidtreasurejade", "voidlow_16" },
{ "voidtsnemo", "voidlow_24" },
{ "voidtwins", "voidlow_25" },
{ "wareacc1", "voidlow_4" },
{ "wareacc2", "voidlow_4" },
{ "warearm1", "voidlow_4" },
{ "warearm2", "voidlow_4" },
{ "warejew1", "voidlow_4" },
{ "warejew2", "voidlow_4" },
{ "warenavalea", "voidlow_4" },
{ "wareweap1", "voidlow_4" },
{ "wareweap2", "voidlow_4" }
};
public static Dictionary<string, string> allItemDropLocations = new Dictionary<string, string>
{
{ "towntier0", "sen_41" },
{ "towntier0_a", "sen_41" },
{ "towntier0_b", "sen_41" },
{ "towntier3", "voidlow_1" },
{ "towntier3_a", "voidlow_1" },
{ "towntier3_b", "voidlow_1" },
{ "ruinedplaza", "voidlow_5" },
{ "ruinedplaza_crit", "voidlow_5" },
{ "voidasmody", "voidhigh_6" },
{ "voidshop", "voidlow_8" },
{ "voidtreasure", "voidlow_16" },
{ "voidtreasurejade", "voidlow_16" },
{ "voidtsnemo", "voidlow_24" },
{ "voidtwins", "voidlow_25" },
{ "wareacc1", "voidlow_4" },
{ "wareacc2", "voidlow_4" },
{ "warearm1", "voidlow_4" },
{ "warearm2", "voidlow_4" },
{ "warejew1", "voidlow_4" },
{ "warejew2", "voidlow_4" },
{ "warenavalea", "voidlow_4" },
{ "wareweap1", "voidlow_4" },
{ "wareweap2", "voidlow_4" },
{ "aquarvendor", "aqua_26" },
{ "elvenemporium", "faen_23" },
{ "felineshop", "ulmin_29" },
{ "firebazaar", "velka_20" },
{ "heronshop", "ulmin_27" },
{ "Merchantwares", "velka_7" },
{ "voodooshop", "aqua_23" },
{ "Jeweler", "sen_35" },
{ "gobletsmerchant", "sewers_4" },
{ "werewolfstall_a", "sen_30" },
{ "werewolfstall_b", "sen_30" },
{ "FrozenSewersElves", "sewers_11" },
{ "FrozenSewersMix", "sewers_11" },
{ "FrozenSewersRatmen", "sewers_11" },
{ "Jewelerrings", "sen_35" },
{ "Mansionleft", "faen_35" },
{ "Mansionleftplus", "faen_35" },
{ "Sailor", "faen_4" },
{ "Stolenitems", "faen_10" },
{ "apprentince", "sen_24" },
{ "balanceblack", "ulmin_52" },
{ "balanceboth", "ulmin_52" },
{ "balancewhite", "ulmin_52" },
{ "battlefield", "aqua_6" },
{ "bridge", "sen_17" },
{ "chappel", "sen_21" },
{ "crane", "velka_21" },
{ "crocoloot", "aqua_7" },
{ "crocosmugglers", "aqua_48" },
{ "desertreliquary", "ulmin_58" },
{ "dreadcosme", "dread_2" },
{ "dreadcuthbert", "dread_2" },
{ "dreadfrancis", "dread_2" },
{ "dreadhoratio", "dread_2" },
{ "dreadjack", "dread_2" },
{ "dreadmimic", "dread_10" },
{ "dreadrhodogor", "dread_2" },
{ "eeriechest_a", "sen_6" },
{ "eeriechest_b", "sen_6" },
{ "lavacascade", "velka_22" },
{ "lootedarmory", "pyr_10" },
{ "obsidianall", "forge_3" },
{ "obsidiananvil", "forge_3" },
{ "obsidianboots", "forge_3" },
{ "obsidianrings", "forge_3" },
{ "obsidianrods", "forge_3" },
{ "rift", "velka_40" },
{ "riftsen", "sen_48" },
{ "sahtibernardstash", "sahti_52" },
{ "sahtidomedesert", "sahti_49" },
{ "sahtidomeice", "sahti_49" },
{ "sahtidomemain", "sahti_49" },
{ "sahtidomemountain", "sahti_49" },
{ "sahtidomeswamp", "sahti_49" },
{ "sahtipiratearsenal", "sahti_25" },
{ "sahtipiratewarehouse", "sahti_25" },
{ "sahtiplaguecot", "sahti_11" },
{ "sahtisurgeonarsenal", "sahti_13" },
{ "sahtisurgeonstash", "sahti_13" },
{ "sahtitreasurechamber", "sahti_25" },
{ "sahtivalkyriestash", "sahti_19" },
{ "thorimsrod", "forge_8" },
{ "treasureaquarfall", "aqua_28" },
{ "uprienergy", "uprising_5" },
{ "uprimagma", "uprising_4" },
{ "voidcraftemerald", "voidlow_14" },
{ "voidcraftgolden", "voidlow_14" },
{ "voidcraftobsidian", "voidlow_14" },
{ "voidcraftpearl", "voidlow_14" },
{ "voidcraftring", "voidlow_14" },
{ "voidcraftruby", "voidlow_14" },
{ "voidcraftsapphire", "voidlow_14" },
{ "voidcrafttopaz", "voidlow_14" },
{ "watermill", "sen_15" },
{ "Jelly", "aqua_41" },
{ "betty", "sen_39" },
{ "blobbleed", "sen_29" },
{ "blobcold", "sewers_13" },
{ "blobdire", "velka_37" },
{ "blobholy", "pyr_12" },
{ "bloblightning", "sahti_30" },
{ "blobmetal", "velka_38" },
{ "blobmind", "dread_7" },
{ "blobpoison", "aqua_44" },
{ "blobselem", "voidlow_28" },
{ "blobshadow", "ulmin_59" },
{ "blobsmyst", "voidlow_28" },
{ "blobsphys", "voidlow_28" },
{ "blobwater", "aqua_45" },
{ "cuby", "pyr_9" },
{ "cubyd", "pyr_9" },
{ "daley", "faen_7" },
{ "fenny", "ulmin_6" },
{ "fishlava", "forge_8" },
{ "inky", "aqua_41" },
{ "liante", "spider_5" },
{ "matey", "sahti_20" },
{ "mimy", "dread_10" },
{ "oculy", "aqua_41" },
{ "sharpy", "aqua_18" },
{ "slimy", "spider_7" },
{ "stormy", "aqua_24" },
{ "wolfy", "sen_46" },
{ "Basthet", "pyr_7" },
{ "Dryad_a", "sen_31" },
{ "Dryad_b", "sen_32" },
{ "Faeborg", "faen_38" },
{ "Hydra", "aqua_35" },
{ "Ignidoh", "velka_32" },
{ "Mansionright", "faen_35" },
{ "Mortis", "ulmin_56" },
{ "Tulah", "spider_8" },
{ "Ylmer", "sen_33" },
{ "belphyor", "secta_5" },
{ "belphyorquest", "velka_8" },
{ "burninghand", "velka_25" },
{ "dreadhalfman", "dread_11" },
{ "elvenarmory", "faen_29" },
{ "elvenarmoryplus", "faen_29" },
{ "goblintown", "velka_6" },
{ "harpychest", "velka_27" },
{ "harpyfight", "velka_27" },
{ "khazakdhum", "velka_29" },
{ "kingrat", "sewers_8" },
{ "minotaurcave", "velka_9" },
{ "sahtikraken", "sahti_65" },
{ "sahtikrakenmjolmir", "sahti_65" },
{ "sahtirustkingtreasure", "sahti_62" },
{ "spiderqueen", "sen_1" },
{ "tyrant", "faen_25" },
{ "tyrantbeavers", "faen_25" },
{ "tyrantchampy", "faen_25" },
{ "tyrantchompy", "faen_25" },
{ "tyrantchumpy", "faen_25" },
{ "upripreboss", "uprising_13" },
{ "yogger", "sen_27" }
};
public static Dictionary<string, string> petDropNodeMap = new Dictionary<string, string>
{
{ "Jelly", "aqua_41" },
{ "betty", "sen_39" },
{ "blobbleed", "sen_29" },
{ "blobcold", "sewers_13" },
{ "blobdire", "velka_37" },
{ "blobholy", "pyr_12" },
{ "bloblightning", "sahti_30" },
{ "blobmetal", "velka_38" },
{ "blobmind", "dread_7" },
{ "blobpoison", "aqua_44" },
{ "blobselem", "voidlow_28" },
{ "blobshadow", "ulmin_59" },
{ "blobsmyst", "voidlow_28" },
{ "blobsphys", "voidlow_28" },
{ "blobwater", "aqua_45" },
{ "cuby", "pyr_9" },
{ "cubyd", "pyr_9" },
{ "daley", "faen_7" },
{ "fenny", "ulmin_6" },
{ "fishlava", "forge_8" },
{ "inky", "aqua_41" },
{ "liante", "spider_5" },
{ "matey", "sahti_20" },
{ "mimy", "dread_10" },
{ "oculy", "aqua_41" },
{ "sharpy", "aqua_18" },
{ "slimy", "spider_7" },
{ "stormy", "aqua_24" },
{ "wolfy", "sen_46" }
};
public static Dictionary<string, string> dropNodeMap = new Dictionary<string, string>
{
{ "Basthet", "pyr_7" },
{ "Dryad_a", "sen_31" },
{ "Dryad_b", "sen_32" },
{ "Faeborg", "faen_38" },
{ "Hydra", "aqua_35" },
{ "Ignidoh", "velka_32" },
{ "Mansionright", "faen_35" },
{ "Mortis", "ulmin_56" },
{ "Tulah", "spider_8" },
{ "Ylmer", "sen_33" },
{ "belphyor", "secta_5" },
{ "belphyorquest", "velka_8" },
{ "burninghand", "velka_25" },
{ "dreadhalfman", "dread_11" },
{ "elvenarmory", "faen_29" },
{ "elvenarmoryplus", "faen_29" },
{ "goblintown", "velka_6" },
{ "harpychest", "velka_27" },
{ "harpyfight", "velka_27" },
{ "khazakdhum", "velka_29" },
{ "kingrat", "sewers_8" },
{ "minotaurcave", "velka_9" },
{ "sahtikraken", "sahti_65" },
{ "sahtikrakenmjolmir", "sahti_65" },
{ "sahtirustkingtreasure", "sahti_62" },
{ "spiderqueen", "sen_1" },
{ "tyrant", "faen_25" },
{ "tyrantbeavers", "faen_25" },
{ "tyrantchampy", "faen_25" },
{ "tyrantchompy", "faen_25" },
{ "tyrantchumpy", "faen_25" },
{ "upripreboss", "uprising_13" },
{ "yogger", "sen_27" }
};
private static Random random = new Random();
public static string SavedSeed = "";
public static void ExecuteSearch()
{
List<(string, string)> itemsAndShops = new List<(string, string)>
{
(Plugin.ItemToSearchFor1.Value, Plugin.LocationToSearchForItem1.Value),
(Plugin.ItemToSearchFor2.Value, Plugin.LocationToSearchForItem2.Value),
(Plugin.ItemToSearchFor3.Value, Plugin.LocationToSearchForItem3.Value),
(Plugin.ItemToSearchFor4.Value, Plugin.LocationToSearchForItem4.Value)
};
Plugin.LogDebug("dict init");
int value = Plugin.NumberOfSeeds.Value;
List<string> values = CheckSeeds(itemsAndShops, value, Plugin.MadnessLevel.Value, Plugin.CorruptorCount.Value);
Plugin.LogInfo("List of Seeds with good things: \n " + string.Join(", ", values));
}
internal static void LogListInfoFromSeed(string seed, string shop, string node)
{
List<string> itemsFromSeed = GetItemsFromSeed(seed, shop, node, 0, _obeliskChallenge: false, 1);
Plugin.LogDebug(seed);
Plugin.LogDebug(string.Join(", ", itemsFromSeed));
}
public static string RandomString(int length)
{
return new string((from s in Enumerable.Repeat("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", length)
select s[random.Next(s.Length)]).ToArray());
}
internal static string DoubleCaravanEpics(List<(string, string)> listOfPairs, int nSeeds)
{
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < nSeeds; i++)
{
string text = RandomString(8).ToUpper();
if (i % 100000 == 0)
{
Plugin.LogDebug($"On Seed {i}: {text}");
}
List<string> itemsFromSeed = GetItemsFromSeed(text, "caravanshop", "sen_44", 0, _obeliskChallenge: false, 1);
if (ItemListContains(itemsFromSeed, "darkhood") && ItemListContains(itemsFromSeed, "assassintools") && (ItemListContains(itemsFromSeed, "longbow") || ItemListContains(itemsFromSeed, "twinblades")) && ItemListContains(itemsFromSeed, "brassamulet"))
{
Plugin.LogDebug("FOUND THE PERFECT DARKHOOD/ASSASSIN TOOL SEED + " + text);
}
foreach (var listOfPair in listOfPairs)
{
if ((itemsFromSeed.Contains(listOfPair.Item1) || itemsFromSeed.Contains(listOfPair.Item1 + "rare")) && (itemsFromSeed.Contains(listOfPair.Item2) || itemsFromSeed.Contains(listOfPair.Item2 + "rare")))
{
stringBuilder.Append(text + " - " + listOfPair.Item1 + " and " + listOfPair.Item2 + " \n");
Plugin.LogDebug(text + " - " + listOfPair.Item1 + " and " + listOfPair.Item2);
}
}
}
return stringBuilder.ToString();
}
public static bool ItemListContains(List<string> itemList, string item)
{
return itemList.Contains(item) || itemList.Contains(item + "rare");
}
internal static bool SeedHasAllItemsInLocations(string seed, List<(string, string)> itemsAndShops, int madness = 1, int corruptorCount = 0)
{
foreach (var itemsAndShop in itemsAndShops)
{
string text;
(text, _) = itemsAndShop;
if (!(text == ""))
{
text = (char.IsDigit(text[text.Length - 1]) ? text.Remove(text.Length - 1) : text);
string item = itemsAndShop.Item2;
if (!CheckSingleShopHasItem(text, item, seed, madness, corruptorCount))
{
return false;
}
}
}
return true;
}
internal static bool CheckSingleShopHasItem(string item, string shop, string seed, int madness, int corruptorCount, string node = null)
{
string text = (allLootLocations.ContainsKey(shop) ? allLootLocations[shop] : node);
if (text == null)
{
Plugin.LogDebug("improper LootLocation - " + shop);
return false;
}
if (!NodeExists(text, seed))
{
Plugin.LogDebug("CheckSingleShop null node: " + text + " in seed " + seed);
return false;
}
List<string> itemsFromSeed = GetItemsFromSeed(seed, shop, text, 0, _obeliskChallenge: false, madness, corruptorCount, Plugin.PovertyEnabled.Value);
return itemsFromSeed.Contains(item);
}
internal static bool CheckSingleNodeAndShop(string item, string shop, string node, string seed, int madness = 1, int corruptorCount = 0, string eventId = null)
{
if (eventId == null)
{
if (!NodeExists(node, seed))
{
Plugin.LogDebug("CheckSingleNodeAndShop null node: " + node + " in seed " + seed);
return false;
}
}
else if (!EventExists(seed, node, eventId))
{
return false;
}
if (node == "")
{
Plugin.LogDebug("improper LootLocation - " + shop);
return false;
}
List<string> itemsFromSeed = GetItemsFromSeed(seed, shop, node, 0, _obeliskChallenge: false, madness, corruptorCount);
return itemsFromSeed.Contains(item);
}
internal static List<string> CheckSeeds(List<(string, string)> itemsAndShops, int nSeeds, int madness = 1, int corruptorCount = 0)
{
Plugin.LogDebug("CheckSeeds - Begin");
List<string> list = new List<string>();
int num = Mathf.Clamp(nSeeds / 100, 1000, 100000);
for (int i = 0; i < nSeeds; i++)
{
string text = RandomString(8).ToUpper();
if (i % num == 0)
{
Plugin.LogDebug($"On Seed {i}: {text}");
}
if (!SeedHasAllItemsInLocations(text, itemsAndShops, madness, corruptorCount))
{
continue;
}
list.Append(text);
List<string> values = itemsAndShops.Select(((string, string) x) => x.Item1).ToList();
string text2 = string.Join(", ", values);
Plugin.LogInfo("Found Seed with " + text2 + ": " + text);
if (Plugin.StopSearchOnSeedFound.Value)
{
Plugin.LogInfo("Stopping search on seed found: " + text);
if (Plugin.SaveSeedToGame.Value)
{
SavedSeed = text;
}
AlertManager.Instance.AlertConfirm("Seed found " + (Plugin.SaveSeedToGame.Value ? "and saved to game" : "") + ":\n " + text + " \n Contains: " + text2, "");
return list;
}
}
return list;
}
internal static void LogSeedsNodeSpecified(List<(string, string, string)> thingsToSearch, int nSeeds = 20000, int madness = 1, int corruptorCount = 0)
{
List<string> list = new List<string>();
for (int i = 0; i < nSeeds; i++)
{
if (i % 10000 == 0)
{
Plugin.LogDebug($"On Seed {i}");
}
string text = RandomString(8).ToUpper();
bool flag = true;
foreach (var item4 in thingsToSearch)
{
string item = item4.Item1;
string item2 = item4.Item2;
string item3 = item4.Item3;
string eventId = ((item3 == "sen_29") ? "e_sen29_a" : null);
if (!CheckSingleNodeAndShop(item, item2, item3, text, madness, corruptorCount, eventId))
{
flag = false;
break;
}
}
if (flag)
{
list.Add(text);
}
if (list.Count() >= 10)
{
break;
}
}
List<string> values = thingsToSearch.Select(((string, string, string) thing) => thing.Item1).ToList();
Plugin.LogDebug("Found Seeds with the following items: " + string.Join(", ", values) + " \n " + string.Join(", ", list));
}
internal static void FindSeedWithItems()
{
List<string> list = new List<string>();
int num = 5000;
for (int i = 0; i < num; i++)
{
string seed = RandomString(8).ToUpper();
List<string> list2 = new List<string>();
foreach (string key in allItemDropLocations.Keys)
{
string node = allItemDropLocations[key];
List<string> itemsFromSeed = GetItemsFromSeed(seed, key, node, 0, _obeliskChallenge: false, 1);
}
}
}
public static void LogAllItems()
{
Plugin.LogInfo("LogAllItems - Start");
int nSeeds = 1000000;
LogCaravanItems(nSeeds);
nSeeds = 1000;
LogGuaranteedDropItems(nSeeds);
LogBossDropItems(nSeeds);
LogPetItems(nSeeds);
LogMythicItems();
}
internal static void LogMythicItems(int nSeeds = 2000)
{
HandleMythics(MythicLocations, nSeeds);
Plugin.LogInfo("Completed Mythic Items");
}
internal static void HandleMythics(Dictionary<string, string> lootNodeMap, int nSeeds = 300, bool rareOnly = false)
{
Dictionary<string, List<string>> itemDict = new Dictionary<string, List<string>>();
foreach (string key in lootNodeMap.Keys)
{
Plugin.LogDebug("Searching Location " + key);
for (int i = 0; i < nSeeds; i++)
{
string seed = RandomString(7).ToUpper();
string node = lootNodeMap[key];
List<string> itemsFromSeed = GetItemsFromSeed(seed, key, node, 0, _obeliskChallenge: false, 1);
UpdateItemDictForMythics(ref itemDict, itemsFromSeed, seed, key, 10);
}
}
Plugin.LogDebug("Shop Items - " + Plugin.DictToString(itemDict));
}
internal static bool EventExists(string seed, string nodeId, string eventId, bool assumePlayerHasReqs = false)
{
//IL_0487: Unknown result type (might be due to invalid IL or missing references)
//IL_048c: Unknown result type (might be due to invalid IL or missing references)
//IL_04ba: Unknown result type (might be due to invalid IL or missing references)
Globals instance = Globals.Instance;
NodeData val = ((instance != null) ? instance.GetNodeData(nodeId) : null);
if ((Object)(object)val == (Object)null)
{
Plugin.LogDebug("Null nodedata/Globals");
return false;
}
Random.InitState(Functions.GetDeterministicHashCode(val.NodeId + seed + "AssignSingleGameNode"));
if (Random.Range(0, 100) >= val.ExistsPercent)
{
return false;
}
bool flag = true;
bool flag2 = true;
if (val.NodeEvent != null && val.NodeEvent.Length != 0 && val.NodeCombat != null && val.NodeCombat.Length != 0)
{
if (Random.Range(0, 100) < val.CombatPercent)
{
flag = false;
}
else
{
flag2 = false;
}
}
if (flag && val.NodeEvent != null && val.NodeEvent.Length != 0)
{
string text = "";
Dictionary<string, int> dictionary = new Dictionary<string, int>();
for (int i = 0; i < val.NodeEvent.Length; i++)
{
if (!((Object)(object)val.NodeEvent[i] != (Object)null))
{
continue;
}
bool flag3 = true;
if ((Object)(object)val.NodeEvent[i].Requirement != (Object)null && assumePlayerHasReqs)
{
flag3 = false;
}
if ((Object)(object)val.NodeEvent[i].RequiredClass != (Object)null && assumePlayerHasReqs)
{
flag3 = false;
}
if (flag3)
{
int value = 10000;
if (i < val.NodeEventPriority.Length)
{
value = val.NodeEventPriority[i];
}
dictionary.Add(val.NodeEvent[i].EventId, value);
}
}
if (dictionary.Count == 0)
{
return false;
}
Dictionary<string, int> dictionary2 = dictionary.OrderBy((KeyValuePair<string, int> x) => x.Value).ToDictionary((KeyValuePair<string, int> x) => x.Key, (KeyValuePair<string, int> x) => x.Value);
int j = 1;
for (int value2 = dictionary2.ElementAt(0).Value; j < dictionary2.Count && dictionary2.ElementAt(j).Value == value2; j++)
{
}
if (j == 1)
{
text = dictionary2.ElementAt(0).Key;
}
else
{
if (val.NodeEventPercent != null && val.NodeEvent.Length == val.NodeEventPercent.Length)
{
Dictionary<string, int> dictionary3 = new Dictionary<string, int>();
int num = 0;
for (int k = 0; k < j; k++)
{
int num2 = 0;
while (k < val.NodeEvent.Length)
{
if (val.NodeEvent[num2].EventId == dictionary2.ElementAt(num).Key)
{
dictionary3.Add(val.NodeEvent[num2].EventId, val.NodeEventPercent[num2]);
num++;
break;
}
num2++;
}
}
int num3 = Random.Range(0, 100);
int num4 = 0;
foreach (KeyValuePair<string, int> item in dictionary3)
{
num4 += item.Value;
if (num3 < num4)
{
text = item.Key;
break;
}
}
}
if (text == "")
{
int index = Random.Range(0, j);
text = dictionary2.ElementAt(index).Key;
}
}
if (text == eventId)
{
return true;
}
}
else if (flag2 && val.NodeCombat != null && val.NodeCombat.Length != 0)
{
string text2 = "";
if (text2 == "")
{
int num5 = 0;
if (val.NodeId == "of1_10" || val.NodeId == "of2_10")
{
State state = Random.state;
Random.InitState(Functions.GetDeterministicHashCode(val.NodeId + seed + "finalBoss"));
num5 = Random.Range(0, val.NodeCombat.Length);
Random.state = state;
}
text2 = val.NodeCombat[num5].CombatId;
if (text2 == eventId)
{
return true;
}
}
}
return false;
}
internal static bool EventExists(string seed, NodeData nodeData, string eventId)
{
string nodeId = nodeData.NodeId;
return EventExists(seed, nodeId, eventId);
}
internal static void FindAndLogSeedsWithEvent(List<string> eventsToFind, int nSeeds = 20000)
{
List<string> list = new List<string>();
for (int i = 0; i < nSeeds; i++)
{
if (i % 10000 == 0)
{
Plugin.LogDebug($"On Seed {i}");
}
string text = RandomString(8).ToUpper();
bool flag = true;
foreach (string item in eventsToFind)
{
string nodeId = ConvertEventToNode(item);
if (!EventExists(text, nodeId, item))
{
flag = false;
break;
}
}
if (flag)
{
list.Add(text);
}
if (list.Count() >= 10)
{
break;
}
}
Plugin.LogDebug("Found Seeds with events: " + string.Join(", ", list));
}
internal static bool NodeExists(string nodeId, string seed, string hasEvent = null)
{
if ((Object)(object)Globals.Instance == (Object)null)
{
return false;
}
if (nodeId == "caravanshop")
{
return true;
}
NodeData nodeData = Globals.Instance.GetNodeData(nodeId);
if ((Object)(object)nodeData == (Object)null)
{
return false;
}
Random.InitState(Functions.GetDeterministicHashCode(nodeId + seed + "AssignSingleGameNode"));
if (Random.Range(0, 100) >= nodeData.ExistsPercent)
{
return false;
}
if (hasEvent != null && (Object)(object)AtOManager.Instance != (Object)null)
{
Dictionary<string, string> value = Traverse.Create((object)AtOManager.Instance).Field("gameNodeAssigned").GetValue<Dictionary<string, string>>();
if (value == null)
{
return false;
}
if (value.ContainsKey(nodeId))
{
string text = value[nodeId];
Plugin.LogDebug(text);
return text.Split(new char[1] { ':' })[1] == hasEvent;
}
return false;
}
return true;
}
internal static void LogPetItems(int nSeeds = 500)
{
HandleDropItems(petDropNodeMap, nSeeds, rareOnly: true);
Plugin.LogInfo("Completed Pet Items");
}
internal static void LogBossDropItems(int nSeeds = 500)
{
HandleDropItems(dropNodeMap, nSeeds, rareOnly: true);
Plugin.LogInfo("Completed Boss Items");
}
internal static void LogGuaranteedDropItems(int nSeeds = 500)
{
HandleDropItems(guaranteedDropNodeMap, nSeeds, rareOnly: true);
Plugin.LogInfo("Completed Guaranteed Items");
}
internal static void LogSingleShop(string shop, string seed, string node = null, int madness = 1, int corruptorCount = 0, bool poverty = false)
{
if (node == null)
{
Plugin.LogError("Node is null");
return;
}
List<string> itemsFromSeed = GetItemsFromSeed(seed, shop, node, 0, _obeliskChallenge: false, 1, 0, poverty);
Plugin.LogDebug("Shop - " + shop + " itemList Items - " + string.Join(", ", itemsFromSeed));
}
internal static void LogShopItems()
{
Dictionary<string, string> lootNodeMap = new Dictionary<string, string>
{
{ "aquarvendor", "aqua_26" },
{ "elvenemporium", "faen_23" },
{ "felineshop", "ulmin_29" },
{ "firebazaar", "velka_20" }
};
int nSeeds = 300;
HandleDropItems(lootNodeMap, nSeeds);
}
internal static void HandleDropItems(Dictionary<string, string> lootNodeMap, int nSeeds = 300, bool rareOnly = false)
{
Dictionary<string, List<string>> itemDict = new Dictionary<string, List<string>>();
foreach (string key in lootNodeMap.Keys)
{
LootData lootData = Globals.Instance.GetLootData(key);
List<string> list = new List<string>();
LootItem[] lootItemTable = lootData.LootItemTable;
foreach (LootItem val in lootItemTable)
{
if (!((Object)(object)val.LootCard == (Object)null) && val.LootCard.CardName != "")
{
if (rareOnly)
{
list.Add(val.LootCard.Id + "rare");
}
else
{
list.Add(val.LootCard.Id);
}
}
}
Plugin.LogDebug("Shop - " + key + " Valid Items - " + string.Join(", ", list));
for (int j = 0; j < nSeeds; j++)
{
string seed = RandomString(7).ToUpper();
string node = lootNodeMap[key];
List<string> itemsFromSeed = GetItemsFromSeed(seed, key, node, 0, _obeliskChallenge: false, 1);
UpdateItemDictForShops(ref itemDict, itemsFromSeed, list, seed, key, 10);
}
}
Plugin.LogDebug("Shop Items - " + Plugin.DictToString(itemDict));
}
internal static void UpdateItemDictForMythics(ref Dictionary<string, List<string>> itemDict, List<string> itemList, string seed, string shopName, int count = 5)
{
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Invalid comparison between Unknown and I4
foreach (string item in itemList)
{
CardData cardData = Globals.Instance.GetCardData(item, false);
if (!((Object)(object)cardData == (Object)null) && (int)cardData.CardRarity == 4)
{
string key = shopName + " - " + cardData.CardName;
if (!itemDict.ContainsKey(key))
{
itemDict.Add(key, new List<string>());
}
if (itemDict[key].Count() < count)
{
itemDict[key].Add(seed);
}
}
}
}
internal static void LogCaravanItems(int nSeeds = 1000)
{
Dictionary<string, List<string>> itemDict = new Dictionary<string, List<string>>();
for (int i = 0; i < nSeeds; i++)
{
if (i % 50000 == 0)
{
Plugin.LogDebug($"On seed {i}");
}
string seed = RandomString(7).ToUpper();
string shop = "caravanshop";
string node = "sen_44";
List<string> itemsFromSeed = GetItemsFromSeed(seed, shop, node, 0, _obeliskChallenge: false, 1);
UpdateItemDict(ref itemDict, itemsFromSeed, seed);
}
Plugin.LogDebug("Dictionary - " + Plugin.DictToString(itemDict));
}
internal static void UpdateItemDictForShops(ref Dictionary<string, List<string>> itemDict, List<string> itemList, List<string> validItems, string seed, string shopName, int count = 5)
{
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Invalid comparison between Unknown and I4
foreach (string item in itemList)
{
if (!validItems.Contains(item))
{
continue;
}
CardData cardData = Globals.Instance.GetCardData(item, false);
if (!((Object)(object)cardData == (Object)null) && (int)cardData.CardUpgraded == 3)
{
string key = shopName + " - " + cardData.CardName;
if (!itemDict.ContainsKey(key))
{
itemDict.Add(key, new List<string>());
}
if (itemDict[key].Count() < count)
{
itemDict[key].Add(seed);
}
}
}
}
internal static void UpdateItemDict(ref Dictionary<string, List<string>> itemDict, List<string> itemList, string seed, int count = 5)
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Invalid comparison between Unknown and I4
foreach (string item in itemList)
{
CardData cardData = Globals.Instance.GetCardData(item, false);
string key = (((int)cardData.CardUpgraded == 3) ? (cardData.CardName + " (Corrupted)") : cardData.CardName);
if (!itemDict.ContainsKey(key))
{
itemDict.Add(key, new List<string>());
}
if (itemDict[key].Count() < count)
{
itemDict[key].Add(seed);
}
}
}
internal static List<string> GetItemsFromSeed(string _seed = "", string _shop = "caravanshop", string _node = "", int _townReroll = 0, bool _obeliskChallenge = false, int _madness = 0, int _corruptorCount = 0, bool _poverty = false)
{
//IL_03b5: Unknown result type (might be due to invalid IL or missing references)
//IL_03bb: Invalid comparison between Unknown and I4
//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
//IL_0201: Invalid comparison between Unknown and I4
//IL_0672: Unknown result type (might be due to invalid IL or missing references)
//IL_0678: Invalid comparison between Unknown and I4
//IL_067c: Unknown result type (might be due to invalid IL or missing references)
//IL_0682: Invalid comparison between Unknown and I4
//IL_069c: Unknown result type (might be due to invalid IL or missing references)
//IL_06a2: Invalid comparison between Unknown and I4
//IL_0255: Unknown result type (might be due to invalid IL or missing references)
//IL_0428: Unknown result type (might be due to invalid IL or missing references)
//IL_042e: Invalid comparison between Unknown and I4
//IL_025e: Unknown result type (might be due to invalid IL or missing references)
//IL_0265: Unknown result type (might be due to invalid IL or missing references)
//IL_045c: Unknown result type (might be due to invalid IL or missing references)
//IL_0462: Invalid comparison between Unknown and I4
//IL_06bc: Unknown result type (might be due to invalid IL or missing references)
//IL_06c2: Invalid comparison between Unknown and I4
//IL_0498: Unknown result type (might be due to invalid IL or missing references)
//IL_049e: Invalid comparison between Unknown and I4
//IL_027c: Unknown result type (might be due to invalid IL or missing references)
//IL_0283: Unknown result type (might be due to invalid IL or missing references)
//IL_04ef: Unknown result type (might be due to invalid IL or missing references)
//IL_04f5: Invalid comparison between Unknown and I4
//IL_04d9: Unknown result type (might be due to invalid IL or missing references)
//IL_04df: Invalid comparison between Unknown and I4
//IL_028c: Unknown result type (might be due to invalid IL or missing references)
//IL_0293: Unknown result type (might be due to invalid IL or missing references)
//IL_06dc: Unknown result type (might be due to invalid IL or missing references)
string text = "";
string text2 = _node;
if (_shop == "caravanshop" && text2 == "")
{
text2 = "sen_44";
}
if (_townReroll > 0)
{
}
LootData lootData = Globals.Instance.GetLootData(_shop);
if ((Object)(object)lootData == (Object)null)
{
Plugin.LogError("Unable to get shop items for " + _shop + " (shop does not exist!)");
return null;
}
List<string> list = new List<string>();
List<string> list2 = new List<string>();
for (int i = 0; i < Globals.Instance.CardListByClass[(CardClass)8].Count; i++)
{
list2.Add(Globals.Instance.CardListByClass[(CardClass)8][i]);
}
int deterministicHashCode = Functions.GetDeterministicHashCode(text2 + _seed + text);
Random.InitState(deterministicHashCode);
IListExtensions.Shuffle<string>((IList<string>)list2, deterministicHashCode);
int num = 0;
int num2 = ((!_obeliskChallenge) ? lootData.NumItems : lootData.LootItemTable.Length);
for (int j = 0; j < num2; j++)
{
if (list.Count >= lootData.NumItems)
{
break;
}
if (j >= lootData.LootItemTable.Length)
{
continue;
}
LootItem val = lootData.LootItemTable[j];
if (!((double)Random.Range(0, 100) < (double)val.LootPercent))
{
continue;
}
if ((Object)(object)val.LootCard != (Object)null)
{
list.Add(val.LootCard.Id);
continue;
}
bool flag = false;
int num3 = 0;
CardData val2 = null;
while (!flag && num3 < 10000)
{
if (num >= list2.Count)
{
num = 0;
}
string text3 = list2[num];
if (!list.Contains(text3))
{
val2 = Globals.Instance.GetCardData(text3, false);
if ((Object)(object)val2.Item != (Object)null && !val2.Item.DropOnly)
{
if ((int)val2.CardUpgraded == 3)
{
flag = false;
}
else if (val2.Item.PercentRetentionEndGame > 0 && (_madness > 2 || _obeliskChallenge))
{
flag = false;
}
else if (val2.Item.PercentDiscountShop > 0 && _poverty)
{
flag = false;
}
else if ((int)val.LootType == 0 && val2.CardRarity == val.LootRarity)
{
flag = true;
}
else if (val2.CardType == val.LootType && val2.CardRarity == val.LootRarity)
{
flag = true;
}
}
}
num++;
num3++;
}
if (flag && (Object)(object)val2 != (Object)null)
{
list.Add(val2.Id);
}
}
for (int k = list.Count; k < lootData.NumItems; k++)
{
bool flag2 = false;
int num4 = 0;
CardData val3 = null;
int num5 = Random.Range(0, 100);
while (!flag2 && num4 < 10000)
{
if (num >= list2.Count)
{
num = 0;
}
string text4 = list2[num];
if (!list.Contains(text4))
{
val3 = Globals.Instance.GetCardData(text4, false);
if ((Object)(object)val3.Item != (Object)null && !val3.Item.DropOnly)
{
if ((int)val3.CardUpgraded == 3)
{
flag2 = false;
}
else if (val3.Item.PercentRetentionEndGame > 0 && (_madness > 2 || _obeliskChallenge))
{
flag2 = false;
}
else if (val3.Item.PercentDiscountShop > 0 && _poverty)
{
flag2 = false;
}
else if ((double)num5 < (double)lootData.DefaultPercentMythic)
{
if ((int)val3.CardRarity == 4)
{
flag2 = true;
}
}
else if ((double)num5 < (double)lootData.DefaultPercentEpic + (double)lootData.DefaultPercentMythic)
{
if ((int)val3.CardRarity == 3)
{
flag2 = true;
}
}
else if ((double)num5 < (double)lootData.DefaultPercentRare + (double)lootData.DefaultPercentEpic + (double)lootData.DefaultPercentMythic)
{
if ((int)val3.CardRarity == 2)
{
flag2 = true;
}
}
else if ((double)num5 < (double)lootData.DefaultPercentUncommon + (double)lootData.DefaultPercentRare + (double)lootData.DefaultPercentEpic + (double)lootData.DefaultPercentMythic)
{
if ((int)val3.CardRarity == 1)
{
flag2 = true;
}
}
else if ((int)val3.CardRarity == 0)
{
flag2 = true;
}
}
}
num++;
num4++;
if (!flag2 && num4 % 100 == 0)
{
num5 += 10;
}
}
if (flag2 && (Object)(object)val3 != (Object)null)
{
list.Add(val3.Id);
continue;
}
break;
}
IListExtensions.Shuffle<string>((IList<string>)list, deterministicHashCode);
if (!_shop.Contains("towntier") && ((!_obeliskChallenge && _madness > 0) || _obeliskChallenge))
{
int num6 = 0;
if (_shop.Contains("exoticshop"))
{
num6 += 8;
}
else if (_shop.Contains("rareshop"))
{
num6 += 4;
}
if (_obeliskChallenge)
{
if (_madness > 8)
{
num6 += 4;
}
else if (_madness > 4)
{
num6 += 2;
}
}
else
{
num6 += Functions.FuncRoundToInt(0.2f * (float)(_madness + _corruptorCount));
}
for (int l = 0; l < list.Count; l++)
{
int num7 = Random.Range(0, 100);
CardData cardData = Globals.Instance.GetCardData(list[l], false);
if (!((Object)(object)cardData == (Object)null))
{
bool flag3 = false;
if (((int)cardData.CardRarity == 4 || (int)cardData.CardRarity == 3) && num7 < 3 + num6)
{
flag3 = true;
}
else if ((int)cardData.CardRarity == 2 && num7 < 5 + num6)
{
flag3 = true;
}
else if ((int)cardData.CardRarity == 1 && num7 < 7 + num6)
{
flag3 = true;
}
else if ((int)cardData.CardRarity == 0 && num7 < 9 + num6)
{
flag3 = true;
}
if (flag3 && (Object)(object)cardData.UpgradesToRare != (Object)null)
{
list[l] = cardData.UpgradesToRare.Id;
}
}
}
}
return list;
}
public static string ConvertEventToNode(string eventId)
{
string pattern = "[^_]*_([^_\\d]*)(\\d+).*";
Match match = Regex.Match(eventId, pattern);
if (match.Success)
{
string value = match.Groups[1].Value;
string value2 = match.Groups[2].Value;
return value + "_" + value2;
}
return eventId;
}
public static void ListToJson(List<ItemObject> inputList, string filePath)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Expected O, but got Unknown
try
{
DataContractJsonSerializer val = new DataContractJsonSerializer(inputList.GetType());
using MemoryStream memoryStream = new MemoryStream();
((XmlObjectSerializer)val).WriteObject((Stream)memoryStream, (object)inputList);
memoryStream.Position = 0L;
using StreamReader streamReader = new StreamReader(memoryStream);
string contents = streamReader.ReadToEnd();
File.WriteAllText(filePath, contents);
}
catch (Exception ex)
{
Plugin.LogDebug("ERROR: Could not create JSON file " + ex.Message);
}
}
public static void ListToText(List<ItemObject> inputList, string filePath)
{
try
{
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append("{");
foreach (ItemObject input in inputList)
{
string id = input.Id;
string value = "\"" + id + "\": ";
stringBuilder.Append(value);
stringBuilder.Append("{");
string value2 = "\"CardName\":\"" + input.Name + "\", ";
string value3 = "\"CardClass\":\"" + input.CardType + "\", ";
string value4 = "\"CardRarity\":\"" + input.CardRarity + "\", ";
string value5 = "\"DropOnly\":" + input.Droponly.ToString().ToLower() + ", ";
string value6 = "\"CardUpgraded\":\"" + input.CardUpgraded + "\", ";
string value7 = "\"UpgradesToRareId\":\"" + input.UpgradesToRareId + "\", ";
string value8 = $"\"PercentRetentionEndGame\":{input.PercentRetentionEndGame}, ";
string value9 = $"\"PercentDiscountShop\":{input.PercentDiscountShop}";
stringBuilder.Append(value2);
stringBuilder.Append(value3);
stringBuilder.Append(value4);
stringBuilder.Append(value5);
stringBuilder.Append(value6);
stringBuilder.Append(value7);
stringBuilder.Append(value8);
stringBuilder.Append(value9);
stringBuilder.Append("}, ");
}
stringBuilder.Remove(stringBuilder.Length - 2, 2);
stringBuilder.Append("}");
File.WriteAllText(filePath, stringBuilder.ToString());
Plugin.LogDebug("Text file successfully created at: " + filePath);
}
catch (Exception ex)
{
Plugin.LogDebug("ERROR: Could not create text file " + ex.Message);
}
}
public static void WriteItemsToText()
{
Plugin.LogDebug("Logging all Keys");
List<ItemObject> list = new List<ItemObject>();
List<string> list2 = Globals.Instance.CardListByClass[(CardClass)8];
foreach (string item2 in list2)
{
CardData cardData = Globals.Instance.GetCardData(item2, true);
if ((Object)(object)cardData == (Object)null || (Object)(object)cardData.Item == (Object)null)
{
Plugin.LogDebug("CardData is null for " + item2);
continue;
}
ItemObject item = new ItemObject(item2, cardData);
list.Add(item);
}
if (Plugin.WriteItemsToTextFile.Value)
{
string text = (Path.IsPathRooted(Plugin.WriteItemsToTextFilePath.Value) ? Plugin.WriteItemsToTextFilePath.Value : (Utility.IsNullOrWhiteSpace(Plugin.WriteItemsToTextFilePath.Value) ? (Paths.BepInExRootPath + "/Logs/AllItems.txt") : (Paths.BepInExRootPath + Plugin.WriteItemsToTextFilePath.Value)));
ListToText(list, text);
AlertManager.Instance.AlertConfirm("All Items written to text at " + text, "");
}
}
public static string GetSavedSeed()
{
if (Utility.IsNullOrWhiteSpace(SavedSeed))
{
AtOManager instance = AtOManager.Instance;
return ((instance != null) ? instance.GetGameId() : null) ?? RandomString(7);
}
return SavedSeed;
}
}
[HarmonyPatch]
public class SeedSearcherPatches
{
[HarmonyPrefix]
[HarmonyPatch(typeof(HeroSelectionManager), "Start")]
public static void HeroSelectionManagerStartPrefix(ref HeroSelectionManager __instance, TMP_Text ___gameSeedTxt)
{
if (Plugin.SaveSeedToGame.Value)
{
AtOManager instance = AtOManager.Instance;
if (instance != null)
{
instance.SetGameId(SeedSearcherFunctions.GetSavedSeed());
}
___gameSeedTxt.text = SeedSearcherFunctions.GetSavedSeed();
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(AtOManager), "BeginAdventure")]
public static void BeginAdventurePrefix(ref AtOManager __instance)
{
if (Plugin.SaveSeedToGame.Value || Plugin.BypassMadnessRandomization.Value)
{
SeedSearcherFunctions.SavedSeed = __instance.GetGameId();
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(AtOManager), "BeginAdventure")]
public static void BeginAdventurePostfix(ref AtOManager __instance)
{
if (Plugin.SaveSeedToGame.Value || Plugin.BypassMadnessRandomization.Value)
{
Plugin.LogDebug("BeginAdventurePostfix - Setting GameID to " + SeedSearcherFunctions.GetSavedSeed());
__instance.SetGameId(SeedSearcherFunctions.GetSavedSeed());
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Globals), "CreateGameContent")]
public static void CreateGameContentPostfix(ref Globals __instance)
{
Plugin.LogInfo("CreateGameContentPostfix - Start");
if (Plugin.SearchForItemsOnStartup.Value)
{
SeedSearcherFunctions.ExecuteSearch();
}
if (false)
{
List<(string, string, string)> list = new List<(string, string, string)>(1) { ("heartofthornsrare", "caravanshop", "sen_44") };
List<(string, string)> list2 = new List<(string, string)>(1) { ("sen_29", "e_sen29_a") };
}
}
}
public static class PluginInfo
{
public const string PLUGIN_GUID = "com.binbin.SeedSearcher";
public const string PLUGIN_NAME = "SeedSearcher";
public const string PLUGIN_VERSION = "1.2.1";
}
}