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
}
}