Decompiled source of REFURBISHED ROBOMANDO v1.0.0

RefurbishedRoboMando.dll

Decompiled 4 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HG.Reflection;
using Microsoft.CodeAnalysis;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using MonoMod.RuntimeDetour;
using R2API;
using RoR2;
using RobomandoMod.Survivors.Robomando.SkillStates;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: OptIn]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("RefurbishedRoboMando")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+2c30b6ba02acba66615f2ae506aae3788a60d295")]
[assembly: AssemblyProduct("RefurbishedRoboMando")]
[assembly: AssemblyTitle("RefurbishedRoboMando")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.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;
		}
	}
}
namespace RefurbishedRoboMando
{
	public static class ColorCode
	{
		public enum FontColor
		{
			cStack,
			cIsDamage,
			cIsHealth,
			cIsUtility,
			cIsHealing
		}

		public static string Style(this string self, FontColor style)
		{
			return "<style=" + style.ToString() + ">" + self + "</style>";
		}
	}
	public static class RoboMandoToggle
	{
		public static ConfigEntry<bool> Enable_Icon_Change;

		public static ConfigEntry<bool> Enable_Logbook_Change;

		public static ConfigEntry<bool> Enable_Skin_Disable;

		public static ConfigEntry<bool> Enable_Skill_Stat_Changes;

		public static ConfigEntry<bool> Enable_Body_Stat_Changes;

		public static ConfigEntry<bool> Enable_Token_Changes;
	}
	public static class RoboMandoStats
	{
		public static ConfigEntry<bool> Icon_Direction;

		public static ConfigEntry<float> Shoot_Damage;

		public static ConfigEntry<float> Shoot_Coefficient;

		public static ConfigEntry<float> Zap_Damage;

		public static ConfigEntry<float> Zap_Coefficient;

		public static ConfigEntry<float> Zap_Cooldown;

		public static ConfigEntry<float> Dive_Splat_Duration;

		public static ConfigEntry<float> Dive_Cooldown;

		public static ConfigEntry<float> Hack_Duration;

		public static ConfigEntry<float> Hack_Cooldown;

		public static ConfigEntry<float> Hack_NoTarget_Cooldown;

		public static ConfigEntry<int> Health_Shield_Percent;
	}
	public static class Configs
	{
		private static BaseUnityPlugin staticPlugin;

		public static void SetUp(BaseUnityPlugin plugin)
		{
			//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d8: Expected O, but got Unknown
			staticPlugin = plugin;
			RoboMandoToggle.Enable_Icon_Change = staticPlugin.Config.Bind<bool>("! General !", "Replace ROBOMANDO Survivor Icon?", true, "[ True = Replaced | False = Original ]\nReplaces ROBOMANDO's icon");
			RoboMandoToggle.Enable_Logbook_Change = staticPlugin.Config.Bind<bool>("! General !", "Replace ROBOMANDO Logbook Model?", true, "[ True = Replaced | False = Original ]\nReplaces ROBOMANDO's Logbook model");
			RoboMandoToggle.Enable_Skin_Disable = staticPlugin.Config.Bind<bool>("! General !", "Disable Non Whitelisted Skins?", true, "[ True = Whitelist | False = Original ]\nRemoves non whitelisted skins, and adds a configurable whitelist");
			RoboMandoToggle.Enable_Skill_Stat_Changes = staticPlugin.Config.Bind<bool>("! General !", "Enable Skill Stat Reworks?", true, "[ True = Reworked | False = Original ]\nAllows configurable stats to ROBOMANDO's skills");
			RoboMandoToggle.Enable_Body_Stat_Changes = staticPlugin.Config.Bind<bool>("! General !", "Enable Body Stat Reworks?", true, "[ True = Reworked | False = Original ]\nAllows minor configurations to ROBOMANDO's base stats");
			RoboMandoToggle.Enable_Token_Changes = staticPlugin.Config.Bind<bool>("! General !", "Enable Description Rewrite?", true, "[ True = Rewritten | False = Original ]\nChanges ROBOMANDO's descriptive texts, required for visible skill stat changes");
			if (RoboMandoToggle.Enable_Icon_Change.Value)
			{
				RoboMandoStats.Icon_Direction = staticPlugin.Config.Bind<bool>("Survivor Icon", "Icon Direction", true, "[ True = Face Left | False = Face Right ]\nWhat direction the icon faces");
			}
			if (RoboMandoToggle.Enable_Skill_Stat_Changes.Value)
			{
				string text = "Skill Statistics";
				RoboMandoStats.Shoot_Damage = staticPlugin.Config.Bind<float>(text, "Primary Damage Modifier", 75f, "[ 75.0 = 75% Damage | Original = 80% ]\nDamage per primary shot");
				RoboMandoStats.Shoot_Coefficient = staticPlugin.Config.Bind<float>(text, "Primary Coefficient Modifier", 100f, "[ 100.0 = 100% Coefficient | Original = 100% ]\nChance to proc per primary shot");
				RoboMandoStats.Zap_Damage = staticPlugin.Config.Bind<float>(text, "Secondary Damage Modifier", 220f, "[ 220.0 = 220% Damage | Original = 180% ]\nDamage per secondary shot");
				RoboMandoStats.Zap_Coefficient = staticPlugin.Config.Bind<float>(text, "Secondary Coefficient Modifier", 200f, "[ 200.0 = 200% Coefficient | Original = 300% ]\nChance to proc per secondary shot");
				RoboMandoStats.Zap_Cooldown = staticPlugin.Config.Bind<float>(text, "Secondary Cooldown", 3f, "[ 3.0 = 3 Seconds | Original = 2 Seconds ]\nSecondary cooldown timer");
				RoboMandoStats.Dive_Splat_Duration = staticPlugin.Config.Bind<float>(text, "Utility Splat Duration", 0.75f, "[ 0.75 = 0.75 Seconds | Original = 2 Seconds ]\nTimer on falling after utility");
				RoboMandoStats.Dive_Cooldown = staticPlugin.Config.Bind<float>(text, "Utility Cooldown", 4f, "[ 4.0 = 4 Seconds | Original = 4 Seconds ]\nUtility cooldown timer");
				RoboMandoStats.Hack_Duration = staticPlugin.Config.Bind<float>(text, "Special Duration", 3f, "[ 3.0 = 3 Seconds | Original = 3.33 Seconds ]\nHacking duration");
				RoboMandoStats.Hack_Cooldown = staticPlugin.Config.Bind<float>(text, "Special Cooldown", 5f, "[ 5.0 = 5 Seconds | Original = 8 Seconds ]\nSpecial cooldown timer");
				RoboMandoStats.Hack_NoTarget_Cooldown = staticPlugin.Config.Bind<float>(text, "Special Fail Cooldown", 0.5f, "[ 0.5 = 0.5 Seconds | Original = 2 Seconds ]\nSpecial cooldown timer when no target");
			}
			if (RoboMandoToggle.Enable_Body_Stat_Changes.Value)
			{
				string text2 = "Body Statistics";
				RoboMandoStats.Health_Shield_Percent = staticPlugin.Config.Bind<int>(text2, "Health to Shield Percent", 0, new ConfigDescription("[ 0.0 = 0% Conversion ]\nBase Health to Shield percent", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
			}
			if (RoboMandoToggle.Enable_Skin_Disable.Value)
			{
				string value = staticPlugin.Config.Bind<string>("Skin Whitelist", "Allowed Skins", "NOODLEGEMO_SKIN_ROBOMANDO_NAME", "List of ROBOMANDO skins that will be ignored when disabling, comma seperated.\n-\nExample: NOODLEGEMO_SKIN_ROBOMANDO_NAME, DEFAULT_SKIN, ...").Value;
				FindSkinDefs(value);
			}
		}

		public static void SkinDefList(List<string> allSkins)
		{
			string text = "\n";
			foreach (string allSkin in allSkins)
			{
				text = text + allSkin + ", ";
			}
			staticPlugin.Config.Bind<string>("Skin Whitelist", "All Skin Tokens", "", $"Just for the sake of printing every single Skin Token for disabling / enabling.\n-{text}");
		}

		private static void FindSkinDefs(string allowedDefs)
		{
			string[] array = allowedDefs.Split(',');
			string[] array2 = array;
			foreach (string text in array2)
			{
				if (!string.IsNullOrEmpty(text) && !string.IsNullOrEmpty(text.Trim()))
				{
					RefurbishedRoboMando.whitelistSkins.Add(text.Trim());
				}
			}
		}
	}
	internal static class Log
	{
		private static ManualLogSource _logSource;

		internal static void Init(ManualLogSource logSource)
		{
			_logSource = logSource;
		}

		internal static void Debug(object data)
		{
			_logSource.LogDebug(data);
		}

		internal static void Error(object data)
		{
			_logSource.LogError(data);
		}

		internal static void Fatal(object data)
		{
			_logSource.LogFatal(data);
		}

		internal static void Info(object data)
		{
			_logSource.LogInfo(data);
		}

		internal static void Message(object data)
		{
			_logSource.LogMessage(data);
		}

		internal static void Warning(object data)
		{
			_logSource.LogWarning(data);
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("noodlegemo.ROBOMANDO_Refurbished", "ROBOMANDO_Refurbished", "1.0.0")]
	public class RefurbishedRoboMando : BaseUnityPlugin
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static Action <0>__ReplaceLast;

			public static Manipulator <1>__ChangeHackCooldown;

			public static Manipulator <2>__ChangeHackFailCooldown;
		}

		public const string PluginGUID = "noodlegemo.ROBOMANDO_Refurbished";

		public const string PluginAuthor = "noodlegemo";

		public const string PluginName = "ROBOMANDO_Refurbished";

		public const string PluginVersion = "1.0.0";

		private static AssetBundle assetBundle;

		private static readonly string roboBodyName = "RobomandoBody";

		private static GameObject roboPrefab;

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

		internal static RefurbishedRoboMando Instance { get; private set; }

		public void Awake()
		{
			Log.Init(((BaseUnityPlugin)this).Logger);
			Configs.SetUp((BaseUnityPlugin)(object)this);
			Instance = this;
			RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(ReplaceLast));
			if (RoboMandoToggle.Enable_Icon_Change.Value)
			{
				assetBundle = AssetBundle.LoadFromFile(Path.Combine(Directory.GetParent(((BaseUnityPlugin)this).Info.Location).ToString(), "Assets/robomandoasset"));
				((ResourceAvailability)(ref BodyCatalog.availability)).CallWhenAvailable((Action)ReplaceIcon);
			}
		}

		private static void ReplaceLast()
		{
			if (RoboMandoToggle.Enable_Skin_Disable.Value)
			{
				DisableSkins();
			}
			if (RoboMandoToggle.Enable_Token_Changes.Value)
			{
				AddLanguageTokens();
			}
			if (RoboMandoToggle.Enable_Skill_Stat_Changes.Value)
			{
				ModifySkillStats();
			}
			if (RoboMandoToggle.Enable_Body_Stat_Changes.Value)
			{
				ModifyBodyStats();
			}
			if (RoboMandoToggle.Enable_Logbook_Change.Value)
			{
				GameObject gameObject = ((Component)roboPrefab.GetComponent<ModelLocator>().modelTransform).gameObject;
				ReplaceLogbook replaceLogbook = gameObject.AddComponent<ReplaceLogbook>();
			}
		}

		private static void ReplaceIcon()
		{
			roboPrefab = BodyCatalog.FindBodyPrefab(roboBodyName);
			CharacterBody val = (Object.op_Implicit((Object)(object)roboPrefab) ? roboPrefab.GetComponent<CharacterBody>() : null);
			if (!((Object)(object)val == (Object)null))
			{
				if (RoboMandoStats.Icon_Direction.Value)
				{
					val.portraitIcon = (Texture)(object)assetBundle.LoadAsset<Sprite>("RobomandoIcon").texture;
				}
				else
				{
					val.portraitIcon = (Texture)(object)assetBundle.LoadAsset<Sprite>("RobomandoIconAlt").texture;
				}
			}
		}

		private static void DisableSkins()
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Expected I4, but got Unknown
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Expected I4, but got Unknown
			CharacterBody val = (Object.op_Implicit((Object)(object)roboPrefab) ? roboPrefab.GetComponent<CharacterBody>() : null);
			if (!Object.op_Implicit((Object)(object)val))
			{
				return;
			}
			List<SkinDef> list = new List<SkinDef>();
			List<string> list2 = new List<string>();
			SkinDef[] bodySkins = BodyCatalog.GetBodySkins(val.bodyIndex);
			foreach (SkinDef val2 in bodySkins)
			{
				if (!((Object)(object)val2 == (Object)null) || val2.nameToken != null)
				{
					list2.Add(val2.nameToken);
					if (whitelistSkins.Contains(val2.nameToken))
					{
						list.Add(val2);
					}
				}
			}
			Configs.SkinDefList(list2);
			SkinDef[][] skins = BodyCatalog.skins;
			int num = (int)val.bodyIndex;
			List<SkinDef> list3 = list;
			int num2 = 0;
			SkinDef[] array = (SkinDef[])(object)new SkinDef[list3.Count];
			foreach (SkinDef item in list3)
			{
				array[num2] = item;
				num2++;
			}
			skins[num] = array;
			SkinDef[][] skinsByBody = SkinCatalog.skinsByBody;
			int num3 = (int)val.bodyIndex;
			List<SkinDef> list4 = list;
			int num4 = 0;
			SkinDef[] array2 = (SkinDef[])(object)new SkinDef[list4.Count];
			foreach (SkinDef item2 in list4)
			{
				array2[num4] = item2;
				num4++;
			}
			skinsByBody[num3] = array2;
			ModelLocator component = roboPrefab.GetComponent<ModelLocator>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				return;
			}
			ModelSkinController component2 = ((Component)component.modelTransform).gameObject.GetComponent<ModelSkinController>();
			if (!Object.op_Implicit((Object)(object)component2))
			{
				return;
			}
			ModelSkinController val3 = component2;
			List<SkinDef> list5 = list;
			int num5 = 0;
			SkinDef[] array3 = (SkinDef[])(object)new SkinDef[list5.Count];
			foreach (SkinDef item3 in list5)
			{
				array3[num5] = item3;
				num5++;
			}
			val3.skins = array3;
		}

		private static void AddLanguageTokens()
		{
			string text = "RAT_ROBOMANDO_";
			LanguageAPI.AddOverlay(text + "NAME", "ROBOMANDO");
			LanguageAPI.AddOverlay(text + "DESCRIPTION", "Your ROBOMANDO Model-7 comes equipped with everything it needs to extract resources from hostile environments.<color=#CCD3E0>\n\n< ! > As weak as Single Fire is, it has no fall-off damage.\n\n< ! > Despite the short range on De-Escalate, you can utilize it to pierce through multiple enemies at once, stunning them all in series.\n\n< ! > Re-Wire allows instant access to any company sanctioned containers or drone utilities - make up your lack of strength and durability through stealing everything!\n\n< ! > Remember that ROBOMANDO's skills aren't the most effective against enemies - use your increased movement speed to maintain distance accordingly.");
			LanguageAPI.AddOverlay(text + "LORE", "Order: ROBOMANDO Model-7\r\nTracking Number: 45133554F44495351454" + "\r\n\r\nT  H  A  N  K    Y  O  U    F  O  R    P  U  R  C  H  A  S  I  N  G    T  H  I  S    R  O  B  O  M  A  N  D  O    M  O  D  E  L   -  7  .".Style(ColorCode.FontColor.cStack) + "\r\nI  N  S  T  R  U  C  T  I  O  N  S    A  R  E    I  N  C  L  U  D  E  D     I  N    A    S  E  P  E  R  A  T  E    P  A  C  K  A  G  E   .".Style(ColorCode.FontColor.cStack) + "\r\n\r\n... Damn.");
			LanguageAPI.AddOverlay(text + "PRIMARY_SHOT_DESCRIPTION", string.Format("Agile".Style(ColorCode.FontColor.cIsUtility) + ". Shoot once for " + "{0}% damage".Style(ColorCode.FontColor.cIsDamage) + ".", RoboMandoStats.Shoot_Damage.Value));
			LanguageAPI.AddOverlay(text + "SECONDARY_ZAP_DESCRIPTION", string.Format("Agile".Style(ColorCode.FontColor.cIsUtility) + ". " + "Stunning".Style(ColorCode.FontColor.cIsDamage) + ". Fire a small electrical charge that " + "pierces enemies ".Style(ColorCode.FontColor.cIsDamage) + "for " + "{0}% damage".Style(ColorCode.FontColor.cIsDamage) + ".", RoboMandoStats.Zap_Damage.Value));
			LanguageAPI.AddOverlay(text + "UTILITY_ROLL_DESCRIPTION", "Attempt to " + "dive forward ".Style(ColorCode.FontColor.cIsUtility) + "a small distance. You " + "cannot be hit ".Style(ColorCode.FontColor.cIsUtility) + "early in the maneuver.");
			LanguageAPI.AddOverlay(text + "SPECIAL_HACK_NAME", "Re-Wire");
			LanguageAPI.AddOverlay(text + "SPECIAL_HACK_DESCRIPTION", "Re-wire a mechanical object, " + "activating it for free".Style(ColorCode.FontColor.cIsUtility) + ".");
			SkillLocator val = (Object.op_Implicit((Object)(object)roboPrefab) ? roboPrefab.GetComponent<SkillLocator>() : null);
			if (Object.op_Implicit((Object)(object)val))
			{
				val.primary.skillFamily.defaultSkillDef.keywordTokens = new string[1] { "KEYWORD_AGILE" };
				val.secondary.skillFamily.defaultSkillDef.keywordTokens = new string[2] { "KEYWORD_AGILE", "KEYWORD_STUNNING" };
			}
		}

		private static void ModifySkillStats()
		{
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Expected O, but got Unknown
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Expected O, but got Unknown
			SkillLocator val = (Object.op_Implicit((Object)(object)roboPrefab) ? roboPrefab.GetComponent<SkillLocator>() : null);
			if (Object.op_Implicit((Object)(object)val))
			{
				Shoot.damageCoefficient = RoboMandoStats.Shoot_Damage.Value / 100f;
				Shoot.procCoefficient = RoboMandoStats.Shoot_Coefficient.Value / 100f;
				Zap.damageCoefficient = RoboMandoStats.Zap_Damage.Value / 100f;
				Zap.procCoefficient = RoboMandoStats.Zap_Coefficient.Value / 100f;
				val.secondary.skillFamily.defaultSkillDef.baseRechargeInterval = RoboMandoStats.Zap_Cooldown.Value;
				Roll.crashDuration = RoboMandoStats.Dive_Splat_Duration.Value;
				val.utility.skillFamily.defaultSkillDef.baseRechargeInterval = RoboMandoStats.Dive_Cooldown.Value;
				Hack.BaseDuration = RoboMandoStats.Hack_Duration.Value;
				Hack.soundDuration = RoboMandoStats.Hack_Duration.Value * (2f / 3f);
				val.special.skillFamily.defaultSkillDef.baseRechargeInterval = RoboMandoStats.Hack_Cooldown.Value;
				val.special.skillFamily.defaultSkillDef.cancelSprintingOnActivation = false;
				RoboMandoStats.Hack_NoTarget_Cooldown.Value = Math.Min(RoboMandoStats.Hack_NoTarget_Cooldown.Value, RoboMandoStats.Hack_Cooldown.Value);
				MethodInfo? method = typeof(Hack).GetMethod("OnEnter");
				object obj = <>O.<1>__ChangeHackCooldown;
				if (obj == null)
				{
					Manipulator val2 = ChangeHackCooldown;
					<>O.<1>__ChangeHackCooldown = val2;
					obj = (object)val2;
				}
				new ILHook((MethodBase)method, (Manipulator)obj);
				MethodInfo? method2 = typeof(Hack).GetMethod("FixedUpdate");
				object obj2 = <>O.<2>__ChangeHackFailCooldown;
				if (obj2 == null)
				{
					Manipulator val3 = ChangeHackFailCooldown;
					<>O.<2>__ChangeHackFailCooldown = val3;
					obj2 = (object)val3;
				}
				new ILHook((MethodBase)method2, (Manipulator)obj2);
			}
		}

		private static void ModifyBodyStats()
		{
			CharacterBody component = roboPrefab.GetComponent<CharacterBody>();
			if (Object.op_Implicit((Object)(object)component))
			{
				float num = (float)RoboMandoStats.Health_Shield_Percent.Value / 100f;
				component.baseMaxHealth = Math.Max(80f * (1f - num), 1f);
				component.levelMaxHealth = 28f * (1f - num);
				component.baseMaxShield = Math.Min(80f * num, 79f);
				component.levelMaxShield = 28f * num;
				component.baseRegen = 3f;
				component.levelRegen = 0.3f;
				component.baseDamage = 15f;
				component.levelDamage = 3.2f;
				component.baseArmor = 0f;
				component.baseMoveSpeed = 9f;
			}
		}

		private static void ChangeHackCooldown(ILContext il)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			float num = default(float);
			if (val.TryGotoNext(new Func<Instruction, bool>[2]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdcR4(x, ref num),
				(Instruction x) => ILPatternMatchingExt.MatchStfld<GenericSkill>(x, "finalRechargeInterval")
			}))
			{
				val.Remove();
				val.Emit(OpCodes.Ldc_R4, RoboMandoStats.Hack_Cooldown.Value);
			}
			else
			{
				Log.Warning("Failed to hook Change Hack Cooldown");
			}
		}

		private static void ChangeHackFailCooldown(ILContext il)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			float num = default(float);
			if (val.TryGotoNext(new Func<Instruction, bool>[2]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdcR4(x, ref num),
				(Instruction x) => ILPatternMatchingExt.MatchStfld<GenericSkill>(x, "finalRechargeInterval")
			}))
			{
				val.Remove();
				val.Emit(OpCodes.Ldc_R4, RoboMandoStats.Hack_NoTarget_Cooldown.Value);
			}
			else
			{
				Log.Warning("Failed to hook Change Hack Fail Cooldown");
			}
		}
	}
	public class ReplaceLogbook : MonoBehaviour
	{
		private ModelSkinController component;

		private static int skinIndex;

		private void Awake()
		{
			skinIndex = 0;
			component = ((Component)this).GetComponent<ModelSkinController>();
			CharacterBody val = BodyCatalog.FindBodyPrefab("RobomandoBody").GetComponent<CharacterBody>();
			if (!Object.op_Implicit((Object)(object)val))
			{
				return;
			}
			SkinDef[] skins = ((Component)component).GetComponent<ModelSkinController>().skins;
			SkinDef[] array = skins;
			int num = 0;
			if (num < array.Length)
			{
				SkinDef val2 = array[num];
				if (!val2.nameToken.Equals("NOODLEGEMO_SKIN_ROBOMANDO_NAME"))
				{
					skinIndex++;
				}
			}
		}

		private void Start()
		{
			if (SceneCatalog.currentSceneDef.cachedName == "logbook")
			{
				component.ApplySkin(skinIndex);
			}
		}
	}
}

ROBOMANDO_Refurbished.dll

Decompiled 4 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using MonoMod.RuntimeDetour.HookGen;
using RoR2;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace ROBOMANDO_Refurbished;

[BepInPlugin("com.noodlegemo.ROBOMANDO_Refurbished", "ROBOMANDO_Refurbished", "1.0.0")]
public class ROBOMANDO_RefurbishedPlugin : BaseUnityPlugin
{
	private class FieldException : Exception
	{
		public FieldException(string message, Exception innerException)
			: base(message, innerException)
		{
		}
	}

	private static AssetBundle assetBundle;

	private static readonly List<Material> materialsWithRoRShader = new List<Material>();

	internal static ROBOMANDO_RefurbishedPlugin Instance { get; private set; }

	internal static ManualLogSource InstanceLogger
	{
		get
		{
			ROBOMANDO_RefurbishedPlugin instance = Instance;
			return (instance != null) ? ((BaseUnityPlugin)instance).Logger : null;
		}
	}

	private void Start()
	{
		Instance = this;
		using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("ROBOMANDO_Refurbished.noodlegemorobomando_refurbished"))
		{
			assetBundle = AssetBundle.LoadFromStream(stream);
		}
		((ResourceAvailability)(ref BodyCatalog.availability)).CallWhenAvailable((Action)BodyCatalogInit);
		HookEndpointManager.Add((MethodBase)typeof(Language).GetMethod("LoadStrings"), (Delegate)new Action<Action<Language>, Language>(LanguageLoadStrings));
		ReplaceShaders();
	}

	private static void ReplaceShaders()
	{
		LoadMaterialsWithReplacedShader("RoR2/Base/Shaders/HGStandard.shader", "Assets/Resources/BodyMat.mat", "Assets/Resources/GunMat.mat");
	}

	private static void LoadMaterialsWithReplacedShader(string shaderPath, params string[] materialPaths)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		Shader shader = Addressables.LoadAssetAsync<Shader>((object)shaderPath).WaitForCompletion();
		foreach (string text in materialPaths)
		{
			Material val = assetBundle.LoadAsset<Material>(text);
			val.shader = shader;
			materialsWithRoRShader.Add(val);
		}
	}

	private static void LanguageLoadStrings(Action<Language> orig, Language self)
	{
		orig(self);
		self.SetStringByToken("NOODLEGEMO_SKIN_ROBOMANDO_NAME", "Refurbished");
	}

	private static void Nothing(Action<SkinDef> orig, SkinDef self)
	{
	}

	private static void BodyCatalogInit()
	{
		MethodInfo method = typeof(SkinDef).GetMethod("Awake", BindingFlags.Instance | BindingFlags.NonPublic);
		HookEndpointManager.Add((MethodBase)method, (Delegate)new Action<Action<SkinDef>, SkinDef>(Nothing));
		AddRobomandoBodyRobomandoSkin();
		HookEndpointManager.Remove((MethodBase)method, (Delegate)new Action<Action<SkinDef>, SkinDef>(Nothing));
	}

	private static void AddRobomandoBodyRobomandoSkin()
	{
		//IL_0273: Unknown result type (might be due to invalid IL or missing references)
		string text = "RobomandoBody";
		string text2 = "Robomando";
		try
		{
			GameObject val = BodyCatalog.FindBodyPrefab(text);
			if (!Object.op_Implicit((Object)(object)val))
			{
				InstanceLogger.LogWarning((object)("Failed to add \"" + text2 + "\" skin because \"" + text + "\" doesn't exist"));
				return;
			}
			ModelLocator component = val.GetComponent<ModelLocator>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				InstanceLogger.LogWarning((object)("Failed to add \"" + text2 + "\" skin to \"" + text + "\" because it doesn't have \"ModelLocator\" component"));
				return;
			}
			GameObject gameObject = ((Component)component.modelTransform).gameObject;
			ModelSkinController skinController = (Object.op_Implicit((Object)(object)gameObject) ? gameObject.GetComponent<ModelSkinController>() : null);
			if (!Object.op_Implicit((Object)(object)skinController))
			{
				InstanceLogger.LogWarning((object)("Failed to add \"" + text2 + "\" skin to \"" + text + "\" because it doesn't have \"ModelSkinController\" component"));
				return;
			}
			Renderer[] renderers = gameObject.GetComponentsInChildren<Renderer>(true);
			SkinDef skin = ScriptableObject.CreateInstance<SkinDef>();
			TryCatchThrow("Icon", delegate
			{
				skin.icon = assetBundle.LoadAsset<Sprite>("Assets\\SkinMods\\ROBOMANDO_Refurbished\\Icons\\RobomandoIcon.png");
			});
			((Object)skin).name = text2;
			skin.nameToken = "NOODLEGEMO_SKIN_ROBOMANDO_NAME";
			skin.rootObject = gameObject;
			TryCatchThrow("Base Skins", delegate
			{
				skin.baseSkins = (SkinDef[])(object)new SkinDef[1] { skinController.skins[0] };
			});
			TryCatchThrow("Unlockable Name", delegate
			{
				skin.unlockableDef = null;
			});
			TryCatchThrow("Game Object Activations", delegate
			{
				skin.gameObjectActivations = Array.Empty<GameObjectActivation>();
			});
			TryCatchThrow("Renderer Infos", delegate
			{
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				//IL_004c: Unknown result type (might be due to invalid IL or missing references)
				//IL_004d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0056: Unknown result type (might be due to invalid IL or missing references)
				//IL_0075: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
				skin.rendererInfos = (RendererInfo[])(object)new RendererInfo[2]
				{
					new RendererInfo
					{
						defaultMaterial = assetBundle.LoadAsset<Material>("Assets/Resources/BodyMat.mat"),
						defaultShadowCastingMode = (ShadowCastingMode)1,
						ignoreOverlays = false,
						renderer = renderers[3]
					},
					new RendererInfo
					{
						defaultMaterial = assetBundle.LoadAsset<Material>("Assets/Resources/GunMat.mat"),
						defaultShadowCastingMode = (ShadowCastingMode)1,
						ignoreOverlays = false,
						renderer = renderers.First((Renderer r) => ((Object)r).name == "Gun")
					}
				};
			});
			TryCatchThrow("Mesh Replacements", delegate
			{
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_003c: Unknown result type (might be due to invalid IL or missing references)
				//IL_003d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0046: Unknown result type (might be due to invalid IL or missing references)
				//IL_0093: Unknown result type (might be due to invalid IL or missing references)
				//IL_0094: Unknown result type (might be due to invalid IL or missing references)
				skin.meshReplacements = (MeshReplacement[])(object)new MeshReplacement[2]
				{
					new MeshReplacement
					{
						mesh = assetBundle.LoadAsset<Mesh>("Assets\\SkinMods\\ROBOMANDO_Refurbished\\Meshes\\Fella.mesh"),
						renderer = renderers[3]
					},
					new MeshReplacement
					{
						mesh = assetBundle.LoadAsset<Mesh>("Assets\\SkinMods\\ROBOMANDO_Refurbished\\Meshes\\Gun.mesh"),
						renderer = renderers.First((Renderer r) => ((Object)r).name == "Gun")
					}
				};
			});
			TryCatchThrow("Minion Skin Replacements", delegate
			{
				skin.minionSkinReplacements = Array.Empty<MinionSkinReplacement>();
			});
			TryCatchThrow("Projectile Ghost Replacements", delegate
			{
				skin.projectileGhostReplacements = Array.Empty<ProjectileGhostReplacement>();
			});
			Array.Resize(ref skinController.skins, skinController.skins.Length + 1);
			skinController.skins[skinController.skins.Length - 1] = skin;
			BodyCatalog.skins[BodyCatalog.FindBodyIndex(val)] = skinController.skins;
		}
		catch (FieldException ex)
		{
			InstanceLogger.LogWarning((object)("Failed to add \"" + text2 + "\" skin to \"" + text + "\""));
			InstanceLogger.LogWarning((object)("Field causing issue: " + ex.Message));
			InstanceLogger.LogError((object)ex.InnerException);
		}
		catch (Exception ex2)
		{
			InstanceLogger.LogWarning((object)("Failed to add \"" + text2 + "\" skin to \"" + text + "\""));
			InstanceLogger.LogError((object)ex2);
		}
	}

	private static void TryCatchThrow(string message, Action action)
	{
		try
		{
			action?.Invoke();
		}
		catch (Exception innerException)
		{
			throw new FieldException(message, innerException);
		}
	}
}