Decompiled source of HIFURexTweaks v1.2.9

HIFURexTweaks.dll

Decompiled 3 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using EntityStates;
using EntityStates.Toolbot;
using EntityStates.Treebot;
using EntityStates.Treebot.Weapon;
using HarmonyLib;
using IL.RoR2;
using KinematicCharacterController;
using Microsoft.CodeAnalysis;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using On.EntityStates;
using On.EntityStates.Treebot;
using On.EntityStates.Treebot.Weapon;
using On.RoR2;
using R2API;
using RoR2;
using RoR2.Projectile;
using RoR2.Skills;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Networking;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("HIFURexTweaks")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("HIFURexTweaks")]
[assembly: AssemblyTitle("HIFURexTweaks")]
[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 HIFURexTweaks
{
	public class ConfigManager
	{
		internal static bool ConfigChanged;

		internal static bool VersionChanged;

		public static T HandleConfig<T>(ConfigEntryBase entry, ConfigFile config, string name)
		{
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Expected O, but got Unknown
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Expected O, but got Unknown
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Expected O, but got Unknown
			MethodInfo methodInfo = (from x in typeof(ConfigFile).GetMethods()
				where x.Name == "Bind"
				select x).First();
			methodInfo = methodInfo.MakeGenericMethod(typeof(T));
			object[] parameters = new object[3]
			{
				(object)new ConfigDefinition(Regex.Replace(config.ConfigFilePath, "\\W", "") + " : " + entry.Definition.Section, name),
				entry.DefaultValue,
				(object)new ConfigDescription(entry.Description.Description, (AcceptableValueBase)null, Array.Empty<object>())
			};
			ConfigEntryBase val = (ConfigEntryBase)methodInfo.Invoke(config, parameters);
			if (Main._preVersioning)
			{
				entry.BoxedValue = entry.DefaultValue;
			}
			if (!ConfigEqual(val.DefaultValue, val.BoxedValue) && VersionChanged)
			{
				entry.BoxedValue = entry.DefaultValue;
				val.BoxedValue = val.DefaultValue;
			}
			return default(T);
		}

		private static bool ConfigEqual(object a, object b)
		{
			if (a.Equals(b))
			{
				return true;
			}
			if (float.TryParse(a.ToString(), out var result) && float.TryParse(b.ToString(), out var result2) && (double)Mathf.Abs(result - result2) < 0.0001)
			{
				return true;
			}
			return false;
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("HIFU.HIFURexTweaks", "HIFURexTweaks", "1.2.8")]
	public class Main : BaseUnityPlugin
	{
		public const string PluginGUID = "HIFU.HIFURexTweaks";

		public const string PluginAuthor = "HIFU";

		public const string PluginName = "HIFURexTweaks";

		public const string PluginVersion = "1.2.8";

		public static ConfigFile HRTConfig;

		public static ConfigFile HRTBackupConfig;

		public static ManualLogSource HRTLogger;

		public static bool _preVersioning;

		public static ConfigEntry<bool> enableAutoConfig { get; set; }

		public static ConfigEntry<string> latestVersion { get; set; }

		public void Awake()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			HRTLogger = ((BaseUnityPlugin)this).Logger;
			HRTConfig = ((BaseUnityPlugin)this).Config;
			HRTBackupConfig = new ConfigFile(Paths.ConfigPath + "\\HIFU.HIFURexTweaks.Backup.cfg", true);
			HRTBackupConfig.Bind<string>(": DO NOT MODIFY THIS FILES CONTENTS :", ": DO NOT MODIFY THIS FILES CONTENTS :", ": DO NOT MODIFY THIS FILES CONTENTS :", ": DO NOT MODIFY THIS FILES CONTENTS :");
			enableAutoConfig = HRTConfig.Bind<bool>("Config", "Enable Auto Config Sync", true, "Disabling this would stop HIFURexTweaks from syncing config whenever a new version is found.");
			_preVersioning = !((Dictionary<ConfigDefinition, string>)AccessTools.DeclaredPropertyGetter(typeof(ConfigFile), "OrphanedEntries").Invoke(HRTConfig, null)).Keys.Any((ConfigDefinition x) => x.Key == "Latest Version");
			latestVersion = HRTConfig.Bind<string>("Config", "Latest Version", "1.2.8", "DO NOT CHANGE THIS");
			if (enableAutoConfig.Value && (_preVersioning || latestVersion.Value != "1.2.8"))
			{
				latestVersion.Value = "1.2.8";
				ConfigManager.VersionChanged = true;
				HRTLogger.LogInfo((object)"Config Autosync Enabled.");
			}
			IEnumerable<Type> enumerable = from type in Assembly.GetExecutingAssembly().GetTypes()
				where !type.IsAbstract && type.IsSubclassOf(typeof(TweakBase))
				select type;
			HRTLogger.LogInfo((object)"==+----------------==TWEAKS==----------------+==");
			foreach (Type item in enumerable)
			{
				TweakBase tweakBase = (TweakBase)Activator.CreateInstance(item);
				if (ValidateTweak(tweakBase))
				{
					tweakBase.Init();
				}
			}
			IEnumerable<Type> enumerable2 = from type in Assembly.GetExecutingAssembly().GetTypes()
				where !type.IsAbstract && type.IsSubclassOf(typeof(MiscBase))
				select type;
			HRTLogger.LogInfo((object)"==+----------------==MISC==----------------+==");
			foreach (Type item2 in enumerable2)
			{
				MiscBase miscBase = (MiscBase)Activator.CreateInstance(item2);
				if (ValidateMisc(miscBase))
				{
					miscBase.Init();
				}
			}
		}

		public bool ValidateTweak(TweakBase tb)
		{
			if (tb.isEnabled && ((BaseUnityPlugin)this).Config.Bind<bool>(tb.Name, "Enable?", true, "Vanilla is false").Value)
			{
				return true;
			}
			return false;
		}

		public bool ValidateMisc(MiscBase mb)
		{
			if (mb.isEnabled && ((BaseUnityPlugin)this).Config.Bind<bool>(mb.Name, "Enable?", true, "Vanilla is false").Value)
			{
				return true;
			}
			return false;
		}

		private void PeripheryMyBeloved()
		{
		}
	}
	public abstract class MiscBase
	{
		public abstract string Name { get; }

		public virtual bool isEnabled { get; } = true;


		public T ConfigOption<T>(T value, string name, string description)
		{
			ConfigEntry<T> val = Main.HRTConfig.Bind<T>(Name, name, value, description);
			ConfigManager.HandleConfig<T>((ConfigEntryBase)(object)val, Main.HRTBackupConfig, name);
			return val.Value;
		}

		public abstract void Hooks();

		public string d(float f)
		{
			return f * 100f + "%";
		}

		public virtual void Init()
		{
			Hooks();
			Main.HRTLogger.LogInfo((object)("Added " + Name));
		}
	}
	public abstract class MiscBase<T> : MiscBase where T : MiscBase<T>
	{
		public static T instance { get; set; }

		public MiscBase()
		{
			if (instance != null)
			{
				throw new InvalidOperationException("Singleton class " + typeof(T).Name + " was instantiated twice");
			}
			instance = this as T;
		}
	}
	public abstract class TweakBase
	{
		public abstract string Name { get; }

		public abstract string SkillToken { get; }

		public abstract string DescText { get; }

		public virtual bool isEnabled { get; } = true;


		public T ConfigOption<T>(T value, string name, string description)
		{
			ConfigEntry<T> val = Main.HRTConfig.Bind<T>(Name, name, value, description);
			ConfigManager.HandleConfig<T>((ConfigEntryBase)(object)val, Main.HRTBackupConfig, name);
			return val.Value;
		}

		public abstract void Hooks();

		public string d(float f)
		{
			return f * 100f + "%";
		}

		public virtual void Init()
		{
			Hooks();
			string text = "TREEBOT_" + SkillToken.ToUpper() + "_DESCRIPTION";
			LanguageAPI.Add(text, DescText);
			Main.HRTLogger.LogInfo((object)("Added " + Name));
		}
	}
	public abstract class TweakBase<T> : TweakBase where T : TweakBase<T>
	{
		public static T instance { get; set; }

		public TweakBase()
		{
			if (instance != null)
			{
				throw new InvalidOperationException("Singleton class " + typeof(T).Name + " was instantiated twice");
			}
			instance = this as T;
		}
	}
}
namespace HIFURexTweaks.Skills
{
	public class BrambleVolley : TweakBase
	{
		public static float damage;

		public static float healPercent;

		public static float healthCost;

		public static float cooldown;

		public static float procCoefficient;

		public override string Name => ": Utility :: Bramble Volley";

		public override string SkillToken => "utility_alt1";

		public override string DescText => "<style=cIsHealth>" + d(healthCost) + " HP</style>. Fire a <style=cIsUtility>Sonic Boom</style> that <style=cIsDamage>damages</style> enemies for <style=cIsDamage>" + d(damage) + " damage</style>. <style=cIsHealing>Heals " + d(healPercent) + " for every target hit</style>.";

		public override void Init()
		{
			damage = ConfigOption(5f, "Damage", "Decimal. Vanilla is 5.5");
			healPercent = ConfigOption(0.08f, "Heal Percent", "Decimal. Vanilla is 0.1");
			healthCost = ConfigOption(0.2f, "Health Cost", "Decimal. Vanilla is 0.2");
			cooldown = ConfigOption(5f, "Cooldown", "Vanilla is 5");
			procCoefficient = ConfigOption(0.5f, "Proc Coefficient", "Vanilla is 0.5");
			base.Init();
		}

		public override void Hooks()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			Changes();
			FirePlantSonicBoom.OnEnter += new hook_OnEnter(FirePlantSonicBoom_OnEnter);
		}

		private void FirePlantSonicBoom_OnEnter(orig_OnEnter orig, FirePlantSonicBoom self)
		{
			FirePlantSonicBoom.damageCoefficient = damage;
			FirePlantSonicBoom.healthFractionPerHit = healPercent;
			FirePlantSonicBoom.healthCostFraction = healthCost;
			FirePlantSonicBoom.procCoefficient = procCoefficient;
			orig.Invoke(self);
		}

		public static void Changes()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			SkillDef val = Addressables.LoadAssetAsync<SkillDef>((object)"RoR2/Base/Treebot/TreebotBodyPlantSonicBoom.asset").WaitForCompletion();
			val.baseRechargeInterval = cooldown;
		}
	}
	public class DIRECTIVEDisperse : TweakBase
	{
		public static float cooldown;

		public static int maxStock;

		public override string Name => ": Utility : Directive Disperse";

		public override string SkillToken => "utility";

		public override string DescText => "Fire a <style=cIsUtility>Sonic Boom</style> that <style=cIsDamage>Weakens</style> all enemies hit." + ((maxStock > 1) ? (" Can hold up to " + maxStock + ".") : "");

		public override void Init()
		{
			cooldown = ConfigOption(4f, "Cooldown", "Vanilla is 5");
			maxStock = ConfigOption(2, "Max Stock", "Vanilla is 1");
			base.Init();
		}

		public override void Hooks()
		{
			Changes();
		}

		public static void Changes()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			SkillDef val = Addressables.LoadAssetAsync<SkillDef>((object)"RoR2/Base/Treebot/TreebotBodySonicBoom.asset").WaitForCompletion();
			val.baseRechargeInterval = cooldown;
			val.baseMaxStock = maxStock;
		}
	}
	public class DIRECTIVEDrill : TweakBase
	{
		public static float damage;

		public static float procCoefficient;

		public static float cooldown;

		public static float duration;

		public override string Name => ": Secondary : DIRECTIVE: Drill";

		public override string SkillToken => "secondary_alt1";

		public override string DescText => "Launch a series of seed bullets into the sky, raining down for <style=cIsDamage>" + d(16f * damage / cooldown) + " damage per second</style>.";

		public override void Init()
		{
			damage = ConfigOption(1.6f, "Damage", "Decimal. Vanilla is 0.9");
			procCoefficient = ConfigOption(1f, "Proc Coefficient", "Vanilla is 0.7");
			cooldown = ConfigOption(5f, "Cooldown", "Vanilla is 6");
			duration = ConfigOption(3f, "Duration", "Vanilla is 3");
			base.Init();
		}

		public override void Hooks()
		{
			Changes();
		}

		public static void Changes()
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			ProjectileDotZone component = LegacyResourcesAPI.Load<GameObject>("prefabs/projectiles/TreebotMortarRain").GetComponent<ProjectileDotZone>();
			component.damageCoefficient = damage / 4.5f;
			component.lifetime = duration;
			component.overlapProcCoefficient = procCoefficient;
			SkillDef val = Addressables.LoadAssetAsync<SkillDef>((object)"RoR2/Base/Treebot/TreebotBodyAimMortarRain.asset").WaitForCompletion();
			val.baseRechargeInterval = cooldown;
		}
	}
	public class DIRECTIVEHarvest : TweakBase
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static StatHookEventHandler <0>__RecalculateStatsAPI_GetStatCoefficients;

			public static hook_OnTriggerStay <1>__BuffPickup_OnTriggerStay;
		}

		public static float damage;

		public static float cooldown;

		public static float endlag;

		public static float percentHeal;

		public static bool giveBuffs;

		public static float buffDuration;

		public static BuffDef checkIfEligible;

		public static BuffDef armorBuffDef;

		public static BuffDef damageBuffDef;

		public static BuffDef attackSpeedBuffDef;

		public static BuffDef movementSpeedBuffDef;

		public static float armorBuff;

		public static float damageBuff;

		public static float attackSpeedBuff;

		public static float movementSpeedBuff;

		public static BuffDef uselessBuff;

		public override string Name => ": Special : DIRECTIVE: Harvest";

		public override string SkillToken => "special_alt1";

		public override string DescText => "Fire a bolt that deals <style=cIsDamage>" + d(damage) + " damage</style> and <style=cIsDamage>injects</style> an enemy. On death, drop multiple <style=cIsHealing>healing fruits</style> that heal for <style=cIsHealing>" + d(percentHeal) + " HP</style>" + (giveBuffs ? " and <style=cIsUtility>give a short buff</style> each." : ".");

		public override void Init()
		{
			damage = ConfigOption(6f, "Damage", "Decimal. Vanilla is 3.3");
			endlag = ConfigOption(0.3f, "Endlag", "Vanilla is 1");
			cooldown = ConfigOption(6f, "Cooldown", "Vanilla is 6");
			percentHeal = ConfigOption(0.15f, "Percent Heal", "Decimal. Vanilla is 0.25");
			giveBuffs = ConfigOption(value: true, "Should fruit give Buffs?", "Vanilla is false");
			buffDuration = ConfigOption(6f, "Buff Duration", "Vanilla is 0");
			armorBuff = ConfigOption(8f, "Armor Buff", "Vanilla is 0");
			damageBuff = ConfigOption(0.08f, "Damage Buff", "Decimal. Vanilla is 0");
			attackSpeedBuff = ConfigOption(0.12f, "Attack Speed Buff", "Decimal. Vanilla, is 0");
			movementSpeedBuff = ConfigOption(0.12f, "Movement Speed Buff", "Decimal. Vanilla is 0");
			uselessBuff = ScriptableObject.CreateInstance<BuffDef>();
			uselessBuff.isHidden = true;
			uselessBuff.isDebuff = false;
			uselessBuff.canStack = false;
			uselessBuff.isCooldown = false;
			((Object)uselessBuff).name = "Useless Buff";
			ContentAddition.AddBuffDef(uselessBuff);
			base.Init();
		}

		public override void Hooks()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Expected O, but got Unknown
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			Changes();
			TreebotFireFruitSeed.OnEnter += new hook_OnEnter(TreebotFireFruitSeed_OnEnter);
			object obj = <>O.<0>__RecalculateStatsAPI_GetStatCoefficients;
			if (obj == null)
			{
				StatHookEventHandler val = RecalculateStatsAPI_GetStatCoefficients;
				<>O.<0>__RecalculateStatsAPI_GetStatCoefficients = val;
				obj = (object)val;
			}
			RecalculateStatsAPI.GetStatCoefficients += (StatHookEventHandler)obj;
			object obj2 = <>O.<1>__BuffPickup_OnTriggerStay;
			if (obj2 == null)
			{
				hook_OnTriggerStay val2 = BuffPickup_OnTriggerStay;
				<>O.<1>__BuffPickup_OnTriggerStay = val2;
				obj2 = (object)val2;
			}
			BuffPickup.OnTriggerStay += (hook_OnTriggerStay)obj2;
			GlobalEventManager.OnCharacterDeath += new Manipulator(GlobalEventManager_OnCharacterDeath);
			TreebotPrepFruitSeed.OnEnter += new hook_OnEnter(TreebotPrepFruitSeed_OnEnter);
		}

		private void TreebotPrepFruitSeed_OnEnter(orig_OnEnter orig, TreebotPrepFruitSeed self)
		{
			self.baseDuration = 1f / 60f;
			self.duration = 1f / 60f;
			orig.Invoke(self);
		}

		private void GlobalEventManager_onCharacterDeathGlobal(DamageReport report)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Invalid comparison between Unknown and I4
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)report.attacker))
			{
				return;
			}
			TeamIndex attackerTeamIndex = report.attackerTeamIndex;
			CharacterBody victimBody = report.victimBody;
			if (!Object.op_Implicit((Object)(object)victimBody) || (!victimBody.HasBuff(Buffs.Fruiting) && (report.damageInfo == null || (report.damageInfo.damageType & 0x20000000) <= 0)))
			{
				return;
			}
			int num = Mathf.Min(Math.Max(1, (int)(victimBody.bestFitRadius * 2f)), 8);
			GameObject val = LegacyResourcesAPI.Load<GameObject>("Prefabs/NetworkedObjects/TreebotFruitPack");
			for (int i = 0; i < num; i++)
			{
				GameObject val2 = Object.Instantiate<GameObject>(val, victimBody.transform.position + Random.insideUnitSphere * victimBody.radius * 0.5f, Random.rotation);
				TeamFilter component = val2.GetComponent<TeamFilter>();
				if (Object.op_Implicit((Object)(object)component))
				{
					component.teamIndex = attackerTeamIndex;
				}
				val2.GetComponentInChildren<HealthPickup>();
				val2.transform.localScale = new Vector3(1f, 1f, 1f);
				NetworkServer.Spawn(val2);
			}
		}

		private void GlobalEventManager_OnCharacterDeath(ILContext il)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			ILCursor val = new ILCursor(il);
			if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdstr(x, "Prefabs/Effects/TreebotFruitDeathEffect.prefab")
			}))
			{
				for (int i = 0; i < 11; i++)
				{
					val.Remove();
				}
			}
			else
			{
				Main.HRTLogger.LogError((object)"Failed to apply VFX Hook");
			}
			val.Index = 0;
		}

		private void TreebotFireFruitSeed_OnEnter(orig_OnEnter orig, TreebotFireFruitSeed self)
		{
			self.damageCoefficient = damage;
			self.baseDuration = endlag;
			orig.Invoke(self);
		}

		public static void BuffPickup_OnTriggerStay(orig_OnTriggerStay orig, BuffPickup self, Collider other)
		{
			if (Object.op_Implicit((Object)(object)self) && (Object)(object)self.buffDef == (Object)(object)checkIfEligible)
			{
				switch (Random.RandomRangeInt(1, 5))
				{
				case 1:
					self.buffDef = armorBuffDef;
					break;
				case 2:
					self.buffDef = damageBuffDef;
					break;
				case 3:
					self.buffDef = attackSpeedBuffDef;
					break;
				default:
					self.buffDef = movementSpeedBuffDef;
					break;
				}
			}
			orig.Invoke(self, other);
		}

		public static void RecalculateStatsAPI_GetStatCoefficients(CharacterBody sender, StatHookEventArgs args)
		{
			if (Object.op_Implicit((Object)(object)sender.inventory))
			{
				args.armorAdd += armorBuff * (float)sender.GetBuffCount(armorBuffDef);
				args.damageMultAdd += damageBuff * (float)sender.GetBuffCount(damageBuffDef);
				args.attackSpeedMultAdd += attackSpeedBuff * (float)sender.GetBuffCount(attackSpeedBuffDef);
				args.moveSpeedMultAdd += movementSpeedBuff * (float)sender.GetBuffCount(movementSpeedBuffDef);
			}
		}

		public static void Changes()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0292: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: Unknown result type (might be due to invalid IL or missing references)
			//IL_029c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0308: Unknown result type (might be due to invalid IL or missing references)
			//IL_0317: Unknown result type (might be due to invalid IL or missing references)
			//IL_033f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0344: Unknown result type (might be due to invalid IL or missing references)
			//IL_0349: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0426: Unknown result type (might be due to invalid IL or missing references)
			//IL_042b: Unknown result type (might be due to invalid IL or missing references)
			LanguageAPI.Add("TREEBOT_SPECIAL_ALT1_NAME", "DIRECTIVE: Harvest");
			SkillDef val = Addressables.LoadAssetAsync<SkillDef>((object)"RoR2/Base/Treebot/TreebotBodyFireFruitSeed.asset").WaitForCompletion();
			val.baseRechargeInterval = cooldown;
			GameObject val2 = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/Treebot/TreebotFruitPack.prefab").WaitForCompletion();
			Object.Destroy((Object)(object)val2.GetComponent<EffectComponent>());
			Transform child = val2.transform.GetChild(2);
			((Component)child).GetComponent<HealthPickup>().fractionalHealing = percentHeal;
			checkIfEligible = ScriptableObject.CreateInstance<BuffDef>();
			checkIfEligible.isDebuff = false;
			checkIfEligible.canStack = false;
			checkIfEligible.iconSprite = null;
			checkIfEligible.buffColor = Color32.op_Implicit(new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue));
			checkIfEligible.isHidden = true;
			ContentAddition.AddBuffDef(checkIfEligible);
			GameObject val3 = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/Treebot/TreebotFruitSeedProjectile.prefab").WaitForCompletion();
			val3.transform.localScale = new Vector3(2f, 2f, 2f);
			if (giveBuffs)
			{
				Texture2D val4 = Addressables.LoadAssetAsync<Texture2D>((object)"RoR2/Base/Common/texBuffGenericShield.tif").WaitForCompletion();
				Texture2D val5 = Addressables.LoadAssetAsync<Texture2D>((object)"RoR2/Base/LunarSkillReplacements/texBuffLunarDetonatorIcon.tif").WaitForCompletion();
				Texture2D val6 = Addressables.LoadAssetAsync<Texture2D>((object)"RoR2/Base/AttackSpeedOnCrit/texBuffAttackSpeedOnCritIcon.tif").WaitForCompletion();
				Texture2D val7 = Addressables.LoadAssetAsync<Texture2D>((object)"RoR2/Base/Common/texMovespeedBuffIcon.tif").WaitForCompletion();
				armorBuffDef = ScriptableObject.CreateInstance<BuffDef>();
				armorBuffDef.isDebuff = false;
				armorBuffDef.canStack = true;
				armorBuffDef.iconSprite = Sprite.Create(val4, new Rect(0f, 0f, (float)((Texture)val4).width, (float)((Texture)val4).height), new Vector2(0f, 0f));
				armorBuffDef.buffColor = Color32.op_Implicit(new Color32((byte)243, (byte)243, (byte)184, (byte)225));
				((Object)armorBuffDef).name = "DIRECTIVE: Harvest Armor";
				armorBuffDef.canStack = true;
				ContentAddition.AddBuffDef(armorBuffDef);
				damageBuffDef = ScriptableObject.CreateInstance<BuffDef>();
				damageBuffDef.isDebuff = false;
				damageBuffDef.canStack = true;
				damageBuffDef.iconSprite = Sprite.Create(val5, new Rect(0f, 0f, (float)((Texture)val5).width, (float)((Texture)val5).height), new Vector2(0f, 0f));
				damageBuffDef.buffColor = Color32.op_Implicit(new Color32((byte)243, (byte)243, (byte)184, (byte)225));
				((Object)damageBuffDef).name = "DIRECTIVE: Harvest Damage";
				damageBuffDef.canStack = true;
				ContentAddition.AddBuffDef(damageBuffDef);
				attackSpeedBuffDef = ScriptableObject.CreateInstance<BuffDef>();
				attackSpeedBuffDef.isDebuff = false;
				attackSpeedBuffDef.canStack = true;
				attackSpeedBuffDef.iconSprite = Sprite.Create(val6, new Rect(0f, 0f, (float)((Texture)val6).width, (float)((Texture)val6).height), new Vector2(0f, 0f));
				attackSpeedBuffDef.buffColor = Color32.op_Implicit(new Color32((byte)243, (byte)243, (byte)184, (byte)225));
				((Object)attackSpeedBuffDef).name = "DIRECTIVE: Harvest Attack Speed";
				attackSpeedBuffDef.canStack = true;
				ContentAddition.AddBuffDef(attackSpeedBuffDef);
				movementSpeedBuffDef = ScriptableObject.CreateInstance<BuffDef>();
				movementSpeedBuffDef.isDebuff = false;
				movementSpeedBuffDef.canStack = true;
				movementSpeedBuffDef.iconSprite = Sprite.Create(val7, new Rect(0f, 0f, (float)((Texture)val7).width, (float)((Texture)val7).height), new Vector2(0f, 0f));
				movementSpeedBuffDef.buffColor = Color32.op_Implicit(new Color32((byte)243, (byte)243, (byte)184, (byte)225));
				((Object)movementSpeedBuffDef).name = "DIRECTIVE: Harvest Move Speed";
				movementSpeedBuffDef.canStack = true;
				ContentAddition.AddBuffDef(movementSpeedBuffDef);
				GameObject val8 = PrefabAPI.InstantiateClone(Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/Common/VFX/HealthOrbEffect.prefab").WaitForCompletion(), "DIRECTIVE: Harvest Pickup", false);
				val8.SetActive(false);
				ContentAddition.AddEffect(val8);
				BuffPickup val9 = ((Component)child).gameObject.AddComponent<BuffPickup>();
				val9.teamFilter = val2.GetComponent<TeamFilter>();
				val9.buffDef = checkIfEligible;
				val9.buffDuration = buffDuration;
				val9.pickupEffect = val8;
				val9.baseObject = ((Component)child).gameObject;
			}
		}
	}
	public class DIRECTIVEInject : TweakBase
	{
		public static float damage;

		public static float procCoefficient;

		public static int syringes;

		public static float durationPer;

		public static float healPercent;

		public override string Name => ": Primary : DIRECTIVE: Inject";

		public override string SkillToken => "primary";

		public override string DescText => "Fire " + syringes + " syringes for <style=cIsDamage>" + syringes + "x" + d(damage) + " damage</style>. The last syringe <style=cIsDamage>Weakens</style> and <style=cIsHealing>heals for " + d(healPercent) + " of damage dealt</style>.";

		public override void Init()
		{
			damage = ConfigOption(0.8f, "Damage", "Decimal. Vanilla is 0.8");
			syringes = ConfigOption(3, "Syringe Count", "Vanilla is 3");
			durationPer = ConfigOption(0.2f, "Duration Per Syringe", "Vanilla is 0.2");
			healPercent = ConfigOption(0.45f, "Healing Percentage", "Decimal. Vanilla is 0.6");
			procCoefficient = ConfigOption(0.5f, "Proc Coefficient", "Vanilla is 0.5");
			base.Init();
		}

		public override void Hooks()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			Changes();
			FireSyringe.OnEnter += new hook_OnEnter(FireSyringe_OnEnter);
		}

		private void FireSyringe_OnEnter(orig_OnEnter orig, FireSyringe self)
		{
			FireSyringe.damageCoefficient = damage;
			FireSyringe.projectileCount = syringes;
			FireSyringe.baseFireDuration = durationPer;
			FireSyringe.baseDuration = (float)syringes * durationPer;
			orig.Invoke(self);
		}

		public static void Changes()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/Treebot/SyringeProjectile.prefab").WaitForCompletion();
			ProjectileController component = val.GetComponent<ProjectileController>();
			component.procCoefficient = procCoefficient;
			ProjectileTargetComponent val2 = val.AddComponent<ProjectileTargetComponent>();
			((Behaviour)val2).enabled = true;
			ProjectileSteerTowardTarget val3 = val.AddComponent<ProjectileSteerTowardTarget>();
			((Behaviour)val3).enabled = true;
			val3.rotationSpeed = 1080f;
			ProjectileDirectionalTargetFinder val4 = val.AddComponent<ProjectileDirectionalTargetFinder>();
			((Behaviour)val4).enabled = true;
			val4.lookRange = 20f;
			val4.lookCone = 10f;
			val4.targetSearchInterval = 0.1f;
			val4.onlySearchIfNoTarget = true;
			val4.allowTargetLoss = false;
			val4.testLoS = false;
			val4.ignoreAir = false;
			val4.flierAltitudeTolerance = float.PositiveInfinity;
			GameObject val5 = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/Treebot/SyringeProjectileHealing.prefab").WaitForCompletion();
			val5.GetComponent<ProjectileHealOwnerOnDamageInflicted>().fractionOfDamage = healPercent;
			ProjectileController component2 = val5.GetComponent<ProjectileController>();
			component2.procCoefficient = procCoefficient;
			ProjectileTargetComponent val6 = val5.AddComponent<ProjectileTargetComponent>();
			((Behaviour)val6).enabled = true;
			ProjectileSteerTowardTarget val7 = val5.AddComponent<ProjectileSteerTowardTarget>();
			((Behaviour)val7).enabled = true;
			val7.rotationSpeed = 1080f;
			ProjectileDirectionalTargetFinder val8 = val5.AddComponent<ProjectileDirectionalTargetFinder>();
			((Behaviour)val8).enabled = true;
			val8.lookRange = 20f;
			val8.lookCone = 10f;
			val8.targetSearchInterval = 0.1f;
			val8.onlySearchIfNoTarget = true;
			val8.allowTargetLoss = false;
			val8.testLoS = false;
			val8.ignoreAir = false;
			val8.flierAltitudeTolerance = float.PositiveInfinity;
		}
	}
	public class SeedBarrage : TweakBase
	{
		public static float damage;

		public static float cooldown;

		public static float healthCost;

		public override string Name => ": Secondary :: Seed Barrage";

		public override string SkillToken => "secondary";

		public override string DescText => "<style=cIsHealth>" + d(healthCost) + " HP</style>. Launch a mortar into the sky for <style=cIsDamage>" + d(damage) + " damage</style>.";

		public override void Init()
		{
			damage = ConfigOption(3.7f, "Damage", "Decimal. Vanilla is 4.5");
			cooldown = ConfigOption(0.5f, "Cooldown", "Vanilla is 0.5");
			healthCost = ConfigOption(0.15f, "Health Cost", "Decimal. Vanilla is 0.15");
			base.Init();
		}

		public override void Hooks()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			Changes();
			FireMortar2.OnEnter += new hook_OnEnter(FireMortar2_OnEnter);
		}

		private void FireMortar2_OnEnter(orig_OnEnter orig, FireMortar2 self)
		{
			FireMortar2.damageCoefficient = damage;
			FireMortar2.healthCostFraction = healthCost;
			orig.Invoke(self);
		}

		public static void Changes()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			SkillDef val = Addressables.LoadAssetAsync<SkillDef>((object)"RoR2/Base/Treebot/TreebotBodyAimMortar2.asset").WaitForCompletion();
			val.baseRechargeInterval = cooldown;
		}
	}
	public class TanglingGrowth : TweakBase
	{
		public static float rootDamage;

		public static float healPercent;

		public static int pulseCount;

		public static float healthCost;

		public static float cooldown;

		public static float radius;

		public override string Name => ": Special :: Tangling Growth";

		public override string SkillToken => "special";

		public override string DescText => "<style=cIsHealth>" + d(healthCost) + " HP</style>. Fire a flower that <style=cIsDamage>roots</style> for <style=cIsDamage>" + d(rootDamage) + " damage</style>. <style=cIsHealing>Heals " + d(healPercent / (float)(pulseCount - 1) * 0.25f) + " HP for every target hit</style>, up to <style=cIsHealing>" + (pulseCount - 1) * 4 + "</style> times.";

		public override void Init()
		{
			rootDamage = ConfigOption(2f, "Root Damage", "Decimal. Vanilla is 2");
			healPercent = ConfigOption(0.08f, "Heal Percent", "Decimal. Formula for Healing Per Pulse: (Heal Percent / (Pulse Count - 1)) * 0.25. Vanilla is 0.08");
			pulseCount = ConfigOption(5, "Pulse Count", "Vanilla is 5");
			healthCost = ConfigOption(0.25f, "Health Cost", "Decimal. Vanilla is 0.25");
			cooldown = ConfigOption(12f, "Cooldown", "Vanilla is 12");
			radius = ConfigOption(10f, "Radius", "Vanilla is 10");
			base.Init();
		}

		public override void Hooks()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			Changes();
			FireFlower2.OnEnter += new hook_OnEnter(FireFlower2_OnEnter);
			FlowerProjectileHover.OnEnter += new hook_OnEnter(FlowerProjectileHover_OnEnter);
		}

		private void FlowerProjectileHover_OnEnter(orig_OnEnter orig, FlowerProjectileHover self)
		{
			((DroneProjectileHover)self).pulseCount = pulseCount;
			((DroneProjectileHover)self).pulseRadius = radius;
			FlowerProjectileHover.healthFractionYieldPerHit = healPercent;
			orig.Invoke(self);
		}

		private void FireFlower2_OnEnter(orig_OnEnter orig, FireFlower2 self)
		{
			FireFlower2.damageCoefficient = rootDamage;
			FireFlower2.healthCostFraction = healthCost;
			orig.Invoke(self);
		}

		public static void Changes()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			SkillDef val = Addressables.LoadAssetAsync<SkillDef>((object)"RoR2/Base/Treebot/TreebotBodyFireFlower2.asset").WaitForCompletion();
			val.baseRechargeInterval = cooldown;
		}
	}
}
namespace HIFURexTweaks.Misc
{
	internal class HurtBox : MiscBase
	{
		public static float SizeMultiplier;

		public override string Name => ": Misc : Hurt Box";

		public override void Init()
		{
			SizeMultiplier = ConfigOption(0.66f, "Size Multiplier", "Vanilla is 1");
			base.Init();
		}

		public override void Hooks()
		{
			Changes();
		}

		private void Changes()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/Treebot/TreebotBody.prefab").WaitForCompletion();
			CapsuleCollider component = ((Component)val.transform.GetChild(0).GetChild(0).GetChild(0)
				.GetChild(0)
				.Find("TempHurtbox")).GetComponent<CapsuleCollider>();
			component.radius = 1.42f * SizeMultiplier;
			component.height = 4.26f * SizeMultiplier;
		}
	}
	internal class WallClimbing : MiscBase
	{
		public override string Name => ": Misc : Wall Climbing";

		public override void Init()
		{
			base.Init();
		}

		public override void Hooks()
		{
			CharacterBody.onBodyStartGlobal += CharacterBody_onBodyStartGlobal;
		}

		private void CharacterBody_onBodyStartGlobal(CharacterBody body)
		{
			if (((Object)body).name == "TreebotBody(Clone)")
			{
				KinematicCharacterMotor component = ((Component)body).GetComponent<KinematicCharacterMotor>();
				component.MaxStableSlopeAngle = 180f;
				component.MaxStepHeight = 2f;
				component.MinRequiredStepDepth = 0f;
				component.PreventSnappingOnLedges = true;
				component.MaxStableDenivelationAngle = 180f;
			}
		}
	}
}