Decompiled source of Dronemeld v1.3.2

Dronemeld.dll

Decompiled 3 months ago
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
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 EntityStates;
using EntityStates.Drone;
using IL.RoR2;
using Mono.Cecil;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using On.EntityStates.Drone;
using On.RoR2;
using On.RoR2.Projectile;
using On.RoR2.Skills;
using R2API;
using R2API.Networking;
using R2API.Networking.Interfaces;
using R2API.Utils;
using RoR2;
using RoR2.Projectile;
using RoR2.Skills;
using TILER2;
using UnityEngine;
using UnityEngine.Networking;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("Dronemeld")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Dronemeld")]
[assembly: AssemblyTitle("Dronemeld")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace ThinkInvisible.Dronemeld;

[BepInPlugin("com.ThinkInvisible.Dronemeld", "Dronemeld", "1.3.2")]
[BepInDependency("com.bepis.r2api", "5.1.1")]
[BepInDependency("com.ThinkInvisible.TILER2", "7.4.2")]
[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
public class DronemeldPlugin : BaseUnityPlugin
{
	public enum DronemeldPriorityOrder
	{
		RoundRobin,
		Random,
		FirstOnly
	}

	public class ServerConfig : AutoConfigContainer
	{
		[AutoConfig(/*Could not decode attribute arguments.*/)]
		[AutoConfigRoOCheckbox(null, null)]
		public bool perPlayer { get; internal set; } = true;


		[AutoConfig(/*Could not decode attribute arguments.*/)]
		[AutoConfigRoOIntSlider("{0:N0}", 1, 10, null, null)]
		public int maxDronesPerType { get; internal set; } = 1;


		[AutoConfig(/*Could not decode attribute arguments.*/)]
		[AutoConfigRoOChoice(null, null)]
		public DronemeldPriorityOrder priorityOrder { get; internal set; }

		[AutoConfig(/*Could not decode attribute arguments.*/)]
		[AutoConfigRoOSlider("+{0:N2}x", 0f, 2f, null, null)]
		public float statMultHealth { get; internal set; } = 1f;


		[AutoConfig(/*Could not decode attribute arguments.*/)]
		[AutoConfigRoOSlider("+{0:N2}x", 0f, 2f, null, null)]
		public float statMultDamage { get; internal set; } = 0.6f;


		[AutoConfig(/*Could not decode attribute arguments.*/)]
		[AutoConfigRoOSlider("+{0:N2}x", 0f, 2f, null, null)]
		public float statMultAttackSpeed { get; internal set; } = 0.6f;


		[AutoConfig(/*Could not decode attribute arguments.*/)]
		[AutoConfigRoOSlider("+{0:N2}x", 0f, 2f, null, null)]
		public float statMultCDR { get; internal set; } = 0.6f;


		[AutoConfig(/*Could not decode attribute arguments.*/)]
		[AutoConfigRoOCheckbox(null, null)]
		public bool quantumTurrets { get; internal set; } = true;


		[AutoConfig(/*Could not decode attribute arguments.*/)]
		[AutoConfigRoOString(null, null)]
		public string masterWhitelist { get; internal set; } = "Drone1Master, Drone2Master, DroneMissileMaster, FlameDroneMaster, MegaDroneMaster, Turret1Master, DroneBackupMaster, BeetleGuardAllyMaster, VoidMegaCrabAllyMaster, VoidJailerAllyMaster, NullifierAllyMaster, MinorConstructOnKillMaster, SquidTurretMaster";


		[AutoConfig(/*Could not decode attribute arguments.*/)]
		[AutoConfigRoOCheckbox(null, null)]
		public bool applyToGoobo { get; internal set; } = true;


		[AutoConfig(/*Could not decode attribute arguments.*/)]
		[AutoConfigRoOString(null, null)]
		public string quantumWhitelist { get; internal set; } = "Turret1Master, MinorConstructOnKillMaster, SquidTurretMaster";

	}

	public class ClientConfig : AutoConfigContainer
	{
		[AutoConfig(/*Could not decode attribute arguments.*/)]
		[AutoConfigRoOSlider("{0:P0}", 0f, 1f, null, null)]
		public float vfxResize { get; internal set; } = 0.25f;

	}

	public struct MsgAddDroneSize : INetMessage, ISerializableObject
	{
		private GameObject _target;

		public MsgAddDroneSize(GameObject target)
		{
			_target = target;
		}

		public void Serialize(NetworkWriter writer)
		{
			writer.Write(_target);
		}

		public void Deserialize(NetworkReader reader)
		{
			_target = reader.ReadGameObject();
		}

		public void OnReceived()
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)_target) && clientConfig.vfxResize != 0f)
			{
				CharacterBody component = _target.GetComponent<CharacterBody>();
				if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component.modelLocator))
				{
					Transform modelTransform = component.modelLocator.modelTransform;
					modelTransform.localScale += Vector3.one * clientConfig.vfxResize;
				}
			}
		}
	}

	public struct MsgRemoveDroneSize : INetMessage, ISerializableObject
	{
		private GameObject _target;

		public MsgRemoveDroneSize(GameObject target)
		{
			_target = target;
		}

		public void Serialize(NetworkWriter writer)
		{
			writer.Write(_target);
		}

		public void Deserialize(NetworkReader reader)
		{
			_target = reader.ReadGameObject();
		}

		public void OnReceived()
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)_target) && clientConfig.vfxResize != 0f)
			{
				CharacterBody component = _target.GetComponent<CharacterBody>();
				if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component.modelLocator))
				{
					Transform modelTransform = component.modelLocator.modelTransform;
					modelTransform.localScale -= Vector3.one * clientConfig.vfxResize;
				}
			}
		}
	}

	[RequireComponent(typeof(CharacterMaster))]
	public class DronemeldQuantumTurret : MonoBehaviour
	{
		private readonly List<Vector3> storedStates = new List<Vector3>();

		private CharacterMaster master;

		private const float EPSILON = 5f;

		public void RegisterLocation(Vector3 pos)
		{
			//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_0033: Unknown result type (might be due to invalid IL or missing references)
			GameObject bodyObject = master.GetBodyObject();
			if (Object.op_Implicit((Object)(object)bodyObject) && !(Vector3.Distance(bodyObject.transform.position, pos) < 5f))
			{
				storedStates.Add(pos);
			}
		}

		private void Awake()
		{
			master = ((Component)this).GetComponent<CharacterMaster>();
			Stage.onServerStageComplete += Stage_onServerStageComplete;
		}

		private void Stage_onServerStageComplete(Stage obj)
		{
			storedStates.Clear();
		}

		private void FixedUpdate()
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: 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)
			//IL_00af: 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)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkServer.active || storedStates.Count < 1)
			{
				return;
			}
			CharacterMaster ownerMaster = master.minionOwnership.ownerMaster;
			if (!Object.op_Implicit((Object)(object)ownerMaster))
			{
				return;
			}
			GameObject ownerObj = ownerMaster.GetBodyObject();
			if (!Object.op_Implicit((Object)(object)ownerObj))
			{
				return;
			}
			GameObject bodyObject = master.GetBodyObject();
			if (Object.op_Implicit((Object)(object)bodyObject))
			{
				float num = Vector3.Distance(ownerObj.transform.position, bodyObject.transform.position);
				Vector3 val = storedStates.OrderBy((Vector3 state) => Vector3.Distance(ownerObj.transform.position, state)).First();
				if (Vector3.Distance(ownerObj.transform.position, val) < num)
				{
					storedStates.Remove(val);
					storedStates.Add(bodyObject.transform.position);
					TeleportHelper.TeleportGameObject(bodyObject, val);
				}
			}
		}
	}

	[RequireComponent(typeof(CharacterMaster))]
	public class TimedDronemeldStack : MonoBehaviour
	{
		private float stopwatch;

		private bool started;

		private CharacterMaster boundCM;

		public void Activate(float time)
		{
			if (!started)
			{
				boundCM.inventory.GiveItem(stackItem, 1);
				CharacterBody body = boundCM.GetBody();
				if (Object.op_Implicit((Object)(object)body))
				{
					NetMessageExtensions.Send((INetMessage)(object)new MsgAddDroneSize(((Component)body).gameObject), (NetworkDestination)1);
				}
				stopwatch = time;
				started = true;
			}
		}

		private void Awake()
		{
			boundCM = ((Component)this).GetComponent<CharacterMaster>();
		}

		private void FixedUpdate()
		{
			if (!started)
			{
				return;
			}
			stopwatch -= Time.fixedDeltaTime;
			if (stopwatch <= 0f)
			{
				boundCM.inventory.RemoveItem(stackItem, 1);
				CharacterBody body = boundCM.GetBody();
				if (Object.op_Implicit((Object)(object)body))
				{
					NetMessageExtensions.Send((INetMessage)(object)new MsgRemoveDroneSize(((Component)body).gameObject), (NetworkDestination)1);
				}
				Object.Destroy((Object)(object)this);
			}
		}
	}

	public const string ModVer = "1.3.2";

	public const string ModName = "Dronemeld";

	public const string ModGuid = "com.ThinkInvisible.Dronemeld";

	private static ConfigFile cfgFile;

	internal static ManualLogSource _logger;

	public static ServerConfig serverConfig = new ServerConfig();

	public static ClientConfig clientConfig = new ClientConfig();

	private static readonly HashSet<string> _masterWhitelist = new HashSet<string>();

	private static Xoroshiro128Plus rng;

	public static ItemDef stackItem;

	private void Awake()
	{
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Expected O, but got Unknown
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_0111: Unknown result type (might be due to invalid IL or missing references)
		//IL_011b: Expected O, but got Unknown
		//IL_0122: Unknown result type (might be due to invalid IL or missing references)
		//IL_012c: Expected O, but got Unknown
		//IL_0133: Unknown result type (might be due to invalid IL or missing references)
		//IL_013d: Expected O, but got Unknown
		//IL_0144: Unknown result type (might be due to invalid IL or missing references)
		//IL_014e: Expected O, but got Unknown
		//IL_0155: Unknown result type (might be due to invalid IL or missing references)
		//IL_015f: Expected O, but got Unknown
		//IL_0166: Unknown result type (might be due to invalid IL or missing references)
		//IL_0170: Expected O, but got Unknown
		//IL_0177: Unknown result type (might be due to invalid IL or missing references)
		//IL_0181: Expected O, but got Unknown
		//IL_0188: Unknown result type (might be due to invalid IL or missing references)
		//IL_0192: Expected O, but got Unknown
		//IL_0199: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a3: Expected O, but got Unknown
		//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b4: Expected O, but got Unknown
		//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c5: Expected O, but got Unknown
		_logger = ((BaseUnityPlugin)this).Logger;
		cfgFile = new ConfigFile(Path.Combine(Paths.ConfigPath, "com.ThinkInvisible.Dronemeld.cfg"), true);
		((AutoConfigContainer)serverConfig).ConfigEntryChanged += delegate(object sender, AutoConfigUpdateActionEventArgs args)
		{
			if (args.target.boundProperty.Name == "masterWhitelist")
			{
				UpdateMasterWhitelist();
			}
		};
		((AutoConfigContainer)serverConfig).BindAll(cfgFile, "Dronemeld", "Server");
		((AutoConfigContainer)clientConfig).BindAll(cfgFile, "Dronemeld", "Client");
		UpdateMasterWhitelist();
		stackItem = ScriptableObject.CreateInstance<ItemDef>();
		stackItem.deprecatedTier = (ItemTier)5;
		stackItem.canRemove = false;
		stackItem.hidden = true;
		stackItem.nameToken = "ITEM_DRONEMELD_STACK_NAME";
		stackItem.loreToken = "";
		stackItem.descriptionToken = "";
		stackItem.pickupToken = "";
		((Object)stackItem).name = "DronemeldInternalStackItem";
		stackItem.tags = (ItemTag[])(object)new ItemTag[0];
		ContentAddition.AddItemDef(stackItem);
		NetworkingAPI.RegisterMessageType<MsgAddDroneSize>();
		Run.Start += new hook_Start(Run_Start);
		SkillDef.OnFixedUpdate += new hook_OnFixedUpdate(SkillDef_OnFixedUpdate);
		RecalculateStatsAPI.GetStatCoefficients += new StatHookEventHandler(RecalculateStatsAPI_GetStatCoefficients);
		CharacterBody.GetDisplayName += new hook_GetDisplayName(CharacterBody_GetDisplayName);
		CharacterMaster.OnBodyStart += new hook_OnBodyStart(CharacterMaster_OnBodyStart);
		DeathState.OnImpactServer += new hook_OnImpactServer(DeathState_OnImpactServer);
		MasterSummon.Perform += new hook_Perform(MasterSummon_Perform);
		GummyCloneProjectile.SpawnGummyClone += new hook_SpawnGummyClone(GummyCloneProjectile_SpawnGummyClone);
		DirectorCore.TrySpawnObject += new hook_TrySpawnObject(DirectorCore_TrySpawnObject);
		CharacterMaster.GetDeployableCount += new Manipulator(CharacterMaster_GetDeployableCount);
		CharacterBody.RecalculateStats += new Manipulator(CharacterBody_RecalculateStats);
	}

	private void UpdateMasterWhitelist()
	{
		_masterWhitelist.Clear();
		_masterWhitelist.UnionWith(from x in serverConfig.masterWhitelist.Split(',')
			select x.Trim());
	}

	public static bool IsDronemeldEnabledFor(string masterPrefabName)
	{
		return _masterWhitelist.Contains(masterPrefabName);
	}

	public static CharacterMaster TryApply(CharacterMaster ownerMaster, string targetPrefabName)
	{
		if (!IsDronemeldEnabledFor(targetPrefabName))
		{
			return null;
		}
		return TryApply(CharacterMaster.readOnlyInstancesList.Where((CharacterMaster m) => (serverConfig.perPlayer ? ((Object)(object)m.minionOwnership.ownerMaster == (Object)(object)ownerMaster) : (m.teamIndex == ownerMaster.teamIndex)) && ((Object)((Component)m).gameObject).name.Replace("(Clone)", "") == targetPrefabName));
	}

	public static CharacterMaster TryApply(IEnumerable<CharacterMaster> targetMasters)
	{
		if (targetMasters.Count() >= serverConfig.maxDronesPerType)
		{
			CharacterMaster val = (CharacterMaster)(serverConfig.priorityOrder switch
			{
				DronemeldPriorityOrder.Random => rng.NextElementUniform<CharacterMaster>(targetMasters.ToArray()), 
				DronemeldPriorityOrder.FirstOnly => targetMasters.First(), 
				DronemeldPriorityOrder.RoundRobin => targetMasters.OrderBy((CharacterMaster d) => d.inventory.GetItemCount(stackItem)).First(), 
				_ => throw new InvalidOperationException("Encountered invalid value of serverConfig.priorityOrder."), 
			});
			MasterSuicideOnTimer val2 = default(MasterSuicideOnTimer);
			if (((Component)val).TryGetComponent<MasterSuicideOnTimer>(ref val2))
			{
				((Component)val).gameObject.AddComponent<TimedDronemeldStack>().Activate(val2.lifeTimer - val2.timer);
				val2.timer = 0f;
			}
			else
			{
				val.inventory.GiveItem(stackItem, 1);
				CharacterBody body = val.GetBody();
				if (Object.op_Implicit((Object)(object)body))
				{
					NetMessageExtensions.Send((INetMessage)(object)new MsgAddDroneSize(((Component)body).gameObject), (NetworkDestination)1);
				}
			}
			return val;
		}
		return null;
	}

	private void Run_Start(orig_Start orig, Run self)
	{
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Expected O, but got Unknown
		orig.Invoke(self);
		if (NetworkServer.active)
		{
			rng = new Xoroshiro128Plus(self.seed);
		}
	}

	private CharacterMaster MasterSummon_Perform(orig_Perform orig, MasterSummon self)
	{
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		CharacterBody val = default(CharacterBody);
		if (Object.op_Implicit((Object)(object)self.masterPrefab) && Object.op_Implicit((Object)(object)self.summonerBodyObject) && self.summonerBodyObject.TryGetComponent<CharacterBody>(ref val) && Object.op_Implicit((Object)(object)val.master))
		{
			CharacterMaster val2 = TryApply(val.master, ((Object)self.masterPrefab).name);
			if (Object.op_Implicit((Object)(object)val2))
			{
				if (serverConfig.quantumWhitelist.Contains(((Object)((Component)val2).gameObject).name.Replace("(Clone)", "")))
				{
					DronemeldQuantumTurret dronemeldQuantumTurret = ((Component)val2).gameObject.AddComponent<DronemeldQuantumTurret>();
					if (!Object.op_Implicit((Object)(object)dronemeldQuantumTurret))
					{
						((Component)val2).gameObject.AddComponent<DronemeldQuantumTurret>();
					}
					else
					{
						dronemeldQuantumTurret.RegisterLocation(self.position);
					}
				}
				return null;
			}
		}
		return orig.Invoke(self);
	}

	private GameObject DirectorCore_TrySpawnObject(orig_TrySpawnObject orig, DirectorCore self, DirectorSpawnRequest directorSpawnRequest)
	{
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		CharacterBody val = default(CharacterBody);
		if (Object.op_Implicit((Object)(object)directorSpawnRequest.summonerBodyObject) && directorSpawnRequest.summonerBodyObject.TryGetComponent<CharacterBody>(ref val) && Object.op_Implicit((Object)(object)val.master))
		{
			CharacterMaster val2 = TryApply(val.master, ((Object)directorSpawnRequest.spawnCard.prefab).name);
			if (Object.op_Implicit((Object)(object)val2))
			{
				if (serverConfig.quantumWhitelist.Contains(((Object)((Component)val2).gameObject).name.Replace("(Clone)", "")))
				{
					DronemeldQuantumTurret dronemeldQuantumTurret = ((Component)val2).gameObject.AddComponent<DronemeldQuantumTurret>();
					if (!Object.op_Implicit((Object)(object)dronemeldQuantumTurret))
					{
						((Component)val2).gameObject.AddComponent<DronemeldQuantumTurret>();
					}
					else
					{
						GameObject val3 = orig.Invoke(self, directorSpawnRequest);
						if (Object.op_Implicit((Object)(object)val3))
						{
							dronemeldQuantumTurret.RegisterLocation(val3.transform.position);
							val3.GetComponent<CharacterMaster>().TrueKill();
							val2.inventory.RemoveItem(stackItem, 1);
						}
					}
				}
				return null;
			}
		}
		return orig.Invoke(self, directorSpawnRequest);
	}

	private void CharacterMaster_GetDeployableCount(ILContext il)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Expected O, but got Unknown
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		ILCursor val = new ILCursor(il);
		if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[1]
		{
			(Instruction i) => ILPatternMatchingExt.MatchLdfld<DeployableInfo>(i, "slot")
		}))
		{
			DeployableInfo capturedDI = default(DeployableInfo);
			val.EmitDelegate<Func<DeployableInfo, DeployableInfo>>((Func<DeployableInfo, DeployableInfo>)delegate(DeployableInfo di)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//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)
				capturedDI = di;
				return di;
			});
			if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[4]
			{
				(Instruction i) => ILPatternMatchingExt.MatchLdloc(i, 0),
				(Instruction i) => ILPatternMatchingExt.MatchLdcI4(i, 1),
				(Instruction i) => ILPatternMatchingExt.MatchAdd(i),
				(Instruction i) => ILPatternMatchingExt.MatchStloc(i, 0)
			}))
			{
				int index = val.Index;
				val.Index = index - 1;
				Inventory val2 = default(Inventory);
				val.EmitDelegate<Func<int, int>>((Func<int, int>)((int addend) => (Object.op_Implicit((Object)(object)capturedDI.deployable) && ((Component)capturedDI.deployable).TryGetComponent<Inventory>(ref val2)) ? (val2.GetItemCount(stackItem) + addend) : addend));
			}
			else
			{
				_logger.LogError((object)"Failed to apply IL patch: CharacterMaster_GetDeployableCount, part 2. Dronemeld will fail to work or have unexpected results on certain spawn methods.");
			}
		}
		else
		{
			_logger.LogError((object)"Failed to apply IL patch: CharacterMaster_GetDeployableCount, part 1. Dronemeld will fail to work or have unexpected results on certain spawn methods.");
		}
	}

	private void CharacterBody_RecalculateStats(ILContext il)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Expected O, but got Unknown
		ILCursor val = new ILCursor(il);
		MethodReference val3 = default(MethodReference);
		if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[2]
		{
			(Instruction i) => ILPatternMatchingExt.MatchCallOrCallvirt<TeamComponent>(i, "GetTeamMembers"),
			(Instruction i) => ILPatternMatchingExt.MatchCallOrCallvirt(i, ref val3)
		}))
		{
			int index = val.Index;
			val.Index = index - 1;
			val.Remove();
			CharacterBody val2 = default(CharacterBody);
			val.EmitDelegate<Func<ReadOnlyCollection<TeamComponent>, int>>((Func<ReadOnlyCollection<TeamComponent>, int>)((ReadOnlyCollection<TeamComponent> members) => members.Sum((TeamComponent m) => (!((Component)m).TryGetComponent<CharacterBody>(ref val2) || !Object.op_Implicit((Object)(object)val2.inventory)) ? 1 : (1 + val2.inventory.GetItemCount(stackItem)))));
		}
		else
		{
			_logger.LogError((object)"Failed to apply IL patch: CharacterBody_RecalculateStats. Empathy Cores will not count Dronemeld stacks for their per-ally stat boost.");
		}
	}

	private void GummyCloneProjectile_SpawnGummyClone(orig_SpawnGummyClone orig, GummyCloneProjectile self)
	{
		ProjectileController val = default(ProjectileController);
		CharacterBody ob = default(CharacterBody);
		if (!serverConfig.applyToGoobo || !((Component)self).TryGetComponent<ProjectileController>(ref val) || !Object.op_Implicit((Object)(object)val.owner) || !val.owner.TryGetComponent<CharacterBody>(ref ob) || !Object.op_Implicit((Object)(object)ob.master) || !Object.op_Implicit((Object)(object)TryApply(CharacterMaster.readOnlyInstancesList.Where((CharacterMaster m) => (serverConfig.perPlayer ? ((Object)(object)m.minionOwnership.ownerMaster == (Object)(object)ob.master) : (m.teamIndex == ob.master.teamIndex)) && m.inventory.GetItemCount(Items.GummyCloneIdentifier) > 0))))
		{
			orig.Invoke(self);
		}
	}

	private void CharacterMaster_OnBodyStart(orig_OnBodyStart orig, CharacterMaster self, CharacterBody body)
	{
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		orig.Invoke(self, body);
		if (Object.op_Implicit((Object)(object)self.inventory) && Object.op_Implicit((Object)(object)body.modelLocator) && Object.op_Implicit((Object)(object)body.modelLocator.modelTransform))
		{
			int itemCount = self.inventory.GetItemCount(stackItem);
			if (NetworkClient.active && Object.op_Implicit((Object)(object)body.modelLocator) && clientConfig.vfxResize > 0f && itemCount > 0)
			{
				Transform modelTransform = body.modelLocator.modelTransform;
				modelTransform.localScale += Vector3.one * clientConfig.vfxResize * (float)itemCount;
			}
		}
	}

	private void RecalculateStatsAPI_GetStatCoefficients(CharacterBody sender, StatHookEventArgs args)
	{
		if (Object.op_Implicit((Object)(object)sender) && Object.op_Implicit((Object)(object)sender.master))
		{
			int itemCount = sender.master.inventory.GetItemCount(stackItem);
			if (itemCount > 0)
			{
				args.baseHealthAdd += (sender.baseMaxHealth + sender.levelMaxHealth * sender.level) * (float)itemCount * serverConfig.statMultHealth;
				args.baseDamageAdd += (sender.baseDamage + sender.levelDamage * sender.level) * (float)itemCount * serverConfig.statMultDamage;
				args.baseAttackSpeedAdd += (sender.baseAttackSpeed + sender.levelAttackSpeed * sender.level) * (float)itemCount * serverConfig.statMultAttackSpeed;
			}
		}
	}

	private void SkillDef_OnFixedUpdate(orig_OnFixedUpdate orig, SkillDef self, GenericSkill skillSlot, float deltaTime)
	{
		if (Object.op_Implicit((Object)(object)skillSlot) && Object.op_Implicit((Object)(object)skillSlot.characterBody) && Object.op_Implicit((Object)(object)skillSlot.characterBody.master))
		{
			int itemCount = skillSlot.characterBody.master.inventory.GetItemCount(stackItem);
			if (itemCount > 0)
			{
				skillSlot.RunRecharge(deltaTime * (float)itemCount * serverConfig.statMultCDR);
			}
		}
		orig.Invoke(self, skillSlot, deltaTime);
	}

	private void DeathState_OnImpactServer(orig_OnImpactServer orig, DeathState self, Vector3 contactPoint)
	{
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		int num = 0;
		if (Object.op_Implicit((Object)(object)((EntityState)self).characterBody) && Object.op_Implicit((Object)(object)((EntityState)self).characterBody.master) && Object.op_Implicit((Object)(object)((EntityState)self).characterBody.master.inventory))
		{
			num = ((EntityState)self).characterBody.master.inventory.GetItemCount(stackItem);
		}
		orig.Invoke(self, contactPoint);
		for (int i = 0; i < num; i++)
		{
			orig.Invoke(self, contactPoint);
		}
	}

	private string CharacterBody_GetDisplayName(orig_GetDisplayName orig, CharacterBody self)
	{
		string text = orig.Invoke(self);
		if (Object.op_Implicit((Object)(object)self) && Object.op_Implicit((Object)(object)self.master))
		{
			int itemCount = self.master.inventory.GetItemCount(stackItem);
			if (itemCount > 0)
			{
				return $"{text} <style=cStack>x{itemCount + 1}</style>";
			}
		}
		return text;
	}
}