Decompiled source of UnikittySnareFlea v1.0.0

plugins/UnikittySnareFlea/UnikittySnareFlea.dll

Decompiled 7 hours ago
using System;
using System.Collections;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using GameNetcodeStuff;
using HarmonyLib;
using UnityEngine;
using UnityEngine.Networking;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace UnikittySnareFlea;

[BepInPlugin("unikitty.snareflea", "Unikitty Snare Flea", "1.0.0")]
public sealed class Plugin : BaseUnityPlugin
{
	internal static Mesh Model { get; private set; }

	internal static Mesh Head { get; private set; }

	internal static Texture2D Texture { get; private set; }

	internal static AudioClip Song { get; private set; }

	private void Awake()
	{
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Expected O, but got Unknown
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
		try
		{
			Model = LoadMesh(Path.Combine(directoryName, "unikitty.mesh"));
			Head = LoadMesh(Path.Combine(directoryName, "unikitty-head.mesh"));
			Texture = new Texture2D(2, 2, (TextureFormat)4, true);
			if (!ImageConversion.LoadImage(Texture, File.ReadAllBytes(Path.Combine(directoryName, "unikitty-diffuse.png")), true))
			{
				throw new InvalidDataException("The Unikitty texture could not be decoded.");
			}
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)ex);
			return;
		}
		new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID).PatchAll(typeof(Plugin).Assembly);
		string text = Path.Combine(directoryName, "ambush.ogg");
		if (File.Exists(text))
		{
			((MonoBehaviour)this).StartCoroutine(LoadSong(new Uri(text).AbsoluteUri));
		}
	}

	private static Mesh LoadMesh(string path)
	{
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_009c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: 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: Expected O, but got Unknown
		using BinaryReader binaryReader = new BinaryReader(File.OpenRead(path));
		int num = binaryReader.ReadInt32();
		int num2 = binaryReader.ReadInt32();
		Vector3[] array = (Vector3[])(object)new Vector3[num];
		Vector3[] array2 = (Vector3[])(object)new Vector3[num];
		Vector2[] array3 = (Vector2[])(object)new Vector2[num];
		int[] array4 = new int[num2];
		for (int i = 0; i < num; i++)
		{
			ref Vector3 reference = ref array[i];
			reference = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
			ref Vector3 reference2 = ref array2[i];
			reference2 = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
			ref Vector2 reference3 = ref array3[i];
			reference3 = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle());
		}
		for (int j = 0; j < num2; j++)
		{
			array4[j] = binaryReader.ReadInt32();
		}
		Mesh val = new Mesh();
		((Object)val).name = "Unikitty";
		val.vertices = array;
		val.normals = array2;
		val.uv = array3;
		val.triangles = array4;
		Mesh val2 = val;
		val2.RecalculateBounds();
		val2.RecalculateTangents();
		return val2;
	}

	private IEnumerator LoadSong(string uri)
	{
		UnityWebRequest request = UnityWebRequestMultimedia.GetAudioClip(uri, (AudioType)14);
		try
		{
			yield return request.SendWebRequest();
			if ((int)request.result == 1)
			{
				Song = DownloadHandlerAudioClip.GetContent(request);
			}
			else
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Could not load Unikitty's ambush music: " + request.error));
			}
		}
		finally
		{
			((IDisposable)request)?.Dispose();
		}
	}
}
[HarmonyPatch(typeof(CentipedeAI))]
internal static class FleaPatches
{
	[HarmonyPostfix]
	[HarmonyPatch("Start")]
	private static void Attach(CentipedeAI __instance)
	{
		if ((Object)(object)__instance.modelContainer != (Object)null)
		{
			((Component)__instance).gameObject.AddComponent<Unikitty>().Initialize(__instance);
		}
	}

	[HarmonyPostfix]
	[HarmonyPatch("LateUpdate")]
	private static void UpdatePose(CentipedeAI __instance, bool ___clingingToCeiling)
	{
		Unikitty component = ((Component)__instance).GetComponent<Unikitty>();
		if ((Object)(object)component != (Object)null)
		{
			component.UpdatePose(___clingingToCeiling);
		}
	}

	[HarmonyPostfix]
	[HarmonyPatch("fallFromCeiling")]
	private static void StartAmbush(CentipedeAI __instance)
	{
		Unikitty component = ((Component)__instance).GetComponent<Unikitty>();
		if ((Object)(object)component != (Object)null && !((EnemyAI)__instance).isEnemyDead)
		{
			component.StartAmbush();
		}
	}

	[HarmonyPatch("StopClingingToPlayer")]
	[HarmonyPostfix]
	private static void Detach(CentipedeAI __instance)
	{
		StopAmbush(__instance);
	}

	[HarmonyPostfix]
	[HarmonyPatch("KillEnemy")]
	private static void Die(CentipedeAI __instance)
	{
		StopAmbush(__instance);
	}

	[HarmonyPatch("OnDisable")]
	[HarmonyPostfix]
	private static void Disable(CentipedeAI __instance)
	{
		StopAmbush(__instance);
	}

	private static void StopAmbush(CentipedeAI instance)
	{
		Unikitty component = ((Component)instance).GetComponent<Unikitty>();
		if ((Object)(object)component != (Object)null)
		{
			component.EndAmbush();
		}
	}
}
public sealed class Unikitty : MonoBehaviour
{
	private CentipedeAI flea;

	private Renderer[] originalRenderers;

	private MeshFilter modelFilter;

	private MeshRenderer replacement;

	private Material material;

	private AudioSource music;

	private bool ambushing;

	private bool hideLatch;

	internal void Initialize(CentipedeAI instance)
	{
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Expected O, but got Unknown
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0104: Expected O, but got Unknown
		flea = instance;
		originalRenderers = (from renderer in ((Component)flea.modelContainer).GetComponentsInChildren<Renderer>(true)
			where renderer is SkinnedMeshRenderer || renderer is MeshRenderer
			select renderer).ToArray();
		if (originalRenderers.Length == 0)
		{
			return;
		}
		Material sharedMaterial = originalRenderers[0].sharedMaterial;
		if (!((Object)(object)sharedMaterial == (Object)null))
		{
			Shader val = Shader.Find("HDRP/Lit");
			if ((Object)(object)val == (Object)null)
			{
				val = sharedMaterial.shader;
			}
			Material val2 = new Material(val);
			val2.mainTexture = (Texture)(object)Plugin.Texture;
			val2.color = Color.white;
			material = val2;
			if (material.HasProperty("_BaseColorMap"))
			{
				material.SetTexture("_BaseColorMap", (Texture)(object)Plugin.Texture);
			}
			if (material.HasProperty("_Smoothness"))
			{
				material.SetFloat("_Smoothness", 0.3f);
			}
			GameObject val3 = new GameObject("Unikitty model");
			val3.transform.SetParent(flea.modelContainer, false);
			modelFilter = val3.AddComponent<MeshFilter>();
			modelFilter.sharedMesh = Plugin.Model;
			replacement = val3.AddComponent<MeshRenderer>();
			((Renderer)replacement).sharedMaterial = material;
			Renderer[] array = originalRenderers;
			foreach (Renderer val4 in array)
			{
				val4.forceRenderingOff = true;
			}
			AudioSource[] componentsInChildren = ((Component)flea).GetComponentsInChildren<AudioSource>(true);
			foreach (AudioSource val5 in componentsInChildren)
			{
				val5.mute = true;
			}
			UpdatePose(onCeiling: false);
		}
	}

	internal void UpdatePose(bool onCeiling)
	{
		//IL_00c3: 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_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0120: Unknown result type (might be due to invalid IL or missing references)
		if (((EnemyAI)flea).isEnemyDead || ((EnemyAI)flea).currentBehaviourStateIndex < 2)
		{
			EndAmbush();
		}
		if ((Object)(object)replacement == (Object)null)
		{
			return;
		}
		PlayerControllerB val = ActiveVictim();
		if ((Object)(object)val != (Object)null && (Object)(object)val.playerGlobalHead != (Object)null)
		{
			Transform playerGlobalHead = val.playerGlobalHead;
			modelFilter.sharedMesh = Plugin.Head;
			((Component)replacement).transform.SetPositionAndRotation(playerGlobalHead.position, playerGlobalHead.rotation);
			((Component)replacement).gameObject.layer = 19;
			((Renderer)replacement).enabled = !IsLocal(val);
			return;
		}
		modelFilter.sharedMesh = Plugin.Model;
		((Component)replacement).transform.localPosition = Vector3.zero;
		bool flag = onCeiling && !ambushing && !((EnemyAI)flea).isEnemyDead;
		float y = ((Component)flea).transform.eulerAngles.y;
		((Component)replacement).transform.rotation = Quaternion.Euler(0f, y, flag ? 180f : 0f);
		((Component)replacement).gameObject.layer = ((Component)originalRenderers[0]).gameObject.layer;
		((Renderer)replacement).enabled = originalRenderers.Any((Renderer renderer) => renderer.enabled && ((Component)renderer).gameObject.activeInHierarchy);
	}

	private PlayerControllerB ActiveVictim()
	{
		PlayerControllerB clingingToPlayer = flea.clingingToPlayer;
		if ((Object)(object)clingingToPlayer == (Object)null)
		{
			hideLatch = false;
			return null;
		}
		if (!hideLatch && !((EnemyAI)flea).isEnemyDead && !clingingToPlayer.isPlayerDead)
		{
			return clingingToPlayer;
		}
		return null;
	}

	private static bool IsLocal(PlayerControllerB victim)
	{
		if ((Object)(object)GameNetworkManager.Instance != (Object)null)
		{
			return (Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)(object)victim;
		}
		return false;
	}

	private void OnGUI()
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Invalid comparison between Unknown and I4
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		if ((int)Event.current.type == 7 && !((Object)(object)flea == (Object)null))
		{
			PlayerControllerB val = ActiveVictim();
			if ((Object)(object)val != (Object)null && IsLocal(val))
			{
				int depth = GUI.depth;
				GUI.depth = -1000;
				GUI.DrawTexture(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), (Texture)(object)Texture2D.blackTexture);
				GUI.depth = depth;
			}
		}
	}

	internal void StartAmbush()
	{
		if (ambushing)
		{
			return;
		}
		ambushing = true;
		hideLatch = false;
		if ((Object)(object)Plugin.Song == (Object)null)
		{
			return;
		}
		if ((Object)(object)music == (Object)null)
		{
			AudioSource creatureSFX = ((EnemyAI)flea).creatureSFX;
			music = ((Component)this).gameObject.AddComponent<AudioSource>();
			music.playOnAwake = false;
			music.loop = true;
			music.spatialBlend = 1f;
			music.minDistance = 2f;
			music.maxDistance = 30f;
			music.rolloffMode = (AudioRolloffMode)1;
			if ((Object)(object)creatureSFX != (Object)null)
			{
				music.outputAudioMixerGroup = creatureSFX.outputAudioMixerGroup;
				music.volume = creatureSFX.volume;
			}
		}
		music.clip = Plugin.Song;
		music.Play();
	}

	internal void EndAmbush()
	{
		hideLatch = (Object)(object)flea != (Object)null && (Object)(object)flea.clingingToPlayer != (Object)null;
		if (ambushing)
		{
			ambushing = false;
			if ((Object)(object)music != (Object)null)
			{
				music.Stop();
			}
		}
	}

	private void OnDisable()
	{
		EndAmbush();
	}

	private void OnDestroy()
	{
		if ((Object)(object)material != (Object)null)
		{
			Object.Destroy((Object)(object)material);
		}
	}
}