//Function called from DrawMapRoads to connect 2 tiles with a road public void ConnectTiles(TileInfo tile1_, TileInfo tile2_, bool setRoadOnEndpoints_ = true) { List <TileInfo> roadPath = PathfindingAlgorithms.DijkstraSearchLandTile(tile1_, tile2_); //If we put road tiles on the endpoints of each path, all tiles have roads if (setRoadOnEndpoints_) { for (int r = 0; r < roadPath.Count; r++) { //If we're on an endpoint, the decoration model isn't deleted if (r == 0 || r == roadPath.Count - 1) { roadPath[r].type = LandType.Road; roadPath[r].tileMaterial = this.roadMaterial; } else { roadPath[r].decorationModel = null; roadPath[r].type = LandType.Road; roadPath[r].tileMaterial = this.roadMaterial; } } } //Otherwise the first and last tiles in the path are ignored so the tiles where location markers are at don't get overridden by roads else { for (int r = 1; r < roadPath.Count - 1; r++) { roadPath[r].decorationModel = null; roadPath[r].type = LandType.Road; roadPath[r].tileMaterial = this.roadMaterial; } } }
//Function called from GenerateSpokeRegion to expand the borders of each region private void ExpandRegionBorders(TileInfo startTile_) { //We find the list of tiles along the edge of the city tile's region List <TileInfo> edgeTiles = PathfindingAlgorithms.FindRegionEdgeTiles(startTile_); //And then we have the region step outward based on the size of the region's boarders Vector2 minMaxSteps = new Vector2(); minMaxSteps.x = edgeTiles.Count * this.minMaxStepPercent.x; minMaxSteps.y = edgeTiles.Count * this.minMaxStepPercent.y; PathfindingAlgorithms.StepOutRegionEdge(edgeTiles, minMaxSteps, this.absoluteMinimumSteps); }
//Function called every frame when the player's mouse is over this object's collider private void OnMouseOver() { //If the selection mode is switched to "None", this tile is no longer hilighted if (TileSelectionMode.GlobalReference.currentSelectionMode == SelectionMode.None) { this.HilightThisTile(false); return; } //If the player left clicks over this tile and the selection mode is anything but "None", it becomes the one that's selected if (Input.GetMouseButtonDown(0) && TileSelectionMode.GlobalReference.currentSelectionMode != SelectionMode.None) { //If the left Alt button isn't held down (for rotating the camera) if (!Input.GetKey(KeyCode.LeftAlt)) { //Un-hilighting the currently selected file if (LandTile.selectedTile != null) { LandTile.selectedTile.HilightThisTile(false); } LandTile.selectedTile = this; //If the selection mode is on "Movement" then the selected characters are told to move to this tile if (TileSelectionMode.GlobalReference.currentSelectionMode == SelectionMode.Movement) { //Making sure the clicked tile isn't the one that the group is already on if (PartyGroup.globalReference.GetComponent <Movement>().currentTile != LandTile.selectedTile.tileReference) { //Using the Dijkstra search to find the dravel path for each character TileInfo startingTile = PartyGroup.globalReference.GetComponent <Movement>().currentTile; TileInfo endTile = LandTile.selectedTile.tileReference; List <TileInfo> pathToFollow = PathfindingAlgorithms.DijkstraSearchLandTile(startingTile, endTile); //Setting the path to follow for the character's movement PartyGroup.globalReference.GetComponent <Movement>().TravelToPath(pathToFollow); //Setting the selection mode to nothing so that it doesn't have to be turned off constantly TileSelectionMode.GlobalReference.ClearSelectionMode(); } //If the clicked tile IS the one the player group is already on, the selection mode is turned off else { TileSelectionMode.GlobalReference.ClearSelectionMode(); } } } } }
//Function inherited from Action.cs public override void PerformAction(CombatTile targetTile_) { //Calling the base function to start the cooldown time base.PerformAction(targetTile_); //If the acting character is an enemy, we need to set the movement path since we're not mousing over tiles if (CombatManager.globalReference.enemyCharactersInCombat.Contains(this.actingCharacter)) { this.movementPath = PathfindingAlgorithms.BreadthFirstSearchCombat(this.movementPath[0], targetTile_, true, true); } //Makes it so that the Update function will now move the character through the movement path this.moveCharacter = true; this.currentNumTilesMoved = 0; }
//Function called internally to highlight or stop highlighting tiles inside an area of effect spell private void HighlightEffectRadius(bool highlightOn_) { //Only works if this tile is in the action range if (!this.inActionRange) { //this.SetTileColor(this.inactiveColor); return; } //If the selected action has a combat effect with a radius greater than 0, we need to highlight those tiles if (CombatActionPanelUI.globalReference.selectedAction != null && CombatActionPanelUI.globalReference.selectedAction.GetComponent <AttackAction>()) { //Getting the reference to the attack action AttackAction selectedAttack = CombatActionPanelUI.globalReference.selectedAction.GetComponent <AttackAction>(); int highestRadius = 0; //Looping through all effects foreach (AttackEffect efc in selectedAttack.effectsOnHit) { if (efc.effectRadius > highestRadius) { highestRadius = efc.effectRadius; } } //If the radius is greater than 0, we need to highlight all tiles in the effect zone if (highestRadius > 0) { List <CombatTile3D> tilesInEffect = PathfindingAlgorithms.FindTilesInActionRange(this, highestRadius); foreach (CombatTile3D tile in tilesInEffect) { //If we turn on the highlight if (highlightOn_) { tile.HighlightTile(true); } //If we turn off the highlight else { tile.HighlightTile(false); } } } } }
public void RequestPath(PathRequest request, bool useInfluenceData, bool needsSmoothing = false) { ThreadPool.QueueUserWorkItem(delegate(object state) { if (needsSmoothing && useInfluenceData) { PathfindingAlgorithms.AStarSearch(_pathfindingGrid, request, FinishedProcessingPath, true, true); } else if (needsSmoothing && !useInfluenceData) { PathfindingAlgorithms.AStarSearch(_pathfindingGrid, request, FinishedProcessingPath, true, false); } else if (!needsSmoothing && useInfluenceData) { PathfindingAlgorithms.AStarSearch(_pathfindingGrid, request, FinishedProcessingPath, false, true); } else if (!needsSmoothing && !useInfluenceData) { PathfindingAlgorithms.AStarSearch(_pathfindingGrid, request, FinishedProcessingPath, false, false); } }); }
public static PathNode FindPath(PathfindingAlgorithms algorithm, PathNode start, PathNode target, NavMap map) { if (start == null || target == null || map == null) return null; switch (algorithm) { case PathfindingAlgorithms.BreadthFirst: return PathfindingUtilities.ReversePath(BreadthFirst(ref start, ref target)); case PathfindingAlgorithms.Dijkstra: return PathfindingUtilities.ReversePath(Dijkstra(ref start, ref target)); case PathfindingAlgorithms.BestFirst: return PathfindingUtilities.ReversePath(BestFirst(ref start, ref target)); default: case PathfindingAlgorithms.aStar: return PathfindingUtilities.ReversePath(aStar(ref start, ref target)); } }
//Function called every frame private void Update() { //If we should be animating this character moving from tile to tile if (this.moveCharacter) { //Increasing the total time that's passed this.currentTimePassed += Time.deltaTime; //If enough time has passed that we've moved one more tile further. We progress the acting character one more tile along the movement path if (this.currentTimePassed >= this.timeToCompleteAction) { //Increasing the index for the number of tiles moved this.currentNumTilesMoved += 1; //Resetting the current movement time this.currentTimePassed = 0; //Moving the character sprite to the new tile position CharacterSpriteBase charSprite = CombatManager.globalReference.GetCharacterSprite(this.actingCharacter); charSprite.transform.position = this.movementPath[this.currentNumTilesMoved].transform.position; //Making sure the sprites are positioned in front of each other correctly CombatManager.globalReference.UpdateCharacterSpriteOrder(); //If the new tile is to the left of the old tile, we face the character left if (this.movementPath[this.currentNumTilesMoved].transform.position.x < this.movementPath[this.currentNumTilesMoved - 1].transform.position.x) { charSprite.SetDirectionFacing(CharacterSpriteBase.DirectionFacing.Left); } //If the new tile is to the right of the old tile, we face the character right else if (this.movementPath[this.currentNumTilesMoved].transform.position.x > this.movementPath[this.currentNumTilesMoved - 1].transform.position.x) { charSprite.SetDirectionFacing(CharacterSpriteBase.DirectionFacing.Right); } //If the new tile is above the old tile, we face the character up else if (this.movementPath[this.currentNumTilesMoved].transform.position.y > this.movementPath[this.currentNumTilesMoved - 1].transform.position.y) { charSprite.SetDirectionFacing(CharacterSpriteBase.DirectionFacing.Up); } //If the new tile is below the old tile, we face the character down else if (this.movementPath[this.currentNumTilesMoved].transform.position.y < this.movementPath[this.currentNumTilesMoved - 1].transform.position.y) { charSprite.SetDirectionFacing(CharacterSpriteBase.DirectionFacing.Down); } //Removing the acting character from the tile they're on CombatManager.globalReference.combatTileGrid[this.actingCharacter.charCombatStats.gridPositionCol][this.actingCharacter.charCombatStats.gridPositionRow].SetObjectOnTile(null, CombatTile.ObjectType.Nothing); //Once the time has passed for this tile, the selected character's position is updated this.actingCharacter.charCombatStats.gridPositionCol = this.movementPath[this.currentNumTilesMoved].col; this.actingCharacter.charCombatStats.gridPositionRow = this.movementPath[this.currentNumTilesMoved].row; CombatManager.globalReference.combatTileGrid[this.actingCharacter.charCombatStats.gridPositionCol][this.actingCharacter.charCombatStats.gridPositionRow].SetObjectOnTile(this.actingCharacter.gameObject, CombatTile.ObjectType.Player); //Looping through and triggering all effects on the moving character that happen during movement foreach (Effect e in this.actingCharacter.charCombatStats.combatEffects) { e.EffectOnMove(); //Checking to see if the acting character has died due to some effect if (this.actingCharacter.GetComponent <PhysicalState>().currentHealth <= 0) { //Clearing the movement path tiles for (int t = this.currentNumTilesMoved; t < this.movementPath.Count; ++t) { this.movementPath[t].GetComponent <Image>().color = new Color(1, 1, 1, this.movementPath[t].inactiveTransparency); } //This game object is destroyed Destroy(this.gameObject); break; } } //If we've moved through all of the tiles on the movement path, this object is destroyed if (this.currentNumTilesMoved + 1 == this.movementPath.Count) { //Setting the character's combat sprite to a stationary position directly on the last tile in our movement path CombatManager.globalReference.GetCharacterSprite(this.actingCharacter).transform.position = this.movementPath[this.movementPath.Count - 1].transform.position; Destroy(this.gameObject); } } } //If there are tiles in the movement path and the mouse is hovering over a combat tile else if (this.movementPath.Count > 0 && CombatTile.mouseOverTile != null) { //If the tile that the mouse is over is connected to the last tile in the current movement path if (this.movementPath[this.movementPath.Count - 1].ourPathPoint.connectedPoints.Contains(CombatTile.mouseOverTile.ourPathPoint) && this.movementPath.Count <= this.range) { //If the tile that the mouse is over isn't already in the movement path and this type of movement allows the user to ignore obstacles if (!this.movementPath.Contains(CombatTile.mouseOverTile)) { //If the tile has no object on it OR if there is an object and the movement action ignores objects if (CombatTile.mouseOverTile.typeOnTile == CombatTile.ObjectType.Nothing || (CombatTile.mouseOverTile.typeOnTile == CombatTile.ObjectType.Object && this.ignoreObstacles) || ((CombatTile.mouseOverTile.typeOnTile == CombatTile.ObjectType.Enemy || CombatTile.mouseOverTile.typeOnTile == CombatTile.ObjectType.Player) && this.ignoreEnemies)) { this.movementPath.Add(CombatTile.mouseOverTile); CombatTile.mouseOverTile.HighlightTile(true); CombatTile.mouseOverTile.SetTileColor(Color.blue); } } //If the tile that the mouse is over IS already in the movement path and isn't the most recent tile else { //Removing all tiles in the movement path that come after this one int indexOfPrevTile = this.movementPath.IndexOf(CombatTile.mouseOverTile) + 1; for (int t = indexOfPrevTile; t < this.movementPath.Count;) { this.movementPath[t].HighlightTile(false); this.movementPath[t].SetTileColor(Color.white); this.movementPath.RemoveAt(t); } } } //If the tile that the mouse is over is NOT connected to the last tile in the current movement path but is still in the path else if (this.movementPath.Contains(CombatTile.mouseOverTile)) { //Removing all tiles in the movement path that come after this one int indexOfPrevTile = this.movementPath.IndexOf(CombatTile.mouseOverTile) + 1; for (int t = indexOfPrevTile; t < this.movementPath.Count;) { this.movementPath[t].HighlightTile(false); this.movementPath[t].SetTileColor(Color.white); this.movementPath.RemoveAt(t); } } //If the tile that the mouse is over is neither on the movement path or on a tile connected to it else { //Making sure the tile that the mouse is over is within this action's range if (CombatTile.mouseOverTile.inActionRange) { //Looping through all of the tiles currently in the movement path and clearing them for (int p = 1; p < this.movementPath.Count; ++p) { this.movementPath[p].HighlightTile(false); this.movementPath[p].SetTileColor(Color.white); } //Use the breadth first search algorithm to find the path to this tile from the player List <CombatTile> newPath = PathfindingAlgorithms.BreadthFirstSearchCombat(this.movementPath[0], CombatTile.mouseOverTile, this.ignoreObstacles, this.ignoreEnemies); if (newPath.Count > 0) { this.movementPath = newPath; } //Looping through each tile that's now in the movement path and coloring it in for (int t = 1; t < this.movementPath.Count; ++t) { this.movementPath[t].HighlightTile(true); this.movementPath[t].GetComponent <Image>().color = Color.blue; } } } } }
public List <Node> RequestNodesAtRadiusWithObstacles(int radius, Vector3 origin) { Debug.Log("originX = " + _pathfindingGrid.GetNodeFromWorldPosition(origin).GridX + " y originZ = " + _pathfindingGrid.GetNodeFromWorldPosition(origin).GridZ); return(PathfindingAlgorithms.BFSWithObstacles(_pathfindingGrid.GetNodeFromWorldPosition(origin), radius, _pathfindingGrid)); }
//Function called every frame private void Update() { //If we should be animating this character moving from tile to tile if (this.moveCharacter) { //Increasing the total time that's passed this.currentTimePassed += Time.deltaTime; GameObject charModel = CombatManager.globalReference.characterHandler.GetCharacterModel(this.actingCharacter); //If enough time has passed that we've moved one more tile further. We progress the acting character one more tile along the movement path if (this.currentTimePassed >= this.timeToCompleteAction) { //Increasing the index for the number of tiles moved this.currentNumTilesMoved += 1; //Resetting the current movement time this.currentTimePassed = 0; //Moving the character sprite to the new tile position charModel.transform.position = this.movementPath[this.currentNumTilesMoved].transform.position; //Removing the acting character from the tile they're on CombatManager.globalReference.tileHandler.combatTileGrid[this.actingCharacter.charCombatStats.gridPositionCol][this.actingCharacter.charCombatStats.gridPositionRow].SetObjectOnTile(null, TileObjectType.Nothing); //Once the time has passed for this tile, the selected character's position is updated this.actingCharacter.charCombatStats.gridPositionCol = this.movementPath[this.currentNumTilesMoved].col; this.actingCharacter.charCombatStats.gridPositionRow = this.movementPath[this.currentNumTilesMoved].row; CombatManager.globalReference.tileHandler.combatTileGrid[this.actingCharacter.charCombatStats.gridPositionCol][this.actingCharacter.charCombatStats.gridPositionRow].SetObjectOnTile(this.actingCharacter.gameObject, TileObjectType.Player); //Looping through and triggering all effects on the moving character that happen during movement foreach (Effect e in this.actingCharacter.charCombatStats.combatEffects) { e.EffectOnMove(); //Checking to see if the acting character has died due to some effect if (this.actingCharacter.GetComponent <PhysicalState>().currentHealth <= 0) { //Clearing the movement path tiles for (int t = this.currentNumTilesMoved; t < this.movementPath.Count; ++t) { this.movementPath[t].SetTileColor(this.movementPath[t].unusedColor); } //This game object is destroyed Destroy(this.gameObject); break; } } //If we've moved through all of the tiles on the movement path, this object is destroyed if (this.currentNumTilesMoved + 1 == this.movementPath.Count) { //Setting the character's combat sprite to a stationary position directly on the last tile in our movement path CombatManager.globalReference.characterHandler.GetCharacterModel(this.actingCharacter).transform.position = this.movementPath[this.movementPath.Count - 1].transform.position; Destroy(this.gameObject); } } //Otherwise we interpolate the character's model to move between tiles else { //Interpolating this character model between the tiles they're moving from and moving to Vector3 startPos = this.movementPath[this.currentNumTilesMoved].transform.position; Vector3 endPos = this.movementPath[this.currentNumTilesMoved + 1].transform.position; float interpPercent = this.currentTimePassed / this.timeToCompleteAction; Vector3 interpPos = (endPos - startPos) * interpPercent; interpPos += startPos; charModel.transform.position = interpPos; //Rotating the model to face the tile they're moving to Vector3 targetPos = this.movementPath[this.currentNumTilesMoved + 1].transform.position; targetPos.y = charModel.transform.position.y; charModel.transform.LookAt(targetPos); } } //If there are tiles in the movement path and the mouse is hovering over a combat tile else if (this.movementPath.Count > 0 && CombatTile3D.mouseOverTile != null) { CombatTile3D lastPathTile = this.movementPath[this.movementPath.Count - 1]; List <CombatTile3D> connectedTiles = new List <CombatTile3D>() { lastPathTile.left, lastPathTile.right, lastPathTile.up, lastPathTile.down }; //If the tile that the mouse is over is connected to the last tile in the current movement path if (connectedTiles.Contains(CombatTile3D.mouseOverTile) && this.movementPath.Count <= this.range) { //If the tile that the mouse is over isn't already in the movement path and this type of movement allows the user to ignore obstacles if (!this.movementPath.Contains(CombatTile3D.mouseOverTile)) { //If the tile has no object on it OR if there is an object and the movement action ignores objects if (CombatTile3D.mouseOverTile.typeOnTile == TileObjectType.Nothing || (CombatTile3D.mouseOverTile.typeOnTile == TileObjectType.Object && this.ignoreObstacles) || ((CombatTile3D.mouseOverTile.typeOnTile == TileObjectType.Enemy || CombatTile3D.mouseOverTile.typeOnTile == TileObjectType.Player) && this.ignoreEnemies)) { this.movementPath.Add(CombatTile3D.mouseOverTile); CombatTile3D.mouseOverTile.HighlightTile(true, true); } } //If the tile that the mouse is over IS already in the movement path and isn't the most recent tile else { //Removing all tiles in the movement path that come after this one int indexOfPrevTile = this.movementPath.IndexOf(CombatTile3D.mouseOverTile) + 1; for (int t = indexOfPrevTile; t < this.movementPath.Count;) { this.movementPath[t].HighlightTile(false); this.movementPath[t].SetTileColor(Color.white); this.movementPath.RemoveAt(t); } } } //If the tile that the mouse is over is NOT connected to the last tile in the current movement path but is still in the path else if (this.movementPath.Contains(CombatTile3D.mouseOverTile)) { //Removing all tiles in the movement path that come after this one int indexOfPrevTile = this.movementPath.IndexOf(CombatTile3D.mouseOverTile) + 1; for (int t = indexOfPrevTile; t < this.movementPath.Count;) { this.movementPath[t].HighlightTile(false); this.movementPath[t].SetTileColor(Color.white); this.movementPath.RemoveAt(t); } } //If the tile that the mouse is over is neither on the movement path or on a tile connected to it else { //Making sure the tile that the mouse is over is within this action's range if (CombatTile3D.mouseOverTile.inActionRange) { //Looping through all of the tiles currently in the movement path and clearing them for (int p = 1; p < this.movementPath.Count; ++p) { this.movementPath[p].HighlightTile(false); this.movementPath[p].SetTileColor(Color.white); } //Use the breadth first search algorithm to find the path to this tile from the player List <CombatTile3D> newPath = PathfindingAlgorithms.BreadthFirstSearchCombat(this.movementPath[0], CombatTile3D.mouseOverTile, this.ignoreObstacles, this.ignoreEnemies); if (newPath.Count > 0) { this.movementPath = newPath; } //Looping through each tile that's now in the movement path and coloring it in for (int t = 1; t < this.movementPath.Count; ++t) { this.movementPath[t].HighlightTile(true, true); } } } } }
//Function called externally from the buttons on the action panel. Tells the combat manager to hilight an action's range public void SelectActionAtIndex(int actionIndex_) { //Clearing all tile highlights before we highlight different ones CombatManager.globalReference.ClearCombatTileHighlights(); //Getting a reference to the character that's currently acting Character actingCharacter = CombatManager.globalReference.actingCharacters[0]; //Finding out which tile the acting character is on CombatTile actingCharsTile = CombatManager.globalReference.FindCharactersTile(actingCharacter); //If the currently selected action is a move action, we need to clear tile highlights along its movement path if (this.selectedAction != null && this.selectedAction.GetComponent <MoveAction>()) { this.selectedAction.GetComponent <MoveAction>().ClearMovePathHighlights(); } //Destroying the game object that holds the currently selected action if (this.selectedAction != null) { Destroy(this.selectedAction.gameObject); } //Creating an instance of the newly selected action prefab object GameObject actionObj = null; //Finding the range of the action based on the button hit int actionRange = 0; switch (this.actionTypeShown) { case Action.ActionType.Major: actionRange = actingCharacter.charActionList.majorActions[actionIndex_].range; actionObj = GameObject.Instantiate(actingCharacter.charActionList.majorActions[actionIndex_].gameObject); //this.selectedAction = actingCharacter.charActionList.standardActions[actionIndex_]; break; case Action.ActionType.Minor: actionRange = actingCharacter.charActionList.minorActions[actionIndex_].range; actionObj = GameObject.Instantiate(actingCharacter.charActionList.minorActions[actionIndex_].gameObject); break; case Action.ActionType.Fast: actionRange = actingCharacter.charActionList.fastActions[actionIndex_].range; actionObj = GameObject.Instantiate(actingCharacter.charActionList.fastActions[actionIndex_].gameObject); break; case Action.ActionType.Massive: actionRange = actingCharacter.charActionList.massiveActions[actionIndex_].range; actionObj = GameObject.Instantiate(actingCharacter.charActionList.massiveActions[actionIndex_].gameObject); break; } //Getting the action component reference from the created action object this.selectedAction = actionObj.GetComponent <Action>(); //Finding out which tiles need to be hilighted if this action isn't a move action List <CombatTile> tilesToHighlight; List <CombatTile> tilesToCheckForCharacters = new List <CombatTile>(); if (!this.selectedAction.GetComponent <MoveAction>()) { tilesToHighlight = PathfindingAlgorithms.FindTilesInActionRange(actingCharsTile, actionRange); tilesToCheckForCharacters = tilesToHighlight; } //If this action is a move action, we have to find the selected tiles based on environment obstacles else { MoveAction ourMoveAct = this.selectedAction.GetComponent <MoveAction>(); //Looping through all of the acting character's perks to see if there are any movement boost perks int rangeModifier = 0; foreach (Perk charPerk in actingCharacter.charPerks.allPerks) { //If the current perk is a movement boost perk that applies to this movement's action type, we apply the number of added spaces if (charPerk.GetType() == typeof(MovementBoostPerk) && ourMoveAct.type == charPerk.GetComponent <MovementBoostPerk>().actionTypeToBoost) { rangeModifier += charPerk.GetComponent <MovementBoostPerk>().addedMovementSpaces; } } //Highlighting all tiles in range tilesToHighlight = PathfindingAlgorithms.FindTilesInActionRange(actingCharsTile, actionRange + rangeModifier, ourMoveAct.ignoreObstacles); tilesToCheckForCharacters = PathfindingAlgorithms.FindTilesInActionRange(actingCharsTile, actionRange + rangeModifier + 1); } //Looping through all tiles in range and hilighting them foreach (CombatTile tile in tilesToHighlight) { tile.inActionRange = true; tile.HighlightTile(false); } //Looping through all of the tiles around the action highlights to check for characters foreach (CombatTile checkedTile in tilesToCheckForCharacters) { //If there's a character sprite on this tile, we hide it a bit if (checkedTile.objectOnThisTile != null) { if (checkedTile.objectOnThisTile.GetComponent <Character>()) { //Getting the sprite base for the character CharacterSpriteBase cSprite = CombatManager.globalReference.GetCharacterSprite(checkedTile.objectOnThisTile.GetComponent <Character>()); //If the character on the tile isn't the one that's acting if (cSprite.ourCharacter != CombatManager.globalReference.actingCharacters[0]) { cSprite.MakeSpritesTransparent(); } } } } //Displays the action's details this.UpdateActionDetailsPanel(); }
//Function called externally from Movement.cs and from StartMapCreation. Spawns the nearest tiles around the player party public void GenerateVisibleLand(TileInfo currentTile_) { //Getting all of the tiles within view range of the current tile List <TileInfo> tilesInRange = PathfindingAlgorithms.FindLandTilesInRange(currentTile_, this.visibilityRange); //Creating a list to hold all of the tiles that are just coming into view List <TileInfo> newTiles = new List <TileInfo>(); //Creating a list to hold all of the tiles that are now outside our view List <TileInfo> oldTiles = new List <TileInfo>(); //Looping through all of the tiles that are currently in view foreach (TileInfo inRangeTile in tilesInRange) { //If the tile in range isn't in the current dictionary of visible objects if (!this.visibleTileObjects.ContainsKey(inRangeTile)) { //The tile is new newTiles.Add(inRangeTile); } } //Looping through all of the tiles that are currently visible foreach (TileInfo visibleTile in this.visibleTileObjects.Keys) { //If the visible tile isn't in range of the new tile if (!tilesInRange.Contains(visibleTile)) { oldTiles.Add(visibleTile); } } //Looping through and removing each tile in the list of old tiles foreach (TileInfo oldTile in oldTiles) { //Deleting the game object for this tile in the visible tile objects dictionary Destroy(this.visibleTileObjects[oldTile]); //Removing this tile from the list this.visibleTileObjects.Remove(oldTile); } //Looping through all of the new tiles and creating an instance of its game object foreach (TileInfo newTile in newTiles) { //Resetting the tile to say it hasn't been checked newTile.hasBeenChecked = false; GameObject hexMesh = this.GetComponent <CreateTileGrid>().hexMesh.gameObject; //Creating an instance of the hex mesh for this tile GameObject tileMesh = Instantiate(hexMesh, new Vector3(newTile.tilePosition.x, newTile.elevation, newTile.tilePosition.z), new Quaternion()); //Setting the mesh's material to the correct one for the tile Material[] tileMat = tileMesh.GetComponent <MeshRenderer>().materials; tileMat[0] = newTile.tileMaterial; tileMesh.GetComponent <MeshRenderer>().materials = tileMat; //Setting the tile's reference in the LandTile component tileMesh.GetComponent <LandTile>().tileReference = newTile; //Adding the hex mesh to our list of visible tile objects this.visibleTileObjects.Add(newTile, tileMesh); //If this tile has a decoration model, an instance of it is created and parented to this tile's mesh object if (newTile.decorationModel != null) { GameObject decor = Instantiate(newTile.decorationModel.gameObject, tileMesh.transform.position, new Quaternion()); decor.transform.SetParent(tileMesh.transform); decor.transform.eulerAngles = new Vector3(0, newTile.decorationRotation, 0); } } }
//Public function called from TileMapManager. Creates a region of a specific zone type using "spokes" that extend outward from the given tile public void GenerateSpokeRegion(int startTileRow_, int startTileCol_, Vector2 spokeMinMax_, Vector2 spokeLengthMinMax_, RegionInfo regionInfo_) { //Throwing an exception if the user inputs a starting tile that isn't on the grid if (startTileCol_ < 0 || startTileCol_ >= TileMapManager.globalReference.tileGrid.Count || startTileRow_ < 0 || startTileRow_ >= TileMapManager.globalReference.tileGrid[0].Count) { throw new System.Exception("The starting tile row or column must be within the bounds of the tile grid"); } //Created a list of int arrays to hold all row/column locations for the tiles in this region //List<List<int>> tilesInRegion = new List<List<int>>(); //tilesInRegion.Add(new List<int> { startTileCol_, startTileRow_ }); List <TileInfo> tilesInRegion = new List <TileInfo>(); tilesInRegion.Add(TileMapManager.globalReference.tileGrid[startTileCol_][startTileRow_]); //Finding the number of spokes int numberOfSpokes = Mathf.RoundToInt(Random.Range(spokeMinMax_.x, spokeMinMax_.y)); //The total angle covered by all spokes. Used to offset each spoke from the previous one float totalAngle = Random.Range(0, 360); float newMinAngle = (360f / numberOfSpokes) * 0.5f; float newMaxAngle = newMinAngle * 3; //Looping through to create each spoke for (int s = 0; s < numberOfSpokes; ++s) { //Finding the angle of the current spoke offset from the previous spoke float spokeAngle = Random.Range(newMinAngle, newMaxAngle); totalAngle += spokeAngle; //Making sure the total angle is between 0 and 360 degrees if (totalAngle > 360) { totalAngle -= 360; } //Finding the length of the current spoke float spokeLength = Random.Range(spokeLengthMinMax_.x, spokeLengthMinMax_.y); //Floats to hold the difference in XY coordinates from the starting tile int xDiff = 0; int yDiff = 0; //Finding the angle under 90 degrees so that we can use trig functions float trigAngle = totalAngle % 90; //Finding the XY difference from the starting tile if (totalAngle <= 90) { //Tile is up and right xDiff = Mathf.RoundToInt(Mathf.Cos(trigAngle * Mathf.Deg2Rad) * spokeLength); yDiff = Mathf.RoundToInt(Mathf.Sin(trigAngle * Mathf.Deg2Rad) * spokeLength); } else if (totalAngle <= 180) { //Tile is up and left xDiff = Mathf.RoundToInt(Mathf.Sin(trigAngle * Mathf.Deg2Rad) * -spokeLength); yDiff = Mathf.RoundToInt(Mathf.Cos(trigAngle * Mathf.Deg2Rad) * spokeLength); } else if (totalAngle <= 270) { //Tile is down and left xDiff = Mathf.RoundToInt(Mathf.Cos(trigAngle * Mathf.Deg2Rad) * -spokeLength); yDiff = Mathf.RoundToInt(Mathf.Sin(trigAngle * Mathf.Deg2Rad) * -spokeLength); } else { //Tile is down and right xDiff = Mathf.RoundToInt(Mathf.Sin(trigAngle * Mathf.Deg2Rad) * spokeLength); yDiff = Mathf.RoundToInt(Mathf.Cos(trigAngle * Mathf.Deg2Rad) * -spokeLength); } //Making sure the tile is within the bouderies of the map if (startTileCol_ + xDiff >= TileMapManager.globalReference.cols) { xDiff = TileMapManager.globalReference.cols - startTileCol_ - 1; } else if (startTileCol_ + xDiff < 0) { xDiff = -startTileCol_; } if (startTileRow_ + yDiff >= TileMapManager.globalReference.rows) { yDiff = TileMapManager.globalReference.rows - startTileRow_ - 1; } else if (startTileRow_ + yDiff < 0) { yDiff = -startTileRow_; } //Adding this tile to the list of tiles in the region //tilesInRegion.Add(new List<int> { startTileCol_ + xDiff, startTileRow_ + yDiff }); tilesInRegion.Add(TileMapManager.globalReference.tileGrid[startTileCol_ + xDiff][startTileRow_ + yDiff]); } //Creating a list to hold all of the tiles along the edge of this region List <TileInfo> edgeTiles = new List <TileInfo>(); //Looping through each spoke point to draw a line between them for (int p = 1; p < tilesInRegion.Count - 1; p++) { List <TileInfo> borderLine = PathfindingAlgorithms.BreadthFirstSearch(tilesInRegion[p], tilesInRegion[p + 1]); for (int bt = 0; bt < borderLine.Count; bt++) { borderLine[bt].SetTileBasedOnRegion(regionInfo_); edgeTiles.Add(borderLine[bt]); } } //Connecting the first point with the last point to close the loop List <TileInfo> finalLine = PathfindingAlgorithms.FindLineOfTiles(tilesInRegion[1], tilesInRegion[tilesInRegion.Count - 1]); for (int bt = 0; bt < finalLine.Count; bt++) { finalLine[bt].SetTileBasedOnRegion(regionInfo_); edgeTiles.Add(finalLine[bt]); } //Filling in all tiles inside the region's border this.FillInRegionOfTiles(tilesInRegion[0], edgeTiles, regionInfo_); //Increasing the size of the region to help smooth it out this.IncreaseRegionSize(edgeTiles, regionInfo_); this.ExpandRegionBorders(tilesInRegion[0]); }
//Function called from StartMapCreation to expand the borders of each region private void ExpandRegionBorders() { //Making a list of each index for the number of total cities List <int> numCities = new List <int>(); for (int r = 0; r < TileMapManager.globalReference.cityTiles.Count; ++r) { numCities.Add(r); } //Creating a separate list to randomize the order of the city indexes List <int> randCityOrder = new List <int>(); for (int c = 0; c < TileMapManager.globalReference.cityTiles.Count; ++c) { //Getting a random index from the numCities list int randIndex = Random.Range(0, TileMapManager.globalReference.cityTiles.Count); //Adding the city index to our list of random city orders randCityOrder.Add(numCities[randIndex]); } //Looping through each city in our randomized order foreach (int index in randCityOrder) { //We get the tile reference for the given index's city TileInfo cityTile = TileMapManager.globalReference.cityTiles[index]; //We find the list of tiles along the edge of the city tile's region List <TileInfo> edgeTiles = PathfindingAlgorithms.FindRegionEdgeTiles(cityTile); //And then we have the region step outward based on the size of the region's boarders Vector2 minMaxSteps = new Vector2(); minMaxSteps.x = edgeTiles.Count * this.minMaxStepPercent.x; minMaxSteps.y = edgeTiles.Count * this.minMaxStepPercent.y; PathfindingAlgorithms.StepOutRegionEdge(edgeTiles, minMaxSteps, this.absoluteMinimumSteps); } //Making a list of each index for the number of total dungeons List <int> numDungeons = new List <int>(); for (int d = 0; d < TileMapManager.globalReference.dungeonTiles.Count; ++d) { numDungeons.Add(d); } //Creating a separate list to randomize the order of the dungeon indexes List <int> randDungeonOrder = new List <int>(); for (int c = 0; c < TileMapManager.globalReference.dungeonTiles.Count; ++c) { //Getting a random index from the numDungeons list int randIndex = Random.Range(0, TileMapManager.globalReference.dungeonTiles.Count); //Adding the dungeon index to our list of random dungeon orders randDungeonOrder.Add(numDungeons[randIndex]); } //Looping through each dungeon in our randomized order foreach (int index in randDungeonOrder) { //We get the tile reference for the given index's dungeon TileInfo dungeonTile = TileMapManager.globalReference.dungeonTiles[index]; //We find the list of tiles along the edge of the dungeon tile's region List <TileInfo> edgeTiles = PathfindingAlgorithms.FindRegionEdgeTiles(dungeonTile); //And then we have the region step outward based on the size of the region's boarders Vector2 minMaxSteps = new Vector2(); minMaxSteps.x = edgeTiles.Count * this.minMaxStepPercent.x; minMaxSteps.y = edgeTiles.Count * this.minMaxStepPercent.y; PathfindingAlgorithms.StepOutRegionEdge(edgeTiles, minMaxSteps, this.absoluteMinimumSteps); } }