using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using RoR2;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Networking;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.2.1.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.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 Local.Enemy.Variety
{
[BepInPlugin("local.enemy.variety", "EnemyVariety", "0.2.1")]
internal class Plugin : BaseUnityPlugin
{
public const string version = "0.2.1";
public const string identifier = "local.enemy.variety";
private static ConfigEntry<bool> boss;
private static ConfigEntry<float> horde;
protected async void Awake()
{
Harmony.CreateAndPatchAll(typeof(Plugin), (string)null);
boss = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Apply to Teleporter Boss", true, "If enabled, multiple types of bosses may appear for the teleporter event.");
horde = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Horde of Many", 5f, new ConfigDescription("Percent chance for a different type of enemy to be chosen instead.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>()));
CombatDirector[] componentsInChildren = (await Addressables.LoadAssetAsync<GameObject>((object)"RoR2/DLC2/ShrineHalcyonite.prefab").Task).GetComponentsInChildren<CombatDirector>();
for (int i = 0; i < componentsInChildren.Length; i++)
{
componentsInChildren[i].resetMonsterCardIfFailed = false;
}
}
[HarmonyPatch(typeof(CombatDirector), "AttemptSpawnOnTarget")]
[HarmonyPrefix]
private static void ResetMonsterCard(CombatDirector __instance, ref bool __state)
{
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
ref DirectorCard currentMonsterCard = ref __instance.currentMonsterCard;
WeightedSelection<DirectorCard> finalMonsterCardsSelection = __instance.finalMonsterCardsSelection;
__state = false;
if (!__instance.resetMonsterCardIfFailed || currentMonsterCard == null || finalMonsterCardsSelection == null)
{
return;
}
ChoiceInfo<DirectorCard>[] choices = finalMonsterCardsSelection.choices;
for (int i = 0; i < choices.Length; i++)
{
ChoiceInfo<DirectorCard> val = choices[i];
if (!object.Equals(currentMonsterCard, val.value) || val.weight <= 0f || currentMonsterCard.cost <= 0)
{
continue;
}
int spawnCountInCurrentWave = __instance.spawnCountInCurrentWave;
int cost = currentMonsterCard.cost;
Xoroshiro128Plus rng = __instance.rng;
do
{
if ((Object)(object)__instance == (Object)(object)TeleporterInteraction.instance?.bossDirector)
{
if (!boss.Value)
{
break;
}
__instance.SetNextSpawnAsBoss();
__state = spawnCountInCurrentWave == 0 || (float)currentMonsterCard.cost <= __instance.monsterCredit;
}
else
{
float num = Mathf.Min(800f, __instance.monsterCredit);
do
{
currentMonsterCard = finalMonsterCardsSelection.Evaluate(rng.nextNormalizedFloat);
}
while ((float)currentMonsterCard.cost < rng.nextNormalizedFloat * num);
__instance.PrepareNewMonsterWave(currentMonsterCard);
}
}
while (currentMonsterCard.cost > cost && (float)currentMonsterCard.cost > __instance.monsterCredit);
__instance.spawnCountInCurrentWave = spawnCountInCurrentWave;
break;
}
}
[HarmonyPatch(typeof(CombatDirector), "AttemptSpawnOnTarget")]
[HarmonyPostfix]
private static void RetryIfNodePlacementFailed(bool __state, ref bool __result)
{
__result |= __state;
}
[HarmonyPatch(typeof(ChargingState), "OnEnter")]
[HarmonyPostfix]
private static void SummonTheHorde(ChargingState __instance)
{
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_008a: Unknown result type (might be due to invalid IL or missing references)
if (!NetworkServer.active)
{
return;
}
CombatDirector bossDirector = __instance.bossDirector;
if (!Object.op_Implicit((Object)(object)bossDirector))
{
return;
}
WeightedSelection<DirectorCard> finalMonsterCardsSelection = bossDirector.finalMonsterCardsSelection;
if (finalMonsterCardsSelection == null || bossDirector.rng.nextNormalizedFloat >= horde.Value / 100f)
{
return;
}
WeightedSelection<DirectorCard> val = new WeightedSelection<DirectorCard>(8);
for (int i = 0; i < finalMonsterCardsSelection.Count; i++)
{
ChoiceInfo<DirectorCard> choice = finalMonsterCardsSelection.GetChoice(i);
DirectorCard value = choice.value;
if (value.IsAvailable() && !value.spawnCard.prefab.GetComponent<CharacterMaster>().bodyPrefab.GetComponent<CharacterBody>().isChampion)
{
val.AddChoice(choice);
}
}
if (val.totalWeight > 0f && val.Count > 0)
{
bossDirector.currentMonsterCard = null;
bossDirector.monsterCardsSelection = val;
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(Chat), "SendBroadcastChat", new Type[] { typeof(ChatMessageBase) })]
private static void ChangeMessage(ChatMessageBase message)
{
SubjectFormatChatMessage val = (SubjectFormatChatMessage)(object)((message is SubjectFormatChatMessage) ? message : null);
if (val != null)
{
bool? flag = val.paramTokens?.Any();
if (flag.HasValue && flag.GetValueOrDefault() && ((SubjectChatMessage)val).baseToken == "SHRINE_COMBAT_USE_MESSAGE")
{
val.paramTokens[0] = Language.GetString("LOGBOOK_CATEGORY_MONSTER").ToLower();
}
}
}
[HarmonyPatch(typeof(BossGroup), "UpdateBossMemories")]
[HarmonyPostfix]
private static void UpdateTitle(BossGroup __instance)
{
if (!boss.Value)
{
return;
}
Dictionary<(string, string), float> dictionary = new Dictionary<(string, string), float>();
float num = 0f;
for (int i = 0; i < __instance.bossMemoryCount; i++)
{
CharacterBody cachedBody = __instance.bossMemories[i].cachedBody;
if (!Object.op_Implicit((Object)(object)cachedBody))
{
continue;
}
HealthComponent healthComponent = cachedBody.healthComponent;
if (!(((healthComponent != null) ? new bool?(healthComponent.alive) : null) ?? true))
{
continue;
}
string bestBodyName = Util.GetBestBodyName(((Component)cachedBody).gameObject);
string text = cachedBody.GetSubtitle();
(string, string) key = (bestBodyName, text);
if (!dictionary.ContainsKey(key))
{
dictionary[key] = 0f;
}
dictionary[key] += healthComponent.combinedHealth + healthComponent.missingCombinedHealth * 4f;
if (dictionary[key] > num)
{
num = dictionary[key];
if (string.IsNullOrEmpty(text))
{
text = Language.GetString("NULL_SUBTITLE");
}
__instance.bestObservedName = bestBodyName;
__instance.bestObservedSubtitle = "<sprite name=\"CloudLeft\" tint=1> " + text + " <sprite name=\"CloudRight\" tint=1>";
}
}
}
[HarmonyPatch(typeof(CombatDirector), "SpendAllCreditsOnMapSpawns")]
[HarmonyPrefix]
private static void PopulateScene(CombatDirector __instance, ref bool __state)
{
__state = __instance.resetMonsterCardIfFailed;
if (SceneCatalog.mostRecentSceneDef.stageOrder > Run.stagesPerLoop)
{
__instance.resetMonsterCardIfFailed = false;
}
}
[HarmonyPatch(typeof(CombatDirector), "SpendAllCreditsOnMapSpawns")]
[HarmonyPostfix]
private static void RestoreValue(CombatDirector __instance, bool __state)
{
__instance.resetMonsterCardIfFailed = __state;
}
}
}