diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/GameScene.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/GameScene.java
index 36809d16a..65583882c 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/GameScene.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/GameScene.java
@@ -27,7 +27,7 @@ import com.shatteredpixel.shatteredpixeldungeon.Badges;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTerrainTilemap;
import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTilemap;
-import com.shatteredpixel.shatteredpixeldungeon.FogOfWar;
+import com.shatteredpixel.shatteredpixeldungeon.tiles.FogOfWar;
import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
import com.shatteredpixel.shatteredpixeldungeon.Statistics;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
@@ -59,6 +59,7 @@ import com.shatteredpixel.shatteredpixeldungeon.sprites.DiscardedItemSprite;
import com.shatteredpixel.shatteredpixeldungeon.sprites.HeroSprite;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite;
import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTileSheet;
+import com.shatteredpixel.shatteredpixeldungeon.tiles.WallBlockingTilemap;
import com.shatteredpixel.shatteredpixeldungeon.ui.ActionIndicator;
import com.shatteredpixel.shatteredpixeldungeon.ui.AttackIndicator;
import com.shatteredpixel.shatteredpixeldungeon.ui.Banner;
@@ -114,6 +115,7 @@ public class GameScene extends PixelScene {
private DungeonTerrainTilemap tiles;
private TerrainFeaturesTilemap terrainFeatures;
private DungeonWallsTilemap walls;
+ private WallBlockingTilemap wallBlocking;
private FogOfWar fog;
private HeroSprite hero;
@@ -241,6 +243,9 @@ public class GameScene extends PixelScene {
walls = new DungeonWallsTilemap();
add(walls);
+ wallBlocking = new WallBlockingTilemap();
+ add (wallBlocking);
+
fog = new FogOfWar( Dungeon.level.width(), Dungeon.level.height() );
add( fog );
@@ -723,13 +728,16 @@ public class GameScene extends PixelScene {
}
public static void updateFog(){
- if (scene != null)
+ if (scene != null) {
scene.fog.updateFog();
+ scene.wallBlocking.updateMap();
+ }
}
public static void updateFog(int x, int y, int w, int h){
if (scene != null) {
scene.fog.updateFogArea(x, y, w, h);
+ scene.wallBlocking.updateArea(x, y, w, h);
}
}
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/FogOfWar.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/tiles/FogOfWar.java
similarity index 50%
rename from core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/FogOfWar.java
rename to core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/tiles/FogOfWar.java
index 21bea1779..9a29ccd34 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/FogOfWar.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/tiles/FogOfWar.java
@@ -18,11 +18,12 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see
*/
-package com.shatteredpixel.shatteredpixeldungeon;
+package com.shatteredpixel.shatteredpixeldungeon.tiles;
import android.opengl.GLES20;
-import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTilemap;
+import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
+import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
import com.watabou.gltextures.SmartTexture;
import com.watabou.gltextures.TextureCache;
import com.watabou.glwrap.Texture;
@@ -37,24 +38,37 @@ import java.nio.IntBuffer;
public class FogOfWar extends Image {
- private static final int VISIBLE[] = new int[]{0xAA000000, 0x55000000, //-2 and -1 brightness
- 0x00000000, //0 brightness
- 0x00000000, 0x00000000}; //1 and 2 brightness
+ //first index is visibility type, second is brightness level
+ private static final int FOG_COLORS[][] = new int[][]{{
+ //visible
+ 0xAA000000, 0x55000000, //-2 and -1 brightness
+ 0x00000000, //0 brightness
+ 0x00000000, 0x00000000 //1 and 2 brightness
+ }, {
+ //visited
+ 0xEE000000, 0xDD000000,
+ 0xCC000000,
+ 0x99000000, 0x66000000
+ }, {
+ //mapped
+ 0xEE442211, 0xDD442211,
+ 0xCC442211,
+ 0x99442211, 0x66442211
+ }, {
+ //invisible
+ 0xFF000000, 0xFF000000,
+ 0xFF000000,
+ 0xFF000000, 0xFF000000
+ }};
- private static final int VISITED[] = new int[]{0xEE000000, 0xDD000000,
- 0xCC000000,
- 0x99000000, 0x66000000};
-
- private static final int MAPPED[] = new int[]{0xEE442211, 0xDD442211,
- 0xCC442211,
- 0x99442211, 0x66442211};
-
- private static final int INVISIBLE[]= new int[]{0xFF000000, 0xFF000000,
- 0xFF000000,
- 0xFF000000, 0xFF000000};
+ private static final int VISIBLE = 0;
+ private static final int VISITED = 1;
+ private static final int MAPPED = 2;
+ private static final int INVISIBLE = 3;
private int mapWidth;
private int mapHeight;
+ private int mapLength;
private int pWidth;
private int pHeight;
@@ -73,6 +87,7 @@ public class FogOfWar extends Image {
this.mapWidth = mapWidth;
this.mapHeight = mapHeight;
+ mapLength = mapHeight * mapWidth;
pWidth = mapWidth * PIX_PER_TILE;
pHeight = mapHeight * PIX_PER_TILE;
@@ -113,30 +128,100 @@ public class FogOfWar extends Image {
updating = new Rect(updated);
updated.setEmpty();
}
+
+ private boolean[] visible;
+ private boolean[] visited;
+ private boolean[] mapped;
+ private int brightness;
private void updateTexture( boolean[] visible, boolean[] visited, boolean[] mapped ) {
+ this.visible = visible;
+ this.visited = visited;
+ this.mapped = mapped;
+ this.brightness = ShatteredPixelDungeon.brightness() + 2;
moveToUpdating();
FogTexture fog = (FogTexture)texture;
- int brightness = ShatteredPixelDungeon.brightness() + 2;
-
+ int cellIndex;
+ int[] colorArray = new int[PIX_PER_TILE*PIX_PER_TILE];
for (int i=updating.top; i < updating.bottom; i++) {
int cell = mapWidth * i + updating.left;
- //fog.pixels.position((width2) * i + updating.left);
for (int j=updating.left; j < updating.right; j++) {
- if (cell >= Dungeon.level.length()) {
- //do nothing
- } else if (visible[cell]) {
- fillCell(j, i, VISIBLE[brightness]);
- } else if (visited[cell]) {
- fillCell(j, i, VISITED[brightness]);
- } else if (mapped[cell] ) {
- fillCell(j, i, MAPPED[brightness]);
- } else {
- fillCell(j, i, INVISIBLE[brightness]);
+
+ if (cell >= Dungeon.level.length()) continue; //do nothing
+
+ if (!visible[cell] && !visited[cell] && !mapped[cell]){
+ fillCell(j, i, FOG_COLORS[INVISIBLE][brightness]);
+ cell++;
+ continue;
}
+
+ //triggers on wall tiles or sideways doors
+ if (DungeonTileSheet.wallStitcheable.contains(Dungeon.level.map[cell]) ||
+ ( DungeonTileSheet.doorTiles.contains(Dungeon.level.map[cell])
+ && cell + mapWidth < mapLength
+ && DungeonTileSheet.wallStitcheable.contains(Dungeon.level.map[cell + mapWidth]))) {
+ cellIndex = getColorIndexForCell(cell);
+
+ if (cell + mapWidth < mapLength){
+ if (!DungeonTileSheet.wallStitcheable.contains(Dungeon.level.map[cell + mapWidth])
+ && getColorIndexForCell(cell + mapWidth) > cellIndex) {
+ cellIndex = getColorIndexForCell(cell + mapWidth);
+ }
+
+ if (cell % mapWidth != 0){
+ if (DungeonTileSheet.wallStitcheable.contains(Dungeon.level.map[cell - 1])){
+ if (getColorIndexForCell(cell - 1 + mapWidth) > cellIndex)
+ colorArray[0] = colorArray[2] = FOG_COLORS[getColorIndexForCell(cell - 1 + mapWidth)][brightness];
+ else
+ colorArray[0] = colorArray[2] = FOG_COLORS[cellIndex][brightness];
+ } else {
+ if (getColorIndexForCell(cell - 1) > cellIndex)
+ colorArray[0] = colorArray[2] = FOG_COLORS[getColorIndexForCell(cell - 1)][brightness];
+ else
+ colorArray[0] = colorArray[2] = FOG_COLORS[cellIndex][brightness];
+ }
+ } else {
+ colorArray[0] = colorArray[2] = FOG_COLORS[cellIndex][brightness];
+ }
+
+ if ((cell+1) % mapWidth != 0){
+ if (DungeonTileSheet.wallStitcheable.contains(Dungeon.level.map[cell + 1])){
+ if (getColorIndexForCell(cell + 1 + mapWidth) > cellIndex)
+ colorArray[1] = colorArray[3] = FOG_COLORS[getColorIndexForCell(cell + 1 + mapWidth)][brightness];
+ else
+ colorArray[1] = colorArray[3] = FOG_COLORS[cellIndex][brightness];
+ } else {
+ if (getColorIndexForCell(cell + 1) > cellIndex)
+ colorArray[1] = colorArray[3] = FOG_COLORS[getColorIndexForCell(cell + 1)][brightness];
+ else
+ colorArray[1] = colorArray[3] = FOG_COLORS[cellIndex][brightness];
+ }
+ } else {
+ colorArray[1] = colorArray[3] = FOG_COLORS[cellIndex][brightness];
+ }
+
+ } else {
+ if (cell % mapWidth != 0 && getColorIndexForCell(cell - 1) > cellIndex) {
+ colorArray[0] = colorArray[2] = FOG_COLORS[getColorIndexForCell(cell - 1)][brightness];
+ } else {
+ colorArray[0] = colorArray[2] = FOG_COLORS[cellIndex][brightness];
+ }
+
+ if ((cell+1) % mapWidth != 0 && getColorIndexForCell(cell + 1) > cellIndex) {
+ colorArray[1] = colorArray[3] = FOG_COLORS[getColorIndexForCell(cell + 1)][brightness];
+ } else {
+ colorArray[1] = colorArray[3] = FOG_COLORS[cellIndex][brightness];
+ }
+ }
+
+ fillCell(j, i, colorArray);
+ } else {
+ fillCell(j, i, FOG_COLORS[getColorIndexForCell(cell)][brightness]);
+ }
+
cell++;
}
}
@@ -148,6 +233,29 @@ public class FogOfWar extends Image {
}
+ private int getColorIndexForCell( int cell ){
+
+ if (visible[cell]) {
+ return VISIBLE;
+ } else if (visited[cell]) {
+ return VISITED;
+ } else if (mapped[cell] ) {
+ return MAPPED;
+ } else {
+ return INVISIBLE;
+ }
+ }
+
+ private void fillCell( int x, int y, int[] colors){
+ FogTexture fog = (FogTexture)texture;
+ for (int i = 0; i < PIX_PER_TILE; i++){
+ fog.pixels.position(((y * PIX_PER_TILE)+i)*width2 + x * PIX_PER_TILE);
+ for (int j = 0; j < PIX_PER_TILE; j++) {
+ fog.pixels.put(colors[i*PIX_PER_TILE + j]);
+ }
+ }
+ }
+
private void fillCell( int x, int y, int color){
FogTexture fog = (FogTexture)texture;
for (int i = 0; i < PIX_PER_TILE; i++){
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/tiles/WallBlockingTilemap.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/tiles/WallBlockingTilemap.java
new file mode 100644
index 000000000..e68fe31ca
--- /dev/null
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/tiles/WallBlockingTilemap.java
@@ -0,0 +1,141 @@
+/*
+ * Pixel Dungeon
+ * Copyright (C) 2012-2015 Oleg Dolya
+ *
+ * Shattered Pixel Dungeon
+ * Copyright (C) 2014-2016 Evan Debenham
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see
+ */
+package com.shatteredpixel.shatteredpixeldungeon.tiles;
+
+import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
+import com.watabou.noosa.TextureFilm;
+import com.watabou.noosa.Tilemap;
+
+
+public class WallBlockingTilemap extends Tilemap {
+
+ public static final int SIZE = 16;
+
+ private static final int BLOCK_NONE = 0;
+ private static final int BLOCK_RIGHT = 1;
+ private static final int BLOCK_LEFT = 2;
+ private static final int BLOCK_ALL = 3;
+
+ public WallBlockingTilemap() {
+ super("wall_blocking.png", new TextureFilm( "wall_blocking.png", SIZE, SIZE ) );
+ map( new int[Dungeon.level.length()], Dungeon.level.width());
+ }
+
+ @Override
+ public synchronized void updateMap() {
+ super.updateMap();
+ for (int i = 0; i < data.length; i++)
+ updateMapCell(i);
+ }
+
+ @Override
+ public synchronized void updateMapCell(int cell) {
+ int prev = data[cell];
+ int curr;
+
+ //no point in blocking tiles that are already obscured by fog
+ if (fogHidden(cell) && fogHidden(cell - mapWidth)){
+ curr = BLOCK_NONE;
+
+ } else if (DungeonTileSheet.wallStitcheable.contains(Dungeon.level.map[cell])) {
+ if (cell + mapWidth < Dungeon.level.map.length) {
+ if (!DungeonTileSheet.wallStitcheable.contains(Dungeon.level.map[cell + mapWidth])) {
+ if (fogHidden(cell + mapWidth)) {
+ curr = BLOCK_ALL;
+ } else {
+ curr = BLOCK_NONE;
+ }
+ } else {
+ curr = BLOCK_NONE;
+
+ if ((cell + 1) % mapWidth != 0) {
+
+ if (!DungeonTileSheet.wallStitcheable.contains(Dungeon.level.map[cell + 1])){
+ if (fogHidden(cell + 1)) {
+ curr += 1;
+ }
+ } else {
+ if (fogHidden(cell + 1 + mapWidth)){
+ curr += 1;
+ }
+ }
+
+ }
+
+ if (cell % mapWidth != 0) {
+
+ if (!DungeonTileSheet.wallStitcheable.contains(Dungeon.level.map[cell - 1])){
+ if (fogHidden(cell - 1)) {
+ curr += 2;
+ }
+ } else {
+ if (fogHidden(cell - 1 + mapWidth)){
+ curr += 2;
+ }
+ }
+
+ }
+
+ }
+
+ } else {
+ curr = BLOCK_NONE;
+
+ if ((cell + 1) % mapWidth != 0 && fogHidden(cell + 1)) {
+ curr += 1;
+ }
+
+ if (cell % mapWidth != 0 && fogHidden(cell - 1)) {
+ curr += 2;
+ }
+ }
+
+ } else {
+ curr = BLOCK_NONE;
+ }
+
+ if (prev != curr){
+ data[cell] = curr;
+ super.updateMapCell(cell);
+ }
+ }
+
+ private boolean fogHidden(int cell){
+ if (cell < 0 || cell >= Dungeon.level.length()) return false;
+ return (!Dungeon.level.visited[cell] && !Dungeon.level.mapped[cell]);
+ }
+
+ public synchronized void updateArea(int x, int y, int w, int h) {
+ int cell;
+ for (int i = x; i <= x+w; i++){
+ for (int j = y; j <= y+h; j++){
+ cell = i + j*mapWidth;
+ if (cell < data.length)
+ updateMapCell(cell);
+ }
+ }
+ }
+
+ @Override
+ protected boolean needsRender(int pos) {
+ return data[pos] != BLOCK_NONE;
+ }
+}