Decompiled source of GokuBracken v1.5.9

GokuBracken.dll

Decompiled 3 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GokuBracken.Core;
using GokuBracken.Patches;
using GokuBracken.Scripts;
using HarmonyLib;
using UnityEngine;
using UnityEngine.Video;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("GokuBracken")]
[assembly: AssemblyDescription("A mod for Lethal Company that replaces the bracken's model with a model of Goku from the Tenkaichi games")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Vulf")]
[assembly: AssemblyProduct("GokuBracken")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("50feedfa-5dd6-4358-936e-87945c1a8cae")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.5.9.0")]
namespace GokuBracken.Scripts
{
	public class GokuController : MonoBehaviour
	{
		private FlowermanAI FlowermanAI { get; set; }

		private int Variant { get; set; }

		private int[] VariantWeights { get; set; }

		private string VariantName => Variant switch
		{
			0 => "Base Goku", 
			1 => "SSJ Goku", 
			2 => "God Goku", 
			3 => "SSB Goku", 
			_ => "Unknown", 
		};

		private string VariantAssetName => Variant switch
		{
			0 => "baseGokuUnlitPrefab", 
			1 => "ssjGokuPrefab", 
			2 => "godGokuPrefab", 
			3 => "ssbGokuPrefab", 
			_ => "Unknown", 
		};

		private Aura VariantAura => Variant switch
		{
			0 => new Aura(Color.white, Color.black, Color.white, Color.white), 
			1 => new Aura(Color32.op_Implicit(new Color32(byte.MaxValue, (byte)142, (byte)0, byte.MaxValue)), Color32.op_Implicit(new Color32(byte.MaxValue, (byte)216, (byte)0, byte.MaxValue)), Color32.op_Implicit(new Color32(byte.MaxValue, (byte)142, (byte)0, byte.MaxValue)), Color32.op_Implicit(new Color32(byte.MaxValue, (byte)142, (byte)0, byte.MaxValue))), 
			2 => new Aura(Color32.op_Implicit(new Color32(byte.MaxValue, (byte)76, (byte)0, byte.MaxValue)), Color32.op_Implicit(new Color32(byte.MaxValue, (byte)76, (byte)0, byte.MaxValue)), Color32.op_Implicit(new Color32(byte.MaxValue, (byte)0, (byte)0, byte.MaxValue)), Color32.op_Implicit(new Color32(byte.MaxValue, (byte)58, (byte)0, byte.MaxValue))), 
			3 => new Aura(Color32.op_Implicit(new Color32((byte)0, (byte)132, byte.MaxValue, byte.MaxValue)), Color32.op_Implicit(new Color32((byte)85, (byte)172, byte.MaxValue, byte.MaxValue)), Color32.op_Implicit(new Color32((byte)0, (byte)137, byte.MaxValue, byte.MaxValue)), Color32.op_Implicit(new Color32((byte)66, (byte)172, byte.MaxValue, byte.MaxValue))), 
			_ => default(Aura), 
		};

		private GameObject BaseGokuObject { get; set; }

		private GameObject SecondaryGokuObject { get; set; }

		private GameObject GokuEyesObject { get; set; }

		private GameObject AuraObject { get; set; }

		private bool IsAttacking { get; set; }

		private bool IsDead { get; set; }

		private void Start()
		{
			FlowermanAI = ((Component)this).GetComponent<FlowermanAI>();
			VariantWeights = new int[4] { 50, 30, 15, 5 };
			int seed = StartOfRound.Instance.randomMapSeed + Mathf.RoundToInt(StartOfRound.Instance.timeSinceRoundStarted / 10f) * 10;
			SelectGokuVariant(seed);
			HideFlowermanModel();
			CreateGokuModels();
			ReplaceFlowermanSFX();
			UpdateScanNodeData();
			CreateAura();
		}

		private void Update()
		{
			//IL_000f: 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_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			Quaternion rotation = ((Component)StartOfRound.Instance.localPlayerController).transform.rotation;
			float num = ((Quaternion)(ref rotation)).eulerAngles.y - 180f;
			AuraObject.transform.rotation = Quaternion.Euler(0f, num, 0f);
			if (((EnemyAI)FlowermanAI).movingTowardsTargetPlayer && !IsAttacking)
			{
				EnterAttackState();
			}
			if (!((EnemyAI)FlowermanAI).movingTowardsTargetPlayer && IsAttacking)
			{
				ExitAttackState();
			}
			if (((EnemyAI)FlowermanAI).isEnemyDead && !IsDead)
			{
				KillGoku();
			}
		}

		private void HideFlowermanModel()
		{
			Renderer[] componentsInChildren = ((Component)((Component)FlowermanAI).transform.Find("FlowermanModel")).GetComponentsInChildren<Renderer>();
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].enabled = false;
			}
		}

		private void CreateGokuModels()
		{
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			GameObject asset = Assets.GetAsset<GameObject>("baseGokuPrefab");
			BaseGokuObject = Object.Instantiate<GameObject>(asset, ((Component)this).gameObject.transform);
			((Object)BaseGokuObject).name = "Base Goku";
			GameObject asset2 = Assets.GetAsset<GameObject>(VariantAssetName);
			SecondaryGokuObject = Object.Instantiate<GameObject>(asset2, ((Component)this).gameObject.transform);
			((Object)SecondaryGokuObject).name = VariantName;
			SecondaryGokuObject.SetActive(false);
			GameObject asset3 = Assets.GetAsset<GameObject>("gokuEyesPrefab");
			GokuEyesObject = Object.Instantiate<GameObject>(asset3, ((Component)this).gameObject.transform);
			GokuEyesObject.transform.localPosition = new Vector3(0f, 2.7f, 0f);
			((Object)GokuEyesObject).name = "GokuEyes";
		}

		private void ReplaceFlowermanSFX()
		{
			if (ConfigManager.UseMusic.Value)
			{
				FlowermanAI.creatureAngerVoice.clip = Assets.GetAsset<AudioClip>("aggressiveSFX");
			}
			if (ConfigManager.UseVoicelines.Value)
			{
				FlowermanAI.crackNeckSFX = Assets.GetAsset<AudioClip>("baseGokuKillSFX");
				FlowermanAI.crackNeckAudio.clip = Assets.GetAsset<AudioClip>("baseGokuKillSFX");
			}
		}

		private void UpdateScanNodeData()
		{
			((Component)FlowermanAI).GetComponentInChildren<ScanNodeProperties>().headerText = "Son Goku";
		}

		private void CreateAura()
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: 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_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: 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_00bf: 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_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: 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_00fa: 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)
			GameObject asset = Assets.GetAsset<GameObject>("auraPrefab");
			AuraObject = Object.Instantiate<GameObject>(asset, SecondaryGokuObject.transform);
			((Object)AuraObject).name = "Aura";
			MainModule main = ((Component)AuraObject.transform.Find("Outer")).GetComponent<ParticleSystem>().main;
			MainModule main2 = ((Component)AuraObject.transform.Find("Inner")).GetComponent<ParticleSystem>().main;
			MainModule main3 = ((Component)AuraObject.transform.Find("Inner Burst")).GetComponent<ParticleSystem>().main;
			MainModule main4 = ((Component)AuraObject.transform.Find("Bottom")).GetComponent<ParticleSystem>().main;
			((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(VariantAura.OuterColor);
			((MainModule)(ref main2)).startColor = MinMaxGradient.op_Implicit(VariantAura.InnerColor);
			((MainModule)(ref main3)).startColor = MinMaxGradient.op_Implicit(VariantAura.InnerBurstColor);
			((MainModule)(ref main4)).startColor = MinMaxGradient.op_Implicit(VariantAura.BottomColor);
		}

		private void EnterAttackState()
		{
			BaseGokuObject.SetActive(false);
			SecondaryGokuObject.SetActive(true);
			IsAttacking = true;
		}

		private void ExitAttackState()
		{
			BaseGokuObject.SetActive(true);
			SecondaryGokuObject.SetActive(false);
			IsAttacking = false;
		}

		private void KillGoku()
		{
			//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_0047: 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_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: 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)
			GokuEyesObject.SetActive(false);
			BaseGokuObject.SetActive(true);
			SecondaryGokuObject.SetActive(false);
			Transform transform = BaseGokuObject.transform;
			Quaternion rotation = BaseGokuObject.transform.rotation;
			float y = ((Quaternion)(ref rotation)).eulerAngles.y;
			rotation = BaseGokuObject.transform.rotation;
			transform.rotation = Quaternion.Euler(-90f, y, ((Quaternion)(ref rotation)).eulerAngles.z);
			if (ConfigManager.UseDeathSound.Value)
			{
				Object.Destroy((Object)(object)Object.Instantiate<GameObject>(Assets.GetAsset<GameObject>("soundContainerPrefab"), BaseGokuObject.transform), 40f);
			}
			IsDead = true;
		}

		private void SelectGokuVariant(int seed)
		{
			Random random = new Random(seed);
			if (VariantWeights.Length == 0)
			{
				Variant = 0;
				return;
			}
			int num = 0;
			for (int i = 0; i < VariantWeights.Length; i++)
			{
				num += VariantWeights[i];
			}
			int num2 = random.Next(0, num);
			for (int j = 0; j < VariantWeights.Length; j++)
			{
				if (num2 < VariantWeights[j])
				{
					Variant = j;
					return;
				}
				num2 -= VariantWeights[j];
			}
			Variant = 0;
		}
	}
	public struct Aura
	{
		public Color OuterColor { get; set; }

		public Color InnerColor { get; set; }

		public Color InnerBurstColor { get; set; }

		public Color BottomColor { get; set; }

		public Aura(Color outerColor, Color innerColor, Color innerBurstColor, Color bottomColor)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			OuterColor = outerColor;
			InnerColor = innerColor;
			InnerBurstColor = innerBurstColor;
			BottomColor = bottomColor;
		}
	}
}
namespace GokuBracken.Patches
{
	[HarmonyPatch]
	internal class EnemyPatches
	{
		[HarmonyPatch(typeof(FlowermanAI), "Start")]
		[HarmonyPostfix]
		public static void CreateGokuModel(FlowermanAI __instance)
		{
			((Component)__instance).gameObject.AddComponent<GokuController>();
		}
	}
	[HarmonyPatch]
	internal class RoundManagementPatches
	{
		private static Transform CardObject { get; set; }

		[HarmonyPatch(typeof(RoundManager), "GenerateNewLevelClientRpc")]
		[HarmonyPostfix]
		public static void GameStart(RoundManager __instance, int randomSeed, int levelID)
		{
			//IL_003e: 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_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			if (levelID == 0)
			{
				if ((Object)(object)CardObject == (Object)null)
				{
					CardObject = Object.Instantiate<GameObject>(Assets.GetAsset<GameObject>("cardsPrefab")).transform;
				}
				CardObject.position = new Vector3(-37f, 0.94f, -40.84f);
				CardObject.rotation = Quaternion.Euler(new Vector3(0f, 196f, 0f));
				CardObject.localScale = new Vector3(0.15f, 0.15f, 0.15f);
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "EndOfGame")]
		[HarmonyPostfix]
		public static void GameEnd(StartOfRound __instance)
		{
			if ((Object)(object)CardObject != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)CardObject).gameObject);
			}
		}
	}
	[HarmonyPatch]
	internal class TerminalPatches
	{
		[HarmonyPatch(typeof(Terminal), "Start")]
		[HarmonyPostfix]
		public static void EditTerminal(Terminal __instance)
		{
			int index = __instance.enemyFiles.FindIndex((TerminalNode e) => ((Object)e).name == "BrackenFile");
			int num = __instance.terminalNodes.allKeywords.ToList().FindIndex((TerminalKeyword e) => ((Object)e).name == "Bracken");
			__instance.enemyFiles[index].creatureName = "Son Goku";
			__instance.enemyFiles[index].displayText = "Hey, you!\nI think it's about time I got a chance to fight.\n";
			__instance.enemyFiles[index].displayVideo = Assets.GetAsset<VideoClip>("gokuLogVideo");
			__instance.terminalNodes.allKeywords[num].word = "goku";
		}
	}
}
namespace GokuBracken.Core
{
	internal static class Assets
	{
		public static AssetBundle AssetBundle { get; private set; }

		private static Dictionary<string, Object> AssetList { get; set; }

		private static string AssemblyName => Assembly.GetExecutingAssembly().FullName.Split(new char[1] { ',' })[0];

		public static void PopulateAssets()
		{
			if ((Object)(object)AssetBundle != (Object)null)
			{
				Logger.LogWarning("Attempted to load the asset bundle but the bundle was not null!");
				return;
			}
			string name = AssemblyName + ".Bundle.gokubracken";
			using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(name))
			{
				AssetBundle = AssetBundle.LoadFromStream(stream);
			}
			if ((Object)(object)AssetBundle == (Object)null)
			{
				Logger.LogError("Asset bundle at " + AssemblyName + ".gokubracken failed to load!");
			}
			AssetList = new Dictionary<string, Object>();
			Object[] array = AssetBundle.LoadAllAssets();
			foreach (Object val in array)
			{
				AssetList.Add(val.name, val);
			}
		}

		public static T GetAsset<T>(string name) where T : Object
		{
			if (!AssetList.TryGetValue(name, out var value))
			{
				Logger.LogError("Attempted to load asset of name " + name + " but no asset of that name exists!");
				return default(T);
			}
			T val = (T)(object)((value is T) ? value : null);
			if ((Object)(object)val == (Object)null)
			{
				Logger.LogError("Attempted to load an asset of type " + typeof(T).Name + " but asset of name " + name + " does not match this type!");
				return default(T);
			}
			return val;
		}
	}
	internal static class ConfigManager
	{
		public static ConfigEntry<bool> UseSkinVariants { get; private set; }

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

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

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

		private static ConfigFile Config => GokuBrackenBase.ModConfig;

		public static void InitializeConfig()
		{
			UseSkinVariants = Config.Bind<bool>("Skin Variants", "Use Skin Variants", true, "Controls whether or not to give Goku the chance to spawn as a different form");
			UseVoicelines = Config.Bind<bool>("Sound", "Use Goku Voicelines", true, "Controls whether or not to replace the bracken's kill sound with Goku voicelines");
			UseMusic = Config.Bind<bool>("Sound", "Use UI Music", true, "Controls whether or not to replace the bracken's agressive sound with the Ultra Instinct theme");
			UseDeathSound = Config.Bind<bool>("Sound", "Use Death Sound", true, "Controls whether or not to play a sound on the bracken's death");
		}
	}
	internal static class Logger
	{
		public static void LogInfo(object message)
		{
			GokuBrackenBase.LogSource.LogInfo(message);
		}

		public static void LogWarning(object message)
		{
			GokuBrackenBase.LogSource.LogWarning(message);
		}

		public static void LogError(object message)
		{
			GokuBrackenBase.LogSource.LogError(message);
		}
	}
	[BepInPlugin("Vulf.GokuBracken", "Goku Bracken", "1.5.8")]
	public class GokuBrackenBase : BaseUnityPlugin
	{
		private static GokuBrackenBase _instance;

		private readonly Harmony Harmony = new Harmony("Vulf.GokuBracken");

		internal static GokuBrackenBase Instance
		{
			get
			{
				return _instance;
			}
			set
			{
				if ((Object)(object)_instance == (Object)null)
				{
					_instance = value;
				}
				else
				{
					Object.Destroy((Object)(object)value);
				}
			}
		}

		public static ManualLogSource LogSource => ((BaseUnityPlugin)Instance).Logger;

		public static ConfigFile ModConfig => ((BaseUnityPlugin)Instance).Config;

		private void Awake()
		{
			Instance = this;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Initializing config...");
			ConfigManager.InitializeConfig();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Loading asset bundle...");
			Assets.PopulateAssets();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Hey it's me! Goku!");
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Your files look pretty strong! I'm gonna patch them!");
			Harmony.PatchAll(typeof(GokuBrackenBase));
			Harmony.PatchAll(typeof(EnemyPatches));
			Harmony.PatchAll(typeof(TerminalPatches));
			Harmony.PatchAll(typeof(RoundManagementPatches));
		}
	}
	internal static class PluginInfo
	{
		public const string GUID = "Vulf.GokuBracken";

		public const string NAME = "Goku Bracken";

		public const string VERSION = "1.5.8";

		public const string ASSET_BUNDLE_NAME = "gokubracken";
	}
}