145 lines
4.9 KiB
C#
145 lines
4.9 KiB
C#
using System.Collections.Generic;
|
|
using GameFramework.DataTable;
|
|
using GeometryTD.DataTable;
|
|
using GeometryTD.Definition;
|
|
using UnityEngine;
|
|
using UnityGameFramework.Runtime;
|
|
|
|
namespace GeometryTD.CustomComponent
|
|
{
|
|
/// <summary>
|
|
/// 战斗节点组件
|
|
/// </summary>
|
|
public class CombatNodeComponent : GameFrameworkComponent
|
|
{
|
|
// Level.Id => Level
|
|
private readonly Dictionary<int, DRLevel> _levelsById = new();
|
|
|
|
// LevelId => LevelPhases
|
|
private readonly Dictionary<int, List<DRLevelPhase>> _phasesByLevelId = new();
|
|
|
|
// LevelPhase.Id => LevelSpawnEntries
|
|
private readonly Dictionary<int, List<DRLevelSpawnEntry>> _spawnEntriesByPhaseId = new();
|
|
|
|
private readonly List<int> _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<DRLevel> dtLevel = GameEntry.DataTable.GetDataTable<DRLevel>();
|
|
IDataTable<DRLevelPhase> dtLevelPhase = GameEntry.DataTable.GetDataTable<DRLevelPhase>();
|
|
IDataTable<DRLevelSpawnEntry> dtSpawnEntry = GameEntry.DataTable.GetDataTable<DRLevelSpawnEntry>();
|
|
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<DRLevelPhase>();
|
|
_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<DRLevelPhase> phases))
|
|
{
|
|
phases = new List<DRLevelPhase>();
|
|
_phasesByLevelId[levelId] = phases;
|
|
}
|
|
|
|
phases.Add(phase);
|
|
_spawnEntriesByPhaseId[phase.Id] = new List<DRLevelSpawnEntry>();
|
|
}
|
|
|
|
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<DRLevelSpawnEntry> entries))
|
|
{
|
|
entries = new List<DRLevelSpawnEntry>();
|
|
_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<DRLevelPhase> 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;
|
|
}
|
|
}
|
|
} |