/// <summary> /// Builds the A* map to be used for NPC pathfinding /// </summary> /// <param name="spriteTileReferences"></param> protected void InitializeAStarMap(TileReferences spriteTileReferences) { Debug.Assert(TheMap != null); Debug.Assert(TheMap.Length > 0); int nXTiles = TheMap[0].Length; int nYTiles = TheMap.Length; // load the A-Star compatible map into memory AStarNodes = Utils.Init2DList <Node>(nXTiles, nYTiles); for (int x = 0; x < nXTiles; x++) { for (int y = 0; y < nYTiles; y++) { TileReference currentTile = spriteTileReferences.GetTileReference(TheMap[x][y]); bool bIsWalkable = currentTile.IsWalking_Passable || currentTile.Index == spriteTileReferences.GetTileReferenceByName("RegularDoor").Index || currentTile.Index == spriteTileReferences .GetTileReferenceByName("RegularDoorView").Index || currentTile.Index == spriteTileReferences .GetTileReferenceByName("LockedDoor").Index || currentTile.Index == spriteTileReferences .GetTileReferenceByName("LockedDoorView").Index; float fWeight = GetAStarWeight(spriteTileReferences, new Point2D(x, y)); Node node = new Node(new System.Numerics.Vector2(x, y), bIsWalkable, fWeight); AStarNodes[x].Add(node); } } AStar = new AStar(AStarNodes); }
/// <summary> /// Calculates an appropriate A* weight based on the current tile as well as the surrounding tiles /// </summary> /// <param name="spriteTileReferences"></param> /// <param name="xy"></param> /// <returns></returns> protected override float GetAStarWeight(TileReferences spriteTileReferences, Point2D xy) { bool isPreferredIndex(int nSprite) { bool bIsPreferredIndex = nSprite == spriteTileReferences.GetTileReferenceByName("BrickFloor").Index || spriteTileReferences.IsPath(nSprite); return(bIsPreferredIndex); } const int fDefaultDeduction = 2; TileReference currentTile = spriteTileReferences.GetTileReference(TheMap[xy.X][xy.Y]); float fCost = 10; // we reduce the weight for the A* for each adjacent brick floor or path tile if (xy.X - 1 >= 0) { fCost -= isPreferredIndex(TheMap[xy.X - 1][xy.Y]) ? fDefaultDeduction : 0; } if (xy.X + 1 < XTILES) { fCost -= isPreferredIndex(TheMap[xy.X + 1][xy.Y]) ? fDefaultDeduction : 0; } if (xy.Y - 1 >= 0) { fCost -= isPreferredIndex(TheMap[xy.X][xy.Y - 1]) ? fDefaultDeduction : 0; } if (xy.Y + 1 < YTILES) { fCost -= isPreferredIndex(TheMap[xy.X][xy.Y + 1]) ? fDefaultDeduction : 0; } return(fCost); }