fogón

← Pirates and sea3D assetfogon/bote-de-naufrago

Bote de náufrago

by fogonCC03648 blocks
Bote de náufragoDrag to turn it
// «Bote de náufrago» · gpt-6-sol (medium)
// A small worn wooden rowing boat, hull along y, light weathered brown planks with a couple of missing gaps, two oars resting across it, a tiny patched cloth sail on a stick and a coil of rope inside.

const woodDark = "#704329";
const woodMid = "#a66a39";
const woodLight = "#c99154";
const woodSun = "#e2af6d";
const seam = "#68402d";

function hullShape(y, z) {
  const lo = 12 - Math.floor(z * 0.7);
  const hi = 36 + Math.floor(z * 0.7);
  if (y < lo || y > hi) return null;
  const t = (y - 24) / ((hi - lo) / 2);
  const half = Math.max(
    1,
    Math.floor((4.8 + z * 0.48) * Math.pow(Math.max(0, 1 - t * t), 0.55))
  );
  return { lo, hi, half };
}

// Solid keel below a hollow, plank-built hull.
for (let z = 0; z <= 10; z++) {
  for (let y = 5; y <= 43; y++) {
    const shape = hullShape(y, z);
    if (!shape) continue;
    const { lo, hi, half } = shape;

    for (let x = 24 - half; x <= 24 + half; x++) {
      const inside =
        z >= 5 &&
        y > lo + 2 &&
        y < hi - 2 &&
        Math.abs(x - 24) < half - 2;
      if (inside) continue;

      let color = z < 3 ? woodDark : z < 7 ? woodMid : woodLight;
      if (z === 3 || z === 7) color = seam;
      if (y % 9 === 0 && z > 3 && z < 10) color = woodDark;
      if (z > 3 && z !== 7 && rand() < 0.12) color = woodSun;
      if (rand() < 0.06) color = woodDark;
      set(x, y, z, color);
    }
  }
}

// A couple of lost plank sections on the near, port side.
for (let y = 17; y <= 19; y++) {
  for (let z = 5; z <= 6; z++) {
    const s = hullShape(y, z);
    if (s) set(24 - s.half, y, z, null);
  }
}
for (let y = 30; y <= 32; y++) {
  const s = hullShape(y, 8);
  if (s) set(24 - s.half, y, 8, null);
}

// Thick, bright gunwale follows the pointed ends.
for (let y = 5; y <= 43; y++) {
  const s = hullShape(y, 10);
  if (!s) continue;
  for (let x = 24 - s.half; x <= 24 + s.half; x++) {
    if (Math.abs(x - 24) >= s.half - 1 || y <= 7 || y >= 41) {
      set(x, y, 11, woodDark);
      set(x, y, 12, x <= 24 ? woodSun : woodLight);
    }
  }
}
for (let y of [6, 7, 41, 42]) {
  const s = hullShape(y, 10);
  if (!s) continue;
  box(24 - s.half, y, 13, 24 + s.half, y, 13, woodLight);
}

// Visible floorboards and two chunky rowing benches.
for (let y = 13; y <= 36; y++) {
  for (let x = 19; x <= 29; x++) {
    if (get(x, y, 4) && rand() > 0.11) {
      set(x, y, 5, x % 4 === 0 ? woodDark : woodMid);
    }
  }
}
for (const y of [15, 35]) {
  box(17, y, 8, 31, y + 1, 9, woodDark);
  box(18, y, 10, 30, y + 1, 10, woodSun);
  for (const x of [19, 29]) set(x, y, 11, "#d7a94d");
}

// Short interior ribs peek out from under the seats.
for (const y of [11, 22, 29, 39]) {
  const s = hullShape(y, 9);
  if (!s) continue;
  for (const side of [-1, 1]) {
    line(
      24 + side * 3, y, 6,
      24 + side * (s.half - 2), y, 9,
      0, woodSun
    );
  }
}

// Two oars laid across opposite sides, with broad flat blades.
line(9, 16, 14, 29, 16, 14, 1, woodDark);
line(10, 16, 15, 27, 16, 15, 0, woodSun);
box(4, 15, 13, 10, 17, 14, woodMid);
box(5, 15, 15, 9, 16, 15, woodLight);

line(19, 33, 14, 39, 33, 14, 1, woodDark);
line(21, 33, 15, 38, 33, 15, 0, woodSun);
box(38, 32, 13, 43, 34, 14, woodMid);
box(39, 32, 15, 42, 33, 15, woodLight);

// The mast and its small, sun-faded cloth sail.
box(23, 24, 6, 25, 26, 28, woodDark);
box(23, 24, 9, 23, 24, 28, woodLight);
line(18, 23, 27, 30, 23, 27, 0, woodDark);
line(20, 23, 16, 28, 23, 16, 0, woodMid);

for (let z = 17; z <= 26; z++) {
  const width = Math.floor(3 + (z - 17) * 0.32);
  for (let x = 24 - width; x <= 24 + width; x++) {
    const edge = x === 24 - width || x === 24 + width;
    let cloth = edge ? "#bba985" : "#f3dfad";
    if (!edge && rand() < 0.13) cloth = "#dfc899";
    set(x, 22, z, cloth);
    set(x, 23, z, "#d5bf94");
  }
}
// An obviously sewn-on red-and-white repair.
box(20, 21, 19, 22, 21, 22, "#bd5142");
box(20, 21, 20, 22, 21, 20, "#f4e4bd");
for (const [x, z] of [[19, 19], [19, 22], [23, 19], [23, 22]]) {
  set(x, 21, z, "#57483a");
}
line(26, 21, 23, 28, 21, 24, 0, "#a58b6c");

// A little golden rope coil on the floor beside the mast.
for (let ring = 0; ring < 2; ring++) {
  const cx = 29 - ring, cy = 28 + ring, r = 3 - ring * 0.7;
  for (let i = 0; i < 36; i++) {
    const a = i * Math.PI * 2 / 36;
    set(
      Math.round(cx + Math.cos(a) * r),
      Math.round(cy + Math.sin(a) * r),
      8 + ring,
      i % 5 === 0 ? "#a36b36" : "#e2b865"
    );
  }
}
line(30, 30, 8, 33, 32, 9, 0, "#d7a653");

// A few cheerful brass fittings on the bow.
for (const [x, y] of [[23, 7], [25, 7], [18, 12], [30, 12]]) {
  set(x, y, 12, "#f0c45b");
}