298 lines
3.9 KiB
HTML
298 lines
3.9 KiB
HTML
<!DOCTYPE html>
|
|
<head>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
|
<meta name="robots" content="noindex">
|
|
<meta charset="UTF-8">
|
|
<style>
|
|
body {
|
|
max-width: 700px;
|
|
margin: auto;
|
|
font-size: 18px;
|
|
font-family: sans-serif;
|
|
padding: 10px;
|
|
}
|
|
|
|
p, li {
|
|
line-height: 1.5em;
|
|
}
|
|
|
|
ul, ol {
|
|
padding-left: 20px;
|
|
margin-left: 0;
|
|
}
|
|
|
|
li {
|
|
margin-left: 0;
|
|
}
|
|
|
|
table {
|
|
border-collapse: collapse;
|
|
}
|
|
|
|
th, td {
|
|
border: 1px solid black;
|
|
padding: 5px;
|
|
text-align: left;
|
|
}
|
|
|
|
button, select, input, textarea {
|
|
font-size: 18px;
|
|
touch-action: manipulation;
|
|
}
|
|
|
|
</style>
|
|
<title>Monument Generator</title>
|
|
</head>
|
|
<body>
|
|
<h1>Monument Generator</h1>
|
|
|
|
<div id="controls">
|
|
<button onclick="generate()">Generate</button>
|
|
</div>
|
|
<div id="output"></div>
|
|
|
|
|
|
<script>
|
|
const dataText = `
|
|
template
|
|
{race} {condition} {monument}.
|
|
|
|
condition
|
|
aberrant
|
|
abyssal
|
|
acidic
|
|
ancient
|
|
astral
|
|
bladed
|
|
bloody
|
|
buried
|
|
cracked
|
|
crumbling
|
|
crystalline
|
|
cursed
|
|
cyclopean
|
|
defiled
|
|
dreamscape
|
|
earthen
|
|
eldritch
|
|
emerald
|
|
entombed
|
|
ethereal
|
|
flaming
|
|
floating
|
|
flooded
|
|
foggy
|
|
frozen
|
|
glass
|
|
glowing
|
|
glyphed
|
|
hallowed
|
|
haunted
|
|
holy
|
|
infested
|
|
lightning-touched
|
|
moontouched
|
|
musical
|
|
necrotic
|
|
obsidian
|
|
oozing
|
|
opal
|
|
poisonous
|
|
psionic
|
|
radiant
|
|
ruby
|
|
ruined
|
|
sapphire
|
|
shadowy
|
|
shadowy
|
|
spiked
|
|
startouched
|
|
stormy
|
|
temporal
|
|
titanic
|
|
twilight
|
|
unearthed
|
|
unhallowed
|
|
unholy
|
|
|
|
monument
|
|
aerie
|
|
altar
|
|
aqueduct
|
|
arcane circle
|
|
archway
|
|
aviary
|
|
barrow
|
|
battlefield
|
|
bell
|
|
bone pile
|
|
boneyard
|
|
bonfire
|
|
brazier
|
|
bridge
|
|
cage
|
|
cairn
|
|
campsite
|
|
canal
|
|
carcass
|
|
carriage
|
|
cauldron
|
|
cave
|
|
cenotaph
|
|
cesspit
|
|
charnel pit
|
|
columns
|
|
crater
|
|
crossroads
|
|
crystal
|
|
dome
|
|
doorway
|
|
earthmote
|
|
effigy
|
|
fighting pit
|
|
firepit
|
|
fossil
|
|
fountain
|
|
gallows
|
|
gateway
|
|
geode
|
|
geyser
|
|
graveyard
|
|
gravestone
|
|
grotto
|
|
grove
|
|
hollow
|
|
huge skull
|
|
idol
|
|
illusion
|
|
keep
|
|
lantern
|
|
machine
|
|
mausoleum
|
|
megalith
|
|
meteorite
|
|
midden
|
|
mill
|
|
mine
|
|
mirror
|
|
monolith
|
|
monument
|
|
mosaic
|
|
nest
|
|
obelisk
|
|
orb
|
|
orrery
|
|
oubliette
|
|
petrified creature
|
|
pillar
|
|
pit
|
|
planar rift
|
|
platform
|
|
podium
|
|
pool
|
|
rock
|
|
ruin
|
|
sacred circle
|
|
sarcophagus
|
|
shipwreck
|
|
shrine
|
|
sigil
|
|
sinkhole
|
|
slab
|
|
spell effect
|
|
sphere
|
|
spire
|
|
statue
|
|
stone circle
|
|
stone tablets
|
|
sundial
|
|
throne
|
|
tomb
|
|
totem
|
|
tower
|
|
trash heap
|
|
tree
|
|
wall
|
|
waymarker
|
|
well
|
|
windmill
|
|
|
|
race
|
|
human
|
|
elven
|
|
dwarven
|
|
halfling
|
|
gnomish
|
|
dragonborn
|
|
orcish
|
|
bestial
|
|
primordial
|
|
gearforged
|
|
constructed
|
|
elemental
|
|
draconic
|
|
fiendish
|
|
giant
|
|
shadow-touched
|
|
aberrant
|
|
fungoid
|
|
goblinoid
|
|
infernal
|
|
celestial
|
|
outerplanar
|
|
faerie
|
|
monstrous
|
|
ooze-touched
|
|
undead
|
|
plant-touched
|
|
minotaur
|
|
shadowborn
|
|
serpentine
|
|
`;
|
|
|
|
|
|
function parseInput(text) {
|
|
const lines = text.trim().split('\n');
|
|
const result = {};
|
|
let currentKey = null;
|
|
for (let line of lines) {
|
|
if (!line.trim()) continue;
|
|
if (!line.startsWith(' ')) {
|
|
currentKey = line.trim().replace(':', '');
|
|
result[currentKey] = [];
|
|
} else if (currentKey) {
|
|
result[currentKey].push(line.trim());
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
function pick(list) {
|
|
return list[Math.floor(Math.random() * list.length)];
|
|
}
|
|
|
|
function fillTemplate(template, data) {
|
|
return template.replace(/{(.*?)}/g, (_, key) => pick(data[key] || ['']));
|
|
}
|
|
|
|
function generate(count = 10) {
|
|
const parsed = parseInput(dataText);
|
|
const template = (parsed.template || [''])[0];
|
|
delete parsed.template;
|
|
|
|
const output = document.getElementById('output');
|
|
output.innerHTML = '';
|
|
for (let i = 0; i < count; i++) {
|
|
const text = fillTemplate(template, parsed);
|
|
const p = document.createElement('p');
|
|
p.textContent = text.charAt(0).toUpperCase() + text.slice(1);
|
|
output.appendChild(p);
|
|
}
|
|
|
|
}
|
|
|
|
window.onload = () => generate();
|
|
</script>
|
|
</body>
|
|
</html>
|