v0.8.0: roughly implemented new DK level

This commit is contained in:
Evan Debenham 2020-01-30 19:12:13 -05:00
parent e24eca94b4
commit 48471bbfef
12 changed files with 633 additions and 34 deletions

View File

@ -133,6 +133,12 @@ public class Rect {
public boolean inside( Point p ) {
return p.x >= left && p.x < right && p.y >= top && p.y < bottom;
}
public Point center() {
return new Point(
(left + right) / 2 + (((right - left) % 2) == 0 ? Random.Int( 2 ) : 0),
(top + bottom) / 2 + (((bottom - top) % 2) == 0 ? Random.Int( 2 ) : 0) );
}
public Rect shrink( int d ) {
return new Rect( left + d, top + d, right - d, bottom - d );

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -135,6 +135,7 @@ public class Assets {
public static final String PRISON_EXIT_OLD = "custom_tiles/prison_exit_old.png";
public static final String PRISON_EXIT_NEW = "custom_tiles/prison_exit_new.png";
public static final String CAVES_BOSS = "custom_tiles/caves_boss.png";
public static final String CITY_BOSS = "custom_tiles/city_boss.png";
public static final String BUFFS_SMALL = "buffs.png";
public static final String BUFFS_LARGE = "large_buffs.png";

View File

@ -44,7 +44,6 @@ import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfUpgrade;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.SpiritBow;
import com.shatteredpixel.shatteredpixeldungeon.journal.Notes;
import com.shatteredpixel.shatteredpixeldungeon.levels.CavesLevel;
import com.shatteredpixel.shatteredpixeldungeon.levels.CityBossLevel;
import com.shatteredpixel.shatteredpixeldungeon.levels.CityLevel;
import com.shatteredpixel.shatteredpixeldungeon.levels.DeadEndLevel;
import com.shatteredpixel.shatteredpixeldungeon.levels.HallsBossLevel;
@ -53,6 +52,7 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.LastLevel;
import com.shatteredpixel.shatteredpixeldungeon.levels.LastShopLevel;
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
import com.shatteredpixel.shatteredpixeldungeon.levels.NewCavesBossLevel;
import com.shatteredpixel.shatteredpixeldungeon.levels.NewCityBossLevel;
import com.shatteredpixel.shatteredpixeldungeon.levels.NewPrisonBossLevel;
import com.shatteredpixel.shatteredpixeldungeon.levels.PrisonLevel;
import com.shatteredpixel.shatteredpixeldungeon.levels.SewerBossLevel;
@ -272,10 +272,22 @@ public class Dungeon {
level = new CityLevel();
break;
case 20:
level = new CityBossLevel();
level = new NewCityBossLevel();
break;
case 21:
level = new LastShopLevel();
//logic for old city boss levels, need to spawn a shop on floor 21
try {
Bundle bundle = FileUtils.bundleFromFile(GamesInProgress.depthFile(GamesInProgress.curSlot, 20));
Class cls = bundle.getBundle(LEVEL).getClass("__className");
if (cls == NewCityBossLevel.class) {
level = new HallsLevel();
} else {
level = new LastShopLevel();
}
} catch (Exception e) {
ShatteredPixelDungeon.reportException(e);
level = new HallsLevel();
}
break;
case 22:
case 23:

View File

@ -132,6 +132,9 @@ public class ShatteredPixelDungeon extends Game {
com.watabou.utils.Bundle.addAlias(
com.shatteredpixel.shatteredpixeldungeon.levels.OldCavesBossLevel.class,
"com.shatteredpixel.shatteredpixeldungeon.levels.CavesBossLevel" );
com.watabou.utils.Bundle.addAlias(
com.shatteredpixel.shatteredpixeldungeon.levels.OldCityBossLevel.class,
"com.shatteredpixel.shatteredpixeldungeon.levels.CityBossLevel" );
}

View File

@ -0,0 +1,39 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2020 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.actors.mobs;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
//TODO currently just regular DK but with no summoning ability
public class DwarfKing extends King {
protected boolean canTryToSummon() {
return false;
}
@Override
public void die(Object cause) {
super.die(cause);
Dungeon.level.unseal();
}
}

View File

@ -43,7 +43,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.keys.SkeletonKey;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTeleportation;
import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfDisintegration;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Grim;
import com.shatteredpixel.shatteredpixeldungeon.levels.CityBossLevel;
import com.shatteredpixel.shatteredpixeldungeon.levels.OldCityBossLevel;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.KingSprite;
@ -62,9 +62,9 @@ public class King extends Mob {
{
spriteClass = KingSprite.class;
HP = HT = 300;
HP = HT = 3;
EXP = 40;
defenseSkill = 25;
defenseSkill = 0;
Undead.count = 0;
@ -91,7 +91,7 @@ public class King extends Mob {
@Override
public int damageRoll() {
return Random.NormalIntRange( 25, 40 );
return Random.NormalIntRange( 0, 0 );
}
@Override
@ -101,26 +101,26 @@ public class King extends Mob {
@Override
public int drRoll() {
return Random.NormalIntRange(0, 14);
return Random.NormalIntRange(0, 0);
}
@Override
protected boolean getCloser( int target ) {
return canTryToSummon() ?
super.getCloser( ((CityBossLevel)Dungeon.level).pedestal( nextPedestal ) ) :
super.getCloser( ((OldCityBossLevel)Dungeon.level).pedestal( nextPedestal ) ) :
super.getCloser( target );
}
@Override
protected boolean canAttack( Char enemy ) {
return canTryToSummon() ?
pos == ((CityBossLevel)Dungeon.level).pedestal( nextPedestal ) :
pos == ((OldCityBossLevel)Dungeon.level).pedestal( nextPedestal ) :
Dungeon.level.adjacent( pos, enemy.pos );
}
private boolean canTryToSummon() {
protected boolean canTryToSummon() {
if (paralysed <= 0 && Undead.count < maxArmySize()) {
Char ch = Actor.findChar( ((CityBossLevel)Dungeon.level).pedestal( nextPedestal ) );
Char ch = Actor.findChar( ((OldCityBossLevel)Dungeon.level).pedestal( nextPedestal ) );
return ch == this || ch == null;
} else {
return false;
@ -129,11 +129,11 @@ public class King extends Mob {
@Override
protected boolean act() {
if (canTryToSummon() && pos == ((CityBossLevel)Dungeon.level).pedestal( nextPedestal )) {
if (canTryToSummon() && pos == ((OldCityBossLevel)Dungeon.level).pedestal( nextPedestal )) {
summon();
return true;
} else {
if (enemy != null && Actor.findChar( ((CityBossLevel)Dungeon.level).pedestal( nextPedestal ) ) == enemy) {
if (enemy != null && canTryToSummon() && Actor.findChar( ((OldCityBossLevel)Dungeon.level).pedestal( nextPedestal ) ) == enemy) {
nextPedestal = !nextPedestal;
}
return super.act();
@ -176,7 +176,7 @@ public class King extends Mob {
}
}
private int maxArmySize() {
protected int maxArmySize() {
return 1 + MAX_ARMY_SIZE * (HT - HP) / HT;
}

View File

@ -0,0 +1,530 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2020 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.DwarfKing;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Imp;
import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.levels.painters.CityPainter;
import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter;
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.ImpShopRoom;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.tiles.CustomTilemap;
import com.watabou.noosa.Group;
import com.watabou.noosa.Tilemap;
import com.watabou.noosa.tweeners.AlphaTweener;
import com.watabou.utils.Bundle;
import com.watabou.utils.PathFinder;
import com.watabou.utils.Point;
import com.watabou.utils.Random;
import com.watabou.utils.Rect;
public class NewCityBossLevel extends Level {
{
color1 = 0x4b6636;
color2 = 0xf2f2f2;
}
private static final Rect entry = new Rect(1, 37, 14, 48);
private static final Rect arena = new Rect(1, 25, 14, 38);
private static final Rect end = new Rect(0, 0, 15, 22);
private static final int bottomDoor = 7 + (arena.bottom-1)*15;
private static final int topDoor = 7 + arena.top*15;
private ImpShopRoom impShop;
@Override
public String tilesTex() {
return Assets.TILES_CITY;
}
@Override
public String waterTex() {
return Assets.WATER_CITY;
}
private static final String IMP_SHOP = "imp_shop";
@Override
public void storeInBundle( Bundle bundle ) {
super.storeInBundle( bundle );
bundle.put( IMP_SHOP, impShop );
}
@Override
public void restoreFromBundle( Bundle bundle ) {
super.restoreFromBundle( bundle );
impShop = (ImpShopRoom) bundle.get( IMP_SHOP );
if (map[topDoor] != Terrain.LOCKED_DOOR) impShop.onLevelLoad(this);
}
@Override
protected boolean build() {
setSize(15, 48);
//entrance room
Painter.fill(this, entry, Terrain.WALL);
Painter.fill(this, entry, 1, Terrain.BOOKSHELF);
Painter.fill(this, entry, 2, Terrain.EMPTY);
Painter.fill(this, entry.left+3, entry.top+3, 1, 5, Terrain.BOOKSHELF);
Painter.fill(this, entry.right-4, entry.top+3, 1, 5, Terrain.BOOKSHELF);
Point c = entry.center();
Painter.fill(this, c.x-1, c.y-2, 3, 1, Terrain.STATUE);
Painter.fill(this, c.x-1, c.y, 3, 1, Terrain.STATUE);
Painter.fill(this, c.x-1, c.y+2, 3, 1, Terrain.STATUE);
Painter.fill(this, c.x, entry.top+1, 1, 6, Terrain.EMPTY_SP);
Painter.set(this, c.x, entry.top, Terrain.DOOR);
entrance = c.x + (c.y+2)*width();
Painter.set(this, entrance, Terrain.ENTRANCE);
//DK's throne room
Painter.fillDiamond(this, arena, 1, Terrain.EMPTY);
Painter.fill(this, arena, 5, Terrain.EMPTY_SP);
Painter.fill(this, arena, 6, Terrain.STATUE_SP);
c = arena.center();
Painter.set(this, c.x-3, c.y, Terrain.STATUE);
Painter.set(this, c.x-4, c.y, Terrain.STATUE);
Painter.set(this, c.x+3, c.y, Terrain.STATUE);
Painter.set(this, c.x+4, c.y, Terrain.STATUE);
Painter.set(this, c.x-3, c.y-3, Terrain.PEDESTAL);
Painter.set(this, c.x+3, c.y-3, Terrain.PEDESTAL);
Painter.set(this, c.x+3, c.y+3, Terrain.PEDESTAL);
Painter.set(this, c.x-3, c.y+3, Terrain.PEDESTAL);
Painter.set(this, c.x, arena.top, Terrain.LOCKED_DOOR);
//exit hallway
Painter.fill(this, end, Terrain.CHASM);
Painter.fill(this, end.left+4, end.top+5, 7, 18, Terrain.EMPTY);
Painter.fill(this, end.left+4, end.top+5, 7, 3, Terrain.EXIT);
exit = end.left+7 + (end.top+7)*width();
impShop = new ImpShopRoom();
impShop.set(end.left+3, end.top+12, end.left+11, end.top+20);
if (impShop.itemCount() > (7*7)){
impShop.bottom += 2;
}
Painter.set(this, impShop.center(), Terrain.PEDESTAL);
Painter.set(this, impShop.left+2, impShop.top, Terrain.STATUE);
Painter.set(this, impShop.left+6, impShop.top, Terrain.STATUE);
Painter.fill(this, end.left+5, end.bottom+1, 5, 1, Terrain.EMPTY);
Painter.fill(this, end.left+6, end.bottom+2, 3, 1, Terrain.EMPTY);
new CityPainter().paint(this, null);
//pillars last, no deco on these
Painter.fill(this, end.left+1, end.top+2, 2, 2, Terrain.WALL);
Painter.fill(this, end.left+1, end.top+7, 2, 2, Terrain.WALL);
Painter.fill(this, end.left+1, end.top+12, 2, 2, Terrain.WALL);
Painter.fill(this, end.left+1, end.top+17, 2, 2, Terrain.WALL);
Painter.fill(this, end.right-3, end.top+2, 2, 2, Terrain.WALL);
Painter.fill(this, end.right-3, end.top+7, 2, 2, Terrain.WALL);
Painter.fill(this, end.right-3, end.top+12, 2, 2, Terrain.WALL);
Painter.fill(this, end.right-3, end.top+17, 2, 2, Terrain.WALL);
CustomTilemap customVisuals = new CustomGroundVisuals();
customVisuals.setRect(0, 0, width(), height());
customTiles.add(customVisuals);
customVisuals = new CustomWallVisuals();
customVisuals.setRect(0, 0, width(), height());
customWalls.add(customVisuals);
return true;
}
@Override
protected void createMobs() {
}
public Actor respawner() {
return null;
}
@Override
protected void createItems() {
Item item = Bones.get();
if (item != null) {
int pos;
do {
pos = randomRespawnCell(null);
} while (pos == entrance);
drop( item, pos ).setHauntedIfCursed().type = Heap.Type.REMAINS;
}
}
@Override
public int randomRespawnCell( Char ch ) {
int cell;
do {
cell = entrance + PathFinder.NEIGHBOURS8[Random.Int(8)];
} while (!passable[cell]
|| (Char.hasProp(ch, Char.Property.LARGE) && !openSpace[cell])
|| Actor.findChar(cell) != null);
return cell;
}
@Override
public void occupyCell( Char ch ) {
super.occupyCell( ch );
if (map[bottomDoor] == Terrain.DOOR && map[topDoor] == Terrain.LOCKED_DOOR
&& ch.pos < bottomDoor && ch == Dungeon.hero) {
seal();
}
}
@Override
public void seal() {
super.seal();
for (Mob m : mobs){
//bring the first ally with you
if (m.alignment == Char.Alignment.ALLY && !m.properties().contains(Char.Property.IMMOVABLE)){
m.pos = Dungeon.hero.pos + (Random.Int(2) == 0 ? +1 : -1);
m.sprite.place(m.pos);
break;
}
}
DwarfKing boss = new DwarfKing();
boss.state = boss.WANDERING;
boss.pos = pointToCell(arena.center());
GameScene.add( boss );
if (heroFOV[boss.pos]) {
boss.notice();
boss.sprite.alpha( 0 );
boss.sprite.parent.add( new AlphaTweener( boss.sprite, 1, 0.1f ) );
}
set( bottomDoor, Terrain.LOCKED_DOOR );
GameScene.updateMap( bottomDoor );
Dungeon.observe();
}
@Override
public void unseal() {
super.unseal();
set( bottomDoor, Terrain.DOOR );
GameScene.updateMap( bottomDoor );
set( topDoor, Terrain.DOOR );
GameScene.updateMap( topDoor );
if (Imp.Quest.isCompleted()) {
impShop.spawnShop(this);
}
Dungeon.observe();
}
@Override
public String tileName( int tile ) {
switch (tile) {
case Terrain.WATER:
return Messages.get(CityLevel.class, "water_name");
case Terrain.HIGH_GRASS:
return Messages.get(CityLevel.class, "high_grass_name");
default:
return super.tileName( tile );
}
}
@Override
public String tileDesc(int tile) {
switch (tile) {
case Terrain.ENTRANCE:
return Messages.get(CityLevel.class, "entrance_desc");
case Terrain.EXIT:
return Messages.get(CityLevel.class, "exit_desc");
case Terrain.WALL_DECO:
case Terrain.EMPTY_DECO:
return Messages.get(CityLevel.class, "deco_desc");
case Terrain.EMPTY_SP:
return Messages.get(CityLevel.class, "sp_desc");
case Terrain.STATUE:
case Terrain.STATUE_SP:
return Messages.get(CityLevel.class, "statue_desc");
case Terrain.BOOKSHELF:
return Messages.get(CityLevel.class, "bookshelf_desc");
default:
return super.tileDesc( tile );
}
}
@Override
public Group addVisuals( ) {
super.addVisuals();
CityLevel.addCityVisuals(this, visuals);
return visuals;
}
//TODO need to change text for some of these tiles
public static class CustomGroundVisuals extends CustomTilemap {
{
texture = Assets.CITY_BOSS;
tileW = 15;
tileH = 48;
}
private static final int STAIR_ROWS = 8;
@Override
public Tilemap create() {
Tilemap v = super.create();
int[] data = new int[tileW*tileH];
int[] map = Dungeon.level.map;
int stairsTop = -1;
//upper part of the level, mostly demon halls tiles
for (int i = tileW; i < tileW*22; i++){
if (map[i] == Terrain.EXIT && stairsTop == -1){
stairsTop = i - tileW;
}
//pillars
if (map[i] == Terrain.WALL && map[i-tileW] == Terrain.CHASM){
data[i] = 13*8 + 6;
data[++i] = 13*8 + 7;
} else if (map[i] == Terrain.WALL && map[i-tileW] == Terrain.WALL){
data[i] = 14*8 + 6;
data[++i] = 14*8 + 7;
} else if (i > tileW && map[i] == Terrain.CHASM && map[i-tileW] == Terrain.WALL) {
data[i] = 15*8 + 6;
data[++i] = 15*8 + 7;
//imp's pedestal
} else if (map[i] == Terrain.PEDESTAL) {
data[i] = 12*8 + 5;
//skull piles
} else if (map[i] == Terrain.STATUE) {
data[i] = 13*8 + 5;
//ground tiles
} else if (map[i] == Terrain.EMPTY || map[i] == Terrain.EMPTY_DECO){
//final ground stiching with city tiles
if (i/tileW == 21){
data[i] = 11*8 + 0;
data[++i] = 11*8 + 1;
data[++i] = 11*8 + 2;
data[++i] = 11*8 + 3;
data[++i] = 11*8 + 4;
data[++i] = 11*8 + 5;
data[++i] = 11*8 + 6;
} else {
//regular ground tiles
if (map[i - 1] == Terrain.CHASM) {
data[i] = 12 * 8 + 1;
} else if (map[i + 1] == Terrain.CHASM) {
data[i] = 12 * 8 + 3;
} else if (map[i] == Terrain.EMPTY_DECO) {
data[i] = 12 * 8 + 4;
} else {
data[i] = 12 * 8 + 2;
}
}
//otherwise no tile here
} else {
data[i] = -1;
}
}
//custom for stairs
int[] rowData = null;
for (int i = 0; i < STAIR_ROWS; i++){
if (i == 0){
rowData = new int[]{-1, -1, 7*8+2, 7*8+3, 7*8+4, -1, -1};
} else if (i == 1){
rowData = new int[]{8*8+0, 8*8+1, 8*8+2, 8*8+3, 8*8+4, 8*8+5, 8*8+6};
} else if (i < STAIR_ROWS-2){
rowData = new int[]{9*8+0, 8*8+3, 8*8+3, 8*8+3, 8*8+3, 8*8+3, 9*8+6};
} else if (i == STAIR_ROWS-2){
rowData = new int[]{9*8+0, 9*8+1, 9*8+2, 9*8+3, 9*8+4, 9*8+5, 9*8+6};
} else {
rowData = new int[]{10*8+0, 10*8+1, 10*8+2, 10*8+3, 10*8+4, 10*8+5, 10*8+6};
}
for (int j = 0; j < rowData.length; j++){
data[stairsTop+j] = rowData[j];
}
stairsTop += tileW;
}
//lower part: statues, pedestals, and carpets
for (int i = tileW*22; i < tileW * tileH; i++){
//pedestal spawners
if (map[i] == Terrain.PEDESTAL){
data[i] = 13*8 + 4;
//statues that should face left instead of right
} else if (map[i] == Terrain.STATUE && i%tileW > 7) {
data[i] = 15 * 8 + 4;
//carpet tiles
} else if (map[i] == Terrain.EMPTY_SP) {
//top row of DK's throne
if (map[i + 1] == Terrain.EMPTY_SP && map[i + tileW] == Terrain.EMPTY_SP) {
data[i] = 13 * 8 + 1;
data[++i] = 13 * 8 + 2;
data[++i] = 13 * 8 + 3;
//mid row of DK's throne
}else if (map[i + 1] == Terrain.STATUE_SP) {
data[i] = 14 * 8 + 1;
data[++i] = 15 * 8 + 5;
data[++i] = 14 * 8 + 3;
//bottom row of DK's throne
} else if (map[i+1] == Terrain.EMPTY_SP && map[i-tileW] == Terrain.EMPTY_SP){
data[i] = 15*8 + 1;
data[++i] = 15*8 + 2;
data[++i] = 15*8 + 3;
//otherwise entrance carpet
} else if (map[i-tileW] != Terrain.EMPTY_SP){
data[i] = 13*8 + 0;
} else if (map[i+tileW] != Terrain.EMPTY_SP){
data[i] = 15*8 + 0;
} else {
data[i] = 14*8 + 0;
}
//otherwise no tile here
} else {
data[i] = -1;
}
}
v.map( data, tileW );
return v;
}
}
public static class CustomWallVisuals extends CustomTilemap {
{
texture = Assets.CITY_BOSS;
tileW = 15;
tileH = 48;
}
@Override
public Tilemap create() {
Tilemap v = super.create();
int[] data = new int[tileW*tileH];
int[] map = Dungeon.level.map;
int stairsTop = -1;
//upper part of the level, mostly demon halls tiles
for (int i = tileW; i < tileW*21; i++) {
if (map[i] == Terrain.EXIT && stairsTop == -1){
stairsTop = i - tileW;
}
//pillars
if (map[i] == Terrain.CHASM && map[i+tileW] == Terrain.WALL) {
data[i] = 12*8 + 6;
data[++i] = 12*8 + 7;
} else if (map[i] == Terrain.WALL && map[i-tileW] == Terrain.CHASM) {
data[i] = 13*8 + 6;
data[++i] = 13*8 + 7;
//otherwise no tile here
} else {
data[i] = -1;
}
}
//custom shadow (and skull tops) for stairs
//TODO this doesn't look so great. Should try baking some of the shadow into the stairs themselves
for (int i = 0; i < CustomGroundVisuals.STAIR_ROWS; i++){
if (i == CustomGroundVisuals.STAIR_ROWS-1){
data[stairsTop] = i*8 + 0;
data[stairsTop+1] = i*8 + 1;
data[stairsTop+2] = data[stairsTop+3] = data[stairsTop+4] = -1;
data[stairsTop+5] = i*8 + 5;
data[stairsTop+6] = i*8 + 6;
} else {
for (int j = 0; j < 7; j++) {
data[stairsTop + j] = i*8 + j;
}
}
stairsTop += tileW;
}
//lower part. Just need to handle statue tiles here
for (int i = tileW*21; i < tileW * tileH; i++){
//DK's throne
if (map[i] == Terrain.STATUE_SP){
data[i-tileW] = 14*8 + 5;
//Statues that need to face left instead of right
} else if (map[i] == Terrain.STATUE && i%tileW > 7){
data[i-tileW] = 14*8 + 4;
}
//always no tile here (as the above statements are modifying previous tiles)
data[i] = -1;
}
v.map( data, tileW );
return v;
}
}
}

View File

@ -41,7 +41,7 @@ import com.watabou.utils.Bundle;
import com.watabou.utils.PathFinder;
import com.watabou.utils.Random;
public class CityBossLevel extends Level {
public class OldCityBossLevel extends Level {
{
color1 = 0x4b6636;

View File

@ -46,7 +46,7 @@ public class CityPainter extends RegularPainter {
} else if (map[i] == Terrain.WALL
&& !DungeonTileSheet.wallStitcheable(map[i + w])
&& Random.Int( 22 - Dungeon.depth ) == 0) {
&& Random.Int( 21 - Dungeon.depth ) == 0) {
map[i] = Terrain.WALL_DECO;
}
}

View File

@ -68,14 +68,17 @@ public class ShopRoom extends SpecialRoom {
@Override
public int minWidth() {
if (itemsToSpawn == null) itemsToSpawn = generateItems();
return Math.max(7, (int)(Math.sqrt(itemsToSpawn.size())+3));
return Math.max(7, (int)(Math.sqrt(itemCount())+3));
}
@Override
public int minHeight() {
return Math.max(7, (int)(Math.sqrt(itemCount())+3));
}
public int itemCount(){
if (itemsToSpawn == null) itemsToSpawn = generateItems();
return Math.max(7, (int)(Math.sqrt(itemsToSpawn.size())+3));
return itemsToSpawn.size();
}
public void paint( Level level ) {
@ -105,8 +108,9 @@ public class ShopRoom extends SpecialRoom {
protected void placeItems( Level level ){
if (itemsToSpawn == null)
if (itemsToSpawn == null){
itemsToSpawn = generateItems();
}
Point itemPlacement = new Point(entrance());
if (itemPlacement.y == top){
@ -167,8 +171,8 @@ public class ShopRoom extends SpecialRoom {
itemsToSpawn.add( Generator.random(Generator.misTiers[3]).quantity(2).identify() );
itemsToSpawn.add( new ScaleArmor().identify() );
break;
case 21:
case 20: case 21:
w = (MeleeWeapon) Generator.random(Generator.wepTiers[4]);
itemsToSpawn.add( Generator.random(Generator.misTiers[4]).quantity(2).identify() );
itemsToSpawn.add( new PlateArmor().identify() );
@ -178,6 +182,7 @@ public class ShopRoom extends SpecialRoom {
break;
}
w.enchant(null);
w.cursed = false;
w.level(0);
w.identify();
itemsToSpawn.add(w);
@ -236,7 +241,7 @@ public class ShopRoom extends SpecialRoom {
bags = (int)Math.ceil(( 5-hourglass.sandBags) * 0.25f ); break;
case 16:
bags = (int)Math.ceil(( 5-hourglass.sandBags) * 0.50f ); break;
case 21:
case 20: case 21:
bags = (int)Math.ceil(( 5-hourglass.sandBags) * 0.80f ); break;
}

View File

@ -21,6 +21,7 @@
package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard;
import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Imp;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.ImpShopkeeper;
@ -28,6 +29,7 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter;
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.ShopRoom;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.watabou.utils.Bundle;
//shops probably shouldn't extend special room, because of cases like this.
@ -62,9 +64,7 @@ public class ImpShopRoom extends ShopRoom {
}
if (Imp.Quest.isCompleted()){
impSpawned = true;
placeItems(level);
placeShopkeeper(level);
spawnShop(level);
} else {
impSpawned = false;
}
@ -78,7 +78,11 @@ public class ImpShopRoom extends ShopRoom {
Mob shopkeeper = new ImpShopkeeper();
shopkeeper.pos = pos;
level.mobs.add( shopkeeper );
if (ShatteredPixelDungeon.scene() instanceof GameScene) {
GameScene.add(shopkeeper);
} else {
level.mobs.add(shopkeeper);
}
}
@ -88,9 +92,10 @@ public class ImpShopRoom extends ShopRoom {
return connected.isEmpty() ? new Door(left, top+2) : super.entrance();
}
private void spawnShop(Level level){
public void spawnShop(Level level){
impSpawned = true;
super.paint(level);
placeItems(level);
placeShopkeeper(level);
}
private static final String IMP = "imp_spawned";
@ -112,9 +117,7 @@ public class ImpShopRoom extends ShopRoom {
super.onLevelLoad(level);
if (Imp.Quest.isCompleted() && !impSpawned){
impSpawned = true;
placeItems(level);
placeShopkeeper(level);
spawnShop(level);
}
}
}