using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using Alexandria.DungeonAPI;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using BetterShop.Patches;
using Dungeonator;
using HarmonyLib;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyCompany("BetterShop")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+2bbcbff1c6ec136a99f87080001e079bac414d57")]
[assembly: AssemblyProduct("BetterShop")]
[assembly: AssemblyTitle("BetterShop")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace BetterShop
{
[BepInPlugin("com.bettershop.etg", "BetterShop", "1.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Plugin : BaseUnityPlugin
{
public const string PLUGIN_GUID = "com.bettershop.etg";
public const string PLUGIN_NAME = "BetterShop";
public const string PLUGIN_VERSION = "1.0.0";
internal static ManualLogSource Log;
internal static Plugin Instance;
internal static ConfigEntry<int> MinGuns;
internal static ConfigEntry<int> MinItems;
internal static ConfigEntry<int> ExtraNpcCount;
internal static ConfigEntry<bool> BulletHellShopEnabled;
private void Awake()
{
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Expected O, but got Unknown
//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
Instance = this;
Log = ((BaseUnityPlugin)this).Logger;
MinGuns = ((BaseUnityPlugin)this).Config.Bind<int>("商店保底", "MinGuns", 1, "商店中至少包含的枪械数量");
MinItems = ((BaseUnityPlugin)this).Config.Bind<int>("商店保底", "MinItems", 1, "商店中至少包含的道具数量");
ExtraNpcCount = ((BaseUnityPlugin)this).Config.Bind<int>("额外NPC", "Count", 1, new ConfigDescription("每层额外生成的 NPC 数量(0=禁用,1-3)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 3), new object[0]));
BulletHellShopEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("枪弹地狱", "ShopEnabled", true, "是否在枪弹地狱(第六层)生成商人");
new Harmony("com.bettershop.etg").PatchAll();
HellShopGenerator.Init();
ExtraNpcInjector.Init();
Log.LogInfo((object)"BetterShop v1.0.0 已加载!Alexandria 依赖注入成功!");
}
}
}
namespace BetterShop.Patches
{
public static class ExtraNpcInjector
{
private struct NpcCandidate
{
public ProceduralFlowModifierData Modifier;
public string SourceName;
}
private static readonly string[] AnnotationBlacklist = new string[11]
{
"shrine", "black_market", "elevator", "exit", "entrance", "boss", "crest", "fireplace", "muncher", "prayer",
"secret"
};
public static void Init()
{
DungeonHooks.OnPreDungeonGeneration += OnPreDungeonGen;
}
private static List<NpcCandidate> CollectAllNpcRooms(DungeonFlow flow)
{
HashSet<string> seenKeys = new HashSet<string>();
List<NpcCandidate> result = new List<NpcCandidate>();
CollectFromNamedSource(StaticInjections.NPC_injections, "NPC_injections", seenKeys, result, requireSpecialCategory: false);
CollectFromNamedSource(StaticInjections.Fallback_Subshop_Injections, "Fallback_Subshop(Vampire/GunMuncher)", seenKeys, result, requireSpecialCategory: false);
CollectFromNamedSource(StaticReferences.subShopTable, "SubShopTable(OldRed/Cursula/Flynt/Trorc/Goopton)", seenKeys, result, requireSpecialCategory: false);
if (GameManager.Instance?.GlobalInjectionData?.entries != null)
{
foreach (MetaInjectionDataEntry entry in GameManager.Instance.GlobalInjectionData.entries)
{
if (entry?.injectionData?.InjectionData != null)
{
CollectFromNamedSource(entry.injectionData, "GlobalInjection/" + (((Object)entry.injectionData).name ?? "?"), seenKeys, result, requireSpecialCategory: true);
}
}
}
if (flow.sharedInjectionData != null)
{
foreach (SharedInjectionData sharedInjectionDatum in flow.sharedInjectionData)
{
if (sharedInjectionDatum?.InjectionData == null)
{
continue;
}
CollectFromNamedSource(sharedInjectionDatum, "FlowShared/" + (((Object)sharedInjectionDatum).name ?? "?"), seenKeys, result, requireSpecialCategory: true);
if (sharedInjectionDatum.AttachedInjectionData == null)
{
continue;
}
foreach (SharedInjectionData attachedInjectionDatum in sharedInjectionDatum.AttachedInjectionData)
{
if (attachedInjectionDatum?.InjectionData != null)
{
CollectFromNamedSource(attachedInjectionDatum, "FlowShared/attached", seenKeys, result, requireSpecialCategory: true);
}
}
}
}
return result;
}
private static void CollectFromNamedSource(SharedInjectionData data, string sourceName, HashSet<string> seenKeys, List<NpcCandidate> result, bool requireSpecialCategory)
{
if ((Object)(object)data == (Object)null || data.InjectionData == null)
{
return;
}
Plugin.Log.LogDebug((object)$" [来源:{sourceName}] 共 {data.InjectionData.Count} 条");
foreach (ProceduralFlowModifierData injectionDatum in data.InjectionData)
{
string modifierKey = GetModifierKey(injectionDatum);
if (string.IsNullOrEmpty(modifierKey) || seenKeys.Contains(modifierKey))
{
continue;
}
if (!IsValidNpc(injectionDatum, requireSpecialCategory))
{
Plugin.Log.LogDebug((object)(" - 跳过: " + modifierKey + " (不满足条件, 来源: " + sourceName + ")"));
continue;
}
string lowerAnnotation = (injectionDatum.annotation ?? "").ToLower();
if (!IsAnnotationBlacklisted(modifierKey.ToLower(), lowerAnnotation))
{
seenKeys.Add(modifierKey);
result.Add(new NpcCandidate
{
Modifier = injectionDatum,
SourceName = sourceName
});
Plugin.Log.LogDebug((object)(" + 收集: " + modifierKey + " (来源: " + sourceName + ")"));
}
}
}
private static string GetModifierKey(ProceduralFlowModifierData mod)
{
if (!string.IsNullOrEmpty(mod.annotation))
{
if (mod.annotation.StartsWith("CHALLENGE - "))
{
return "CHALLENGE";
}
return mod.annotation;
}
if ((Object)(object)mod.exactRoom != (Object)null && !string.IsNullOrEmpty(((Object)mod.exactRoom).name))
{
return ((Object)mod.exactRoom).name;
}
if (mod.roomTable?.includedRooms?.elements != null)
{
foreach (WeightedRoom element in mod.roomTable.includedRooms.elements)
{
if ((Object)(object)element?.room != (Object)null && !string.IsNullOrEmpty(((Object)element.room).name))
{
return "table:" + ((Object)element.room).name;
}
}
}
return null;
}
private static bool IsValidNpc(ProceduralFlowModifierData mod, bool requireSpecialCategory)
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Invalid comparison between Unknown and I4
//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
//IL_00a7: Invalid comparison between Unknown and I4
//IL_014e: Unknown result type (might be due to invalid IL or missing references)
//IL_0154: Invalid comparison between Unknown and I4
if ((Object)(object)mod.exactRoom != (Object)null)
{
if (requireSpecialCategory && (int)mod.exactRoom.category != 5)
{
return false;
}
return true;
}
if (mod.roomTable?.includedRooms?.elements != null && mod.roomTable.includedRooms.elements.Count > 0)
{
if (requireSpecialCategory)
{
foreach (WeightedRoom element in mod.roomTable.includedRooms.elements)
{
if ((Object)(object)element?.room != (Object)null && (int)element.room.category == 5)
{
return true;
}
}
if (mod.roomTable.includedRoomTables != null)
{
foreach (GenericRoomTable includedRoomTable in mod.roomTable.includedRoomTables)
{
if (includedRoomTable?.includedRooms?.elements == null)
{
continue;
}
foreach (WeightedRoom element2 in includedRoomTable.includedRooms.elements)
{
if ((Object)(object)element2?.room != (Object)null && (int)element2.room.category == 5)
{
return true;
}
}
}
}
return false;
}
return true;
}
if (mod.roomTable?.includedRoomTables != null)
{
foreach (GenericRoomTable includedRoomTable2 in mod.roomTable.includedRoomTables)
{
if (includedRoomTable2?.includedRooms?.elements != null && includedRoomTable2.includedRooms.elements.Count > 0)
{
return true;
}
}
}
return false;
}
private static bool IsAnnotationBlacklisted(string lowerKey, string lowerAnnotation)
{
for (int i = 0; i < AnnotationBlacklist.Length; i++)
{
string value = AnnotationBlacklist[i];
if (lowerKey.Contains(value) || lowerAnnotation.Contains(value))
{
return true;
}
}
return false;
}
private static void OnPreDungeonGen(LoopDungeonGenerator generator, Dungeon dungeon, DungeonFlow flow, int dungeonSeed)
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Invalid comparison between Unknown and I4
//IL_0149: Unknown result type (might be due to invalid IL or missing references)
//IL_014e: Unknown result type (might be due to invalid IL or missing references)
//IL_0160: Unknown result type (might be due to invalid IL or missing references)
//IL_0167: Unknown result type (might be due to invalid IL or missing references)
//IL_016e: Unknown result type (might be due to invalid IL or missing references)
//IL_0187: Unknown result type (might be due to invalid IL or missing references)
//IL_0194: Unknown result type (might be due to invalid IL or missing references)
//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
//IL_01c3: 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_01d9: Unknown result type (might be due to invalid IL or missing references)
//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
//IL_0204: Unknown result type (might be due to invalid IL or missing references)
//IL_020d: Expected O, but got Unknown
//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
int value = Plugin.ExtraNpcCount.Value;
if (value <= 0)
{
return;
}
if ((int)dungeon.tileIndices.tilesetId == 64)
{
Plugin.Log.LogInfo((object)"[BetterShop] 裂隙层已排除,不注入额外 NPC。");
}
else
{
if (((Object)flow).name == "Foyer Flow" || GameManager.IsReturningToFoyerWithPlayer)
{
return;
}
Plugin.Log.LogInfo((object)"[BetterShop] 正在从所有注入源收集 NPC...");
List<NpcCandidate> list = CollectAllNpcRooms(flow);
if (list.Count == 0)
{
Plugin.Log.LogWarning((object)"[BetterShop] 未找到任何有效的 NPC 房间!");
return;
}
Plugin.Log.LogInfo((object)$"[BetterShop] 已收集 {list.Count} 个 NPC 候选:");
for (int i = 0; i < list.Count; i++)
{
string arg = GetModifierKey(list[i].Modifier) ?? "?";
string sourceName = list[i].SourceName;
Plugin.Log.LogInfo((object)$" [{i}] {arg} ({sourceName})");
}
int num = Mathf.Min(value, list.Count);
List<NpcCandidate> list2 = new List<NpcCandidate>(list);
for (int j = 0; j < num; j++)
{
int index = Random.Range(0, list2.Count);
ProceduralFlowModifierData modifier = list2[index].Modifier;
list2.RemoveAt(index);
string text = GetModifierKey(modifier) ?? "unknown";
ProceduralFlowModifierData item = new ProceduralFlowModifierData
{
annotation = "BetterShop Extra NPC: " + text,
DEBUG_FORCE_SPAWN = false,
OncePerRun = false,
placementRules = new List<FlowModifierPlacementType>
{
(FlowModifierPlacementType)1,
(FlowModifierPlacementType)3
},
roomTable = modifier.roomTable,
exactRoom = modifier.exactRoom,
exactSecondaryRoom = modifier.exactSecondaryRoom,
framedCombatNodes = 0,
IsWarpWing = false,
RequiresMasteryToken = false,
chanceToLock = 0f,
selectionWeight = 300f,
chanceToSpawn = 1f,
RequiredValidPlaceable = modifier.RequiredValidPlaceable,
prerequisites = (DungeonPrerequisite[])(object)new DungeonPrerequisite[0],
CanBeForcedSecret = false,
RandomNodeChildMinDistanceFromEntrance = 0
};
SharedInjectionData val = ScriptableObject.CreateInstance<SharedInjectionData>();
((Object)val).name = "BetterShop_ExtraNPC_" + text;
val.UseInvalidWeightAsNoInjection = true;
val.PreventInjectionOfFailedPrerequisites = false;
val.IsNPCCell = true;
val.IgnoreUnmetPrerequisiteEntries = false;
val.OnlyOne = false;
val.ChanceToSpawnOne = 1f;
val.AttachedInjectionData = new List<SharedInjectionData>();
val.InjectionData = new List<ProceduralFlowModifierData> { item };
if (flow.sharedInjectionData == null)
{
flow.sharedInjectionData = new List<SharedInjectionData>();
}
flow.sharedInjectionData.Add(val);
Plugin.Log.LogInfo((object)$"[BetterShop] 额外 NPC 注入成功:{text} (层: {dungeon.tileIndices.tilesetId})");
}
Plugin.Log.LogInfo((object)$"[BetterShop] 共注入 {num} 个额外 NPC。");
}
}
}
public static class HellShopGenerator
{
public static void Init()
{
DungeonHooks.OnPreDungeonGeneration += InjectHellShopViaInjection;
}
private static void InjectHellShopViaInjection(LoopDungeonGenerator generator, Dungeon dungeon, DungeonFlow flow, int dungeonSeed)
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Invalid comparison between Unknown and I4
//IL_0310: Unknown result type (might be due to invalid IL or missing references)
//IL_0315: Unknown result type (might be due to invalid IL or missing references)
//IL_0320: Unknown result type (might be due to invalid IL or missing references)
//IL_0327: Unknown result type (might be due to invalid IL or missing references)
//IL_032e: Unknown result type (might be due to invalid IL or missing references)
//IL_0347: Unknown result type (might be due to invalid IL or missing references)
//IL_034e: Unknown result type (might be due to invalid IL or missing references)
//IL_0355: Unknown result type (might be due to invalid IL or missing references)
//IL_035c: Unknown result type (might be due to invalid IL or missing references)
//IL_0363: Unknown result type (might be due to invalid IL or missing references)
//IL_036a: Unknown result type (might be due to invalid IL or missing references)
//IL_0371: Unknown result type (might be due to invalid IL or missing references)
//IL_037c: Unknown result type (might be due to invalid IL or missing references)
//IL_0387: Unknown result type (might be due to invalid IL or missing references)
//IL_0392: Unknown result type (might be due to invalid IL or missing references)
//IL_0399: Unknown result type (might be due to invalid IL or missing references)
//IL_03a5: Unknown result type (might be due to invalid IL or missing references)
//IL_03ac: Unknown result type (might be due to invalid IL or missing references)
//IL_03b4: Expected O, but got Unknown
if (!Plugin.BulletHellShopEnabled.Value || (int)dungeon.tileIndices.tilesetId != 128)
{
return;
}
Plugin.Log.LogInfo((object)"[BetterShop] 正在适配注入 Bello 商店至第六层...");
Dungeon orLoadByName = DungeonDatabase.GetOrLoadByName("Base_Castle");
PrototypeDungeonRoom val = null;
string text = null;
foreach (DungeonFlow flow2 in orLoadByName.PatternSettings.flows)
{
if (flow2.sharedInjectionData != null)
{
foreach (SharedInjectionData sharedInjectionDatum in flow2.sharedInjectionData)
{
if ((Object)(object)sharedInjectionDatum == (Object)null || sharedInjectionDatum.InjectionData == null)
{
continue;
}
foreach (ProceduralFlowModifierData injectionDatum in sharedInjectionDatum.InjectionData)
{
if ((Object)(object)injectionDatum.exactRoom != (Object)null && ((Object)injectionDatum.exactRoom).name.ToLower().Contains("shop"))
{
val = injectionDatum.exactRoom;
text = "SharedInjectionData";
break;
}
}
if ((Object)(object)val != (Object)null)
{
break;
}
}
}
if ((Object)(object)val != (Object)null)
{
break;
}
foreach (DungeonFlowNode allNode in flow2.AllNodes)
{
if ((Object)(object)allNode.overrideExactRoom != (Object)null && ((Object)allNode.overrideExactRoom).name.ToLower().Contains("shop"))
{
val = allNode.overrideExactRoom;
text = "FlowNode.overrideExactRoom";
break;
}
}
if ((Object)(object)val != (Object)null)
{
break;
}
foreach (DungeonFlowNode allNode2 in flow2.AllNodes)
{
if ((Object)(object)allNode2.overrideRoomTable != (Object)null && allNode2.overrideRoomTable.includedRooms != null)
{
foreach (WeightedRoom element in allNode2.overrideRoomTable.includedRooms.elements)
{
if ((Object)(object)element.room != (Object)null && ((Object)element.room).name.ToLower().Contains("shop"))
{
val = element.room;
text = "FlowNode.overrideRoomTable";
break;
}
}
}
if ((Object)(object)val != (Object)null)
{
break;
}
}
if ((Object)(object)val != (Object)null)
{
break;
}
}
if ((Object)(object)val == (Object)null)
{
Plugin.Log.LogError((object)"[BetterShop] 无法在 Castle 资源中找到商店模板!(已搜索 SharedInjectionData / FlowNode / RoomTable)");
return;
}
Plugin.Log.LogInfo((object)("[BetterShop] 找到商店模板: " + ((Object)val).name + " (来源: " + text + ")"));
ProceduralFlowModifierData item = new ProceduralFlowModifierData
{
annotation = "Bello Shop Injector",
DEBUG_FORCE_SPAWN = false,
OncePerRun = false,
placementRules = new List<FlowModifierPlacementType>
{
(FlowModifierPlacementType)1,
(FlowModifierPlacementType)3
},
roomTable = null,
exactRoom = val,
exactSecondaryRoom = null,
framedCombatNodes = 0,
IsWarpWing = false,
RequiresMasteryToken = false,
chanceToLock = 0f,
selectionWeight = 10000f,
chanceToSpawn = 1f,
RequiredValidPlaceable = null,
prerequisites = (DungeonPrerequisite[])(object)new DungeonPrerequisite[0],
CanBeForcedSecret = false,
RandomNodeChildMinDistanceFromEntrance = 0
};
SharedInjectionData val2 = ScriptableObject.CreateInstance<SharedInjectionData>();
((Object)val2).name = "BetterShop_Hell_Injection";
val2.UseInvalidWeightAsNoInjection = true;
val2.PreventInjectionOfFailedPrerequisites = false;
val2.IsNPCCell = false;
val2.IgnoreUnmetPrerequisiteEntries = false;
val2.OnlyOne = false;
val2.ChanceToSpawnOne = 1f;
val2.AttachedInjectionData = new List<SharedInjectionData>();
val2.InjectionData = new List<ProceduralFlowModifierData> { item };
if (flow.sharedInjectionData == null)
{
flow.sharedInjectionData = new List<SharedInjectionData>();
}
flow.sharedInjectionData.Add(val2);
Plugin.Log.LogInfo((object)"[BetterShop] 注入成功:商店已加入第六层生成队列。");
}
}
[HarmonyPatch(typeof(BaseShopController), "DoSetup")]
public class ShopGuaranteePatch
{
private static bool IsRealItem(PickupObject item)
{
if ((Object)(object)item == (Object)null || item is Gun)
{
return false;
}
if (item is HealthPickup || item is AmmoPickup || item is KeyBulletPickup || item is SilencerItem)
{
return false;
}
if (item.PickupObjectId == 565 || item.PickupObjectId == 137 || item.PickupObjectId == 316)
{
return false;
}
if (!(item is PlayerItem))
{
return item is PassiveItem;
}
return true;
}
[HarmonyPostfix]
public static void Postfix(BaseShopController __instance, ref List<ShopItemController> ___m_itemControllers, ref List<GameObject> ___m_shopItems)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
if ((int)__instance.baseShopType != 0)
{
return;
}
if (GameStatsManager.Instance != null && GameStatsManager.Instance.IsRainbowRun)
{
Plugin.Log.LogInfo((object)"[BetterShop] 彩虹模式,保底已禁用。");
return;
}
int value = Plugin.MinGuns.Value;
int value2 = Plugin.MinItems.Value;
if ((value <= 0 && value2 <= 0) || ___m_itemControllers == null || ___m_itemControllers.Count == 0)
{
return;
}
int num = 0;
int num2 = 0;
int num3 = ((__instance.spawnPositions != null) ? __instance.spawnPositions.Length : 0);
Plugin.Log.LogInfo((object)"==================================================");
Plugin.Log.LogInfo((object)"[BetterShop] 商店生成完毕,扫描台面物品...");
for (int i = 0; i < ___m_itemControllers.Count; i++)
{
ShopItemController val = ___m_itemControllers[i];
if (!((Object)(object)val == (Object)null) && !((Object)(object)val.item == (Object)null))
{
string text = "消耗品/杂物";
if (val.item is Gun)
{
num++;
text = "【枪械】";
}
else if (IsRealItem(val.item))
{
num2++;
text = "【道具】";
}
Plugin.Log.LogInfo((object)$" [{i}] ID:{val.item.PickupObjectId,-4} {text,-8} {val.item.EncounterNameOrDisplayName}");
}
}
Plugin.Log.LogInfo((object)$"[BetterShop] 枪:{num}/{value} 道具:{num2}/{value2}");
bool flag = num < value;
bool flag2 = num2 < value2;
if (!flag && !flag2)
{
Plugin.Log.LogInfo((object)"[BetterShop] 已达标!");
Plugin.Log.LogInfo((object)"==================================================\n");
return;
}
Transform[] spawnPositionsGroup = __instance.spawnPositionsGroup2;
if (spawnPositionsGroup == null || spawnPositionsGroup.Length == 0)
{
Plugin.Log.LogWarning((object)"[BetterShop] 无 Group2 位置,无法补齐。");
Plugin.Log.LogInfo((object)"==================================================\n");
return;
}
List<int> list = new List<int>();
List<int> list2 = new List<int>();
HashSet<int> hashSet = new HashSet<int>();
for (int j = num3; j < ___m_itemControllers.Count; j++)
{
ShopItemController val2 = ___m_itemControllers[j];
if ((Object)(object)val2 == (Object)null)
{
continue;
}
for (int k = 0; k < spawnPositionsGroup.Length; k++)
{
if ((Object)(object)((BraveBehaviour)val2).transform.parent == (Object)(object)spawnPositionsGroup[k])
{
hashSet.Add(k);
if ((Object)(object)val2.item != (Object)null && !(val2.item is Gun) && !IsRealItem(val2.item))
{
list2.Add(j);
}
break;
}
}
}
for (int l = 0; l < spawnPositionsGroup.Length; l++)
{
if (!hashSet.Contains(l))
{
list.Add(l);
}
}
Plugin.Log.LogInfo((object)$"[BetterShop] Group2 空位:{list.Count} 消耗品位:{list2.Count}");
PlayerController primaryPlayer = GameManager.Instance.PrimaryPlayer;
if (flag)
{
if (list.Count > 0)
{
int num4 = list[0];
list.RemoveAt(0);
GameObject rewardObjectShopStyle = GameManager.Instance.RewardManager.GetRewardObjectShopStyle(primaryPlayer, true, false, ___m_shopItems);
if ((Object)(object)rewardObjectShopStyle != (Object)null)
{
PickupObject component = rewardObjectShopStyle.GetComponent<PickupObject>();
if ((Object)(object)component != (Object)null)
{
SpawnShopItem(component, spawnPositionsGroup[num4], __instance, ___m_itemControllers, ___m_shopItems);
num++;
Plugin.Log.LogInfo((object)$"[BetterShop] >>> 空位补枪: [{component.EncounterNameOrDisplayName}] (ID:{component.PickupObjectId})");
}
}
}
else if (list2.Count > 0)
{
int index = list2[0];
list2.RemoveAt(0);
GameObject rewardObjectShopStyle2 = GameManager.Instance.RewardManager.GetRewardObjectShopStyle(primaryPlayer, true, false, ___m_shopItems);
if ((Object)(object)rewardObjectShopStyle2 != (Object)null)
{
PickupObject component2 = rewardObjectShopStyle2.GetComponent<PickupObject>();
if ((Object)(object)component2 != (Object)null)
{
PickupObject item = ___m_itemControllers[index].item;
string text2 = ((item != null) ? item.EncounterNameOrDisplayName : null) ?? "?";
___m_itemControllers[index].Initialize(component2, __instance);
num++;
Plugin.Log.LogInfo((object)("[BetterShop] >>> 替换补枪: [" + text2 + "] -> [" + component2.EncounterNameOrDisplayName + "]"));
}
}
}
}
if (num2 < value2)
{
if (list.Count > 0)
{
int num5 = list[0];
list.RemoveAt(0);
PickupObject guaranteedItem = GetGuaranteedItem(__instance, ___m_shopItems);
if ((Object)(object)guaranteedItem != (Object)null)
{
SpawnShopItem(guaranteedItem, spawnPositionsGroup[num5], __instance, ___m_itemControllers, ___m_shopItems);
num2++;
Plugin.Log.LogInfo((object)$"[BetterShop] >>> 空位补道具: [{guaranteedItem.EncounterNameOrDisplayName}] (ID:{guaranteedItem.PickupObjectId})");
}
}
else if (list2.Count > 0)
{
int index2 = list2[0];
list2.RemoveAt(0);
PickupObject guaranteedItem2 = GetGuaranteedItem(__instance, ___m_shopItems);
if ((Object)(object)guaranteedItem2 != (Object)null)
{
PickupObject item2 = ___m_itemControllers[index2].item;
string text3 = ((item2 != null) ? item2.EncounterNameOrDisplayName : null) ?? "?";
___m_itemControllers[index2].Initialize(guaranteedItem2, __instance);
num2++;
Plugin.Log.LogInfo((object)("[BetterShop] >>> 替换补道具: [" + text3 + "] -> [" + guaranteedItem2.EncounterNameOrDisplayName + "]"));
}
}
}
Plugin.Log.LogInfo((object)$"[BetterShop] 最终: 枪:{num} 道具:{num2}");
Plugin.Log.LogInfo((object)"==================================================\n");
}
private static void SpawnShopItem(PickupObject pickup, Transform spawnPos, BaseShopController shop, List<ShopItemController> controllers, List<GameObject> shopItems)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: 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)
//IL_0092: 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)
GameObject val = new GameObject("Shop guaranteed item");
val.transform.parent = spawnPos;
val.transform.localPosition = Vector3.zero;
EncounterTrackable component = ((Component)pickup).GetComponent<EncounterTrackable>();
if ((Object)(object)component != (Object)null)
{
GameManager.Instance.ExtantShopTrackableGuids.Add(component.EncounterGuid);
}
ShopItemController val2 = val.AddComponent<ShopItemController>();
if (((Object)spawnPos).name.Contains("SIDE") || ((Object)spawnPos).name.Contains("EAST"))
{
val2.itemFacing = (Direction)2;
}
else if (((Object)spawnPos).name.Contains("WEST"))
{
val2.itemFacing = (Direction)6;
}
else if (((Object)spawnPos).name.Contains("NORTH"))
{
val2.itemFacing = (Direction)0;
}
RoomHandler absoluteParentRoom = ((DungeonPlaceableBehaviour)shop).GetAbsoluteParentRoom();
if (absoluteParentRoom != null && !absoluteParentRoom.IsRegistered((IPlayerInteractable)(object)val2))
{
absoluteParentRoom.RegisterInteractable((IPlayerInteractable)(object)val2);
}
val2.Initialize(pickup, shop);
controllers.Add(val2);
shopItems.Add(((Component)pickup).gameObject);
}
private static PickupObject GetGuaranteedItem(BaseShopController shop, List<GameObject> exclude)
{
PlayerController primaryPlayer = GameManager.Instance.PrimaryPlayer;
for (int i = 0; i < 10; i++)
{
GameObject rewardObjectShopStyle = GameManager.Instance.RewardManager.GetRewardObjectShopStyle(primaryPlayer, false, false, exclude);
if (!((Object)(object)rewardObjectShopStyle == (Object)null))
{
PickupObject component = rewardObjectShopStyle.GetComponent<PickupObject>();
if ((Object)(object)component != (Object)null && IsRealItem(component))
{
return component;
}
}
}
GameObject val = shop.shopItems.SelectByWeightWithoutDuplicatesFullPrereqs(exclude, (Func<GameObject, float, float>)null, GameManager.Instance.IsSeeded);
if ((Object)(object)val != (Object)null)
{
PickupObject component2 = val.GetComponent<PickupObject>();
if ((Object)(object)component2 != (Object)null && IsRealItem(component2))
{
return component2;
}
}
Plugin.Log.LogWarning((object)"[BetterShop] 无法找到合适的道具进行补齐。");
return null;
}
}
}