using System; using System.Collections.Generic; using Cielonos.Core.Interaction; using Cielonos.MainGame.Characters; using Cielonos.MainGame.Inventory; using Cielonos.MainGame.Inventory.Collections; using Cielonos.MainGame.Items; using Cielonos.MainGame.Rewards; using Cielonos.MainGame.UI; using Sirenix.OdinInspector; using UnityEngine; namespace Cielonos.MainGame.Interactions { /// /// 物流中心(商店)场景交互对象。 /// 玩家靠近按交互键后呼出 LogisticCenterUIPage,显示可购买的随机装备。 /// 商店可反复打开(不像机械台单次使用),商品在首次进入时生成,买完即消失。 /// 货币通过消耗背包中的 RareMaterial 消耗品来支付。 /// public class LogisticsCenter : InteractableObjectBase { [TitleGroup("Reward Profile")] [SerializeField, Required] private RewardProfile _profile; private List currentOffers; private bool isInitialized; protected override void InitializeChoices() { choices.Add(new InteractionChoice("Open Logistic Center", OpenShop)); } /// /// 由 RunManager 或场景加载逻辑调用,预先生成本次商店的商品列表和价格。 /// 若未调用此方法,交互时会自动从 Resources/Items 中生成。 /// /// 本局 Run 的随机数生成器。 public void Setup(System.Random rng) { currentOffers = RollShopOffers(rng); isInitialized = true; } private void OpenShop() { if (!isInitialized) { System.Random rng = RunManager.Instance?.currentRun?.randomizer?.Next() ?? new System.Random(); currentOffers = RollShopOffers(rng); isInitialized = true; } if (currentOffers == null || currentOffers.Count == 0) { Debug.LogWarning("[LogisticCenter] 候选池为空,没有可售卖的装备。"); return; } var uiPage = PlayerCanvas.MainGamePages.logisticsCenterPage; uiPage.SetOffers(currentOffers, HandlePurchase); uiPage.Open(); } private void HandlePurchase(int index) { if (index < 0 || index >= currentOffers.Count) return; ShopOffer offer = currentOffers[index]; // 获取玩家背包中的 RareMaterial PlayerInventorySubcontroller inventorySc = MainGameManager.Player.inventorySc; RareMaterial rareMaterial = MainGameManager.Player.inventorySc.GetRareMaterial(); if (rareMaterial == null || rareMaterial.stackAmount < offer.price) { Debug.Log("[LogisticCenter] RareMaterial 不足,无法购买。"); return; } // 扣除 RareMaterial rareMaterial.Use(offer.price); int remaining = rareMaterial != null ? rareMaterial.stackAmount : 0; // 将物品加入背包 inventorySc.backpackSm.ObtainItemPrefab(offer.item); // 从商品列表中移除已购买的商品 currentOffers.RemoveAt(index); Debug.Log($"[LogisticCenter] 玩家购买了 '{offer.item.name}',花费 {offer.price} RareMaterial,剩余 {remaining}。"); } /// /// 从 RewardProfile 生成商店候选并生成包含价格的 ShopOffer。 /// Profile 可明确限制可用主武器,避免废弃武器自动进入商店池。 /// private List RollShopOffers(System.Random rng) { if (_profile == null) { Debug.LogError("[LogisticsCenter] RewardProfile is not assigned."); return new List(); } List rolledItems = RewardGenerator.GeneratePrefabOffers(_profile, rng, RewardGenerationContext.FromPlayer().ExcludeOwnedNonConsumables()); List offers = new List(rolledItems.Count); foreach (ItemBase item in rolledItems) { if (item == null || item.contentData == null) continue; int price = MainGameManager.Config.RollPrice(item.contentData.itemRarity, rng); offers.Add(new ShopOffer(item, price)); } return offers; } } /// /// 商店中的单个商品条目:包含物品预制体引用和售价。 /// [Serializable] public class ShopOffer { public ItemBase item; public int price; public ShopOffer(ItemBase item, int price) { this.item = item; this.price = price; } } }