← City3D assetfogon/antena-de-celular
Antena de celular
Drag to turn it// «Antena de celular» · gpt-6-sol (medium)
// A cell phone tower: a tall slim lattice steel tower in grey and red and white stripes on a concrete base, with three white panel antennas near the top, a small dish, and a red warning light on the tip.
// Concrete pad with a dark curb and a lightly mottled top.
box(8, 8, 0, 39, 39, 0, "#777b7d");
box(9, 9, 1, 38, 38, 1, "#c8c5bc");
for (let x = 9; x <= 38; x++)
for (let y = 9; y <= 38; y++)
if (rand() < 0.12) set(x, y, 1, rand() < 0.5 ? "#bdbab1" : "#d3d0c7");
box(13, 13, 2, 34, 34, 2, "#a9a8a2");
box(15, 15, 3, 32, 32, 3, "#c7c4ba");
box(16, 16, 4, 31, 31, 4, "#aaa9a3");
// Small dark-green perimeter fence, open at the front.
for (let x = 11; x <= 36; x += 5) {
if (x < 21 || x > 27) box(x, 11, 2, x, 11, 5, "#24564c");
box(x, 36, 2, x, 36, 5, "#24564c");
}
for (let y = 11; y <= 36; y += 5) {
box(11, y, 2, 11, y, 5, "#24564c");
box(36, y, 2, 36, y, 5, "#24564c");
}
for (let x = 11; x <= 36; x++) {
if (x < 21 || x > 27) set(x, 11, 4, "#397568");
set(x, 36, 4, "#397568");
}
for (let y = 11; y <= 36; y++) {
set(11, y, 4, "#397568");
set(36, y, 4, "#397568");
}
// Four tapering lattice legs. The front is toward decreasing y.
function bounds(z) {
const inset = Math.round((z - 5) * 4 / 34);
return [17 + inset, 30 - inset];
}
function paint(z) {
if (z >= 35) return "#c84e49";
if (z >= 29) return "#eeeae0";
if (z >= 23) return "#c84e49";
if (z >= 18) return "#eeeae0";
if (z >= 12) return "#bd4844";
return "#858e90";
}
// Cross-bracing on all four faces, behind the heavier legs.
const levels = [6, 11, 16, 21, 26, 31, 36, 39];
for (let i = 0; i < levels.length - 1; i++) {
const a = levels[i], b = levels[i + 1];
const [la, ra] = bounds(a), [lb, rb] = bounds(b);
const brace = i % 2 ? "#9da5a4" : "#6d787b";
line(la, la, a, rb, lb, b, 0, brace);
line(ra, la, a, lb, lb, b, 0, brace);
line(la, ra, a, rb, rb, b, 0, brace);
line(ra, ra, a, lb, rb, b, 0, brace);
line(la, la, a, lb, rb, b, 0, brace);
line(ra, la, a, rb, rb, b, 0, brace);
line(la, ra, a, lb, lb, b, 0, brace);
line(ra, ra, a, rb, lb, b, 0, brace);
}
for (const z of levels) {
const [l, r] = bounds(z);
const c = z >= 23 ? paint(z) : "#687477";
box(l, l, z, r, l, z, c);
box(l, r, z, r, r, z, c);
box(l, l, z, l, r, z, c);
box(r, l, z, r, r, z, c);
}
for (let z = 5; z <= 39; z++) {
const [l, r] = bounds(z);
const c = paint(z);
for (const x of [l, r])
for (const y of [l, r]) {
box(x, y, z, x + 1, y + 1, z, c);
set(x, y, z, z % 7 === 0 ? "#f1eee6" : c);
}
}
// Anchored feet and a few conspicuous warning markings.
for (const x of [17, 30])
for (const y of [17, 30]) box(x - 1, y - 1, 4, x + 2, y + 2, 5, "#596366");
for (let x = 17; x <= 30; x += 3)
box(x, 15, 4, x + 1, 15, 4, "#e5bd46");
// Three chunky white cellular panels on steel outriggers.
for (const z of [34, 39]) {
line(23, 22, z, 21, 17, z, 0, "#697579");
line(25, 23, z, 30, 23, z, 0, "#697579");
line(22, 25, z, 17, 25, z, 0, "#697579");
}
box(19, 16, 32, 23, 17, 40, "#aab2b2");
box(19, 15, 33, 23, 16, 39, "#eeeae2");
box(20, 15, 34, 22, 15, 38, "#ffffff");
box(29, 21, 32, 30, 26, 40, "#aab2b2");
box(30, 22, 33, 30, 25, 39, "#f4f1e9");
box(30, 22, 34, 30, 24, 38, "#ffffff");
box(16, 22, 32, 17, 27, 40, "#aab2b2");
box(16, 23, 33, 16, 26, 39, "#f4f1e9");
box(16, 23, 34, 16, 25, 38, "#ffffff");
// Small forward-facing microwave dish and its offset mounting arm.
line(21, 21, 27, 18, 17, 27, 0, "#626e72");
for (let x = 14; x <= 20; x++)
for (let z = 25; z <= 31; z++) {
const d = (x - 17) ** 2 + (z - 28) ** 2;
if (d <= 10) set(x, 15, z, "#737f82");
if (d <= 7) set(x, 14, z, "#f1efe7");
if (d <= 2) set(x, 13, z, "#ffffff");
}
set(17, 13, 28, "#9ba7a7");
// Tip mast and beacon housing.
box(23, 23, 39, 24, 24, 43, "#717b7e");
box(22, 22, 42, 25, 25, 42, "#535d60");
box(23, 23, 43, 24, 24, 43, "#333b3e");
part("warning_light", [24, 24, 44]);
box(23, 23, 44, 24, 24, 45, "#ff2222");
animate("warning_light", {
type: "colors",
palette: ["#ff2222", "#3a0a0a"],
pattern: "pulse",
glow: 1
});import { draw } from "./assets/voxel";
import { antenaDeCelular } from "./assets/antena-de-celular";
// Every frame: standing on (x, y), the centre of its base.
draw(ctx, antenaDeCelular, x, y, { size: 64, angle: 0, t: performance.now() / 1000 });
// size: its longest side, in px
// angle: turn on the floor, in radians
// t: seconds; if it moves, that animates it# In a terminal, in the game's folder
fogon assets add antena-de-celular
# With Fogón's tools (connector)
add_assets({ slug: "<your-game>", ids: ["antena-de-celular"] })
# It lands in client/assets/antena-de-celular.ts
# https://fogon.page/object/antena-de-celular