using System; using System.Collections; using System.Collections.Generic; using System.Text; using HG; using JetBrains.Annotations; using UnityEngine; using UnityEngine.ResourceManagement.AsyncOperations; namespace RoR2; public static class PickupCatalog { public struct Enumerator : IEnumerator, IEnumerator, IDisposable { private PickupIndex position; public PickupIndex Current => position; object IEnumerator.Current => Current; public bool MoveNext() { ++position; return position.value < pickupCount; } public void Reset() { position = PickupIndex.none; } void IDisposable.Dispose() { } } private static PickupDef[] entries = Array.Empty(); private static PickupIndex[] itemIndexToPickupIndex = Array.Empty(); private static PickupIndex[] equipmentIndexToPickupIndex = Array.Empty(); private static PickupIndex[] artifactIndexToPickupIndex = Array.Empty(); private static PickupIndex[] miscPickupIndexToPickupIndex = Array.Empty(); private static readonly Dictionary nameToPickupIndex = new Dictionary(); private static readonly Dictionary itemTierToPickupIndex = new Dictionary(); public static readonly Color invalidPickupColor = Color.black; public static readonly string invalidPickupToken = "???"; public static Action> modifyPickups; public static int pickupCount { get; private set; } public static GenericStaticEnumerable allPickupIndices => default(GenericStaticEnumerable); public static IEnumerable allPickups => entries; [NotNull] public static T[] GetPerPickupBuffer() { return new T[pickupCount]; } public static void SetEntries([NotNull] PickupDef[] pickupDefs) { Array.Resize(ref entries, pickupDefs.Length); pickupCount = pickupDefs.Length; Array.Copy(pickupDefs, entries, entries.Length); Array.Resize(ref itemIndexToPickupIndex, ItemCatalog.itemCount); Array.Resize(ref equipmentIndexToPickupIndex, EquipmentCatalog.equipmentCount); Array.Resize(ref artifactIndexToPickupIndex, ArtifactCatalog.artifactCount); Array.Resize(ref miscPickupIndexToPickupIndex, MiscPickupCatalog.pickupCount); nameToPickupIndex.Clear(); itemTierToPickupIndex.Clear(); for (int i = 0; i < entries.Length; i++) { PickupDef pickupDef = entries[i]; PickupIndex pickupIndex2 = (pickupDef.pickupIndex = new PickupIndex(i)); if (pickupDef.itemIndex != ItemIndex.None) { itemIndexToPickupIndex[(int)pickupDef.itemIndex] = pickupIndex2; } else if (pickupDef.itemTier != ItemTier.NoTier) { itemTierToPickupIndex.Add(pickupDef.itemTier, pickupDef.pickupIndex); } if (pickupDef.equipmentIndex != EquipmentIndex.None) { equipmentIndexToPickupIndex[(int)pickupDef.equipmentIndex] = pickupIndex2; } if (pickupDef.artifactIndex != ArtifactIndex.None) { artifactIndexToPickupIndex[(int)pickupDef.artifactIndex] = pickupIndex2; } if (pickupDef.miscPickupIndex != MiscPickupIndex.None) { miscPickupIndexToPickupIndex[(int)pickupDef.miscPickupIndex] = pickupIndex2; } } for (int j = 0; j < entries.Length; j++) { PickupDef pickupDef2 = entries[j]; nameToPickupIndex[pickupDef2.internalName] = pickupDef2.pickupIndex; } } [SystemInitializer(new Type[] { typeof(ItemCatalog), typeof(EquipmentCatalog), typeof(ArtifactCatalog), typeof(MiscPickupCatalog) })] public static IEnumerator Init() { AsyncOperationHandle equipmentDefPreload = LegacyResourcesAPI.LoadAsync("Prefabs/ItemPickups/EquipmentOrb"); while (!equipmentDefPreload.IsDone) { yield return null; } EquipmentDef.SetDropletDisplayPrefab(equipmentDefPreload.Result); List pickupDefs = new List(); foreach (ItemTierDef allItemTierDef in ItemTierCatalog.allItemTierDefs) { PickupDef pickupDef = new PickupDef(); pickupDef.internalName = "ItemTier." + allItemTierDef.tier; pickupDef.itemTier = allItemTierDef.tier; pickupDef.dropletDisplayPrefab = allItemTierDef?.dropletDisplayPrefab; pickupDef.baseColor = ColorCatalog.GetColor(allItemTierDef.colorIndex); pickupDef.darkColor = ColorCatalog.GetColor(allItemTierDef.darkColorIndex); pickupDef.interactContextToken = "ITEM_PICKUP_CONTEXT"; pickupDef.isLunar = allItemTierDef.tier == ItemTier.Lunar; pickupDef.isBoss = allItemTierDef.tier == ItemTier.Boss; pickupDefs.Add(pickupDef); } yield return null; for (int i = 0; i < ItemCatalog.itemCount; i++) { PickupDef item = ItemCatalog.GetItemDef((ItemIndex)i).CreatePickupDef(); pickupDefs.Add(item); } yield return null; for (int j = 0; j < EquipmentCatalog.equipmentCount; j++) { PickupDef item2 = EquipmentCatalog.GetEquipmentDef((EquipmentIndex)j).CreatePickupDef(); pickupDefs.Add(item2); } yield return null; for (int k = 0; k < MiscPickupCatalog.pickupCount; k++) { PickupDef item3 = MiscPickupCatalog.miscPickupDefs[k].CreatePickupDef(); pickupDefs.Add(item3); } yield return null; for (int l = 0; l < ArtifactCatalog.artifactCount; l++) { PickupDef item4 = ArtifactCatalog.GetArtifactDef((ArtifactIndex)l).CreatePickupDef(); pickupDefs.Add(item4); } yield return null; modifyPickups?.Invoke(pickupDefs); SetEntries(pickupDefs.ToArray()); } public static PickupIndex FindScrapIndexForItemTier(ItemTier tier) { PickupIndex result = PickupIndex.none; switch (tier) { case ItemTier.Tier1: result = FindPickupIndex("ItemIndex.ScrapWhite"); break; case ItemTier.Tier2: result = FindPickupIndex("ItemIndex.ScrapGreen"); break; case ItemTier.Tier3: result = FindPickupIndex("ItemIndex.ScrapRed"); break; case ItemTier.Boss: result = FindPickupIndex("ItemIndex.ScrapYellow"); break; } return result; } public static PickupIndex FindPickupIndex([NotNull] string pickupName) { if (nameToPickupIndex.TryGetValue(pickupName, out var value)) { return value; } return PickupIndex.none; } public static PickupIndex FindPickupIndex(ItemIndex itemIndex) { return ArrayUtils.GetSafe(itemIndexToPickupIndex, (int)itemIndex, in PickupIndex.none); } public static PickupIndex FindPickupIndex(ItemTier tier) { if (itemTierToPickupIndex.TryGetValue(tier, out var value)) { return value; } return PickupIndex.none; } public static PickupIndex FindPickupIndex(EquipmentIndex equipmentIndex) { return ArrayUtils.GetSafe(equipmentIndexToPickupIndex, (int)equipmentIndex, in PickupIndex.none); } public static PickupIndex FindPickupIndex(ArtifactIndex artifactIndex) { return ArrayUtils.GetSafe(artifactIndexToPickupIndex, (int)artifactIndex, in PickupIndex.none); } public static PickupIndex FindPickupIndex(MiscPickupIndex miscIndex) { return ArrayUtils.GetSafe(miscPickupIndexToPickupIndex, (int)miscIndex, in PickupIndex.none); } [CanBeNull] public static PickupDef GetPickupDef(PickupIndex pickupIndex) { return ArrayUtils.GetSafe(entries, pickupIndex.value); } [NotNull] public static GameObject GetHiddenPickupDisplayPrefab() { return LegacyResourcesAPI.Load("Prefabs/PickupModels/PickupMystery"); } [ConCommand(commandName = "pickup_print_all", flags = ConVarFlags.None, helpText = "Prints all pickup definitions.")] private static void CCPickupPrintAll(ConCommandArgs args) { StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < pickupCount; i++) { PickupDef pickupDef = GetPickupDef(new PickupIndex(i)); stringBuilder.Append("[").Append(i).Append("]={internalName=") .Append(pickupDef.internalName) .Append("}") .AppendLine(); } } }