fogón

← Fantasy3D assetfogon/enano-con-hacha

Enano con hacha

by fogonCC017398 blocks
Enano con hachaDrag to turn it
// «Enano con hacha» · gpt-6-sol (medium)
// A short stocky cartoon dwarf facing front (-y): a huge braided orange-red beard down to the belt, a round steel helmet with two small horns, big nose, chainmail shirt under a brown leather vest, wide iron belt buckle, chunky boots, and a big double-bladed axe held in the right hand.

// Short, stocky storybook dwarf. Front faces -y.
const steel = "#899ba0";
const steelLight = "#bdcbd0";
const steelDark = "#52646c";
const leather = "#70452f";
const leatherLight = "#96613c";
const brass = "#e5b85d";
const beard = "#b94625";
const beardLight = "#e77937";
const beardDark = "#85301f";

// Walking legs: separate parts pivoting at the hips.
function makeLeg(name, x, speed) {
  part(name, [x, 23, 12]);
  animate(name, { type: "swing", axis: "x", speed, amplitude: 0.3 });

  ellipsoid(x, 23, 8, 5, 5, 6, "#465157");
  ellipsoid(x, 20, 4, 5, 6, 4, "#543f32");
  box(x - 5, 15, 0, x + 5, 25, 3, "#342e30");
  ellipsoid(x, 18, 3, 5, 5, 3, "#77533a");
  box(x - 5, 15, 4, x + 5, 24, 5, "#a17447");
  box(x - 4, 15, 5, x + 4, 16, 5, brass);
}
makeLeg("left leg", 17, 5);
makeLeg("right leg", 29, -5);

part("body");

// Broad chainmail torso and rounded shoulders.
ellipsoid(23, 23, 19, 12, 10, 10, steelDark);
ellipsoid(23, 22, 20, 11, 9, 9, "#75878a");
for (let x = 15; x <= 31; x += 3) {
  for (let z = 16; z <= 26; z += 3) {
    const y = 14 + Math.round(Math.abs(x - 23) * 0.18);
    if (get(x, y, z)) set(x, y - 1, z, (x + z) % 2 ? steelLight : steel);
  }
}

// Leather vest panels, edging and brass studs.
ellipsoid(15, 19, 21, 5, 7, 8, leather);
ellipsoid(31, 19, 21, 5, 7, 8, leather);
box(12, 15, 16, 15, 17, 26, leatherLight);
box(31, 15, 16, 34, 17, 26, leatherLight);
for (const x of [14, 32]) {
  for (const z of [18, 23]) set(x, 14, z, brass);
}

// Belt and oversized iron buckle.
box(12, 14, 12, 34, 31, 15, "#49362c");
box(13, 13, 14, 33, 15, 15, leatherLight);
box(19, 10, 11, 27, 13, 17, steelDark);
box(20, 9, 12, 26, 10, 16, steelLight);
box(22, 8, 13, 24, 9, 15, "#b68d4b");
set(23, 7, 14, brass);

// Left sleeve and relaxed mitten.
ellipsoid(10, 22, 23, 5, 6, 6, leather);
ellipsoid(9, 19, 18, 4, 5, 6, steelDark);
ellipsoid(9, 16, 14, 4, 4, 4, "#d99468");
box(6, 17, 18, 12, 20, 19, leatherLight);

// Big friendly face.
ellipsoid(23, 21, 30, 11, 9, 9, "#d99468");
ellipsoid(15, 16, 29, 3, 3, 3, "#e5a276");
ellipsoid(31, 16, 29, 3, 3, 3, "#e5a276");
for (const x of [18, 28]) {
  ellipsoid(x, 12, 31, 3, 2, 3, "#f4e3b4");
  box(x - 1, 9, 30, x, 9, 32, "#263a42");
  set(x - 1, 8, 32, "#ffffff");
}
box(15, 10, 34, 20, 12, 35, beardDark);
box(26, 10, 34, 31, 12, 35, beardDark);

// Thick moustache frames the oversized nose.
ellipsoid(19, 10, 26, 6, 3, 3, beard);
ellipsoid(27, 10, 26, 6, 3, 3, beard);
ellipsoid(18, 8, 27, 4, 2, 2, beardLight);
ellipsoid(28, 8, 27, 4, 2, 2, beardLight);
ellipsoid(23, 8, 29, 4, 4, 4, "#eaa77a");
ellipsoid(23, 6, 28, 3, 2, 2, "#f2b58b");
set(18, 7, 27, beardDark);
set(28, 7, 27, beardDark);

// Huge layered beard, tapering to the belt. Three chunky braids sit on top.
ellipsoid(23, 14, 22, 10, 5, 9, beardDark);
ellipsoid(23, 12, 21, 9, 5, 8, beard);
for (const [x, bottom] of [[17, 16], [23, 13], [29, 16]]) {
  for (let z = 26; z >= bottom; z -= 3) {
    const taper = (26 - z) / (26 - bottom);
    const centerX = x + (x < 23 ? taper : x > 23 ? -taper : 0);
    ellipsoid(centerX - 1, 8, z, 3, 3, 2, beardLight);
    ellipsoid(centerX + 1, 7, z - 1, 3, 3, 2, beard);
    set(centerX - 2, 5, z, "#f18b42");
  }
  box(x - 2, 6, bottom + 1, x + 2, 8, bottom + 2, brass);
  ellipsoid(x, 8, bottom, 2, 2, 2, beardDark);
}
for (let i = 0; i < 35; i++) {
  const x = 15 + Math.floor(rand() * 17);
  const z = 17 + Math.floor(rand() * 11);
  if (get(x, 7, z)) set(x, 6, z, rand() < 0.5 ? "#ef8040" : "#9e371f");
}

// Steel helmet dome, raised rim, crest and warm brass rivets.
for (let x = 12; x <= 34; x++) {
  for (let y = 12; y <= 31; y++) {
    for (let z = 33; z <= 40; z++) {
      const d = ((x - 23) / 11) ** 2 +
                ((y - 22) / 10) ** 2 +
                ((z - 32) / 8) ** 2;
      if (d <= 1) set(x, y, z, z >= 37 ? steelLight : steel);
    }
  }
}
ellipsoid(23, 20, 33, 12, 10, 2, steelDark);
box(14, 11, 33, 32, 13, 34, steelLight);
box(20, 10, 34, 26, 12, 35, "#a9b9bb");
for (const x of [15, 19, 27, 31]) set(x, 10, 34, brass);
line(23, 15, 36, 23, 20, 40, 1, steelDark);

// Two short, outward-curving ivory horns.
for (const side of [-1, 1]) {
  const root = 23 + side * 10;
  line(root, 22, 36, root + side * 3, 22, 39, 2, "#d9c7a3");
  line(root + side * 3, 22, 39, root + side * 5, 21, 42, 1, "#f5e5c4");
  set(root + side * 5, 21, 43, "#fff2d4");
  ellipsoid(root, 22, 36, 3, 3, 2, brass);
}

// Axe arm pivots at the right shoulder; the entire weapon follows the chop.
part("axe arm", [33, 22, 25]);
animate("axe arm", { type: "swing", axis: "x", speed: 3, amplitude: 0.5 });

ellipsoid(34, 21, 24, 5, 6, 5, leather);
ellipsoid(36, 18, 21, 4, 5, 5, steelDark);
box(33, 14, 19, 39, 18, 21, leatherLight);
ellipsoid(38, 14, 18, 3, 3, 3, "#d99468");

// Long dark-wood haft, held through the fist.
box(38, 12, 8, 39, 14, 38, "#523a30");
box(38, 11, 10, 38, 11, 37, "#87603b");
box(37, 11, 16, 40, 15, 18, leather);
box(37, 12, 10, 40, 14, 11, brass);
box(37, 12, 27, 40, 14, 28, brass);

// Double-bladed axe head: thick center and broad pale cutting edges.
box(36, 11, 32, 41, 15, 37, steelDark);
ellipsoid(34, 13, 35, 5, 3, 6, steel);
ellipsoid(43, 13, 35, 4, 3, 6, steel);
for (let z = 31; z <= 39; z++) {
  const reach = Math.round(3 * Math.sqrt(Math.max(0, 1 - ((z - 35) / 5) ** 2)));
  for (let y = 12; y <= 14; y++) {
    for (let x = 30; x <= 30 + reach; x++) set(x, y, z, steelLight);
    for (let x = 46 - reach; x <= 46; x++) set(x, y, z, steelLight);
  }
}
box(37, 10, 33, 40, 11, 37, "#65777c");
set(38, 9, 35, "#58eee0");
set(39, 9, 36, "#80fff0");
set(39, 9, 34, "#58eee0");
box(37, 12, 38, 40, 14, 39, brass);

part("body");