Add arches, which demand to be collapsed
This commit is contained in:
parent
9ad13f7a5a
commit
01e316d979
Binary file not shown.
Before Width: | Height: | Size: 737 B After Width: | Height: | Size: 867 B |
BIN
assets/images/vaults/warehouse_1x1.png
Normal file
BIN
assets/images/vaults/warehouse_1x1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 820 B |
BIN
assets/images/vaults/warehouse_2x2.png
Normal file
BIN
assets/images/vaults/warehouse_2x2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 792 B |
@ -82,7 +82,7 @@ class Bitmap<T> {
|
||||
}
|
||||
|
||||
void set(int x, int y, T value) {
|
||||
assert(x < 0 || y < 0 || x >= size.dx || y >= size.dy);
|
||||
assert(!(x < 0 || y < 0 || x >= size.dx || y >= size.dy));
|
||||
data[y * size.dx + x] = value;
|
||||
}
|
||||
|
||||
@ -101,6 +101,22 @@ class Bitmap<T> {
|
||||
}
|
||||
}
|
||||
|
||||
void blitFromWith(Bitmap<T> other, int dx, int dy, T Function(T, T) merge) {
|
||||
assert(rect.containsRect(geo.Rect(dx, dy, other.size.dx, other.size.dy)));
|
||||
var x0 = other.rect.x0;
|
||||
var y0 = other.rect.x0;
|
||||
var x1 = other.rect.x1;
|
||||
var y1 = other.rect.y1;
|
||||
var myW = size.dx;
|
||||
var otW = other.size.dx;
|
||||
for (var x = x0; x < x1; x++) {
|
||||
for (var y = y0; y < y1; y++) {
|
||||
data[(y + dy) * myW + (x + dx)] =
|
||||
merge(data[(y + dy) * myW + (x + dx)], other.data[y * otW + x]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Bitmap<T> flip() {
|
||||
var geo.Size(:dx, :dy) = size;
|
||||
|
||||
|
@ -31,7 +31,7 @@ void main() async {
|
||||
while (true) {
|
||||
clear();
|
||||
Vault output = Generator(math.Random(seed), vaults)
|
||||
.generate(Requirement(16, 32, 16, 24, DirectionSet({})), false);
|
||||
.generate(Requirement(16, 32, 16, 24, DirectionSet({})));
|
||||
var geo.Size(dx: w, dy: h) = output.size;
|
||||
for (var y = 0; y < h; y++) {
|
||||
for (var x = 0; x < w; x++) {
|
||||
@ -44,7 +44,12 @@ void main() async {
|
||||
case VaultTile.door:
|
||||
cursor.puts("d");
|
||||
case VaultTile.wall:
|
||||
case VaultTile.defaultwall:
|
||||
cursor.puts("#");
|
||||
case VaultTile.archpronewall:
|
||||
cursor.puts("%");
|
||||
case VaultTile.archwall:
|
||||
cursor.puts("\$");
|
||||
case VaultTile.exit:
|
||||
cursor.puts("X");
|
||||
case VaultTile.meta0:
|
||||
|
@ -12,7 +12,7 @@ part 'requirement.dart';
|
||||
part 'vault.dart';
|
||||
part 'vaults.dart';
|
||||
|
||||
const vaultTries = 10;
|
||||
const vaultTries = 30;
|
||||
|
||||
class Generator {
|
||||
final math.Random _random;
|
||||
@ -21,7 +21,12 @@ class Generator {
|
||||
|
||||
Generator(this._random, this._vaults);
|
||||
|
||||
Vault generate(Requirement requirement, bool canBeVault) {
|
||||
Vault generate(Requirement requirement) {
|
||||
var out = _generateOriented(requirement, false);
|
||||
return _finalize(out);
|
||||
}
|
||||
|
||||
Vault _generateOriented(Requirement requirement, bool canBeVault) {
|
||||
if (canBeVault) {
|
||||
Vault? suggested = _suggest(vaultTries, requirement);
|
||||
if (suggested != null) {
|
||||
@ -47,7 +52,7 @@ class Generator {
|
||||
}
|
||||
|
||||
req2 = unReorientRequirement(requirement, orientation);
|
||||
var out2 = _generate(req2);
|
||||
var out2 = _generateBsp(req2);
|
||||
var out1 = reorientVault(out2, orientation);
|
||||
|
||||
// log("$orientation ${requirement.vx} ${requirement.vy} ${req2.vx} ${req2.vy} ${out2.vx} ${out2.vy} ${out1.vx} ${out1.vy}");
|
||||
@ -58,7 +63,7 @@ class Generator {
|
||||
return out1;
|
||||
}
|
||||
|
||||
Vault _generate(Requirement req) {
|
||||
Vault _generateBsp(Requirement req) {
|
||||
var vxMin = req.vxMin;
|
||||
var vyMin = req.vyMin;
|
||||
var vxMax = req.vxMax;
|
||||
@ -72,7 +77,7 @@ class Generator {
|
||||
var vyRand = _random.nextInt(vyMax + 1 - vyMin) + vyMin;
|
||||
|
||||
if (vxMax < 2 || vyMax < 2) {
|
||||
return Vault.blank(vxMax, vyRand, VaultTile.wall, req.smooth);
|
||||
return Vault.blank(vxMax, vyRand, VaultTile.defaultwall, req.smooth);
|
||||
} else if (vxMax < 9 || (vxMax - 2) * (vyMax - 2) < 12) {
|
||||
var v2 = Vault.blank(
|
||||
vxMax - 2, vyMax - 2, VaultTile.bspfloor, req.smooth.clone());
|
||||
@ -83,7 +88,7 @@ class Generator {
|
||||
var leftReq = Requirement(
|
||||
math.max(vxMin - 4, 2), vxMax - 4, vyMin, vyMax, req.smooth.clone());
|
||||
leftReq.smooth.directions.add(Direction.right);
|
||||
var leftChild = generate(leftReq, true);
|
||||
var leftChild = _generateOriented(leftReq, true);
|
||||
|
||||
var vyMinRight = vyMin;
|
||||
var vyMaxRight = vyMax;
|
||||
@ -100,21 +105,21 @@ class Generator {
|
||||
req.smooth.clone(),
|
||||
);
|
||||
rightReq.smooth.directions.add(Direction.left);
|
||||
var rightChild = generate(rightReq, true);
|
||||
var rightChild = _generateOriented(rightReq, true);
|
||||
|
||||
var vxTotal = leftChild.vx + rightChild.vx - 1;
|
||||
var vyTotal = math.max(leftChild.vy, rightChild.vy);
|
||||
|
||||
if (smoothUp) {
|
||||
var v =
|
||||
Vault.blank(vxTotal, vyTotal, VaultTile.wall, req.smooth.clone());
|
||||
var v = Vault.blank(
|
||||
vxTotal, vyTotal, VaultTile.defaultwall, req.smooth.clone());
|
||||
v.blitFrom(leftChild, 0, 0);
|
||||
v.blitFrom(rightChild, leftChild.vx - 1, 0);
|
||||
return v;
|
||||
}
|
||||
if (smoothDown) {
|
||||
var v =
|
||||
Vault.blank(vxTotal, vyTotal, VaultTile.wall, req.smooth.clone());
|
||||
var v = Vault.blank(
|
||||
vxTotal, vyTotal, VaultTile.defaultwall, req.smooth.clone());
|
||||
v.blitFrom(leftChild, 0, vyTotal - leftChild.vy);
|
||||
v.blitFrom(rightChild, leftChild.vx - 1, vyTotal - rightChild.vy);
|
||||
return v;
|
||||
@ -126,7 +131,8 @@ class Generator {
|
||||
if (vyTMax > vyTotal) {
|
||||
vyTotal += _random.nextInt(vyTMax - vyTotal);
|
||||
}
|
||||
var v = Vault.blank(vxTotal, vyTotal, VaultTile.wall, req.smooth.clone());
|
||||
var v = Vault.blank(
|
||||
vxTotal, vyTotal, VaultTile.defaultwall, req.smooth.clone());
|
||||
if (_random.nextBool()) {
|
||||
v.blitFrom(leftChild, 0, 0);
|
||||
v.blitFrom(rightChild, leftChild.vx - 1, vyTotal - rightChild.vy);
|
||||
@ -230,8 +236,8 @@ class Generator {
|
||||
sz.dy,
|
||||
DirectionSet(
|
||||
{Direction.up, Direction.left, Direction.down, Direction.right}));
|
||||
var inner = generate(metaRequirement, true);
|
||||
var dest = Vault(Bitmap.blank(vault.vx, vault.vy, VaultTile.wall),
|
||||
var inner = _generateOriented(metaRequirement, true);
|
||||
var dest = Vault(Bitmap.blank(vault.vx, vault.vy, VaultTile.defaultwall),
|
||||
vault.smooth.clone());
|
||||
dest.blitFrom(vault, 0, 0);
|
||||
dest.blitFrom(inner, i.rect.x0, i.rect.y0);
|
||||
@ -240,4 +246,52 @@ class Generator {
|
||||
|
||||
return vault;
|
||||
}
|
||||
|
||||
Vault _finalize(Vault subj) {
|
||||
var vx = subj.vx, vy = subj.vy;
|
||||
subj = Vault.blankWith(vx, vy, (x, y) {
|
||||
var bed = VaultTile.defaultwall;
|
||||
if (x == 0 || x == vx - 1 || y == 0 || y == vy - 1) {
|
||||
bed = VaultTile.wall;
|
||||
}
|
||||
var tile = mergeVaultTile(bed, subj.tiles.get(x, y)!);
|
||||
return tile;
|
||||
}, subj.smooth.clone());
|
||||
|
||||
bool canSupportArch(VaultTile? tile) {
|
||||
return tile == VaultTile.bspfloor ||
|
||||
tile == VaultTile.floor ||
|
||||
tile == VaultTile.exit;
|
||||
}
|
||||
|
||||
var orthoOffsets = [(0, -1), (0, 1), (-1, 0), (1, 0)];
|
||||
List<(int, int)> newArches = [];
|
||||
for (int x = 0; x < vx; x++) {
|
||||
for (int y = 0; y < vy; y++) {
|
||||
var t = subj.tiles.get(x, y);
|
||||
if (t == VaultTile.archwall) {
|
||||
var supporters = 0;
|
||||
for (var (dx, dy) in orthoOffsets) {
|
||||
VaultTile? neighbor = subj.tiles.get(x + dx, y + dy);
|
||||
if (canSupportArch(neighbor)) {
|
||||
supporters++;
|
||||
}
|
||||
}
|
||||
|
||||
if (supporters == 2) {
|
||||
newArches.add((x, y));
|
||||
}
|
||||
subj.tiles.set(x, y, VaultTile.wall);
|
||||
}
|
||||
if (t == VaultTile.archpronewall || t == VaultTile.defaultwall) {
|
||||
subj.tiles.set(x, y, VaultTile.wall);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var (ax, ay) in newArches) {
|
||||
subj.tiles.set(ax, ay, VaultTile.floor);
|
||||
}
|
||||
return subj;
|
||||
}
|
||||
}
|
||||
|
@ -14,12 +14,17 @@ class Vault {
|
||||
return Vault(Bitmap.blank(vx, vy, lt), smooth);
|
||||
}
|
||||
|
||||
static Vault blankWith(
|
||||
int vx, int vy, VaultTile Function(int, int) lt, DirectionSet smooth) {
|
||||
return Vault(Bitmap.blankWith(vx, vy, lt), smooth);
|
||||
}
|
||||
|
||||
void clear(VaultTile lt) {
|
||||
tiles.clear(lt);
|
||||
}
|
||||
|
||||
void blitFrom(Vault other, int dx, int dy) {
|
||||
tiles.blitFrom(other.tiles, dx, dy);
|
||||
tiles.blitFromWith(other.tiles, dx, dy, mergeVaultTile);
|
||||
}
|
||||
|
||||
Vault flip() {
|
||||
@ -34,3 +39,16 @@ class Vault {
|
||||
return Vault(tiles.rotateLeft(), smooth.rotateLeft());
|
||||
}
|
||||
}
|
||||
|
||||
VaultTile mergeVaultTile(VaultTile bottom, VaultTile top) {
|
||||
if (bottom == VaultTile.wall && top == VaultTile.archpronewall) {
|
||||
return VaultTile.wall;
|
||||
}
|
||||
if (bottom == VaultTile.wall && top == VaultTile.archwall) {
|
||||
return VaultTile.wall;
|
||||
}
|
||||
if (bottom == VaultTile.archwall && top == VaultTile.archpronewall) {
|
||||
return VaultTile.archwall;
|
||||
}
|
||||
return top;
|
||||
}
|
||||
|
@ -73,6 +73,9 @@ enum VaultTile {
|
||||
door,
|
||||
bspfloor,
|
||||
floor,
|
||||
defaultwall, // defaultwall is in generated rooms and is overwritten by anything
|
||||
archpronewall, // archpronewall cannot overwrite wall or archwall
|
||||
archwall, // archwall cannot overwrite wall.
|
||||
wall,
|
||||
}
|
||||
|
||||
@ -91,6 +94,10 @@ VaultTile? colorToVaultTile(int c) {
|
||||
case 0x000000:
|
||||
case 0x707070:
|
||||
return VaultTile.wall;
|
||||
case 0xFF8000:
|
||||
return VaultTile.archwall;
|
||||
case 0x7F4000:
|
||||
return VaultTile.archpronewall;
|
||||
case 0xFFFFFF:
|
||||
case 0xFFFF00:
|
||||
case 0xFF00FF:
|
||||
|
Loading…
Reference in New Issue
Block a user