public AbstractNode CreateAbstractNodeInSector(MultiLevelSector sector, Tile tile, WorldArea area) { AbstractNode sectorNode = new AbstractNode(); sectorNode.tileConnection = tile; tile.hasAbstractNodeConnection = true; sectorNode.sector = sector.ID; sectorNode.worldAreaIndex = area.index; if (area.tileSectorNodeConnections[sector.level].ContainsKey(tile)) { area.tileSectorNodeConnections[sector.level][tile].Add(sectorNode); } else { area.tileSectorNodeConnections[sector.level].Add(tile, new List <AbstractNode>() { sectorNode }); } return(sectorNode); }
public void AddEmptyField(int sectorIndex, int tilesInSectorAmount, WorldArea area) { Field.Add(new IntVector2(area.Index, sectorIndex), new int[tilesInSectorAmount]); }
private void AddChange(IntVector2 key, Tile tile, WorldArea area, int side) { IntVector2 otherSectorKey = new IntVector2(); int otherSector = -1; // if other side of the sector has already been added, we dont need to add this if (side == 0) { otherSector = tile.sectorIndex - worldData.multiLevelSectorManager.GetSectorGridWidthAtLevel(area, 0); } else if (side == 1) { otherSector = tile.sectorIndex + worldData.multiLevelSectorManager.GetSectorGridWidthAtLevel(area, 0); } else if (side == 2 && area.sectorGrid[0][tile.sectorIndex].gridX > 0) { otherSector = tile.sectorIndex - 1; } else if (side == 3 && area.sectorGrid[0][tile.sectorIndex].gridX < worldData.multiLevelSectorManager.GetSectorGridWidthAtLevel(area, 0) - 1) { otherSector = tile.sectorIndex + 1; } if (worldData.pathfinder.maxLevelAmount > 1) { // add highlevel sector changes if (worldData.multiLevelSectorManager.GetHigherSectorFromLower(1, area.sectorGrid[0][tile.sectorIndex], area) != worldData.multiLevelSectorManager.GetHigherSectorFromLower(1, area.sectorGrid[0][otherSector], area)) { IntVector3 highLevelEdgeKey = new IntVector3(area.index, 0, 0); int sideValue = 0; if (tile.sectorIndex < otherSector) { sideValue = side; highLevelEdgeKey.y = tile.sectorIndex; highLevelEdgeKey.z = otherSector; } else { sideValue = worldData.multiLevelSectorManager.FlipDirection(side); highLevelEdgeKey.y = otherSector; highLevelEdgeKey.z = tile.sectorIndex; } if (!sectorEdgeChangesHighLevel.ContainsKey(highLevelEdgeKey)) { sectorEdgeChangesHighLevel.Add(highLevelEdgeKey, sideValue); } } } if (otherSector > 0 && otherSector < area.sectorGrid[0].Length) { otherSectorKey.x = tile.worldAreaIndex; otherSectorKey.y = otherSector; if (sectorEdgeChangesLowLevel.ContainsKey(otherSectorKey)) { if (sectorEdgeChangesLowLevel[otherSectorKey].Contains(worldData.multiLevelSectorManager.FlipDirection(side))) // other side already filled in { if (!sectorChanges.Contains(key)) // other sector exist and the side. add our sector for general change { sectorChanges.Add(key); } } else if (!sectorEdgeChangesLowLevel[key].Contains(side)) // other sector exist but not the side. add our sector for Edge change { sectorEdgeChangesLowLevel[key].Add(side); } } else// other sector not (yet? )added. add ourselves and other sector for genral change { if (!sectorChanges.Contains(otherSectorKey)) { sectorChanges.Add(otherSectorKey); } if (!sectorEdgeChangesLowLevel[key].Contains(side)) { sectorEdgeChangesLowLevel[key].Add(side); } } } else if (!sectorEdgeChangesLowLevel[key].Contains(side))// other sector does not exist, add ourselves { sectorEdgeChangesLowLevel[key].Add(side); } }
private List <Tile> GetNodesOnSectorRowNoBlocked(Vector2 start, Vector2 direction, WorldArea area) { List <Tile> returnList = new List <Tile>(); for (int i = 0; i < GetSectorWidthAtLevel(area, 0); i++) { var x = (int)start.x + (int)direction.x * i; var y = (int)start.y + (int)direction.y * i; if (x > -1 && x < area.GridWidth && y > -1 && y < area.GridLength) { Tile tile = area.TileGrid[x][y]; if (tile != null && !tile.Blocked) { returnList.Add(tile); } } } return(returnList); }
// calculate distances to other high level nodes public void ConnectNodeInSector(MultiLevelSector sector, AbstractNode sectorNode, WorldArea area) { int maxNodes = sector.WorldAreaNodes.Count + sector.SectorNodesOnEdge[0].Count + sector.SectorNodesOnEdge[1].Count + sector.SectorNodesOnEdge[2].Count + sector.SectorNodesOnEdge[3].Count; //Debug.Log("low level sector ConnectNodeInSector " + maxNodes); // 2 sectorNodes on same location, connect them if (area.TileSectorNodeConnections[sector.Level][sectorNode.TileConnection].Count > 1 && area.TileSectorNodeConnections[sector.Level].ContainsKey(sectorNode.TileConnection)) { maxNodes--; Manager.ConnectSectorNodes(area.TileSectorNodeConnections[sector.Level][sectorNode.TileConnection][0], area.TileSectorNodeConnections[sector.Level][sectorNode.TileConnection][1], 0); } _openSet.Clear(); _closedSet.Clear(); _openSet.Add(sectorNode.TileConnection); _openSet[0].IntegrationValue = 0; // Debug.Log("max nodes " + maxNodes); while (_openSet.Count > 0 && maxNodes != 0) { Tile currentNode = _openSet[0]; foreach (Tile neighbour in Manager.WorldData.TileManager.GetAllNeighboursForSectorNodeSearch( currentNode, area)) { //Debug.Log("neighbor"); if (!_openSet.Contains(neighbour)) { _openSet.Add(neighbour); // if true, there is a higher node here if (neighbour.HasAbstractNodeConnection) //.higherLevelNodeIndex.Count > 0) { //Debug.Log("found connection"); //Get all HigherNodes on this Lower Node & connect them List <AbstractNode> neighbourSectorNodes = area.TileSectorNodeConnections[sector.Level][ neighbour]; // GetHigherLevelNodeList(neighbour, sector); Manager.ConnectSectorNodes(sectorNode, neighbourSectorNodes, neighbour.IntegrationValue / 10); // 10 times scaling - more accurate but slower/ Math.FloorToInt((neighbour.totalPathCost / 10f) + 0.5f) maxNodes -= neighbourSectorNodes.Count; } } } _closedSet.Add(currentNode); _openSet.Remove(currentNode); } // reset foreach (Tile tile in _openSet) { tile.IntegrationValue = TileManager.TileResetIntegrationValue; } foreach (Tile tile in _closedSet) { tile.IntegrationValue = TileManager.TileResetIntegrationValue; } }
public AbstractNode CreateAbstractNodeInSector(MultiLevelSector sector, Tile tile, WorldArea area) { AbstractNode sectorNode = new AbstractNode { TileConnection = tile }; tile.HasAbstractNodeConnection = true; sectorNode.Sector = sector.Id; sectorNode.WorldAreaIndex = area.Index; if (area.TileSectorNodeConnections[sector.Level].ContainsKey(tile)) { area.TileSectorNodeConnections[sector.Level][tile].Add(sectorNode); } else { area.TileSectorNodeConnections[sector.Level].Add(tile, new List <AbstractNode> { sectorNode }); } return(sectorNode); }
public int GetSectorGridHeightAtLevel(WorldArea worldLayer, int level) { return(worldLayer.LevelDimensions[level][3]); }
public List <Tile> GetNeighboursExpansionSearch(Tile node, WorldArea area) { List <Tile> neighbours = new List <Tile>(); int directionValue = node.gridPos.x + 1; if (directionValue < area.gridWidth && area.searchField[directionValue][node.gridPos.y] && area.tileGrid[directionValue][node.gridPos.y] != null) // right { if (!area.tileGrid[directionValue][node.gridPos.y].blocked && TilesWithinRangeGeneration(node, area.tileGrid[directionValue][node.gridPos.y])) { int newCost = node.integrationValue + area.tileGrid[directionValue][node.gridPos.y].cost; if (newCost < area.tileGrid[directionValue][node.gridPos.y].integrationValue) { area.tileGrid[directionValue][node.gridPos.y].integrationValue = newCost; neighbours.Add(area.tileGrid[directionValue][node.gridPos.y]); } } } directionValue = node.gridPos.x - 1; if (directionValue > -1 && area.searchField[directionValue][node.gridPos.y] && area.tileGrid[directionValue][node.gridPos.y] != null) // left { if (!area.tileGrid[directionValue][node.gridPos.y].blocked && TilesWithinRangeGeneration(node, area.tileGrid[directionValue][node.gridPos.y])) { int newCost = node.integrationValue + area.tileGrid[directionValue][node.gridPos.y].cost; if (newCost < area.tileGrid[directionValue][node.gridPos.y].integrationValue) { area.tileGrid[directionValue][node.gridPos.y].integrationValue = newCost; neighbours.Add(area.tileGrid[directionValue][node.gridPos.y]); } } } directionValue = node.gridPos.y - 1; if (directionValue > -1 && area.searchField[node.gridPos.x][directionValue] && area.tileGrid[node.gridPos.x][directionValue] != null) // top { if (!area.tileGrid[node.gridPos.x][directionValue].blocked && TilesWithinRangeGeneration(node, area.tileGrid[node.gridPos.x][directionValue])) { int newCost = node.integrationValue + area.tileGrid[node.gridPos.x][directionValue].cost; if (newCost < area.tileGrid[node.gridPos.x][directionValue].integrationValue) { area.tileGrid[node.gridPos.x][directionValue].integrationValue = newCost; neighbours.Add(area.tileGrid[node.gridPos.x][directionValue]); } } } directionValue = node.gridPos.y + 1; if (directionValue < area.gridLength && area.searchField[node.gridPos.x][directionValue] && area.tileGrid[node.gridPos.x][directionValue] != null) // bot { if (!area.tileGrid[node.gridPos.x][directionValue].blocked && TilesWithinRangeGeneration(node, area.tileGrid[node.gridPos.x][directionValue])) { int newCost = node.integrationValue + area.tileGrid[node.gridPos.x][directionValue].cost; if (newCost < area.tileGrid[node.gridPos.x][directionValue].integrationValue) { area.tileGrid[node.gridPos.x][directionValue].integrationValue = newCost; neighbours.Add(area.tileGrid[node.gridPos.x][directionValue]); } } } return(neighbours); }
public Vector3 GetTileWorldPosition(Tile tile, WorldArea worldArea) { return(new Vector3(worldData.pathfinder.worldStart.x + ((worldArea.leftOffset + tile.gridPos.x) * worldData.pathfinder.tileSize) + (worldData.pathfinder.tileSize * 0.5f), tile.yWorldPos, worldData.pathfinder.worldStart.z - ((worldArea.topOffset + tile.gridPos.y) * worldData.pathfinder.tileSize) - (worldData.pathfinder.tileSize * 0.5f))); }
public IntegrationField CreateIntegrationField(List <Tile> tiles, List <int> sectors, WorldArea area) { IntegrationField integrationField = new IntegrationField(); integrationField.AddFields(sectors, WorldData.MultiLevelSectorManager.GetSectorWidthAtLevel(area, 0) * WorldData.MultiLevelSectorManager.GetSectorHeightAtLevel(area, 0), tiles, area); return(integrationField); }
// extra fields are being created, create & add a field by expanding from neighbouring sectors private void CreateFieldToAdd(int emptySector, List <int> neighbourSectors, FlowFieldPath flowFieldPath, WorldArea area) { // get all tiles between the sectors List <Tile> tilesChangedInNeighbourSectors = new List <Tile>(); List <int> allSectors = new List <int> { emptySector }; allSectors.AddRange(neighbourSectors); // set which fields/sectors we can do a tile expansion over WorldData.MultiLevelSectorManager.SetSearchFields(allSectors, area, true); // for each neighbour sector in the Path foreach (int neighbourSector in neighbourSectors) { // get the tiles on edge var tilesOnEdge = WorldData.MultiLevelSectorManager.RowBetweenSectorsWithinWorldArea( area.SectorGrid[0][neighbourSector], area.SectorGrid[0][emptySector], area); //request integration values int[] fieldValues = flowFieldPath.IntegrationField.Field[new IntVector2(area.Index, neighbourSector)]; // put the integration back in the tiles foreach (Tile tile in WorldData.MultiLevelSectorManager.GetTilesInSector( area.SectorGrid[0][neighbourSector], area)) { tile.IntegrationValue = fieldValues[tile.IndexWithinSector]; tilesChangedInNeighbourSectors.Add(tile); } _tilesSearchList.AddRange(tilesOnEdge); } // expand over this and neighbouring sectors, starting at the edges WaveExpansionSearchTiles(area); // remove tiles that have direct connection to a different World Area, their flow direction must not change foreach (int neighbourSector in neighbourSectors) { foreach (AbstractNode node in area.SectorGrid[0][neighbourSector].WorldAreaNodes.Keys) { _closedSet.Remove(node.TileConnection); } } // add new values to flow field pat WorldData.FlowFieldManager.AddToFlowFieldPath(_closedSet, allSectors, area, flowFieldPath); flowFieldPath.FlowField.FillFlowField(_closedSet, WorldData); // reset earlier removed tiles foreach (int neighbourSector in neighbourSectors) { foreach (AbstractNode node in area.SectorGrid[0][neighbourSector].WorldAreaNodes.Keys) { node.TileConnection.IntegrationValue = TileManager.TileResetIntegrationValue; } } _closedSet.AddRange(tilesChangedInNeighbourSectors); _closedSetFinish.AddRange(_closedSet); ResetTilesAfterSearch(); // set search fields back to false WorldData.MultiLevelSectorManager.SetSearchFields(allSectors, area, false); }
public void StartIntegrationFieldCreation(Tile destinationTile, List <List <int> > areasAndSectorsParam, FlowFieldPath flowPathParam, SearchPathJob pathJob, int key, bool pathEdit) { FlowFieldPath flowPath = null; bool aPathIsCreated = false; List <List <int> > areasAndSectors = areasAndSectorsParam; List <int> areas = new List <int>(); List <List <int> > sectors = new List <List <int> >(); Dictionary <IntVector2, List <Tile> > areaConnectionTiles = new Dictionary <IntVector2, List <Tile> >(); bool firstWorldArea = !pathEdit; for (int a = 0; a < areasAndSectors.Count; a++) // each separate search //areasAndSectors.Count { var firstWorldAreaOfNewSearch = true; var index = 0; areas.Clear(); sectors.Clear(); Dictionary <IntVector2, int[]> alreadyFilledInSector = null; IntVector2 areaSectorKey = new IntVector2(0, 0); //area.index, sectorIndex); if (pathEdit && flowPathParam != null) { flowPath = flowPathParam; } //setup/starting point of the sectors- and areas- lists int startIndex; if (a == 0 && !pathEdit) // first search { startIndex = 0; areas.Add(areasAndSectors[a][0]); sectors.Add(new List <int>()); } else // we start with a search that is not the first one. we might be able to skip a lot of already integrated sectors { if (flowPath == null) { flowPath = WorldData.FlowFieldManager.FlowFieldPaths[ WorldData.FlowFieldManager.FlowFieldPaths.Count - 1]; } alreadyFilledInSector = flowPath.IntegrationField.Field; startIndex = -1; for (int i = 0; i < areasAndSectors[a].Count; i += 2) { areaSectorKey.X = areasAndSectors[a][i]; areaSectorKey.Y = areasAndSectors[a][i + 1]; if (!alreadyFilledInSector.ContainsKey(areaSectorKey)) // sector not yet filled in { startIndex = i; areas.Add(areasAndSectors[a][startIndex]); sectors.Add(new List <int>()); break; } } } // if -1 we can skip it all if (startIndex != -1) // else entire path already calculated by a different search { // set what tiles to cross over during a search // separate areas and sectors in arrays for (int i = startIndex; i < areasAndSectors[a].Count; i += 2) { areaSectorKey.X = areasAndSectors[a][i]; areaSectorKey.Y = areasAndSectors[a][i + 1]; if (areasAndSectors[a][i] == areas[index]) { sectors[index].Add(areasAndSectors[a][i + 1]); } else { index++; areas.Add(areasAndSectors[a][i]); sectors.Add(new List <int>()); sectors[index].Add(areasAndSectors[a][i + 1]); } if (alreadyFilledInSector != null && alreadyFilledInSector.ContainsKey(areaSectorKey) ) // added sector already filled in { // a couple of sectors where not already found, then they were, then they aren't again // we split up this search, so that every search in the flowing steps is a list of sectors that all directly connect. // no gaps of already filled in sectors areasAndSectors.Add(new List <int>()); for (int j = i; j < areasAndSectors[a].Count; j++) { areasAndSectors[areasAndSectors.Count - 1].Add(areasAndSectors[a][j]); } break; } } if (!firstWorldArea && areasAndSectors[a][startIndex] != areasAndSectors[a][startIndex - 2]) // different world areas { firstWorldAreaOfNewSearch = false; } // going through our areas- and sectors- lists for (int i = 0; i < areas.Count; i++) { WorldData.MultiLevelSectorManager.SetSearchFields(areas[i], sectors[i], true); WorldArea currentWorldArea = WorldData.WorldAreas[areas[i]]; if (firstWorldAreaOfNewSearch) { _openSet.Clear(); List <Tile> oldSectorTiles = new List <Tile>(); if (firstWorldArea) { _tilesSearchList.Add(destinationTile); _tilesSearchList[0].IntegrationValue = 0; } else { WorldArea area = WorldData.WorldAreas[areasAndSectors[a][startIndex]]; MultiLevelSector start = area.SectorGrid[0][areasAndSectors[a][startIndex - 1]]; MultiLevelSector next = area.SectorGrid[0][areasAndSectors[a][startIndex + 1]]; oldSectorTiles = WorldData.MultiLevelSectorManager.RowBetweenSectorsWithinWorldArea(start, next, area); if (pathEdit) // put old values back in the old tiles { IntVector2 oldTileKey = new IntVector2(); foreach (Tile tile in oldSectorTiles) { oldTileKey.X = tile.WorldAreaIndex; oldTileKey.Y = tile.SectorIndex; tile.IntegrationValue = flowPath.IntegrationField.Field[oldTileKey][tile.IndexWithinSector]; } } _tilesSearchList.AddRange(oldSectorTiles); } foreach (Tile oldTile in oldSectorTiles) { _closedSet.Remove(oldTile); } } else { WorldArea previousWorldArea; int lastSectorOfPreviousWorldArea; if (i == 0) // previous world area is not in array, removed because of already covered { previousWorldArea = WorldData.WorldAreas[areasAndSectors[a][startIndex - 2]]; lastSectorOfPreviousWorldArea = areasAndSectors[a][startIndex - 1]; } else { previousWorldArea = WorldData.WorldAreas[areas[i - 1]]; lastSectorOfPreviousWorldArea = sectors[i - 1][sectors[i - 1].Count - 1]; } int sectorOfCurrentArea = sectors[i][0]; IntVector2 areaConnectionKey = new IntVector2(currentWorldArea.Index, previousWorldArea.Index); if (!areaConnectionTiles.ContainsKey(areaConnectionKey)) { areaConnectionTiles.Add(areaConnectionKey, new List <Tile>()); } List <Tile> tiles = SwitchToNextWorldArea(previousWorldArea, currentWorldArea, lastSectorOfPreviousWorldArea, sectorOfCurrentArea, flowPath); areaConnectionTiles[areaConnectionKey].AddRange(tiles); } WaveExpansionSearchTiles(currentWorldArea); _closedSetFinish.AddRange(_closedSet); // all integration fields generated, create flow field if (firstWorldArea) { aPathIsCreated = true; WorldData.FlowFieldManager.CreateFlowFieldPath(_closedSet, sectors[i], areas, destinationTile, currentWorldArea, key); } else { WorldData.FlowFieldManager.AddToFlowFieldPath(_closedSet, sectors[i], currentWorldArea); if (pathEdit) { aPathIsCreated = true; } } _closedSet.Clear(); firstWorldAreaOfNewSearch = false; firstWorldArea = false; WorldData.MultiLevelSectorManager.SetSearchFields(areas[i], sectors[i], false); } } } if (flowPath == null && WorldData.FlowFieldManager.FlowFieldPaths.Count > 0) { flowPath = WorldData.FlowFieldManager.FlowFieldPaths[ WorldData.FlowFieldManager.FlowFieldPaths.Count - 1]; } if (flowPath != null) { flowPath.FlowField.FillFlowField(_closedSetFinish, WorldData); WorldData.FlowFieldManager.AddAreaTilesToFlowFieldPath(areaConnectionTiles); } if (pathJob != null) { pathJob.PathCreated(aPathIsCreated ? flowPath : null, false); } else { if (aPathIsCreated) { if (flowPath != null) { WorldData.Pathfinder.PathCreated(flowPath, flowPath.Key, pathEdit); } } else { WorldData.Pathfinder.PathCreated(null, 0, pathEdit); } } ResetTilesAfterSearch(); }
// create flow field public void CreateFlowFieldPath(List <Tile> tiles, List <int> sectors, List <int> worldAreas, Tile destination, WorldArea area, int key) { FlowFieldPath path = new FlowFieldPath(); path.Create(destination, WorldData.IntegrationFieldManager.CreateIntegrationField(tiles, sectors, area), CreateFlowField(sectors, area), key); FlowFieldPaths.Add(path); }
// get list of nodes that are on the border of start sector, with next sector public List <Tile> RowBetweenSectorsWithinWorldArea(MultiLevelSector sectorStart, MultiLevelSector sectorNext, WorldArea area) { Vector2 dir = DirectionBetweenSectorsVector2(sectorStart, sectorNext); if (dir == -Vector2.up) { return(GetNodesOnSectorRowNoBlocked(new Vector2(sectorStart.left, sectorStart.top), Vector2.right, area)); } if (dir == Vector2.up) { return(GetNodesOnSectorRowNoBlocked(new Vector2(sectorStart.left, sectorStart.bottom), Vector2.right, area)); } if (dir == -Vector2.right) { return(GetNodesOnSectorRowNoBlocked(new Vector2(sectorStart.left, sectorStart.top), Vector2.up, area)); } if (dir == Vector2.right) { return(GetNodesOnSectorRowNoBlocked(new Vector2(sectorStart.right, sectorStart.top), Vector2.up, area)); } return(null); }
public void ConnectNodeInSector(MultiLevelSector sector, AbstractNode sectorNode, WorldArea area) { if (sector.Level == 0) { LowLevel.ConnectNodeInSector(sector, sectorNode, area); } else { HighLevel.ConnectNodeInSector(sector, sectorNode, area); } }
public List <Tile> GetAllNeighboursForSectorNodeSearch(Tile tile, WorldArea area) { List <Tile> neighbours = new List <Tile>(); Tile neighbour = null; int checkX = 0; int checkY = 0; //straight for (int i = 0; i < straightDirections.Length; i += 2) { checkX = tile.gridPos.x + straightDirections[i]; checkY = tile.gridPos.y + straightDirections[i + 1]; if (checkX > -1 && checkX < area.gridWidth && checkY > -1 && checkY < area.gridLength) { neighbour = area.tileGrid[checkX][checkY]; //if (worldData.worldBuilder.worldIsBuilt) // Debug.Log("tile.sector " + tile.sector + " neighbour " + neighbour.sector); if (neighbour != null && !neighbour.blocked && neighbour.sectorIndex == tile.sectorIndex && TilesWithinRangeGeneration(tile, neighbour)) { int newCost = tile.integrationValue + neighbour.cost * 10; //if (worldData.worldBuilder.worldIsBuilt) // Debug.Log("add right?"); if (newCost < neighbour.integrationValue) { //if (worldData.worldBuilder.worldIsBuilt) // Debug.Log("ADDED"); neighbour.integrationValue = newCost; neighbours.Add(neighbour); } } } } // diagonal for (int i = 0; i < diagonalDirections.Length; i += 2) { checkX = tile.gridPos.x + diagonalDirections[i]; checkY = tile.gridPos.y + diagonalDirections[i + 1]; if (checkX > -1 && checkX < area.gridWidth && checkY > -1 && checkY < area.gridLength) { neighbour = area.tileGrid[checkX][checkY]; if (neighbour != null && !neighbour.blocked && neighbour.sectorIndex == tile.sectorIndex) { int newCost = tile.integrationValue + neighbour.cost * 14; if (newCost < neighbour.integrationValue) // if not blocked { if ((area.tileGrid[neighbour.gridPos.x][tile.gridPos.y] == null || area.tileGrid[neighbour.gridPos.x][tile.gridPos.y].blocked) && (area.tileGrid[tile.gridPos.x][neighbour.gridPos.y] == null || area.tileGrid[tile.gridPos.x][neighbour.gridPos.y].blocked)) { // diagonal was blocked off } else if (TilesWithinRangeGeneration(tile, neighbour)) { neighbour.integrationValue = newCost; neighbours.Add(neighbour); } } } } } return(neighbours); }
public void CreateSectorNodes(MultiLevelSector sector, int neighbourId, int edgeIndex, int edgeIndexNeighbourSector, Tile inSectorNode, Tile inNeighbourSectorNode, WorldArea area) { AbstractNode node = CreateAbstractNodeOnSectorEdge(sector, edgeIndex, inSectorNode, area); AbstractNode neighbourNode = CreateAbstractNodeOnSectorEdge(area.SectorGrid[sector.Level][neighbourId], edgeIndexNeighbourSector, inNeighbourSectorNode, area); node.NodeConnectionToOtherSector = neighbourNode; neighbourNode.NodeConnectionToOtherSector = node; ConnectSectorNodes(node, neighbourNode, 1); }
// find path on higher level between start and goal/destination public List <List <int> > FindPaths(Dictionary <IntVector2, Tile> startingPoints, Tile destinationTile, WorldArea destinationArea) { multiSectorNodes = new List <AbstractNode>(); int maxLevelAmount = worldData.pathfinder.maxLevelAmount; if (maxLevelAmount == 0) { if (worldData.pathfinder.worldIsMultiLayered) { Debug.Log("Invalid search: A Multi Layerd world cannot find paths with no Levels Of Abstraction "); return(null); } else { maxLevelAmount = 1; } } // adding all the start/destination nodes per level. for (int i = 0; i < maxLevelAmount; i++) { foreach (IntVector2 key in startingPoints.Keys) { Tile startTile = startingPoints[key]; startNodeSector = worldData.multiLevelSectorManager.GetSectorOfTile(i, startTile, worldData.worldAreas[key.x]); startMultiSectorNode = worldData.multiLevelSectorManager.CreateAbstractNodeInSector(startNodeSector, startTile, worldData.worldAreas[key.x]); worldData.multiLevelSectorManager.ConnectNodeInSector(startNodeSector, startMultiSectorNode, worldData.worldAreas[key.x]);//, new List<HigherNode>()); multiSectorNodes.Add(startMultiSectorNode); } // create temporary highlevel node on the start node // calculate its distance to the other high level nodes in the same sector, build connections between them destinationNodeSector = worldData.multiLevelSectorManager.GetSectorOfTile(i, destinationTile, destinationArea); destinationMultiSectorNode = worldData.multiLevelSectorManager.CreateAbstractNodeInSector(destinationNodeSector, destinationTile, destinationArea); worldData.multiLevelSectorManager.ConnectNodeInSector(destinationNodeSector, destinationMultiSectorNode, destinationArea); multiSectorNodes.Add(destinationMultiSectorNode); } bool nextStep = false; AbstractNode start; AbstractNode destination; previousNodesStartingPointCount = startingPoints.Count; sectorIndexesAllLowerPaths.Clear(); for (int j = 0; j < startingPoints.Count; j++) // for each starting point { for (int i = multiSectorNodes.Count - 1; i > -1; i -= startingPoints.Count + 1) { nextStep = false; int level = i / (startingPoints.Count + 1); start = multiSectorNodes[i - (j + 1)]; destination = multiSectorNodes[i]; if (start.sector == destination.sector)// starting point == destination { if (worldData.pathfinder.maxLevelAmount == 0) { AddToPath(new List <int> { start.worldAreaIndex, start.sector }); nextStep = true; } else { foreach (AbstractNode sectorNode in destination.connections.Keys) { if (sectorNode == start) // direct connection in sector { if (level != 0) // go to the next layer { nextStep = true; } else // level = 0, our goal is right next to us { AddToPath(new List <int> { start.worldAreaIndex, start.sector }); } break; } } } } //validSectorsFound if (!nextStep) { if (level != 0) // we have to search the path between them, using A-star on the high level network { List <int> sectorIndexes = null; if (validSectorsFound.Count == 0) { sectorIndexes = SearchHighLevelPath(start, destination, true); } else { sectorIndexes = SearchHighLevelPath(start, destination, validSectorsFound, true); } if (sectorIndexes == null) { Debug.Log("indexes ARE null, no Path on this hierachal Level: " + level); } else { validSectorsFound.Clear(); for (int k = 0; k < sectorIndexes.Count; k += 2) { foreach (int[] list in worldData.multiLevelSectorManager.GetLowerSectorsFromHigher(level, sectorIndexes[k + 1], worldData.worldAreas[sectorIndexes[k]])) { foreach (int lowerIndex in list) { validSectorsFound.Add(new IntVector2(sectorIndexes[k], lowerIndex), false); } } } } } else // lowest level reached { List <int> sectorIndexes = null; if (validSectorsFound.Count == 0) { sectorIndexes = SearchHighLevelPath(start, destination, true); } else { sectorIndexes = SearchHighLevelPath(start, destination, validSectorsFound, true); } validSectorsFound.Clear(); if (sectorIndexes != null) { AddToPath(sectorIndexes); } } } } } return(sectorIndexesAllLowerPaths); }
public int GetSectorGridWidthAtLevel(WorldArea worldLayer, int level) { return(worldLayer.LevelDimensions[level][2]); }
public void FindConnectionInsideSectorOnly(AbstractNode start, AbstractNode destination, MultiLevelSector sector, WorldArea area) { // if we look for ourself or already have a connection, we are done here if (start == destination || start.connections.ContainsKey(destination)) { return; } int lowerLevel = sector.level - 1; if (!area.tileSectorNodeConnections[lowerLevel].ContainsKey(start.tileConnection)) { Debug.Log("node index " + start.worldAreaIndex + " actual world index " + area.index + " start high " + start.tileConnection.gridPos.x + " y " + start.tileConnection.gridPos.y); } int connectionDistance = FindConnectionThroughPathInsideSectorOnly(lowerLevel, area.tileSectorNodeConnections[lowerLevel][start.tileConnection], area.tileSectorNodeConnections[lowerLevel][destination.tileConnection], worldData.multiLevelSectorManager.GetLowerSectorsFromHigher(sector.level, sector.ID, area)); if (connectionDistance > -1) { worldData.multiLevelSectorManager.ConnectSectorNodes(start, destination, connectionDistance); } }
public MultiLevelSector GetHigherSectorFromLower(int level, MultiLevelSector sector, WorldArea area) { int x = Mathf.FloorToInt(sector.Left / (float)GetSectorWidthAtLevel(area, level)); int y = Mathf.FloorToInt(sector.Top / (float)GetSectorHeightAtLevel(area, level)); int index = (y * GetSectorGridWidthAtLevel(area, level)) + x; return(area.SectorGrid[level][index]); }
public void AddSectorInPath(WorldArea area, Tile tile, FlowFieldPath path) { _pathAdjustmentsInProgress.Add(new IntVector3(path.Key, area.Index, tile.SectorIndex)); _pathJobs.Add(new AddToPathJob(area, tile, path, this)); //_Jobs.Add(new AddToPathJob(area, tile, path, this), true); }
private void RebuildNodesOnSectorEdge(MultiLevelSector sector, int edgeIndex, int edgeIndexNeighbourSector, Vector2 startInSector, Vector2 startInNeighbourSector, Vector2 direction, WorldArea area) { // remove connections to sector nodes on edge + remove them and those directly linked on neighbour sector Manager.RemoveAllAbstractNodesOnSectorEdge(sector, edgeIndex); var maxStep = direction == Vector2.right ? sector.TilesInWidth : sector.TilesInHeight; int sec = -1; for (int i = 0; i < maxStep; i++) { Tile neighbour = area.TileGrid[(int)startInNeighbourSector.x + (int)direction.x * i][ (int)startInNeighbourSector.y + (int)direction.y * i]; if (neighbour != null) { sec = neighbour.SectorIndex; Manager.RemoveAllAbstractNodesOnSectorEdge(area.SectorGrid[0][sec], edgeIndexNeighbourSector); break; } } if (sec != -1) // if we haven't found any tiles, no reason to try and build connections { // build nodes on edge bool sectorNodesOpen = false; int openLength = -1; int startNodeOfGroup = 0; for (int i = 0; i < maxStep; i++) { var tile1 = area.TileGrid[(int)startInSector.x + (int)direction.x * i][ (int)startInSector.y + (int)direction.y * i]; var tile2 = area.TileGrid[(int)startInNeighbourSector.x + (int)direction.x * i][ (int)startInNeighbourSector.y + (int)direction.y * i]; if (tile1 != null && tile2 != null && !tile1.Blocked && !tile2.Blocked && Manager.WorldData.TileManager.TilesWithinRangeGeneration(tile1, tile2)) { // starting point of a new connection/gate between sectors if (!sectorNodesOpen) { sectorNodesOpen = true; } openLength++; } else { if (sectorNodesOpen) // if we have had a couple of open nodes couples { // small enough to represent with 1 transition if (openLength < Manager.MaxGateSize) { int steps = Mathf.FloorToInt(openLength * 0.5f) + startNodeOfGroup; Tile neighbourTile = area.TileGrid[(int)startInNeighbourSector.x + (int)direction.x * steps][ (int)startInNeighbourSector.y + (int)direction.y * steps]; Manager.CreateSectorNodes(sector, neighbourTile.SectorIndex, edgeIndex, edgeIndexNeighbourSector, area.TileGrid[(int)startInSector.x + (int)direction.x * steps][ (int)startInSector.y + (int)direction.y * steps], neighbourTile, area); } else { // to large, 2 transitions. on on each end int multilayer = startNodeOfGroup; Tile neighbourTile = area.TileGrid[(int)startInNeighbourSector.x + (int)direction.x * multilayer][ (int)startInNeighbourSector.y + (int)direction.y * multilayer]; Manager.CreateSectorNodes(sector, neighbourTile.SectorIndex, edgeIndex, edgeIndexNeighbourSector, area.TileGrid[(int)startInSector.x + (int)direction.x * multilayer][ (int)startInSector.y + (int)direction.y * multilayer], neighbourTile, area); multilayer = (startNodeOfGroup + openLength); neighbourTile = area.TileGrid[(int)startInNeighbourSector.x + (int)direction.x * multilayer][ (int)startInNeighbourSector.y + (int)direction.y * multilayer]; Manager.CreateSectorNodes(sector, neighbourTile.SectorIndex, edgeIndex, edgeIndexNeighbourSector, area.TileGrid[(int)startInSector.x + (int)direction.x * multilayer][ (int)startInSector.y + (int)direction.y * multilayer], neighbourTile, area); } openLength = -1; sectorNodesOpen = false; } startNodeOfGroup = i + 1; } } if (sectorNodesOpen) // if we have had a couple of open nodes couples { if (openLength < Manager.MaxGateSize) { int steps = Mathf.FloorToInt(openLength * 0.5f) + startNodeOfGroup; Tile neighbourTile = area.TileGrid[(int)startInNeighbourSector.x + (int)direction.x * steps][ (int)startInNeighbourSector.y + (int)direction.y * steps]; Manager.CreateSectorNodes(sector, neighbourTile.SectorIndex, edgeIndex, edgeIndexNeighbourSector, area.TileGrid[(int)startInSector.x + (int)direction.x * steps][ (int)startInSector.y + (int)direction.y * steps], neighbourTile, area); } else { // to large, 2 transitions. on on each end int multilayer = startNodeOfGroup; Tile neighbourTile = area.TileGrid[(int)startInNeighbourSector.x + (int)direction.x * multilayer][ (int)startInNeighbourSector.y + (int)direction.y * multilayer]; Manager.CreateSectorNodes(sector, neighbourTile.SectorIndex, edgeIndex, edgeIndexNeighbourSector, area.TileGrid[(int)startInSector.x + (int)direction.x * multilayer][ (int)startInSector.y + (int)direction.y * multilayer], neighbourTile, area); multilayer = (startNodeOfGroup + openLength); neighbourTile = area.TileGrid[(int)startInNeighbourSector.x + (int)direction.x * multilayer][ (int)startInNeighbourSector.y + (int)direction.y * multilayer]; Manager.CreateSectorNodes(sector, neighbourTile.SectorIndex, edgeIndex, edgeIndexNeighbourSector, area.TileGrid[(int)startInSector.x + (int)direction.x * multilayer][ (int)startInSector.y + (int)direction.y * multilayer], neighbourTile, area); } } } }
void OnSceneGUI() { Pathfinder myTarget = (Pathfinder)target; if (myTarget.worldData.worldAreas.Count != 0) // no values/ nothing generated { if (myTarget.worldData.drawCost) { if (brush == null) { brush = myTarget.transform.GetChild(1).gameObject.transform; brush.gameObject.SetActive(true); } brush.localScale = new Vector3(myTarget.brushSize * myTarget.tileSize, 1, myTarget.brushSize * myTarget.tileSize); Event current = Event.current; int controlID = GUIUtility.GetControlID(GetHashCode(), FocusType.Passive); int layer = (1 << myTarget.groundLayer); switch (current.type) { case EventType.MouseMove: { Ray ray = HandleUtility.GUIPointToWorldRay(current.mousePosition); RaycastHit hit; if (Physics.Raycast(ray, out hit, 100f, layer)) { WorldArea area = myTarget.worldData.tileManager.GetWorldAreaAtPosition(hit.point); Tile tileHit = myTarget.worldData.tileManager.GetTileInWorldArea(area, hit.point); if (tileHit != null) { brush.position = myTarget.worldData.tileManager.GetTileWorldPosition(tileHit, area); } } break; } case EventType.mouseDrag: { if (current.button == 0) { //Ray ray = Camera.current.ScreenPointToRay(e.mousePosition); Ray ray = HandleUtility.GUIPointToWorldRay(current.mousePosition); RaycastHit hit; if (Physics.Raycast(ray, out hit, 100f, layer)) { WorldArea area = myTarget.worldData.tileManager.GetWorldAreaAtPosition(hit.point); Tile tileHit = myTarget.worldData.tileManager.GetTileInWorldArea(area, hit.point); if (tileHit != null) { tileHit.cost += myTarget.brushStrength; if (tileHit.cost > myTarget.maxCostValue) { tileHit.cost = myTarget.maxCostValue; } tilesCostChanged.Clear(); tilesCostChanged.Add(tileHit); brush.position = myTarget.worldData.tileManager.GetTileWorldPosition(tileHit, area); if (myTarget.brushSize != 1) { int brushMaxDif = (int)(myTarget.brushSize * 0.5f); for (int x = -brushMaxDif; x <= brushMaxDif; x++) { for (int y = -brushMaxDif; y <= brushMaxDif; y++) { if (x != 0 || y != 0) { if (Physics.Raycast(brush.position + new Vector3(x * myTarget.tileSize, 0.1f, y * myTarget.tileSize) + (Vector3.up * myTarget.generationClimbHeight), Vector3.down, out hit, myTarget.generationClimbHeight + 0.2f, layer)) { area = myTarget.worldData.tileManager.GetWorldAreaAtPosition(hit.point); tileHit = myTarget.worldData.tileManager.GetTileInWorldArea(area, hit.point); if (tileHit != null) { int fallOff = Mathf.Max(Mathf.Abs(x), Mathf.Abs(y)) * myTarget.brushFallOff; if (fallOff < myTarget.brushStrength) { tileHit.cost += myTarget.brushStrength - fallOff; if (tileHit.cost > myTarget.maxCostValue) { tileHit.cost = myTarget.maxCostValue; } tilesCostChanged.Add(tileHit); } } } } } } } myTarget.costManager.EditCostFieldAlpha(tilesCostChanged); } } } current.Use(); break; } case EventType.layout: HandleUtility.AddDefaultControl(controlID); break; } if (GUI.changed) { EditorUtility.SetDirty(target); } } else { if (brush != null) { brush.gameObject.SetActive(false); } brush = null; } } }
public void AddSectorInPath(WorldArea area, Tile tile, FlowFieldPath path) { pathAdjustmentsInProgress.Add(new IntVector3(path.key, area.index, tile.sectorIndex)); pathJobs.Add(new AddToPathJob(area, tile, path, this)); }
private List <MultiLevelSector> GetNeighboursWithinWorldArea(MultiLevelSector sector, WorldArea area) { List <MultiLevelSector> neighbours = new List <MultiLevelSector>(); int sectorsGridHeight = GetSectorGridHeightAtLevel(area, sector.Level); int sectorsGridWidth = GetSectorGridWidthAtLevel(area, sector.Level); int checkX = sector.GridX + 1; int checkY = sector.GridY; if (checkX >= 0 && checkX < sectorsGridWidth) { neighbours.Add(area.SectorGrid[sector.Level][(checkY * sectorsGridWidth) + checkX]); } checkX = sector.GridX - 1; checkY = sector.GridY; if (checkX >= 0 && checkX < sectorsGridWidth) { neighbours.Add(area.SectorGrid[sector.Level][(checkY * sectorsGridWidth) + checkX]); } checkX = sector.GridX; checkY = sector.GridY - 1; if (checkY >= 0 && checkY < sectorsGridHeight) { neighbours.Add(area.SectorGrid[sector.Level][(checkY * sectorsGridWidth) + checkX]); } checkX = sector.GridX; checkY = sector.GridY + 1; if (checkY >= 0 && checkY < sectorsGridHeight) { neighbours.Add(area.SectorGrid[sector.Level][(checkY * sectorsGridWidth) + checkX]); } return(neighbours); }
private void RemoveWorldAreaNodes(IntVector3 key) { WorldArea area = worldData.worldAreas[key.x]; List <AbstractNode> abstractNodes = new List <AbstractNode>(area.sectorGrid[0][key.z].worldAreaNodes.Keys); AbstractNode abstractNode; for (int i = 0; i < abstractNodes.Count; i++) { abstractNode = abstractNodes[i]; if (area.sectorGrid[0][key.z].worldAreaNodes[abstractNode] == key.y) { List <AbstractNode> abstractNodes2 = null; WorldArea otherArea = worldData.worldAreas[key.y]; MultiLevelSector otherSector = otherArea.sectorGrid[0][abstractNode.nodeConnectionToOtherSector.tileConnection.sectorIndex]; // remove in other connected sector first worldData.multiLevelSectorManager.RemoveAbstractNode(0, abstractNode.nodeConnectionToOtherSector); otherSector.worldAreaNodes.Remove(abstractNode.nodeConnectionToOtherSector); // visual otherSector.SearchConnections(); if (worldData.pathfinder.maxLevelAmount > 1) { abstractNodes2 = new List <AbstractNode>(worldData.multiLevelSectorManager.GetHigherSectorFromLower(1, otherSector, otherArea).worldAreaNodes.Keys); AbstractNode worldAreaNode; for (int j = 0; j < abstractNodes2.Count; j++) { worldAreaNode = abstractNodes2[j]; if (worldAreaNode.nodeConnectionToOtherSector.worldAreaIndex == area.index && worldAreaNode.tileConnection.sectorIndex == abstractNode.nodeConnectionToOtherSector.tileConnection.sectorIndex) // if this node connects with other, and in the right lower sector { worldData.multiLevelSectorManager.RemoveAbstractNode(1, worldAreaNode); otherArea.sectorGrid[1][worldAreaNode.sector].worldAreaNodes.Remove(worldAreaNode); // visual otherArea.sectorGrid[1][worldAreaNode.sector].SearchConnections(); } } } worldData.multiLevelSectorManager.RemoveAbstractNode(0, abstractNode); area.sectorGrid[0][key.z].worldAreaNodes.Remove(abstractNode); // visual area.sectorGrid[0][key.z].SearchConnections(); if (worldData.pathfinder.maxLevelAmount > 1) { abstractNodes2.Clear(); abstractNodes2.AddRange(worldData.multiLevelSectorManager.GetHigherSectorFromLower(1, area.sectorGrid[0][key.z], area).worldAreaNodes.Keys); AbstractNode worldAreaNode; for (int j = 0; j < abstractNodes2.Count; j++) { worldAreaNode = abstractNodes2[j]; if (worldAreaNode.nodeConnectionToOtherSector.worldAreaIndex == key.y && worldAreaNode.tileConnection.sectorIndex == key.z) // if this node connects with other, and in the right lower sector { worldData.multiLevelSectorManager.RemoveAbstractNode(1, worldAreaNode); Debug.Log("area.sectorGrid " + area.sectorGrid.Length + " " + worldAreaNode.sector); area.sectorGrid[1][worldAreaNode.sector].worldAreaNodes.Remove(worldAreaNode); // visual area.sectorGrid[1][worldAreaNode.sector].SearchConnections(); } } } } } }
public void SetupSectorsWorldArea(WorldArea worldArea) { int sectorWidth = WorldData.Pathfinder.sectorSize; int sectorHeight = WorldData.Pathfinder.sectorSize; if (WorldData.Pathfinder.maxLevelAmount == 0) { sectorWidth = worldArea.GridWidth; sectorHeight = worldArea.GridLength; worldArea.LevelDimensions = new int[1][]; worldArea.LevelDimensions[0] = new int[4]; worldArea.LevelDimensions[0][0] = sectorWidth; worldArea.LevelDimensions[0][1] = sectorHeight; worldArea.LevelDimensions[0][2] = 1; worldArea.LevelDimensions[0][3] = 1; worldArea.SectorGrid = new MultiLevelSector[1][]; worldArea.SectorGrid[0] = new MultiLevelSector[worldArea.LevelDimensions[0][2] * worldArea.LevelDimensions[0][3]]; int j = 0; int i = 0; int level = 0; int index = 0; worldArea.TileSectorNodeConnections = new Dictionary <Tile, List <AbstractNode> > [1]; worldArea.TileSectorNodeConnections[level] = new Dictionary <Tile, List <AbstractNode> >(); worldArea.SectorGrid[level][index] = new MultiLevelSector { GridX = j, GridY = i, Id = index, Level = level, Top = i * worldArea.LevelDimensions[level][0], Bottom = i * worldArea.LevelDimensions[level][0] + worldArea.LevelDimensions[level][0] - 1, Left = j * worldArea.LevelDimensions[level][0], Right = j * worldArea.LevelDimensions[level][0] + worldArea.LevelDimensions[level][0] - 1 }; worldArea.SectorGrid[level][index].TilesInWidth = Mathf.Min( worldArea.GridWidth - worldArea.SectorGrid[level][index].Left, worldArea.LevelDimensions[level][0]); worldArea.SectorGrid[level][index].TilesInHeight = Mathf.Min( worldArea.GridLength - worldArea.SectorGrid[level][index].Top, worldArea.LevelDimensions[level][1]); worldArea.SectorGrid[level][index].WorldAreaIndex = worldArea.Index; worldArea.SectorGrid[level][index].Setup(); } else { worldArea.TileSectorNodeConnections = new Dictionary <Tile, List <AbstractNode> > [WorldData.Pathfinder.maxLevelAmount]; worldArea.LookUpLowerSectors = new int[WorldData.Pathfinder.maxLevelAmount - 1][][][]; worldArea.LevelDimensions = new int[WorldData.Pathfinder.maxLevelAmount][]; worldArea.SectorGrid = new MultiLevelSector[WorldData.Pathfinder.maxLevelAmount][]; } for (int level = 0; level < WorldData.Pathfinder.maxLevelAmount; level++) { worldArea.TileSectorNodeConnections[level] = new Dictionary <Tile, List <AbstractNode> >(); worldArea.LevelDimensions[level] = new int[4]; worldArea.LevelDimensions[level][0] = sectorWidth; worldArea.LevelDimensions[level][1] = sectorHeight; worldArea.LevelDimensions[level][2] = Mathf.FloorToInt((worldArea.GridWidth / (float)sectorWidth)); //Math.CeilToInt(worldLayer.gridWidth / (float)sectorWidth); worldArea.LevelDimensions[level][3] = Mathf.FloorToInt((worldArea.GridLength / (float)sectorHeight)); //Math.CeilToInt(worldLayer.gridHeight / (float)sectorHeight); worldArea.SectorGrid[level] = new MultiLevelSector[worldArea.LevelDimensions[level][2] * worldArea.LevelDimensions[level][3]]; for (int i = 0; i < worldArea.LevelDimensions[level][3]; i++) { for (int j = 0; j < worldArea.LevelDimensions[level][2]; j++) { int index = (i * worldArea.LevelDimensions[level][2]) + j; worldArea.SectorGrid[level][index] = new MultiLevelSector { GridX = j, GridY = i, Id = index, Level = level, Top = i * worldArea.LevelDimensions[level][0], Bottom = i * worldArea.LevelDimensions[level][0] + worldArea.LevelDimensions[level][0] - 1, Left = j * worldArea.LevelDimensions[level][0], Right = j * worldArea.LevelDimensions[level][0] + worldArea.LevelDimensions[level][0] - 1 }; worldArea.SectorGrid[level][index].TilesInWidth = Mathf.Min( worldArea.GridWidth - worldArea.SectorGrid[level][index].Left, worldArea.LevelDimensions[level][0]); worldArea.SectorGrid[level][index].TilesInHeight = Mathf.Min( worldArea.GridLength - worldArea.SectorGrid[level][index].Top, worldArea.LevelDimensions[level][1]); worldArea.SectorGrid[level][index].WorldAreaIndex = worldArea.Index; worldArea.SectorGrid[level][index].Setup(); } } sectorWidth *= WorldData.Pathfinder.levelScaling; sectorHeight *= WorldData.Pathfinder.levelScaling; if (level != 0) { worldArea.LookUpLowerSectors[level - 1] = new int[worldArea.SectorGrid[level].Length][][]; } } if (WorldData.Pathfinder.maxLevelAmount != 0) { FillInLookUpLowerSectors(worldArea); } }
private void RemoveWorldAreaNodes(IntVector3 key) { WorldArea area = WorldData.WorldAreas[key.X]; List <AbstractNode> abstractNodes = new List <AbstractNode>(area.SectorGrid[0][key.Z].WorldAreaNodes.Keys); foreach (var abstractNode in abstractNodes) { if (area.SectorGrid[0][key.Z].WorldAreaNodes[abstractNode] == key.Y) { List <AbstractNode> abstractNodes2 = null; WorldArea otherArea = WorldData.WorldAreas[key.Y]; MultiLevelSector otherSector = otherArea.SectorGrid[0][abstractNode.NodeConnectionToOtherSector.TileConnection.SectorIndex]; // remove in other connected sector first WorldData.MultiLevelSectorManager.RemoveAbstractNode(0, abstractNode.NodeConnectionToOtherSector); otherSector.WorldAreaNodes.Remove(abstractNode.NodeConnectionToOtherSector); // visual otherSector.SearchConnections(); if (WorldData.Pathfinder.maxLevelAmount > 1) { abstractNodes2 = new List <AbstractNode>(WorldData.MultiLevelSectorManager .GetHigherSectorFromLower(1, otherSector, otherArea).WorldAreaNodes.Keys); foreach (var t in abstractNodes2) { var worldAreaNode = t; if (worldAreaNode.NodeConnectionToOtherSector.WorldAreaIndex == area.Index && worldAreaNode.TileConnection.SectorIndex == abstractNode.NodeConnectionToOtherSector .TileConnection .SectorIndex) // if this node connects with other, and in the right lower sector { WorldData.MultiLevelSectorManager.RemoveAbstractNode(1, worldAreaNode); otherArea.SectorGrid[1][worldAreaNode.Sector].WorldAreaNodes.Remove(worldAreaNode); // visual otherArea.SectorGrid[1][worldAreaNode.Sector].SearchConnections(); } } } WorldData.MultiLevelSectorManager.RemoveAbstractNode(0, abstractNode); area.SectorGrid[0][key.Z].WorldAreaNodes.Remove(abstractNode); // visual area.SectorGrid[0][key.Z].SearchConnections(); if (WorldData.Pathfinder.maxLevelAmount > 1) { if (abstractNodes2 != null) { abstractNodes2.Clear(); abstractNodes2.AddRange(WorldData.MultiLevelSectorManager .GetHigherSectorFromLower(1, area.SectorGrid[0][key.Z], area).WorldAreaNodes.Keys); foreach (var worldAreaNode in abstractNodes2) { if (worldAreaNode.NodeConnectionToOtherSector.WorldAreaIndex == key.Y && worldAreaNode.TileConnection.SectorIndex == key.Z ) // if this node connects with other, and in the right lower sector { WorldData.MultiLevelSectorManager.RemoveAbstractNode(1, worldAreaNode); Debug.Log("area.sectorGrid " + area.SectorGrid.Length + " " + worldAreaNode.Sector); area.SectorGrid[1][worldAreaNode.Sector].WorldAreaNodes.Remove(worldAreaNode); // visual area.SectorGrid[1][worldAreaNode.Sector].SearchConnections(); } } } } } } }
public AbstractNode CreateAbstractNodeOnSectorEdge(MultiLevelSector sector, int edgeIndex, Tile tile, WorldArea area) { AbstractNode sectorNode = CreateAbstractNodeInSector(sector, tile, area); sector.sectorNodesOnEdge[edgeIndex].Add(sectorNode); return(sectorNode); }