public void applyEffect(Tile tile) { if (_applyEffect) { // update temperature: compute at water level elevation and not at tile's elevation tile.temperature = (HexRegion.computeTemperatureAtPos(tile.getPos() - new UnityEngine.Vector3(0, tile.elevationToWater, 0))); base.applyEffect(tile); } }
public HexRoom(RegionType regionType, HexRegions hexRegions) { float randomValue = Random.value; HexRegion currentRegion = null; foreach (HexRegion region in hexRegions.regions) { if (region.IsInRange(randomValue)) { currentRegion = region; break; } } if (currentRegion.type == regionType) { currentRegion = hexRegions.regions [((int)(currentRegion.type) + 1) % hexRegions.regions.Count]; } this.region = currentRegion; }
private void spawnNonPlayablePlayers() { HexRegion region = mapGenerator.getRegion() as HexRegion; // TODO implement more functionality here // get tiles within vicinity Tile tile = region.getTileAt(this.humanPlayer.getTilePos().index); PathResult pr = (new DijkstraUniformCostPathFinder(uniformCost: 1f, maxDepth: enemySpawnPointSearchMaxDepth, maxCost: float.MaxValue)) .pathFromTo(region, tile, new HexTile(new Vector3(), new Vector2(float.MaxValue, float.MaxValue))); // spawn enemies at tiles with tribes foreach (Tile t in pr.getExploredTiles()) { if ((t.getPos() - humanPlayer.getPos()).magnitude <= enemyDespawnRadius && checkForPlayersAt(t) == null && AIs.Count < maxEnemiesSpawned) { if (t.getTileType().GetType() == typeof(LandTileType)) { foreach (TileAttribute ta in t.getTileAttributes()) { if (ta.GetType() == typeof(LocalTribe)) { int strength = (ta as LocalTribe).level * enemyStrengthPerTribeLevel; NonPlayablePlayer p = new NonPlayablePlayer(50, strength); p.setTilePos(t); if (p.computeStrength() > 0) { AIs.Add(new ArtificialIntelligence(p)); } break; } } } } } }
public PathResult pathFromTo(HexRegion region, Tile start, Tile goal, bool playersCanBlockPath = false) { return(pathFromTo(region, start, goal, this, playersCanBlockPath)); }
// inspired by http://www.redblobgames.com/pathfinding/a-star/introduction.html public virtual PathResult pathFromTo(Tile start, Tile goal, HeuristicPathFinder heuristic, bool playersCanBlockPath = false) { HexRegion region = GameControl.gameSession.mapGenerator.getRegion() as HexRegion; return(pathFromTo(region, start, goal, heuristic, playersCanBlockPath)); }
public virtual PathResult pathFromTo(HexRegion region, Tile start, Tile goal, HeuristicPathFinder heuristic, bool playersCanBlockPath = false) { PathResult pathResult = new PathResult(); PathTile goalPt = new PathTile(goal); // set up lists PriorityQueue <PathTile> frontier = new PriorityQueue <PathTile>(); Dictionary <Vector2, PathTile> explored = new Dictionary <Vector2, PathTile>(); Dictionary <Vector2, PathTile> previous = new Dictionary <Vector2, PathTile>(); Dictionary <Vector2, float> costs = new Dictionary <Vector2, float>(); PathTile crt; crt = new PathTile(start); crt.depth = 0; frontier.Enqueue(crt, 0); previous[crt.tile.index] = null; costs[crt.tile.index] = 0; // start pathfinding while (!frontier.IsEmpty()) { // get current crt = frontier.Dequeue(); // record that the tile was explored explored[crt.tile.index] = crt; if (crt.CompareTo(goalPt)) { // reached goal; search complete pathResult.reachedGoal = true; pathResult.pathCost = costs[crt.tile.index]; break; } // get neighbor tiles List <PathTile> neighbors = new List <PathTile>(); foreach (Tile neighborTile in region.getTileNeighbors(crt.tile.index)) { PathTile neighbor = new PathTile(neighborTile); //neighborPt.cost = crt.cost + costBetween(crt, neighborPt); neighbor.depth = crt.depth + 1; neighbors.Add(neighbor); } // add neighbor tiles to search float cost, priority; foreach (PathTile neighbor in neighbors) { // check if exceeding max depth if (neighbor.depth > maxDepth) { break; } // compute cost float _cost = costBetween(crt, neighbor); // check if path is blocked by another player if (playersCanBlockPath && GameControl.gameSession.checkForPlayersAt(neighbor.tile) != null) { if (!neighbor.CompareTo(goalPt)) // ensures that you can move to a tile with an enemy { _cost = float.PositiveInfinity; // set highest cost to signify that the tile is unreachable } } cost = costs[crt.tile.index] + _cost; if (cost <= maxCost) { if (!costs.ContainsKey(neighbor.tile.index) || cost < costs[neighbor.tile.index]) { costs[neighbor.tile.index] = cost; // compute heuristic priority priority = cost + heuristic.heuristic(neighbor, goalPt); priority -= neighbor.depth * heuristicDepthInfluence; // makes so that tiles closest to goal are more eagerly explored frontier.Enqueue(neighbor, priority); previous[neighbor.tile.index] = crt; } } } } // build list of tiles on path if goal was reached if (pathResult.reachedGoal) { pathResult.addPathtile(goalPt); crt = previous[goal.index]; while (crt != null) { pathResult.addPathtile(crt); crt = previous[crt.tile.index]; } } foreach (PathTile pt in explored.Values) { pathResult.addExploredPathtile(pt); } return(pathResult); }
public PathResult pathFromTo(HexRegion _region, Tile start, Tile goal, bool playersCanBlockPath = false) { // attempt normal Dijsktra pathfinder first PathResult pr = DijsktraPF.pathFromTo( _region, start, goal, playersCanBlockPath ); if (pr.reachedGoal) { return(pr); } // get full path to tile even if its out of range PathResult prA = AstarPF.pathFromTo( _region, start, GameControl.gameSession.humanPlayer.getTilePos(), playersCanBlockPath ); // get move range PathResult prD = DijsktraPF.pathFromTo( _region, start, new HexTile(new Vector3(float.MaxValue, float.MaxValue, float.MaxValue), new Vector2(float.MaxValue, float.MaxValue)), playersCanBlockPath ); // get the last tile given by astar pathfinder to goal that is still within move range Tile _goal = null; if (prA.reachedGoal) { foreach (Tile t in prA.getTilesOnPathStartFirst()) { bool outOfRange = true; foreach (Tile explored in prD.getExploredTiles()) { if (t.getPos() == explored.getPos()) { _goal = t; outOfRange = false; break; } } if (outOfRange) { break; } } } if (_goal != null) { return(DijsktraPF.pathFromTo( _region, start, _goal, playersCanBlockPath )); } else { return(prD); } }
public abstract PathResult pathFromTo(HexRegion _region, Tile start, Tile goal, bool playersCanBlockPath = false);
// TODO test this method more thoroughly // attempt to place player in the center of the generated region private void InitializeHumanPlayerPosition() { // get a tile in the center of the region float regionSize = mapGenerator.getRegion().getViewableSize(); Tile tile = mapGenerator.getRegion().getTileAt(new Vector3()); HexRegion region = mapGenerator.getRegion() as HexRegion; PathResult pr, prLocal; int landmassSearchDepth = 10, maxDepth = 50, increments = 10; while (landmassSearchDepth <= maxDepth) { // run uniform cost search to locate surronding land tiles pr = (new DijkstraUniformCostPathFinder(uniformCost: 1f, maxDepth: landmassSearchDepth, maxCost: float.MaxValue)) .pathFromTo(region, tile, new HexTile(new Vector3(), new Vector2(float.MaxValue, float.MaxValue))); // check if explored tiles are part of big enough landmass foreach (Tile _tile in pr.getExploredTiles()) { if (_tile.getTileType().GetType() == typeof(LandTileType)) { // run Dijkstra pathfinder starting at current landtype tile and count how many landtype tiles are reachable from it prLocal = (new DijkstraPathFinder(maxDepth: 20, maxCost: 500, maxIncrementalCost: humanPlayer.getMaxActionPoints())) .pathFromTo(region, _tile, new HexTile(new Vector3(), new Vector2(float.MaxValue, float.MaxValue))); int localCount = 0; foreach (Tile __tile in prLocal.getExploredTiles()) { // count local landmass landtype tiles if (__tile.getTileType().GetType() == typeof(LandTileType)) { localCount++; } } // check if tile's local landmass has enough landtype tiles if (localCount >= playerPosLandmassTilesConstraint) { // run pathfinder again but with small max depth to see if the player can actually move around prLocal = (new DijkstraPathFinder(maxDepth: humanPlayer.getMaxActionPoints(), maxCost: humanPlayer.getMaxActionPoints(), maxIncrementalCost: humanPlayer.getMaxActionPoints())) .pathFromTo(region, _tile, new HexTile(new Vector3(), new Vector2(float.MaxValue, float.MaxValue))); int _localCount = 0; foreach (Tile __tile in prLocal.getExploredTiles()) { // count local landmass landtype tiles if (__tile.getTileType().GetType() == typeof(LandTileType)) { _localCount++; } } if (_localCount >= playerPosLocalTilesConstraint) { // located acceptable starting position // set player pos and return from this method humanPlayer.setTilePos(_tile); return; } } } } // if couldnt locate land tiles during last time, increase maxdepth and run again landmassSearchDepth += increments; } }