v2.3.2: improved item placement logic in shops.
This improves layouts and also fixes seed problems with varying item count
This commit is contained in:
@@ -22,6 +22,7 @@
|
|||||||
package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special;
|
package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special;
|
||||||
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Belongings;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Belongings;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Shopkeeper;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Shopkeeper;
|
||||||
@@ -111,38 +112,88 @@ public class ShopRoom extends SpecialRoom {
|
|||||||
itemsToSpawn = generateItems();
|
itemsToSpawn = generateItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
Point itemPlacement = new Point(entrance());
|
Point entryInset = new Point(entrance());
|
||||||
if (itemPlacement.y == top){
|
if (entryInset.y == top){
|
||||||
itemPlacement.y++;
|
entryInset.y++;
|
||||||
} else if (itemPlacement.y == bottom) {
|
} else if (entryInset.y == bottom) {
|
||||||
itemPlacement.y--;
|
entryInset.y--;
|
||||||
} else if (itemPlacement.x == left){
|
} else if (entryInset.x == left){
|
||||||
itemPlacement.x++;
|
entryInset.x++;
|
||||||
} else {
|
} else {
|
||||||
itemPlacement.x--;
|
entryInset.x--;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Item item : itemsToSpawn) {
|
Point curItemPlace = entryInset.clone();
|
||||||
|
|
||||||
if (itemPlacement.x == left+1 && itemPlacement.y != top+1){
|
int inset = 1;
|
||||||
itemPlacement.y--;
|
|
||||||
} else if (itemPlacement.y == top+1 && itemPlacement.x != right-1){
|
for (Item item : itemsToSpawn.toArray(new Item[0])) {
|
||||||
itemPlacement.x++;
|
|
||||||
} else if (itemPlacement.x == right-1 && itemPlacement.y != bottom-1){
|
//place items in a clockwise pattern
|
||||||
itemPlacement.y++;
|
if (curItemPlace.x == left+inset && curItemPlace.y != top+inset){
|
||||||
|
curItemPlace.y--;
|
||||||
|
} else if (curItemPlace.y == top+inset && curItemPlace.x != right-inset){
|
||||||
|
curItemPlace.x++;
|
||||||
|
} else if (curItemPlace.x == right-inset && curItemPlace.y != bottom-inset){
|
||||||
|
curItemPlace.y++;
|
||||||
} else {
|
} else {
|
||||||
itemPlacement.x--;
|
curItemPlace.x--;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cell = level.pointToCell(itemPlacement);
|
//once we get to the inset from the entrance again, move another cell inward and loop
|
||||||
|
if (curItemPlace.equals(entryInset)){
|
||||||
|
|
||||||
if (level.heaps.get( cell ) != null) {
|
if (entryInset.y == top+inset){
|
||||||
do {
|
entryInset.y++;
|
||||||
cell = level.pointToCell(random());
|
} else if (entryInset.y == bottom-inset){
|
||||||
} while (level.heaps.get( cell ) != null || level.findMob( cell ) != null);
|
entryInset.y--;
|
||||||
|
}
|
||||||
|
if (entryInset.x == left+inset){
|
||||||
|
entryInset.x++;
|
||||||
|
} else if (entryInset.x == right-inset){
|
||||||
|
entryInset.x--;
|
||||||
|
}
|
||||||
|
inset++;
|
||||||
|
|
||||||
|
if (inset > (Math.min(width(), height())-3)/2){
|
||||||
|
break; //out of space!
|
||||||
|
}
|
||||||
|
|
||||||
|
curItemPlace = entryInset.clone();
|
||||||
|
|
||||||
|
//make sure to step forward again
|
||||||
|
if (curItemPlace.x == left+inset && curItemPlace.y != top+inset){
|
||||||
|
curItemPlace.y--;
|
||||||
|
} else if (curItemPlace.y == top+inset && curItemPlace.x != right-inset){
|
||||||
|
curItemPlace.x++;
|
||||||
|
} else if (curItemPlace.x == right-inset && curItemPlace.y != bottom-inset){
|
||||||
|
curItemPlace.y++;
|
||||||
|
} else {
|
||||||
|
curItemPlace.x--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cell = level.pointToCell(curItemPlace);
|
||||||
level.drop( item, cell ).type = Heap.Type.FOR_SALE;
|
level.drop( item, cell ).type = Heap.Type.FOR_SALE;
|
||||||
|
itemsToSpawn.remove(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
//we didn't have enough space to place everything neatly, so now just fill in anything left
|
||||||
|
if (!itemsToSpawn.isEmpty()){
|
||||||
|
for (Point p : getPoints()){
|
||||||
|
int cell = level.pointToCell(p);
|
||||||
|
if ((level.map[cell] == Terrain.EMPTY_SP || level.map[cell] == Terrain.EMPTY)
|
||||||
|
&& level.heaps.get(cell) == null && level.findMob(cell) == null){
|
||||||
|
level.drop( itemsToSpawn.remove(0), level.pointToCell(p) ).type = Heap.Type.FOR_SALE;
|
||||||
|
}
|
||||||
|
if (itemsToSpawn.isEmpty()){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!itemsToSpawn.isEmpty()){
|
||||||
|
ShatteredPixelDungeon.reportException(new RuntimeException("failed to place all items in a shop!"));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -270,11 +321,6 @@ public class ShopRoom extends SpecialRoom {
|
|||||||
rare.cursedKnown = true;
|
rare.cursedKnown = true;
|
||||||
itemsToSpawn.add( rare );
|
itemsToSpawn.add( rare );
|
||||||
|
|
||||||
//hard limit is 63 items + 1 shopkeeper, as shops can't be bigger than 8x8=64 internally
|
|
||||||
if (itemsToSpawn.size() > 63) {
|
|
||||||
throw new RuntimeException("Shop attempted to carry more than 63 items!");
|
|
||||||
}
|
|
||||||
|
|
||||||
//use a new generator here to prevent items in shop stock affecting levelgen RNG (e.g. sandbags)
|
//use a new generator here to prevent items in shop stock affecting levelgen RNG (e.g. sandbags)
|
||||||
//we can use a random long for the seed as it will be the same long every time
|
//we can use a random long for the seed as it will be the same long every time
|
||||||
Random.pushGenerator(Random.Long());
|
Random.pushGenerator(Random.Long());
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ public class ImpShopRoom extends ShopRoom {
|
|||||||
//fix for connections not being bundled normally
|
//fix for connections not being bundled normally
|
||||||
@Override
|
@Override
|
||||||
public Door entrance() {
|
public Door entrance() {
|
||||||
return connected.isEmpty() ? new Door(left, top+2) : super.entrance();
|
return connected.isEmpty() ? new Door((left+right)/2 + 1, bottom-1) : super.entrance();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void spawnShop(Level level){
|
public void spawnShop(Level level){
|
||||||
|
|||||||
Reference in New Issue
Block a user