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 On.RoR2;
using R2API;
using RiskOfOptions;
using RiskOfOptions.OptionConfigs;
using RiskOfOptions.Options;
using RoR2;
using UnityEngine;
using UnityEngine.Networking;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Artifact Of Focus Mod")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Artifact Of Focus Mod")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("3a717cff-0ef5-4f38-82ed-43b8b31b91da")]
[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 ArtifactOfFocus;
[BepInPlugin("com.Basher93.ArtifactOfFocus", "Artifact of Focus", "1.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class ArtifactOfFocus : BaseUnityPlugin
{
public static ArtifactDef FocusArtifactDef;
public void Awake()
{
ConfigManager.Init(((BaseUnityPlugin)this).Config);
Assets.PopulateAssets();
FocusArtifactDef = ScriptableObject.CreateInstance<ArtifactDef>();
FocusArtifactDef.cachedName = "ArtifactOfFocus";
FocusArtifactDef.nameToken = "ARTIFACTOFFOCUS_NAME";
FocusArtifactDef.descriptionToken = "ARTIFACTOFFOCUS_DESC";
FocusArtifactDef.smallIconSelectedSprite = Assets.iconSelected;
FocusArtifactDef.smallIconDeselectedSprite = Assets.iconDeselected;
ContentAddition.AddArtifactDef(FocusArtifactDef);
LanguageAPI.Add("ARTIFACTOFFOCUS_NAME", "Artifact of Focus");
LanguageAPI.Add("ARTIFACTOFFOCUS_DESC", "Fewer chests and shrines. All drops include the one same random item, chosen at run start.");
FocusArtifactLogic.Init();
}
}
public static class Assets
{
public static Sprite iconSelected;
public static Sprite iconDeselected;
public static void PopulateAssets()
{
string directoryName = Path.GetDirectoryName(typeof(ArtifactOfFocus).Assembly.Location);
Debug.Log((object)("[ArtifactOfFocus] Loading assets from: " + directoryName));
iconSelected = LoadSprite(Path.Combine(directoryName, "IconSelected.png"));
iconDeselected = LoadSprite(Path.Combine(directoryName, "IconDeselected.png"));
}
private static Sprite LoadSprite(string path)
{
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Expected O, but got Unknown
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
if (!File.Exists(path))
{
Debug.LogError((object)("[ArtifactOfFocus] Asset not found at path: " + path));
return null;
}
byte[] array = File.ReadAllBytes(path);
Texture2D val = new Texture2D(256, 256, (TextureFormat)4, false);
ImageConversion.LoadImage(val, array);
((Texture)val).filterMode = (FilterMode)1;
((Texture)val).wrapMode = (TextureWrapMode)1;
val.Apply();
return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
}
}
public static class ConfigManager
{
public static ConfigEntry<float> ChestSpawnMultiplier;
public static ConfigEntry<float> TerminalSpawnMultiplier;
public static ConfigEntry<float> ShrineSpawnMultiplier;
public static ConfigEntry<float> WhiteChance;
public static ConfigEntry<float> GreenChance;
public static ConfigEntry<float> RedChance;
public static ConfigEntry<float> YellowChance;
public static ConfigEntry<float> BlueChance;
public static void Init(ConfigFile config)
{
//IL_0107: Unknown result type (might be due to invalid IL or missing references)
//IL_010c: Unknown result type (might be due to invalid IL or missing references)
//IL_0117: Unknown result type (might be due to invalid IL or missing references)
//IL_0122: Unknown result type (might be due to invalid IL or missing references)
//IL_0132: Expected O, but got Unknown
//IL_012d: Unknown result type (might be due to invalid IL or missing references)
//IL_0137: Expected O, but got Unknown
//IL_013c: Unknown result type (might be due to invalid IL or missing references)
//IL_0141: Unknown result type (might be due to invalid IL or missing references)
//IL_014c: Unknown result type (might be due to invalid IL or missing references)
//IL_0157: Unknown result type (might be due to invalid IL or missing references)
//IL_0167: Expected O, but got Unknown
//IL_0162: Unknown result type (might be due to invalid IL or missing references)
//IL_016c: Expected O, but got Unknown
//IL_0171: Unknown result type (might be due to invalid IL or missing references)
//IL_0176: Unknown result type (might be due to invalid IL or missing references)
//IL_0181: Unknown result type (might be due to invalid IL or missing references)
//IL_018c: Unknown result type (might be due to invalid IL or missing references)
//IL_019c: Expected O, but got Unknown
//IL_0197: Unknown result type (might be due to invalid IL or missing references)
//IL_01a1: Expected O, but got Unknown
//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
//IL_01d1: Expected O, but got Unknown
//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
//IL_01d6: Expected O, but got Unknown
//IL_01db: 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_01eb: Unknown result type (might be due to invalid IL or missing references)
//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
//IL_0206: Expected O, but got Unknown
//IL_0201: Unknown result type (might be due to invalid IL or missing references)
//IL_020b: Expected O, but got Unknown
//IL_0210: Unknown result type (might be due to invalid IL or missing references)
//IL_0215: Unknown result type (might be due to invalid IL or missing references)
//IL_0220: Unknown result type (might be due to invalid IL or missing references)
//IL_022b: Unknown result type (might be due to invalid IL or missing references)
//IL_023b: Expected O, but got Unknown
//IL_0236: Unknown result type (might be due to invalid IL or missing references)
//IL_0240: Expected O, but got Unknown
//IL_0245: Unknown result type (might be due to invalid IL or missing references)
//IL_024a: Unknown result type (might be due to invalid IL or missing references)
//IL_0255: Unknown result type (might be due to invalid IL or missing references)
//IL_0260: Unknown result type (might be due to invalid IL or missing references)
//IL_0270: Expected O, but got Unknown
//IL_026b: Unknown result type (might be due to invalid IL or missing references)
//IL_0275: Expected O, but got Unknown
//IL_027a: Unknown result type (might be due to invalid IL or missing references)
//IL_027f: Unknown result type (might be due to invalid IL or missing references)
//IL_028a: Unknown result type (might be due to invalid IL or missing references)
//IL_0295: Unknown result type (might be due to invalid IL or missing references)
//IL_02a5: Expected O, but got Unknown
//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
//IL_02aa: Expected O, but got Unknown
ChestSpawnMultiplier = config.Bind<float>("SpawnRates", "ChestSpawnMultiplier", 0.5f, "Multiplier for chest spawns (0 to 1). Default is 0.5");
TerminalSpawnMultiplier = config.Bind<float>("SpawnRates", "TerminalSpawnMultiplier", 0.5f, "Multiplier for terminal spawns (0 to 1). Default is 0.5");
ShrineSpawnMultiplier = config.Bind<float>("SpawnRates", "ShrineSpawnMultiplier", 0.75f, "Multiplier for chance shrine spawns (0 to 1). Default is 0.75");
WhiteChance = config.Bind<float>("RarityChances", "WhiteItemChance", 73f, "Chance for white tier items to be selected (Total must be 100)");
GreenChance = config.Bind<float>("RarityChances", "GreenItemChance", 24f, "Chance for green tier items to be selected (Total must be 100)");
RedChance = config.Bind<float>("RarityChances", "RedItemChance", 1f, "Chance for red tier items to be selected (Total must be 100)");
YellowChance = config.Bind<float>("RarityChances", "YellowItemChance", 1f, "Chance for yellow tier items to be selected (Total must be 100)");
BlueChance = config.Bind<float>("RarityChances", "BlueItemChance", 1f, "Chance for blue (lunar) tier items to be selected (Total must be 100)");
ModSettingsManager.SetModDescription("Artifact of Focus - Halved chest spawns, but on every item pickup the run's focused item is also dropped!");
ModSettingsManager.AddOption((BaseOption)new StepSliderOption(ChestSpawnMultiplier, new StepSliderConfig
{
min = 0f,
max = 1f,
increment = 0.05f
}));
ModSettingsManager.AddOption((BaseOption)new StepSliderOption(TerminalSpawnMultiplier, new StepSliderConfig
{
min = 0f,
max = 1f,
increment = 0.05f
}));
ModSettingsManager.AddOption((BaseOption)new StepSliderOption(ShrineSpawnMultiplier, new StepSliderConfig
{
min = 0f,
max = 1f,
increment = 0.05f
}));
ModSettingsManager.AddOption((BaseOption)new StepSliderOption(WhiteChance, new StepSliderConfig
{
min = 0f,
max = 100f,
increment = 1f
}));
ModSettingsManager.AddOption((BaseOption)new StepSliderOption(GreenChance, new StepSliderConfig
{
min = 0f,
max = 100f,
increment = 1f
}));
ModSettingsManager.AddOption((BaseOption)new StepSliderOption(RedChance, new StepSliderConfig
{
min = 0f,
max = 100f,
increment = 1f
}));
ModSettingsManager.AddOption((BaseOption)new StepSliderOption(YellowChance, new StepSliderConfig
{
min = 0f,
max = 100f,
increment = 1f
}));
ModSettingsManager.AddOption((BaseOption)new StepSliderOption(BlueChance, new StepSliderConfig
{
min = 0f,
max = 100f,
increment = 1f
}));
}
}
public static class FocusArtifactLogic
{
private static readonly FieldInfo originObjectField = typeof(PickupDropletController).GetField("originObject", BindingFlags.Instance | BindingFlags.NonPublic);
public static PickupIndex selectedPickupIndex = PickupIndex.none;
private static readonly HashSet<PickupDropletController> dropletsHandled = new HashSet<PickupDropletController>();
private static readonly Dictionary<CharacterMaster, int> previousCounts = new Dictionary<CharacterMaster, int>();
private static bool itemRolled = false;
private static readonly Dictionary<CharacterMaster, int> previousTotalCounts = new Dictionary<CharacterMaster, int>();
public static void Init()
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Expected O, but got Unknown
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Expected O, but got Unknown
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Expected O, but got Unknown
Run.onRunStartGlobal += OnRunStart;
SceneDirector.Start += new hook_Start(OnSceneDirectorStart);
CharacterMaster.OnInventoryChanged += new hook_OnInventoryChanged(OnInventoryChanged);
PickupDropletController.Start += new hook_Start(OnPickupDropletControllerStart);
}
private static void OnRunStart(Run run)
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
previousCounts.Clear();
dropletsHandled.Clear();
selectedPickupIndex = PickupIndex.none;
itemRolled = false;
EnsureItemRolled();
}
private static void EnsureItemRolled()
{
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: 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_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: 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_00b6: Unknown result type (might be due to invalid IL or missing references)
//IL_0067: Unknown result type (might be due to invalid IL or missing references)
//IL_006d: Invalid comparison between Unknown and I4
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
if (itemRolled)
{
return;
}
if ((Object)(object)Run.instance == (Object)null || Run.instance.availableTier1DropList == null || Run.instance.availableTier1DropList.Count == 0)
{
Debug.LogWarning((object)"[ArtifactOfFocus] Run or drop list not ready yet.");
return;
}
selectedPickupIndex = RollItemFromConfig();
if (selectedPickupIndex != PickupIndex.none)
{
PickupDef pickupDef = PickupCatalog.GetPickupDef(selectedPickupIndex);
if (pickupDef != null && (int)pickupDef.itemIndex != -1)
{
string @string = Language.GetString(ItemCatalog.GetItemDef(pickupDef.itemIndex).nameToken);
Chat.AddMessage("Artifact of Focus: All items this run will include: " + @string);
Debug.Log((object)("[ArtifactOfFocus] Selected focused item: " + @string));
}
else
{
Debug.LogError((object)"[ArtifactOfFocus] Invalid item selected.");
selectedPickupIndex = PickupIndex.none;
}
}
else
{
Debug.LogWarning((object)"[ArtifactOfFocus] No valid item selected.");
}
itemRolled = true;
}
private static PickupIndex RollItemFromConfig()
{
//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
//IL_0100: Unknown result type (might be due to invalid IL or missing references)
//IL_0103: Invalid comparison between Unknown and I4
//IL_01be: Unknown result type (might be due to invalid IL or missing references)
//IL_0113: Unknown result type (might be due to invalid IL or missing references)
//IL_0116: Invalid comparison between Unknown and I4
//IL_0126: Unknown result type (might be due to invalid IL or missing references)
//IL_0129: Invalid comparison between Unknown and I4
//IL_0139: Unknown result type (might be due to invalid IL or missing references)
//IL_013c: Invalid comparison between Unknown and I4
//IL_0199: Unknown result type (might be due to invalid IL or missing references)
//IL_019e: Unknown result type (might be due to invalid IL or missing references)
//IL_0190: Unknown result type (might be due to invalid IL or missing references)
//IL_0195: Unknown result type (might be due to invalid IL or missing references)
//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
List<Tuple<ItemTier, int>> list = new List<Tuple<ItemTier, int>>
{
new Tuple<ItemTier, int>((ItemTier)0, (int)ConfigManager.WhiteChance.Value),
new Tuple<ItemTier, int>((ItemTier)1, (int)ConfigManager.GreenChance.Value),
new Tuple<ItemTier, int>((ItemTier)2, (int)ConfigManager.RedChance.Value),
new Tuple<ItemTier, int>((ItemTier)4, (int)ConfigManager.YellowChance.Value),
new Tuple<ItemTier, int>((ItemTier)3, (int)ConfigManager.BlueChance.Value)
};
int num = 0;
foreach (Tuple<ItemTier, int> item2 in list)
{
num += item2.Item2;
}
if (num == 0)
{
return PickupIndex.none;
}
int num2 = Random.Range(0, num);
int num3 = 0;
foreach (Tuple<ItemTier, int> item3 in list)
{
num3 += item3.Item2;
if (num2 < num3)
{
ItemTier item = item3.Item1;
List<PickupIndex> source = Run.instance.availableTier1DropList;
if ((int)item == 1)
{
source = Run.instance.availableTier2DropList;
}
else if ((int)item == 2)
{
source = Run.instance.availableTier3DropList;
}
else if ((int)item == 4)
{
source = Run.instance.availableBossDropList;
}
else if ((int)item == 3)
{
source = Run.instance.availableLunarItemDropList;
}
List<PickupIndex> list2 = source.Where(delegate(PickupIndex p)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Invalid comparison between Unknown and I4
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
PickupDef pickupDef = PickupCatalog.GetPickupDef(p);
return pickupDef != null && (int)pickupDef.itemIndex != -1 && !ItemCatalog.GetItemDef(pickupDef.itemIndex).IsUtility();
}).ToList();
if (list2.Count > 0)
{
return list2[Random.Range(0, list2.Count)];
}
return PickupIndex.none;
}
}
return PickupIndex.none;
}
private static void OnSceneDirectorStart(orig_Start orig, SceneDirector self)
{
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: Invalid comparison between Unknown and I4
orig.Invoke(self);
RunArtifactManager instance = RunArtifactManager.instance;
if (instance == null || !instance.IsArtifactEnabled(ArtifactOfFocus.FocusArtifactDef))
{
return;
}
float num = Mathf.Clamp01(ConfigManager.ChestSpawnMultiplier.Value);
PurchaseInteraction[] array = Object.FindObjectsOfType<PurchaseInteraction>();
foreach (PurchaseInteraction val in array)
{
if ((int)val.costType == 1 && Random.value > num)
{
Object.Destroy((Object)(object)((Component)val).gameObject);
}
}
}
private static void OnPickupDropletControllerStart(orig_Start orig, PickupDropletController self)
{
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_0067: 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_007a: 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_008f: Invalid comparison between Unknown and I4
//IL_00de: Unknown result type (might be due to invalid IL or missing references)
//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
//IL_0100: Unknown result type (might be due to invalid IL or missing references)
//IL_0092: Unknown result type (might be due to invalid IL or missing references)
orig.Invoke(self);
if (!NetworkServer.active || !RunArtifactManager.instance.IsArtifactEnabled(ArtifactOfFocus.FocusArtifactDef))
{
return;
}
if (selectedPickupIndex == PickupIndex.none)
{
Debug.LogWarning((object)"[ArtifactOfFocus] Focused item not rolled yet.");
EnsureItemRolled();
if (selectedPickupIndex == PickupIndex.none)
{
return;
}
}
if (self.pickupIndex == PickupIndex.none || self.pickupIndex == selectedPickupIndex)
{
return;
}
PickupDef pickupDef = PickupCatalog.GetPickupDef(self.pickupIndex);
if (pickupDef != null && (int)pickupDef.itemIndex != -1)
{
ItemDef itemDef = ItemCatalog.GetItemDef(pickupDef.itemIndex);
if ((Object)(object)itemDef != (Object)null && itemDef.ContainsTag((ItemTag)10))
{
Debug.Log((object)"[ArtifactOfFocus] Skipping scrap-related drop (likely printer).");
return;
}
}
if (!dropletsHandled.Contains(self))
{
dropletsHandled.Add(self);
Vector3 position = ((Component)self).transform.position;
Vector3 zero = Vector3.zero;
PickupDropletController.CreatePickupDroplet(selectedPickupIndex, position, zero);
string @string = Language.GetString(ItemCatalog.GetItemDef(PickupCatalog.GetPickupDef(selectedPickupIndex).itemIndex).nameToken);
Chat.AddMessage("<color=#b4d455>" + @string + "</color> granted by the Artifact of Focus!");
}
}
private static void OnInventoryChanged(orig_OnInventoryChanged orig, CharacterMaster master)
{
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: 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_006f: Invalid comparison between Unknown and I4
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
//IL_00db: Unknown result type (might be due to invalid IL or missing references)
//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
orig.Invoke(master);
if (!NetworkServer.active || !RunArtifactManager.instance.IsArtifactEnabled(ArtifactOfFocus.FocusArtifactDef) || selectedPickupIndex == PickupIndex.none)
{
return;
}
Inventory inventory = master.inventory;
if ((Object)(object)inventory == (Object)null)
{
return;
}
int num = 0;
foreach (ItemIndex value2 in Enum.GetValues(typeof(ItemIndex)))
{
if ((int)value2 != -1 && value2 != PickupCatalog.GetPickupDef(selectedPickupIndex).itemIndex)
{
num += inventory.GetItemCount(value2);
}
}
previousTotalCounts.TryGetValue(master, out var value);
int num2 = num - value;
if (num2 > 0)
{
inventory.GiveItem(PickupCatalog.GetPickupDef(selectedPickupIndex).itemIndex, num2);
string @string = Language.GetString(ItemCatalog.GetItemDef(PickupCatalog.GetPickupDef(selectedPickupIndex).itemIndex).nameToken);
Chat.AddMessage($"<color=#b4d455>{@string}</color> granted by the Artifact of Focus x{num2}!");
}
previousTotalCounts[master] = num;
}
}
public static class ItemDefExtensions
{
public static bool IsUtility(this ItemDef def)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Invalid comparison between Unknown and I4
if ((int)def.tier == 3)
{
if (!def.tags.Contains((ItemTag)3))
{
return ((Object)def).name.ToLower().Contains("lunarutility");
}
return true;
}
return false;
}
}