// === BUILD PLAN ===
// Style: Scottish Highland distillery (harled stone, slate, pagoda malt kiln) — LAYERED build
// Footprint: T-plan. Still house 13x19 (x28..40, z30..48, ridge along Z) + malt kiln tower 9x9
// (x30..38, z22..30) at the NORTH end + bonded warehouse 13x9 (x14..26, z36..44) west,
// joined by a link corridor. Front door on the MAX-Z facade (faces the camera).
// Height: walls Y14..22 (8 air) | ridge Y29 | kiln tower Y30 + curved pagoda tiers to Y44
//
// GROUND FLOOR (top-down, 1 char = 1 block, Z down = toward camera):
// z22 ######### <- pagoda malt kiln (fire pit + drying grate)
// z30 ####D####
// z31 # MEZZANINE OVER (Y18) # mash tun (O)
// z40 # [ ]washbacks [ ] #
// z45 # (O) still (O) still#
// z48 ##W##DD##W## <- ENTRANCE facade (+Z, toward camera)
// west wing: warehouse of dunnage cask racks, linked at z39..41
//
// FRONT (+Z) ELEVATION:
// /\ pagoda behind
// / \ _/\_
// |W DD W| |__|
// |______|
//
// MATERIALS PLAN (LAYERED: placeholders -> masks -> texture LAST):
// walls : placeholder white_wool -> replaceMasked gradientPalette mossy_cobble->calcite->smooth_quartz
// — WHY: harled whitewash that gets damp/mossy at the bottom (fake AO, describes the volume)
// tower : placeholder light_gray_wool -> replaceMasked noisePalette calcite/white_terracotta/diorite
// wareh. : placeholder brown_wool -> replaceMasked noisePalette dark stone + dark_oak frame
// roof : deepslate_tile / cobbled_deepslate / deepslate_brick STAIRS via per-stair palette (facing kept)
// accents: waxed copper stills, spruce gallery, iron bars, lanterns
// Rooms: Still room (mash tun, 2 washbacks, 2 pot stills, spirit safe), Mezzanine gallery (casks, desk),
// Malt kiln (hearth, grate, malt sacks), Warehouse (dunnage racks 3 high)
// STAIR PLAN: delta walkY14 -> mezzWalkY19 = 5 -> staircase(30,44,14,19,'north'), lands flush on the gallery lip
// === END PLAN ===
var padY = 12;
var floorY = padY + 1; // 13
var walkY = floorY + 1; // 14
var wallTopY = 22;
var roofBaseY = wallTopY + 1;
var mezzFloorY = 18;
var mezzWalkY = mezzFloorY + 1;
// === TERRAIN (superpowers: blob + hills + flatten + river + surface) ===
var land = blob(38, 36, 38, {irregularity: 0.38, seed: 15});
var h = hills({base: 10, amp: 4, scale: 0.045, seed: 6});
h = flatten(h, {x0: 12, z0: 20, x1: 60, z1: 58}, padY, 9);
var ground = h;
var riv = null;
try {
riv = river({from: [-4, 6], to: [78, 16], heightFn: h, halfWidth: 5, widthVar: 0.45, seed: 4, bounds: land.bounds});
ground = riv.height;
} catch (e) { riv = null; }
var mat = function (x, z) {
if (riv && riv.inChannel(x, z)) return 'gravel';
var n = noise2d('perlin', x, z, {seed: 22});
if (ground(x, z) > padY + 2) return n > 0.55 ? 'stone' : 'coarse_dirt';
return n > 0.62 ? 'moss_block' : (n > 0.3 ? 'grass_block' : 'podzol');
};
surface(land, ground, mat, {sub: 'dirt', deep: 'stone', depth: 5});
// === LAYER 1 : FORM IN PLACEHOLDERS ===
var SHx1 = 28, SHx2 = 40, SHz1 = 30, SHz2 = 48;
var KTx1 = 30, KTx2 = 38, KTz1 = 22, KTz2 = 30, KTtop = 30;
var WHx1 = 14, WHx2 = 26, WHz1 = 36, WHz2 = 44, WHtop = 19;
function perim(x1, z1, x2, z2, y1, y2, pat) {
fill(x1, y1, z1, x2, y2, z1, pat);
fill(x1, y1, z2, x2, y2, z2, pat);
fill(x1, y1, z1, x1, y2, z2, pat);
fill(x2, y1, z1, x2, y2, z2, pat);
}
// plinths (stone platform, 1 block proud — Highland buildings sit on a plinth)
fill(SHx1 - 1, padY - 3, SHz1 - 1, SHx2 + 1, floorY, SHz2 + 1, 'stone_bricks');
fill(KTx1 - 1, padY - 3, KTz1 - 1, KTx2 + 1, floorY, KTz2 + 1, 'stone_bricks');
fill(WHx1 - 1, padY - 3, WHz1 - 1, WHx2 + 1, floorY, WHz2 + 1, 'stone_bricks');
fill(26, padY - 3, 38, 28, floorY, 42, 'stone_bricks');
// walls as placeholders
perim(SHx1, SHz1, SHx2, SHz2, floorY + 1, wallTopY, 'white_wool');
perim(KTx1, KTz1, KTx2, KTz2, floorY + 1, KTtop, 'light_gray_wool');
perim(WHx1, WHz1, WHx2, WHz2, floorY + 1, WHtop, 'brown_wool');
perim(26, 38, 28, 42, floorY + 1, 18, 'brown_wool');
// solid infill so clearMasked has something to carve
fill(SHx1, floorY + 1, SHz1, SHx2, wallTopY, SHz2, 'white_wool');
fill(KTx1, floorY + 1, KTz1, KTx2, KTtop, KTz2, 'light_gray_wool');
fill(WHx1, floorY + 1, WHz1, WHx2, WHtop, WHz2, 'brown_wool');
fill(26, floorY + 1, 38, 28, 18, 42, 'brown_wool');
// === LAYER 2 : CARVE WITH MASKS (rooms, doors, windows) ===
clearMasked(SHx1 + 1, walkY, SHz1 + 1, SHx2 - 1, wallTopY - 1, SHz2 - 1, onlyMaterial('white_wool'));
clearMasked(KTx1 + 1, walkY, KTz1 + 1, KTx2 - 1, KTtop - 1, KTz2 - 1, onlyMaterial('light_gray_wool'));
clearMasked(WHx1 + 1, walkY, WHz1 + 1, WHx2 - 1, WHtop - 1, WHz2 - 1, onlyMaterial('brown_wool'));
clearMasked(27, walkY, 39, 27, 17, 41, onlyMaterial('brown_wool'));
// link corridor doorways
clearMasked(26, walkY, 39, 26, walkY + 2, 41, onlyMaterial('brown_wool'));
clearMasked(28, walkY, 39, 28, walkY + 2, 41, onlyMaterial('white_wool'));
// still house <-> kiln doorway
clearMasked(33, walkY, SHz1, 35, walkY + 2, SHz1, onlyMaterial('white_wool'));
clearMasked(33, walkY, KTz2, 35, walkY + 2, KTz2, onlyMaterial('light_gray_wool'));
// MAIN ENTRANCE on the +Z facade
clearMasked(33, walkY, SHz2, 34, walkY + 3, SHz2, onlyMaterial('white_wool'));
// small-paned windows: front, and rows down both long walls
var wslots = [];
function carveWin(x1, y1, z1, x2, y2, z2, ph) {
clearMasked(x1, y1, z1, x2, y2, z2, onlyMaterial(ph));
wslots.push([x1, y1, z1, x2, y2, z2]);
}
carveWin(30, walkY + 1, SHz2, 31, walkY + 3, SHz2, 'white_wool');
carveWin(36, walkY + 1, SHz2, 37, walkY + 3, SHz2, 'white_wool');
carveWin(32, mezzWalkY + 1, SHz2, 36, mezzWalkY + 2, SHz2, 'white_wool');
var wz;
for (wz = 33; wz <= 45; wz += 4) {
carveWin(SHx1, walkY + 1, wz, SHx1, walkY + 3, wz + 1, 'white_wool');
carveWin(SHx2, walkY + 1, wz, SHx2, walkY + 3, wz + 1, 'white_wool');
carveWin(SHx1, mezzWalkY + 1, wz, SHx1, mezzWalkY + 2, wz, 'white_wool');
carveWin(SHx2, mezzWalkY + 1, wz, SHx2, mezzWalkY + 2, wz, 'white_wool');
}
// kiln slit windows
carveWin(KTx1, walkY + 4, 25, KTx1, walkY + 6, 27, 'light_gray_wool');
carveWin(KTx2, walkY + 4, 25, KTx2, walkY + 6, 27, 'light_gray_wool');
carveWin(33, walkY + 8, KTz1, 35, walkY + 10, KTz1, 'light_gray_wool');
// warehouse door (+Z) + slits
clearMasked(20, walkY, WHz2, 20, walkY + 1, WHz2, onlyMaterial('brown_wool'));
carveWin(17, walkY + 2, WHz2, 17, walkY + 3, WHz2, 'brown_wool');
carveWin(23, walkY + 2, WHz2, 23, walkY + 3, WHz2, 'brown_wool');
carveWin(WHx1, walkY + 2, 39, WHx1, walkY + 3, 41, 'brown_wool');
// === LAYER 3 : TEXTURE LAST (replaceMasked over the placeholders) ===
var shPal = gradientPalette(floorY, wallTopY, [
{block: 'mossy_cobblestone', from: 0}, {block: 'cobblestone', from: 0.18},
{block: 'calcite', from: 0.38}, {block: 'smooth_quartz', from: 0.68}, {block: 'white_terracotta', from: 0.85}
], {noise: 0.3, seed: 12});
var ktPal = noisePalette([
{block: 'calcite', weight: 40}, {block: 'white_terracotta', weight: 30},
{block: 'diorite', weight: 18}, {block: 'smooth_quartz', weight: 12}
], {seed: 3, freq: 0.11});
var whPal = noisePalette([
{block: 'cobblestone', weight: 38}, {block: 'mossy_cobblestone', weight: 27},
{block: 'stone_bricks', weight: 20}, {block: 'andesite', weight: 15}
], {seed: 8, freq: 0.12});
replaceMasked(SHx1 - 2, floorY, SHz1 - 2, SHx2 + 2, wallTopY + 2, SHz2 + 2, shPal, onlyMaterial('white_wool'));
replaceMasked(KTx1 - 2, floorY, KTz1 - 2, KTx2 + 2, KTtop + 2, KTz2 + 2, ktPal, onlyMaterial('light_gray_wool'));
replaceMasked(WHx1 - 2, floorY, WHz1 - 2, WHx2 + 2, WHtop + 2, WHz2 + 2, whPal, onlyMaterial('brown_wool'));
replaceMasked(25, floorY, 37, 29, 19, 43, whPal, onlyMaterial('brown_wool'));
// glaze every carved window slot with panes (only where air)
var i, s;
for (i = 0; i < wslots.length; i++) {
s = wslots[i];
fillMasked(s[0], s[1], s[2], s[3], s[4], s[5], 'glass_pane', onlyAir());
}
// astragals / mullions: iron bars across the middle row of the big windows
for (wz = 33; wz <= 45; wz += 4) {
fill(SHx1, walkY + 2, wz, SHx1, walkY + 2, wz + 1, 'iron_bars');
fill(SHx2, walkY + 2, wz, SHx2, walkY + 2, wz + 1, 'iron_bars');
}
// === WALL DEPTH : pilasters, sills, cornice ===
for (var px = SHx1; px <= SHx2; px += 4) {
fill(px, floorY + 1, SHz1 - 1, px, wallTopY, SHz1 - 1, 'stone_bricks');
fill(px, floorY + 1, SHz2 + 1, px, wallTopY, SHz2 + 1, 'stone_bricks');
}
for (var pz = SHz1 + 2; pz <= SHz2 - 2; pz += 4) {
fill(SHx1 - 1, floorY + 1, pz, SHx1 - 1, wallTopY, pz, 'stone_bricks');
fill(SHx2 + 1, floorY + 1, pz, SHx2 + 1, wallTopY, pz, 'stone_bricks');
}
perim(SHx1 - 1, SHz1 - 1, SHx2 + 1, SHz2 + 1, wallTopY, wallTopY, 'stone_brick_slab[type=top]');
perim(WHx1 - 1, WHz1 - 1, WHx2 + 1, WHz2 + 1, WHtop, WHtop, 'cobblestone_slab[type=top]');
// window sills
for (wz = 33; wz <= 45; wz += 4) {
ps(SHx1 - 1, walkY, wz, 'stone_brick_slab[type=top]');
ps(SHx2 + 1, walkY, wz, 'stone_brick_slab[type=top]');
}
// entrance surround + doors (+Z facade)
ps(33, walkY, SHz2, 'dark_oak_door[facing=north,half=lower,hinge=left]');
ps(33, walkY + 1, SHz2, 'dark_oak_door[facing=north,half=upper,hinge=left]');
ps(34, walkY, SHz2, 'dark_oak_door[facing=north,half=lower,hinge=right]');
ps(34, walkY + 1, SHz2, 'dark_oak_door[facing=north,half=upper,hinge=right]');
fill(32, walkY, SHz2 + 1, 32, walkY + 3, SHz2 + 1, 'stone_bricks');
fill(35, walkY, SHz2 + 1, 35, walkY + 3, SHz2 + 1, 'stone_bricks');
fill(32, walkY + 4, SHz2 + 1, 35, walkY + 4, SHz2 + 1, 'stone_brick_slab[type=top]');
ps(33, walkY + 4, SHz2 + 1, 'oak_wall_sign[facing=south]');
ps(34, walkY + 4, SHz2 + 1, 'oak_wall_sign[facing=south]');
pb(32, walkY + 3, SHz2 + 2, 'chain[axis=y]'); ps(32, walkY + 2, SHz2 + 2, 'lantern[hanging=true]');
pb(35, walkY + 3, SHz2 + 2, 'chain[axis=y]'); ps(35, walkY + 2, SHz2 + 2, 'lantern[hanging=true]');
// === ROOF : slate gable, ridge along Z (slopes E/W), per-stair palette keeps facing ===
var slate = noisePalette([
{block: 'deepslate_tile_stairs', weight: 46}, {block: 'cobbled_deepslate_stairs', weight: 30},
{block: 'deepslate_brick_stairs', weight: 24}
], {seed: 5, freq: 0.17});
var halfW = 7; // width 13
for (var rz = SHz1 - 1; rz <= SHz2 + 1; rz++) {
for (var st = 0; st < halfW; st++) {
roofStair(SHx1 - 1 + st, roofBaseY + st, rz, slate(SHx1 + st, 0, rz), 'west');
roofStair(SHx2 + 1 - st, roofBaseY + st, rz, slate(SHx2 - st, 0, rz), 'east');
}
pb(34, roofBaseY + halfW - 1, rz, 'deepslate_tiles'); // solid ridge beam
}
// gable triangles at both ends
for (var gs = 0; gs < halfW; gs++) {
for (var gx = SHx1 + gs; gx <= SHx2 - gs; gx++) {
pb(gx, roofBaseY + gs, SHz1, shPal(gx, roofBaseY + gs, SHz1));
pb(gx, roofBaseY + gs, SHz2, shPal(gx, roofBaseY + gs, SHz2));
}
}
// gable vent + skylight strip on the +Z gable
fill(33, roofBaseY + 2, SHz2, 34, roofBaseY + 3, SHz2, 'glass_pane');
// eave brackets under the overhang (visual support, upside-down stairs)
for (var bz = SHz1; bz <= SHz2; bz += 3) {
ps(SHx1 - 2, roofBaseY - 1, bz, 'spruce_stairs[facing=east,half=top]');
ps(SHx2 + 2, roofBaseY - 1, bz, 'spruce_stairs[facing=west,half=top]');
}
// warehouse roof (ridge along X, slopes N/S)
var whHalf = 5;
for (var wx = WHx1 - 1; wx <= WHx2 + 1; wx++) {
for (var ws = 0; ws < whHalf; ws++) {
roofStair(wx, WHtop + 1 + ws, WHz1 - 1 + ws, slate(wx, 0, WHz1 + ws), 'north');
roofStair(wx, WHtop + 1 + ws, WHz2 + 1 - ws, slate(wx, 0, WHz2 - ws), 'south');
}
pb(wx, WHtop + whHalf, 40, 'deepslate_tiles');
}
for (var ws2 = 0; ws2 < whHalf; ws2++) {
for (var wgz = WHz1 + ws2; wgz <= WHz2 - ws2; wgz++) {
pb(WHx1, WHtop + 1 + ws2, wgz, whPal(WHx1, WHtop + 1 + ws2, wgz));
pb(WHx2, WHtop + 1 + ws2, wgz, whPal(WHx2, WHtop + 1 + ws2, wgz));
}
}
// link corridor flat roof
fill(26, 19, 38, 28, 19, 42, 'spruce_slab[type=top]');
// === MALT KILN : tower body already placed; add curved pagoda tiers ===
function ringStairs(x1, z1, x2, z2, y, matFn) {
var a;
for (a = x1; a <= x2; a++) {
roofStair(a, y, z1, matFn(a, 0, z1), 'north');
roofStair(a, y, z2, matFn(a, 0, z2), 'south');
}
for (a = z1 + 1; a <= z2 - 1; a++) {
roofStair(x1, y, a, matFn(x1, 0, a), 'west');
roofStair(x2, y, a, matFn(x2, 0, a), 'east');
}
}
function pagodaTier(x1, z1, x2, z2, baseY, matFn) {
// thin eave lip (widest), then two stair layers stepping in and up = curved eave
perim(x1 - 2, z1 - 2, x2 + 2, z2 + 2, baseY, baseY, 'deepslate_tile_slab[type=top]');
ringStairs(x1 - 1, z1 - 1, x2 + 1, z2 + 1, baseY + 1, matFn);
ringStairs(x1, z1, x2, z2, baseY + 2, matFn);
fill(x1 + 1, baseY + 3, z1 + 1, x2 - 1, baseY + 3, z2 - 1, 'deepslate_tiles');
// upturned corner tips (Japanese eave flick)
ps(x1 - 2, baseY + 1, z1 - 2, 'deepslate_tile_stairs[facing=south,half=top]');
ps(x2 + 2, baseY + 1, z1 - 2, 'deepslate_tile_stairs[facing=south,half=top]');
ps(x1 - 2, baseY + 1, z2 + 2, 'deepslate_tile_stairs[facing=north,half=top]');
ps(x2 + 2, baseY + 1, z2 + 2, 'deepslate_tile_stairs[facing=north,half=top]');
}
// dark timber cornice under the first tier
perim(KTx1 - 1, KTz1 - 1, KTx2 + 1, KTz2 + 1, KTtop, KTtop, 'dark_oak_log[axis=x]');
pagodaTier(KTx1, KTz1, KTx2, KTz2, KTtop + 1, slate);
// second stage (inset per pagoda rule) + its own curved roof
fill(KTx1 + 2, KTtop + 4, KTz1 + 2, KTx2 - 2, 37, KTz2 - 2, 'air');
perim(KTx1 + 2, KTz1 + 2, KTx2 - 2, KTz2 - 2, KTtop + 4, 37, ktPal);
fill(KTx1 + 2, KTtop + 4, KTz1 + 2, KTx1 + 2, 37, KTz1 + 2, 'dark_oak_log[axis=y]');
fill(KTx2 - 2, KTtop + 4, KTz1 + 2, KTx2 - 2, 37, KTz1 + 2, 'dark_oak_log[axis=y]');
fill(KTx1 + 2, KTtop + 4, KTz2 - 2, KTx1 + 2, 37, KTz2 - 2, 'dark_oak_log[axis=y]');
fill(KTx2 - 2, KTtop + 4, KTz2 - 2, KTx2 - 2, 37, KTz2 - 2, 'dark_oak_log[axis=y]');
fill(34, 36, KTz1 + 2, 34, 36, KTz2 - 2, 'spruce_trapdoor[facing=north,half=top,open=false]');
pagodaTier(KTx1 + 2, KTz1 + 2, KTx2 - 2, KTz2 - 2, 38, slate);
// copper cowl + vane on top
makeCylinder(34, 42, 26, 'waxed_exposed_copper', 1, 2, true);
pb(34, 44, 26, 'waxed_copper_block');
pb(34, 45, 26, 'lightning_rod');
// === INTERIORS ===
var stonePal = noisePalette([
{block: 'stone_bricks', weight: 38}, {block: 'andesite', weight: 26},
{block: 'cobblestone', weight: 20}, {block: 'mossy_stone_bricks', weight: 16}
], {seed: 27, freq: 0.14});
fill(SHx1 + 1, floorY, SHz1 + 1, SHx2 - 1, floorY, SHz2 - 1, stonePal);
fill(KTx1 + 1, floorY, KTz1 + 1, KTx2 - 1, floorY, KTz2 - 1, stonePal);
fill(WHx1 + 1, floorY, WHz1 + 1, WHx2 - 1, floorY, WHz2 - 1, 'coarse_dirt');
fill(27, floorY, 39, 27, floorY, 41, stonePal);
// ceiling tie beams
for (var tb = SHz1 + 3; tb <= SHz2 - 3; tb += 4) {
fill(SHx1 + 1, wallTopY - 1, tb, SHx2 - 1, wallTopY - 1, tb, 'dark_oak_log[axis=x]');
}
// mash tun (spruce, copper lid)
makeCylinder(33, walkY, 34, noisePalette([{block: 'spruce_planks', weight: 60}, {block: 'stripped_spruce_log', weight: 40}], {seed: 2}), 3, 4, true);
makeCylinder(33, walkY + 4, 34, 'waxed_exposed_copper', 3, 1, true);
pb(33, walkY + 5, 34, 'waxed_copper_block');
ps(30, walkY, 34, 'lever[face=wall,facing=west]');
// two washbacks
function washback(cx, cz) {
makeCylinder(cx, walkY, cz, 'spruce_planks', 2, 3, true);
makeCylinder(cx, walkY + 3, cz, 'dark_oak_planks', 2, 1, false);
pb(cx, walkY + 3, cz, 'water');
ps(cx, walkY, cz - 2, 'spruce_trapdoor[facing=south,half=bottom,open=false]');
}
washback(31, 40); washback(37, 40);
// two copper pot stills (open to the roof, seen from the entrance)
function potStill(cx, cz) {
fill(cx - 2, floorY, cz - 2, cx + 2, floorY, cz + 2, 'polished_andesite');
makeCylinder(cx, walkY, cz, 'bricks', 2, 1, true);
ps(cx, walkY, cz + 2, 'campfire[lit=true]');
makeCylinder(cx, walkY + 1, cz, noisePalette([{block: 'waxed_copper_block', weight: 60}, {block: 'waxed_exposed_copper', weight: 25}, {block: 'waxed_cut_copper', weight: 15}], {seed: 31}), 2, 4, true);
makeCylinder(cx, walkY + 5, cz, 'waxed_cut_copper', 1, 3, true);
pb(cx, walkY + 8, cz, 'waxed_copper_block');
pb(cx, walkY + 9, cz, 'waxed_copper_block');
pb(cx, walkY + 9, cz + 1, 'waxed_exposed_copper');
pb(cx, walkY + 8, cz + 2, 'waxed_exposed_copper');
pb(cx, walkY + 7, cz + 2, 'copper_bulb[lit=true]');
makeCylinder(cx, walkY + 3, cz, 'waxed_oxidized_cut_copper', 2, 1, false);
}
potStill(31, 45); potStill(37, 45);
// spirit safe + bench beside the entrance
pb(34, walkY, 46, 'stripped_dark_oak_log');
ps(34, walkY + 1, 46, 'glass');
pb(33, walkY, 46, 'stripped_dark_oak_log');
ps(33, walkY + 1, 46, 'brewing_stand');
ps(35, walkY, 46, 'barrel[facing=up]');
rug(32, walkY, 47, 4, 1, 'red', 'brown');
// mezzanine gallery + posts + railing, then the staircase (cuts its own hole)
fill(SHx1 + 1, mezzFloorY, SHz1 + 1, SHx2 - 1, mezzFloorY, 39, 'spruce_planks');
fill(33, mezzFloorY, 40, 35, mezzFloorY, 40, 'spruce_planks');
for (var mx = SHx1 + 2; mx <= SHx2 - 2; mx += 4) {
for (var mz = SHz1 + 2; mz <= 38; mz += 4) {
fill(mx, walkY, mz, mx, mezzFloorY - 1, mz, 'spruce_log[axis=y]');
}
}
for (var rx = SHx1 + 1; rx <= SHx2 - 1; rx++) {
if (rx < 33 || rx > 35) pb(rx, mezzWalkY, 39, 'spruce_fence');
}
// stair moved to the CENTRE AISLE — the old run at x30 came up inside a washback
fill(33, walkY, 39, 35, mezzFloorY - 1, 45, 'air');
fill(33, floorY, 39, 35, floorY, 45, stonePal);
staircase(34, 44, walkY, mezzWalkY, 'north', {material: 'dark_oak_stairs', rail: 'dark_oak_fence'});
// gallery contents
for (var gcx = 30; gcx <= 38; gcx += 3) {
pb(gcx, mezzWalkY, 33, 'barrel[facing=up]');
pb(gcx, mezzWalkY + 1, 33, 'barrel[facing=up]');
pb(gcx + 1, mezzWalkY, 33, 'hay_block');
}
ps(31, mezzWalkY, 36, 'lectern[facing=east]');
chairStair(30, mezzWalkY, 36, 'dark_oak_stairs', 'east');
pb(35, mezzWalkY, 36, 'dark_oak_fence'); pb(35, mezzWalkY + 1, 36, 'dark_oak_pressure_plate');
pb(36, mezzWalkY, 36, 'barrel[facing=up]');
rug(33, mezzWalkY, 37, 4, 2, 'brown', 'gray');
pb(33, wallTopY - 1, 35, 'chain[axis=y]'); ps(33, wallTopY - 2, 35, 'lantern[hanging=true]');
pb(37, wallTopY - 1, 37, 'chain[axis=y]'); ps(37, wallTopY - 2, 37, 'lantern[hanging=true]');
// ground-floor lighting under the gallery
for (var glz = 33; glz <= 47; glz += 4) {
pb(29, glz > 39 ? wallTopY - 1 : mezzFloorY - 1, glz, 'chain[axis=y]');
ps(29, (glz > 39 ? wallTopY - 1 : mezzFloorY - 1) - 1, glz, 'lantern[hanging=true]');
pb(39, glz > 39 ? wallTopY - 1 : mezzFloorY - 1, glz, 'chain[axis=y]');
ps(39, (glz > 39 ? wallTopY - 1 : mezzFloorY - 1) - 1, glz, 'lantern[hanging=true]');
}
// malt kiln interior
fill(32, floorY, 24, 36, floorY, 28, 'stone_bricks');
fill(33, walkY, 25, 35, walkY, 27, 'iron_bars');
ps(34, floorY, 26, 'campfire[lit=true]');
fill(31, walkY, 23, 31, walkY + 1, 25, 'hay_block');
pb(37, walkY, 23, 'barrel[facing=up]'); pb(37, walkY, 28, 'composter');
pb(36, walkY, 29, 'cauldron[level=2]');
ps(31, walkY, 28, 'ladder[facing=east]');
ps(31, walkY + 1, 28, 'ladder[facing=east]');
ps(31, walkY + 2, 28, 'ladder[facing=east]');
pb(34, walkY + 6, 26, 'chain[axis=y]'); ps(34, walkY + 5, 26, 'lantern[hanging=true]');
// warehouse: dunnage cask racks 3 high
for (var dz = WHz1 + 2; dz <= WHz2 - 2; dz += 3) {
for (var dx = WHx1 + 2; dx <= WHx2 - 2; dx += 3) {
pb(dx, walkY, dz, 'oak_log[axis=x]'); pb(dx + 1, walkY, dz, 'oak_log[axis=x]');
pb(dx, walkY + 1, dz, 'barrel[facing=up]'); pb(dx + 1, walkY + 1, dz, 'barrel[facing=up]');
pb(dx, walkY + 2, dz, 'barrel[facing=up]'); pb(dx + 1, walkY + 2, dz, 'barrel[facing=up]');
}
}
pb(20, WHtop - 1, 40, 'chain[axis=y]'); ps(20, WHtop - 2, 40, 'lantern[hanging=true]');
pb(16, WHtop - 1, 43, 'chain[axis=y]'); ps(16, WHtop - 2, 43, 'lantern[hanging=true]');
ps(24, walkY, WHz2 - 1, 'cartography_table');
// === EXTERIOR : yard, wall, riverside ===
var pathPal = noisePalette([{block: 'gravel', weight: 42}, {block: 'cobblestone', weight: 33}, {block: 'andesite', weight: 25}], {seed: 19});
for (var qz = 49; qz <= 60; qz++) {
for (var qx = 31; qx <= 36; qx++) {
pb(qx, Math.floor(ground(qx, qz)), qz, pathPal(qx, 0, qz));
}
}
for (var yx = 16; yx <= 44; yx++) {
pb(yx, Math.floor(ground(yx, 47)), 47, pathPal(yx, 0, 47));
pb(yx, Math.floor(ground(yx, 48)), 48, pathPal(yx, 0, 48));
}
// low mossy stone wall around the site (follows the ground)
function wallRun(x1, z1, x2, z2) {
var a;
if (x1 === x2) { for (a = z1; a <= z2; a++) pb(x1, Math.floor(ground(x1, a)) + 1, a, 'mossy_cobblestone_wall'); }
else { for (a = x1; a <= x2; a++) pb(a, Math.floor(ground(a, z1)) + 1, z1, 'mossy_cobblestone_wall'); }
}
wallRun(10, 58, 62, 58);
wallRun(10, 20, 10, 58);
wallRun(62, 20, 62, 58);
wallRun(10, 20, 62, 20);
fill(31, padY, 58, 36, padY + 3, 58, 'air');
pb(30, padY + 1, 58, 'mossy_cobblestone_wall'); pb(37, padY + 1, 58, 'mossy_cobblestone_wall');
pb(30, padY + 2, 58, 'stone_brick_slab[type=bottom]'); pb(37, padY + 2, 58, 'stone_brick_slab[type=bottom]');
lampPost(30, padY + 1, 52, 4, 'cobblestone_wall');
lampPost(37, padY + 1, 52, 4, 'cobblestone_wall');
lampPost(24, padY + 1, 47, 4, 'cobblestone_wall');
lampPost(44, padY + 1, 34, 4, 'cobblestone_wall');
// outdoor cask stack + cart by the yard
for (var oy = 0; oy < 3; oy++) {
for (var oxx = 42 + oy; oxx <= 50 - oy; oxx += 2) {
pb(oxx, padY + 1 + oy, 44, 'barrel[facing=up]');
pb(oxx, padY + 1 + oy, 46, 'barrel[facing=up]');
}
}
pb(44, padY + 1, 50, 'oak_log[axis=x]'); pb(45, padY + 1, 50, 'oak_log[axis=x]');
ps(46, padY + 1, 50, 'oak_fence');
// riverside: jetty + mossy boulders + reeds
if (riv) {
for (var jz = 18; jz <= 24; jz++) {
for (var jx = 33; jx <= 35; jx++) {
pb(jx, riv.waterY + 1, jz, 'spruce_planks');
}
pb(32, riv.waterY + 1, jz, 'spruce_fence');
pb(36, riv.waterY + 1, jz, 'spruce_fence');
}
pb(34, riv.waterY + 2, 19, 'barrel[facing=up]');
pb(33, riv.waterY + 2, 20, 'barrel[facing=up]');
lampPost(36, riv.waterY + 1, 22, 3, 'oak_fence');
}
for (var brx = 18; brx <= 54; brx += 6) {
var bgy = Math.floor(ground(brx, 26 + (brx % 5)));
makeSphere(brx, bgy, 26 + (brx % 5), noisePalette([{block: 'mossy_cobblestone', weight: 58}, {block: 'stone', weight: 27}, {block: 'andesite', weight: 15}], {seed: 14}), 2, true);
}
try {
placeTree(20, padY + 1, 28, 'spruce');
placeTree(48, padY + 1, 26, 'spruce');
placeTree(52, padY + 1, 52, 'oak');
placeTree(16, padY + 1, 52, 'spruce');
placeTree(24, padY + 1, 24, 'spruce');
} catch (e) { }
// ground cover
for (var vx = 12; vx <= 60; vx++) {
for (var vz = 20; vz <= 58; vz++) {
var nn = noise2d('perlin', vx * 1.9, vz * 1.9, {seed: 41});
if (nn > 0.87 && (vx < 26 || vx > 42 || vz < 28 || vz > 50)) {
var gy2 = Math.floor(ground(vx, vz));
pb(vx, gy2 + 1, vz, nn > 0.945 ? 'fern' : (nn > 0.91 ? 'grass' : 'moss_carpet'));
}
}
}