138 lines
5.7 KiB
C#
138 lines
5.7 KiB
C#
using System;
|
||
using Cielonos.MainGame.Characters;
|
||
using Cielonos.MainGame.Inventory.Collections;
|
||
using UnityEngine;
|
||
|
||
namespace Cielonos.MainGame
|
||
{
|
||
/// <summary>
|
||
/// 战斗房间生命周期状态。
|
||
/// </summary>
|
||
public enum CombatRoomState
|
||
{
|
||
Inactive, // 未进入任何战斗房间
|
||
Fighting, // 战斗进行中
|
||
Cleared, // 全部敌人已清除
|
||
}
|
||
|
||
public partial class CombatManager
|
||
{
|
||
/// <summary>
|
||
/// 战斗房间生命周期子模块。
|
||
/// 负责监听敌人死亡事件,在房间清空时触发 OnRoomCleared。
|
||
/// </summary>
|
||
public class CombatRoomSubmodule : SubmoduleBase<CombatManager>
|
||
{
|
||
// ----------------------------------------------------------------
|
||
// 状态
|
||
// ----------------------------------------------------------------
|
||
|
||
/// <summary>当前战斗房间的生命周期状态。</summary>
|
||
public CombatRoomState roomState = CombatRoomState.Inactive;
|
||
|
||
// ----------------------------------------------------------------
|
||
// 事件
|
||
// ----------------------------------------------------------------
|
||
|
||
/// <summary>
|
||
/// 战斗房间内所有敌人清除时触发。
|
||
/// 由外部系统(RunManager、RewardDispatcher 等)监听,执行掉落和阶段切换。
|
||
/// </summary>
|
||
public event Action OnRoomCleared;
|
||
|
||
/// <summary>
|
||
/// 单个敌人死亡时触发。参数为死亡的敌人实例,供货币/统计系统使用。
|
||
/// </summary>
|
||
public event Action<CharacterBase> OnEnemyDefeated;
|
||
|
||
// ----------------------------------------------------------------
|
||
// 构造
|
||
// ----------------------------------------------------------------
|
||
|
||
public CombatRoomSubmodule(CombatManager owner) : base(owner)
|
||
{
|
||
}
|
||
|
||
// ----------------------------------------------------------------
|
||
// 公共 API
|
||
// ----------------------------------------------------------------
|
||
|
||
/// <summary>
|
||
/// 开始一场战斗房间。绑定敌人移除事件,将状态置为 Fighting。
|
||
/// 应在 ZoneManager 完成敌人生成之后调用。
|
||
/// 若当前敌人列表为空(已被清空或无敌人配置),立即标记 Cleared 并触发 OnRoomCleared。
|
||
/// </summary>
|
||
public void StartRoom()
|
||
{
|
||
// 防御性取消订阅,避免因上一场未正确 Reset 导致重复注册
|
||
owner.enemySm.OnEnemyRemoved -= HandleEnemyRemoved;
|
||
|
||
if (owner.enemySm.activeEnemiesList.Count == 0)
|
||
{
|
||
// 无敌人可战斗,直接标记清空
|
||
roomState = CombatRoomState.Cleared;
|
||
Debug.Log("[CombatManager] 战斗房间无敌人,直接标记已清空。");
|
||
OnRoomCleared?.Invoke();
|
||
return;
|
||
}
|
||
|
||
roomState = CombatRoomState.Fighting;
|
||
owner.enemySm.OnEnemyRemoved += HandleEnemyRemoved;
|
||
//Debug.Log($"[CombatManager] 战斗房间开始,当前敌人数:{owner.enemySm.activeEnemiesList.Count}");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 手动结束/重置战斗房间(场景切换或放弃时调用)。
|
||
/// 解绑事件并重置状态,不触发 OnRoomCleared。
|
||
/// </summary>
|
||
public void Reset()
|
||
{
|
||
owner.enemySm.OnEnemyRemoved -= HandleEnemyRemoved;
|
||
owner.enemySm.Reset();
|
||
owner.coordinatorSm.Reset();
|
||
roomState = CombatRoomState.Inactive;
|
||
//Debug.Log("[CombatManager] 战斗房间已重置。");
|
||
}
|
||
|
||
// ----------------------------------------------------------------
|
||
// 内部实现
|
||
// ----------------------------------------------------------------
|
||
|
||
/// <summary>监听 EnemySubmodule.OnEnemyRemoved,判断房间是否清空。</summary>
|
||
private void HandleEnemyRemoved(CharacterBase enemy)
|
||
{
|
||
if (roomState != CombatRoomState.Fighting) return;
|
||
|
||
OnEnemyDefeated?.Invoke(enemy);
|
||
GrantCurrencyDrop(enemy);
|
||
//Debug.Log($"[CombatManager] 敌人死亡:{enemy.name},剩余:{owner.enemySm.activeEnemiesList.Count}");
|
||
|
||
if (owner.enemySm.activeEnemiesList.Count > 0)
|
||
{
|
||
return;
|
||
}
|
||
|
||
// 所有敌人已清除
|
||
roomState = CombatRoomState.Cleared;
|
||
owner.enemySm.OnEnemyRemoved -= HandleEnemyRemoved;
|
||
//Debug.Log("[CombatManager] 战斗房间已清空,触发 OnRoomCleared。");
|
||
OnRoomCleared?.Invoke();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 根据死亡敌人的 EnemyRank 向玩家发放对应数量的稀有材料。
|
||
/// </summary>
|
||
private void GrantCurrencyDrop(CharacterBase enemy)
|
||
{
|
||
if (enemy is not Enemy typedEnemy) return;
|
||
|
||
System.Random rng = new System.Random();
|
||
int amount = MainGameManager.Config.RollCurrency(typedEnemy.enemyRank, rng);
|
||
|
||
MainGameManager.Player.inventorySc.backpackSm.ObtainItem<RareMaterial>(amount);
|
||
//Debug.Log($"[CombatRoomSubmodule] 击杀 {typedEnemy.enemyRank} 敌人,获得稀有材料 x{amount}。");
|
||
}
|
||
}
|
||
}
|
||
}
|