// wegwarte/js/melden.js
async function ortSetzen(koordinate) {
const [x, y] = koordinate;
const a = zustand.konfig.ausdehnung;
$('#ort-fehler') && ($('#ort-fehler').textContent = '');
if (x < a.x0 || x > a.x1 || y < a.y0 || y > a.y1) {
$('#ort-fehler').textContent = 'Dieser Ort liegt außerhalb von Auenfeld. Hinweise nehmen wir nur innerhalb der Stadtgrenze an.';
return;
}
m.x = Math.round(x * 10) / 10;
m.y = Math.round(y * 10) / 10;
const [t, o] = await Promise.all([api(`/api/nahe?x=${m.x}&y=${m.y}`).catch(() => []), api(`/api/ort?x=${m.x}&y=${m.y}`).catch(() => null)]);
if (o && !o.drin) { fehler('ort-fehler', 'Dieser Ort liegt außerhalb von Auenfeld. Hinweise nehmen wir nur innerhalb der Stadtgrenze an.'); m.x = m.y = null; return; }
m.nahe = t;
m.ortText = o?.ortsangabe || 'Ort auf der Karte'; // dieselbe Angabe, die der Hinweis später trägt
m.amt = null;
const anz = $('#ort-anzeige span:last-child');
if (anz) anz.textContent = m.ortText;
$('#leiste-fehler') && ($('#leiste-fehler').textContent = '');
$('#weiter')?.removeAttribute('aria-disabled');
ansagen(`Ort übernommen: ${m.ortText}.`);
naheZeigen();
}
// waldzeit/js/sim.js
export function wetter(seed) {
const r = zufall(seed);
return JAHRE.slice(1).map(() => ({ duerre: r(), sturm: r(), brand: r(), staerke: r() }));
}
export function trockenheit(standort, klima, jahr) {
const p = (jahr - 2025) / 75;
return clamp(0.12 + (1 - standort.wasser) * 0.45 + klima.anstieg * p);
}
const biomasse = (k) => 1 - Math.exp(-k.alter * ARTEN[k.art].wachstum / 40);
const stress = (art, D) => clamp((D - ARTEN[art].trocken) * 1.4);
function vielfaltIndex(gewichte) {
const ges = Object.values(gewichte).reduce((a, b) => a + b, 0);
if (ges <= 0) return 0;
let h = 0;
for (const g of Object.values(gewichte)) if (g > 0) h -= (g / ges) * Math.log(g / ges);
return clamp(h / Math.log(5));
}
// fadenlauf/js/player.js
export const zeit = (s) => {
if (!Number.isFinite(s) || s < 0) s = 0;
const m = Math.floor(s / 60);
return `${m}:${String(Math.floor(s % 60)).padStart(2, '0')}`;
};
const TEMPI = [1, 1.25, 0.85];
export class Spieler {
constructor(wurzel, { tempo = 1, beiDreiviertel, beiEnde, beiStart, weiter } = {}) {
this.wurzel = wurzel;
this.audio = new Audio();
this.audio.preload = 'metadata';
this.tempo = TEMPI.includes(tempo) ? tempo : 1;
this.beiDreiviertel = beiDreiviertel;
this.beiEnde = beiEnde;
this.beiStart = beiStart;
this.weiter = weiter;