Decompiled source of MecchaModel v0.1.0

BepInEx/plugins/MecchaModel.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using GameNetcodeStuff;
using Microsoft.CodeAnalysis;
using ModelReplacement;
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: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyCompany("MecchaModel")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("MecchaModel")]
[assembly: AssemblyTitle("MecchaModel")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 MecchaModel
{
	public class MRMECCHA : BodyReplacementBase
	{
		private MecchaRosto rosto;

		protected override GameObject LoadAssetsAndReturnModel()
		{
			return Assets.MainAssetBundle.LoadAsset<GameObject>("Meccha");
		}

		protected override void AddModelScripts()
		{
			((BodyReplacementBase)this).AddModelScripts();
			rosto = base.replacementModel.AddComponent<MecchaRosto>();
			rosto.owner = this;
		}

		protected override void OnEmoteStart(int emoteId)
		{
			((BodyReplacementBase)this).OnEmoteStart(emoteId);
			if (Object.op_Implicit((Object)(object)rosto))
			{
				rosto.emoting = true;
			}
		}

		protected override void OnEmoteEnd()
		{
			((BodyReplacementBase)this).OnEmoteEnd();
			if (Object.op_Implicit((Object)(object)rosto))
			{
				rosto.emoting = false;
			}
		}

		protected override void OnDamageTaken(bool dead)
		{
			((BodyReplacementBase)this).OnDamageTaken(dead);
			if (Object.op_Implicit((Object)(object)rosto) && !dead)
			{
				rosto.Startle();
			}
		}
	}
	public class MecchaRosto : MonoBehaviour
	{
		public MRMECCHA owner;

		public bool emoting;

		private float startleUntil;

		private float nextBlink;

		private float blinkT = -1f;

		private float blep;

		private float nervosa;

		private readonly List<(SkinnedMeshRenderer r, int piscarL, int piscarR, int blep, int nervosa)> rends = new List<(SkinnedMeshRenderer, int, int, int, int)>();

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

		private float lastGlow = -1f;

		private void Start()
		{
			SkinnedMeshRenderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<SkinnedMeshRenderer>(true);
			foreach (SkinnedMeshRenderer val in componentsInChildren)
			{
				Mesh sharedMesh = val.sharedMesh;
				if ((Object)(object)sharedMesh == (Object)null || sharedMesh.blendShapeCount == 0)
				{
					continue;
				}
				rends.Add((val, sharedMesh.GetBlendShapeIndex("exp_Piscar.L"), sharedMesh.GetBlendShapeIndex("exp_Piscar.R"), sharedMesh.GetBlendShapeIndex("exp_Blep"), sharedMesh.GetBlendShapeIndex("exp_Nervosa")));
				Material[] materials = ((Renderer)val).materials;
				foreach (Material val2 in materials)
				{
					if ((Object)(object)val2 != (Object)null && ((Object)val2).name.StartsWith("MCG_Pele"))
					{
						eyeMats.Add(val2);
					}
				}
			}
			nextBlink = Time.time + Random.Range(2f, 5f);
		}

		public void Startle()
		{
			startleUntil = Time.time + 2.5f;
		}

		private static void Set(SkinnedMeshRenderer r, int i, float w)
		{
			if (i >= 0)
			{
				r.SetBlendShapeWeight(i, w);
			}
		}

		private void LateUpdate()
		{
			//IL_030d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0314: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB val = (((Object)(object)owner != (Object)null) ? ((BodyReplacementBase)owner).controller : null);
			float deltaTime = Time.deltaTime;
			float num = 0f;
			if (Plugin.blink.Value)
			{
				if (blinkT < 0f && Time.time >= nextBlink)
				{
					blinkT = 0f;
				}
				if (blinkT >= 0f)
				{
					blinkT += deltaTime;
					num = ((blinkT < 0.07f) ? (blinkT / 0.07f) : ((blinkT < 0.12f) ? 1f : (1f - (blinkT - 0.12f) / 0.1f)));
					if (blinkT > 0.22f)
					{
						blinkT = -1f;
						num = 0f;
						nextBlink = Time.time + Random.Range(2.5f, 6f);
						if (Random.value < 0.15f)
						{
							nextBlink = Time.time + 0.25f;
						}
					}
				}
			}
			bool flag = (Object)(object)val != (Object)null && val.isPlayerDead;
			if (flag)
			{
				num = 1f;
			}
			bool flag2 = (Object)(object)val != (Object)null && !flag && val.health <= Plugin.nervousHealth.Value;
			float num2 = ((Plugin.nervousOnDamage.Value && (Time.time < startleUntil || flag2)) ? 1f : 0f);
			float num3 = ((Plugin.blepOnEmote.Value && emoting) ? 1f : 0f);
			nervosa = Mathf.MoveTowards(nervosa, num2, deltaTime * 5f);
			blep = Mathf.MoveTowards(blep, num3, deltaTime * 6f);
			if (nervosa > 0.5f)
			{
				num *= 0.3f;
			}
			foreach (var (val2, i, i2, i3, i4) in rends)
			{
				if (!((Object)(object)val2 == (Object)null))
				{
					Set(val2, i, num * 100f);
					Set(val2, i2, num * 100f);
					Set(val2, i3, blep * 100f);
					Set(val2, i4, nervosa * 100f);
				}
			}
			float num4 = (((Object)(object)val != (Object)null && val.isInsideFactory) ? Plugin.eyeGlowInside.Value : Plugin.eyeGlowOutside.Value);
			if (flag)
			{
				num4 = 0f;
			}
			if (Mathf.Approximately(num4, lastGlow))
			{
				return;
			}
			foreach (Material eyeMat in eyeMats)
			{
				if ((Object)(object)eyeMat != (Object)null)
				{
					eyeMat.SetColor("_EmissiveColor", Color.white * num4);
				}
			}
			lastGlow = num4;
		}
	}
	[BepInPlugin("com.tavin.mecchamodel", "MecchaModel", "0.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string GUID = "com.tavin.mecchamodel";

		public static ConfigFile config;

		public static ConfigEntry<bool> enableModelForAllSuits { get; private set; }

		public static ConfigEntry<bool> enableModelAsDefault { get; private set; }

		public static ConfigEntry<string> suitNamesToEnableModel { get; private set; }

		public static ConfigEntry<bool> blink { get; private set; }

		public static ConfigEntry<bool> blepOnEmote { get; private set; }

		public static ConfigEntry<bool> nervousOnDamage { get; private set; }

		public static ConfigEntry<int> nervousHealth { get; private set; }

		public static ConfigEntry<float> eyeGlowInside { get; private set; }

		public static ConfigEntry<float> eyeGlowOutside { get; private set; }

		private static void InitConfig()
		{
			enableModelForAllSuits = config.Bind<bool>("Suits to Replace Settings", "Enable Model for all Suits", false, "Enable to model replace every suit. Set to false to specify suits");
			enableModelAsDefault = config.Bind<bool>("Suits to Replace Settings", "Enable Model as default", false, "Enable to model replace every suit that hasn't been otherwise registered.");
			suitNamesToEnableModel = config.Bind<string>("Suits to Replace Settings", "Suits to enable Model for", "Meccha", "Enter a comma separated list of suit names.(Additionally, [Default,Orange suit,Green suit,Pajama suit,Hazard suit])");
			blink = config.Bind<bool>("Face", "Blink", true, "Meccha blinks every few seconds.");
			blepOnEmote = config.Bind<bool>("Face", "Blep on emote", true, "Tongue out (blep) while emoting.");
			nervousOnDamage = config.Bind<bool>("Face", "Nervous when hurt", true, "Wide eyes and sweat drops for a moment after taking damage, and while health is low.");
			nervousHealth = config.Bind<int>("Face", "Nervous health threshold", 30, "Health at or below which she stays nervous.");
			eyeGlowInside = config.Bind<float>("Eyes", "Glow inside the facility", 1f, "Eye glow strength inside the facility (0 = off). The eyes glow in the dark.");
			eyeGlowOutside = config.Bind<float>("Eyes", "Glow outside", 0f, "Eye glow strength on the ship and outside.");
		}

		private void Awake()
		{
			config = ((BaseUnityPlugin)this).Config;
			InitConfig();
			Assets.PopulateAssets();
			if (enableModelForAllSuits.Value)
			{
				ModelReplacementAPI.RegisterModelReplacementOverride(typeof(MRMECCHA));
			}
			if (enableModelAsDefault.Value)
			{
				ModelReplacementAPI.RegisterModelReplacementDefault(typeof(MRMECCHA));
			}
			string[] array = suitNamesToEnableModel.Value.Split(',');
			for (int i = 0; i < array.Length; i++)
			{
				string text = array[i].Trim();
				if (text.Length > 0)
				{
					ModelReplacementAPI.RegisterSuitModelReplacement(text, typeof(MRMECCHA));
				}
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("Plugin {0} is loaded! bundle={1}", "com.tavin.mecchamodel", (Object)(object)Assets.MainAssetBundle != (Object)null));
		}
	}
	public static class Assets
	{
		public static string mainAssetBundleName = "mecchabundle";

		public static AssetBundle MainAssetBundle = null;

		private static string GetAssemblyName()
		{
			return Assembly.GetExecutingAssembly().GetName().Name.Replace(" ", "_");
		}

		public static void PopulateAssets()
		{
			if ((Object)(object)MainAssetBundle != (Object)null)
			{
				return;
			}
			using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(GetAssemblyName() + "." + mainAssetBundleName);
			if (stream == null)
			{
				Console.WriteLine("MecchaModel: embedded asset bundle not found");
			}
			else
			{
				MainAssetBundle = AssetBundle.LoadFromStream(stream);
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}