v0.6.0: refactored shop rooms and the imp's shop
Imp's shop now spawns even if floor 21 is visited
This commit is contained in:
parent
b0456bd505
commit
85d9c94f93
|
@ -33,6 +33,7 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.ShopRoom;
|
|||
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.EntranceRoom;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.ExitRoom;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.FissureRoom;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.ImpShopRoom;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
||||
import com.watabou.noosa.Group;
|
||||
import com.watabou.utils.Random;
|
||||
|
@ -61,14 +62,9 @@ public class LastShopLevel extends RegularLevel {
|
|||
ArrayList<Room> rooms = new ArrayList<>();
|
||||
|
||||
rooms.add ( roomEntrance = new EntranceRoom());
|
||||
rooms.add( new ImpShopRoom() );
|
||||
rooms.add( roomExit = new ExitRoom());
|
||||
|
||||
if (Imp.Quest.isCompleted()){
|
||||
rooms.add( new ShopRoom() );
|
||||
} else {
|
||||
rooms.add( new FissureRoom() );
|
||||
}
|
||||
|
||||
return rooms;
|
||||
}
|
||||
|
||||
|
|
|
@ -397,6 +397,7 @@ public abstract class RegularLevel extends Level {
|
|||
|
||||
rooms = new ArrayList<>( (Collection<Room>) ((Collection<?>) bundle.getCollection( "rooms" )) );
|
||||
for (Room r : rooms) {
|
||||
r.onLevelLoad( this );
|
||||
if (r instanceof EntranceRoom || r.legacyType.equals("ENTRANCE")){
|
||||
roomEntrance = r;
|
||||
} else if (r instanceof ExitRoom || r.legacyType.equals("EXIT")){
|
||||
|
|
|
@ -157,7 +157,8 @@ public class LegacyBuilder extends Builder {
|
|||
connected.add( or );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
if (Dungeon.shopOnLevel()) {
|
||||
Room shop = null;
|
||||
for (Room r : roomEntrance.connected.keySet()) {
|
||||
|
@ -176,7 +177,7 @@ public class LegacyBuilder extends Builder {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
specials = new ArrayList<>( SpecialRoom.SPECIALS );
|
||||
if (Dungeon.bossLevel( Dungeon.depth + 1 )) {
|
||||
specials.remove( WeakFloorRoom.class );
|
||||
|
|
|
@ -298,6 +298,11 @@ public class Room extends Rect implements Graph.Node, Bundlable {
|
|||
if (bundle.contains( "type" ))
|
||||
legacyType = bundle.getString( "type" );
|
||||
}
|
||||
|
||||
//Note that currently connections and neighbours are not preserved on load
|
||||
public void onLevelLoad( Level level ){
|
||||
//does nothing by default
|
||||
}
|
||||
|
||||
public static class Door extends Point {
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.armor.MailArmor;
|
|||
import com.shatteredpixel.shatteredpixeldungeon.items.armor.PlateArmor;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.armor.ScaleArmor;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.TimekeepersHourglass;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.bags.Bag;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.bags.PotionBandolier;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.bags.ScrollHolder;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.bags.SeedPouch;
|
||||
|
@ -81,26 +82,17 @@ import java.util.Collections;
|
|||
|
||||
public class ShopRoom extends SpecialRoom {
|
||||
|
||||
private static int pasWidth;
|
||||
private static int pasHeight;
|
||||
|
||||
private static ArrayList<Item> itemsToSpawn;
|
||||
private ArrayList<Item> itemsToSpawn;
|
||||
|
||||
@Override
|
||||
public int minWidth() {
|
||||
if (itemsToSpawn == null) generateItems();
|
||||
if (itemsToSpawn == null) itemsToSpawn = generateItems();
|
||||
return Math.max(7, (int)(Math.sqrt(itemsToSpawn.size())+3));
|
||||
}
|
||||
|
||||
//FIXME this is messy, the floor 21 shop should probably just be its own class.
|
||||
@Override
|
||||
public int maxConnections(int direction) {
|
||||
return Dungeon.depth == 21 ? 2 : 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int minHeight() {
|
||||
if (itemsToSpawn == null) generateItems();
|
||||
if (itemsToSpawn == null) itemsToSpawn = generateItems();
|
||||
return Math.max(7, (int)(Math.sqrt(itemsToSpawn.size())+3));
|
||||
}
|
||||
|
||||
|
@ -108,43 +100,71 @@ public class ShopRoom extends SpecialRoom {
|
|||
|
||||
Painter.fill( level, this, Terrain.WALL );
|
||||
Painter.fill( level, this, 1, Terrain.EMPTY_SP );
|
||||
|
||||
pasWidth = width() - 3;
|
||||
pasHeight = height() - 3;
|
||||
int per = pasWidth * 2 + pasHeight * 2;
|
||||
|
||||
if (itemsToSpawn == null)
|
||||
generateItems();
|
||||
|
||||
int pos = xy2p( this, entrance() ) + (per - itemsToSpawn.size()) / 2;
|
||||
for (Item item : itemsToSpawn) {
|
||||
|
||||
Point xy = p2xy( this, (pos + per) % per );
|
||||
int cell = xy.x + xy.y * level.width();
|
||||
|
||||
if (level.heaps.get( cell ) != null) {
|
||||
do {
|
||||
cell = level.pointToCell(random());
|
||||
} while (level.heaps.get( cell ) != null);
|
||||
}
|
||||
|
||||
level.drop( item, cell ).type = Heap.Type.FOR_SALE;
|
||||
|
||||
pos++;
|
||||
}
|
||||
|
||||
placeShopkeeper( level, this );
|
||||
|
||||
placeShopkeeper( level );
|
||||
|
||||
placeItems( level );
|
||||
|
||||
for (Door door : connected.values()) {
|
||||
door.set( Door.Type.REGULAR );
|
||||
}
|
||||
|
||||
itemsToSpawn = null;
|
||||
}
|
||||
|
||||
protected void placeShopkeeper( Level level ) {
|
||||
|
||||
int pos = level.pointToCell(center());
|
||||
|
||||
Mob shopkeeper = new Shopkeeper();
|
||||
shopkeeper.pos = pos;
|
||||
level.mobs.add( shopkeeper );
|
||||
|
||||
}
|
||||
|
||||
protected void placeItems( Level level ){
|
||||
|
||||
if (itemsToSpawn == null)
|
||||
itemsToSpawn = generateItems();
|
||||
|
||||
Point itemPlacement = new Point(entrance());
|
||||
if (itemPlacement.y == top){
|
||||
itemPlacement.y++;
|
||||
} else if (itemPlacement.y == bottom) {
|
||||
itemPlacement.y--;
|
||||
} else if (itemPlacement.x == left){
|
||||
itemPlacement.x++;
|
||||
} else {
|
||||
itemPlacement.x--;
|
||||
}
|
||||
|
||||
for (Item item : itemsToSpawn) {
|
||||
|
||||
if (itemPlacement.x == left+1 && itemPlacement.y != top+1){
|
||||
itemPlacement.y--;
|
||||
} else if (itemPlacement.y == top+1 && itemPlacement.x != right-1){
|
||||
itemPlacement.x++;
|
||||
} else if (itemPlacement.x == right-1 && itemPlacement.y != bottom-1){
|
||||
itemPlacement.y++;
|
||||
} else {
|
||||
itemPlacement.x--;
|
||||
}
|
||||
|
||||
int cell = level.pointToCell(itemPlacement);
|
||||
|
||||
if (level.heaps.get( cell ) != null) {
|
||||
do {
|
||||
cell = level.pointToCell(random());
|
||||
} while (level.heaps.get( cell ) != null || level.findMob( cell ) != null);
|
||||
}
|
||||
|
||||
level.drop( item, cell ).type = Heap.Type.FOR_SALE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void generateItems() {
|
||||
protected static ArrayList<Item> generateItems() {
|
||||
|
||||
itemsToSpawn = new ArrayList<Item>();
|
||||
ArrayList<Item> itemsToSpawn = new ArrayList<>();
|
||||
|
||||
switch (Dungeon.depth) {
|
||||
case 6:
|
||||
|
@ -185,7 +205,7 @@ public class ShopRoom extends SpecialRoom {
|
|||
itemsToSpawn.add( new MerchantsBeacon() );
|
||||
|
||||
|
||||
ChooseBag(Dungeon.hero.belongings);
|
||||
itemsToSpawn.add(ChooseBag(Dungeon.hero.belongings));
|
||||
|
||||
|
||||
itemsToSpawn.add( new PotionOfHealing() );
|
||||
|
@ -275,9 +295,10 @@ public class ShopRoom extends SpecialRoom {
|
|||
throw new RuntimeException("Shop attempted to carry more than 63 items!");
|
||||
|
||||
Random.shuffle(itemsToSpawn);
|
||||
return itemsToSpawn;
|
||||
}
|
||||
|
||||
private static void ChooseBag(Belongings pack){
|
||||
protected static Bag ChooseBag(Belongings pack){
|
||||
|
||||
int seeds = 0, scrolls = 0, potions = 0, wands = 0;
|
||||
|
||||
|
@ -297,92 +318,22 @@ public class ShopRoom extends SpecialRoom {
|
|||
//note that the order here gives a perference if counts are otherwise equal
|
||||
if (seeds >= scrolls && seeds >= potions && seeds >= wands && !Dungeon.limitedDrops.seedBag.dropped()) {
|
||||
Dungeon.limitedDrops.seedBag.drop();
|
||||
itemsToSpawn.add( new SeedPouch() );
|
||||
return new SeedPouch();
|
||||
|
||||
} else if (scrolls >= potions && scrolls >= wands && !Dungeon.limitedDrops.scrollBag.dropped()) {
|
||||
Dungeon.limitedDrops.scrollBag.drop();
|
||||
itemsToSpawn.add( new ScrollHolder() );
|
||||
return new ScrollHolder();
|
||||
|
||||
} else if (potions >= wands && !Dungeon.limitedDrops.potionBag.dropped()) {
|
||||
Dungeon.limitedDrops.potionBag.drop();
|
||||
itemsToSpawn.add( new PotionBandolier() );
|
||||
return new PotionBandolier();
|
||||
|
||||
} else if (!Dungeon.limitedDrops.wandBag.dropped()) {
|
||||
Dungeon.limitedDrops.wandBag.drop();
|
||||
itemsToSpawn.add(new WandHolster());
|
||||
return new WandHolster();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static int spaceNeeded(){
|
||||
if (itemsToSpawn == null)
|
||||
generateItems();
|
||||
|
||||
//plus one for the shopkeeper
|
||||
return itemsToSpawn.size() + 1;
|
||||
}
|
||||
|
||||
private static void placeShopkeeper( Level level, Room room ) {
|
||||
|
||||
int pos;
|
||||
do {
|
||||
pos = level.pointToCell(room.random());
|
||||
} while (level.heaps.get( pos ) != null);
|
||||
|
||||
Mob shopkeeper = level instanceof LastShopLevel ? new ImpShopkeeper() : new Shopkeeper();
|
||||
shopkeeper.pos = pos;
|
||||
level.mobs.add( shopkeeper );
|
||||
|
||||
if (level instanceof LastShopLevel) {
|
||||
for (int i = 0; i < PathFinder.NEIGHBOURS9.length; i++) {
|
||||
int p = shopkeeper.pos + PathFinder.NEIGHBOURS9[i];
|
||||
if (level.map[p] == Terrain.EMPTY_SP) {
|
||||
level.map[p] = Terrain.WATER;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static int xy2p( Room room, Point xy ) {
|
||||
if (xy.y == room.top) {
|
||||
|
||||
return (xy.x - room.left - 1);
|
||||
|
||||
} else if (xy.x == room.right) {
|
||||
|
||||
return (xy.y - room.top - 1) + pasWidth;
|
||||
|
||||
} else if (xy.y == room.bottom) {
|
||||
|
||||
return (room.right - xy.x - 1) + pasWidth + pasHeight;
|
||||
|
||||
} else {
|
||||
|
||||
if (xy.y == room.top + 1) {
|
||||
return 0;
|
||||
} else {
|
||||
return (room.bottom - xy.y - 1) + pasWidth * 2 + pasHeight;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static Point p2xy( Room room, int p ) {
|
||||
if (p < pasWidth) {
|
||||
|
||||
return new Point( room.left + 1 + p, room.top + 1);
|
||||
|
||||
} else if (p < pasWidth + pasHeight) {
|
||||
|
||||
return new Point( room.right - 1, room.top + 1 + (p - pasWidth) );
|
||||
|
||||
} else if (p < pasWidth * 2 + pasHeight) {
|
||||
|
||||
return new Point( room.right - 1 - (p - (pasWidth + pasHeight)), room.bottom - 1 );
|
||||
|
||||
} else {
|
||||
|
||||
return new Point( room.left + 1, room.bottom - 1 - (p - (pasWidth * 2 + pasHeight)) );
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2017 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.rooms.standard;
|
||||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Imp;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.ImpShopkeeper;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Shopkeeper;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.LastShopLevel;
|
||||
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.Room;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.ShopRoom;
|
||||
import com.watabou.utils.Bundle;
|
||||
import com.watabou.utils.PathFinder;
|
||||
|
||||
//shops probably shouldn't extend special room, because of cases like this.
|
||||
public class ImpShopRoom extends ShopRoom {
|
||||
|
||||
private boolean impSpawned = false;
|
||||
|
||||
//force a certain size here to guarantee enough room for 48 items, and the same center space
|
||||
@Override
|
||||
public int minWidth() {
|
||||
return 9;
|
||||
}
|
||||
public int minHeight() {
|
||||
return 9;
|
||||
}
|
||||
public int maxWidth() { return 9; }
|
||||
public int maxHeight() { return 9; }
|
||||
|
||||
@Override
|
||||
public int maxConnections(int direction) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Level level) {
|
||||
Painter.fill( level, this, Terrain.WALL );
|
||||
Painter.fill( level, this, 1, Terrain.EMPTY_SP );
|
||||
Painter.fill( level, this, 3, Terrain.WATER);
|
||||
|
||||
for (Door door : connected.values()) {
|
||||
door.set( Door.Type.REGULAR );
|
||||
}
|
||||
|
||||
if (Imp.Quest.isCompleted()){
|
||||
impSpawned = true;
|
||||
placeItems(level);
|
||||
placeShopkeeper(level);
|
||||
} else {
|
||||
impSpawned = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void placeShopkeeper(Level level) {
|
||||
|
||||
int pos = level.pointToCell(center());
|
||||
|
||||
Mob shopkeeper = new ImpShopkeeper();
|
||||
shopkeeper.pos = pos;
|
||||
level.mobs.add( shopkeeper );
|
||||
|
||||
}
|
||||
|
||||
//fix for connections not being bundled normally
|
||||
@Override
|
||||
public Door entrance() {
|
||||
return connected.isEmpty() ? new Door(left, top+2) : super.entrance();
|
||||
}
|
||||
|
||||
private void spawnShop(Level level){
|
||||
impSpawned = true;
|
||||
super.paint(level);
|
||||
}
|
||||
|
||||
private static final String IMP = "imp_spawned";
|
||||
|
||||
@Override
|
||||
public void storeInBundle(Bundle bundle) {
|
||||
super.storeInBundle(bundle);
|
||||
bundle.put(IMP, impSpawned);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restoreFromBundle(Bundle bundle) {
|
||||
super.restoreFromBundle(bundle);
|
||||
impSpawned = bundle.getBoolean(IMP);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLevelLoad(Level level) {
|
||||
super.onLevelLoad(level);
|
||||
|
||||
if (Imp.Quest.isCompleted() && !impSpawned){
|
||||
impSpawned = true;
|
||||
placeItems(level);
|
||||
placeShopkeeper(level);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user