using UnityEngine; using BaseGames.Core.Events; namespace BaseGames.Quest { /// /// 任务奖励 SO(架构 22_QuestChallengeModule §4)。 /// 由 QuestManager.CompleteQuest() 调用 Apply() 发放奖励。 /// 资产路径: Assets/ScriptableObjects/Quest/Reward_{questId}.asset /// [CreateAssetMenu(menuName = "Quest/Reward")] public class RewardSO : ScriptableObject { public int geo; // Geo 货币奖励 public int soulBonus; // 灵魂槽扩展(+MaxSoulPower) public string[] itemIds; // 物品/护符 ID 列表(通过 InventoryManager 发放) public int affinityBonus; // 对发布 NPC 的好感度增量(存入 SaveData.World.NpcRelations) public string unlockDialogueKey; // 解锁 NPC 新台词集合 key(架构 §4) [Tooltip("是否解锁能力(AbilityType 无 None 值,用 bool 标识)")] public bool unlocksAbility; // ⚠️ AbilityType 无 None,用 bool 标识 public uint unlockedAbilityFlag; // AbilityType 的 uint 位掩码值(仅当 unlocksAbility == true 有效) [Header("物品发放事件")] [Tooltip("EVT_CollectiblePickup:向 QuestManager/EquipmentManager 广播 itemId")] [SerializeField] private StringEventChannelSO _onCollectiblePickup; /// /// 将奖励应用到游戏状态(由 QuestManager.CompleteQuest 调用)。 /// 通过 接口操作,避免直接依赖 BaseGames.Player 程序集。 /// public void Apply(IRewardTarget target) { if (target == null) return; if (geo > 0) target.AddGeo(geo); if (soulBonus > 0) target.AddSoulPower(soulBonus); if (unlocksAbility && unlockedAbilityFlag != 0) target.UnlockAbilityFlag(unlockedAbilityFlag); // 通过 EVT_CollectiblePickup 事件频道广播每个物品 ID if (itemIds != null && _onCollectiblePickup != null) { foreach (var id in itemIds) _onCollectiblePickup.Raise(id); } } } }