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);
        }
Exemple #2
0
 public void AddEmptyField(int sectorIndex, int tilesInSectorAmount, WorldArea area)
 {
     Field.Add(new IntVector2(area.Index, sectorIndex), new int[tilesInSectorAmount]);
 }
Exemple #3
0
        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);
            }
        }
Exemple #4
0
        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);
        }
Exemple #5
0
        // 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;
            }
        }
Exemple #6
0
        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);
        }
Exemple #7
0
 public int GetSectorGridHeightAtLevel(WorldArea worldLayer, int level)
 {
     return(worldLayer.LevelDimensions[level][3]);
 }
Exemple #8
0
        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);
        }
Exemple #9
0
 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)));
 }
Exemple #10
0
        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);
        }
Exemple #11
0
        // 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);
        }
Exemple #12
0
        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();
        }
Exemple #13
0
        // 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);
        }
Exemple #15
0
 public void ConnectNodeInSector(MultiLevelSector sector, AbstractNode sectorNode, WorldArea area)
 {
     if (sector.Level == 0)
     {
         LowLevel.ConnectNodeInSector(sector, sectorNode, area);
     }
     else
     {
         HighLevel.ConnectNodeInSector(sector, sectorNode, area);
     }
 }
Exemple #16
0
        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);
        }
Exemple #17
0
        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);
        }
Exemple #18
0
        // 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);
        }
Exemple #19
0
 public int GetSectorGridWidthAtLevel(WorldArea worldLayer, int level)
 {
     return(worldLayer.LevelDimensions[level][2]);
 }
Exemple #20
0
        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);
            }
        }
Exemple #21
0
        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]);
        }
Exemple #22
0
 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);
 }
Exemple #23
0
        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;
                }
            }
        }
Exemple #25
0
 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));
 }
Exemple #26
0
        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);
        }
Exemple #27
0
        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();
                            }
                        }
                    }
                }
            }
        }
Exemple #28
0
        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);
            }
        }
Exemple #29
0
        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);
        }