Skip to content

Commit

Permalink
Bigger and deeper dungeons.
Browse files Browse the repository at this point in the history
  • Loading branch information
Bernardo Sulzbach committed Oct 12, 2015
1 parent 03021d1 commit ca1a0e2
Show file tree
Hide file tree
Showing 4 changed files with 161 additions and 16 deletions.
104 changes: 95 additions & 9 deletions src/main/java/org/dungeon/game/DungeonCreator.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
package org.dungeon.game;

import org.dungeon.game.LocationPreset.Type;
import org.dungeon.logging.DungeonLogger;
import org.dungeon.util.Percentage;

import org.jetbrains.annotations.NotNull;

Expand All @@ -29,7 +31,14 @@
*/
class DungeonCreator implements Serializable {

private static final MinimumBoundingRectangle minimumBoundingRectangle = new MinimumBoundingRectangle(1, 1);
private static final Percentage HORIZONTAL_EXPANSION_PROBABILITY = Percentage.fromString("50%");

/**
* It is of uttermost importance that we respect this rectangle.
*
* Currently a 5x1 So that we can make dungeons like this: R=R=R (where R is a room and = is a corridor).
*/
private static final MinimumBoundingRectangle minimumBoundingRectangle = new MinimumBoundingRectangle(5, 1);
private final DungeonDistributor distributor;

public DungeonCreator(DungeonDistributor distributor) {
Expand All @@ -46,29 +55,106 @@ private static LocationPreset getRandomEntrancePreset() {
return Random.select(entrancePresets);
}

private static LocationPreset getRandomStairwayPreset() {
LocationPresetStore locationPresetStore = GameData.getLocationPresetStore();
List<LocationPreset> entrancePresets = locationPresetStore.getLocationPresetsByType(Type.DUNGEON_STAIRWAY);
return Random.select(entrancePresets);
}

private static LocationPreset getRandomRoomPreset() {
LocationPresetStore locationPresetStore = GameData.getLocationPresetStore();
List<LocationPreset> entrancePresets = locationPresetStore.getLocationPresetsByType(Type.DUNGEON_ROOM);
return Random.select(entrancePresets);
}

private static LocationPreset getRandomCorridorPreset() {
LocationPresetStore locationPresetStore = GameData.getLocationPresetStore();
List<LocationPreset> entrancePresets = locationPresetStore.getLocationPresetsByType(Type.DUNGEON_CORRIDOR);
return Random.select(entrancePresets);
}

/**
* Creates a dungeon placing the entrance at the specified point. The world should not have a location at the
* specified point.
*/
public void createDungeon(@NotNull World world, @NotNull Point entrance) {
createEntrance(world, entrance);
Location dungeonRoom = new Location(getRandomRoomPreset(), world);
world.addLocation(dungeonRoom, new Point(entrance, Direction.DOWN));
Point mainRoomPoint = createEntrance(world, entrance);
Location mainRoomLocation = createMainRoom(world, mainRoomPoint);
finishDungeon(world, mainRoomPoint, mainRoomLocation);
}

private void createEntrance(@NotNull World world, @NotNull Point entrance) {
/**
* Creates the dungeon's entrance and the necessary stairways.
*
* Returns the point where the main dungeon room should be.
*/
private Point createEntrance(@NotNull World world, @NotNull Point entrance) {
// The entrance.
if (world.alreadyHasLocationAt(entrance)) {
throw new IllegalStateException("world has location at the specified entrance.");
}
Location dungeonEntrance = new Location(getRandomEntrancePreset(), world);
world.addLocation(dungeonEntrance, entrance);
distributor.registerDungeonEntrance(entrance);
// The stairway.
Point stairwayPoint = new Point(entrance, Direction.DOWN);
// Note that all DUNGEON_STAIRWAY presets are blocked towards North, East, South, and West.
world.addLocation(new Location(getRandomStairwayPreset(), world), stairwayPoint);
return new Point(stairwayPoint, Direction.DOWN);
}

private LocationPreset getRandomRoomPreset() {
LocationPresetStore locationPresetStore = GameData.getLocationPresetStore();
List<LocationPreset> entrancePresets = locationPresetStore.getLocationPresetsByType(Type.DUNGEON_ROOM);
return Random.select(entrancePresets);
@NotNull
private Location createMainRoom(@NotNull World world, Point mainRoomPoint) {
// Note that all DUNGEON_ROOM presets are open on all directions. It is up to the code to properly block them.
Location dungeonRoom = new Location(getRandomRoomPreset(), world);
dungeonRoom.getBlockedEntrances().block(Direction.NORTH);
dungeonRoom.getBlockedEntrances().block(Direction.DOWN);
dungeonRoom.getBlockedEntrances().block(Direction.SOUTH);
world.addLocation(dungeonRoom, mainRoomPoint); // The main room. All dungeons have one.
return dungeonRoom;
}

/**
* Finishes the dungeon by randomly deciding to expand it to the east and west.
*
* If this method does not make a corridor to east or west, it blocks that entrance in the main room to prevent
* glitches.
*/
private void finishDungeon(@NotNull World world, Point mainRoomPoint, Location mainRoomLocation) {
// UPDATING THIS LOGIC MAY REQUIRE YOU TO UPDATE THE minimumBoundingRectangle variable.
if (Random.roll(HORIZONTAL_EXPANSION_PROBABILITY)) {
expandTowards(world, mainRoomPoint, Direction.EAST);
} else {
mainRoomLocation.getBlockedEntrances().block(Direction.EAST);
}
if (Random.roll(HORIZONTAL_EXPANSION_PROBABILITY)) {
expandTowards(world, mainRoomPoint, Direction.WEST);
} else {
mainRoomLocation.getBlockedEntrances().block(Direction.WEST);
}
}

private void expandTowards(@NotNull World world, @NotNull Point origin, Direction direction) {
Point corridorPoint = new Point(origin, direction);
if (world.alreadyHasLocationAt(corridorPoint)) {
DungeonLogger.warning("Found an existing location when attempting to expand a Dungeon at " + corridorPoint + ".");
}
// Note that all DUNGEON_CORRIDOR presets have blocked UP and DOWN. It is up to the code to properly block the rest.
Location corridorLocation = new Location(getRandomCorridorPreset(), world);
corridorLocation.getBlockedEntrances().block(Direction.NORTH);
corridorLocation.getBlockedEntrances().block(Direction.SOUTH);
world.addLocation(corridorLocation, corridorPoint);
Point roomPoint = new Point(corridorPoint, direction);
if (world.alreadyHasLocationAt(roomPoint)) {
DungeonLogger.warning("Found an existing location when attempting to expand a Dungeon at " + roomPoint + ".");
}
Location roomLocation = new Location(getRandomRoomPreset(), world);
roomLocation.getBlockedEntrances().block(Direction.UP);
roomLocation.getBlockedEntrances().block(Direction.NORTH);
roomLocation.getBlockedEntrances().block(Direction.DOWN);
roomLocation.getBlockedEntrances().block(Direction.SOUTH);
roomLocation.getBlockedEntrances().block(direction);
world.addLocation(roomLocation, roomPoint);
}

}
2 changes: 1 addition & 1 deletion src/main/java/org/dungeon/game/DungeonDistributor.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
/**
* A class that is responsible for distributing dungeons.
*/
public class DungeonDistributor implements Serializable {
class DungeonDistributor implements Serializable {

private static final Percentage dungeonProbability = Percentage.fromString("2%");
private static final Set<Point> entrances = new HashSet<Point>();
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/dungeon/game/LocationPreset.java
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,6 @@ public void setBlobSize(int blobSize) {
this.blobSize = blobSize;
}

enum Type {RIVER, BRIDGE, DUNGEON_ENTRANCE, DUNGEON_ROOM, LAND}
enum Type {RIVER, BRIDGE, DUNGEON_ENTRANCE, DUNGEON_STAIRWAY, DUNGEON_ROOM, DUNGEON_CORRIDOR, LAND}

}
69 changes: 64 additions & 5 deletions src/main/resources/locations.json
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,28 @@
}
]
},
{
"id": "DUNGEON_STAIRWAY",
"type": "DUNGEON_STAIRWAY",
"name": {
"singular": "Dungeon Stairway"
},
"color": [
192,
192,
192
],
"symbol": "S",
"info": "A set of stone steps.",
"blobSize": 0,
"lightPermittivity": 0.2,
"blockedEntrances": [
"N",
"E",
"S",
"W"
]
},
{
"id": "DUNGEON_ROOM",
"type": "DUNGEON_ROOM",
Expand All @@ -182,11 +204,48 @@
"blobSize": 0,
"lightPermittivity": 0.0,
"blockedEntrances": [
"N",
"E",
"D",
"S",
"W"
],
"spawners": [
{
"id": "FROG",
"population": 2,
"delay": 2
},
{
"id": "HUGE_SPIDER",
"population": 1,
"delay": 4
}
],
"items": [
{
"id": "TORCH",
"probability": 1.0
},
{
"id": "TOME_OF_PERCEIVE",
"probability": 0.05
}
]
},
{
"id": "DUNGEON_CORRIDOR",
"type": "DUNGEON_CORRIDOR",
"name": {
"singular": "Dungeon Corridor"
},
"color": [
192,
192,
192
],
"symbol": "=",
"info": "A dark corridor with stone walls.",
"blobSize": 0,
"lightPermittivity": 0.0,
"blockedEntrances": [
"U",
"D"
],
"spawners": [
{
Expand Down

0 comments on commit ca1a0e2

Please sign in to comment.