v0.5.0: initial implementation of new game visuals

Very messy, crashes outside of sewers, more work needed.
This commit is contained in:
Evan Debenham 2016-12-03 02:47:35 -05:00
parent c9e9c70683
commit e782b31cac
6 changed files with 406 additions and 64 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View File

@ -100,7 +100,7 @@ public class Assets {
public static final String ITEMS = "items.png";
public static final String TERRAIN_FEATURES = "terrain_features.png";
public static final String TILES_SEWERS = "tiles0.png";
public static final String TILES_SEWERS = "tiles_sewer.png";
public static final String TILES_PRISON = "tiles1.png";
public static final String TILES_CAVES = "tiles2.png";
public static final String TILES_CITY = "tiles3.png";

View File

@ -24,6 +24,7 @@ import android.util.SparseIntArray;
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTileSheet;
import com.watabou.noosa.Image;
import com.watabou.noosa.TextureFilm;
import com.watabou.noosa.Tilemap;
@ -45,59 +46,59 @@ public class DungeonTilemap extends Tilemap {
//Used to map dungeon tiles to their default visual values
public static SparseIntArray defaultVisuals = new SparseIntArray(32);
static {
defaultVisuals.put(Terrain.CHASM, 0);
defaultVisuals.put(Terrain.EMPTY, 1);
defaultVisuals.put(Terrain.GRASS, 2);
defaultVisuals.put(Terrain.EMPTY_WELL, 3);
defaultVisuals.put(Terrain.WALL, 4);
defaultVisuals.put(Terrain.DOOR, 5);
defaultVisuals.put(Terrain.OPEN_DOOR, 6);
defaultVisuals.put(Terrain.ENTRANCE, 7);
defaultVisuals.put(Terrain.EXIT, 8);
defaultVisuals.put(Terrain.EMBERS, 9);
defaultVisuals.put(Terrain.LOCKED_DOOR, 10);
defaultVisuals.put(Terrain.PEDESTAL, 11);
defaultVisuals.put(Terrain.WALL_DECO, 12);
defaultVisuals.put(Terrain.BARRICADE, 13);
defaultVisuals.put(Terrain.EMPTY_SP, 14);
defaultVisuals.put(Terrain.HIGH_GRASS, 15);
defaultVisuals.put(Terrain.CHASM, DungeonTileSheet.CHASM);
defaultVisuals.put(Terrain.EMPTY, DungeonTileSheet.FLOOR);
defaultVisuals.put(Terrain.GRASS, DungeonTileSheet.GRASS);
defaultVisuals.put(Terrain.EMPTY_WELL, DungeonTileSheet.EMPTY_WELL);
defaultVisuals.put(Terrain.WALL, DungeonTileSheet.FLAT_WALL);
defaultVisuals.put(Terrain.DOOR, DungeonTileSheet.FLAT_DOOR);
defaultVisuals.put(Terrain.OPEN_DOOR, DungeonTileSheet.FLAT_DOOR_OPEN);
defaultVisuals.put(Terrain.ENTRANCE, DungeonTileSheet.ENTRANCE);
defaultVisuals.put(Terrain.EXIT, DungeonTileSheet.EXIT);
defaultVisuals.put(Terrain.EMBERS, DungeonTileSheet.EMBERS);
defaultVisuals.put(Terrain.LOCKED_DOOR, DungeonTileSheet.FLAT_DOOR_LOCKED);
defaultVisuals.put(Terrain.PEDESTAL, DungeonTileSheet.PEDESTAL);
defaultVisuals.put(Terrain.WALL_DECO, DungeonTileSheet.FLAT_WALL_DECO);
defaultVisuals.put(Terrain.BARRICADE, DungeonTileSheet.BARRICADE);
defaultVisuals.put(Terrain.EMPTY_SP, DungeonTileSheet.FLOOR_SP);
defaultVisuals.put(Terrain.HIGH_GRASS, DungeonTileSheet.HIGH_GRASS);
defaultVisuals.put(Terrain.SECRET_DOOR, defaultVisuals.get(Terrain.WALL));
defaultVisuals.put(Terrain.SECRET_TRAP, defaultVisuals.get(Terrain.EMPTY));
defaultVisuals.put(Terrain.TRAP, defaultVisuals.get(Terrain.EMPTY));
defaultVisuals.put(Terrain.INACTIVE_TRAP, defaultVisuals.get(Terrain.EMPTY));
defaultVisuals.put(Terrain.EMPTY_DECO, 16);
defaultVisuals.put(Terrain.LOCKED_EXIT, 17);
defaultVisuals.put(Terrain.UNLOCKED_EXIT, 18);
defaultVisuals.put(Terrain.SIGN, 19);
defaultVisuals.put(Terrain.WELL, 20);
defaultVisuals.put(Terrain.STATUE, 21);
defaultVisuals.put(Terrain.STATUE_SP, 22);
defaultVisuals.put(Terrain.BOOKSHELF, 23);
defaultVisuals.put(Terrain.ALCHEMY, 24);
defaultVisuals.put(Terrain.EMPTY_DECO, DungeonTileSheet.FLOOR_DECO);
defaultVisuals.put(Terrain.LOCKED_EXIT, DungeonTileSheet.LOCKED_EXIT);
defaultVisuals.put(Terrain.UNLOCKED_EXIT, DungeonTileSheet.UNLOCKED_EXIT);
defaultVisuals.put(Terrain.SIGN, DungeonTileSheet.SIGN);
defaultVisuals.put(Terrain.WELL, DungeonTileSheet.WELL);
defaultVisuals.put(Terrain.STATUE, DungeonTileSheet.STATUE);
defaultVisuals.put(Terrain.STATUE_SP, DungeonTileSheet.STATUE_SP);
defaultVisuals.put(Terrain.BOOKSHELF, DungeonTileSheet.BOOKSHELF);
defaultVisuals.put(Terrain.ALCHEMY, DungeonTileSheet.ALCHEMY_POT);
defaultVisuals.put(Terrain.WATER, 63);
defaultVisuals.put(Terrain.WATER, DungeonTileSheet.WATER);
}
//These alt visuals will trigger 50% of the time
public static SparseIntArray commonAltVisuals = new SparseIntArray(32);
static {
commonAltVisuals.put(1, 38);
commonAltVisuals.put(2, 39);
commonAltVisuals.put(4, 40);
commonAltVisuals.put(9, 41);
commonAltVisuals.put(12, 42);
commonAltVisuals.put(14, 43);
commonAltVisuals.put(15, 44);
commonAltVisuals.put(16, 45);
commonAltVisuals.put(23, 46);
commonAltVisuals.put(DungeonTileSheet.FLOOR, DungeonTileSheet.FLOOR_ALT_1);
commonAltVisuals.put(DungeonTileSheet.GRASS, DungeonTileSheet.GRASS_ALT);
commonAltVisuals.put(DungeonTileSheet.FLAT_WALL, DungeonTileSheet.FLAT_WALL_ALT);
commonAltVisuals.put(DungeonTileSheet.EMBERS, DungeonTileSheet.EMBERS_ALT);
commonAltVisuals.put(DungeonTileSheet.FLAT_WALL_DECO, DungeonTileSheet.FLAT_WALL_DECO_ALT);
commonAltVisuals.put(DungeonTileSheet.FLOOR_SP, DungeonTileSheet.FLOOR_SP_ALT);
commonAltVisuals.put(DungeonTileSheet.HIGH_GRASS, DungeonTileSheet.HIGH_GRASS_ALT);
commonAltVisuals.put(DungeonTileSheet.FLOOR_DECO, DungeonTileSheet.FLOOR_DECO_ALT);
commonAltVisuals.put(DungeonTileSheet.BOOKSHELF, DungeonTileSheet.BOOKSHELF_ALT);
}
//These alt visuals trigger 10% of the time (and also override common alts when they show up)
public static SparseIntArray rareAltVisuals = new SparseIntArray(32);
static {
rareAltVisuals.put(1, 47);
rareAltVisuals.put(DungeonTileSheet.FLOOR, DungeonTileSheet.FLOOR_ALT_2);
}
//These tiles can stitch with water
@ -106,35 +107,36 @@ public class DungeonTilemap extends Tilemap {
Terrain.ENTRANCE, Terrain.EXIT, Terrain.EMBERS,
Terrain.BARRICADE, Terrain.HIGH_GRASS, Terrain.SECRET_TRAP,
Terrain.TRAP, Terrain.INACTIVE_TRAP, Terrain.EMPTY_DECO,
Terrain.SIGN, Terrain.WELL, Terrain.STATUE, Terrain.ALCHEMY
Terrain.SIGN, Terrain.WELL, Terrain.STATUE, Terrain.ALCHEMY,
Terrain.DOOR, Terrain.OPEN_DOOR, Terrain.LOCKED_DOOR
);
//tiles that can stitch with chasms (from above), and which visual represents the stitching
public static SparseIntArray chasmStitcheable = new SparseIntArray(32);
static {
//floor
chasmStitcheable.put( Terrain.EMPTY, 32 );
chasmStitcheable.put( Terrain.GRASS, 32 );
chasmStitcheable.put( Terrain.EMPTY_WELL, 32 );
chasmStitcheable.put( Terrain.HIGH_GRASS, 32 );
chasmStitcheable.put( Terrain.EMPTY_DECO, 32 );
chasmStitcheable.put( Terrain.SIGN, 32 );
chasmStitcheable.put( Terrain.EMPTY_WELL, 32 );
chasmStitcheable.put( Terrain.STATUE, 32 );
chasmStitcheable.put( Terrain.EMPTY, DungeonTileSheet.CHASM_FLOOR );
chasmStitcheable.put( Terrain.GRASS, DungeonTileSheet.CHASM_FLOOR );
chasmStitcheable.put( Terrain.EMPTY_WELL, DungeonTileSheet.CHASM_FLOOR );
chasmStitcheable.put( Terrain.HIGH_GRASS, DungeonTileSheet.CHASM_FLOOR );
chasmStitcheable.put( Terrain.EMPTY_DECO, DungeonTileSheet.CHASM_FLOOR );
chasmStitcheable.put( Terrain.SIGN, DungeonTileSheet.CHASM_FLOOR );
chasmStitcheable.put( Terrain.EMPTY_WELL, DungeonTileSheet.CHASM_FLOOR );
chasmStitcheable.put( Terrain.STATUE, DungeonTileSheet.CHASM_FLOOR );
//special floor
chasmStitcheable.put( Terrain.EMPTY_SP, 33 );
chasmStitcheable.put( Terrain.STATUE_SP, 33 );
chasmStitcheable.put( Terrain.EMPTY_SP, DungeonTileSheet.CHASM_FLOOR_SP );
chasmStitcheable.put( Terrain.STATUE_SP, DungeonTileSheet.CHASM_FLOOR_SP );
//wall
chasmStitcheable.put( Terrain.WALL, 34 );
chasmStitcheable.put( Terrain.DOOR, 34 );
chasmStitcheable.put( Terrain.OPEN_DOOR, 34 );
chasmStitcheable.put( Terrain.LOCKED_DOOR, 34 );
chasmStitcheable.put( Terrain.WALL_DECO, 34 );
chasmStitcheable.put( Terrain.WALL, DungeonTileSheet.CHASM_WALL );
chasmStitcheable.put( Terrain.DOOR, DungeonTileSheet.CHASM_WALL );
chasmStitcheable.put( Terrain.OPEN_DOOR, DungeonTileSheet.CHASM_WALL );
chasmStitcheable.put( Terrain.LOCKED_DOOR, DungeonTileSheet.CHASM_WALL );
chasmStitcheable.put( Terrain.WALL_DECO, DungeonTileSheet.CHASM_WALL );
//water
chasmStitcheable.put( Terrain.WATER, 35 );
chasmStitcheable.put( Terrain.WATER, DungeonTileSheet.CHASM_WATER );
}
private int[] map;
@ -168,7 +170,7 @@ public class DungeonTilemap extends Tilemap {
public synchronized void updateMap() {
super.updateMap();
for (int i = 0; i < data.length; i++)
data[i] = getTileVisual(i ,map[i]);
data[i] = getTileVisual(i ,map[i], false);
}
@Override
@ -178,31 +180,69 @@ public class DungeonTilemap extends Tilemap {
super.updateMapCell(cell - mapWidth - 1);
super.updateMapCell(cell + mapWidth + 1);
for (int i : PathFinder.NEIGHBOURS9)
data[cell + i] = getTileVisual(cell + i, map[cell + i]);
data[cell + i] = getTileVisual(cell + i, map[cell + i], false);
//unless we're at the level's edge, then just do the one tile.
} else {
super.updateMapCell(cell);
data[cell] = getTileVisual(cell, map[cell]);
data[cell] = getTileVisual(cell, map[cell], false);
}
}
private int getTileVisual(int pos, int tile){
//These tiles count as wall for the purposes of wall stitching
public static List wallStitcheable = Arrays.asList(
Terrain.WALL, Terrain.WALL_DECO, Terrain.SECRET_DOOR,
Terrain.LOCKED_EXIT, Terrain.UNLOCKED_EXIT
);
private int getTileVisual(int pos, int tile, boolean flat) {
int visual = defaultVisuals.get(tile);
if (tile == Terrain.WATER){
for (int i = 0; i < PathFinder.CIRCLE4.length; i++){
if (tile == Terrain.WATER) {
for (int i = 0; i < PathFinder.CIRCLE4.length; i++) {
if (waterStitcheable.contains(map[pos + PathFinder.CIRCLE4[i]])) {
//equivalent to: cell -= 2^i
visual -= (1 << i);
//equivalent to: cell += 2^i
visual += (1 << i);
}
}
return visual;
} else if (tile == Terrain.CHASM && pos >= mapWidth) {
return chasmStitcheable.get(map[pos - mapWidth], visual);
}
} else if (tileVariance[pos] > 0.9f
if (!flat) {
if ((tile == Terrain.DOOR || tile == Terrain.LOCKED_DOOR || tile == Terrain.OPEN_DOOR) && map[pos - mapWidth] == Terrain.WALL) {
return DungeonTileSheet.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 if (tile == Terrain.WALL || tile == Terrain.WALL_DECO){
if (tile == Terrain.WALL) {
if (pos + mapWidth < size && (map[pos + mapWidth] == Terrain.DOOR || map[pos + mapWidth] == Terrain.LOCKED_DOOR || map[pos + mapWidth] == Terrain.OPEN_DOOR)){
visual = DungeonTileSheet.RAISED_WALL_DOOR;
} else {
visual = DungeonTileSheet.RAISED_WALL;
}
} else
visual = DungeonTileSheet.RAISED_WALL_DECO;
if (tileVariance[pos] > 0.5f)
visual += 16;
if (pos % mapWidth != 0 && !wallStitcheable.contains(map[pos - 1]))
visual += 2;
if (pos % mapWidth != mapWidth-1 && !wallStitcheable.contains(map[pos + 1]))
visual += 1;
return visual;
}
}
if (tileVariance[pos] > 0.9f
&& rareAltVisuals.indexOfKey(visual) >= 0){
return rareAltVisuals.get(visual);
@ -259,7 +299,7 @@ public class DungeonTilemap extends Tilemap {
public static Image tile( int pos, int tile ) {
Image img = new Image( instance.texture );
img.frame( instance.tileset.get( instance.getTileVisual( pos, tile ) ) );
img.frame( instance.tileset.get( instance.getTileVisual( pos, tile, true ) ) );
return img;
}

View File

@ -63,6 +63,7 @@ import com.shatteredpixel.shatteredpixeldungeon.ui.AttackIndicator;
import com.shatteredpixel.shatteredpixeldungeon.ui.Banner;
import com.shatteredpixel.shatteredpixeldungeon.ui.BusyIndicator;
import com.shatteredpixel.shatteredpixeldungeon.ui.CustomTileVisual;
import com.shatteredpixel.shatteredpixeldungeon.ui.DungeonWallsTilemap;
import com.shatteredpixel.shatteredpixeldungeon.ui.GameLog;
import com.shatteredpixel.shatteredpixeldungeon.ui.HealthIndicator;
import com.shatteredpixel.shatteredpixeldungeon.ui.LootIndicator;
@ -111,6 +112,7 @@ public class GameScene extends PixelScene {
private SkinnedBlock water;
private DungeonTilemap tiles;
private TerrainFeaturesTilemap terrainFeatures;
private DungeonWallsTilemap walls;
private FogOfWar fog;
private HeroSprite hero;
@ -233,6 +235,9 @@ public class GameScene extends PixelScene {
addBlobSprite( blob );
}
walls = new DungeonWallsTilemap();
add(walls);
fog = new FogOfWar( Dungeon.level.width(), Dungeon.level.height() );
add( fog );
@ -675,6 +680,7 @@ public class GameScene extends PixelScene {
if (scene != null) {
scene.tiles.map(Dungeon.level.map, Dungeon.level.width() );
scene.terrainFeatures.map(Dungeon.level.map, Dungeon.level.width() );
scene.walls.map(Dungeon.level.map, Dungeon.level.width() );
}
updateFog();
}
@ -684,6 +690,7 @@ public class GameScene extends PixelScene {
if (scene != null) {
scene.tiles.updateMap();
scene.terrainFeatures.updateMap();
scene.walls.updateMap();
}
}
@ -691,6 +698,7 @@ public class GameScene extends PixelScene {
if (scene != null) {
scene.tiles.updateMapCell( cell );
scene.terrainFeatures.updateMapCell( cell );
scene.walls.updateMapCell( cell );
}
}

View File

@ -0,0 +1,132 @@
/*
* 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 <http://www.gnu.org/licenses/>
*/
package com.shatteredpixel.shatteredpixeldungeon.tiles;
public class DungeonTileSheet {
private static final int WIDTH = 16;
private static int xy(int x, int y){
x -= 1; y -= 1;
return x + WIDTH*y;
}
private static final int GROUND = xy(1, 1); //32 slots
public static final int FLOOR = GROUND +0;
public static final int FLOOR_DECO = GROUND +1;
public static final int HIGH_GRASS = GROUND +2;
public static final int GRASS = GROUND +3;
public static final int EMBERS = GROUND +4;
public static final int FLOOR_SP = GROUND +5;
public static final int FLOOR_ALT_1 = GROUND +7;
public static final int FLOOR_DECO_ALT = GROUND +8;
public static final int HIGH_GRASS_ALT = GROUND +9;
public static final int GRASS_ALT = GROUND +10;
public static final int EMBERS_ALT = GROUND +11;
public static final int FLOOR_SP_ALT = GROUND +12;
public static final int FLOOR_ALT_2 = GROUND +14;
public static final int ENTRANCE = GROUND +16;
public static final int EXIT = GROUND +17;
public static final int SIGN = GROUND +18;
public static final int STATUE = GROUND +19;
public static final int STATUE_SP = GROUND +20;
public static final int WELL = GROUND +21;
public static final int EMPTY_WELL = GROUND +22;
public static final int ALCHEMY_POT = GROUND +23;
public static final int PEDESTAL = GROUND +24;
public static final int BARRICADE = GROUND +25;
public static final int BOOKSHELF = GROUND +26;
public static final int BOOKSHELF_ALT = GROUND +28;
public static final int WATER = xy(1, 3); //16 slots
//next 15 slots are all water stitching with ground.
//+1 for ground above, +2 for ground right, +4 for ground below, +8 for ground left.
public static final int CHASM = xy(1, 4); //16 tiles
//chasm stitching visuals...
public static final int CHASM_FLOOR = CHASM+1;
public static final int CHASM_FLOOR_SP = CHASM+2;
public static final int CHASM_WALL = CHASM+3;
public static final int CHASM_WATER = CHASM+4;
/*
These tiles present wall visuals as flat
*/
private static final int FLAT_WALLS = xy(1, 5); //16 slots
public static final int FLAT_WALL = FLAT_WALLS+0;
public static final int FLAT_WALL_DECO = FLAT_WALLS+1;
public static final int FLAT_WALL_ALT = FLAT_WALLS+3;
public static final int FLAT_WALL_DECO_ALT = FLAT_WALLS+4;
private static final int FLAT_DOORS = xy(1,6); //16 slots
public static final int FLAT_DOOR = FLAT_DOORS+0;
public static final int FLAT_DOOR_OPEN = FLAT_DOORS+1;
public static final int FLAT_DOOR_LOCKED = FLAT_DOORS+2;
public static final int UNLOCKED_EXIT = FLAT_DOORS+3;
public static final int LOCKED_EXIT = FLAT_DOORS+4;
/*
These tiles present visuals that are raised and rendered on the lower layer (behind characters)
*/
private static final int RAISED_WALLS = xy(1, 8); //32 slots
//+1 for walls to the right, +2 for walls to the left
public static final int RAISED_WALL = RAISED_WALLS+0;
public static final int RAISED_WALL_DECO = RAISED_WALLS+4;
//wall that appears behind a top/bottom doorway
public static final int RAISED_WALL_DOOR = RAISED_WALLS+8;
public static final int RAISED_WALL_ALT = RAISED_WALLS+16;
public static final int RAISED_WALL_DECO_ALT = RAISED_WALLS+20;
private static final int RAISED_DOORS = xy(1, 10); //16 slots
public static final int RAISED_DOOR = RAISED_DOORS+0;
public static final int RAISED_DOOR_OPEN = RAISED_DOORS+1;
public static final int RAISED_DOOR_LOCKED = RAISED_DOORS+2;
//floor tile that appears on a top/bottom doorway
public static final int RAISED_DOOR_SIDEWAYS = RAISED_DOORS+3;
/*
These tiles present visuals that are raised and rendered on the upper layer (above characters)
*/
//+1 for wall right, +2 for wall right-below, +4 for wall left-below, +8 for wall left.
public static final int WALLS_INTERNAL = xy(1, 12); //16 slots
//+1 for walls to the down-right, +2 for walls to the down-left
private static final int WALLS_OVERHANG = xy(1, 13); //16 slots
public static final int WALL_OVERHANG = WALLS_OVERHANG+0;
public static final int DOOR_SIDEWAYS_OVERHANG = WALL_OVERHANG+4;
public static final int DOOR_SIDEWAYS_OVERHANG_OPEN = WALL_OVERHANG+8;
//no attachment to adjacent walls
public static final int DOOR_OVERHANG = WALL_OVERHANG+12;
public static final int DOOR_OVERHANG_OPEN = WALL_OVERHANG+13;
public static final int DOOR_SIDEWAYS = WALL_OVERHANG+14;
public static final int DOOR_SIDEWAYS_LOCKED = WALL_OVERHANG+15;
}

View File

@ -0,0 +1,162 @@
/*
* 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 <http://www.gnu.org/licenses/>
*/
package com.shatteredpixel.shatteredpixeldungeon.ui;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.Trap;
import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTileSheet;
import com.watabou.noosa.TextureFilm;
import com.watabou.noosa.Tilemap;
import com.watabou.utils.PathFinder;
import com.watabou.utils.Random;
import java.util.Arrays;
import java.util.List;
public class DungeonWallsTilemap extends Tilemap {
public static final int SIZE = 16;
private static DungeonWallsTilemap instance;
//These tiles count as wall for the purposes of wall stitching
public static List wallStitcheable = Arrays.asList(
Terrain.WALL, Terrain.WALL_DECO, Terrain.SECRET_DOOR,
Terrain.LOCKED_EXIT, Terrain.UNLOCKED_EXIT
);
private int[] map;
private float[] tileVariance;
public DungeonWallsTilemap(){
super(
Dungeon.level.tilesTex(),
new TextureFilm( Dungeon.level.tilesTex(), SIZE, SIZE ) );
Random.seed( Dungeon.seedCurDepth());
tileVariance = new float[Dungeon.level.map.length];
for (int i = 0; i < tileVariance.length; i++)
tileVariance[i] = Random.Float();
Random.seed();
map( Dungeon.level.map, Dungeon.level.width() );
instance = this;
}
@Override
//we need to retain two arrays, map is the dungeon tilemap which we can reference.
// Data is our own internal image representation of the tiles, which may differ.
public void map(int[] data, int cols) {
map = data;
super.map(new int[data.length], cols);
}
@Override
public synchronized void updateMap() {
super.updateMap();
for (int i = 0; i < data.length; i++)
data[i] = getTileVisual(i ,map[i]);
}
@Override
public synchronized void updateMapCell(int cell) {
//update in a 3x3 grid to account for neighbours which might also be affected
if (Dungeon.level.insideMap(cell)) {
super.updateMapCell(cell - mapWidth - 1);
super.updateMapCell(cell + mapWidth + 1);
for (int i : PathFinder.NEIGHBOURS9)
data[cell + i] = getTileVisual(cell + i, map[cell + i]);
//unless we're at the level's edge, then just do the one tile.
} else {
super.updateMapCell(cell);
data[cell] = getTileVisual(cell, map[cell]);
}
}
private int getTileVisual(int pos, int tile){
if (wallStitcheable.contains(tile)) {
if (pos + mapWidth < size && !wallStitcheable.contains(map[pos + mapWidth])){
if (map[pos + mapWidth] == Terrain.DOOR){
return DungeonTileSheet.DOOR_SIDEWAYS;
} else if (map[pos + mapWidth] == Terrain.LOCKED_DOOR){
return DungeonTileSheet.DOOR_SIDEWAYS_LOCKED;
}
} else {
//otherwise, need to stitch with right, bottom-right, bottom-left, and left.
int visual = DungeonTileSheet.WALLS_INTERNAL;
if (pos % mapWidth != 0 && !wallStitcheable.contains(map[pos - 1]))
visual += 8;
if (pos % mapWidth != 0 && pos + mapWidth < size && !wallStitcheable.contains(map[pos - 1 + mapWidth]))
visual += 4;
if ((pos+1) % mapWidth != 0 && pos + mapWidth < size && !wallStitcheable.contains(map[pos + 1 + mapWidth]))
visual += 2;
if ((pos+1) % mapWidth != 0 && !wallStitcheable.contains(map[pos + 1]))
visual += 1;
return visual;
}
} else if (Dungeon.level.insideMap(pos) && wallStitcheable.contains(map[pos+mapWidth])) {
int visual;
if (map[pos] == Terrain.DOOR || map[pos] == Terrain.LOCKED_DOOR)
visual = DungeonTileSheet.DOOR_SIDEWAYS_OVERHANG;
else if (map[pos] == Terrain.OPEN_DOOR)
visual = DungeonTileSheet.DOOR_SIDEWAYS_OVERHANG_OPEN;
else
visual = DungeonTileSheet.WALL_OVERHANG;
if (!wallStitcheable.contains(map[pos - 1 + mapWidth]))
visual += 2;
if (!wallStitcheable.contains(map[pos + 1 + mapWidth]))
visual += 1;
return visual;
} else if (Dungeon.level.insideMap(pos) && (map[pos+mapWidth] == Terrain.DOOR || map[pos+mapWidth] == Terrain.LOCKED_DOOR) ) {
return DungeonTileSheet.DOOR_OVERHANG;
} else if (Dungeon.level.insideMap(pos) && map[pos+mapWidth] == Terrain.OPEN_DOOR ) {
return DungeonTileSheet.DOOR_OVERHANG_OPEN;
}
return -1;
}
@Override
public boolean overlapsPoint( float x, float y ) {
return true;
}
@Override
public boolean overlapsScreenPoint( int x, int y ) {
return true;
}
@Override
protected boolean needsRender(int pos) {
return data[pos] != -1;
}
}