using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
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: AssemblyCompany("GuaranteedCosmeticCrate")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("GuaranteedCosmeticCrate")]
[assembly: AssemblyTitle("GuaranteedCosmeticCrate")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace GuaranteedCosmeticCrate;
[BepInPlugin("nzoow.repo.guaranteedcosmeticcrate", "GuaranteedCosmeticCrate", "3.0.0")]
[BepInProcess("REPO.exe")]
public class GuaranteedCosmeticCratePlugin : BaseUnityPlugin
{
[HarmonyPatch(typeof(ValuableDirector))]
public static class ValuableDirectorPatch
{
[HarmonyPatch("SpawnCosmeticWorldObject")]
[HarmonyPrefix]
public unsafe static bool SpawnCosmeticWorldObjectPrefix(ref Rarity _cosmeticRarity)
{
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
//IL_00b2: 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_0107: Unknown result type (might be due to invalid IL or missing references)
//IL_0109: Expected I4, but got Unknown
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_008b: Unknown result type (might be due to invalid IL or missing references)
//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
if (isModSpawning)
{
return true;
}
if ((Object)(object)Instance != (Object)null && Instance.cfgVanillaSpawnEnabled != null && !Instance.cfgVanillaSpawnEnabled.Value)
{
Rarity val = (Rarity)0;
if (Instance.spawnOnly.Value)
{
if (Instance.onlyCommon.Value)
{
val = (Rarity)0;
}
else if (Instance.onlyUncommon.Value)
{
val = (Rarity)1;
}
else if (Instance.onlyRare.Value)
{
val = (Rarity)2;
}
else if (Instance.onlyUltraRare.Value)
{
val = (Rarity)3;
}
}
else
{
val = Instance.RollRarity(ValuableDirector.instance);
}
if (Log != null)
{
Log.LogWarning((object)("[MY_MOD] Intercepted vanilla box! Changed rarity from " + ((object)Unsafe.As(ref _cosmeticRarity)/*cast due to .constrained prefix*/).ToString() + " to " + ((object)(*(Rarity*)(&val))/*cast due to .constrained prefix*/).ToString() + ""));
}
_cosmeticRarity = (Rarity)(int)val;
}
return true;
}
[HarmonyPatch("Awake")]
[HarmonyPostfix]
public static void AwakePostfix(ValuableDirector __instance)
{
boxSpawnedThisRound = false;
if (Log != null)
{
Log.LogInfo((object)"[GuaranteedCrate] New round detected! Resetting spawn flags.");
}
if ((Object)(object)Instance != (Object)null && (Object)(object)__instance != (Object)null)
{
if (Log != null)
{
Log.LogInfo((object)"[GuaranteedCrate] Auto-triggering TryGuaranteeCrate from Awake Postfix...");
}
Instance.TryGuaranteeCrate(__instance);
}
}
}
internal static GuaranteedCosmeticCratePlugin Instance;
internal static ManualLogSource Log;
private Harmony harmony;
internal ConfigEntry cfgGuaranteedCrate;
internal ConfigEntry cfgSpawnChanceMultiplier;
internal ConfigEntry cfgRareMultiplier;
internal ConfigEntry cfgUltraRareMultiplier;
internal ConfigEntry cfgVerboseLogs;
private MethodInfo spawnMethod;
internal ConfigEntry cfgCommonMultiplier;
internal ConfigEntry cfgUncommonMultiplier;
internal ConfigEntry onlyCommon;
internal ConfigEntry onlyUncommon;
internal ConfigEntry onlyRare;
internal ConfigEntry onlyUltraRare;
internal ConfigEntry spawnOnly;
internal static bool boxSpawnedThisRound;
internal static bool isModSpawning;
internal ConfigEntry cfgVanillaSpawnEnabled;
private void Awake()
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Expected O, but got Unknown
Instance = this;
Log = ((BaseUnityPlugin)this).Logger;
BindConfig();
harmony = new Harmony("nzoow.repo.guaranteedcosmeticcrate");
harmony.PatchAll();
Type type = AccessTools.TypeByName("ValuableDirector");
if (type != null)
{
spawnMethod = AccessTools.Method(type, "SpawnCosmeticWorldObject", (Type[])null, (Type[])null);
}
((BaseUnityPlugin)this).Logger.LogInfo((object)"[GuaranteedCrate] Plugin loaded");
}
private void OnDestroy()
{
Harmony val = harmony;
if (val != null)
{
val.UnpatchSelf();
}
}
private void BindConfig()
{
cfgGuaranteedCrate = ((BaseUnityPlugin)this).Config.Bind("General", "GuaranteedCrate", true, "Guarantee at least one cosmetic crate");
cfgVanillaSpawnEnabled = ((BaseUnityPlugin)this).Config.Bind("General", "VanillaSpawnEnabled", false, "If true, game will spawn its own boxes alongside the mod. If false, ALL boxes will be replaced by mod.");
spawnOnly = ((BaseUnityPlugin)this).Config.Bind("Spawn Only", "Spawn only one type of boxes mode", false, "Spawn only one type of boxes mode");
cfgSpawnChanceMultiplier = ((BaseUnityPlugin)this).Config.Bind("General", "SpawnChanceMultiplier", 1.5f, "Multiplier for vanilla cosmetic spawn chance");
cfgCommonMultiplier = ((BaseUnityPlugin)this).Config.Bind("Rarity", "CommonMultiplier", 0.3f, "Common chance multiplier");
onlyCommon = ((BaseUnityPlugin)this).Config.Bind("Spawn Only", "Spawn only Common Boxes", false, "Spawn only Common Boxes");
cfgUncommonMultiplier = ((BaseUnityPlugin)this).Config.Bind("Rarity", "UncommonMultiplier", 0.5f, "Uncommon chance multiplier");
onlyUncommon = ((BaseUnityPlugin)this).Config.Bind("Spawn Only", "Spawn only Uncommon Boxes", false, "Spawn only Uncommon Boxes");
cfgRareMultiplier = ((BaseUnityPlugin)this).Config.Bind("Rarity", "RareMultiplier", 4f, "Rare chance multiplier");
onlyRare = ((BaseUnityPlugin)this).Config.Bind("Spawn Only", "Spawn only Rare Boxes", false, "Spawn only Rare Boxes");
cfgUltraRareMultiplier = ((BaseUnityPlugin)this).Config.Bind("Rarity", "UltraRareMultiplier", 2f, "UltraRare chance multiplier");
onlyUltraRare = ((BaseUnityPlugin)this).Config.Bind("Spawn Only", "Spawn only UltraRare Boxes", false, "Spawn only UltraRare Boxes");
cfgVerboseLogs = ((BaseUnityPlugin)this).Config.Bind("Debug", "VerboseLogs", true, "Enable detailed logs");
}
internal unsafe void TryGuaranteeCrate(ValuableDirector director)
{
//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
//IL_0233: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)director == (Object)null || spawnMethod == null)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)"[GuaranteedCrate] Director or spawn method null");
}
else
{
if (boxSpawnedThisRound)
{
return;
}
try
{
FieldInfo fieldInfo = AccessTools.Field(typeof(ValuableDirector), "cosmeticWorldObjectTargetAmount");
if (fieldInfo != null)
{
_ = (int)fieldInfo.GetValue(director);
}
if (!cfgGuaranteedCrate.Value)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"[GuaranteedCrate] Guaranteed crate disabled");
return;
}
((BaseUnityPlugin)this).Logger.LogWarning((object)"[GuaranteedCrate] No vanilla cosmetic crate detected.");
((BaseUnityPlugin)this).Logger.LogWarning((object)"[GuaranteedCrate] Forcing cosmetic crate spawn...");
List list = Object.FindObjectsOfType(false).ToList();
List[] array = new List[7]
{
list.FindAll((ValuableVolume x) => (int)x.VolumeType == 0),
list.FindAll((ValuableVolume x) => (int)x.VolumeType == 1),
list.FindAll((ValuableVolume x) => (int)x.VolumeType == 2),
list.FindAll((ValuableVolume x) => (int)x.VolumeType == 3),
list.FindAll((ValuableVolume x) => (int)x.VolumeType == 4),
list.FindAll((ValuableVolume x) => (int)x.VolumeType == 5),
list.FindAll((ValuableVolume x) => (int)x.VolumeType == 6)
};
List[] array2 = array;
for (int num = 0; num < array2.Length; num++)
{
array2[num].Shuffle();
}
int[] array3 = new int[7];
Rarity val = RollRarity(director);
((BaseUnityPlugin)this).Logger.LogInfo((object)("[!!!] [GuaranteedCrate] Selected rarity: " + ((object)(*(Rarity*)(&val))/*cast due to .constrained prefix*/).ToString() + " [!!!]"));
isModSpawning = true;
spawnMethod.Invoke(director, new object[3] { val, array3, array });
isModSpawning = false;
((BaseUnityPlugin)this).Logger.LogInfo((object)"[GuaranteedCrate] Cosmetic crate spawned successfully");
boxSpawnedThisRound = true;
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogError((object)("[GuaranteedCrate] Force spawn failed:\n" + ex.ToString()));
isModSpawning = false;
}
}
}
internal Rarity RollRarity(ValuableDirector director)
{
//IL_028e: Unknown result type (might be due to invalid IL or missing references)
//IL_0291: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_0089: Unknown result type (might be due to invalid IL or missing references)
//IL_009f: Expected I4, but got Unknown
//IL_0133: Unknown result type (might be due to invalid IL or missing references)
//IL_014d: Unknown result type (might be due to invalid IL or missing references)
//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
//IL_0232: Unknown result type (might be due to invalid IL or missing references)
//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
//IL_016c: Unknown result type (might be due to invalid IL or missing references)
//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
//IL_017b: Unknown result type (might be due to invalid IL or missing references)
//IL_024e: Unknown result type (might be due to invalid IL or missing references)
//IL_0210: Unknown result type (might be due to invalid IL or missing references)
//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
//IL_018d: Unknown result type (might be due to invalid IL or missing references)
//IL_025d: Unknown result type (might be due to invalid IL or missing references)
//IL_021f: Unknown result type (might be due to invalid IL or missing references)
//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
//IL_026c: Unknown result type (might be due to invalid IL or missing references)
//IL_022e: Unknown result type (might be due to invalid IL or missing references)
Rarity rarity;
try
{
int num = director.CosmeticWorldObjectLevelLoopsGet();
float num2 = ((director.CosmeticWorldObjectLevelLoopsClampedGet() < num) ? 1f : ((float)(RunManager.instance.levelsCompleted % director.cosmeticWorldObjectsLevelLoop) / (float)director.cosmeticWorldObjectsLevelLoop));
float num3 = 0f;
float num4 = 0f;
float num5 = 0f;
float num6 = 0f;
foreach (CosmeticWorldObjectSetup cosmeticWorldObjectSetup in director.cosmeticWorldObjectSetups)
{
float num7 = Mathf.Max(0f, cosmeticWorldObjectSetup.chanceCurve.Evaluate(num2));
rarity = cosmeticWorldObjectSetup.rarity;
switch ((int)rarity)
{
case 0:
num3 += num7 * cfgCommonMultiplier.Value;
break;
case 1:
num4 += num7 * cfgUncommonMultiplier.Value;
break;
case 2:
num5 += num7 * cfgRareMultiplier.Value;
break;
case 3:
num6 += num7 * cfgUltraRareMultiplier.Value;
break;
}
}
float num8 = num3 + num4 + num5 + num6;
if (num8 <= 0f)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)"[GuaranteedCrate] Invalid rarity total, fallback UltraRare");
rarity = (Rarity)3;
}
else
{
float num9 = Random.Range(0f, num8);
if (num9 < num3)
{
rarity = (Rarity)0;
if (spawnOnly.Value)
{
if (onlyUncommon.Value)
{
rarity = (Rarity)1;
}
if (onlyRare.Value)
{
rarity = (Rarity)2;
}
if (onlyUltraRare.Value)
{
rarity = (Rarity)3;
}
}
}
else
{
num9 -= num3;
if (num9 < num4)
{
rarity = (Rarity)1;
if (spawnOnly.Value)
{
if (onlyCommon.Value)
{
rarity = (Rarity)0;
}
if (onlyRare.Value)
{
rarity = (Rarity)2;
}
if (onlyUltraRare.Value)
{
rarity = (Rarity)3;
}
}
}
else
{
num9 -= num4;
if (num9 < num5)
{
rarity = (Rarity)2;
if (spawnOnly.Value)
{
if (onlyCommon.Value)
{
rarity = (Rarity)0;
}
if (onlyUncommon.Value)
{
rarity = (Rarity)1;
}
if (onlyUltraRare.Value)
{
rarity = (Rarity)3;
}
}
}
else
{
rarity = (Rarity)3;
if (spawnOnly.Value)
{
if (onlyCommon.Value)
{
rarity = (Rarity)0;
}
if (onlyUncommon.Value)
{
rarity = (Rarity)1;
}
if (onlyRare.Value)
{
rarity = (Rarity)2;
}
}
}
}
}
}
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogError((object)("[GuaranteedCrate] RollRarity failed, fallback UltraRare:\n" + ex.ToString()));
rarity = (Rarity)3;
}
return rarity;
}
static GuaranteedCosmeticCratePlugin()
{
}
}
[HarmonyPatch(typeof(ValuableDirector), "SetupHost")]
internal static class ValuableDirectorPatch
{
private static IEnumerator Postfix(IEnumerator __result, ValuableDirector __instance)
{
while (__result.MoveNext())
{
yield return __result.Current;
}
if (!((Object)(object)GuaranteedCosmeticCratePlugin.Instance == (Object)null))
{
yield return (object)new WaitForSeconds(0.25f);
GuaranteedCosmeticCratePlugin.Instance.TryGuaranteeCrate(__instance);
}
}
}
[HarmonyPatch(typeof(Random), "Range", new Type[]
{
typeof(int),
typeof(int)
})]
internal static class CosmeticSpawnChancePatch
{
private static void Prefix(int minInclusive, ref int maxExclusive)
{
try
{
if (!((Object)(object)GuaranteedCosmeticCratePlugin.Instance == (Object)null))
{
float value = GuaranteedCosmeticCratePlugin.Instance.cfgSpawnChanceMultiplier.Value;
if (!(value <= 1f) && maxExclusive == 100)
{
maxExclusive = Mathf.Max(1, Mathf.RoundToInt((float)maxExclusive / value));
}
}
}
catch
{
}
}
}
internal static class ShuffleExt
{
internal static void Shuffle(this IList list)
{
for (int num = list.Count - 1; num > 0; num--)
{
int index = Random.Range(0, num + 1);
T value = list[num];
list[num] = list[index];
list[index] = value;
}
}
}