// === BUILD PLAN ===
// Style: Hanseatic Backsteingotik (Baltic brick warehouse / Speicher)
// Footprint: COMPOSITE (non-rectangular) = main store 17x25 (X32..48, Z30..54)
// + west counting-house annex 12x14 (X20..31, Z38..51) + chimney bump-out
// + stone quay + canal on the +Z (water) side. Gable faces +Z (rule 15).
// Height: floors at Y13/18/23/28 (4 storeys), wall top Y32, roof ridge Y41,
// crow-step gable crest Y43, hoist beam Y42.
//
// GROUND FLOOR (top-down, 1 char = 1 block, Z increases downward = toward canal):
// Z30 #########NNN######### N = rear crow gable wall
// Z33 #.....................# . = store floor, S = stair run
// Z34 #..SSS................#
// Z40 #..SSS.......CCC......# C = crate stacks
// Z45 A==D..........BBB.....# A = annex, D = internal door, B = barrels
// Z54 ######GGGGG########### G = big loading gate (arch)
// Z56..Z66 = stone quay + bollards ; Z67+ = canal water
//
// FRONT ELEVATION (z=54, crow-stepped gable):
// ___
// __|HHH|__ H = hoist beam + winch at apex
// __| |__
// __| [ ] hatch |__ [ ] = shuttered loading hatch (one per storey)
// | [ ] |
// | [ ] |
// |===== GGGGG ========| G = arched cargo gate
//
// MATERIALS PLAN (which palette on which PART, and WHY):
// plinth : stone_bricks/mossy/cobble noise — WHY: wet stone base, grounds the tower
// walls : gradientPalette granite->bricks->red_terracotta, noise .3
// — WHY: grime dark LOW, clean red brick HIGH = fakes shadow + age (volume, not confetti)
// lesenes: same brick, PROUD by 1 block every 4 blocks — WHY: kills flat_walls, real Backsteingotik
// roof : noisePalette deepslate_tile/polished/cobbled STAIRS
// — WHY: dark slate CONTRASTS the red brick (monochrome red would read flat)
// timber : spruce_log hoist beam + spruce_trapdoor shutters — WHY: warm accent vs cold slate
// ridge : SOLID deepslate_bricks beam — WHY: top-slab ridge leaves a sky gap (ridge_gap)
// Rooms: F1 loading hall (gate, weigh station, barrels, crates, desk)
// F2 grain loft (hay sacks, barrels) / F3 ledger + spice store (shelves, chests)
// F4 hoist loft (winch, rope, watchman bunk) / annex = counting office (fireplace, desk)
// STAIR PLAN: delta = 5 per storey, single 45deg flights via staircase() in a RESERVED
// column x34..36, z32..46 — nothing is stacked there. F1->F2 south @ z33, F2->F3 south @ z40,
// F3->F4 south @ z33. Each returns flush at the upper walkY.
// === END PLAN ===
var CK = [];
function ck(m) { CK.push(m); }
ck('PLAN');
// ---------- Y levels ----------
var GY = 12; // terrain surface top block
var f1 = 13, w1 = 14;
var f2 = 18, w2 = 19;
var f3 = 23, w3 = 24;
var f4 = 28, w4 = 29;
var wallTop = 32;
var roofBase = 33;
var X1 = 32, X2 = 48, Z1 = 30, Z2 = 54;
var CX = 40; // centre X
// ---------- palettes ----------
var plinthPal = noisePalette([
{ block: 'stone_bricks', weight: 40 },
{ block: 'mossy_stone_bricks', weight: 28 },
{ block: 'cobblestone', weight: 20 },
{ block: 'cracked_stone_bricks', weight: 12 }
], { seed: 3, freq: 0.15 });
var wallPal = gradientPalette(f1, wallTop, [
{ block: 'granite', from: 0 },
{ block: 'bricks', from: 0.14 },
{ block: 'red_terracotta', from: 0.82 }
], { noise: 0.3, seed: 8 });
var roofPal = noisePalette([
{ block: 'deepslate_tile_stairs', weight: 55 },
{ block: 'polished_deepslate_stairs', weight: 25 },
{ block: 'cobbled_deepslate_stairs', weight: 20 }
], { seed: 12, freq: 0.17 });
var floorPal = noisePalette([
{ block: 'spruce_planks', weight: 55 },
{ block: 'dark_oak_planks', weight: 25 },
{ block: 'oak_planks', weight: 20 }
], { seed: 21, freq: 0.2 });
var quayPal = noisePalette([
{ block: 'stone_bricks', weight: 35 },
{ block: 'andesite', weight: 25 },
{ block: 'cobblestone', weight: 22 },
{ block: 'mossy_cobblestone', weight: 18 }
], { seed: 33, freq: 0.13 });
// ---------- TERRAIN (superpowers, never a flat square) ----------
var h = hills({ base: GY, amp: 3, scale: 0.045, seed: 4 });
var pad = flatten(h, { x0: 16, z0: 22, x1: 66, z1: 66 }, GY, 9);
var land = blob(48, 44, 47, { irregularity: 0.35, seed: 9 });
var groundMat = patches([
{ block: 'grass_block', w: 55 },
{ block: 'coarse_dirt', w: 25 },
{ block: 'podzol', w: 20 }
], 0.06, 5);
surface(land, pad, groundMat, { sub: 'dirt', deep: 'stone', depth: 4 });
ck('TERRAIN');
// ---------- CANAL + QUAY ----------
var canalZ = 67, waterY = 11;
fill(4, 5, canalZ, 92, 26, 94, 'air');
fill(4, 6, canalZ, 92, 7, 94, 'gravel');
fill(4, 8, canalZ, 92, waterY, 94, 'water');
// quay retaining wall + deck
fill(14, 7, 56, 70, GY, 66, quayPal);
for (var qz = 56; qz <= 66; qz++) {
for (var qx = 14; qx <= 70; qx++) {
if ((qx + qz) % 7 === 0) { pb(qx, GY, qz, 'gravel'); }
}
}
fill(14, 7, canalZ - 1, 70, GY, canalZ - 1, 'stone_bricks');
for (var wz = 0; wz < 3; wz++) {
for (var wx = 16; wx <= 68; wx += 1) {
if ((wx * 3 + wz * 5) % 11 === 0) { pb(wx, GY - 1 - wz, canalZ - 1, 'mossy_stone_bricks'); }
}
}
// mooring bollards on the quay
var bolX = [34, 40, 46, 26, 54];
for (var bi = 0; bi < bolX.length; bi++) {
pb(bolX[bi], GY + 1, 63, 'stripped_dark_oak_log');
ps(bolX[bi], GY + 2, 63, 'dark_oak_slab[type=bottom]');
}
ck('QUAY');
// ---------- WAREHOUSE SHELL ----------
fill(X1 + 1, f1, Z1 + 1, X2 - 1, f1, Z2 - 1, plinthPal); // ground floor slab (stone)
fill(X1, f1, Z1, X1, wallTop, Z2, wallPal); // west wall
fill(X2, f1, Z1, X2, wallTop, Z2, wallPal); // east wall
fill(X1, f1, Z1, X2, wallTop, Z1, wallPal); // rear (north) wall
fill(X1, f1, Z2, X2, wallTop, Z2, wallPal); // front (south, canal) wall
// wet stone plinth (3 rows) all round
fill(X1, f1, Z1, X1, f1 + 2, Z2, plinthPal);
fill(X2, f1, Z1, X2, f1 + 2, Z2, plinthPal);
fill(X1, f1, Z1, X2, f1 + 2, Z1, plinthPal);
fill(X1, f1, Z2, X2, f1 + 2, Z2, plinthPal);
// LESENES (proud brick strips) — wall depth, every 4 blocks on both long walls
var lesZ = [33, 37, 41, 45, 49];
for (var li = 0; li < lesZ.length; li++) {
var lz = lesZ[li];
fill(X1 - 1, f1, lz, X1 - 1, wallTop - 1, lz + 1, wallPal);
fill(X2 + 1, f1, lz, X2 + 1, wallTop - 1, lz + 1, wallPal);
ps(X1 - 1, wallTop, lz, 'brick_stairs[facing=east,half=top]');
ps(X1 - 1, wallTop, lz + 1, 'brick_stairs[facing=east,half=top]');
ps(X2 + 1, wallTop, lz, 'brick_stairs[facing=west,half=top]');
ps(X2 + 1, wallTop, lz + 1, 'brick_stairs[facing=west,half=top]');
}
// corbelled string-courses at every floor line (dogtooth band)
var bandY = [f2 - 1, f3 - 1, f4 - 1, wallTop - 1];
for (var bj = 0; bj < bandY.length; bj++) {
var by = bandY[bj];
for (var cz = Z1; cz <= Z2; cz++) {
if (cz % 2 === 0) { ps(X1 - 1, by, cz, 'brick_slab[type=top]'); ps(X2 + 1, by, cz, 'brick_slab[type=top]'); }
}
for (var cx2 = X1; cx2 <= X2; cx2++) {
if (cx2 % 2 === 0) { ps(cx2, by, Z1 - 1, 'brick_slab[type=top]'); ps(cx2, by, Z2 + 1, 'brick_slab[type=top]'); }
}
}
// timber floors
fill(X1 + 1, f2, Z1 + 1, X2 - 1, f2, Z2 - 1, floorPal);
fill(X1 + 1, f3, Z1 + 1, X2 - 1, f3, Z2 - 1, floorPal);
fill(X1 + 1, f4, Z1 + 1, X2 - 1, f4, Z2 - 1, floorPal);
// exposed ceiling beams under each timber floor
var beamY = [f2 - 1, f3 - 1, f4 - 1];
for (var bk = 0; bk < beamY.length; bk++) {
for (var bz = Z1 + 2; bz <= Z2 - 2; bz += 4) {
fill(X1 + 1, beamY[bk], bz, X2 - 1, beamY[bk], bz, 'stripped_spruce_log[axis=x]');
}
}
ck('SHELL');
// ---------- ROOF ----------
placeGableRoof(X1, X2, Z1 + 1, Z2 - 1, roofBase, 'deepslate_tile_stairs', 'deepslate_tile_slab', 'bricks');
// re-lay slopes with a noise palette (facing preserved via roofStair)
for (var rz = Z1 + 1; rz <= Z2 - 1; rz++) {
for (var s = 0; s < 9; s++) {
var wx2 = X1 - 1 + s, ex2 = X2 + 1 - s;
roofStair(wx2, roofBase + s, rz, roofPal(wx2, 0, rz), 'west');
roofStair(ex2, roofBase + s, rz, roofPal(ex2, 0, rz), 'east');
}
}
// SOLID ridge beam (never a top-slab -> no ridge_gap)
fill(CX, roofBase + 8, Z1, CX, roofBase + 8, Z2, 'deepslate_bricks');
// eave corbels so the overhang is supported, not floating
for (var ez = Z1 + 1; ez <= Z2 - 1; ez++) {
ps(X1 - 1, wallTop, ez, 'brick_slab[type=top]');
ps(X2 + 1, wallTop, ez, 'brick_slab[type=top]');
}
ck('ROOF');
// ---------- CROW-STEPPED GABLES (front z=54 = canal side, rear z=30) ----------
function crowGable(zp) {
for (var gx = X1; gx <= X2; gx++) {
var d = Math.abs(gx - CX);
var st = Math.floor(d / 2);
var topY = 43 - 2 * st;
fill(gx, roofBase, zp, gx, topY, zp, wallPal);
// coping slab on top of each step
ps(gx, topY + 1, zp, 'stone_brick_slab[type=bottom]');
if (d % 2 === 1 && d > 0) {
// the vertical riser face of the step gets a white coping too
ps(gx, topY + 2, zp, 'stone_brick_slab[type=bottom]');
}
}
// blind niches in the gable (Backsteingotik) — recessed dark panels
var nX = [36, 40, 44];
for (var ni = 0; ni < nX.length; ni++) {
var nx = nX[ni];
var nh = (nx === CX) ? 41 : 37;
fill(nx, roofBase + 1, zp, nx, nh, zp, 'red_nether_bricks');
ps(nx, nh + 1, zp, 'brick_stairs[facing=north,half=top]');
}
}
crowGable(Z2);
crowGable(Z1);
// attic clear (roof was laid first, so clear the triangle step-by-step, never the roof itself)
for (var sa = 0; sa < 8; sa++) {
fill(X1 + sa, roofBase + sa, Z1 + 1, X2 - sa, roofBase + sa, Z2 - 1, 'air');
}
// RIDGE LAST: the clear used to run one layer too high and ate the beam, leaving an
// open slot the full length of the ridge. Re-lay it AFTER every clear.
fill(CX, roofBase + 8, Z1, CX, roofBase + 8, Z2, 'deepslate_bricks');
fill(CX - 1, roofBase + 8, Z1 + 1, CX + 1, roofBase + 8, Z2 - 1, 'deepslate_bricks');
var rcz;
for (rcz = Z1; rcz <= Z2; rcz++) { ps(CX, roofBase + 9, rcz, 'deepslate_tile_slab[type=bottom]'); }
ck('GABLES');
// ---------- OPENINGS ----------
// big arched cargo gate, ground floor, canal side
fill(38, w1, Z2, 42, w1 + 2, Z2, 'air');
ps(38, w1 + 3, Z2, 'brick_stairs[facing=east,half=bottom]');
ps(42, w1 + 3, Z2, 'brick_stairs[facing=west,half=bottom]');
fill(39, w1 + 3, Z2, 41, w1 + 3, Z2, 'air');
fill(38, w1 + 4, Z2, 42, w1 + 4, Z2, 'stone_bricks');
fill(37, f1, Z2, 37, w1 + 4, Z2, 'stone_bricks');
fill(43, f1, Z2, 43, w1 + 4, Z2, 'stone_bricks');
ps(38, w1, Z2 + 1, 'dark_oak_trapdoor[facing=north,half=bottom,open=true]');
ps(42, w1, Z2 + 1, 'dark_oak_trapdoor[facing=north,half=bottom,open=true]');
// stacked shuttered loading hatches, canal side, one per upper storey
var hatchW = [w2, w3, w4];
for (var hi = 0; hi < hatchW.length; hi++) {
var hy = hatchW[hi];
fill(39, hy, Z2, 41, hy + 1, Z2, 'air');
fill(38, hy - 1, Z2, 42, hy - 1, Z2, 'stone_bricks');
ps(38, hy, Z2, 'spruce_trapdoor[facing=east,half=bottom,open=true]');
ps(42, hy, Z2, 'spruce_trapdoor[facing=west,half=bottom,open=true]');
ps(39, hy + 2, Z2, 'brick_stairs[facing=south,half=top]');
ps(41, hy + 2, Z2, 'brick_stairs[facing=south,half=top]');
// loading platform lip
ps(40, hy - 1, Z2 + 1, 'spruce_slab[type=top]');
}
// small windows on the long walls, between the lesenes, every storey
var winZ = [35, 39, 43, 47, 51];
var winY = [w1, w2, w3, w4];
for (var wi = 0; wi < winZ.length; wi++) {
for (var wj = 0; wj < winY.length; wj++) {
var vz = winZ[wi], vy = winY[wj] + 1;
fill(X1, vy, vz, X1, vy + 1, vz, 'air');
fill(X2, vy, vz, X2, vy + 1, vz, 'air');
ps(X1, vy, vz, 'glass_pane');
ps(X1, vy + 1, vz, 'glass_pane');
ps(X2, vy, vz, 'glass_pane');
ps(X2, vy + 1, vz, 'glass_pane');
ps(X1 - 1, vy, vz, 'spruce_trapdoor[facing=east,half=bottom,open=true]');
ps(X2 + 1, vy, vz, 'spruce_trapdoor[facing=west,half=bottom,open=true]');
ps(X1, vy + 2, vz, 'brick_stairs[facing=west,half=top]');
ps(X2, vy + 2, vz, 'brick_stairs[facing=east,half=top]');
}
}
ck('OPENINGS');
// ---------- STAIRS (reserved column x34..36, z32..46) ----------
staircase(35, 33, w1, w2, 'south', { width: 2, material: 'spruce_stairs', rail: 'spruce_fence' });
staircase(35, 40, w2, w3, 'south', { width: 2, material: 'spruce_stairs', rail: 'spruce_fence' });
staircase(35, 33, w3, w4, 'south', { width: 2, material: 'spruce_stairs', rail: 'spruce_fence' });
ck('STAIRS');
// ---------- INTERIOR ----------
function crate(x, y, z, tall) {
pb(x, y, z, 'barrel[facing=up]');
if (tall) { pb(x, y + 1, z, 'barrel[facing=up]'); }
}
function sackPile(x, y, z) {
pb(x, y, z, 'hay_block[axis=y]');
pb(x + 1, y, z, 'hay_block[axis=x]');
pb(x, y + 1, z, 'hay_block[axis=z]');
}
function hangLamp(x, y, z) { ps(x, y, z, 'lantern[hanging=true]'); }
// F1 — loading hall
rug(38, w1, 48, 5, 4, 'red', 'brown');
crate(44, w1, 50, true); crate(45, w1, 50, true); crate(46, w1, 50, false);
crate(44, w1, 48, false); crate(45, w1, 48, true);
pb(46, w1, 45, 'chest[facing=west]'); pb(46, w1, 44, 'chest[facing=west]');
pb(45, w1, 43, 'barrel[facing=up]'); pb(45, w1 + 1, 43, 'barrel[facing=up]');
ps(38, w1, 51, 'anvil[facing=north]'); // weigh station
pb(37, w1, 51, 'stripped_spruce_log'); ps(37, w1 + 1, 51, 'spruce_slab[type=bottom]');
ps(34, w1, 50, 'lectern[facing=east]'); // clerk's desk
pb(33, w1, 50, 'barrel[facing=up]');
chairStair(35, w1, 50, 'spruce_stairs', 'west');
pb(33, w1, 46, 'cauldron'); pb(34, w1, 46, 'composter');
sackPile(43, w1, 33); sackPile(45, w1, 35);
pb(46, w1, 38, 'cartography_table'); pb(46, w1, 39, 'barrel[facing=up]');
hangLamp(38, f2 - 2, 44); hangLamp(44, f2 - 2, 47); hangLamp(34, f2 - 2, 43);
hangLamp(40, f2 - 2, 36);
fill(33, w1, 31, 33, w1, 32, 'oak_leaves[persistent=true]');
// F2 — grain loft
sackPile(38, w2, 34); sackPile(41, w2, 33); sackPile(44, w2, 35);
sackPile(38, w2, 48); sackPile(43, w2, 50);
crate(45, w2, 44, true); crate(46, w2, 44, false); crate(45, w2, 45, false);
crate(33, w2, 47, true); crate(33, w2, 48, false);
pb(46, w2, 51, 'chest[facing=west]');
ps(40, w2, 50, 'smithing_table');
pb(34, w2, 51, 'barrel[facing=up]'); pb(34, w2 + 1, 51, 'barrel[facing=up]');
rug(39, w2, 45, 3, 3, 'brown', 'white');
hangLamp(40, f3 - 2, 40); hangLamp(45, f3 - 2, 48); hangLamp(34, f3 - 2, 36);
// F3 — ledger room + spice store
shelfWall(44, w3, 31, 'south', 6, 2);
ps(43, w3, 33, 'lectern[facing=east]');
chairStair(42, w3, 33, 'dark_oak_stairs', 'east');
pb(42, w3, 35, 'dark_oak_fence'); pb(42, w3 + 1, 35, 'oak_pressure_plate');
pb(41, w3, 35, 'barrel[facing=up]');
crate(45, w3, 46, true); crate(46, w3, 46, true); crate(45, w3, 47, false);
crate(33, w3, 44, true); crate(34, w3, 44, false);
pb(38, w3, 50, 'chest[facing=north]'); pb(39, w3, 50, 'chest[facing=north]');
sackPile(36, w3, 49);
rug(40, w3, 40, 4, 4, 'blue', 'light_gray');
pb(46, w3, 41, 'flower_pot'); pb(33, w3, 51, 'potted_fern');
hangLamp(43, f4 - 2, 34); hangLamp(40, f4 - 2, 45); hangLamp(45, f4 - 2, 50);
// F4 — hoist loft with the winch, rope and a watchman's corner
fill(39, w4, 50, 41, w4, 52, 'spruce_planks');
fill(38, w4 + 3, 50, 42, w4 + 3, 50, 'stripped_spruce_log[axis=x]'); // winch axle bearer
pb(40, w4 + 2, 51, 'stripped_spruce_log[axis=x]');
ps(39, w4 + 2, 51, 'spruce_fence'); ps(41, w4 + 2, 51, 'spruce_fence');
pb(40, w4 + 1, 51, 'barrel[facing=up]');
placeBed(34, w4, 33, 'red', 'south');
pb(33, w4, 33, 'spruce_fence'); pb(33, w4 + 1, 33, 'oak_pressure_plate');
ps(33, w4 + 2, 33, 'lantern[hanging=false]');
pb(45, w4, 33, 'barrel[facing=up]'); crate(45, w4, 35, true);
sackPile(44, w4, 44); crate(34, w4, 46, true);
ps(38, w4, 36, 'crafting_table'); pb(37, w4, 36, 'chest[facing=south]');
rug(38, w4, 42, 4, 3, 'yellow', 'brown');
hangLamp(40, roofBase + 2, 40); hangLamp(38, roofBase + 1, 47);
ck('INTERIOR');
// ---------- HOIST BEAM + WINCH (projecting from the gable apex) ----------
fill(CX, 42, Z2, CX, 42, Z2 + 5, 'stripped_spruce_log[axis=z]');
ps(CX, 41, Z2 + 1, 'spruce_stairs[facing=south,half=top]');
ps(CX - 1, 42, Z2 + 4, 'spruce_fence');
ps(CX + 1, 42, Z2 + 4, 'spruce_fence');
for (var ry = 36; ry <= 41; ry++) { pb(CX, ry, Z2 + 4, 'iron_bars'); }
pb(CX, 35, Z2 + 4, 'barrel[facing=up]');
ps(CX, 34, Z2 + 4, 'spruce_slab[type=top]');
ps(CX, 43, Z2, 'lantern[hanging=true]');
// gable-apex support brackets
ps(CX - 1, 41, Z2 + 1, 'spruce_stairs[facing=west,half=top]');
ps(CX + 1, 41, Z2 + 1, 'spruce_stairs[facing=east,half=top]');
// ---------- WEST ANNEX (counting house) ----------
var AX1 = 20, AX2 = 31, AZ1 = 38, AZ2 = 51;
var aTop = 21, aRoof = 22, aw = w1;
fill(AX1 + 1, f1, AZ1 + 1, AX2 - 1, f1, AZ2 - 1, floorPal);
fill(AX1, f1, AZ1, AX1, aTop, AZ2, wallPal);
fill(AX2, f1, AZ1, AX2, aTop, AZ2, wallPal);
fill(AX1, f1, AZ1, AX2, aTop, AZ1, wallPal);
fill(AX1, f1, AZ2, AX2, aTop, AZ2, wallPal);
fill(AX1, f1, AZ1, AX1, f1 + 2, AZ2, plinthPal);
fill(AX1, f1, AZ1, AX2, f1 + 2, AZ1, plinthPal);
fill(AX1, f1, AZ2, AX2, f1 + 2, AZ2, plinthPal);
// half-timbered upper band for material contrast
for (var tz = AZ1; tz <= AZ2; tz += 3) {
fill(AX1, aTop - 4, tz, AX1, aTop, tz, 'dark_oak_log[axis=y]');
fill(AX2, aTop - 4, tz, AX2, aTop, tz, 'dark_oak_log[axis=y]');
}
fill(AX1, aTop - 4, AZ1, AX2, aTop - 4, AZ1, 'dark_oak_log[axis=x]');
fill(AX1, aTop, AZ1, AX2, aTop, AZ1, 'dark_oak_log[axis=x]');
placeGableRoof(AX1, AX2, AZ1 + 1, AZ2 - 1, aRoof, 'deepslate_tile_stairs', 'deepslate_tile_slab', 'bricks');
fill(AX1 + 5, aRoof + 5, AZ1, AX1 + 6, aRoof + 5, AZ2, 'deepslate_bricks');
// annex gables solid
for (var agx = AX1; agx <= AX2; agx++) {
var ad = Math.min(agx - AX1, AX2 - agx);
var atY = aRoof + ad;
if (atY > aRoof + 5) { atY = aRoof + 5; }
fill(agx, aRoof, AZ1, agx, atY, AZ1, wallPal);
fill(agx, aRoof, AZ2, agx, atY, AZ2, wallPal);
}
for (var sc = 0; sc < 6; sc++) {
fill(AX1 + sc, aRoof + sc, AZ1 + 1, AX2 - sc, aRoof + sc, AZ2 - 1, 'air');
}
// annex chimney bump-out (west face)
fill(AX1 - 1, f1, 43, AX1 - 1, 30, 45, 'bricks');
fill(AX1 - 1, 26, 43, AX1 - 1, 30, 45, 'deepslate_bricks');
fill(AX1, aw, 44, AX1, aw + 2, 44, 'air');
ps(AX1, aw, 44, 'campfire[lit=true,facing=east]');
fill(AX1 - 1, aw, 44, AX1 - 1, aw + 3, 44, 'air');
fill(AX1 - 1, aw + 4, 44, AX1 - 1, 25, 44, 'air');
// annex door to the quay + internal door to the warehouse
fill(26, aw, AZ2, 26, aw + 1, AZ2, 'air');
ps(26, aw, AZ2, 'dark_oak_door[facing=south,half=lower,hinge=left]');
ps(26, aw + 1, AZ2, 'dark_oak_door[facing=south,half=upper,hinge=left]');
fill(AX2, aw, 45, X1, aw + 1, 45, 'air');
ps(AX2, aw, 45, 'oak_door[facing=east,half=lower,hinge=left]');
ps(AX2, aw + 1, 45, 'oak_door[facing=east,half=upper,hinge=left]');
// annex windows
var awZ = [41, 44, 48];
for (var ai = 0; ai < awZ.length; ai++) {
fill(AX1, aw + 1, awZ[ai], AX1, aw + 2, awZ[ai], 'air');
ps(AX1, aw + 1, awZ[ai], 'glass_pane'); ps(AX1, aw + 2, awZ[ai], 'glass_pane');
ps(AX1 - 1, aw + 1, awZ[ai], 'spruce_trapdoor[facing=east,half=bottom,open=true]');
}
fill(23, aw + 1, AZ2, 24, aw + 2, AZ2, 'air');
ps(23, aw + 1, AZ2, 'glass_pane'); ps(24, aw + 1, AZ2, 'glass_pane');
ps(23, aw + 2, AZ2, 'glass_pane'); ps(24, aw + 2, AZ2, 'glass_pane');
ps(23, aw, AZ2 + 1, 'spruce_slab[type=top]');
pb(24, aw, AZ2 + 1, 'flower_pot');
// annex interior — counting office
rug(24, aw, 46, 5, 4, 'green', 'brown');
fill(27, aw, 47, 29, aw, 47, 'dark_oak_fence');
fill(27, aw + 1, 47, 29, aw + 1, 47, 'dark_oak_pressure_plate');
chairStair(28, aw, 48, 'dark_oak_stairs', 'north');
chairStair(28, aw, 46, 'dark_oak_stairs', 'south');
shelfWall(22, aw, 40, 'south', 5, 2);
ps(25, aw, 41, 'lectern[facing=south]');
pb(29, aw, 40, 'chest[facing=south]'); pb(30, aw, 40, 'barrel[facing=up]');
pb(22, aw, 49, 'barrel[facing=up]'); pb(22, aw + 1, 49, 'barrel[facing=up]');
ps(23, aw, 43, 'cartography_table');
hangLamp(26, aTop - 1, 45); hangLamp(29, aTop - 1, 48); hangLamp(23, aTop - 1, 41);
ps(27, aw, 42, 'flower_pot');
ck('ANNEX');
// ---------- EXTERIOR / LANDSCAPING ----------
// cobbled lane from the gate down to the quay
for (var lz = Z2 + 1; lz <= 66; lz++) {
for (var lx = 36; lx <= 44; lx++) {
pb(lx, GY, lz, ((lx * 5 + lz * 3) % 9 === 0) ? 'gravel' : 'cobblestone');
}
}
for (var lx2 = 26; lx2 <= 44; lx2++) { pb(lx2, GY, 56, 'cobblestone'); pb(lx2, GY, 57, 'cobblestone'); }
lampPost(35, GY + 1, 58, 4, 'dark_oak_fence');
lampPost(45, GY + 1, 58, 4, 'dark_oak_fence');
lampPost(30, GY + 1, 55, 4, 'dark_oak_fence');
lampPost(52, GY + 1, 62, 4, 'dark_oak_fence');
// dockside goods
crate(37, GY + 1, 59, true); crate(38, GY + 1, 59, false); crate(37, GY + 1, 60, false);
crate(44, GY + 1, 61, true); crate(45, GY + 1, 61, false);
sackPile(48, GY + 1, 58);
pb(43, GY + 1, 58, 'chest[facing=south]');
ps(50, GY + 1, 60, 'oak_fence'); ps(50, GY + 2, 60, 'oak_fence');
ps(50, GY + 3, 60, 'oak_fence'); ps(51, GY + 3, 60, 'oak_fence');
ps(51, GY + 2, 60, 'iron_bars'); pb(51, GY + 1, 60, 'barrel[facing=up]'); // small dock crane
// nets / greenery / weathering on the quay
for (var vg = 0; vg < 26; vg++) {
var gx2 = 16 + (vg * 7) % 52;
var gz2 = 57 + (vg * 5) % 9;
if ((vg % 3) === 0) { ps(gx2, GY + 1, gz2, 'moss_carpet'); }
else if ((vg % 3) === 1) { pb(gx2, GY, gz2, 'mossy_cobblestone'); }
else { ps(gx2, GY + 1, gz2, 'brown_carpet'); }
}
for (var vv = 40; vv <= 66; vv += 3) { ps(15, GY, vv, 'vine[south=true]'); }
// low quay fence to the east
for (var fz = 58; fz <= 66; fz += 1) { if (fz % 2 === 0) { pb(58, GY + 1, fz, 'oak_fence'); } }
// a couple of moored rowboats (blocks, not entities)
fill(33, waterY, 69, 36, waterY, 70, 'spruce_slab[type=bottom]');
ps(32, waterY, 69, 'spruce_stairs[facing=east,half=bottom]');
ps(37, waterY, 70, 'spruce_stairs[facing=west,half=bottom]');
fill(46, waterY, 71, 49, waterY, 72, 'dark_oak_slab[type=bottom]');
// mooring posts in the water
pb(38, waterY + 1, 69, 'stripped_dark_oak_log'); pb(38, waterY, 69, 'stripped_dark_oak_log');
pb(44, waterY + 1, 70, 'stripped_dark_oak_log'); pb(44, waterY, 70, 'stripped_dark_oak_log');
// grass / bushes on the landward side
for (var bg = 0; bg < 30; bg++) {
var bx2 = 18 + (bg * 11) % 46;
var bz2 = 18 + (bg * 7) % 12;
ps(bx2, GY + 1, bz2, (bg % 4 === 0) ? 'oak_leaves[persistent=true]' : 'short_grass');
}
for (var fl = 0; fl < 12; fl++) {
ps(20 + (fl * 5) % 40, GY + 1, 24 + (fl * 3) % 6, (fl % 2 === 0) ? 'poppy' : 'dandelion');
}
ck('EXTERIOR');
ck('DONE');