using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using AkechiBracken.Core;
using AkechiBracken.Patches;
using AkechiBracken.Scripts;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("AkechiBracken")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AkechiBracken")]
[assembly: AssemblyCopyright("Copyright © 2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("2f4869f2-4749-4b64-9b84-22f15eae6e4d")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace AkechiBracken.Scripts
{
public class AkechiController : MonoBehaviour
{
private FlowermanAI FlowermanAI { get; set; }
private GameObject DefaultAkechiObject { get; set; }
private GameObject AggressiveAkechiObject { get; set; }
private GameObject DeadAkechiObject { get; set; }
private bool IsDead { get; set; }
private AudioClip[] CrackNeckAudioClips { get; set; }
private int CrackNeckRandomIdx { get; set; }
private void Start()
{
FlowermanAI = ((Component)this).GetComponent<FlowermanAI>();
HideFlowermanModel();
CreateAkechiModels();
ReplaceFlowermanSFX();
UpdateScanNodeData();
}
private void Update()
{
if (((EnemyAI)FlowermanAI).isEnemyDead)
{
if (!IsDead)
{
KillAkechi();
}
}
else if (FlowermanAI.isInAngerMode)
{
EnterAttackState();
}
else
{
ExitAttackState();
}
}
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 CreateAkechiModels()
{
GameObject asset = Assets.GetAsset<GameObject>("AkechiBracken_Default_Prefab");
DefaultAkechiObject = Object.Instantiate<GameObject>(asset, ((Component)this).gameObject.transform);
((Object)DefaultAkechiObject).name = "Default Akechi";
GameObject asset2 = Assets.GetAsset<GameObject>("AkechiBracken_Aggressive_Prefab");
AggressiveAkechiObject = Object.Instantiate<GameObject>(asset2, ((Component)this).gameObject.transform);
((Object)AggressiveAkechiObject).name = "Aggressive Akechi";
GameObject asset3 = Assets.GetAsset<GameObject>("AkechiBracken_Death_Prefab");
DeadAkechiObject = Object.Instantiate<GameObject>(asset3, ((Component)this).gameObject.transform);
((Object)DeadAkechiObject).name = "Dead Akechi";
}
private void ReplaceFlowermanSFX()
{
if (ConfigManager.UseMusic.Value)
{
FlowermanAI.creatureAngerVoice.clip = Assets.GetAsset<AudioClip>("AkechiBracken_Aggressive_SFX");
}
if (ConfigManager.UseVoicelines.Value)
{
CrackNeckAudioClips = (AudioClip[])(object)new AudioClip[4];
CrackNeckAudioClips[0] = Assets.GetAsset<AudioClip>("AkechiBracken_CrackNeck1_SFX");
CrackNeckAudioClips[1] = Assets.GetAsset<AudioClip>("AkechiBracken_CrackNeck2_SFX");
CrackNeckAudioClips[2] = Assets.GetAsset<AudioClip>("AkechiBracken_CrackNeck3_SFX");
CrackNeckAudioClips[3] = Assets.GetAsset<AudioClip>("AkechiBracken_CrackNeck4_SFX");
CrackNeckRandomIdx = Random.Range(0, CrackNeckAudioClips.Length - 1);
FlowermanAI.crackNeckSFX = CrackNeckAudioClips[CrackNeckRandomIdx];
FlowermanAI.crackNeckAudio.clip = CrackNeckAudioClips[CrackNeckRandomIdx];
((EnemyAI)FlowermanAI).enemyBehaviourStates[0].VoiceClip = Assets.GetAsset<AudioClip>("AkechiBracken_Ambient_SFX");
((EnemyAI)FlowermanAI).enemyBehaviourStates[1].VoiceClip = Assets.GetAsset<AudioClip>("AkechiBracken_Voice_SFX");
((EnemyAI)FlowermanAI).enemyType.hitEnemyVoiceSFX = Assets.GetAsset<AudioClip>("AkechiBracken_Hit_SFX");
((EnemyAI)FlowermanAI).enemyType.stunSFX = Assets.GetAsset<AudioClip>("AkechiBracken_Stunned_SFX");
}
if (ConfigManager.UseDeathSound.Value)
{
((EnemyAI)FlowermanAI).dieSFX = Assets.GetAsset<AudioClip>("AkechiBracken_Death_SFX");
}
}
private void UpdateScanNodeData()
{
((Component)FlowermanAI).GetComponentInChildren<ScanNodeProperties>().headerText = "Goro Akechi";
}
private void EnterAttackState()
{
DefaultAkechiObject.SetActive(false);
AggressiveAkechiObject.SetActive(true);
}
private void ExitAttackState()
{
DefaultAkechiObject.SetActive(true);
AggressiveAkechiObject.SetActive(false);
}
private void KillAkechi()
{
DefaultAkechiObject.SetActive(false);
AggressiveAkechiObject.SetActive(false);
DeadAkechiObject.SetActive(true);
DeadAkechiObject.GetComponentInChildren<ParticleSystem>().Play();
((EnemyAI)FlowermanAI).enemyType.hitBodySFX = null;
((EnemyAI)FlowermanAI).enemyType.hitEnemyVoiceSFX = null;
IsDead = true;
}
}
}
namespace AkechiBracken.Patches
{
[HarmonyPatch]
internal class EnemyPatches
{
[HarmonyPatch(typeof(FlowermanAI), "Start")]
[HarmonyPostfix]
public static void CreateAkechiModel(FlowermanAI __instance)
{
((Component)__instance).gameObject.AddComponent<AkechiController>();
}
}
[HarmonyPatch]
internal class TerminalPatches
{
[HarmonyPatch(typeof(Terminal), "Awake")]
[HarmonyPostfix]
public static void EditTerminal(Terminal __instance)
{
__instance.enemyFiles[1].creatureName = "Goro Akechi";
__instance.enemyFiles[1].displayText = "Shut up, shut up, shut up! Teammates!? Friends!? To hell with that! Why am I inferior to you...!? I was extremely particular about my life, my grades, my public image, so someone would want me around! I am an ace detective... a celebrity! But you... You're just some criminal trash living in an attic! So how!? How does someone like you have things I don't!? How can such a worthless piece of trash be more special than me!?";
int num = -1;
for (int i = 0; i < __instance.terminalNodes.allKeywords.Length - 1; i++)
{
if (__instance.terminalNodes.allKeywords[i].word == "brackens")
{
num = i;
break;
}
}
if (num >= 0)
{
__instance.terminalNodes.allKeywords[num].word = "goro akechi";
}
else
{
Logger.LogWarning("AkechiBracken - Warning: Could not locate terminal keyword to swap 'Brackens' for 'Goro Akechi'! Terminal may not work correctly when parsing as a result.");
}
}
}
}
namespace AkechiBracken.Core
{
internal static class PluginInfo
{
public const string GUID = "Balaneo.AkechiBracken";
public const string NAME = "Akechi Bracken";
public const string VERSION = "1.0.0.0";
public const string ASSET_BUNDLE_NAME = "akechibracken";
}
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 => AkechiBrackenBase.ModConfig;
public static void InitializeConfig()
{
UseVoicelines = Config.Bind<bool>("Sound", "Use Akechi Voicelines", true, "Controls whether or not to replace the bracken's kill sound with Akechi voicelines");
UseMusic = Config.Bind<bool>("Sound", "Use UI Music", true, "Controls whether or not to replace the bracken's agressive sound with Akechis boss fight music");
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)
{
AkechiBrackenBase.LogSource.LogInfo(message);
}
public static void LogWarning(object message)
{
AkechiBrackenBase.LogSource.LogWarning(message);
}
public static void LogError(object message)
{
AkechiBrackenBase.LogSource.LogError(message);
}
}
[BepInPlugin("Balaneo.AkechiBracken", "Akechi Bracken", "1.0.0.0")]
public class AkechiBrackenBase : BaseUnityPlugin
{
private static AkechiBrackenBase _instance;
private readonly Harmony Harmony = new Harmony("Balaneo.AkechiBracken");
internal static AkechiBrackenBase Instance
{
get
{
return _instance;
}
set
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Expected O, but got Unknown
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Expected O, but got Unknown
if ((Object)_instance == (Object)null)
{
_instance = value;
}
else
{
Object.Destroy((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)"Goro Akechi has arrived!");
Harmony.PatchAll(typeof(AkechiBrackenBase));
Harmony.PatchAll(typeof(EnemyPatches));
Harmony.PatchAll(typeof(TerminalPatches));
}
}
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()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Expected O, but got Unknown
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_006d: Expected O, but got Unknown
if ((Object)AssetBundle != (Object)null)
{
Logger.LogWarning("Attempted to load the asset bundle but the bundle was not null!");
return;
}
string name = AssemblyName + ".Bundles.akechibracken";
using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(name))
{
AssetBundle = AssetBundle.LoadFromStream(stream);
}
if ((Object)AssetBundle == (Object)null)
{
Logger.LogError("Asset bundle at " + AssemblyName + ".akechibracken failed to load!");
}
AssetList = new Dictionary<string, Object>();
Object[] array = AssetBundle.LoadAllAssets();
Object[] array2 = array;
foreach (Object val in array2)
{
AssetList.Add(val.name, val);
}
}
public static T GetAsset<T>(string name) where T : Object
{
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: Expected O, but got Unknown
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)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;
}
}
}