// add sectors/fields public void AddToFlowFieldPath(List <Tile> tiles, List <int> sectors, Tile destination, SearchPathJob pathJob, WorldArea area) { int amount = worldData.multiLevelSectorManager.GetSectorWidthAtLevel(area, 0) * worldData.multiLevelSectorManager.GetSectorHeightAtLevel(area, 0); flowFieldPaths[flowFieldPaths.Count - 1].intergrationField.AddFields(sectors, amount, tiles, area); flowFieldPaths[flowFieldPaths.Count - 1].flowField.AddFields(sectors, amount, area); }
public void StartIntegrationFieldCreation(Tile destinationTile, List <List <int> > _areasAndSectors, FlowFieldPath _flowPath, SearchPathJob pathJob, int key, bool pathEdit) { FlowFieldPath flowPath = null; bool aPathIsCreated = false; List <List <int> > areasAndSectors = _areasAndSectors; int index = 0; int startIndex = 0; 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 = true; if (pathEdit) { firstWorldArea = false; } bool firstWorldAreaOfNewSearch = true; for (int a = 0; a < areasAndSectors.Count; a++) // each seperate search //areasAndSectors.Count { firstWorldAreaOfNewSearch = true; index = 0; areas.Clear(); sectors.Clear(); Dictionary <IntVector2, int[]> alreadyFilledInSector = null; IntVector2 areaSectorKey = new IntVector2(0, 0);//area.index, sectorIndex); if (pathEdit && _flowPath != null) { flowPath = _flowPath; } //setup/starting point of the sectors- and areas- lists 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 firts one. we might be able to skip alot of already integrated sectors { if (flowPath == null) { flowPath = worldData.flowFieldManager.flowFieldPaths[worldData.flowFieldManager.flowFieldPaths.Count - 1]; } alreadyFilledInSector = flowPath.intergrationField.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 diffrent search { // set what tiles to cross over during a search // seperate 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 arent again // we split up this search, so that every search in the folowing steps is a list of sectors that all directly connect. // no gaps of alredy filledin 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 && firstWorldAreaOfNewSearch && areasAndSectors[a][startIndex] != areasAndSectors[a][startIndex - 2]) // diffrent 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 && !pathEdit) { 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.intergrationField.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 alredy 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 intergration fields generated, create flow field if (firstWorldArea) { aPathIsCreated = true; worldData.flowFieldManager.CreateFlowFieldPath(closedSet, sectors[i], areas, destinationTile, pathJob, currentWorldArea, key); } else { worldData.flowFieldManager.AddToFlowFieldPath(closedSet, sectors[i], destinationTile, pathJob, 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) { if (aPathIsCreated) { pathJob.PathCreated(flowPath, false); } else { pathJob.PathCreated(null, false); } } else { if (aPathIsCreated) { worldData.pathfinder.PathCreated(flowPath, flowPath.key, pathEdit); } else { worldData.pathfinder.PathCreated(null, 0, pathEdit); } } ResetTilesAfterSearch(); }
// create flowfield public void CreateFlowFieldPath(List <Tile> tiles, List <int> sectors, List <int> worldAreas, Tile destination, SearchPathJob pathJob, WorldArea area, int key) { FlowFieldPath path = new FlowFieldPath(); path.Create(destination, worldAreas, worldData.intergrationFieldManager.CreateIntergrationField(tiles, sectors, destination, area), CreateFlowField(sectors, area), key); flowFieldPaths.Add(path); }