fogón

← Pirates and sea3D assetfogon/faro

Faro

by fogonCC013233 blocks
FaroDrag to turn it
// «Faro» · gpt-6-sol (medium)
// A tall round lighthouse on a small rocky base: white tower with thick red horizontal stripes, a small door at the bottom front, a black railing balcony near the top and a glass lantern room with a bright yellow light and a red cone roof.

const cx = 24, cy = 24;

function disc(z, radius, color, inner = -1) {
  for (let x = cx - radius; x <= cx + radius; x++)
    for (let y = cy - radius; y <= cy + radius; y++) {
      const d = Math.hypot(x - cx, y - cy);
      if (d <= radius && d > inner) set(x, y, z, color);
    }
}

// Low, uneven rocky island with a few sunny patches.
for (let z = 0; z <= 4; z++) {
  for (let x = 5; x <= 43; x++) {
    for (let y = 5; y <= 43; y++) {
      const dx = x - cx, dy = y - cy;
      const angle = Math.atan2(dy, dx);
      const edge = 18 - z * 1.35
        + 1.1 * Math.sin(angle * 7)
        + 0.7 * Math.sin(angle * 13);
      if (Math.hypot(dx, dy) > edge) continue;
      const shades = ["#777a73", "#85877b", "#969789", "#a4a18d"];
      let color = shades[Math.floor(rand() * shades.length)];
      if (z >= 3 && rand() < 0.20) color = "#c5b38a";
      set(x, y, z, color);
    }
  }
}
for (let i = 0; i < 55; i++) {
  const a = rand() * Math.PI * 2, r = 13 + rand() * 5;
  const x = Math.round(cx + Math.cos(a) * r);
  const y = Math.round(cy + Math.sin(a) * r);
  if (get(x, y, 3)) set(x, y, 4, rand() < 0.6 ? "#b0a997" : "#d0bc91");
}

// Solid, gently tapering striped tower.
for (let z = 4; z <= 33; z++) {
  const radius = 10 - Math.floor((z - 4) / 10);
  const red = (z >= 10 && z <= 14) ||
              (z >= 20 && z <= 24) ||
              (z >= 30 && z <= 33);
  for (let x = cx - radius; x <= cx + radius; x++)
    for (let y = cy - radius; y <= cy + radius; y++) {
      if (Math.hypot(x - cx, y - cy) > radius) continue;
      const front = y < cy;
      let color;
      if (red) {
        color = front ? "#e9473e" : "#b92d31";
        if (rand() < 0.10) color = "#d63834";
      } else {
        color = front ? "#fff4dd" : "#dfd8c5";
        if (rand() < 0.10) color = "#eee5cf";
      }
      set(x, y, z, color);
    }
}

// Heavy stone footing.
disc(4, 11, "#bbb6a4", 9);
disc(5, 10, "#e3d7bd", 9);

// Recessed plank door and its chunky dark arch.
box(21, 12, 5, 27, 14, 10, "#493b37");
box(22, 11, 5, 26, 12, 10, "#925932");
for (let x = 22; x <= 26; x++)
  for (let z = 5; z <= 10; z++)
    if (x === 22 || x === 25) set(x, 10, z, "#bb7940");
box(21, 12, 11, 27, 14, 11, "#493b37");
box(22, 12, 12, 26, 14, 12, "#493b37");
box(23, 11, 9, 25, 11, 10, "#342d2c");
set(25, 9, 7, "#ffd36a");
box(21, 9, 4, 27, 12, 4, "#c2b49a");

// Two small glowing tower windows, with bold frames.
function windowAt(y, z) {
  box(22, y, z, 26, y, z + 5, "#434044");
  box(23, y - 1, z + 1, 25, y - 1, z + 4, "#f6c967");
  box(24, y - 2, z + 1, 24, y - 2, z + 4, "#ffe89a");
  box(22, y - 2, z, 26, y - 2, z, "#4c4540");
  box(22, y - 2, z + 5, 26, y - 2, z + 5, "#4c4540");
  box(24, y - 3, z + 1, 24, y - 3, z + 4, "#544947");
}
windowAt(15, 17);
windowAt(16, 26);

// Projecting black balcony and gold-edged deck.
disc(33, 12, "#292c31");
disc(34, 12, "#424248");
disc(34, 10, "#c49a52", 9);
disc(35, 7, "#302e34");
disc(35, 12, "#25292e", 11);

for (let i = 0; i < 20; i++) {
  const a = i * Math.PI * 2 / 20;
  const x = Math.round(cx + 11.5 * Math.cos(a));
  const y = Math.round(cy + 11.5 * Math.sin(a));
  box(x, y, 35, x, y, 38, "#25282e");
}
for (let z of [36, 38]) disc(z, 12, "#292c32", 11);

// Lantern-room sill, glass walls, and stout metal mullions.
disc(35, 7, "#34363a");
disc(36, 7, "#45464a", 5);
for (let z = 37; z <= 40; z++) {
  for (let x = cx - 6; x <= cx + 6; x++)
    for (let y = cy - 6; y <= cy + 6; y++) {
      const d = Math.hypot(x - cx, y - cy);
      if (d > 5 && d <= 6) {
        const glass = y < cy ? "#8bdce5" : "#54aab9";
        set(x, y, z, rand() < 0.14 ? "#d5f7ed" : glass);
      }
    }
}
for (let i = 0; i < 8; i++) {
  const a = i * Math.PI / 4;
  const x = Math.round(cx + 6 * Math.cos(a));
  const y = Math.round(cy + 6 * Math.sin(a));
  box(x, y, 36, x, y, 41, "#30333a");
}
disc(40, 7, "#36363a", 6);

// Broad red cone roof, ending in a small golden finial.
const roofRadii = [8, 7, 5, 3, 1];
for (let i = 0; i < roofRadii.length; i++) {
  const z = 41 + i, r = roofRadii[i];
  for (let x = cx - r; x <= cx + r; x++)
    for (let y = cy - r; y <= cy + r; y++)
      if (Math.hypot(x - cx, y - cy) <= r)
        set(x, y, z, y < cy ? "#e84738" : "#bd2d31");
}
disc(41, 8, "#8e292e", 7);
set(cx, cy, 45, "#ffce65");

// The animated beacon sits inside the glass, with a bright front-facing glow.
part("lanternLight", [cx, cy, 39]);
sphere(cx, cy, 38, 2, "#ffdd67");
sphere(cx, 19, 38, 2, "#fff2a1");
set(cx, 17, 38, "#fff9d6");
animate("lanternLight", {
  type: "colors",
  palette: ["#ffc442", "#ffe26d", "#fff4aa", "#fffbea"],
  pattern: "pulse",
  glow: 0.8
});