public Dictionary <Coord, List <Coord> > GetAvailableDestinations(Coord enemy, int movementPoint) { TerrainCellFinderSystem cellFinderSystem = ecsManager.GetSystem <TerrainCellFinderSystem>(); UnitFinderSystem unitFinderSystem = ecsManager.GetSystem <UnitFinderSystem>(); var cachedPaths = new Dictionary <Coord, List <Coord> >(); var edges = GetGraphEdges(); var paths = _pathfinder.findAllPaths(edges, enemy); foreach (var key in paths.Keys) { if (!cellFinderSystem.IsValidCell(key) || (unitFinderSystem.GetUnitAtCoord(key) != null)) { continue; } var path = paths[key]; var pathCost = path.Count; if (pathCost <= movementPoint) { cachedPaths.Add(key, path); } } return(cachedPaths); }
protected Dictionary <Coord, Dictionary <Coord, int> > GetGraphEdges() { CellsListComponent cellsList = ecsManager.GetVSingletonComponent <CellsListComponent>(); List <Coord> cells = ecsManager.GetVComponentsFromList <PositionComponent>(cellsList.cellIds).Select(i => i.position).ToList(); Dictionary <Coord, Dictionary <Coord, int> > ret = new Dictionary <Coord, Dictionary <Coord, int> >(); TerrainCellFinderSystem cellFinderSystem = ecsManager.GetSystem <TerrainCellFinderSystem>(); foreach (var cell in cells) { if (cellFinderSystem.IsValidCell(cell)) { ret[cell] = new Dictionary <Coord, int>(); foreach (var neighbour in cell.GetSurroundingCoords().FindAll(c => cellFinderSystem.IsValidCell(c))) { ret[cell][neighbour] = 1; // cost of moving to that cell } } } return(ret); }
public override List <Coord> SelectCoords(Coord loc, VEntityComponentSystemManager boardState) { List <Coord> selectedCoords = new List <Coord>(); TerrainCellFinderSystem terrainCellFinderSystem = boardState.GetSystem <TerrainCellFinderSystem>(); foreach (Coord direction in Coord.diagonalCoords) { for (int distance = offset + 1; infinite || distance <= length; distance++) { Coord newCoord = loc + (direction * distance); if (terrainCellFinderSystem.IsValidCell(newCoord)) { selectedCoords.Add(newCoord); } else { break; } } } return(selectedCoords); }
protected override void OnEnemySetupStart(VEntity entity) { CellScoresComponent CellScoresComponent = ecsManager.GetVSingletonComponent <CellScoresComponent>(); CellScoresComponent.cellScores = new Dictionary <Coord, int>(); CellsListComponent cellsList = ecsManager.GetVSingletonComponent <CellsListComponent>(); List <PositionComponent> positions = ecsManager.GetVComponentsFromList <PositionComponent>(cellsList.cellIds); TerrainCellFinderSystem cellFinderSystem = ecsManager.GetSystem <TerrainCellFinderSystem>(); foreach (PositionComponent p in positions) { CellScoresComponent.cellScores.Add(p.position, 0); } // generically gets all entities that are targetable by the AI, has a position component, and ripples the scores the their positions. List <VEntity> enemyTargets = ecsManager.FilterEntities(test: (ventity) => { return(VEntityComponentSystemManager.HasVComponent <EnemyTargetComponent>(ventity) && VEntityComponentSystemManager.HasVComponent <PositionComponent>(ventity)); }); foreach (VEntity targetEntity in enemyTargets) { PositionComponent targetComponent = targetEntity.GetVComponent <PositionComponent>(); RippleScores(targetComponent.position, 5, CellScoresComponent.cellScores); } List <VEntity> enemies = ecsManager.GetSystem <UnitFinderSystem>().GetAllEnemyUnits().ToList(); foreach (VEntity enemy in enemies) { var availableDestinations = ecsManager.GetSystem <PathingSystem>().GetAvailableDestinations(VEntityComponentSystemManager.GetVComponent <PositionComponent>(enemy).position, 5); var moveScores = new Dictionary <Coord, int>(); foreach (Coord cell in availableDestinations.Keys) { int s = 0; foreach (Coord neighbor in cell.GetSurroundingCoords(true, false).FindAll(c => cellFinderSystem.IsValidCell(c))) { s += CellScoresComponent.cellScores[neighbor]; } moveScores.Add(cell, s); } var sortedMoveScore = moveScores.OrderByDescending(x => x.Value); // destination cell is where the unit is going to move to, defaulting to its original position Coord destinationCell = VEntityComponentSystemManager.GetVComponent <PositionComponent>(enemy).position; if (sortedMoveScore.Count() == 1) { destinationCell = sortedMoveScore.First().Key; } else if (sortedMoveScore.Count() > 1) { // randomly choose between the top two choices if there are more than 1 destinationCell = sortedMoveScore.ElementAt(Random.Range(0, 2)).Key; } ecsManager.ExecuteImmediateEvent("EnemyMove", component: new MovementEvent { sourceId = enemy.id, targetCoord = destinationCell }); ecsManager.ExecuteImmediateEvent("QueueAction", component: new QueueActionEvent { entityId = enemy.id }); } }