v2.1.3: added basic mining and sub-floor functionality!
This commit is contained in:
BIN
core/src/main/assets/sounds/mine.mp3
Normal file
BIN
core/src/main/assets/sounds/mine.mp3
Normal file
Binary file not shown.
@@ -206,6 +206,7 @@ public class Assets {
|
||||
public static final String CHAINS = "sounds/chains.mp3";
|
||||
public static final String SCAN = "sounds/scan.mp3";
|
||||
public static final String SHEEP = "sounds/sheep.mp3";
|
||||
public static final String MINE = "sounds/mine.mp3";
|
||||
|
||||
public static final String[] all = new String[]{
|
||||
CLICK, BADGE, GOLD,
|
||||
@@ -218,7 +219,7 @@ public class Assets {
|
||||
DESCEND, EAT, READ, LULLABY, DRINK, SHATTER, ZAP, LIGHTNING, LEVELUP, DEATH,
|
||||
CHALLENGE, CURSED, TRAP, EVOKE, TOMB, ALERT, MELD, BOSS, BLAST, PLANT, RAY, BEACON,
|
||||
TELEPORT, CHARMS, MASTERY, PUFF, ROCKS, BURNING, FALLING, GHOST, SECRET, BONES,
|
||||
BEE, DEGRADE, MIMIC, DEBUFF, CHARGEUP, GAS, CHAINS, SCAN, SHEEP
|
||||
BEE, DEGRADE, MIMIC, DEBUFF, CHARGEUP, GAS, CHAINS, SCAN, SHEEP, MINE
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -58,6 +58,7 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.HallsBossLevel;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.HallsLevel;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.LastLevel;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.MiningLevel;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.PrisonBossLevel;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.PrisonLevel;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.RegularLevel;
|
||||
@@ -338,6 +339,17 @@ public class Dungeon {
|
||||
default:
|
||||
level = new DeadEndLevel();
|
||||
}
|
||||
} else if (branch == 1) {
|
||||
switch (depth) {
|
||||
case 11:
|
||||
case 12:
|
||||
case 13:
|
||||
case 14:
|
||||
level = new MiningLevel();
|
||||
break;
|
||||
default:
|
||||
level = new DeadEndLevel();
|
||||
}
|
||||
} else {
|
||||
level = new DeadEndLevel();
|
||||
}
|
||||
|
||||
@@ -108,6 +108,8 @@ import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfExperience
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfHealing;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.potions.elixirs.ElixirOfMight;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.potions.exotic.PotionOfDivineInspiration;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.quest.DarkGold;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.quest.Pickaxe;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfAccuracy;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfEvasion;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfForce;
|
||||
@@ -133,6 +135,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.MissileWea
|
||||
import com.shatteredpixel.shatteredpixeldungeon.journal.Document;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.journal.Notes;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.MiningLevel;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.features.Chasm;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.features.LevelTransition;
|
||||
@@ -804,7 +807,10 @@ public class Hero extends Char {
|
||||
} else if (curAction instanceof HeroAction.Unlock) {
|
||||
actResult = actUnlock((HeroAction.Unlock) curAction);
|
||||
|
||||
} else if (curAction instanceof HeroAction.LvlTransition) {
|
||||
} else if (curAction instanceof HeroAction.Mine) {
|
||||
actResult = actMine( (HeroAction.Mine)curAction );
|
||||
|
||||
}else if (curAction instanceof HeroAction.LvlTransition) {
|
||||
actResult = actTransition( (HeroAction.LvlTransition)curAction );
|
||||
|
||||
} else if (curAction instanceof HeroAction.Attack) {
|
||||
@@ -1132,6 +1138,50 @@ public class Hero extends Char {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean actMine(HeroAction.Mine action){
|
||||
if (Dungeon.level.adjacent(pos, action.dst)
|
||||
&& (Dungeon.level.map[action.dst] == Terrain.WALL || Dungeon.level.map[action.dst] == Terrain.WALL_DECO)
|
||||
&& Dungeon.level.insideMap(action.dst)){
|
||||
sprite.attack(action.dst, new Callback() {
|
||||
@Override
|
||||
public void call() {
|
||||
|
||||
if (Dungeon.level.map[action.dst] == Terrain.WALL_DECO){
|
||||
DarkGold gold = new DarkGold();
|
||||
if (gold.doPickUp( Dungeon.hero )) {
|
||||
GLog.i( Messages.capitalize(Messages.get(Dungeon.hero, "you_now_have", gold.name())) );
|
||||
} else {
|
||||
Dungeon.level.drop( gold, pos ).sprite.drop();
|
||||
}
|
||||
CellEmitter.center( action.dst ).burst( Speck.factory( Speck.STAR ), 7 );
|
||||
Sample.INSTANCE.play( Assets.Sounds.EVOKE );
|
||||
} else {
|
||||
CellEmitter.get( action.dst ).burst( Speck.factory( Speck.ROCK ), 2 );
|
||||
Sample.INSTANCE.play( Assets.Sounds.MINE );
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
for (int i : PathFinder.NEIGHBOURS9) {
|
||||
GameScene.updateMap( action.dst+i );
|
||||
}
|
||||
|
||||
Dungeon.observe();
|
||||
|
||||
spendAndNext(TICK);
|
||||
ready();
|
||||
}
|
||||
});
|
||||
return false;
|
||||
}
|
||||
ready();
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean actTransition(HeroAction.LvlTransition action ) {
|
||||
int stairs = action.dst;
|
||||
@@ -1613,6 +1663,13 @@ public class Hero extends Char {
|
||||
curAction = new HeroAction.Attack( ch );
|
||||
}
|
||||
|
||||
//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)){
|
||||
|
||||
curAction = new HeroAction.Mine( cell );
|
||||
|
||||
} else if (heap != null
|
||||
//moving to an item doesn't auto-pickup when enemies are near...
|
||||
&& (visibleEnemies.size() == 0 || cell == pos ||
|
||||
|
||||
@@ -69,6 +69,12 @@ public class HeroAction {
|
||||
this.dst = stairs;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Mine extends HeroAction {
|
||||
public Mine( int wall ) {
|
||||
this.dst = wall;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Alchemy extends HeroAction {
|
||||
public Alchemy( int pot ) {
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2023 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.levels;
|
||||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Bones;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.features.LevelTransition;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.CaveRoom;
|
||||
|
||||
public class MiningLevel extends Level {
|
||||
|
||||
{
|
||||
color1 = 0x534f3e;
|
||||
color2 = 0xb9d661;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String tilesTex() {
|
||||
return Assets.Environment.TILES_CAVES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String waterTex() {
|
||||
return Assets.Environment.WATER_CAVES;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean build() {
|
||||
|
||||
//a few niceties are needed here before putting this out, things like water, short grass
|
||||
// tile deco, and a pause to hunger/regen
|
||||
|
||||
setSize(32, 32);
|
||||
|
||||
CaveRoom c = new CaveRoom();
|
||||
c.set(1, 1, 31, 31);
|
||||
c.paint(this);
|
||||
|
||||
Painter.fill(this, 15, 15, 3, 3, Terrain.EMPTY);
|
||||
int entrance = 16 * width() + 16;
|
||||
|
||||
transitions.add(new LevelTransition(this,
|
||||
entrance,
|
||||
LevelTransition.Type.BRANCH_ENTRANCE,
|
||||
Dungeon.depth,
|
||||
0,
|
||||
LevelTransition.Type.BRANCH_EXIT));
|
||||
|
||||
map[entrance] = Terrain.ENTRANCE;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mob createMob() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createMobs() {
|
||||
}
|
||||
|
||||
public Actor addRespawner() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createItems() {
|
||||
Item item = Bones.get();
|
||||
if (item != null) {
|
||||
drop( item, entrance()-width() ).setHauntedIfCursed().type = Heap.Type.REMAINS;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int randomRespawnCell( Char ch ) {
|
||||
return entrance()-width();
|
||||
}
|
||||
}
|
||||
@@ -21,10 +21,12 @@
|
||||
|
||||
package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard;
|
||||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Blacksmith;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.Generator;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.features.LevelTransition;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.BurningTrap;
|
||||
import com.watabou.utils.Point;
|
||||
@@ -72,6 +74,22 @@ public class BlacksmithRoom extends StandardRoom {
|
||||
} while (level.heaps.get( npc.pos ) != null);
|
||||
level.mobs.add( npc );
|
||||
|
||||
// TODO need to add some better visuals here (even just a simple custom asset)
|
||||
Random.pushGenerator(Dungeon.seedCurDepth()+1);
|
||||
int entrancePos;
|
||||
do {
|
||||
entrancePos = level.pointToCell(random( 2 ));
|
||||
} while (level.heaps.get( npc.pos ) != null || entrancePos == npc.pos);
|
||||
Random.popGenerator();
|
||||
|
||||
level.transitions.add(new LevelTransition(level,
|
||||
entrancePos,
|
||||
LevelTransition.Type.BRANCH_EXIT,
|
||||
Dungeon.depth,
|
||||
Dungeon.branch+1,
|
||||
LevelTransition.Type.BRANCH_ENTRANCE));
|
||||
Painter.set(level, entrancePos, Terrain.EXIT);
|
||||
|
||||
for(Point p : getPoints()) {
|
||||
int cell = level.pointToCell(p);
|
||||
if (level.map[cell] == Terrain.TRAP){
|
||||
|
||||
@@ -60,6 +60,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTeleportat
|
||||
import com.shatteredpixel.shatteredpixeldungeon.journal.Document;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.journal.Journal;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.MiningLevel;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.RegularLevel;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room;
|
||||
@@ -428,6 +429,9 @@ public class GameScene extends PixelScene {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (Dungeon.level instanceof MiningLevel){
|
||||
add(new WndStory(Messages.get(this, "blacksmith_quest_window_title") + ":\n\n" + Messages.get(this, "blacksmith_quest_window")).setDelays(0.6f, 1.4f));
|
||||
}
|
||||
if (Dungeon.hero.isAlive()) {
|
||||
Badges.validateNoKilling();
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ package com.shatteredpixel.shatteredpixeldungeon.tiles;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.HallsBossLevel;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.MiningLevel;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
|
||||
import com.watabou.noosa.TextureFilm;
|
||||
import com.watabou.noosa.Tilemap;
|
||||
@@ -107,9 +108,10 @@ public class WallBlockingTilemap extends Tilemap {
|
||||
//- none of the remaining 5 neighbour cells are both not a wall and visible
|
||||
|
||||
//if all 3 above are wall we can shortcut and just clear the cell
|
||||
//unless one or more is a shelf, then we have to just block none
|
||||
//unless one or more is a shelf, or we can mine, then we have to just block none
|
||||
if (wall(cell - 1 - mapWidth) && wall(cell - mapWidth) && wall(cell + 1 - mapWidth)){
|
||||
if (shelf(cell - 1 - mapWidth) || shelf(cell - mapWidth) || shelf(cell + 1 - mapWidth)){
|
||||
if (shelf(cell - 1 - mapWidth) || shelf(cell - mapWidth)
|
||||
|| shelf(cell + 1 - mapWidth) || Dungeon.level instanceof MiningLevel){
|
||||
curr = BLOCK_NONE;
|
||||
} else {
|
||||
curr = CLEARED;
|
||||
|
||||
Reference in New Issue
Block a user