//private void SmoothBlur(int iterations) { // float[,] newValues = new float[width, height]; // for (int i = 0; i < iterations; i += 1) { // for (int x = 0; x < width; x += 1) { // for (int y = 0; y < height; y += 1) { // RMTile tile = GetTile(x, y); // float sum = 0; // float count = 0; // for (int xx = x - 1; xx < x + 2; xx += 1) { // int ix = Mathf.Clamp(xx, 0, width - 1); // for (int yy = y - 1; yy < y + 2; yy += 1) { // if (xx == x && yy == y) continue; // int iy = Mathf.Clamp(yy, 0, width - 1); // RMTile nt = GetTile(ix, iy); // sum += nt.h; // count += 1; // } // } // newValues[x, y] = sum / count; // } // } // } // for (int x = 0; x < width; x += 1) { // for (int y = 0; y < height; y += 1) { // tiles[x, y].h = newValues[x, y]; // } // } //} private void SmoothMap(int iterations, int threshhold) { for (int i = 0; i < iterations; i += 1) { for (int x = 0; x < width; x += 1) { for (int y = 0; y < height; y += 1) { RMTile tile = GetTile(x, y); if (tile.markedAs != TYPE.ROAD && tile.markedAs != TYPE.BUILDING) { Dictionary <int, int> dct = Neighbours(x, y, tile.h); var sorted = from entry in dct orderby entry.Value descending select entry; foreach (var t in sorted) { if (t.Value > threshhold) { tile.h = t.Key; break; } } } } } } }
public void SetNeighbours() { neighbours.Clear(); RMTile t = map.GetTile(x - 1, y); if (t != null) { neighbours.Add(t, t.GetMovementFactor()); } t = map.GetTile(x + 1, y); if (t != null) { neighbours.Add(t, t.GetMovementFactor()); } t = map.GetTile(x, y - 1); if (t != null) { neighbours.Add(t, t.GetMovementFactor()); } t = map.GetTile(x, y + 1); if (t != null) { neighbours.Add(t, t.GetMovementFactor()); } }
public RMGPath(RoadMapGen map, RMTile start, RMTile end) { this.map = map; this.width = map.width; this.height = map.height; nodes = new RMGNode[width, height]; for (int x = 0; x < width; x += 1) { for (int y = 0; y < height; y += 1) { nodes[x, y] = new RMGNode(map, x, y); } } for (int x = 0; x < width; x += 1) { for (int y = 0; y < height; y += 1) { RMGNode n = nodes[x, y]; n.neighbours[0] = getNode(x - 1, y); n.neighbours[1] = getNode(x + 1, y); n.neighbours[2] = getNode(x, y - 1); n.neighbours[3] = getNode(x, y + 1); } } this.start = getNode(start.x, start.y); this.end = getNode(end.x, end.y); //Debug.Log("end = " + end); }
public RMGNode(RoadMapGen map, int x, int y) { this.x = x; this.y = y; this.tile = map.GetTile(x, y); moveFactor = tile.GetMovementFactor(); }
Tuple <int, int, int> GetTuple(int x, int y) { if (OOB(x, y)) { return(null); } RMTile tile = GetTile(x, y); return(MT(tile.x, tile.y, tile.d)); }
void ProcBuildings() { foreach (RMGBuilding b in buildings) { for (int xx = b.tlx; xx <= b.brx; xx += 1) { for (int yy = b.tly; yy <= b.bry; yy += 1) { b.tiles.Add(GetTile(xx, yy)); } } for (int xx = b.tlx + 1; xx < b.brx; xx += 1) { for (int yy = b.tly + 1; yy < b.bry; yy += 1) { RMTile t = GetTile(xx, yy); if (t != null) { t.btype = BUILDING_TYPE.INSIDE; } else { Debug.LogError(b + " is invalid"); } } } } for (int i = buildings.Count - 1; i >= 0; i -= 1) { RMGBuilding A = buildings[i]; for (int j = buildings.Count - 1; j >= 0; j -= 1) { if (i == j) { continue; } RMGBuilding B = buildings[j]; if (A.yDir != 0 && B.yDir != 0) { RemoveEastWestWalls(A, B); } else if (A.xDir != 0 && B.xDir != 0) { RemoveNorthSouthWalls(A, B); } } } }
private void SaveToPng() { Texture2D tex = new Texture2D(width * 4, height * 4, TextureFormat.ARGB32, false); for (int x = 0; x < width; x += 1) { for (int y = 0; y < height; y += 1) { RMTile t = GetTile(x, y); Color c = Color.white; switch (t.showsAs) { case TYPE.GROUND: float v = (((float)t.h) / ((float)numGroundTileTypes)); c = new Color(v, v, v); break; case TYPE.ROAD: c = Color.gray; break; case TYPE.BUILDING: c = Color.red; break; case TYPE.WATER: c = Color.blue; break; default: break; } for (int xx = x * 4; xx < (x * 4) + 4; xx += 1) { for (int yy = y * 4; yy < (y * 4) + 4; yy += 1) { tex.SetPixel(xx, yy, c); } } } } tex.Apply(); SaveTexToPng("map", tex); }
public bool IsObstacle(int x, int y) { if (OOB(x, y)) { return(true); } RMTile tile = GetTile(x, y); if (tile.markedAs == TYPE.BUILDING) { return(true); } return(false); }
private void RemoveEastWestWalls(RMGBuilding A, RMGBuilding B) { bool isWestNeighbour = false; bool isEastNeighbour = false; for (int y = A.tly + 1; y < A.bry; y += 1) { RMTile west = GetTile(A.tlx - 1, y); RMTile east = GetTile(A.brx + 1, y); if (west != null) { if (B.tiles.Contains(west)) { isWestNeighbour = true; break; } } if (east != null) { if (B.tiles.Contains(east)) { isEastNeighbour = true; break; } } } if (isWestNeighbour || isEastNeighbour) { RMGBuilding removeWestWall = null; RMGBuilding removeEastWall = null; if (A.area < B.area) { if (isWestNeighbour) { removeWestWall = A; } else { removeEastWall = A; } } else if (A.area >= B.area) { if (isWestNeighbour) { removeEastWall = B; } else { removeWestWall = B; } } List <RMTile> toRemove = new List <RMTile>(); if (removeWestWall != null) { for (int y = removeWestWall.tly + 1; y < removeWestWall.bry; y += 1) { RMTile t = GetTile(removeWestWall.tlx, y); int countWalls = 0; for (int xx = removeWestWall.tlx - 1; xx <= removeWestWall.tlx; xx += 1) { for (int yy = y - 1; yy <= y + 1; yy += 1) { if (xx == removeWestWall.tlx && yy == y) { continue; } if (t.btype == BUILDING_TYPE.EDGE) { countWalls += 1; } } } if (countWalls >= 5) { toRemove.Add(t); } } } if (removeEastWall != null) { for (int y = removeEastWall.tly + 1; y < removeEastWall.bry; y += 1) { RMTile t = GetTile(removeEastWall.brx, y); int countWalls = 0; for (int xx = removeEastWall.tlx; xx <= removeEastWall.tlx + 1; xx += 1) { for (int yy = y - 1; yy <= y + 1; yy += 1) { if (xx == removeEastWall.tlx && yy == y) { continue; } if (t.btype == BUILDING_TYPE.EDGE) { countWalls += 1; } } } if (countWalls >= 5) { toRemove.Add(t); } } } foreach (var t in toRemove) { t.btype = BUILDING_TYPE.INSIDE; } } }
private void RemoveNorthSouthWalls(RMGBuilding A, RMGBuilding B) { bool isNorthNeighbour = false; bool isSouthNeighbour = false; for (int x = A.tlx + 1; x < A.brx; x += 1) { RMTile north = GetTile(x, A.tly - 1); RMTile east = GetTile(x, A.bry + 1); if (north != null) { if (B.tiles.Contains(north)) { isNorthNeighbour = true; break; } } if (east != null) { if (B.tiles.Contains(east)) { isSouthNeighbour = true; break; } } } if (isNorthNeighbour || isSouthNeighbour) { RMGBuilding removeNorthWall = null; RMGBuilding removeSouthWall = null; if (A.area < B.area) { if (isNorthNeighbour) { removeNorthWall = A; } else { removeSouthWall = A; } } else if (A.area >= B.area) { if (isNorthNeighbour) { removeSouthWall = B; } else { removeNorthWall = B; } } if (removeNorthWall != null) { for (int x = removeNorthWall.tlx + 1; x < removeNorthWall.brx; x += 1) { RMTile t = GetTile(x, removeNorthWall.tly); t.btype = BUILDING_TYPE.INSIDE; } } if (removeSouthWall != null) { for (int x = removeSouthWall.tlx + 1; x < removeSouthWall.brx; x += 1) { RMTile t = GetTile(x, removeSouthWall.bry); t.btype = BUILDING_TYPE.INSIDE; } } } }
private void MakeRoads() { for (int x = 0; x < width; x += RoadMapGen.BLOCK_WIDTH) { bool goY = true; for (int y = 0; y < height; y += 1) { if (y % RoadMapGen.BLOCK_WIDTH == 1) { if (Chance(ROAD_Y_CHANCE)) { goY = Chance(ROAD_Y_ON_CHANCE); } } if (goY) { RMTile t = GetTile(x, y); if (XChance(x)) { t.showsAs = TYPE.ROAD; } t.markedAs = TYPE.ROAD; t = GetTile(x + 1, y); if (t != null) { t.markedAs = TYPE.ROAD; if (XChance(x)) { t.showsAs = TYPE.ROAD; } } } } } for (int y = 0; y < width; y += BLOCK_WIDTH) { bool goX = true; for (int x = 0; x < width; x += 1) { float c1 = 1 - ((float)(width - x) / (float)(width)); if (x % BLOCK_WIDTH == 1) { if (Chance(ROAD_X_CHANCE)) { goX = XChance(x); } } if (goX) { RMTile t = GetTile(x, y); t.markedAs = TYPE.ROAD; if (XChance(x)) { t.showsAs = TYPE.ROAD; } t = GetTile(x, y + 1); if (t != null) { t.markedAs = TYPE.ROAD; if (XChance(x)) { t.showsAs = TYPE.ROAD; } } } } } }
private bool MakeWave(int startX, int startY, int endX, int endY, int newH) { RMTile start = GetTile(startX, startY); RMTile end = GetTile(endX, endY); if (IsObstacle(startX, startY) || IsObstacle(endX, endY)) { return(false); } List <Tuple <int, int, int> > nodes = new List <Tuple <int, int, int> >(); nodes.Add(MT(endX, endY, 1)); while (nodes.Count > 0) { List <Tuple <int, int, int> > newNodes = new List <Tuple <int, int, int> >(); foreach (var node in nodes) { int x = node.Item1; int y = node.Item2; int d = node.Item3; GetTile(x, y).d = d; //check east if (!OOB(x + 1, y) && GetTile(x + 1, y).d == 0) { newNodes.Add(MT(x + 1, y, d + 1)); } //check west if (!OOB(x - 1, y) && GetTile(x - 1, y).d == 0) { newNodes.Add(MT(x - 1, y, d + 1)); } //check north if (!OOB(x, y - 1) && GetTile(x, y - 1).d == 0) { newNodes.Add(MT(x, y - 1, d + 1)); } //check south if (!OOB(x, y + 1) && GetTile(x, y + 1).d == 0) { newNodes.Add(MT(x, y + 1, d + 1)); } } newNodes.Sort((e1, e2) => p(e1.Item1, e1.Item2).CompareTo(p(e1.Item1, e2.Item2))); newNodes = newNodes.GroupBy(e => p(e.Item1, e.Item2)).Select(e => e.First()).ToList(); nodes.Clear(); nodes.AddRange(newNodes); } List <RMTile> tilesToUpdate = new List <RMTile>(); int maxD = 0; for (int x = 0; x < width; x += 1) { for (int y = 0; y < height; y += 1) { RMTile t = tiles[x, y]; if (t.d > maxD) { maxD = t.d; } } } for (int x = 0; x < width; x += 1) { for (int y = 0; y < height; y += 1) { RMTile t = tiles[x, y]; t.fd = (float)t.d / (float)maxD; } } tilesToUpdate.Add(start); int max = UnityEngine.Random.Range(1, maxD); for (int x = 0; x < width; x += 1) { for (int y = 0; y < height; y += 1) { RMTile t = tiles[x, y]; float c = (float)t.d / (float)max; if (Chance(c / 2.0f)) { if (t.markedAs != TYPE.BUILDING && t.showsAs != TYPE.ROAD) { if (t.d <= max) { tilesToUpdate.Add(t); } } } } } foreach (RMTile t in tilesToUpdate) { t.h = newH; } return(true); }
void SearchForBuildingsX(int x, int xDir) { MODE mode = MODE.SEARCH; for (int y = 0; y < width; y += 1) { RMTile t = GetTile(x, y); RMTile above = GetTile(x - xDir, y); if (t == null) { continue; } if (above == null || above.markedAs != TYPE.ROAD) { continue; } if (t.showsAs == TYPE.BUILDING) { continue; } if (t.markedAs == TYPE.GROUND) { if (mode == MODE.SEARCH) //can begin { if (XChance(x)) { mode = MODE.PLACE; } else { mode = MODE.DONTPLACE; } } } else if (t.markedAs == TYPE.ROAD) { if (mode == MODE.PLACE || mode == MODE.DONTPLACE) { mode = MODE.SEARCH; } } if (mode == MODE.PLACE) { int w = BUILDING_SIZE_MIN * xDir; int h = BUILDING_SIZE_MIN; int tlx = int.MaxValue, tly = int.MaxValue, brx = int.MinValue, bry = int.MinValue; bool valid = false; while (true) { bool doesItFit = true; for (int yy = y; yy < y + h; yy += 1) { for (int xx = x; ; xx += xDir) { if (xDir > 0) { if (xx >= x + w) { break; } } else if (xDir < 0) { if (xx <= x + w) { break; } } RMTile tt = GetTile(xx, yy); if (tt == null || tt.markedAs == TYPE.ROAD) { doesItFit = false; } } if (!doesItFit) { break; } } if (doesItFit) { for (int yy = y; yy < y + h; yy += 1) { for (int xx = x; ; xx += xDir) { if (xDir > 0) { if (xx >= x + w) { break; } } else if (xDir < 0) { if (xx <= x + w) { break; } } RMTile tt = GetTile(xx, yy); tt.showsAs = TYPE.BUILDING; tt.markedAs = TYPE.BUILDING; if (xx < tlx) { tlx = xx; } if (xx > brx) { brx = xx; } if (yy < tly) { tly = yy; } if (yy > bry) { bry = yy; } valid = true; } } w += (Chance(0.4f)) ? 1 * xDir : 0; h += (Chance(0.4f)) ? 1 : 0; if (Math.Abs(w) > BUILDING_SIZE_MAX || Math.Abs(h) > BUILDING_SIZE_MAX) { break; } if (Chance(0.1f)) { break; } } else { break; } } if (valid) { for (int xx = tlx; xx <= brx; xx += 1) { RMTile tle = GetTile(xx, tly); tle.btype = BUILDING_TYPE.EDGE; tle = GetTile(xx, bry); tle.btype = BUILDING_TYPE.EDGE; } for (int yy = tly; yy <= bry; yy += 1) { RMTile tle = GetTile(tlx, yy); tle.btype = BUILDING_TYPE.EDGE; tle = GetTile(brx, yy); tle.btype = BUILDING_TYPE.EDGE; } buildings.Add(new RMGBuilding(tlx, tly, brx, bry, xDir, 0)); } y += h - 1; } } }