v0.5.0: several improvements to tilemaps

This commit is contained in:
Evan Debenham 2016-12-10 03:02:39 -05:00
parent 9a3ecbe081
commit d9fe08695a
8 changed files with 298 additions and 265 deletions

View File

@ -43,116 +43,13 @@ public class DungeonTilemap extends Tilemap {
private static DungeonTilemap instance; private static DungeonTilemap instance;
//Used to map dungeon tiles to their default visual values
public static SparseIntArray defaultVisuals = new SparseIntArray(32);
static {
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, 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, DungeonTileSheet.WATER);
}
//These alt visuals will trigger 50% of the time
public static SparseIntArray commonAltVisuals = new SparseIntArray(32);
static {
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(DungeonTileSheet.FLOOR, DungeonTileSheet.FLOOR_ALT_2);
}
//These tiles can stitch with water
public static List waterStitcheable = Arrays.asList(
Terrain.EMPTY, Terrain.GRASS, Terrain.EMPTY_WELL,
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.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, 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, DungeonTileSheet.CHASM_FLOOR_SP );
chasmStitcheable.put( Terrain.STATUE_SP, DungeonTileSheet.CHASM_FLOOR_SP );
//wall
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, DungeonTileSheet.CHASM_WATER );
}
private int[] map; private int[] map;
private float[] tileVariance;
public DungeonTilemap() { public DungeonTilemap() {
super( super(
Dungeon.level.tilesTex(), Dungeon.level.tilesTex(),
new TextureFilm( Dungeon.level.tilesTex(), SIZE, SIZE ) ); 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() ); map( Dungeon.level.map, Dungeon.level.width() );
instance = this; instance = this;
@ -189,26 +86,19 @@ public class DungeonTilemap extends Tilemap {
} }
} }
//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) { private int getTileVisual(int pos, int tile, boolean flat) {
int visual = defaultVisuals.get(tile); int visual = DungeonTileSheet.directVisuals.get(tile, -1);
if (tile == Terrain.WATER) { if (tile == Terrain.WATER) {
for (int i = 0; i < PathFinder.CIRCLE4.length; i++) { return DungeonTileSheet.getWaterTile(
if (waterStitcheable.contains(map[pos + PathFinder.CIRCLE4[i]])) { map[pos + PathFinder.CIRCLE4[0]],
//equivalent to: cell += 2^i map[pos + PathFinder.CIRCLE4[1]],
visual += (1 << i); map[pos + PathFinder.CIRCLE4[2]],
} map[pos + PathFinder.CIRCLE4[3]]
} );
return visual;
} else if (tile == Terrain.CHASM && pos >= mapWidth) { } else if (tile == Terrain.CHASM && pos >= mapWidth) {
return chasmStitcheable.get(map[pos - mapWidth], visual); return DungeonTileSheet.chasmStitcheable.get(map[pos - mapWidth], DungeonTileSheet.CHASM);
} }
if (!flat) { if (!flat) {
@ -230,28 +120,21 @@ public class DungeonTilemap extends Tilemap {
} else } else
visual = DungeonTileSheet.RAISED_WALL_DECO; visual = DungeonTileSheet.RAISED_WALL_DECO;
if (tileVariance[pos] > 0.5f) visual = DungeonTileSheet.getVisualWithAlts(visual, pos);
visual += 16;
if (pos % mapWidth != 0 && !wallStitcheable.contains(map[pos - 1])) if (pos % mapWidth != 0 && !DungeonTileSheet.wallStitcheable.contains(map[pos - 1]))
visual += 2; visual += 2;
if (pos % mapWidth != mapWidth-1 && !wallStitcheable.contains(map[pos + 1])) if (pos % mapWidth != mapWidth-1 && !DungeonTileSheet.wallStitcheable.contains(map[pos + 1]))
visual += 1; visual += 1;
return visual; return visual;
} }
} else {
if (visual == -1)
visual = DungeonTileSheet.directFlatVisuals.get(tile);
} }
if (tileVariance[pos] > 0.9f return DungeonTileSheet.getVisualWithAlts(visual, pos);
&& rareAltVisuals.indexOfKey(visual) >= 0){
return rareAltVisuals.get(visual);
} else if (tileVariance[pos] > 0.5f
&& commonAltVisuals.indexOfKey(visual) >= 0) {
return commonAltVisuals.get(visual);
}
return visual;
} }
public int screenToTile(int x, int y ) { public int screenToTile(int x, int y ) {
@ -310,7 +193,7 @@ public class DungeonTilemap extends Tilemap {
@Override @Override
protected boolean needsRender(int pos) { protected boolean needsRender(int pos) {
return (Level.discoverable[pos] || data[pos] == defaultVisuals.get(Terrain.CHASM)) return (Level.discoverable[pos] || data[pos] == DungeonTileSheet.CHASM)
&& data[pos] != defaultVisuals.get(Terrain.WATER); && data[pos] != DungeonTileSheet.WATER;
} }
} }

View File

@ -596,16 +596,6 @@ public abstract class Level implements Bundlable {
} }
public void destroy( int pos ) { public void destroy( int pos ) {
if (!DungeonTilemap.waterStitcheable.contains(map[pos])) {
for (int j = 0; j < PathFinder.NEIGHBOURS4.length; j++) {
if (water[pos + PathFinder.NEIGHBOURS4[j]]) {
set(pos, Terrain.WATER);
return;
}
}
}
set( pos, Terrain.EMBERS ); set( pos, Terrain.EMBERS );
} }

View File

@ -48,7 +48,6 @@ import com.shatteredpixel.shatteredpixeldungeon.items.bags.SeedPouch;
import com.shatteredpixel.shatteredpixeldungeon.items.bags.WandHolster; import com.shatteredpixel.shatteredpixeldungeon.items.bags.WandHolster;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.Potion; import com.shatteredpixel.shatteredpixeldungeon.items.potions.Potion;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTeleportation; import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTeleportation;
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
import com.shatteredpixel.shatteredpixeldungeon.levels.RegularLevel; import com.shatteredpixel.shatteredpixeldungeon.levels.RegularLevel;
import com.shatteredpixel.shatteredpixeldungeon.levels.features.Chasm; import com.shatteredpixel.shatteredpixeldungeon.levels.features.Chasm;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.Trap; import com.shatteredpixel.shatteredpixeldungeon.levels.traps.Trap;
@ -58,19 +57,20 @@ import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite;
import com.shatteredpixel.shatteredpixeldungeon.sprites.DiscardedItemSprite; import com.shatteredpixel.shatteredpixeldungeon.sprites.DiscardedItemSprite;
import com.shatteredpixel.shatteredpixeldungeon.sprites.HeroSprite; import com.shatteredpixel.shatteredpixeldungeon.sprites.HeroSprite;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite; import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite;
import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTileSheet;
import com.shatteredpixel.shatteredpixeldungeon.ui.ActionIndicator; import com.shatteredpixel.shatteredpixeldungeon.ui.ActionIndicator;
import com.shatteredpixel.shatteredpixeldungeon.ui.AttackIndicator; import com.shatteredpixel.shatteredpixeldungeon.ui.AttackIndicator;
import com.shatteredpixel.shatteredpixeldungeon.ui.Banner; import com.shatteredpixel.shatteredpixeldungeon.ui.Banner;
import com.shatteredpixel.shatteredpixeldungeon.ui.BusyIndicator; import com.shatteredpixel.shatteredpixeldungeon.ui.BusyIndicator;
import com.shatteredpixel.shatteredpixeldungeon.ui.CustomTileVisual; import com.shatteredpixel.shatteredpixeldungeon.ui.CustomTileVisual;
import com.shatteredpixel.shatteredpixeldungeon.ui.DungeonWallsTilemap; import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonWallsTilemap;
import com.shatteredpixel.shatteredpixeldungeon.ui.GameLog; import com.shatteredpixel.shatteredpixeldungeon.ui.GameLog;
import com.shatteredpixel.shatteredpixeldungeon.ui.HealthIndicator; import com.shatteredpixel.shatteredpixeldungeon.ui.HealthIndicator;
import com.shatteredpixel.shatteredpixeldungeon.ui.LootIndicator; import com.shatteredpixel.shatteredpixeldungeon.ui.LootIndicator;
import com.shatteredpixel.shatteredpixeldungeon.ui.QuickSlotButton; import com.shatteredpixel.shatteredpixeldungeon.ui.QuickSlotButton;
import com.shatteredpixel.shatteredpixeldungeon.ui.ResumeIndicator; import com.shatteredpixel.shatteredpixeldungeon.ui.ResumeIndicator;
import com.shatteredpixel.shatteredpixeldungeon.ui.StatusPane; import com.shatteredpixel.shatteredpixeldungeon.ui.StatusPane;
import com.shatteredpixel.shatteredpixeldungeon.ui.TerrainFeaturesTilemap; import com.shatteredpixel.shatteredpixeldungeon.tiles.TerrainFeaturesTilemap;
import com.shatteredpixel.shatteredpixeldungeon.ui.Toast; import com.shatteredpixel.shatteredpixeldungeon.ui.Toast;
import com.shatteredpixel.shatteredpixeldungeon.ui.Toolbar; import com.shatteredpixel.shatteredpixeldungeon.ui.Toolbar;
import com.shatteredpixel.shatteredpixeldungeon.ui.Window; import com.shatteredpixel.shatteredpixeldungeon.ui.Window;
@ -183,6 +183,8 @@ public class GameScene extends PixelScene {
}; };
terrain.add( water ); terrain.add( water );
DungeonTileSheet.setupVariance(Dungeon.level.map.length, Dungeon.seedCurDepth());
tiles = new DungeonTilemap(); tiles = new DungeonTilemap();
terrain.add( tiles ); terrain.add( tiles );

View File

@ -20,6 +20,14 @@
*/ */
package com.shatteredpixel.shatteredpixeldungeon.tiles; package com.shatteredpixel.shatteredpixeldungeon.tiles;
import android.util.SparseIntArray;
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
import com.watabou.utils.Random;
import java.util.Arrays;
import java.util.List;
public class DungeonTileSheet { public class DungeonTileSheet {
private static final int WIDTH = 16; private static final int WIDTH = 16;
@ -29,6 +37,12 @@ public class DungeonTileSheet {
return x + WIDTH*y; return x + WIDTH*y;
} }
/**********************************************************************
* Floor Tiles
************************/
private static final int GROUND = xy(1, 1); //32 slots private static final int GROUND = xy(1, 1); //32 slots
public static final int FLOOR = GROUND +0; public static final int FLOOR = GROUND +0;
public static final int FLOOR_DECO = GROUND +1; public static final int FLOOR_DECO = GROUND +1;
@ -61,10 +75,39 @@ public class DungeonTileSheet {
public static final int BOOKSHELF_ALT = GROUND +28; public static final int BOOKSHELF_ALT = GROUND +28;
/**********************************************************************
* Water Tiles
**********************************************************************/
public static final int WATER = xy(1, 3); //16 slots public static final int WATER = xy(1, 3); //16 slots
//next 15 slots are all water stitching with ground. //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.
//These tiles can stitch with water
public static List waterStitcheable = Arrays.asList(
Terrain.EMPTY, Terrain.GRASS, Terrain.EMPTY_WELL,
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.DOOR, Terrain.OPEN_DOOR, Terrain.LOCKED_DOOR
);
//+1 for ground above, +2 for ground right, +4 for ground below, +8 for ground left.
public static int getWaterTile(int top, int right, int bottom, int left){
int result = WATER;
if (waterStitcheable.contains(top)) result += 1;
if (waterStitcheable.contains(right)) result += 2;
if (waterStitcheable.contains(bottom)) result += 4;
if (waterStitcheable.contains(left)) result += 8;
return result;
}
/**********************************************************************
* Chasm Tiles
**********************************************************************/
public static final int CHASM = xy(1, 4); //16 tiles public static final int CHASM = xy(1, 4); //16 tiles
//chasm stitching visuals... //chasm stitching visuals...
@ -73,9 +116,40 @@ public class DungeonTileSheet {
public static final int CHASM_WALL = CHASM+3; public static final int CHASM_WALL = CHASM+3;
public static final int CHASM_WATER = CHASM+4; public static final int CHASM_WATER = CHASM+4;
/* //tiles that can stitch with chasms (from above), and which visual represents the stitching
These tiles present wall visuals as flat public static SparseIntArray chasmStitcheable = new SparseIntArray(32);
*/ static {
//floor
chasmStitcheable.put( Terrain.EMPTY, CHASM_FLOOR );
chasmStitcheable.put( Terrain.GRASS, CHASM_FLOOR );
chasmStitcheable.put( Terrain.EMPTY_WELL, CHASM_FLOOR );
chasmStitcheable.put( Terrain.HIGH_GRASS, CHASM_FLOOR );
chasmStitcheable.put( Terrain.EMPTY_DECO, CHASM_FLOOR );
chasmStitcheable.put( Terrain.SIGN, CHASM_FLOOR );
chasmStitcheable.put( Terrain.EMPTY_WELL, CHASM_FLOOR );
chasmStitcheable.put( Terrain.STATUE, CHASM_FLOOR );
//special floor
chasmStitcheable.put( Terrain.EMPTY_SP, CHASM_FLOOR_SP );
chasmStitcheable.put( Terrain.STATUE_SP, CHASM_FLOOR_SP );
//wall
chasmStitcheable.put( Terrain.WALL, CHASM_WALL );
chasmStitcheable.put( Terrain.DOOR, CHASM_WALL );
chasmStitcheable.put( Terrain.OPEN_DOOR, CHASM_WALL );
chasmStitcheable.put( Terrain.LOCKED_DOOR, CHASM_WALL );
chasmStitcheable.put( Terrain.WALL_DECO, CHASM_WALL );
//water
chasmStitcheable.put( Terrain.WATER, CHASM_WATER );
}
/**********************************************************************
Flat Wall Tiles
**********************************************************************/
private static final int FLAT_WALLS = xy(1, 5); //16 slots 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 = FLAT_WALLS+0;
public static final int FLAT_WALL_DECO = FLAT_WALLS+1; public static final int FLAT_WALL_DECO = FLAT_WALLS+1;
@ -91,9 +165,14 @@ public class DungeonTileSheet {
public static final int LOCKED_EXIT = FLAT_DOORS+4; public static final int LOCKED_EXIT = FLAT_DOORS+4;
/* public static SparseIntArray defaultFlatVisuals = new SparseIntArray(32);
These tiles present visuals that are raised and rendered on the lower layer (behind characters)
*/
/**********************************************************************
* Raised Wall Tiles, Lower Layer
**********************************************************************/
private static final int RAISED_WALLS = xy(1, 8); //32 slots private static final int RAISED_WALLS = xy(1, 8); //32 slots
//+1 for walls to the right, +2 for walls to the left //+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 = RAISED_WALLS+0;
@ -111,9 +190,19 @@ public class DungeonTileSheet {
//floor tile that appears on a top/bottom doorway //floor tile that appears on a top/bottom doorway
public static final int RAISED_DOOR_SIDEWAYS = RAISED_DOORS+3; 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) //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
);
/**********************************************************************
* Raised Wall Tiles, Upper Layer
**********************************************************************/
//+1 for wall right, +2 for wall right-below, +4 for wall left-below, +8 for wall left. //+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 public static final int WALLS_INTERNAL = xy(1, 12); //16 slots
@ -129,4 +218,98 @@ public class DungeonTileSheet {
public static final int DOOR_SIDEWAYS_LOCKED = WALL_OVERHANG+15; public static final int DOOR_SIDEWAYS_LOCKED = WALL_OVERHANG+15;
/**********************************************************************
* Logic for the selection of tile visuals
**********************************************************************/
//These visuals always directly represent a game tile with no stitching required
public static SparseIntArray directVisuals = new SparseIntArray(32);
static {
directVisuals.put(Terrain.EMPTY, FLOOR);
directVisuals.put(Terrain.GRASS, GRASS);
directVisuals.put(Terrain.EMPTY_WELL, EMPTY_WELL);
directVisuals.put(Terrain.ENTRANCE, ENTRANCE);
directVisuals.put(Terrain.EXIT, EXIT);
directVisuals.put(Terrain.EMBERS, EMBERS);
directVisuals.put(Terrain.PEDESTAL, PEDESTAL);
directVisuals.put(Terrain.BARRICADE, BARRICADE);
directVisuals.put(Terrain.EMPTY_SP, FLOOR_SP);
directVisuals.put(Terrain.HIGH_GRASS, HIGH_GRASS);
directVisuals.put(Terrain.SECRET_TRAP, directVisuals.get(Terrain.EMPTY));
directVisuals.put(Terrain.TRAP, directVisuals.get(Terrain.EMPTY));
directVisuals.put(Terrain.INACTIVE_TRAP, directVisuals.get(Terrain.EMPTY));
directVisuals.put(Terrain.EMPTY_DECO, FLOOR_DECO);
directVisuals.put(Terrain.LOCKED_EXIT, LOCKED_EXIT);
directVisuals.put(Terrain.UNLOCKED_EXIT, UNLOCKED_EXIT);
directVisuals.put(Terrain.SIGN, SIGN);
directVisuals.put(Terrain.WELL, WELL);
directVisuals.put(Terrain.STATUE, STATUE);
directVisuals.put(Terrain.STATUE_SP, STATUE_SP);
directVisuals.put(Terrain.BOOKSHELF, BOOKSHELF);
directVisuals.put(Terrain.ALCHEMY, ALCHEMY_POT);
}
//These visuals directly represent game tiles (no stitching) when terrain is being shown as flat
public static SparseIntArray directFlatVisuals = new SparseIntArray(32);
static {
directFlatVisuals.put(Terrain.WALL, FLAT_WALL);
directFlatVisuals.put(Terrain.DOOR, FLAT_DOOR);
directFlatVisuals.put(Terrain.OPEN_DOOR, FLAT_DOOR_OPEN);
directFlatVisuals.put(Terrain.LOCKED_DOOR, FLAT_DOOR_LOCKED);
directFlatVisuals.put(Terrain.WALL_DECO, FLAT_WALL_DECO);
directFlatVisuals.put(Terrain.SECRET_DOOR, directFlatVisuals.get(Terrain.WALL));
}
/**********************************************************************
* Logic for the selection of alternate tile visuals
**********************************************************************/
public static byte[] tileVariance;
public static void setupVariance(int size, long seed){
Random.seed( seed );
tileVariance = new byte[size];
for (int i = 0; i < tileVariance.length; i++)
tileVariance[i] = (byte)Random.Int(100);
Random.seed();
}
//These alt visuals will trigger 50% of the time (45% of the time if a rare alt is also present)
public static SparseIntArray commonAltVisuals = new SparseIntArray(32);
static {
commonAltVisuals.put(FLOOR, FLOOR_ALT_1);
commonAltVisuals.put(GRASS, GRASS_ALT);
commonAltVisuals.put(FLAT_WALL, FLAT_WALL_ALT);
commonAltVisuals.put(EMBERS, EMBERS_ALT);
commonAltVisuals.put(FLAT_WALL_DECO, FLAT_WALL_DECO_ALT);
commonAltVisuals.put(FLOOR_SP, FLOOR_SP_ALT);
commonAltVisuals.put(HIGH_GRASS, HIGH_GRASS_ALT);
commonAltVisuals.put(FLOOR_DECO, FLOOR_DECO_ALT);
commonAltVisuals.put(BOOKSHELF, BOOKSHELF_ALT);
commonAltVisuals.put(RAISED_WALL, RAISED_WALL_ALT);
commonAltVisuals.put(RAISED_WALL_DECO, RAISED_WALL_DECO_ALT);
}
//These alt visuals trigger 5% of the time (and also override common alts when they show up)
public static SparseIntArray rareAltVisuals = new SparseIntArray(32);
static {
rareAltVisuals.put(FLOOR, FLOOR_ALT_2);
}
public static int getVisualWithAlts(int visual, int pos){
if (tileVariance[pos] >= 95 && rareAltVisuals.indexOfKey(visual) >= 0)
return rareAltVisuals.get(visual);
else if (tileVariance[pos] >= 50 && commonAltVisuals.indexOfKey(visual) >= 0)
return commonAltVisuals.get(visual);
else
return visual;
}
} }

View File

@ -18,12 +18,11 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/> * along with this program. If not, see <http://www.gnu.org/licenses/>
*/ */
package com.shatteredpixel.shatteredpixeldungeon.ui; package com.shatteredpixel.shatteredpixeldungeon.tiles;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain; 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.TextureFilm;
import com.watabou.noosa.Tilemap; import com.watabou.noosa.Tilemap;
import com.watabou.utils.PathFinder; import com.watabou.utils.PathFinder;
@ -38,26 +37,13 @@ public class DungeonWallsTilemap extends Tilemap {
private static DungeonWallsTilemap instance; 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 int[] map;
private float[] tileVariance;
public DungeonWallsTilemap(){ public DungeonWallsTilemap(){
super( super(
Dungeon.level.tilesTex(), Dungeon.level.tilesTex(),
new TextureFilm( Dungeon.level.tilesTex(), SIZE, SIZE ) ); 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() ); map( Dungeon.level.map, Dungeon.level.width() );
instance = this; instance = this;
@ -96,8 +82,8 @@ public class DungeonWallsTilemap extends Tilemap {
private int getTileVisual(int pos, int tile){ private int getTileVisual(int pos, int tile){
if (wallStitcheable.contains(tile)) { if (DungeonTileSheet.wallStitcheable.contains(tile)) {
if (pos + mapWidth < size && !wallStitcheable.contains(map[pos + mapWidth])){ if (pos + mapWidth < size && !DungeonTileSheet.wallStitcheable.contains(map[pos + mapWidth])){
if (map[pos + mapWidth] == Terrain.DOOR){ if (map[pos + mapWidth] == Terrain.DOOR){
return DungeonTileSheet.DOOR_SIDEWAYS; return DungeonTileSheet.DOOR_SIDEWAYS;
@ -108,18 +94,18 @@ public class DungeonWallsTilemap extends Tilemap {
} else { } else {
//otherwise, need to stitch with right, bottom-right, bottom-left, and left. //otherwise, need to stitch with right, bottom-right, bottom-left, and left.
int visual = DungeonTileSheet.WALLS_INTERNAL; int visual = DungeonTileSheet.WALLS_INTERNAL;
if (pos % mapWidth != 0 && !wallStitcheable.contains(map[pos - 1])) if (pos % mapWidth != 0 && !DungeonTileSheet.wallStitcheable.contains(map[pos - 1]))
visual += 8; visual += 8;
if (pos % mapWidth != 0 && pos + mapWidth < size && !wallStitcheable.contains(map[pos - 1 + mapWidth])) if (pos % mapWidth != 0 && pos + mapWidth < size && !DungeonTileSheet.wallStitcheable.contains(map[pos - 1 + mapWidth]))
visual += 4; visual += 4;
if ((pos+1) % mapWidth != 0 && pos + mapWidth < size && !wallStitcheable.contains(map[pos + 1 + mapWidth])) if ((pos+1) % mapWidth != 0 && pos + mapWidth < size && !DungeonTileSheet.wallStitcheable.contains(map[pos + 1 + mapWidth]))
visual += 2; visual += 2;
if ((pos+1) % mapWidth != 0 && !wallStitcheable.contains(map[pos + 1])) if ((pos+1) % mapWidth != 0 && !DungeonTileSheet.wallStitcheable.contains(map[pos + 1]))
visual += 1; visual += 1;
return visual; return visual;
} }
} else if (Dungeon.level.insideMap(pos) && wallStitcheable.contains(map[pos+mapWidth])) { } else if (Dungeon.level.insideMap(pos) && DungeonTileSheet.wallStitcheable.contains(map[pos+mapWidth])) {
int visual; int visual;
if (map[pos] == Terrain.DOOR || map[pos] == Terrain.LOCKED_DOOR) if (map[pos] == Terrain.DOOR || map[pos] == Terrain.LOCKED_DOOR)
@ -129,9 +115,9 @@ public class DungeonWallsTilemap extends Tilemap {
else else
visual = DungeonTileSheet.WALL_OVERHANG; visual = DungeonTileSheet.WALL_OVERHANG;
if (!wallStitcheable.contains(map[pos - 1 + mapWidth])) if (!DungeonTileSheet.wallStitcheable.contains(map[pos - 1 + mapWidth]))
visual += 2; visual += 2;
if (!wallStitcheable.contains(map[pos + 1 + mapWidth])) if (!DungeonTileSheet.wallStitcheable.contains(map[pos + 1 + mapWidth]))
visual += 1; visual += 1;
return visual; return visual;
@ -157,6 +143,6 @@ public class DungeonWallsTilemap extends Tilemap {
@Override @Override
protected boolean needsRender(int pos) { protected boolean needsRender(int pos) {
return data[pos] != -1; return data[pos] != -1 && Level.discoverable[pos];
} }
} }

View File

@ -18,7 +18,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/> * along with this program. If not, see <http://www.gnu.org/licenses/>
*/ */
package com.shatteredpixel.shatteredpixeldungeon.ui; package com.shatteredpixel.shatteredpixeldungeon.tiles;
import com.shatteredpixel.shatteredpixeldungeon.Assets; import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
@ -29,15 +29,11 @@ import com.shatteredpixel.shatteredpixeldungeon.plants.Plant;
import com.watabou.noosa.Image; import com.watabou.noosa.Image;
import com.watabou.noosa.TextureFilm; import com.watabou.noosa.TextureFilm;
import com.watabou.noosa.Tilemap; import com.watabou.noosa.Tilemap;
import com.watabou.noosa.tweeners.AlphaTweener;
import com.watabou.noosa.tweeners.ScaleTweener; import com.watabou.noosa.tweeners.ScaleTweener;
import com.watabou.utils.PathFinder; import com.watabou.utils.PathFinder;
import com.watabou.utils.PointF; import com.watabou.utils.PointF;
import com.watabou.utils.Random;
import com.watabou.utils.SparseArray; import com.watabou.utils.SparseArray;
import static com.shatteredpixel.shatteredpixeldungeon.DungeonTilemap.tileToWorld;
//TODO add in a proper set of vfx for plants growing/withering, grass burning, discovering traps //TODO add in a proper set of vfx for plants growing/withering, grass burning, discovering traps
public class TerrainFeaturesTilemap extends Tilemap { public class TerrainFeaturesTilemap extends Tilemap {
@ -46,7 +42,6 @@ public class TerrainFeaturesTilemap extends Tilemap {
private static TerrainFeaturesTilemap instance; private static TerrainFeaturesTilemap instance;
private int[] map; private int[] map;
private float[] tileVariance;
private SparseArray<Plant> plants; private SparseArray<Plant> plants;
private SparseArray<Trap> traps; private SparseArray<Trap> traps;
@ -57,12 +52,6 @@ public class TerrainFeaturesTilemap extends Tilemap {
this.plants = plants; this.plants = plants;
this.traps = traps; this.traps = traps;
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() ); map( Dungeon.level.map, Dungeon.level.width() );
instance = this; instance = this;
@ -113,11 +102,11 @@ public class TerrainFeaturesTilemap extends Tilemap {
} }
if (tile == Terrain.HIGH_GRASS){ if (tile == Terrain.HIGH_GRASS){
return 9 + 16*((Dungeon.depth-1)/5) + (tileVariance[pos] > 0.5f ? 1 : 0); return 9 + 16*((Dungeon.depth-1)/5) + (DungeonTileSheet.tileVariance[pos] >= 50 ? 1 : 0);
} else if (tile == Terrain.GRASS) { } else if (tile == Terrain.GRASS) {
return 11 + 16*((Dungeon.depth-1)/5) + (tileVariance[pos] > 0.5f ? 1 : 0); return 11 + 16*((Dungeon.depth-1)/5) + (DungeonTileSheet.tileVariance[pos] >= 50 ? 1 : 0);
} else if (tile == Terrain.EMBERS) { } else if (tile == Terrain.EMBERS) {
return 13 + (tileVariance[pos] > 0.5f ? 1 : 0); return 13 + (DungeonTileSheet.tileVariance[pos] >= 50 ? 1 : 0);
} }
return -1; return -1;

View File

@ -22,7 +22,7 @@ package com.shatteredpixel.shatteredpixeldungeon.windows;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.plants.Plant; import com.shatteredpixel.shatteredpixeldungeon.plants.Plant;
import com.shatteredpixel.shatteredpixeldungeon.ui.TerrainFeaturesTilemap; import com.shatteredpixel.shatteredpixeldungeon.tiles.TerrainFeaturesTilemap;
public class WndInfoPlant extends WndTitledMessage { public class WndInfoPlant extends WndTitledMessage {

View File

@ -23,7 +23,7 @@ package com.shatteredpixel.shatteredpixeldungeon.windows;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.Trap; import com.shatteredpixel.shatteredpixeldungeon.levels.traps.Trap;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.ui.TerrainFeaturesTilemap; import com.shatteredpixel.shatteredpixeldungeon.tiles.TerrainFeaturesTilemap;
public class WndInfoTrap extends WndTitledMessage { public class WndInfoTrap extends WndTitledMessage {