Decompiled source of InvisibilityDecoy v1.0.0

InvisibilityDecoy.dll

Decompiled 20 hours 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 BepInEx;
using BepInEx.Logging;
using BoplFixedMath;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyVersion("0.0.0.0")]
namespace InvisibilityDecoy;

public sealed class DecoyActor : MonoBehaviour
{
	internal Player State;

	internal int OwnerId;

	internal SlimeController Controller;

	internal PlayerBody Body;

	internal PlayerPhysics Physics;

	internal PlayerCollision Collision;

	internal IPhysicsCollider Hurtbox;

	internal bool Removed;

	private DecoySnapshot appearance;

	private Material bodyMaterial;

	private readonly List<DecoyCooldown> cooldowns = new List<DecoyCooldown>();

	private static readonly string[] palette = new string[3] { "_MainColor", "_ShadowColor", "_ReflectionColour" };

	private readonly Dictionary<string, Color> normalColors = new Dictionary<string, Color>();

	private bool frozenPalette;

	private readonly List<AbilityReadyIndicator> indicators = new List<AbilityReadyIndicator>();

	private readonly List<Material> iconMaterials = new List<Material>();

	internal void SetAppearanceMaterial(Material source)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Expected O, but got Unknown
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		bodyMaterial = new Material(source);
		((Renderer)Controller.GetPlayerSprite()).sharedMaterial = bodyMaterial;
		State.Color = bodyMaterial;
		string[] array = palette;
		foreach (string text in array)
		{
			if (bodyMaterial.HasProperty(text))
			{
				normalColors[text] = source.GetColor(text);
			}
		}
		UpdateTimeStopAppearance();
	}

	private void LateUpdate()
	{
		UpdateTimeStopAppearance();
	}

	private void UpdateTimeStopAppearance()
	{
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: 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)
		if (Removed || (Object)(object)bodyMaterial == (Object)null)
		{
			return;
		}
		bool flag = GameTime.IsTimeStopped();
		if (flag == frozenPalette)
		{
			return;
		}
		foreach (KeyValuePair<string, Color> normalColor in normalColors)
		{
			Color value = normalColor.Value;
			if (flag)
			{
				((Color)(ref value))..ctor(((Color)(ref value)).grayscale, ((Color)(ref value)).grayscale, ((Color)(ref value)).grayscale, value.a);
			}
			bodyMaterial.SetColor(normalColor.Key, value);
		}
		frozenPalette = flag;
	}

	private void ChargeIndicators(Fix deltaTime)
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: 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_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: 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)
		//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)
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_010f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0114: Unknown result type (might be due to invalid IL or missing references)
		//IL_0121: Unknown result type (might be due to invalid IL or missing references)
		//IL_0126: 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_0139: Unknown result type (might be due to invalid IL or missing references)
		//IL_013e: Unknown result type (might be due to invalid IL or missing references)
		if (GameSessionHandler.GameIsPaused)
		{
			return;
		}
		Fix val = GameTime.FixedDeltaTime(State.Id, deltaTime);
		for (int i = 0; i < cooldowns.Count; i++)
		{
			DecoyCooldown value = cooldowns[i];
			bool flag = value.Delay <= Fix.Zero && value.Elapsed >= value.Duration;
			Fix val2 = val;
			if (value.Delay > Fix.Zero)
			{
				Fix val3 = Fix.Min(value.Delay, val2);
				ref Fix delay = ref value.Delay;
				delay -= val3;
				val2 -= val3;
			}
			value.Elapsed = Fix.Min(value.Duration, value.Elapsed + val2);
			cooldowns[i] = value;
			AbilityReadyIndicator val4 = indicators[i];
			if (!((Object)(object)val4 == (Object)null))
			{
				bool flag2 = value.Delay <= Fix.Zero && value.Elapsed >= value.Duration;
				val4.SetCooldownProgress((value.Delay > Fix.Zero) ? 0f : ((value.Duration <= Fix.Zero) ? 1f : ((float)(value.Elapsed / value.Duration))));
				if (!flag && flag2)
				{
					val4.ResetAnimation();
				}
			}
		}
	}

	internal void Configure(Player state, DecoySnapshot snapshot, SlimeController controller)
	{
		State = state;
		OwnerId = snapshot.OwnerId;
		appearance = snapshot;
		Controller = controller;
		Body = ((Component)this).GetComponent<PlayerBody>();
		Physics = ((Component)this).GetComponent<PlayerPhysics>();
		Collision = ((Component)this).GetComponent<PlayerCollision>();
		Hurtbox = ((Component)this).GetComponent<IPhysicsCollider>();
		if ((Object)(object)controller == (Object)null || (Object)(object)Body == (Object)null || (Object)(object)Physics == (Object)null || (Object)(object)Collision == (Object)null || Hurtbox == null)
		{
			throw new InvalidOperationException("The native empty-player prefab is missing a required component.");
		}
		RefreshTimeProtection();
	}

	internal DecoySnapshot SnapshotForCopy()
	{
		//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_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: 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_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		PlayerInfo pose = appearance.Pose;
		pose.position = Body.position;
		pose.rotation = Body.rotation;
		pose.isGrounded = false;
		pose.currentlyAttachedGround = null;
		return new DecoySnapshot
		{
			OwnerId = OwnerId,
			Team = State.Team,
			Scale = Hurtbox.Scale,
			Pose = pose,
			Prefab = appearance.Prefab,
			Animation = appearance.Animation,
			Material = appearance.Material,
			Tint = Controller.GetPlayerSprite().color,
			SortingLayer = ((Renderer)Controller.GetPlayerSprite()).sortingLayerID,
			SortingOrder = ((Renderer)Controller.GetPlayerSprite()).sortingOrder,
			Indicators = indicators.ToArray(),
			Cooldowns = cooldowns.ToArray()
		};
	}

	internal void RefreshTimeProtection()
	{
		State.isProtectedFromTimeStop = false;
	}

	internal void Simulate(Fix deltaTime)
	{
		//IL_0037: 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_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d3: 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_00d9: 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_0100: Unknown result type (might be due to invalid IL or missing references)
		//IL_0110: Unknown result type (might be due to invalid IL or missing references)
		//IL_0115: Unknown result type (might be due to invalid IL or missing references)
		if (Removed)
		{
			return;
		}
		RefreshTimeProtection();
		State.GetRawInputProfile().Reset();
		State.isInvisible = false;
		State.Position = Body.position;
		Hurtbox.Scale = State.Scale;
		ChargeIndicators(deltaTime);
		if (GameTime.IsTimeStoppedFor(State.Id) || GameSessionHandler.GameIsPaused || !Physics.IsGrounded())
		{
			return;
		}
		StickyRoundedRectangle attachedGround = Physics.getAttachedGround();
		if ((Object)(object)attachedGround == (Object)null || ((MonoUpdatable)attachedGround).IsDestroyed || !((Component)attachedGround).gameObject.activeInHierarchy)
		{
			Physics.UnGround(true, false);
			return;
		}
		Vec2 val = attachedGround.currentNormal(Body);
		if (Vec2.Dot(Body.externalVelocity, val) > (Fix)2L)
		{
			Physics.UnGround(true, false);
			return;
		}
		Physics.groundedSpeed = Fix.Zero;
		Physics.Move(Vec2.zero, deltaTime, true);
	}

	internal bool Remove(bool effect, bool ignoreInvulnerability)
	{
		//IL_00b9: 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_00da: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		if (Removed || ((Object)(object)Collision != (Object)null && Collision.IsInvulnerable && !ignoreInvulnerability))
		{
			return false;
		}
		Removed = true;
		State.playersAndClonesStillAlive = 0;
		if ((Object)(object)Body != (Object)null && Body.ropeBody != null)
		{
			Body.AttachRope((RopeBody)null, Body.topAttachment);
		}
		if (Hurtbox != null)
		{
			Hurtbox.enabled = false;
		}
		if (effect && (Object)(object)Collision != (Object)null && (Object)(object)Collision.deathEffect != (Object)null)
		{
			GameObject obj = FixTransform.InstantiateFixed(Collision.deathEffect, Body.position);
			Transform transform = obj.transform;
			transform.localScale *= (float)Body.fixtrans.Scale;
			SpriteRenderer component = obj.GetComponent<SpriteRenderer>();
			if ((Object)(object)component != (Object)null)
			{
				((Renderer)component).sharedMaterial = appearance.Material;
			}
		}
		DestroyIndicators();
		DecoyRegistry.Forget(this);
		Updater.DestroyFix(((Component)this).gameObject);
		return true;
	}

	internal void CopyIndicators(AbilityReadyIndicator[] source)
	{
		//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Expected O, but got Unknown
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: 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_010d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0127: Unknown result type (might be due to invalid IL or missing references)
		//IL_012c: 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)
		//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0100: Unknown result type (might be due to invalid IL or missing references)
		if (source == null)
		{
			return;
		}
		for (int i = 0; i < source.Length; i++)
		{
			AbilityReadyIndicator val = source[i];
			if (!((Object)(object)val == (Object)null))
			{
				AbilityReadyIndicator val2 = Object.Instantiate<AbilityReadyIndicator>(val);
				indicators.Add(val2);
				cooldowns.Add((appearance.Cooldowns != null && i < appearance.Cooldowns.Length) ? appearance.Cooldowns[i] : default(DecoyCooldown));
				SpriteRenderer component = ((Component)val2).GetComponent<SpriteRenderer>();
				Material val3 = new Material(((Renderer)val.GetSpriteRen()).material);
				iconMaterials.Add(val3);
				((Renderer)component).material = val3;
				Color color = component.color;
				color.a = 1f;
				component.color = color;
				FollowTransform component2 = ((Component)val2).GetComponent<FollowTransform>();
				if ((Object)(object)component2 != (Object)null)
				{
					Transform val4 = ((Component)val).GetComponent<FollowTransform>()?.Leader;
					((Component)val2).transform.position = (((Object)(object)val4 == (Object)null) ? (((Component)val).transform.position - ((Component)appearance.Pose.slimeController).transform.position) : (((Component)val).transform.position - val4.position));
					component2.Leader = ((Component)this).transform;
				}
				val2.Init();
				Sprite primarySprite = val.GetPrimarySprite();
				if ((Object)(object)primarySprite != (Object)null)
				{
					val2.SetSprite(primarySprite, true);
				}
				((Component)val2).gameObject.SetActive(((Component)val).gameObject.activeSelf);
				val2.InstantlySyncTransform();
			}
		}
		Controller.AbilityReadyIndicators = indicators.ToArray();
		ChargeIndicators(Fix.Zero);
	}

	private void DestroyIndicators()
	{
		foreach (AbilityReadyIndicator indicator in indicators)
		{
			if ((Object)(object)indicator != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)indicator).gameObject);
			}
		}
		indicators.Clear();
		cooldowns.Clear();
		foreach (Material iconMaterial in iconMaterials)
		{
			if ((Object)(object)iconMaterial != (Object)null)
			{
				Object.Destroy((Object)(object)iconMaterial);
			}
		}
		iconMaterials.Clear();
	}

	private void OnDestroy()
	{
		Removed = true;
		DestroyIndicators();
		if ((Object)(object)bodyMaterial != (Object)null)
		{
			Object.Destroy((Object)(object)bodyMaterial);
		}
		if (State != null)
		{
			DecoyRegistry.Forget(this);
		}
	}
}
internal struct DecoyCooldown
{
	internal Fix Elapsed;

	internal Fix Duration;

	internal Fix Delay;
}
internal sealed class DecoySnapshot
{
	internal int OwnerId;

	internal int Team;

	internal Fix Scale;

	internal PlayerInfo Pose;

	internal SlimeController Prefab;

	internal AnimationData Animation;

	internal Material Material;

	internal Color Tint;

	internal int SortingLayer;

	internal int SortingOrder;

	internal AbilityReadyIndicator[] Indicators;

	internal DecoyCooldown[] Cooldowns;
}
internal static class DecoyFactory
{
	internal static DecoySnapshot Capture(InstantAbility ability)
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_0201: Unknown result type (might be due to invalid IL or missing references)
		//IL_0206: Unknown result type (might be due to invalid IL or missing references)
		//IL_010d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0112: Unknown result type (might be due to invalid IL or missing references)
		//IL_012c: Unknown result type (might be due to invalid IL or missing references)
		//IL_013c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0137: Unknown result type (might be due to invalid IL or missing references)
		//IL_0159: Unknown result type (might be due to invalid IL or missing references)
		//IL_015e: Unknown result type (might be due to invalid IL or missing references)
		//IL_016c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0171: Unknown result type (might be due to invalid IL or missing references)
		//IL_017f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0184: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)ability == (Object)null)
		{
			return null;
		}
		PlayerInfo playerInfo = ability.playerInfo;
		SlimeController slimeController = playerInfo.slimeController;
		if ((Object)(object)slimeController == (Object)null || ((MonoUpdatable)slimeController).IsDestroyed || (Object)(object)((Component)slimeController).GetComponent<DecoyActor>() != (Object)null)
		{
			return null;
		}
		Player player = PlayerHandler.Get().GetPlayer(playerInfo.playerId);
		PlayerCollision playerCollision = slimeController.GetPlayerCollision();
		SpriteRenderer playerSprite = slimeController.GetPlayerSprite();
		if (player == null || !player.IsAlive || (Object)(object)playerCollision == (Object)null || (Object)(object)playerSprite == (Object)null || (Object)(object)playerCollision.reviveEffectPrefab == (Object)null || (Object)(object)playerCollision.reviveEffectPrefab.emptyPlayerPrefab == (Object)null)
		{
			return null;
		}
		Fix[] value = Traverse.Create((object)slimeController).Field("abilityCooldownTimers").GetValue<Fix[]>();
		DecoyCooldown[] array = new DecoyCooldown[slimeController.AbilityReadyIndicators.Length];
		for (int i = 0; i < array.Length; i++)
		{
			if (i < slimeController.abilities.Count && !((Object)(object)slimeController.abilities[i] == (Object)null))
			{
				AbilityMonoBehaviour val = slimeController.abilities[i];
				array[i].Duration = val.GetCooldown();
				array[i].Elapsed = ((value != null && i < value.Length) ? value[i] : Fix.Zero);
				if ((Object)(object)((Component)val).GetComponent<Invisibility>() != (Object)null)
				{
					array[i].Duration = Fix.One;
					array[i].Elapsed = Fix.One;
					array[i].Delay = Fix.Zero;
				}
			}
		}
		return new DecoySnapshot
		{
			OwnerId = player.Id,
			Team = player.Team,
			Scale = slimeController.body.fixtrans.Scale,
			Pose = playerInfo,
			Prefab = playerCollision.reviveEffectPrefab.emptyPlayerPrefab,
			Animation = slimeController.animData,
			Material = ((Renderer)playerSprite).sharedMaterial,
			Tint = playerSprite.color,
			SortingLayer = ((Renderer)playerSprite).sortingLayerID,
			SortingOrder = ((Renderer)playerSprite).sortingOrder,
			Indicators = slimeController.AbilityReadyIndicators,
			Cooldowns = array
		};
	}

	internal static DecoyActor Spawn(DecoySnapshot snapshot, Vec2 position, bool activation)
	{
		//IL_0041: 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_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_012a: Unknown result type (might be due to invalid IL or missing references)
		//IL_016e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0173: Unknown result type (might be due to invalid IL or missing references)
		//IL_018d: Unknown result type (might be due to invalid IL or missing references)
		//IL_018e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0195: Unknown result type (might be due to invalid IL or missing references)
		//IL_019a: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_020e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0213: Unknown result type (might be due to invalid IL or missing references)
		//IL_021e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0223: Unknown result type (might be due to invalid IL or missing references)
		//IL_023c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0241: Unknown result type (might be due to invalid IL or missing references)
		//IL_0250: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
		if (snapshot == null || !DecoyRegistry.MakeRoom(snapshot.OwnerId, activation))
		{
			return null;
		}
		Player val = null;
		GameObject val2 = null;
		try
		{
			SpriteFrame[] animation = snapshot.Animation.GetAnimation("idle");
			if (animation == null || animation.Length == 0)
			{
				throw new InvalidOperationException("The source slime has no idle animation.");
			}
			val = DecoyRegistry.Allocate(snapshot.Team, snapshot.Scale, snapshot.Material, position);
			val2 = FixTransform.InstantiateFixed(((Component)snapshot.Prefab).gameObject, position, snapshot.Pose.rotation);
			DecoyActor decoyActor = val2.AddComponent<DecoyActor>();
			SlimeController component = val2.GetComponent<SlimeController>();
			decoyActor.Configure(val, snapshot, component);
			DecoyRegistry.Attach(decoyActor);
			((Object)val2).name = "InvisibilityDecoy";
			component.playerNumber = val.Id;
			component.suppressInput = true;
			component.isAbilitylessClone = true;
			component.abilities = new List<AbilityMonoBehaviour>();
			component.AbilityReadyIndicators = Array.Empty<AbilityReadyIndicator>();
			component.animData = snapshot.Animation;
			Traverse.Create((object)component).Field("currentState").SetValue((object)(State)0);
			Traverse.Create((object)component).Field("hasSpawned").SetValue((object)true);
			decoyActor.Collision.SetInvulnerable(false, uint.MaxValue);
			decoyActor.Hurtbox.Scale = val.Scale;
			decoyActor.Hurtbox.enabled = true;
			((Behaviour)decoyActor.Physics).enabled = true;
			Traverse.Create((object)decoyActor.Physics).Field("ApplyGravity").SetValue((object)true);
			PlayerInfo pose = snapshot.Pose;
			pose.playerId = val.Id;
			pose.slimeController = component;
			pose.position = position;
			pose.externalVelocity = Vec2.zero;
			pose.selfImposedVelocity = Vec2.zero;
			pose.groundedSpeed = Fix.Zero;
			pose.ropeBody = null;
			if (!activation || (Object)(object)pose.currentlyAttachedGround == (Object)null || ((MonoUpdatable)pose.currentlyAttachedGround).IsDestroyed)
			{
				pose.isGrounded = false;
				pose.currentlyAttachedGround = null;
			}
			decoyActor.Physics.SyncPhysicsTo(pose);
			decoyActor.Body.simulated = true;
			decoyActor.Body.selfImposedVelocity = Vec2.zero;
			decoyActor.Body.externalVelocity = Vec2.zero;
			SpriteRenderer playerSprite = component.GetPlayerSprite();
			decoyActor.SetAppearanceMaterial(snapshot.Material);
			Color tint = snapshot.Tint;
			tint.a = 1f;
			playerSprite.color = tint;
			((Renderer)playerSprite).enabled = true;
			((Renderer)playerSprite).sortingLayerID = snapshot.SortingLayer;
			((Renderer)playerSprite).sortingOrder = snapshot.SortingOrder;
			FlippingTransform componentInChildren = ((Component)component).GetComponentInChildren<FlippingTransform>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				componentInChildren.alignTransform(snapshot.Pose.isFacingRight);
			}
			SpriteAnimator component2 = ((Component)playerSprite).GetComponent<SpriteAnimator>();
			if ((Object)(object)component2 == (Object)null)
			{
				throw new InvalidOperationException("The native slime sprite has no SpriteAnimator.");
			}
			component2.AlwaysStopDuringTimeStop = true;
			component2.beginAnimation(animation);
			val2.SetActive(true);
			decoyActor.CopyIndicators(snapshot.Indicators);
			return decoyActor;
		}
		catch (Exception ex)
		{
			if (val != null)
			{
				val.playersAndClonesStillAlive = 0;
			}
			if ((Object)(object)val2 != (Object)null)
			{
				DecoyActor component3 = val2.GetComponent<DecoyActor>();
				if ((Object)(object)component3 != (Object)null && component3.State != null)
				{
					component3.Remove(effect: false, ignoreInvulnerability: true);
				}
				else
				{
					Updater.DestroyFix(val2);
				}
			}
			Plugin.Log.LogError((object)("Invisibility Decoy: spawning failed; native invisibility remains active. " + ex));
			return null;
		}
	}
}
internal static class DecoyRegistry
{
	private sealed class Entry
	{
		internal Player State;

		internal DecoyActor Body;
	}

	private static readonly Dictionary<int, Entry> entries = new Dictionary<int, Entry>();

	private static readonly List<DecoyActor> active = new List<DecoyActor>();

	private static int nextId = -10000;

	internal static bool TryGetPlayer(int id, out Player player)
	{
		Entry value;
		bool flag = entries.TryGetValue(id, out value);
		player = (flag ? value.State : null);
		return flag;
	}

	internal static DecoyActor Find(int id)
	{
		if (!entries.TryGetValue(id, out var value))
		{
			return null;
		}
		return value.Body;
	}

	internal static Player Allocate(int team, Fix scale, Material material, Vec2 position)
	{
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: 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)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: 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_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Expected O, but got Unknown
		while (PlayerHandler.Get().GetPlayer(nextId) != null)
		{
			nextId--;
		}
		Player val = new Player(nextId--, team)
		{
			Scale = scale,
			Color = material,
			Position = position,
			SpawnPosition = position,
			IsLocalPlayer = false,
			CanUseAbilities = false,
			ignoreAllInputs = true,
			isInvisible = false,
			ExtraLife = (ReviveStatus)0,
			playersAndClonesStillAlive = 1
		};
		entries.Add(val.Id, new Entry
		{
			State = val
		});
		return val;
	}

	internal static void Attach(DecoyActor actor)
	{
		entries[actor.State.Id].Body = actor;
		active.Add(actor);
	}

	internal static void Forget(DecoyActor actor)
	{
		active.Remove(actor);
		if (actor.State != null && entries.TryGetValue(actor.State.Id, out var value) && value.State == actor.State)
		{
			value.State.playersAndClonesStillAlive = 0;
			value.Body = null;
		}
	}

	internal static bool MakeRoom(int ownerId, bool activation)
	{
		active.RemoveAll((DecoyActor actor) => (Object)(object)actor == (Object)null || actor.Removed);
		int num = 0;
		DecoyActor decoyActor = null;
		foreach (DecoyActor item in active)
		{
			if (item.OwnerId == ownerId)
			{
				num++;
				if ((Object)(object)decoyActor == (Object)null)
				{
					decoyActor = item;
				}
			}
		}
		if (num < 16)
		{
			return true;
		}
		if (!activation)
		{
			return false;
		}
		decoyActor?.Remove(effect: false, ignoreInvulnerability: true);
		return true;
	}

	internal static void Clear()
	{
		DecoyActor[] array = active.ToArray();
		foreach (DecoyActor decoyActor in array)
		{
			if ((Object)(object)decoyActor != (Object)null)
			{
				decoyActor.Remove(effect: false, ignoreInvulnerability: true);
			}
		}
		active.Clear();
		entries.Clear();
		nextId = -10000;
	}
}
[HarmonyPatch(typeof(ShootDuplicator), "ApplyDuplicationEffect")]
internal static class DuplicateDecoyPatch
{
	private static bool Prefix(ShootDuplicator __instance, GameObject obj, Vec2 objPos, Vec2 dir, ref bool hasFired)
	{
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: 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_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: 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)
		DecoyActor decoyActor = (((Object)(object)obj == (Object)null) ? null : obj.GetComponent<DecoyActor>());
		if ((Object)(object)decoyActor == (Object)null)
		{
			return true;
		}
		hasFired = true;
		if (decoyActor.Removed)
		{
			return false;
		}
		DecoyActor decoyActor2 = DecoyFactory.Spawn(decoyActor.SnapshotForCopy(), objPos, activation: false);
		if ((Object)(object)decoyActor2 != (Object)null)
		{
			Vec2 val = decoyActor.Controller.CurrentNormal();
			Vec2 val2 = ((dir == val) ? dir : Vec2.Slerp(dir, val, __instance.f03));
			decoyActor2.Body.selfImposedVelocity = val2 * (Fix)1.3 * decoyActor2.Physics.jumpStrength;
		}
		return false;
	}
}
[HarmonyPatch]
internal static class CloneDecoyPatch
{
	private static IEnumerable<MethodBase> TargetMethods()
	{
		yield return AccessTools.Method(typeof(PlayerCollision), "SpawnClone", (Type[])null, (Type[])null);
		yield return AccessTools.Method(typeof(PlayerCollision), "SpawnAbilityLessClone", (Type[])null, (Type[])null);
	}

	private static bool Prefix(SlimeController slimeContToRevive, Vec2 targetPosition, ref SlimeController __result)
	{
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		DecoyActor decoyActor = (((Object)(object)slimeContToRevive == (Object)null) ? null : ((Component)slimeContToRevive).GetComponent<DecoyActor>());
		if ((Object)(object)decoyActor == (Object)null)
		{
			return true;
		}
		DecoyActor decoyActor2 = (decoyActor.Removed ? null : DecoyFactory.Spawn(decoyActor.SnapshotForCopy(), targetPosition, activation: false));
		__result = (((Object)(object)decoyActor2 == (Object)null) ? null : decoyActor2.Controller);
		return false;
	}
}
[HarmonyPatch(typeof(Invisibility), "CastInvisibility")]
internal static class CastInvisibilityPatch
{
	private static void Prefix(InstantAbility ___ia, out DecoySnapshot __state)
	{
		__state = null;
		try
		{
			__state = DecoyFactory.Capture(___ia);
		}
		catch (Exception ex)
		{
			Plugin.Log.LogError((object)("Could not capture decoy appearance: " + ex));
		}
	}

	private static void Postfix(DecoySnapshot __state)
	{
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		if (__state != null)
		{
			Player player = PlayerHandler.Get().GetPlayer(__state.OwnerId);
			if (player != null && player.IsAlive && player.isInvisible)
			{
				DecoyFactory.Spawn(__state, __state.Pose.position, activation: true);
				InstantInvisibilityPatch.RegisterInitialCast(player.Id);
			}
		}
	}
}
[HarmonyPatch(typeof(PlayerHandler), "GetPlayer")]
internal static class ResolveDecoyPatch
{
	private static bool Prefix(int playerId, ref Player __result)
	{
		if (!DecoyRegistry.TryGetPlayer(playerId, out var player))
		{
			return true;
		}
		__result = player;
		return false;
	}
}
[HarmonyPatch(typeof(PlayerCollision), "killPlayer")]
internal static class DecoyHitPatch
{
	[HarmonyPriority(800)]
	private static bool Prefix(PlayerCollision __instance, bool spawnEffect, bool ignoreInvulnerability, ref bool __result)
	{
		DecoyActor component = ((Component)__instance).GetComponent<DecoyActor>();
		if ((Object)(object)component == (Object)null)
		{
			return true;
		}
		__result = component.Remove(spawnEffect, ignoreInvulnerability);
		return false;
	}
}
[HarmonyPatch(typeof(Player), "Kill")]
internal static class DecoyPlayerDeathPatch
{
	private static bool Prefix(Player __instance)
	{
		if (!DecoyRegistry.TryGetPlayer(__instance.Id, out var player) || player != __instance)
		{
			return true;
		}
		DecoyRegistry.Find(__instance.Id)?.Remove(effect: false, ignoreInvulnerability: true);
		return false;
	}
}
[HarmonyPatch(typeof(SlimeController), "UpdateSim")]
internal static class PassiveSlimePatch
{
	private static bool Prefix(SlimeController __instance, Fix __0)
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		DecoyActor component = ((Component)__instance).GetComponent<DecoyActor>();
		if ((Object)(object)component == (Object)null)
		{
			return true;
		}
		component.Simulate(__0);
		return false;
	}
}
[HarmonyPatch]
internal static class PassiveLifecyclePatch
{
	private static IEnumerable<MethodBase> TargetMethods()
	{
		string[] names = new string[8] { "Init", "Spawn", "ReSpawn", "PrepareToRevive", "EnterAbility", "Bite", "OnNoLongerGrounded", "attachToGround" };
		return from method in typeof(SlimeController).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
			where names.Contains(method.Name)
			select method;
	}

	private static bool Prefix(SlimeController __instance)
	{
		return (Object)(object)((Component)__instance).GetComponent<DecoyActor>() == (Object)null;
	}
}
[HarmonyPatch(typeof(SlimeController), "OnCollide")]
internal static class PassiveContactPatch
{
	private static bool Prefix(SlimeController __instance, CollisionInformation collision)
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)((Component)__instance).GetComponent<DecoyActor>() != (Object)null)
		{
			return false;
		}
		FixTransform fixTrans = collision.colliderPP.fixTrans;
		DecoyActor decoyActor = (((Object)(object)fixTrans == (Object)null) ? null : ((Component)fixTrans).GetComponent<DecoyActor>());
		if (!((Object)(object)decoyActor == (Object)null))
		{
			return decoyActor.OwnerId != __instance.playerNumber;
		}
		return true;
	}
}
[HarmonyPatch(typeof(SlimeController), "ApplyRagDoll")]
internal static class PassiveImpulsePatch
{
	private static bool Prefix(SlimeController __instance, Vec2 speed)
	{
		//IL_002d: 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)
		DecoyActor component = ((Component)__instance).GetComponent<DecoyActor>();
		if ((Object)(object)component == (Object)null)
		{
			return true;
		}
		if (!component.Removed)
		{
			component.Physics.UnGround(true, false);
			component.Body.selfImposedVelocity = speed;
		}
		return false;
	}
}
[HarmonyPatch(typeof(PlayerPhysics), "UnGround")]
internal static class DecoyJumpSoundPatch
{
	private static void Prefix(PlayerPhysics __instance, ref bool playSoundEffect)
	{
		if ((Object)(object)((Component)__instance).GetComponent<DecoyActor>() != (Object)null)
		{
			playSoundEffect = false;
		}
	}
}
[HarmonyPatch(typeof(PlayerPhysics), "UpdateSim")]
internal static class DecoyTimeStopPatch
{
	private static bool Prefix(PlayerPhysics __instance)
	{
		DecoyActor component = ((Component)__instance).GetComponent<DecoyActor>();
		if ((Object)(object)component == (Object)null)
		{
			return true;
		}
		component.RefreshTimeProtection();
		if (!component.Removed && !GameSessionHandler.GameIsPaused)
		{
			return !GameTime.IsTimeStoppedFor(component.State.Id);
		}
		return false;
	}
}
[HarmonyPatch(typeof(DynamicAbilityPickup), "OnCollide")]
internal static class DecoyPickupPatch
{
	private static bool Prefix(CollisionInformation collision)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		FixTransform fixTrans = collision.colliderPP.fixTrans;
		if (!((Object)(object)fixTrans == (Object)null))
		{
			return (Object)(object)((Component)fixTrans).GetComponent<DecoyActor>() == (Object)null;
		}
		return true;
	}
}
[HarmonyPatch(typeof(PlayerHandler), "ResetForNextStage")]
internal static class DecoyRoundCleanupPatch
{
	private static void Prefix()
	{
		DecoyRegistry.Clear();
	}
}
[HarmonyPatch(typeof(Updater), "PreLevelLoad")]
internal static class DecoyLevelCleanupPatch
{
	private static void Prefix()
	{
		DecoyRegistry.Clear();
	}
}
[HarmonyPatch]
internal static class FrozenDecoyBodyPatch
{
	private static IEnumerable<MethodBase> TargetMethods()
	{
		yield return AccessTools.Method(typeof(PlayerBody), "UpdateSim", (Type[])null, (Type[])null);
		yield return AccessTools.Method(typeof(PlayerBody), "LateUpdateSim", (Type[])null, (Type[])null);
		yield return AccessTools.Method(typeof(PlayerPhysics), "LateUpdateSim", (Type[])null, (Type[])null);
	}

	private static bool Prefix(Component __instance)
	{
		DecoyActor component = __instance.GetComponent<DecoyActor>();
		if (!((Object)(object)component == (Object)null))
		{
			if (!component.Removed && !GameTime.IsTimeStopped())
			{
				return !GameSessionHandler.GameIsPaused;
			}
			return false;
		}
		return true;
	}
}
[HarmonyPatch(typeof(Invisibility), "SetAlphaBasedOnPlayerInvisibiltyTime")]
internal static class InstantInvisibilityPatch
{
	private static readonly HashSet<int> _initialCasts = new HashSet<int>();

	public static void RegisterInitialCast(int playerId)
	{
		_initialCasts.Add(playerId);
	}

	private static void Postfix(Player player, SpriteRenderer spriteRen)
	{
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: 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_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		if (player == null || (Object)(object)spriteRen == (Object)null)
		{
			return;
		}
		if (!player.isInvisible)
		{
			_initialCasts.Remove(player.Id);
		}
		else if (_initialCasts.Contains(player.Id))
		{
			if (player.timeSpentInvisible >= (Fix)1f)
			{
				_initialCasts.Remove(player.Id);
			}
			else if (spriteRen.color.a < 1f)
			{
				Color color = spriteRen.color;
				color.a = 0f;
				spriteRen.color = color;
			}
		}
	}
}
[BepInPlugin("com.maha.boplbattle.invisibilitydecoy", "Invisibility Decoy", "1.0.2")]
public sealed class Plugin : BaseUnityPlugin
{
	public const string Guid = "com.maha.boplbattle.invisibilitydecoy";

	internal static ManualLogSource Log;

	internal const int MaxDecoysPerOwner = 16;

	private void Awake()
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		Log = ((BaseUnityPlugin)this).Logger;
		new Harmony("com.maha.boplbattle.invisibilitydecoy").PatchAll();
		Log.LogInfo((object)"Invisibility Decoy: native invisibility now leaves a passive, independent slime decoy.");
	}
}