private bool HasEdge(int x, int y, Direction dir) { Room.Tile tile = room.GetTile(x, y); Room.Tile.TerrainType terrain = tile.Terrain; Room.SlopeDirection slope = (terrain == Room.Tile.TerrainType.Slope) ? room.IdentifySlope(x, y) : Room.SlopeDirection.Broken; if (terrain == Room.Tile.TerrainType.Solid) { return(true); } if (terrain == Room.Tile.TerrainType.Air || terrain == Room.Tile.TerrainType.ShortcutEntrance || terrain == Room.Tile.TerrainType.Floor) { return(false); } switch (dir) { case Direction.Up: return(slope == Room.SlopeDirection.DownRight || slope == Room.SlopeDirection.DownLeft); case Direction.Right: return(slope == Room.SlopeDirection.UpLeft || slope == Room.SlopeDirection.DownLeft); case Direction.Down: return(slope == Room.SlopeDirection.UpRight || slope == Room.SlopeDirection.UpLeft); case Direction.Left: return(slope == Room.SlopeDirection.DownRight || slope == Room.SlopeDirection.UpRight); } return(false); }
public bool PointInSolid(int x, int y) { Room.Tile tile = Room.realizedRoom.GetTile(new Vector2(x, y)); int lx = x - tile.X * 20; int ly = y - tile.Y * 20; switch (tile.Terrain) { case global::Room.Tile.TerrainType.Solid: return(true); case global::Room.Tile.TerrainType.Air: return(false); case global::Room.Tile.TerrainType.Floor: return(ly > 10); case global::Room.Tile.TerrainType.ShortcutEntrance: return(true); case global::Room.Tile.TerrainType.Slope: switch (Room.realizedRoom.IdentifySlope(tile.X, tile.Y)) { case global::Room.SlopeDirection.Broken: return(true); case global::Room.SlopeDirection.DownRight: return(ly > lx); case global::Room.SlopeDirection.UpLeft: return(ly < lx); case global::Room.SlopeDirection.UpRight: return(ly < 20 - lx); case global::Room.SlopeDirection.DownLeft: return(ly > 20 - lx); } break; } return(false); }
public void UpdateMapper(int iterations) { Room.Tile[,] tiles = _tiles; for (int i = 0; i < iterations; i++) { switch (state) { case MappingState.FindingEdges: { Room.Tile tile = tiles[_x, _y]; Room.Tile.TerrainType terrain = tile.Terrain; Room.SlopeDirection slope = (terrain == Room.Tile.TerrainType.Slope) ? room.IdentifySlope(_x, _y) : Room.SlopeDirection.Broken; if (HasEdge(_x, _y, Direction.Left) && !HasEdge(_x - 1, _y, Direction.Right)) { AddEdge(_x, _y, Direction.Left); } if (HasEdge(_x, _y, Direction.Down) && !HasEdge(_x, _y - 1, Direction.Up)) { AddEdge(_x, _y, Direction.Down); } if (HasEdge(_x, _y, Direction.Right) && !HasEdge(_x + 1, _y, Direction.Left)) { AddEdge(_x, _y, Direction.Right); } if (HasEdge(_x, _y, Direction.Up) && !HasEdge(_x, _y + 1, Direction.Down)) { AddEdge(_x, _y, Direction.Up); } if (slope != Room.SlopeDirection.Broken) { AddSlopeEdge(_x, _y, slope); } _x++; if (_x >= room.TileWidth) { _x = 0; _y++; if (_y >= room.TileHeight) { _y = corners.Count; state = MappingState.DuplicatingPoints; } } } break; case MappingState.DuplicatingPoints: { corners.Add(corners[_x]); _x++; if (_x >= _y) { state = MappingState.Done; _x = 0; _y = 0; } } break; case MappingState.Done: return; } } }
public void ApplyTerrain(bool finalize = true) { if (!affectTerrain) { return; } Room rroom = Room.realizedRoom; if (rroom == null) { return; } // No culling should happen int seed = Random.seed; Random.seed = ID.number; IntVector2 mins = rroom.GetTilePosition(realPos - new Vector2(rad, rad)); IntVector2 maxs = rroom.GetTilePosition(realPos + new Vector2(rad, rad)); // Erode terrain for (int tx = mins.x; tx <= maxs.x; tx++) { for (int ty = mins.y; ty <= maxs.y; ty++) { Room.Tile tile = rroom.GetTile(tx, ty); float dist = Vector2.Distance(rroom.MiddleOfTile(tile.X, tile.Y), realPos); //bool hasNearbyShortcut = false; //for(int ox = -1; ox <= 1; ox++) //{ // for(int oy = -1; oy <= 1; oy++) // { // if(rroom.GetTile(tx + ox, ty + oy).Terrain == global::Room.Tile.TerrainType.ShortcutEntrance) // { // hasNearbyShortcut = true; // break; // } // } //} //if (hasNearbyShortcut) continue; if (dist < rad * 0.85f - Random.value * 30f) { if (tile.Terrain == global::Room.Tile.TerrainType.ShortcutEntrance) { shortcutsModified = true; int ind = System.Array.IndexOf(rroom.shortcutsIndex, new IntVector2(tile.X, tile.Y)); rroom.shortcuts[ind].shortCutType = ShortcutData.Type.DeadEnd; foreach (UpdatableAndDeletable obj in rroom.updateList) { if (obj is ShortcutHelper sh) { for (int i = sh.pushers.Count - 1; i >= 0; i--) { ShortcutHelper.ShortcutPusher sp = sh.pushers[i]; if (sp.shortCutPos.x == tile.X && sp.shortCutPos.y == tile.Y) { sh.pushers.RemoveAt(i); } } } } } if (dist < rad * 0.7f - Random.value * 15f) { tile.wallbehind = false; } tile.Terrain = global::Room.Tile.TerrainType.Air; tile.horizontalBeam = false; tile.verticalBeam = false; if (tile.shortCut != 0) { shortcutsModified = true; tile.shortCut = 0; } } } } // Convert all slopable blocks into slopes, with some random chance for (int tx = mins.x - 1; tx <= maxs.x + 1; tx++) { for (int ty = mins.y - 1; ty <= maxs.y + 1; ty++) { Room.Tile tile = rroom.GetTile(tx, ty); float dist = Vector2.Distance(rroom.MiddleOfTile(tile.X, tile.Y), realPos); //bool hasNearbyShortcut = false; //for(int i = 0; i < 4; i++) //{ // if(rroom.GetTile(tx + Custom.fourDirections[i].x, ty + Custom.fourDirections[i].y).Terrain == global::Room.Tile.TerrainType.ShortcutEntrance) // { // hasNearbyShortcut = true; // break; // } //} //if (hasNearbyShortcut) continue; if (dist < rad * 0.85f + 20f) { if (tile.Terrain == global::Room.Tile.TerrainType.Solid) { if (IsSlopeValid(tx, ty) && (Random.value < 0.65f)) { tile.Terrain = global::Room.Tile.TerrainType.Slope; } } } } } // One last pass to remove any broken slopes for (int tx = mins.x - 1; tx <= maxs.x + 1; tx++) { for (int ty = mins.y - 1; ty <= maxs.y + 1; ty++) { Room.Tile tile = rroom.GetTile(tx, ty); if (tile.Terrain == global::Room.Tile.TerrainType.Slope && rroom.IdentifySlope(tx, ty) == global::Room.SlopeDirection.Broken) { tile.Terrain = global::Room.Tile.TerrainType.Air; } } } Random.seed = seed; if (finalize) { FinalizeTerrainDestruction(rroom); } }