v0.2.3e: Improved shop generation logic, fixes bugs and allows for much larger shops without error.

This commit is contained in:
Evan Debenham
2015-01-17 04:38:18 -05:00
parent e4e12f74dd
commit a1754cd68a
3 changed files with 65 additions and 45 deletions
@@ -24,6 +24,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Imp;
import com.shatteredpixel.shatteredpixeldungeon.items.Heap; import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
import com.shatteredpixel.shatteredpixeldungeon.items.Item; import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.levels.Room.Type; import com.shatteredpixel.shatteredpixeldungeon.levels.Room.Type;
import com.shatteredpixel.shatteredpixeldungeon.levels.painters.ShopPainter;
import com.watabou.noosa.Scene; import com.watabou.noosa.Scene;
import com.watabou.utils.Graph; import com.watabou.utils.Graph;
import com.watabou.utils.Random; import com.watabou.utils.Random;
@@ -49,6 +50,8 @@ public class LastShopLevel extends RegularLevel {
@Override @Override
protected boolean build() { protected boolean build() {
feeling = Feeling.CHASM;
initRooms(); initRooms();
@@ -110,7 +113,8 @@ public class LastShopLevel extends RegularLevel {
} }
} }
if (roomShop == null || shopSquare < 30) { if (roomShop == null || shopSquare < 30
|| ((roomShop.width()-1)*(roomShop.height()-1) < ShopPainter.spaceNeeded())) {
return false; return false;
} else { } else {
roomShop.type = Imp.Quest.isCompleted() ? Room.Type.SHOP : Room.Type.STANDARD; roomShop.type = Imp.Quest.isCompleted() ? Room.Type.SHOP : Room.Type.STANDARD;
@@ -31,6 +31,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfWealth;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfUpgrade; import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfUpgrade;
import com.shatteredpixel.shatteredpixeldungeon.levels.Room.Type; import com.shatteredpixel.shatteredpixeldungeon.levels.Room.Type;
import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter; import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter;
import com.shatteredpixel.shatteredpixeldungeon.levels.painters.ShopPainter;
import com.watabou.utils.Bundle; import com.watabou.utils.Bundle;
import com.watabou.utils.Graph; import com.watabou.utils.Graph;
import com.watabou.utils.Random; import com.watabou.utils.Random;
@@ -123,7 +124,7 @@ public abstract class RegularLevel extends Level {
if (Dungeon.shopOnLevel()) { if (Dungeon.shopOnLevel()) {
Room shop = null; Room shop = null;
for (Room r : roomEntrance.connected.keySet()) { for (Room r : roomEntrance.connected.keySet()) {
if (r.connected.size() == 1 && r.width() >= 5 && r.height() >= 5) { if (r.connected.size() == 1 && ((r.width()-1)*(r.height()-1) >= ShopPainter.spaceNeeded())) {
shop = r; shop = r;
break; break;
} }
@@ -56,11 +56,14 @@ import com.watabou.utils.Point;
import com.watabou.utils.Random; import com.watabou.utils.Random;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
public class ShopPainter extends Painter { public class ShopPainter extends Painter {
private static int pasWidth; private static int pasWidth;
private static int pasHeight; private static int pasHeight;
private static ArrayList<Item> itemsToSpawn;
public static void paint( Level level, Room room ) { public static void paint( Level level, Room room ) {
@@ -71,10 +74,11 @@ public class ShopPainter extends Painter {
pasHeight = room.height() - 2; pasHeight = room.height() - 2;
int per = pasWidth * 2 + pasHeight * 2; int per = pasWidth * 2 + pasHeight * 2;
Item[] range = range(); if (itemsToSpawn == null)
generateItems();
int pos = xy2p( room, room.entrance() ) + (per - range.length) / 2; int pos = xy2p( room, room.entrance() ) + (per - itemsToSpawn.size()) / 2;
for (int i=0; i < range.length; i++) { for (Item item : itemsToSpawn) {
Point xy = p2xy( room, (pos + per) % per ); Point xy = p2xy( room, (pos + per) % per );
int cell = xy.x + xy.y * Level.WIDTH; int cell = xy.x + xy.y * Level.WIDTH;
@@ -85,7 +89,7 @@ public class ShopPainter extends Painter {
} while (level.heaps.get( cell ) != null); } while (level.heaps.get( cell ) != null);
} }
level.drop( range[i], cell ).type = Heap.Type.FOR_SALE; level.drop( item, cell ).type = Heap.Type.FOR_SALE;
pos++; pos++;
} }
@@ -95,66 +99,68 @@ public class ShopPainter extends Painter {
for (Room.Door door : room.connected.values()) { for (Room.Door door : room.connected.values()) {
door.set( Room.Door.Type.REGULAR ); door.set( Room.Door.Type.REGULAR );
} }
itemsToSpawn = null;
} }
private static Item[] range() { private static void generateItems() {
ArrayList<Item> items = new ArrayList<Item>(); itemsToSpawn = new ArrayList<Item>();
switch (Dungeon.depth) { switch (Dungeon.depth) {
case 6: case 6:
items.add( (Random.Int( 2 ) == 0 ? new Quarterstaff() : new Spear()).identify() ); itemsToSpawn.add( (Random.Int( 2 ) == 0 ? new Quarterstaff() : new Spear()).identify() );
items.add( new LeatherArmor().identify() ); itemsToSpawn.add( new LeatherArmor().identify() );
items.add( new SeedPouch() ); itemsToSpawn.add( new SeedPouch() );
items.add( new Weightstone() ); itemsToSpawn.add( new Weightstone() );
break; break;
case 11: case 11:
items.add( (Random.Int( 2 ) == 0 ? new Sword() : new Mace()).identify() ); itemsToSpawn.add( (Random.Int( 2 ) == 0 ? new Sword() : new Mace()).identify() );
items.add( new MailArmor().identify() ); itemsToSpawn.add( new MailArmor().identify() );
items.add( new ScrollHolder() ); itemsToSpawn.add( new ScrollHolder() );
items.add( new Weightstone() ); itemsToSpawn.add( new Weightstone() );
break; break;
case 16: case 16:
items.add( (Random.Int( 2 ) == 0 ? new Longsword() : new BattleAxe()).identify() ); itemsToSpawn.add( (Random.Int( 2 ) == 0 ? new Longsword() : new BattleAxe()).identify() );
items.add( new ScaleArmor().identify() ); itemsToSpawn.add( new ScaleArmor().identify() );
items.add( new WandHolster() ); itemsToSpawn.add( new WandHolster() );
items.add( new Weightstone() ); itemsToSpawn.add( new Weightstone() );
break; break;
case 21: case 21:
switch (Random.Int( 3 )) { switch (Random.Int( 3 )) {
case 0: case 0:
items.add( new Glaive().identify() ); itemsToSpawn.add( new Glaive().identify() );
break; break;
case 1: case 1:
items.add( new WarHammer().identify() ); itemsToSpawn.add( new WarHammer().identify() );
break; break;
case 2: case 2:
items.add( new PlateArmor().identify() ); itemsToSpawn.add( new PlateArmor().identify() );
break; break;
} }
items.add( new Torch() ); itemsToSpawn.add( new Torch() );
items.add( new Torch() ); itemsToSpawn.add( new Torch() );
break; break;
} }
items.add( new PotionOfHealing() ); itemsToSpawn.add( new PotionOfHealing() );
for (int i=0; i < 3; i++) { for (int i=0; i < 3; i++) {
items.add( Generator.random( Generator.Category.POTION ) ); itemsToSpawn.add( Generator.random( Generator.Category.POTION ) );
} }
items.add( new ScrollOfIdentify() ); itemsToSpawn.add( new ScrollOfIdentify() );
items.add( new ScrollOfRemoveCurse() ); itemsToSpawn.add( new ScrollOfRemoveCurse() );
items.add( new ScrollOfMagicMapping() ); itemsToSpawn.add( new ScrollOfMagicMapping() );
items.add( Generator.random( Generator.Category.SCROLL ) ); itemsToSpawn.add( Generator.random( Generator.Category.SCROLL ) );
items.add( new OverpricedRation() ); itemsToSpawn.add( new OverpricedRation() );
items.add( new OverpricedRation() ); itemsToSpawn.add( new OverpricedRation() );
items.add( new Ankh() ); itemsToSpawn.add( new Ankh() );
TimekeepersHourglass hourglass = Dungeon.hero.belongings.getItem(TimekeepersHourglass.class); TimekeepersHourglass hourglass = Dungeon.hero.belongings.getItem(TimekeepersHourglass.class);
@@ -175,15 +181,24 @@ public class ShopPainter extends Painter {
for(int i = 1; i <= bags; i++){ for(int i = 1; i <= bags; i++){
items.add( new TimekeepersHourglass.sandBag()); itemsToSpawn.add( new TimekeepersHourglass.sandBag());
hourglass.sandBags ++; hourglass.sandBags ++;
} }
} }
Item[] range =items.toArray( new Item[0] ); //this is a hard limit, level gen allows for at most an 8x5 room, can't fit more than 39 items + 1 shopkeeper.
Random.shuffle( range ); if (itemsToSpawn.size() > 39)
throw new RuntimeException("Shop attempted to carry more than 39 items!");
return range;
Collections.shuffle(itemsToSpawn);
}
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 ) { private static void placeShopkeeper( Level level, Room room ) {