Files
Cielonos/Assets/Scripts/MainGame/Narrative/CustomFunctions/CustomFunctions.cs
SoulliesOfficial 9a9e48f8a5
2026-06-27 12:52:03 -04:00

107 lines
5.0 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 Cielonos.MainGame;
using Cielonos.MainGame.Inventory;
using Cielonos.MainGame.Narrative;
using UnityEngine;
using Yarn.Unity;
namespace Cielonos.Narrative
{
public static partial class CustomFunctions
{
/// <summary>
/// 提供给 Yarn Spinner 调用的自定义函数,用于在对话中给予玩家指定物品。
/// 物品在授予后,会自动写入 InfoTransistor 中的 StartInventory以便跨场景保存。
/// </summary>
/// <param name="itemClass">物品的类名(需存在于 Inventory.Collections 命名空间下)</param>
/// <param name="stackAmount">物品的数量/层数,默认为 1</param>
[YarnCommand("obtain_item")]
public static void ObtainItem(string itemClass, int stackAmount = 1)
{
PlayerInventorySaveData startInventory = InfoTransistor.GetInfo<PlayerInventorySaveData>("StartInventory");
if (startInventory == null)
{
// 如果当前不存在过渡存档数据,说明这是本次场景内的第一次额外物品获取。
// 此时建立一个空的 SaveData 作为起始收集器。
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;
}
ItemBase item = MainGameManager.Player.inventorySc.backpackSm.ObtainItem(type, stackAmount);
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)
{
MainGameManager.Player.inventorySc.backpackSm.ObtainItem(passiveEquipment);
startInventory.passiveEquipments.Add(itemSaveData);
}
else if (item is ConsumableBase consumable)
{
itemSaveData.stackAmount = stackAmount;
startInventory.consumables.Add(itemSaveData);
Debug.Log($"[obtain_item] Obtained consumable '{itemClass}' with stack amount {stackAmount}.");
}
}
[YarnFunction("check_have_item")]
public static bool CheckHaveItem(string itemClass)
{
return MainGameManager.Player.inventorySc.backpackSm.HaveItem(itemClass);
}
/// <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}'");
}
}
}
}