using System;
using System.Collections;
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 System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Newtonsoft.Json;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("PissyEnemies")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("PissyEnemies")]
[assembly: AssemblyCopyright("Copyright © 2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("9d9d3f61-800f-4c7e-987b-5b816a6b0169")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace PissyEnemies;
internal class CustomRager : MonoBehaviour
{
public string ragingInfoComponent;
public string ragingInfoEnemy;
public float ragingInfoVolume;
public List<AudioClip> ragingInfoClips;
public int ragingInfoTauntCount;
private bool eternalTaunt;
public AudioSource audiosource;
public AudioSource audiosourceOG;
private EnemyIdentifier enemyIdentifier;
private object enemyScript;
private PropertyInfo enraged;
private bool canTaunt = true;
private bool canEnrage = true;
private List<AudioClip> unusedTaunts;
private int tauntCountdown;
private void Awake()
{
audiosourceOG = ((Component)this).GetComponent<AudioSource>();
audiosource = ((Component)this).gameObject.AddComponent<AudioSource>();
enemyIdentifier = ((Component)this).gameObject.GetComponent<EnemyIdentifier>();
unusedTaunts = new List<AudioClip>();
}
private void Start()
{
//IL_0176: Unknown result type (might be due to invalid IL or missing references)
//IL_017c: Expected O, but got Unknown
audiosource.playOnAwake = false;
audiosource.outputAudioMixerGroup = MonoSingleton<AudioMixerController>.instance.allGroup;
audiosource.minDistance = 8f;
audiosource.spatialBlend = 1f;
audiosource.clip = ragingInfoClips[0];
audiosource.volume = ragingInfoVolume;
audiosource.maxDistance = Plugin.maxDistance.Value;
audiosource.dopplerLevel = Plugin.doppler.Value;
ragingInfoClips.ForEach(delegate(AudioClip x)
{
unusedTaunts.Add(x);
});
try
{
enemyScript = ((Component)this).gameObject.GetComponents(typeof(Component)).ToList().Find((Component x) => ((object)x).GetType().Name == ragingInfoComponent);
enraged = enemyScript.GetType().GetProperty("isEnraged");
}
catch (Exception ex)
{
Debug.LogError((object)("There's been an error while getting the enemy script component for \"" + ragingInfoEnemy + "\" (" + ragingInfoComponent + ") and enraged property! This is most likely caused by trying to add a CustomRager to an unenragable enemy. To solve this, please check your PissyEnemies.json and correct it.\n" + ex.Message));
Object.Destroy((Object)(object)this);
}
eternalTaunt = ragingInfoTauntCount < 0;
tauntCountdown = ragingInfoTauntCount;
UnityAction val = (UnityAction)delegate
{
audiosource.Stop();
};
enemyIdentifier.onDeath.AddListener(val);
}
private void LateUpdate()
{
if (!enemyIdentifier.dead)
{
bool flag;
try
{
flag = (bool)enraged.GetValue(enemyScript);
}
catch
{
flag = false;
}
if (flag && !canTaunt && !audiosource.isPlaying)
{
canTaunt = true;
}
else if (audiosource.isPlaying)
{
canTaunt = false;
}
if (canTaunt)
{
EnrageTaunt(ragingInfoClips);
}
else if (!flag)
{
audiosource.Stop();
}
if (tauntCountdown <= 0 && !flag)
{
tauntCountdown = ragingInfoTauntCount;
}
}
}
public void EnrageTaunt(List<AudioClip> clips)
{
if (tauntCountdown <= 0 && !eternalTaunt)
{
return;
}
if (clips.Count > 1)
{
if (unusedTaunts.Count == 0)
{
ragingInfoClips.ForEach(delegate(AudioClip x)
{
unusedTaunts.Add(x);
});
}
int index = Random.Range(0, unusedTaunts.Count);
audiosource.PlayOneShot(unusedTaunts[index]);
unusedTaunts.RemoveAt(index);
}
else
{
audiosource.Play();
}
if (!eternalTaunt)
{
tauntCountdown--;
}
}
}
public class RagingInfo : MonoBehaviour
{
public string component { get; set; }
public string enemy { get; set; }
public List<AudioClip> clips { get; set; }
public float volume { get; set; }
public int tauntcount { get; set; }
public RagingInfo(string component, List<AudioClip> clips, string enemy, string volume, int tauntcount)
{
this.component = component;
this.enemy = enemy;
this.clips = clips;
this.volume = (float.TryParse(volume, out var _) ? float.Parse(volume) : Plugin.volume.Value);
this.tauntcount = tauntcount;
}
public RagingInfo(RagingInfo ri)
{
component = ri.component;
clips = ri.clips;
enemy = ri.enemy;
volume = ri.volume;
tauntcount = ri.tauntcount;
}
public RagingInfo()
{
}
}
[HarmonyPatch(typeof(EnemyIdentifier))]
[HarmonyPatch("Start")]
public static class EnemyIdentifier_Start_Patch
{
[HarmonyPostfix]
private static void Postfix(EnemyIdentifier __instance)
{
GameObject gameObject = ((Component)__instance).gameObject;
Debug.Log((object)gameObject);
List<Component> list = gameObject.GetComponents<Component>().ToList();
bool flag = false;
foreach (Component item in list)
{
try
{
foreach (RagingInfo enemy in Plugin.enemies)
{
if (enemy.component.Equals(((object)item).GetType().Name) && enemy.enemy.Equals(((object)(EnemyType)(ref __instance.enemyType)).ToString()))
{
CustomRager customRager = ((Component)__instance).gameObject.AddComponent<CustomRager>();
customRager.ragingInfoComponent = enemy.component;
customRager.ragingInfoEnemy = enemy.enemy;
customRager.ragingInfoClips = enemy.clips;
customRager.ragingInfoVolume = enemy.volume;
customRager.ragingInfoTauntCount = enemy.tauntcount;
flag = true;
break;
}
}
}
catch
{
Debug.Log((object)("Error trying to find enemy component for " + ((object)(EnemyType)(ref __instance.enemyType)).ToString()));
break;
}
if (flag)
{
break;
}
}
}
}
[BepInPlugin("simonciott.ultrakill.pissyenemies", "PissyEnemies", "1.0.0")]
public class Plugin : BaseUnityPlugin
{
private const string modGUID = "simonciott.ultrakill.pissyenemies";
private const string modName = "PissyEnemies";
private const string modVersion = "1.0.0";
private const string easteregg = "SONO PARANOICO ED OSSESSIVO FINO ALL'ABIURA DI ME";
private static readonly Harmony Harmony = new Harmony("simonciott.ultrakill.pissyenemies");
public static readonly string pissyEnemiesPath;
public static readonly string pissyEnemiesPathConfig;
public static readonly string lastResortPath;
public static readonly List<string> supportedFormats;
public static List<RagingInfo> enemies;
public static List<RageData> enemiesData;
public static bool canRun;
public static bool isConfigPath;
public static ConfigEntry<float> maxDistance;
public static ConfigEntry<float> volume;
public static ConfigEntry<float> doppler;
public static string usedPath;
private void Awake()
{
Debug.Log((object)"PissyEnemies is loading...");
volume = ((BaseUnityPlugin)this).Config.Bind<float>("General", "volume", 1f, "The volume of the audio if the property in the json is null or invalid. Must be between 0 and 1");
maxDistance = ((BaseUnityPlugin)this).Config.Bind<float>("General", "maxDistance", 120f, "The maximum distance the sound can be hear from");
doppler = ((BaseUnityPlugin)this).Config.Bind<float>("General", "doppler", 0f, "Enhances the doppler effect. Must be between 0 and 1");
try
{
enemiesData = JsonConvert.DeserializeObject<List<RageData>>(File.ReadAllText(Path.Combine(pissyEnemiesPathConfig, "PissyEnemies.json")));
usedPath = pissyEnemiesPathConfig;
}
catch
{
Debug.Log((object)"Config path data failed to load or is missing. Trying to load original path.");
isConfigPath = false;
try
{
enemiesData = JsonConvert.DeserializeObject<List<RageData>>(File.ReadAllText(Path.Combine(pissyEnemiesPath, "PissyEnemies.json")));
usedPath = pissyEnemiesPath;
}
catch
{
Debug.Log((object)"Either paths are invalid. Trying out last resort.");
try
{
enemiesData = JsonConvert.DeserializeObject<List<RageData>>(File.ReadAllText(Path.Combine(lastResortPath, "PissyEnemies.json")));
usedPath = lastResortPath;
goto end_IL_00e6;
}
catch
{
Debug.LogError((object)"All possible data paths are missing. Impossible to load PissyEnemies data.");
canRun = false;
goto end_IL_00e6;
}
end_IL_00e6:;
}
}
if (canRun)
{
for (int i = 0; i < enemiesData.Count; i++)
{
((MonoBehaviour)this).StartCoroutine(LoadAudio(enemiesData[i].component, enemiesData[i].enemy, enemiesData[i].clips, enemiesData[i].volume, enemiesData[i].tauntcount, i));
}
Harmony.PatchAll();
Debug.Log((object)"PissyEnemies is loaded! But check the logs if all audio clips load!");
}
}
public static IEnumerator LoadAudio(string name, string enemy, List<string> filenames, string volume, int tauntcount, int index)
{
for (int i = 0; i < index; i++)
{
yield return null;
}
List<AudioClip> clips = new List<AudioClip>();
foreach (string filename in filenames)
{
UnityWebRequest request = GetAudioFromFile(filename, usedPath);
request.SendWebRequest();
while (!request.isDone)
{
yield return null;
}
try
{
if (request.isHttpError)
{
throw new Exception("http error.");
}
AudioClip clip = DownloadHandlerAudioClip.GetContent(request);
((Object)clip).name = "PissyEnemies_" + name + "_" + Path.GetFileNameWithoutExtension(filename);
clips.Add(clip);
Debug.Log((object)(((Object)clip).name + " has been loaded."));
}
catch (Exception e)
{
Debug.LogError((object)("failed to load " + filename + "!\n" + e.Message));
}
}
enemies.Add(new RagingInfo(name, clips, enemy, volume, tauntcount));
}
public static UnityWebRequest GetAudioFromFile(string filename, string dataPath)
{
try
{
if (!supportedFormats.Any((string x) => x == Path.GetExtension(filename)))
{
throw new Exception("file is of unsupported format.");
}
string text = Path.Combine("file://", dataPath);
string[] files = Directory.GetFiles(dataPath, filename, SearchOption.AllDirectories);
if (files.Length < 1)
{
throw new Exception("file doesn't exist.");
}
string text2 = files[0];
return UnityWebRequestMultimedia.GetAudioClip("file://" + text2, (AudioType)0);
}
catch (Exception ex)
{
Debug.LogError((object)("Failed to get audio file " + filename + "!\n" + ex.Message));
return null;
}
}
static Plugin()
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Expected O, but got Unknown
string? directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
char directorySeparatorChar = Path.DirectorySeparatorChar;
pissyEnemiesPath = Path.Combine(directoryName, "PissyEnemies" + directorySeparatorChar);
string configPath = Paths.ConfigPath;
directorySeparatorChar = Path.DirectorySeparatorChar;
pissyEnemiesPathConfig = Path.Combine(configPath, "PissyEnemies" + directorySeparatorChar);
string? directoryName2 = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
directorySeparatorChar = Path.DirectorySeparatorChar;
lastResortPath = directoryName2 + directorySeparatorChar;
supportedFormats = new string[3] { ".wav", ".mp3", ".ogg" }.ToList();
enemies = new List<RagingInfo>();
canRun = true;
isConfigPath = true;
}
}
public class RageData
{
public string component { get; set; }
public string enemy { get; set; }
public List<string> clips { get; set; }
public string volume { get; set; }
public int tauntcount { get; set; }
}