diff --git a/core/src/main/assets/environment/tiles_caves.png b/core/src/main/assets/environment/tiles_caves.png index 578462edd..023e39d51 100644 Binary files a/core/src/main/assets/environment/tiles_caves.png and b/core/src/main/assets/environment/tiles_caves.png differ diff --git a/core/src/main/assets/messages/levels/levels.properties b/core/src/main/assets/messages/levels/levels.properties index 907a53b3f..da5910e6d 100644 --- a/core/src/main/assets/messages/levels/levels.properties +++ b/core/src/main/assets/messages/levels/levels.properties @@ -222,6 +222,11 @@ levels.level.statue_desc=Someone wanted to adorn this place, but failed, obvious levels.level.alchemy_desc=This pot is filled with magical water. Items can be mixed into the pot to create something new! levels.level.empty_well_desc=The well has run dry. +levels.mininglevel.crystal_name=Crystal spike +levels.mininglevel.boulder_name=Boulder +levels.mininglevel.crystal_desc=There is a large and colorful crystal outcropping here. Crystal is fragile, and can easily be broken with a pickaxe, or will break if something is mined next to it. +levels.mininglevel.boulder_desc=There is a large boulder is blocking the way. It should be fairly easy to break with a pickaxe. + levels.prisonlevel.water_name=Dark cold water levels.prisonlevel.empty_deco_desc=There are old blood stains on the floor. levels.prisonlevel.bookshelf_desc=This is probably a vestige of a prison library. Might it burn? diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Hero.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Hero.java index 40fad1dad..dfa3b9c08 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Hero.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Hero.java @@ -74,6 +74,7 @@ import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter; import com.shatteredpixel.shatteredpixeldungeon.effects.CheckedCell; import com.shatteredpixel.shatteredpixeldungeon.effects.Speck; import com.shatteredpixel.shatteredpixeldungeon.effects.SpellSprite; +import com.shatteredpixel.shatteredpixeldungeon.effects.Splash; import com.shatteredpixel.shatteredpixeldungeon.items.Amulet; import com.shatteredpixel.shatteredpixeldungeon.items.Ankh; import com.shatteredpixel.shatteredpixeldungeon.items.Dewdrop; @@ -163,8 +164,10 @@ import com.shatteredpixel.shatteredpixeldungeon.windows.WndResurrect; import com.shatteredpixel.shatteredpixeldungeon.windows.WndTradeItem; import com.watabou.noosa.Game; import com.watabou.noosa.audio.Sample; +import com.watabou.noosa.tweeners.Delayer; import com.watabou.utils.Bundle; import com.watabou.utils.Callback; +import com.watabou.utils.ColorMath; import com.watabou.utils.GameMath; import com.watabou.utils.PathFinder; import com.watabou.utils.Point; @@ -1144,7 +1147,10 @@ public class Hero extends Char { public boolean actMine(HeroAction.Mine action){ if (Dungeon.level.adjacent(pos, action.dst)){ path = null; - if ((Dungeon.level.map[action.dst] == Terrain.WALL || Dungeon.level.map[action.dst] == Terrain.WALL_DECO) + if ((Dungeon.level.map[action.dst] == Terrain.WALL + || Dungeon.level.map[action.dst] == Terrain.WALL_DECO + || Dungeon.level.map[action.dst] == Terrain.MINE_CRYSTAL + || Dungeon.level.map[action.dst] == Terrain.MINE_BOULDER) && Dungeon.level.insideMap(action.dst)){ sprite.attack(action.dst, new Callback() { @Override @@ -1157,16 +1163,30 @@ public class Hero extends Char { } else { Dungeon.level.drop( gold, pos ).sprite.drop(); } + PixelScene.shake(0.5f, 0.5f); CellEmitter.center( action.dst ).burst( Speck.factory( Speck.STAR ), 7 ); Sample.INSTANCE.play( Assets.Sounds.EVOKE ); - } else { + Level.set( action.dst, Terrain.EMPTY_DECO ); + + } else if (Dungeon.level.map[action.dst] == Terrain.WALL){ + //TODO inc. hunger by 5 + PixelScene.shake(0.5f, 0.5f); CellEmitter.get( action.dst ).burst( Speck.factory( Speck.ROCK ), 2 ); Sample.INSTANCE.play( Assets.Sounds.MINE ); + Level.set( action.dst, Terrain.EMPTY_DECO ); + + } else if (Dungeon.level.map[action.dst] == Terrain.MINE_CRYSTAL){ + Splash.at(action.dst, 0xFFFFFF, 5); //TODO match color? + Sample.INSTANCE.play( Assets.Sounds.SHATTER ); + Level.set( action.dst, Terrain.EMPTY ); + + } else if (Dungeon.level.map[action.dst] == Terrain.MINE_BOULDER){ + //TODO inc. hunger by 1 + Splash.at(action.dst, ColorMath.random( 0x444444, 0x777766 ), 5); + Sample.INSTANCE.play( Assets.Sounds.MINE, 0.6f ); + Level.set( action.dst, Terrain.EMPTY ); } - PixelScene.shake(0.5f, 0.5f); - - Level.set( action.dst, Terrain.EMPTY_DECO ); for (int i : PathFinder.NEIGHBOURS9) { Dungeon.level.discoverable[action.dst + i] = true; } @@ -1174,9 +1194,41 @@ public class Hero extends Char { GameScene.updateMap( action.dst+i ); } - Dungeon.observe(); + boolean crystalAdjacent = false; + for (int i : PathFinder.NEIGHBOURS8) { + if (Dungeon.level.map[action.dst + i] == Terrain.MINE_CRYSTAL){ + crystalAdjacent = true; + break; + } + } - spendAndNext(TICK); + if (crystalAdjacent){ + sprite.parent.add(new Delayer(0.2f){ + @Override + protected void onComplete() { + boolean broke = false; + for (int i : PathFinder.NEIGHBOURS8) { + if (Dungeon.level.map[action.dst+i] == Terrain.MINE_CRYSTAL){ + Splash.at(action.dst+i, 0xFFFFFF, 5); + Level.set( action.dst+i, Terrain.EMPTY ); + broke = true; + } + } + if (broke){ + Sample.INSTANCE.play( Assets.Sounds.SHATTER ); + } + + for (int i : PathFinder.NEIGHBOURS9) { + GameScene.updateMap( action.dst+i ); + } + spendAndNext(TICK); + } + }); + } else { + spendAndNext(TICK); + } + + Dungeon.observe(); } }); } else { @@ -1676,7 +1728,10 @@ public class Hero extends Char { //TODO perhaps only trigger this if hero is already adjacent? reducing mistaps } else if (Dungeon.level instanceof MiningLevel && belongings.getItem(Pickaxe.class) != null && - (Dungeon.level.map[cell] == Terrain.WALL || Dungeon.level.map[cell] == Terrain.WALL_DECO)){ + (Dungeon.level.map[cell] == Terrain.WALL + || Dungeon.level.map[cell] == Terrain.WALL_DECO + || Dungeon.level.map[cell] == Terrain.MINE_CRYSTAL + || Dungeon.level.map[cell] == Terrain.MINE_BOULDER)){ curAction = new HeroAction.Mine( cell ); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/MiningLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/MiningLevel.java index 3b535bbac..1e012570d 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/MiningLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/MiningLevel.java @@ -120,6 +120,30 @@ public class MiningLevel extends CavesLevel { } } + @Override + public String tileName( int tile ) { + switch (tile) { + case Terrain.MINE_CRYSTAL: + return Messages.get(MiningLevel.class, "crystal_name"); + case Terrain.MINE_BOULDER: + return Messages.get(MiningLevel.class, "boulder_name"); + default: + return super.tileName( tile ); + } + } + + @Override + public String tileDesc( int tile ) { + switch (tile) { + case Terrain.MINE_CRYSTAL: + return Messages.get(MiningLevel.class, "crystal_desc"); + case Terrain.MINE_BOULDER: + return Messages.get(MiningLevel.class, "boulder_desc"); + default: + return super.tileDesc( tile ); + } + } + @Override public Group addVisuals() { super.addVisuals(); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/Terrain.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/Terrain.java index df7356da4..34b79bb4c 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/Terrain.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/Terrain.java @@ -58,6 +58,10 @@ public class Terrain { public static final int CUSTOM_DECO = 23; //invisible decoration that will also be a custom visual, re-uses the old terrain ID for signs public static final int STATUE = 25; public static final int STATUE_SP = 26; + //These decorations are environment-specific + //33 and 34 are reserved for future statue-like decorations + public static final int MINE_CRYSTAL = 35; + public static final int MINE_BOULDER = 36; public static final int WATER = 29; 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 c8959d207..1704c7e44 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/tiles/DungeonTerrainTilemap.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/tiles/DungeonTerrainTilemap.java @@ -70,6 +70,12 @@ public class DungeonTerrainTilemap extends DungeonTilemap { return DungeonTileSheet.RAISED_STATUE; } else if (tile == Terrain.STATUE_SP) { return DungeonTileSheet.RAISED_STATUE_SP; + } else if (tile == Terrain.MINE_CRYSTAL) { + return DungeonTileSheet.getVisualWithAlts( + DungeonTileSheet.RAISED_MINE_CRYSTAL, + pos); + } else if (tile == Terrain.MINE_BOULDER) { + return DungeonTileSheet.RAISED_MINE_BOULDER; } else if (tile == Terrain.ALCHEMY) { return DungeonTileSheet.RAISED_ALCHEMY_POT; } else if (tile == Terrain.BARRICADE) { 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 ea9e936ae..1f9dfe19c 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/tiles/DungeonTileSheet.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/tiles/DungeonTileSheet.java @@ -96,6 +96,8 @@ public class DungeonTileSheet { chasmStitcheable.put( Terrain.BOOKSHELF, CHASM_FLOOR ); chasmStitcheable.put( Terrain.BARRICADE, CHASM_FLOOR ); chasmStitcheable.put( Terrain.PEDESTAL, CHASM_FLOOR ); + chasmStitcheable.put( Terrain.MINE_BOULDER, CHASM_FLOOR ); + chasmStitcheable.put( Terrain.MINE_CRYSTAL, CHASM_FLOOR ); //special floor chasmStitcheable.put( Terrain.EMPTY_SP, CHASM_FLOOR_SP ); @@ -132,6 +134,7 @@ public class DungeonTileSheet { Terrain.BARRICADE, Terrain.HIGH_GRASS, Terrain.FURROWED_GRASS, Terrain.SECRET_TRAP, Terrain.TRAP, Terrain.INACTIVE_TRAP, Terrain.EMPTY_DECO, Terrain.CUSTOM_DECO, Terrain.WELL, Terrain.STATUE, Terrain.ALCHEMY, + Terrain.MINE_CRYSTAL, Terrain.MINE_BOULDER, Terrain.DOOR, Terrain.OPEN_DOOR, Terrain.LOCKED_DOOR, Terrain.CRYSTAL_DOOR )); @@ -182,6 +185,11 @@ public class DungeonTileSheet { public static final int FLAT_STATUE = FLAT_OTHER+8; public static final int FLAT_STATUE_SP = FLAT_OTHER+9; + public static final int FLAT_MINE_CRYSTAL = FLAT_OTHER+12; + public static final int FLAT_MINE_CRYSTAL_ALT = FLAT_OTHER+13; + public static final int FLAT_MINE_CRYSTAL_ALT_2 = FLAT_OTHER+14; + public static final int FLAT_MINE_BOULDER = FLAT_OTHER+15; + /********************************************************************** * Raised Tiles, Lower Layer @@ -273,6 +281,11 @@ public class DungeonTileSheet { public static final int RAISED_STATUE = RAISED_OTHER+8; public static final int RAISED_STATUE_SP = RAISED_OTHER+9; + public static final int RAISED_MINE_CRYSTAL = RAISED_OTHER+12; + public static final int RAISED_MINE_CRYSTAL_ALT = RAISED_OTHER+13; + public static final int RAISED_MINE_CRYSTAL_ALT_2=RAISED_OTHER+14; + public static final int RAISED_MINE_BOULDER = RAISED_OTHER+15; + /********************************************************************** * Raised Tiles, Upper Layer @@ -348,6 +361,11 @@ public class DungeonTileSheet { public static final int STATUE_OVERHANG = OTHER_OVERHANG+8; public static final int STATUE_SP_OVERHANG = OTHER_OVERHANG+9; + public static final int MINE_CRYSTAL_OVERHANG = OTHER_OVERHANG+12; + public static final int MINE_CRYSTAL_OVERHANG_ALT = OTHER_OVERHANG+13; + public static final int MINE_CRYSTAL_OVERHANG_ALT_2 = OTHER_OVERHANG+14; + public static final int MINE_BOULDER_OVERHANG = OTHER_OVERHANG+15; + public static final int HIGH_GRASS_UNDERHANG = OTHER_OVERHANG+18; public static final int FURROWED_UNDERHANG = OTHER_OVERHANG+19; @@ -399,6 +417,9 @@ public class DungeonTileSheet { directFlatVisuals.put(Terrain.STATUE, FLAT_STATUE); directFlatVisuals.put(Terrain.STATUE_SP, FLAT_STATUE_SP); + directFlatVisuals.put(Terrain.MINE_CRYSTAL, FLAT_MINE_CRYSTAL); + directFlatVisuals.put(Terrain.MINE_BOULDER, FLAT_MINE_BOULDER); + directFlatVisuals.put(Terrain.SECRET_DOOR, directFlatVisuals.get(Terrain.WALL)); } @@ -434,6 +455,7 @@ public class DungeonTileSheet { commonAltVisuals.put(FLAT_BOOKSHELF, FLAT_BOOKSHELF_ALT); commonAltVisuals.put(FLAT_HIGH_GRASS, FLAT_HIGH_GRASS_ALT); commonAltVisuals.put(FLAT_FURROWED_GRASS, FLAT_FURROWED_ALT); + commonAltVisuals.put(FLAT_MINE_CRYSTAL, FLAT_MINE_CRYSTAL_ALT); commonAltVisuals.put(RAISED_WALL, RAISED_WALL_ALT); commonAltVisuals.put(RAISED_WALL_DECO, RAISED_WALL_DECO_ALT); @@ -443,14 +465,19 @@ public class DungeonTileSheet { commonAltVisuals.put(RAISED_FURROWED_GRASS, RAISED_FURROWED_ALT); commonAltVisuals.put(HIGH_GRASS_OVERHANG, HIGH_GRASS_OVERHANG_ALT); commonAltVisuals.put(FURROWED_OVERHANG, FURROWED_OVERHANG_ALT); + commonAltVisuals.put(RAISED_MINE_CRYSTAL, RAISED_MINE_CRYSTAL_ALT); commonAltVisuals.put(HIGH_GRASS_UNDERHANG, HIGH_GRASS_UNDERHANG_ALT); commonAltVisuals.put(FURROWED_UNDERHANG, FURROWED_UNDERHANG_ALT); + commonAltVisuals.put(MINE_CRYSTAL_OVERHANG, MINE_CRYSTAL_OVERHANG_ALT); } //These alt visuals trigger 5% of the time (and also override common alts when they show up) public static SparseArray rareAltVisuals = new SparseArray<>(); static { - rareAltVisuals.put(FLOOR, FLOOR_ALT_2); + rareAltVisuals.put(FLOOR, FLOOR_ALT_2); + rareAltVisuals.put(FLAT_MINE_CRYSTAL, FLAT_MINE_CRYSTAL_ALT_2); + rareAltVisuals.put(RAISED_MINE_CRYSTAL, RAISED_MINE_CRYSTAL_ALT_2); + rareAltVisuals.put(MINE_CRYSTAL_OVERHANG, MINE_CRYSTAL_OVERHANG_ALT_2); } public static int getVisualWithAlts(int visual, int pos){ 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 750fc9a66..ac5045fd3 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/tiles/DungeonWallsTilemap.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/tiles/DungeonWallsTilemap.java @@ -84,6 +84,10 @@ public class DungeonWallsTilemap extends DungeonTilemap { return DungeonTileSheet.STATUE_OVERHANG; } else if (pos + mapWidth < size && map[pos+mapWidth] == Terrain.STATUE_SP){ return DungeonTileSheet.STATUE_SP_OVERHANG; + } else if (pos + mapWidth < size && map[pos+mapWidth] == Terrain.MINE_CRYSTAL){ + return DungeonTileSheet.getVisualWithAlts(DungeonTileSheet.MINE_CRYSTAL_OVERHANG, pos + mapWidth); + } else if (pos + mapWidth < size && map[pos+mapWidth] == Terrain.MINE_BOULDER){ + return DungeonTileSheet.MINE_BOULDER_OVERHANG; } else if (pos + mapWidth < size && map[pos+mapWidth] == Terrain.ALCHEMY){ return DungeonTileSheet.ALCHEMY_POT_OVERHANG; } else if (pos + mapWidth < size && map[pos+mapWidth] == Terrain.BARRICADE){