Decompiled source of SurvivorSortOrder v1.0.4

SillySortOrder.dll

Decompiled 2 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using On.RoR2;
using RoR2;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("SillySortOrder")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("SillySortOrder")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("68d4b4da-4f05-4c48-a834-bb2de3af9e55")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: UnverifiableCode]
namespace SillyMod;

public class ConFag
{
	public enum Ror1MixType
	{
		Default,
		Risky1First,
		Risky1ButMixed
	}

	public static bool MixRor1Survivors;

	public static Ror1MixType Ror1Mix;

	public static bool NemesesSeparate;

	public static bool ForceModdedCharactersOut;

	public static string ForceOutWhiteList;

	public static Dictionary<string, float> CustomOrderSortings;

	public static List<string> ParseErrorLog = new List<string>();

	public static BaseUnityPlugin plugin;

	public static bool Debug;

	public static void DoConfig(BaseUnityPlugin plugin)
	{
		ConFag.plugin = plugin;
		MixRor1Survivors = plugin.Config.Bind<bool>("love ya", "Mix ror1 surivors", true, "Modded ror1 survivors will be mixed in with the rest of the cast, loosely based on their unlock condition.\nSet to false to separate them out and neatly place them together right after Vanilla\nOverrides those mods' original configs").Value;
		NemesesSeparate = plugin.Config.Bind<bool>("love ya", "Separate Nemesis", false, "Set to true to separate out nemesis survivors from the main lineup, grouped up after ror1 and ror2 survivors.\nSet to false to place next to their counterpart").Value;
		ForceModdedCharactersOut = plugin.Config.Bind<bool>("love ya", "Force Modded Characters Out", true, "Set to true to separate out any other non-ror1 modded characters.\nSet to false to leave them where their mod placed them").Value;
		string value = plugin.Config.Bind<string>("love ya", "Custom Order", "", "List of characters to apply a custom order, comma separated. .\nFormat is BodyName:Number. Number can be decimal between two values to place your character in between.\nExample: EngiBody:69,HereticBody:2,EnforcerBody:6.5,HANDOverclockedBody:8.1\nYou can copy from Print Sorting config below.").Value;
		CustomOrderSortings = ParseCustomOrder(value);
	}

	public static void PrintSortingConfig(string log)
	{
		Debug = plugin.Config.Bind<bool>("love ya", "Print Sorting", true, "This config does nothing. just shows what the game's current order is when you run the game so you can copy paste\n" + log).Value;
	}

	private static Dictionary<string, float> ParseCustomOrder(string customOrder)
	{
		Dictionary<string, float> dictionary = new Dictionary<string, float>();
		string[] array = customOrder.Split(new char[1] { ',' });
		foreach (string text in array)
		{
			if (string.IsNullOrEmpty(text))
			{
				continue;
			}
			string[] array2 = text.Split(new char[1] { ':' });
			if (array2.Length >= 2)
			{
				try
				{
					string key = array2[0].TrimStart(Array.Empty<char>()).TrimEnd(Array.Empty<char>());
					dictionary[key] = float.Parse(array2[1].TrimStart(Array.Empty<char>()).TrimEnd(Array.Empty<char>()));
				}
				catch (Exception arg)
				{
					ParseErrorLog.Add($"Custom Sort could not find sort position for entry: {text}\n{arg}");
				}
			}
			else
			{
				ParseErrorLog.Add("Custom Sort Entry Invalid: " + text + ". Should be BodyName:Number");
				if (array2.Length > 2)
				{
					ParseErrorLog.Add("If someone put : in their bodyname there's nothing I can do. Reach out to the mod creator, tell them Timesweeper sent you.");
				}
			}
		}
		return dictionary;
	}
}
[BepInPlugin("com.TheTimeSweeper.SurvivorSortOrder", "SurvivorSortOrder", "1.0.3")]
public class SillySortPlugin : BaseUnityPlugin
{
	public static Dictionary<string, float> ClassicSurivorSortings = new Dictionary<string, float>();

	public static Dictionary<string, float> VanillaSurivorSortings = new Dictionary<string, float>();

	public static ManualLogSource Log;

	public const float AFTER_VANILLA_INDEX = 20f;

	public const float NEMESES_INDEX = 21f;

	public const float AFTER_END_INDEX = 25f;

	private void Awake()
	{
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Expected O, but got Unknown
		Log = ((BaseUnityPlugin)this).Logger;
		ConFag.DoConfig((BaseUnityPlugin)(object)this);
		SetSurvivorSortings();
		SurvivorCatalog.SetSurvivorDefs += new hook_SetSurvivorDefs(SurvivorCatalog_SetSurvivorDefs);
	}

	private void SetSurvivorSortings()
	{
		VanillaSurivorSortings = new Dictionary<string, float>();
		VanillaSurivorSortings["CommandoBody"] = 1f;
		VanillaSurivorSortings["HuntressBody"] = 2f;
		VanillaSurivorSortings["Bandit2Body"] = 3f;
		VanillaSurivorSortings["ToolbotBody"] = 4f;
		VanillaSurivorSortings["EngiBody"] = 5f;
		VanillaSurivorSortings["MageBody"] = 6f;
		VanillaSurivorSortings["MercBody"] = 7f;
		VanillaSurivorSortings["TreebotBody"] = 8f;
		VanillaSurivorSortings["LoaderBody"] = 9f;
		VanillaSurivorSortings["CrocoBody"] = 10f;
		VanillaSurivorSortings["CaptainBody"] = 11f;
		VanillaSurivorSortings["HereticBody"] = 13f;
		VanillaSurivorSortings["RailgunnerBody"] = 14f;
		VanillaSurivorSortings["VoidSurvivorBody"] = 15f;
		if (ConFag.MixRor1Survivors)
		{
			ClassicSurivorSortings["HANDOverclockedBody"] = 4.1f;
			ClassicSurivorSortings["EnforcerBody"] = 5.1f;
			ClassicSurivorSortings["SniperClassicBody"] = 7.1f;
			ClassicSurivorSortings["CHEF"] = 8.2f;
			ClassicSurivorSortings["MinerBody"] = 9.1f;
		}
		else
		{
			ClassicSurivorSortings["EnforcerBody"] = 20.1f;
			ClassicSurivorSortings["SniperClassicBody"] = 20.2f;
			ClassicSurivorSortings["HANDOverclockedBody"] = 20.3f;
			ClassicSurivorSortings["CHEF"] = 20.4f;
			ClassicSurivorSortings["MinerBody"] = 20.5f;
		}
	}

	private void SurvivorCatalog_SetSurvivorDefs(orig_SetSurvivorDefs orig, SurvivorDef[] newSurvivorDefs)
	{
		try
		{
			Log.LogMessage((object)"[Before Sort]");
			PrintOrder(newSurvivorDefs);
			Dictionary<string, float> dictionary = new Dictionary<string, float>();
			for (int num = newSurvivorDefs.Length - 1; num >= 0; num--)
			{
				string name = ((Object)newSurvivorDefs[num].bodyPrefab).name;
				if (ConFag.ForceModdedCharactersOut && !ClassicSurivorSortings.ContainsKey(name) && !VanillaSurivorSortings.ContainsKey(name))
				{
					newSurvivorDefs[num].desiredSortPosition = 25f + newSurvivorDefs[num].desiredSortPosition * 0.001f;
				}
				if (ClassicSurivorSortings.ContainsKey(name))
				{
					newSurvivorDefs[num].desiredSortPosition = ClassicSurivorSortings[name];
				}
				if (!string.IsNullOrEmpty(newSurvivorDefs[num].displayNameToken))
				{
					string key = Language.GetString(newSurvivorDefs[num].displayNameToken, "en").ToLowerInvariant();
					dictionary[key] = newSurvivorDefs[num].desiredSortPosition;
				}
			}
			for (int i = 0; i < newSurvivorDefs.Length; i++)
			{
				if (string.IsNullOrEmpty(newSurvivorDefs[i].displayNameToken))
				{
					continue;
				}
				string text = Language.GetString(newSurvivorDefs[i].displayNameToken, "en").ToLowerInvariant();
				if (!text.Contains("nemesis"))
				{
					continue;
				}
				string[] array = text.Replace("nemesis ", "").Split(new char[1] { ' ' });
				for (int j = 0; j < array.Length; j++)
				{
					foreach (string key2 in dictionary.Keys)
					{
						if (array[j].Contains(key2.ToLowerInvariant()))
						{
							if (ConFag.NemesesSeparate)
							{
								newSurvivorDefs[i].desiredSortPosition = 21f + newSurvivorDefs[i].desiredSortPosition * 0.01f;
							}
							else
							{
								newSurvivorDefs[i].desiredSortPosition = dictionary[key2] + 1E-05f;
							}
						}
					}
				}
			}
			for (int k = 0; k < newSurvivorDefs.Length; k++)
			{
				string name2 = ((Object)newSurvivorDefs[k].bodyPrefab).name;
				if (ConFag.CustomOrderSortings.ContainsKey(name2))
				{
					newSurvivorDefs[k].desiredSortPosition = ConFag.CustomOrderSortings[name2];
					ConFag.CustomOrderSortings.Remove(name2);
				}
			}
			Log.LogMessage((object)"[After Sort]");
			PrintOrder(newSurvivorDefs, toConfig: true);
			string text2 = "";
			foreach (KeyValuePair<string, float> customOrderSorting in ConFag.CustomOrderSortings)
			{
				text2 = text2 + customOrderSorting.Key + ", ";
			}
			if (!string.IsNullOrEmpty(text2))
			{
				Log.LogWarning((object)("Could not find body to sort for: " + text2 + "\nEither these characters don't exist or you messed up typing lol."));
			}
			for (int l = 0; l < ConFag.ParseErrorLog.Count; l++)
			{
				Log.LogError((object)ConFag.ParseErrorLog[l]);
			}
		}
		catch (Exception ex)
		{
			Log.LogError((object)("Failed to sort survivors. Reach out to `thetimesweeper` on discord and send this error pls\n" + ex));
		}
		orig.Invoke(newSurvivorDefs);
	}

	private void PrintOrder(SurvivorDef[] newSurvivorDefs, bool toConfig = false)
	{
		List<SurvivorDef> list = newSurvivorDefs.ToList();
		list.Sort((SurvivorDef def1, SurvivorDef def2) => (def1.desiredSortPosition >= def2.desiredSortPosition) ? 1 : (-1));
		string text = "Printed Sort Order:\n";
		for (int i = 0; i < list.Count; i++)
		{
			Log.LogMessage((object)(((Object)list[i].bodyPrefab).name + " sort position: " + list[i].desiredSortPosition));
			string arg = ((i == 0) ? "" : ", ");
			text += $"{arg}{((Object)list[i].bodyPrefab).name}:{list[i].desiredSortPosition}";
		}
		if (toConfig)
		{
			Log.LogMessage((object)text);
			ConFag.PrintSortingConfig(text);
		}
	}

	private void PrintStats(List<SurvivorDef> newSurvivorDefs)
	{
		for (int i = 0; i < newSurvivorDefs.Count; i++)
		{
			CharacterBody component = newSurvivorDefs[i].bodyPrefab.GetComponent<CharacterBody>();
			Log.LogInfo((object)$"{newSurvivorDefs[i]._cachedName}: Health {component.baseMaxHealth}, Regen: {component.baseRegen}, Armor {component.baseArmor}");
		}
	}
}