v2.2.0: early code for gnoll caves quest levelgen

This commit is contained in:
Evan Debenham
2023-10-04 22:47:26 -04:00
parent e0f7f2d620
commit d51e397c26
9 changed files with 219 additions and 9 deletions

View File

@@ -80,6 +80,12 @@ public class Point {
public float length() {
return (float)Math.sqrt( x * x + y * y );
}
public static float distance( Point a, Point b ) {
float dx = a.x - b.x;
float dy = a.y - b.y;
return (float)Math.sqrt( dx * dx + dy * dy );
}
@Override
public boolean equals( Object obj ) {

View File

@@ -21,6 +21,9 @@
package com.shatteredpixel.shatteredpixeldungeon.levels.painters;
import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.quest.DarkGold;
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room;
@@ -55,6 +58,11 @@ public class MiningLevelPainter extends CavesPainter {
goldToAdd--;
}
}
for (Heap h : level.heaps.valueList()){
for (Item i : h.items){
if (i instanceof DarkGold) goldToAdd -= i.quantity();
}
}
int[] map = level.map;
do {
@@ -112,15 +120,16 @@ public class MiningLevelPainter extends CavesPainter {
float hiddenDoorChance = 0.90f;
//wall doors will still be wall
//hidden doors become wall tiles a bit later in painting
//everything else becomes empty
//everything else usually becomes empty, but can be wall sometimes
for (Room r : rooms) {
for (Room n : r.connected.keySet()) {
Room.Door d = r.connected.get(n);
int door = d.x + d.y * l.width();
if (d.type == Room.Door.Type.HIDDEN){
if (d.type == Room.Door.Type.WALL || d.type == Room.Door.Type.HIDDEN){
l.map[door] = Terrain.WALL;
} else {
//some of these are randomly hidden, using the same rules as regular levels

View File

@@ -287,6 +287,9 @@ public abstract class RegularPainter extends Painter {
case CRYSTAL:
l.map[door] = Terrain.CRYSTAL_DOOR;
break;
case WALL:
l.map[door] = Terrain.WALL;
break;
}
}
}

View File

@@ -428,7 +428,7 @@ public abstract class Room extends Rect implements Graph.Node, Bundlable {
public static class Door extends Point implements Bundlable {
public enum Type {
EMPTY, TUNNEL, WATER, REGULAR, UNLOCKED, HIDDEN, BARRICADE, LOCKED, CRYSTAL
EMPTY, TUNNEL, WATER, REGULAR, UNLOCKED, HIDDEN, BARRICADE, LOCKED, CRYSTAL, WALL
}
public Type type = Type.EMPTY;
@@ -442,9 +442,15 @@ public abstract class Room extends Rect implements Graph.Node, Bundlable {
public Door( int x, int y ) {
super( x, y );
}
private boolean typeLocked = false;
public void lockTypeChanges( boolean lock ){
typeLocked = lock;
}
public void set( Type type ) {
if (type.compareTo( this.type ) > 0) {
if (!typeLocked && type.compareTo( this.type ) > 0) {
this.type = type;
}
}
@@ -454,6 +460,7 @@ public abstract class Room extends Rect implements Graph.Node, Bundlable {
bundle.put("x", x);
bundle.put("y", y);
bundle.put("type", type);
bundle.put("type_locked", typeLocked);
}
@Override
@@ -461,6 +468,7 @@ public abstract class Room extends Rect implements Graph.Node, Bundlable {
x = bundle.getInt("x");
y = bundle.getInt("y");
type = bundle.getEnum("type", Type.class);
typeLocked = bundle.getBoolean("type_locked");
}
}
}

View File

@@ -28,12 +28,18 @@ 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.rooms.Room;
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.secret.SecretRoom;
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.EntranceRoom;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.tiles.CustomTilemap;
import com.watabou.noosa.Image;
import com.watabou.noosa.Tilemap;
import com.watabou.utils.GameMath;
import com.watabou.utils.Point;
import com.watabou.utils.Random;
import java.util.ArrayList;
public class MineEntrance extends EntranceRoom {
@@ -66,8 +72,8 @@ public class MineEntrance extends EntranceRoom {
Painter.set( level, entrance, Terrain.ENTRANCE );
QuestExit vis = new QuestExit();
Point p = level.cellToPoint(entrance);
vis.pos(p.x - 1, p.y - 1);
Point e = level.cellToPoint(entrance);
vis.pos(e.x - 1, e.y - 1);
level.customTiles.add(vis);
level.transitions.add(new LevelTransition(level,
@@ -84,6 +90,41 @@ public class MineEntrance extends EntranceRoom {
Painter.set(level, r, Terrain.MINE_CRYSTAL);
}
}
} else if (Blacksmith.Quest.Type() == Blacksmith.Quest.GNOLL) {
//connections to non-secret rooms have a 7/8 chance to become empty, otherwise wall
for (Room n : connected.keySet()){
if (!(n instanceof SecretRoom) && connected.get(n).type == Door.Type.REGULAR){
if (Random.Int(8) == 0){
connected.get(n).set(Door.Type.EMPTY);
} else {
connected.get(n).set(Door.Type.WALL);
}
connected.get(n).lockTypeChanges(true);
}
}
ArrayList<Door> doors = new ArrayList<>();
for (Door d : connected.values()){
if (d.type == Door.Type.WALL){
doors.add(d);
}
}
for (Point p : getPoints()){
int cell = level.pointToCell(p);
if (level.distance(cell, entrance) > 1 && level.map[cell] == Terrain.EMPTY){
float dist = 1000;
for (Door d : doors){
dist = Math.min(dist, Point.distance(p, d));
}
dist = GameMath.gate(1f, dist-0.5f, 5f);
if (Random.Float((float) Math.pow(dist, 2)) < 1f) {
Painter.set(level, cell, Terrain.MINE_BOULDER);
}
}
}
}
}

View File

@@ -26,8 +26,14 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Blacksmith;
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.secret.SecretRoom;
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.CaveRoom;
import com.watabou.utils.GameMath;
import com.watabou.utils.Point;
import com.watabou.utils.Random;
import java.util.ArrayList;
public class MineGiantRoom extends CaveRoom {
@@ -61,6 +67,49 @@ public class MineGiantRoom extends CaveRoom {
level.mobs.add(m);
Painter.set(level, p, Terrain.EMPTY);
} else if (Blacksmith.Quest.Type() == Blacksmith.Quest.GNOLL){
Painter.fillEllipse(level, this, 3, Terrain.EMPTY);
//connections to non-secret rooms have a 7/8 chance to become empty, otherwise wall
for (Room n : connected.keySet()){
if (!(n instanceof SecretRoom) && connected.get(n).type == Door.Type.REGULAR){
if (Random.Int(8) == 0){
connected.get(n).set(Door.Type.EMPTY);
} else {
connected.get(n).set(Door.Type.WALL);
}
connected.get(n).lockTypeChanges(true);
}
}
ArrayList<Door> doors = new ArrayList<>();
for (Door d : connected.values()){
if (d.type == Door.Type.WALL){
doors.add(d);
}
}
for (Point p : getPoints()){
int cell = level.pointToCell(p);
if (level.map[cell] == Terrain.EMPTY){
float dist = 1000;
for (Door d : doors){
dist = Math.min(dist, Point.distance(p, d));
}
dist = GameMath.gate(1f, dist-0.5f, 3f);
if (Random.Float((float)Math.pow(dist, 2)) < 1f){
Painter.set(level, cell, Terrain.MINE_BOULDER);
}
}
}
for (int i = 0; i < 8; i ++){
Point r = random(5);
if (level.map[level.pointToCell(r)] != Terrain.WALL) {
Painter.set(level, r, Terrain.BARRICADE);
}
}
} else {
Painter.fillEllipse(level, this, 3, Terrain.EMPTY);
}

View File

@@ -26,9 +26,13 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Blacksmith;
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.secret.SecretRoom;
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.CaveRoom;
import com.watabou.utils.GameMath;
import com.watabou.utils.PathFinder;
import com.watabou.utils.Point;
import com.watabou.utils.Random;
import java.util.ArrayList;
@@ -88,6 +92,49 @@ public class MineLargeRoom extends CaveRoom {
level.mobs.add(m);
Painter.set(level, p, Terrain.EMPTY);
} else if (Blacksmith.Quest.Type() == Blacksmith.Quest.GNOLL){
Painter.fillEllipse(level, this, 3, Terrain.EMPTY);
//connections to non-secret rooms have a 7/8 chance to become empty, otherwise wall
for (Room n : connected.keySet()){
if (!(n instanceof SecretRoom) && connected.get(n).type == Door.Type.REGULAR){
if (Random.Int(8) == 0){
connected.get(n).set(Door.Type.EMPTY);
} else {
connected.get(n).set(Door.Type.WALL);
}
connected.get(n).lockTypeChanges(true);
}
}
ArrayList<Door> doors = new ArrayList<>();
for (Door d : connected.values()){
if (d.type == Door.Type.WALL){
doors.add(d);
}
}
for (Point p : getPoints()){
int cell = level.pointToCell(p);
if (level.map[cell] == Terrain.EMPTY){
float dist = 1000;
for (Door d : doors){
dist = Math.min(dist, Point.distance(p, d));
}
dist = GameMath.gate(1f, dist-0.5f, 5f);
if (Random.Float((float)Math.pow(dist, 2)) < 1f){
Painter.set(level, cell, Terrain.MINE_BOULDER);
}
}
}
for (int i = 0; i < 4; i ++){
Point r = random(5);
if (level.map[level.pointToCell(r)] != Terrain.WALL) {
Painter.set(level, r, Terrain.BARRICADE);
}
}
} else {
Painter.fillEllipse(level, this, 3, Terrain.EMPTY);
}

View File

@@ -22,6 +22,8 @@
package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.quest;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Blacksmith;
import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
import com.shatteredpixel.shatteredpixeldungeon.items.quest.DarkGold;
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter;
@@ -40,14 +42,18 @@ public class MineSecretRoom extends SecretRoom {
public void paint(Level level) {
Painter.fill( level, this, Terrain.WALL );
entrance().set( Door.Type.HIDDEN );
if (Blacksmith.Quest.Type() == Blacksmith.Quest.CRYSTAL) {
Painter.fill(level, this, 1, Terrain.MINE_CRYSTAL);
} else if (Blacksmith.Quest.Type() == Blacksmith.Quest.GNOLL) {
Painter.fill( level, this, 1, Terrain.EMPTY_SP );
level.drop(new DarkGold().quantity(Random.NormalIntRange(3, 5)), level.pointToCell(center())).type = Heap.Type.CHEST;
return;
} else {
Painter.fill(level, this, 1, Terrain.EMPTY);
}
entrance().set( Door.Type.HIDDEN );
int goldAmount = Random.NormalIntRange(3, 5);
for (int i = 0; i < goldAmount; i++){

View File

@@ -25,8 +25,14 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Blacksmith;
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.secret.SecretRoom;
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.CaveRoom;
import com.watabou.utils.GameMath;
import com.watabou.utils.Point;
import com.watabou.utils.Random;
import java.util.ArrayList;
public class MineSmallRoom extends CaveRoom {
@@ -57,6 +63,41 @@ public class MineSmallRoom extends CaveRoom {
Painter.set(level, r, Terrain.MINE_CRYSTAL);
}
}
} else if (Blacksmith.Quest.Type() == Blacksmith.Quest.GNOLL) {
//connections to non-secret rooms have a 7/8 chance to become empty, otherwise wall
for (Room n : connected.keySet()){
if (!(n instanceof SecretRoom) && connected.get(n).type == Door.Type.REGULAR){
if (Random.Int(8) == 0){
connected.get(n).set(Door.Type.EMPTY);
} else {
connected.get(n).set(Door.Type.WALL);
}
connected.get(n).lockTypeChanges(true);
}
}
ArrayList<Door> doors = new ArrayList<>();
for (Door d : connected.values()){
if (d.type == Door.Type.WALL){
doors.add(d);
}
}
for (Point p : getPoints()){
int cell = level.pointToCell(p);
if (level.map[cell] == Terrain.EMPTY){
float dist = 1000;
for (Door d : doors){
dist = Math.min(dist, Point.distance(p, d));
}
dist = GameMath.gate(1f, dist, 5f);
if (Random.Float((float) Math.pow(dist, 2)) < 1f) {
Painter.set(level, cell, Terrain.MINE_BOULDER);
}
}
}
}
}