// Hakka tulou roundhouse
// circular earth wall, 3 floors, courtyard in the middle, tile roof
var floorY = 0;
var wallTop = 15;
var outerR = 21;
var innerR = 15;
var x, z, y, dist;
// ground
fill(-30, floorY - 1, -30, 30, floorY - 1, 30, 'stone');
fill(-30, floorY, -30, 30, floorY, 30, 'grass_block');
// main circular wall (rammed earth = terracotta)
for (x = -outerR - 1; x <= outerR + 1; x++) {
for (z = -outerR - 1; z <= outerR + 1; z++) {
dist = Math.sqrt(x * x + z * z);
if (dist <= outerR && dist >= outerR - 2) {
for (y = floorY + 1; y <= wallTop; y++) {
pb(x, y, z, 'terracotta');
}
}
}
}
// inner wall of the ring (wood)
for (x = -innerR - 1; x <= innerR + 1; x++) {
for (z = -innerR - 1; z <= innerR + 1; z++) {
dist = Math.sqrt(x * x + z * z);
if (dist <= innerR && dist >= innerR - 1) {
for (y = floorY + 1; y <= wallTop; y++) {
pb(x, y, z, 'oak_planks');
}
}
}
}
// floors inside the ring (3 levels)
for (x = -outerR; x <= outerR; x++) {
for (z = -outerR; z <= outerR; z++) {
dist = Math.sqrt(x * x + z * z);
if (dist < outerR - 2 && dist > innerR - 1) {
pb(x, floorY, z, 'oak_planks');
pb(x, 5, z, 'oak_planks');
pb(x, 10, z, 'oak_planks');
}
if (dist <= innerR - 1) {
pb(x, floorY, z, 'dirt'); // courtyard ground
}
}
}
// courtyard is open - clear it
for (x = -innerR; x <= innerR; x++) {
for (z = -innerR; z <= innerR; z++) {
dist = Math.sqrt(x * x + z * z);
if (dist < innerR - 1) {
for (y = floorY + 1; y <= wallTop + 4; y++) {
b(x, y, z, 'air');
}
}
}
}
// entrance: hole in the south wall
for (x = -1; x <= 1; x++) {
for (z = 13; z <= 22; z++) {
for (y = floorY + 1; y <= floorY + 3; y++) {
b(x, y, z, 'air');
}
}
}
// windows on the upper floors
for (x = -outerR; x <= outerR; x++) {
for (z = -outerR; z <= outerR; z++) {
dist = Math.sqrt(x * x + z * z);
if (dist <= outerR && dist >= outerR - 2) {
if ((x + z) % 6 === 0 && z < 12) {
b(x, 7, z, 'air');
b(x, 8, z, 'air');
b(x, 12, z, 'air');
b(x, 13, z, 'air');
}
}
}
}
// roof - grey tiles sloping in toward the courtyard
for (x = -outerR - 2; x <= outerR + 2; x++) {
for (z = -outerR - 2; z <= outerR + 2; z++) {
dist = Math.sqrt(x * x + z * z);
if (dist <= outerR + 2 && dist >= innerR - 2) {
var ry = wallTop + 1 + Math.floor((dist - (innerR - 2)) / 2);
pb(x, ry, z, 'deepslate_tiles');
}
}
}
// ladders up to the other floors
for (y = floorY + 1; y <= 10; y++) {
ps(0, y, -17, 'ladder[facing=south]');
}
// ancestral hall in the middle of the courtyard
fill(-3, floorY + 1, -3, 3, floorY + 4, 3, 'dark_oak_planks');
fill(-2, floorY + 1, -2, 2, floorY + 4, 2, 'air');
fill(-1, floorY + 1, 3, 1, floorY + 3, 3, 'air');
fill(-3, floorY + 5, -3, 3, floorY + 5, 3, 'deepslate_tiles');
pb(0, floorY + 1, -2, 'crafting_table');
pb(0, floorY + 2, -2, 'lantern');
// a bit of furniture in the ring
pb(18, floorY + 1, 0, 'crafting_table');
pb(17, floorY + 1, 0, 'furnace');
pb(-18, floorY + 1, 0, 'chest');
pb(-17, floorY + 1, 0, 'barrel');
ps(16, floorY + 1, 5, 'red_bed[facing=north,part=foot]');
ps(16, floorY + 1, 4, 'red_bed[facing=north,part=head]');
pb(0, floorY + 1, 8, 'oak_fence');
pb(2, floorY + 1, 8, 'oak_fence');
// a path to the door
fill(-1, floorY, 22, 1, floorY, 29, 'gravel');