Files
Cielonos/Assets/Scripts/MainGame/Interactions/LogisticsCenter.cs
SoulliesOfficial 649b7a5ddc 更新
2026-05-23 08:27:50 -04:00

135 lines
4.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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;
}
}
}