fogón

← Ancient and prehistory3D assetfogon/town-wall

Muralla con almenas

by fogonCC013912 blocks
Muralla con almenasDrag to turn it
// «Muralla con almenas» · propio
// A straight section of sandstone town wall: big blocks with mortar lines, a darker foot, a pale band near the top and a row of square merlons.

// A straight section of sandstone town wall: big blocks, a darker foot, a pale band and square merlons.
const stone = ["#a37c4b", "#b38c57", "#c19a64", "#cda870", "#d8b57e"];
const footStone = ["#806038", "#8f6d42", "#9c794c"];
const mortar = "#84653c";
const trim = ["#d4bd8c", "#e0cb9c", "#ebd8ad", "#f2e2bd"];
const clampi = (v, lo, hi) => Math.max(lo, Math.min(hi, v));
const X0 = 2, X1 = 45, Y0 = 19, Y1 = 28, TOP = 27;
const hash = (a, b) => {
  const s = Math.sin(a * 12.9898 + b * 78.233) * 43758.5453;
  return s - Math.floor(s);
};
function blockAt(u, z, tones, base) {
  const row = Math.floor(z / 4);
  const len = 8 + (row % 3);
  const shift = (row % 2) * 4 + ((row * 5) % 3);
  const k = Math.floor((u + shift) / len);
  if (z % 4 === 3 || (u + shift) % len === 0) return mortar;
  let tone = base + Math.floor(hash(k, row) * 3);
  if (rand() < 0.12) tone--;
  return tones[clampi(tone, 0, tones.length - 1)];
}
// The wall.
for (let x = X0; x <= X1; x++)
  for (let y = Y0; y <= Y1; y++)
    for (let z = 0; z <= TOP; z++) {
      const u = x === X0 || x === X1 ? y + 2 : x;
      set(x, y, z, blockAt(u, z, stone, z > 16 ? 2 : 1));
    }
// The foot: darker, a block wider.
for (let x = X0 - 1; x <= X1 + 1; x++)
  for (let y = Y0 - 1; y <= Y1 + 1; y++)
    for (let z = 0; z <= 5; z++) {
      const u = x < X0 || x > X1 ? y + 2 : x + 3;
      const c = blockAt(u, z, footStone, 0);
      set(x, y, z, z === 5 ? footStone[2] : c);
    }
// The pale band.
for (let x = X0 - 1; x <= X1 + 1; x++)
  for (let y = Y0 - 1; y <= Y1 + 1; y++)
    for (let z = TOP - 3; z <= TOP - 2; z++) set(x, y, z, (x + 5) % 11 === 0 ? "#bfa878" : trim[clampi((z === TOP - 2 ? 2 : 1) - (rand() < 0.15 ? 1 : 0), 0, 3)]);
// The walk on top and the merlons along its front and back edges.
for (let x = X0; x <= X1; x++) for (let y = Y0; y <= Y1; y++) set(x, y, TOP, stone[clampi(3 - (rand() < 0.2 ? 1 : 0), 0, 4)]);
for (let x = X0; x <= X1; x++) {
  const m = (x - X0) % 8;
  if (m > 4) continue;
  for (const y of [Y0, Y0 + 1, Y1 - 1, Y1])
    for (let z = TOP + 1; z <= TOP + 6; z++) {
      let tone = z >= TOP + 5 ? 3 : 2;
      if (m === 0 || m === 4) tone--;
      if (rand() < 0.12) tone--;
      set(x, y, z, z === TOP + 6 ? trim[clampi(tone - 1, 0, 3)] : stone[clampi(tone + 1, 0, 4)]);
    }
}
// An arrow slit in the middle.
box(23, Y0, 13, 24, Y0, 20, "#2a1d12");
box(22, Y0, 16, 25, Y0, 17, "#2a1d12");