Files
Cielonos/Assets/Scripts/MainGame/Managers/CombatManager/CombatRoomSubmodule/CombatRoomSubmodule.cs

138 lines
5.7 KiB
C#
Raw Normal View History

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