Files
Cielonos/Assets/Scripts/MainGame/Narrative/CustomFunctions/CustomFunctions.cs

107 lines
5.0 KiB
C#
Raw Normal View History

2026-06-05 04:21:00 -04:00
using System;
using Cielonos.MainGame;
using Cielonos.MainGame.Inventory;
2026-06-27 12:52:03 -04:00
using Cielonos.MainGame.Narrative;
2026-06-02 12:55:39 -04:00
using UnityEngine;
2026-06-05 04:21:00 -04:00
using Yarn.Unity;
2026-06-02 12:55:39 -04:00
namespace Cielonos.Narrative
{
public static partial class CustomFunctions
{
2026-06-27 12:52:03 -04:00
/// <summary>
/// 提供给 Yarn Spinner 调用的自定义函数,用于在对话中给予玩家指定物品。
/// 物品在授予后,会自动写入 InfoTransistor 中的 StartInventory以便跨场景保存。
/// </summary>
/// <param name="itemClass">物品的类名(需存在于 Inventory.Collections 命名空间下)</param>
/// <param name="stackAmount">物品的数量/层数,默认为 1</param>
2026-06-05 04:21:00 -04:00
[YarnCommand("obtain_item")]
2026-06-27 12:52:03 -04:00
public static void ObtainItem(string itemClass, int stackAmount = 1)
2026-06-05 04:21:00 -04:00
{
PlayerInventorySaveData startInventory = InfoTransistor.GetInfo<PlayerInventorySaveData>("StartInventory");
if (startInventory == null)
{
2026-06-27 12:52:03 -04:00
// 如果当前不存在过渡存档数据,说明这是本次场景内的第一次额外物品获取。
// 此时建立一个空的 SaveData 作为起始收集器。
2026-06-05 04:21:00 -04:00
InfoTransistor.SetInfo("StartInventory", new PlayerInventorySaveData());
startInventory = InfoTransistor.GetInfo<PlayerInventorySaveData>("StartInventory");
}
Type type = Type.GetType($"Cielonos.MainGame.Inventory.Collections.{itemClass}");
if (type == null)
{
Debug.LogError($"[YarnCommand] Cannot find item class type for name '{itemClass}'. Make sure it is in namespace Cielonos.MainGame.Inventory.Collections");
return;
}
2026-06-27 12:52:03 -04:00
ItemBase item = MainGameManager.Player.inventorySc.backpackSm.ObtainItem(type, stackAmount);
2026-06-05 04:21:00 -04:00
ItemSaveData itemSaveData = new ItemSaveData(itemClass);
if (item is MainWeaponBase mainWeapon)
{
MainGameManager.Player.inventorySc.equipmentSm.PrepareMainWeapon(mainWeapon);
MainGameManager.Player.inventorySc.equipmentSm.EquipMainWeapon(mainWeapon);
startInventory.mainWeapons.Add(itemSaveData);
startInventory.preparedMainWeapons.Add(itemSaveData);
startInventory.currentMainWeapon = itemSaveData;
}
else if (item is SupportEquipmentBase supportEquipment)
{
MainGameManager.Player.inventorySc.equipmentSm.EquipSupportEquipment(supportEquipment, 0);
startInventory.supportEquipments.Add(itemSaveData);
startInventory.currentSupportEquipments.Add(itemSaveData);
}
else if (item is PassiveEquipmentBase passiveEquipment)
{
2026-06-27 12:52:03 -04:00
MainGameManager.Player.inventorySc.backpackSm.ObtainItem(passiveEquipment);
2026-06-05 04:21:00 -04:00
startInventory.passiveEquipments.Add(itemSaveData);
}
else if (item is ConsumableBase consumable)
{
2026-06-27 12:52:03 -04:00
itemSaveData.stackAmount = stackAmount;
2026-06-05 04:21:00 -04:00
startInventory.consumables.Add(itemSaveData);
2026-06-27 12:52:03 -04:00
Debug.Log($"[obtain_item] Obtained consumable '{itemClass}' with stack amount {stackAmount}.");
2026-06-05 04:21:00 -04:00
}
}
2026-06-12 17:11:39 -04:00
[YarnFunction("check_have_item")]
public static bool CheckHaveItem(string itemClass)
{
return MainGameManager.Player.inventorySc.backpackSm.HaveItem(itemClass);
}
2026-06-27 12:52:03 -04:00
/// <summary>
/// 结束当前的地图事件Event
/// 调用后会通知 RunManager 将当前节点标记为已完成/已耗尽,并把系统状态恢复到 MapSelection 以便玩家继续前进。
/// </summary>
[YarnCommand("finish_event")]
public static void FinishEvent()
{
if (RunManager.Instance != null && RunManager.Instance.currentPhase == RunPhase.InEvent)
{
RunManager.Instance.CompleteCurrentNode();
Debug.Log("[CustomFunctions] finish_event: 当前地图事件已结束,系统状态已恢复到 MapSelection。");
}
}
/// <summary>
/// 耗尽/禁用指定的 NPC 交互(在剧情结束后彻底移除它的对话选项)。
/// 适用于那些不能被反复对话的 NPC或者需要等离开场景才重置交互逻辑的 NPC。
/// </summary>
/// <param name="npcID">NPC 的标识ID例如 "SupportPersonnel"</param>
[YarnCommand("exhaust_npc")]
public static void ExhaustNpc(string npcID)
{
if (StoryDirector.ActiveNpcs.TryGetValue(npcID, out var npc))
{
npc.SetExhausted();
Debug.Log($"[CustomFunctions] NPC '{npcID}' 交互已耗尽。");
}
else
{
Debug.LogWarning($"[CustomFunctions] exhaust_npc 找不到处于激活状态的 NPC: '{npcID}'");
}
}
2026-06-02 12:55:39 -04:00
}
}