/// <summary> /// Gets minimap textures for a specified surface. The position is the centered location. The range is the number of chunks x/y away from center to get. /// </summary> /// <param name="surface"></param> /// <param name="position"></param> /// <param name="ranges"></param> public void GenerateMinimapTextures(SurfaceContainer surface, Vector2 position, int xRange, int yRange, List <VertexArray> vertexArrays) { int[] chunkIndices = SurfaceContainer.WorldToChunkCoords(position); vertexArrays.Clear(); for (int i = chunkIndices[0] - xRange; i <= chunkIndices[0] + xRange; i++) { for (int j = chunkIndices[1] - yRange; j <= chunkIndices[1] + yRange; j++) { Chunk chunk = surface.GetChunk((i * surface.worldSize) + j, false); if (chunk != null) { VertexArray vA; if (!minimapVertexArrays.TryGetValue(i * surface.worldSize + j, out vA)) { vA = tileCollection.GenerateTerrainMinimap(chunk, (i * surface.worldSize) + j, surface.worldSize); minimapVertexArrays.Add(i * surface.worldSize + j, vA); } vertexArrays.Add(vA); //next get entities //This is very dynamic so there is no point caching it List <Entity> entityList = chunk.entityList; VertexArray entityArray = new VertexArray(PrimitiveType.Triangles); int oX = i * Props.chunkSize; int oY = j * Props.chunkSize; for (int l = 0; l < entityList.Count; l++) { EntityPhysical e = entityList[l] as EntityPhysical; if (e == null) { continue; } int[] pos = surface.WorldToAbsoluteTileCoords(e.position.x, e.position.y); float halfWidth = e.tileWidth; float halfHeight = e.tileHeight; entityArray.Append(new Vertex(new Vector2f(pos[0] - halfWidth, pos[1] - halfHeight), e.mapColor)); entityArray.Append(new Vertex(new Vector2f(pos[0] + halfWidth, pos[1] - halfHeight), e.mapColor)); entityArray.Append(new Vertex(new Vector2f(pos[0] - halfWidth, pos[1] + halfHeight), e.mapColor)); entityArray.Append(new Vertex(new Vector2f(pos[0] + halfWidth, pos[1] - halfHeight), e.mapColor)); entityArray.Append(new Vertex(new Vector2f(pos[0] + halfWidth, pos[1] + halfHeight), e.mapColor)); entityArray.Append(new Vertex(new Vector2f(pos[0] - halfWidth, pos[1] + halfHeight), e.mapColor)); } if (entityArray.VertexCount > 0) { vertexArrays.Add(entityArray); } } } } }
public PathNode GetPath(SurfaceContainer surface, Vector2 start, Vector2 target, int pathTimeout, Base.CollisionLayer unwalkableMask, Base.CollisionLayer collisionMask, float frictionFactor) { this.frictionFactor = frictionFactor; int frictionMask = (int)(collisionMask & Base.CollisionLayer.Terrain); //a nonzero value means the pathcost is higher for lower frictions frictionMask = frictionMask / (1 + frictionMask); //Normalize the frictionmask to 0 or 1 using +1 trick int[] startCoords = surface.WorldToAbsoluteTileCoords(start.x, start.y); int[] endCoords = surface.WorldToAbsoluteTileCoords(target.x, target.y); float heuristic = CalculateHeuristic(startCoords, endCoords); PathNode startNode = new PathNode(null, 0, 0, heuristic, startCoords); List <PathNode> openList = new List <PathNode>(); List <PathNode> closedList = new List <PathNode>(); PathNode endNode = null; openList.Add(startNode); while (openList.Count > 0 && pathTimeout > 0) { pathTimeout--; PathNode curNode = null; int removeIndex = 0; for (int i = 0; i < openList.Count; i++) { if (curNode == null || openList[i].cost < curNode.cost) { removeIndex = i; curNode = openList[i]; } } openList.RemoveAt(removeIndex); closedList.Add(curNode); if (pathTimeout == 0 || (curNode.coords[0] == endCoords[0] && curNode.coords[1] == endCoords[1])) { endNode = curNode; break; } for (int i = curNode.coords[0] - 1; i <= curNode.coords[0] + 1; i++) { for (int j = curNode.coords[1] - 1; j <= curNode.coords[1] + 1; j++) { bool ignore = false; if (i < 0 || j < 0) //Check if coords are outside worldSize { ignore = true; } if (ignore == false) //else check that coords are not already in closedList { for (int k = 0; k < closedList.Count; k++) { if (closedList[k].coords[0] == i && closedList[k].coords[1] == j) { ignore = true; break; } } } if (ignore == false) //else check that coords are not already in openList { for (int k = 0; k < openList.Count; k++) { if (openList[k].coords[0] == i && openList[k].coords[1] == j) { ignore = true; break; } } } if (!ignore) //if neither of the preceding conditiosn set ignore to false, add tile to open list on path search { Tile tile = tileCollection.GetTerrainTile(surface.GetTileFromWorldInt(i, j)); int solidMask = (int)((unwalkableMask & collisionMask) & tile.collisionMask); // a zero value when the tile is walkable if (solidMask == 0) { int[] coords = new int[] { i, j }; PathNode newNode = new PathNode(curNode, frictionMask * (frictionFactor * (1 / tile.frictionModifier)), curNode.begin + 1, CalculateHeuristic(coords, endCoords), coords); openList.Add(newNode); } } } } } return(endNode); }