diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/tiles/DungeonTerrainTilemap.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/tiles/DungeonTerrainTilemap.java index c09187392..7b2ca4501 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/tiles/DungeonTerrainTilemap.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/tiles/DungeonTerrainTilemap.java @@ -56,7 +56,7 @@ public class DungeonTerrainTilemap extends DungeonTilemap { } if (!flat) { - if ((DungeonTileSheet.doorTiles.contains(tile))) { + if ((DungeonTileSheet.doorTile(tile))) { return DungeonTileSheet.getRaisedDoorTile(tile, map[pos - mapWidth]); } else if (tile == Terrain.WALL || tile == Terrain.WALL_DECO || tile == Terrain.SECRET_DOOR || tile == Terrain.BOOKSHELF){ @@ -97,8 +97,8 @@ public class DungeonTerrainTilemap extends DungeonTilemap { return data[pos] != DungeonTileSheet.WATER || ( pos + mapWidth < size && - DungeonTileSheet.wallStitcheable.contains(map[pos]) && - DungeonTileSheet.wallStitcheable.contains(map[pos + mapWidth]) + DungeonTileSheet.wallStitcheable(map[pos]) && + DungeonTileSheet.wallStitcheable(map[pos + mapWidth]) ); } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/tiles/DungeonTileSheet.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/tiles/DungeonTileSheet.java index 9acd754e3..f4a1daeab 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/tiles/DungeonTileSheet.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/tiles/DungeonTileSheet.java @@ -191,15 +191,25 @@ public class DungeonTileSheet { public static final int RAISED_WALL_DECO_ALT = RAISED_WALLS+20; public static final int RAISED_WALL_BOOKSHELF_ALT = RAISED_WALLS+28; + //we use an array instead of a collection because the small element count + // makes array traversal much faster than something like HashSet.contains. + //These tiles count as wall for the purposes of wall stitching - public static HashSet wallStitcheable = new HashSet<>(Arrays.asList( + private static int[] wallStitcheable = new int[]{ Terrain.WALL, Terrain.WALL_DECO, Terrain.SECRET_DOOR, Terrain.LOCKED_EXIT, Terrain.UNLOCKED_EXIT, Terrain.BOOKSHELF, NULL_TILE - )); + }; + + public static boolean wallStitcheable(int tile){ + for (int i : wallStitcheable) + if (tile == i) + return true; + return false; + } public static int getRaisedWallTile(int tile, int pos, int right, int below, int left){ int result; - if (doorTiles.contains(below)) result = RAISED_WALL_DOOR; + if (doorTile(below)) result = RAISED_WALL_DOOR; else if (tile == Terrain.WALL || tile == Terrain.SECRET_DOOR) result = RAISED_WALL; else if (tile == Terrain.WALL_DECO) result = RAISED_WALL_DECO; else if (tile == Terrain.BOOKSHELF) result = RAISED_WALL_BOOKSHELF; @@ -207,8 +217,8 @@ public class DungeonTileSheet { result = getVisualWithAlts(result, pos); - if (!wallStitcheable.contains(right)) result += 1; - if (!wallStitcheable.contains(left)) result += 2; + if (!wallStitcheable(right)) result += 1; + if (!wallStitcheable(left)) result += 2; return result; } @@ -221,16 +231,23 @@ public class DungeonTileSheet { public static int getRaisedDoorTile(int tile, int below){ - if (wallStitcheable.contains(below)) return RAISED_DOOR_SIDEWAYS; + if (wallStitcheable(below)) return RAISED_DOOR_SIDEWAYS; else if (tile == Terrain.DOOR) return DungeonTileSheet.RAISED_DOOR; else if (tile == Terrain.OPEN_DOOR) return DungeonTileSheet.RAISED_DOOR_OPEN; else if (tile == Terrain.LOCKED_DOOR) return DungeonTileSheet.RAISED_DOOR_LOCKED; else return -1; } - public static HashSet doorTiles = new HashSet<>(Arrays.asList( + private static int[] doorTiles = new int[]{ Terrain.DOOR, Terrain.LOCKED_DOOR, Terrain.OPEN_DOOR - )); + }; + + public static boolean doorTile(int tile){ + for (int i : doorTiles) + if (tile == i) + return true; + return false; + } private static final int RAISED_OTHER = xy(1, 11); //16 slots public static final int RAISED_SIGN = RAISED_OTHER+0; @@ -255,10 +272,10 @@ public class DungeonTileSheet { if (tile == Terrain.BOOKSHELF) result = WALL_INTERNAL_WOODEN; else result = WALL_INTERNAL; - if (!wallStitcheable.contains(right)) result += 1; - if (!wallStitcheable.contains(rightBelow)) result += 2; - if (!wallStitcheable.contains(leftBelow)) result += 4; - if (!wallStitcheable.contains(left)) result += 8; + if (!wallStitcheable(right)) result += 1; + if (!wallStitcheable(rightBelow)) result += 2; + if (!wallStitcheable(leftBelow)) result += 4; + if (!wallStitcheable(left)) result += 8; return result; } @@ -278,8 +295,8 @@ public class DungeonTileSheet { else if (below == Terrain.BOOKSHELF) visual = WALL_OVERHANG_WOODEN; else visual = WALL_OVERHANG; - if (!wallStitcheable.contains(rightBelow)) visual += 1; - if (!wallStitcheable.contains(leftBelow)) visual += 2; + if (!wallStitcheable(rightBelow)) visual += 1; + if (!wallStitcheable(leftBelow)) visual += 2; return visual; } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/tiles/DungeonTilemap.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/tiles/DungeonTilemap.java index 48c91cbd3..ae5822124 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/tiles/DungeonTilemap.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/tiles/DungeonTilemap.java @@ -92,11 +92,11 @@ public abstract class DungeonTilemap extends Tilemap { if (wallAssist && map != null - && DungeonTileSheet.wallStitcheable.contains(map[cell])){ + && DungeonTileSheet.wallStitcheable(map[cell])){ if (cell + mapWidth < size && p.y % 1 >= 0.75f - && !DungeonTileSheet.wallStitcheable.contains(map[cell + mapWidth])){ + && !DungeonTileSheet.wallStitcheable(map[cell + mapWidth])){ cell += mapWidth; } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/tiles/DungeonWallsTilemap.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/tiles/DungeonWallsTilemap.java index c3f1cbcdb..7b8ba71e2 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/tiles/DungeonWallsTilemap.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/tiles/DungeonWallsTilemap.java @@ -43,8 +43,8 @@ public class DungeonWallsTilemap extends DungeonTilemap { if (flat) return -1; - if (DungeonTileSheet.wallStitcheable.contains(tile)) { - if (pos + mapWidth < size && !DungeonTileSheet.wallStitcheable.contains(map[pos + mapWidth])){ + if (DungeonTileSheet.wallStitcheable(tile)) { + if (pos + mapWidth < size && !DungeonTileSheet.wallStitcheable(map[pos + mapWidth])){ if (map[pos + mapWidth] == Terrain.DOOR){ return DungeonTileSheet.DOOR_SIDEWAYS; @@ -66,7 +66,7 @@ public class DungeonWallsTilemap extends DungeonTilemap { } - if (pos + mapWidth < size && DungeonTileSheet.wallStitcheable.contains(map[pos+mapWidth])) { + if (pos + mapWidth < size && DungeonTileSheet.wallStitcheable(map[pos+mapWidth])) { return DungeonTileSheet.stitchWallOverhangTile( tile, diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/tiles/FogOfWar.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/tiles/FogOfWar.java index 5c80cb2d6..928dc5915 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/tiles/FogOfWar.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/tiles/FogOfWar.java @@ -163,15 +163,15 @@ public class FogOfWar extends Image { } //triggers on wall tiles or sideways doors - if (DungeonTileSheet.wallStitcheable.contains(Dungeon.level.map[cell]) || - ( DungeonTileSheet.doorTiles.contains(Dungeon.level.map[cell]) + if (DungeonTileSheet.wallStitcheable(Dungeon.level.map[cell]) || + ( DungeonTileSheet.doorTile(Dungeon.level.map[cell]) && cell + mapWidth < mapLength - && DungeonTileSheet.wallStitcheable.contains(Dungeon.level.map[cell + mapWidth]))) { + && DungeonTileSheet.wallStitcheable(Dungeon.level.map[cell + mapWidth]))) { cellIndex = getColorIndexForCell(cell); if (cell + mapWidth < mapLength){ - if (!DungeonTileSheet.wallStitcheable.contains(Dungeon.level.map[cell + mapWidth]) - && !DungeonTileSheet.doorTiles.contains(Dungeon.level.map[cell + mapWidth])){ + if (!DungeonTileSheet.wallStitcheable(Dungeon.level.map[cell + mapWidth]) + && !DungeonTileSheet.doorTile(Dungeon.level.map[cell + mapWidth])){ if (getColorIndexForCell(cell + mapWidth) > cellIndex) cellIndex = getColorIndexForCell(cell + mapWidth); fillCell(j, i, FOG_COLORS[cellIndex][brightness]); @@ -180,8 +180,8 @@ public class FogOfWar extends Image { } if (cell % mapWidth != 0){ - if (DungeonTileSheet.wallStitcheable.contains(Dungeon.level.map[cell - 1]) - || DungeonTileSheet.doorTiles.contains(Dungeon.level.map[cell - 1])){ + if (DungeonTileSheet.wallStitcheable(Dungeon.level.map[cell - 1]) + || DungeonTileSheet.doorTile(Dungeon.level.map[cell - 1])){ if (getColorIndexForCell(cell - 1 + mapWidth) > cellIndex) colorArray[0] = colorArray[2] = FOG_COLORS[getColorIndexForCell(cell - 1 + mapWidth)][brightness]; else @@ -197,8 +197,8 @@ public class FogOfWar extends Image { } if ((cell+1) % mapWidth != 0){ - if (DungeonTileSheet.wallStitcheable.contains(Dungeon.level.map[cell + 1]) - || DungeonTileSheet.doorTiles.contains(Dungeon.level.map[cell + 1])){ + if (DungeonTileSheet.wallStitcheable(Dungeon.level.map[cell + 1]) + || DungeonTileSheet.doorTile(Dungeon.level.map[cell + 1])){ if (getColorIndexForCell(cell + 1 + mapWidth) > cellIndex) colorArray[1] = colorArray[3] = FOG_COLORS[getColorIndexForCell(cell + 1 + mapWidth)][brightness]; else @@ -228,7 +228,7 @@ public class FogOfWar extends Image { } fillCell(j, i, colorArray); - } else if (DungeonTileSheet.doorTiles.contains(Dungeon.level.map[cell])) { + } else if (DungeonTileSheet.doorTile(Dungeon.level.map[cell])) { colorArray[0] = colorArray[1] = FOG_COLORS[getColorIndexForCell(cell)][brightness]; colorArray[2] = colorArray[3] = FOG_COLORS[getColorIndexForCell(cell + mapWidth)][brightness]; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/tiles/GridTileMap.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/tiles/GridTileMap.java index 6a91732a1..7a595b09a 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/tiles/GridTileMap.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/tiles/GridTileMap.java @@ -26,8 +26,8 @@ public class GridTileMap extends DungeonTilemap { return -1; } else if (DungeonTileSheet.floorTile(tile)) { return gridSetting; - } else if (DungeonTileSheet.doorTiles.contains(tile)){ - if (DungeonTileSheet.wallStitcheable.contains(map[pos - mapWidth])){ + } else if (DungeonTileSheet.doorTile(tile)){ + if (DungeonTileSheet.wallStitcheable(map[pos - mapWidth])){ return 12 + gridSetting; } else if ( tile == Terrain.OPEN_DOOR){ return 8 + gridSetting; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/tiles/WallBlockingTilemap.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/tiles/WallBlockingTilemap.java index e1779fdb3..6590e0a6b 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/tiles/WallBlockingTilemap.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/tiles/WallBlockingTilemap.java @@ -21,6 +21,7 @@ package com.shatteredpixel.shatteredpixeldungeon.tiles; import com.shatteredpixel.shatteredpixeldungeon.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.levels.Level; import com.watabou.noosa.TextureFilm; import com.watabou.noosa.Tilemap; @@ -29,6 +30,7 @@ public class WallBlockingTilemap extends Tilemap { public static final int SIZE = 16; + private static final int CLEARED = -1; private static final int BLOCK_NONE = 0; private static final int BLOCK_RIGHT = 1; private static final int BLOCK_LEFT = 2; @@ -42,6 +44,7 @@ public class WallBlockingTilemap extends Tilemap { @Override public synchronized void updateMap() { super.updateMap(); + data = new int[size]; //clears all values, including cleared tiles for (int i = 0; i < data.length; i++) updateMapCell(i); } @@ -51,78 +54,76 @@ public class WallBlockingTilemap extends Tilemap { int prev = data[cell]; int curr; - //no point in blocking tiles that are already obscured by fog - if (fogHidden(cell) && fogHidden(cell - mapWidth) && fogHidden(cell + mapWidth)){ - curr = BLOCK_NONE; + if (prev == CLEARED){ + return; - } else if (wall(cell)) { - if (cell + mapWidth < Dungeon.level.map.length) { - if (!wall(cell + mapWidth)) { - if (!fogHidden(cell + mapWidth)){ - curr = BLOCK_NONE; - } else if ((cell + 1) % mapWidth != 0 && !fogHidden(cell + 1) - && !door(cell + 1) && !(wall(cell + 1) && wall(cell + 1 + mapWidth))){ - curr = BLOCK_NONE; - } else if (cell % mapWidth != 0 && !fogHidden(cell - 1) - && !door(cell - 1) && !(wall(cell - 1) && wall(cell - 1 + mapWidth))){ - curr = BLOCK_NONE; - } else { - curr = BLOCK_ALL; - } - } else { - curr = BLOCK_NONE; + } else if (!Level.discoverable[cell]) { + curr = CLEARED; - if ((cell + 1) % mapWidth != 0) { + //handles blocking wall overhang (which is technically on a none wall tile) + } else if (!wall(cell)) { - if (!wall(cell + 1) && !door(cell + 1)){ - if (fogHidden(cell + 1)) { - curr += 1; - } - } else { - if (fogHidden(cell + 1 + mapWidth)){ - curr += 1; - } - } + if (!fogHidden(cell)) { + curr = CLEARED; - } - - if (cell % mapWidth != 0) { - - if (!wall(cell - 1) && !door(cell - 1)){ - if (fogHidden(cell - 1)) { - curr += 2; - } - } else { - if (fogHidden(cell - 1 + mapWidth)){ - curr += 2; - } - } - - } - - } + } else if ( wall(cell + mapWidth) && !fogHidden(cell + mapWidth) + && fogHidden(cell - 1) && fogHidden(cell + 1)) { + curr = BLOCK_ALL; } else { curr = BLOCK_NONE; - - if ((cell + 1) % mapWidth != 0 && fogHidden(cell + 1)) { - curr += 1; - } - - if (cell % mapWidth != 0 && fogHidden(cell - 1)) { - curr += 2; - } } } else { - if (fogHidden(cell - 1) && fogHidden(cell) && fogHidden(cell + 1) - && cell + mapWidth < Dungeon.level.map.length - && wall(cell + mapWidth -1 ) && wall(cell + mapWidth) && wall(cell + mapWidth + 1) - && !fogHidden(cell + mapWidth)){ - curr = BLOCK_ALL; - } else { + + if (fogHidden(cell - mapWidth) && fogHidden(cell) && fogHidden(cell + mapWidth)) { curr = BLOCK_NONE; + + //camera-facing wall tiles + } else if (!wall(cell + mapWidth)) { + + if (!fogHidden(cell + mapWidth)){ + curr = CLEARED; + + } else if ((cell + 1) % mapWidth != 0 && !fogHidden(cell + 1) + && !door(cell + 1) && !(wall(cell + 1) && wall(cell + 1 + mapWidth))){ + curr = CLEARED; + + } else if (cell % mapWidth != 0 && !fogHidden(cell - 1) + && !door(cell - 1) && !(wall(cell - 1) && wall(cell - 1 + mapWidth))){ + curr = CLEARED; + + } else { + curr = BLOCK_ALL; + } + + //internal wall tiles + } else { + + curr = BLOCK_NONE; + + if ((cell + 1) % mapWidth != 0) { + if ((wall(cell + 1) || fogHidden(cell + 1 - mapWidth)) + && fogHidden(cell + 1) + && (wall(cell + 1 + mapWidth) || fogHidden(cell + 1 + mapWidth))){ + curr += 1; + } + } + + if (cell % mapWidth != 0) { + if ((wall(cell - 1) || fogHidden(cell - 1 - mapWidth)) + && fogHidden(cell - 1) + && (wall(cell - 1 + mapWidth) || fogHidden(cell - 1 + mapWidth))){ + curr += 2; + } + } + + if (curr == BLOCK_NONE) { + curr = CLEARED; + } + } + } if (prev != curr){ @@ -140,12 +141,13 @@ public class WallBlockingTilemap extends Tilemap { return false; } - private boolean wall(int cell){ - return DungeonTileSheet.wallStitcheable.contains(Dungeon.level.map[cell]); + //for the purposes of wall stitching, tiles below the map count as walls + private boolean wall(int cell) { + return cell >= 0 && (cell >= size || DungeonTileSheet.wallStitcheable(Dungeon.level.map[cell])); } - private boolean door(int cell ) { - return DungeonTileSheet.doorTiles.contains(Dungeon.level.map[cell]); + private boolean door(int cell) { + return cell >= 0 && cell < size && DungeonTileSheet.doorTile(Dungeon.level.map[cell]); } public synchronized void updateArea(int x, int y, int w, int h) { @@ -153,7 +155,7 @@ public class WallBlockingTilemap extends Tilemap { for (int i = x; i <= x+w; i++){ for (int j = y; j <= y+h; j++){ cell = i + j*mapWidth; - if (cell < data.length) + if (cell < data.length && data[cell] != CLEARED) updateMapCell(cell); } } @@ -161,6 +163,6 @@ public class WallBlockingTilemap extends Tilemap { @Override protected boolean needsRender(int pos) { - return data[pos] != BLOCK_NONE; + return data[pos] > BLOCK_NONE; } }