135 lines
4.8 KiB
C#
135 lines
4.8 KiB
C#
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.UI;
|
||
using UnityEngine;
|
||
|
||
namespace Cielonos.MainGame.Interactions
|
||
{
|
||
/// <summary>
|
||
/// 物流中心(商店)场景交互对象。
|
||
/// 玩家靠近按交互键后呼出 LogisticCenterUIPage,显示可购买的随机装备。
|
||
/// 商店可反复打开(不像机械台单次使用),商品在首次进入时生成,买完即消失。
|
||
/// 货币通过消耗背包中的 RareMaterial 消耗品来支付。
|
||
/// </summary>
|
||
public class LogisticsCenter : InteractableObjectBase
|
||
{
|
||
private const int OFFER_COUNT = 5;
|
||
|
||
private List<ShopOffer> currentOffers;
|
||
private bool isInitialized;
|
||
|
||
protected override void InitializeChoices()
|
||
{
|
||
choices.Add(new InteractionChoice("Open Logistic Center", OpenShop));
|
||
}
|
||
|
||
/// <summary>
|
||
/// 由 RunManager 或场景加载逻辑调用,预先生成本次商店的商品列表和价格。
|
||
/// 若未调用此方法,交互时会自动从 Resources/Items 中生成。
|
||
/// </summary>
|
||
/// <param name="rng">本局 Run 的随机数生成器。</param
|
||
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.ObtainItem(offer.prefab);
|
||
|
||
// 从商品列表中移除已购买的商品
|
||
currentOffers.RemoveAt(index);
|
||
|
||
Debug.Log($"[LogisticCenter] 玩家购买了 '{offer.prefab.name}',花费 {offer.price} RareMaterial,剩余 {remaining}。");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 从 Resources/Items 中筛选可售卖的装备并生成 ShopOffer(含随机价格)。
|
||
/// 商店出售所有类型装备(MainWeapon、Support、Passive),但排除 None 稀有度。
|
||
/// </summary>
|
||
private static List<ShopOffer> RollShopOffers(System.Random rng)
|
||
{
|
||
ItemFilter filter = ItemFilter.ByRarity(ItemRarity.None).Not();
|
||
|
||
List<GameObject> rolledItems = ItemPoolHelper.Roll(
|
||
OFFER_COUNT, rng, filter,
|
||
"MainWeapon", "SupportEquipment", "PassiveEquipment"
|
||
);
|
||
|
||
List<ShopOffer> offers = new List<ShopOffer>(rolledItems.Count);
|
||
foreach (GameObject prefab in rolledItems)
|
||
{
|
||
ItemBase item = prefab.GetComponent<ItemBase>();
|
||
if (item == null || item.contentData == null) continue;
|
||
|
||
int price = MainGameManager.Config.RollPrice(item.contentData.itemRarity, rng);
|
||
offers.Add(new ShopOffer(prefab, price));
|
||
}
|
||
|
||
return offers;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 商店中的单个商品条目:包含物品预制体引用和售价。
|
||
/// </summary>
|
||
[Serializable]
|
||
public class ShopOffer
|
||
{
|
||
public GameObject prefab;
|
||
public int price;
|
||
|
||
public ShopOffer(GameObject prefab, int price)
|
||
{
|
||
this.prefab = prefab;
|
||
this.price = price;
|
||
}
|
||
}
|
||
}
|