using System.Collections;
using UnityEngine;
using UnityEngine.AddressableAssets;
using BaseGames.Core;
using BaseGames.Core.Events;
using BaseGames.Enemies;
using BaseGames.Player;
namespace BaseGames.Challenge
{
///
/// 挑战房间流程管理器(架构 22_QuestChallengeModule §12)。
/// 挂在挑战房间场景的 [ChallengeManager] GameObject 上,场景加载时自动启动挑战。
///
public class ChallengeRoomManager : MonoBehaviour
{
[SerializeField] private ChallengeRoomSO _challengeData;
[SerializeField] private PlayerStats _player; // 由场景 Inspector 绑定
[Header("Event Channels")]
[SerializeField] private StringEventChannelSO _onChallengeCompleted; // EVT_ChallengeCompleted
[SerializeField] private StringEventChannelSO _onChallengeFailed; // EVT_ChallengeFailed
private int _currentEncounterIndex;
private int _remainingEnemies;
private float _elapsedTime;
private bool _isRunning;
private bool _noHitViolated; // 架构 §12:requireNoHit 挑战是否被破坏
private void OnEnable()
{
if (_player != null) _player.OnDamaged += OnPlayerDamaged;
}
private void OnDisable()
{
if (_player != null) _player.OnDamaged -= OnPlayerDamaged;
}
private void OnPlayerDamaged() => _noHitViolated = true;
private void Start() => StartChallenge();
private void Update()
{
if (!_isRunning) return;
_elapsedTime += Time.deltaTime;
if (_challengeData.timeLimit > 0 && _elapsedTime >= _challengeData.timeLimit)
FailChallenge();
}
private void StartChallenge()
{
// 自动快速存档(失败后读档返回挑战入口)
ServiceLocator.GetOrDefault()?.QuickSave();
_isRunning = true;
_currentEncounterIndex = 0;
_elapsedTime = 0f;
_noHitViolated = false;
SpawnWave(0);
}
private void SpawnWave(int index)
{
if (_challengeData.encounters == null || index >= _challengeData.encounters.Length)
{
CompleteChallenge();
return;
}
var enc = _challengeData.encounters[index];
_remainingEnemies = 0;
foreach (var entry in enc.enemies)
{
for (int i = 0; i < entry.count; i++)
{
_remainingEnemies++;
Vector3 pos = entry.spawnPoint != null ? entry.spawnPoint.position : Vector3.zero;
Addressables.InstantiateAsync(entry.enemyAddressKey, pos, Quaternion.identity)
.Completed += handle =>
{
if (handle.Result != null &&
handle.Result.TryGetComponent(out var enemy))
{
enemy.OnDied += OnEnemyDefeated;
}
};
}
}
}
private void OnEnemyDefeated()
{
_remainingEnemies = Mathf.Max(0, _remainingEnemies - 1);
if (_remainingEnemies > 0) return;
_currentEncounterIndex++;
if (_currentEncounterIndex >= _challengeData.encounters.Length)
CompleteChallenge();
else
StartCoroutine(DelayedNextWave(_challengeData.encounters[_currentEncounterIndex].waveDelay));
}
private IEnumerator DelayedNextWave(float delay)
{
yield return new WaitForSeconds(delay);
SpawnWave(_currentEncounterIndex);
}
private void CompleteChallenge()
{
_isRunning = false;
// requireNoHit 挑战:受到伤害则判定失败(架构 §12)
if (_challengeData.requireNoHit && _noHitViolated)
{
FailChallenge();
return;
}
var reward = ServiceLocator.GetOrDefault() is { } sm && sm.IsFirstClear(_challengeData.challengeId)
? _challengeData.firstClearReward
: _challengeData.repeatedReward;
reward?.Apply(_player);
_onChallengeCompleted?.Raise(_challengeData.challengeId);
}
private void FailChallenge()
{
_isRunning = false;
_onChallengeFailed?.Raise(_challengeData.challengeId);
ServiceLocator.GetOrDefault()?.QuickLoad();
}
}
}