Skip to content

Commit

Permalink
Smaller themed keeps.
Browse files Browse the repository at this point in the history
  • Loading branch information
munificent committed Jan 7, 2019
1 parent 168fb92 commit 1a7d8f3
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 16 deletions.
2 changes: 1 addition & 1 deletion lib/src/content/monster/monsters.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class Monsters {
"undead/skeleton",
];
for (var group in groups) {
breeds.defineTags(group);
breeds.defineTags("monster/$group");
}

// TODO: https://en.wikipedia.org/wiki/P%C3%BAca
Expand Down
32 changes: 26 additions & 6 deletions lib/src/content/stage/architectural_style.dart
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,14 @@ class ArchitecturalStyle {
decorDensity: 0.07,
create: () => Dungeon());

// TODO: Decide if we should ever do full-size keeps anymore.
// Generic default dungeon style.
addStyle("keep",
startFrequency: 2.0,
endFrequency: 5.0,
decor: "keep",
decorDensity: 0.07,
create: () => Keep());
// addStyle("keep",
// startFrequency: 2.0,
// endFrequency: 5.0,
// decor: "keep",
// decorDensity: 0.07,
// create: () => Keep());

// TODO: Define more.
// TODO: More catacomb styles with different tile types and tuned params.
Expand Down Expand Up @@ -141,6 +142,25 @@ class ArchitecturalStyle {
pit("plant", start: 15, end: 40);
pit("eye", start: 20, end: 100);
pit("dragon", start: 60, end: 100);

// Keeps.
keep(String monsters, {int start, int end}) {
addStyle("$monsters keep",
start: start,
end: end,
startFrequency: 2.0,
decor: "keep",
decorDensity: 0.07,
monsters: monsters,
// Keep spawns monsters itself.
monsterDensity: 0.0,
itemDensity: 1.5,
canFill: false,
create: () => Keep(5));
}

keep("goblin", start: 3, end: 16);
// TODO: More.
}

final String name;
Expand Down
1 change: 1 addition & 0 deletions lib/src/content/stage/decorator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ class Decorator {

var experience = 0;
spawn(Breed breed, Vec pos) {
if (_architect.stage.actorAt(pos) != null) return;
if (!_canSpawn(breed)) return;

if (breed.flags.unique) _spawnedUniques.add(breed);
Expand Down
63 changes: 54 additions & 9 deletions lib/src/content/stage/keep.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'package:piecemeal/piecemeal.dart';

import '../../engine.dart';
import 'architect.dart';
import 'painter.dart';
import 'room.dart';

// TODO: Give at an optional max number of rooms so that it
Expand All @@ -15,10 +16,28 @@ import 'room.dart';
class Keep extends Architecture {
static JunctionSet debugJunctions;

// TODO: Fields to tune numbers below.
final JunctionSet _junctions;

final JunctionSet _junctions = JunctionSet();
int _placedRooms = 0;

int _maxRooms;

factory Keep([int maxRooms]) {
if (maxRooms != null) {
// TODO: For now, small keeps always pack rooms in densely. Have
// different styles of keep for different monsters?
return Keep._(rng.triangleInt(maxRooms, maxRooms ~/ 2), TakeFrom.oldest);
} else {
// TODO: Do we still need this case? Do we want keeps that span the whole
// dungeon?
return Keep._(null, rng.item(TakeFrom.values));
}
}

Keep._(this._maxRooms, TakeFrom takeFrom)
: _junctions = JunctionSet(takeFrom);

// TODO: Different paint styles.
String get paintStyle => "stone";

Iterable<String> build() sync* {
Expand All @@ -27,12 +46,34 @@ class Keep extends Architecture {
// If we are covering the whole area, attempt to place multiple rooms.
// That way, if there disconnected areas (like a river cutting through the
// stage, we can still hopefully cover it all.
var startingRooms = region == Region.everywhere ? 20 : 1;
var startingRooms = 1;
if (region == Region.everywhere && _maxRooms == null) {
startingRooms = 20;
}

for (var i = 0; i < startingRooms; i++) {
yield* _growRooms();
}
}

bool spawnMonsters(Painter painter) {
var tiles = painter.ownedTiles
.where((pos) => painter.getTile(pos).isWalkable)
.toList();
rng.shuffle(tiles);

for (var pos in tiles) {
// TODO: Make this tunable?
if (!rng.oneIn(20)) continue;

var group = rng.item(style.monsterGroups);
var breed = painter.chooseBreed(painter.depth, tag: group);
painter.spawnMonster(pos, breed);
}

return true;
}

Iterable<String> _growRooms() sync* {
if (!_tryPlaceStartingRoom()) return;

Expand All @@ -46,11 +87,14 @@ class Keep extends Architecture {

if (_tryAttachRoom(junction)) {
yield "Room";
continue;
}

// TODO: Make tunable.
if (junction.tries < 5) _junctions.add(junction);
_placedRooms++;
if (_maxRooms != null && _placedRooms >= _maxRooms) break;
} else {
// Couldn't place the room, but maybe try the junction again.
// TODO: Make tunable.
if (junction.tries < 5) _junctions.add(junction);
}
}
}

Expand Down Expand Up @@ -221,11 +265,12 @@ class Junction {
enum TakeFrom { newest, oldest, random }

class JunctionSet {
// TODO: Let the architectural style control this.
final TakeFrom _takeFrom = rng.item(TakeFrom.values);
final TakeFrom _takeFrom;
final Map<Vec, Junction> _byPosition = {};
final List<Junction> _junctions = [];

JunctionSet(this._takeFrom);

bool get isNotEmpty => _junctions.isNotEmpty;

Junction operator [](Vec pos) => _byPosition[pos];
Expand Down
2 changes: 2 additions & 0 deletions web/debug/dungeon.dart
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ void hover(Vec pos) {
Future generate() async {
hues.clear();
Keep.debugJunctions = null;
Debug.densityMap = null;

_game = Game(content, save, depth);
var thisGame = _game;
var stage = _game.stage;
Expand Down

0 comments on commit 1a7d8f3

Please sign in to comment.