using System.Collections.Generic; using GameFramework.DataTable; using GeometryTD.DataTable; using GeometryTD.Definition; using UnityEngine; using UnityGameFramework.Runtime; namespace GeometryTD.CustomComponent { /// /// 战斗节点组件 /// public class CombatNodeComponent : GameFrameworkComponent { // Level.Id => Level private readonly Dictionary _levelsById = new(); // LevelId => LevelPhases private readonly Dictionary> _phasesByLevelId = new(); // LevelPhase.Id => LevelSpawnEntries private readonly Dictionary> _spawnEntriesByPhaseId = new(); private readonly List _levelIdBuffer = new(); public LevelThemeType CurrentThemeType { get; private set; } public DRLevel CurrentLevel { get; private set; } public void OnInit(LevelThemeType themeType) { CurrentThemeType = themeType; CurrentLevel = null; _levelsById.Clear(); _phasesByLevelId.Clear(); _spawnEntriesByPhaseId.Clear(); _levelIdBuffer.Clear(); IDataTable dtLevel = GameEntry.DataTable.GetDataTable(); IDataTable dtLevelPhase = GameEntry.DataTable.GetDataTable(); IDataTable dtSpawnEntry = GameEntry.DataTable.GetDataTable(); if (dtLevel == null || dtLevelPhase == null || dtSpawnEntry == null) { Log.Warning("CombatNodeComponent init failed. Missing data table(s)."); return; } DRLevel[] levels = dtLevel.GetAllDataRows(); foreach (var level in levels) { if (level.LevelThemeType != themeType) { continue; } _levelsById[level.Id] = level; _phasesByLevelId[level.Id] = new List(); _levelIdBuffer.Add(level.Id); } DRLevelPhase[] levelPhases = dtLevelPhase.GetAllDataRows(); foreach (var phase in levelPhases) { int levelId = phase.Id / 1000; if (!_levelsById.ContainsKey(levelId)) { continue; } if (!_phasesByLevelId.TryGetValue(levelId, out List phases)) { phases = new List(); _phasesByLevelId[levelId] = phases; } phases.Add(phase); _spawnEntriesByPhaseId[phase.Id] = new List(); } DRLevelSpawnEntry[] spawnEntries = dtSpawnEntry.GetAllDataRows(); for (int i = 0; i < spawnEntries.Length; i++) { DRLevelSpawnEntry spawnEntry = spawnEntries[i]; int phaseId = spawnEntry.Id / 1000; int levelId = phaseId / 1000; if (!_levelsById.ContainsKey(levelId)) { continue; } if (!_spawnEntriesByPhaseId.TryGetValue(phaseId, out List entries)) { entries = new List(); _spawnEntriesByPhaseId[phaseId] = entries; } entries.Add(spawnEntry); } Log.Info( "CombatNodeComponent initialized. Theme={0}, Levels={1}, Phases={2}, Entries={3}", themeType, _levelsById.Count, CountPhases(), CountEntries()); } public void StartCombat() { if (_levelIdBuffer.Count <= 0) { Log.Warning("CombatNodeComponent has no level cache. Call OnInit(levelThemeType) first."); return; } int randomIndex = Random.Range(0, _levelIdBuffer.Count); int randomLevelId = _levelIdBuffer[randomIndex]; CurrentLevel = _levelsById[randomLevelId]; // TODO: 在这里接入真实战斗节点玩法启动流程(场景进入、敌人生成、结算等)。 Log.Info("StartCombat selected level '{0}' (Theme={1}).", CurrentLevel.Id, CurrentThemeType); } private int CountPhases() { int count = 0; foreach (List phases in _phasesByLevelId.Values) { count += phases.Count; } return count; } private int CountEntries() { int count = 0; foreach (var list in _spawnEntriesByPhaseId.Values) { count += list.Count; } return count; } } }