Tourismustal: Sprite-Editor, Bikepark-Umbau, Animationen, Ambiente, Baumenue-Layout
- Justier-Editor (editor.html): jedes Gebaeude in allen Stufen, 1x1 und Mega-2x2, Oeko an/aus - Sprite-Breite, Boden-Anker und Solarpanel- Position (dx/dy/s pro Sprite-Key) live auf echten Tiles tunen. Werte wirken sofort via localStorage-Override, Export-JSON zum Einbacken. - Bikepark umgebaut aufs Rodelbahn-Prinzip: 1x1-Station, Flowtrail- Strecke 5 Felder talwaerts mit Schwuengen, Platz wird SCHON BEIM BAU geprueft und reserviert (tile.bikeTrail blockiert Bebauung), fahrende Raeder mit Kurvenneigung (mehr Biker je Ausbaustufe), Ziel-Bogen. - Animationen: Spielplatz (Schaukel + Rutscher), Hochseilgarten (Zipline-Gleiter), Aussichtsplattform (Foto-Blitz), Fahrradverleih (drehendes Werkstatt-Rad), Gasthaus (Kamin-Dampf). - Ambiente: Wolkenschatten ziehen uebers Tal; Schafe auf Almen und Kuehe auf Talwiesen (grasen, deterministische Herdenplaetze, nicht im Winter). - Baumenue-Karten: oben Titel+Info links / Preis rechts, darunter zweispaltig Icon und Beschreibung. - Solar-Position pro Gebaeudetyp justierbar (SOLAR_POS). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -260,6 +260,7 @@ export function canPlace(state, type, c, r) {
|
||||
if (!t) return { ok: false, reason: 'Außerhalb der Karte.' + platz };
|
||||
if (!inCore(c + dc, r + dr)) return { ok: false, reason: 'Hier ist unwegsames Hochgebirge – im Tal bauen.' + platz };
|
||||
if (t.building) return { ok: false, reason: 'Hier steht schon ein Gebäude.' + platz };
|
||||
if (t.bikeTrail) return { ok: false, reason: 'Hier verläuft die Bikepark-Strecke.' };
|
||||
if (t.terrain === 'rock') return { ok: false, reason: 'Auf Fels kann nicht gebaut werden.' + platz };
|
||||
if (t.terrain === 'water') return { ok: false, reason: 'Im Fluss kann nicht gebaut werden.' + platz };
|
||||
if (t.terrain === 'village') return { ok: false, reason: 'Hier steht das alte Dorf.' + platz };
|
||||
@@ -308,6 +309,17 @@ export function canPlace(state, type, c, r) {
|
||||
if (type === 'forest' && !['meadow', 'alm', 'field'].includes(tile.terrain)) {
|
||||
return { ok: false, reason: 'Aufforsten geht nur auf freien Wiesen, Almen oder Feldern.' };
|
||||
}
|
||||
if (def.trailLen) {
|
||||
// Die Flowtrail-Strecke braucht ihren Platz SCHON BEIM BAU: trailLen
|
||||
// freie Felder direkt talwärts unter der Station.
|
||||
for (let i = 1; i <= def.trailLen; i++) {
|
||||
const t = state.map[r + i]?.[c];
|
||||
if (!t || t.building || t.bikeTrail || t.road
|
||||
|| ['water', 'rock', 'village'].includes(t.terrain)) {
|
||||
return { ok: false, reason: `${def.name} braucht ${def.trailLen} freie Felder talwärts (direkt unterhalb) für die Strecke.` };
|
||||
}
|
||||
}
|
||||
}
|
||||
if (type === 'access') {
|
||||
let nearRoad = false;
|
||||
for (let rr = r - 1; rr <= r + 1 && !nearRoad; rr++) {
|
||||
@@ -358,16 +370,11 @@ export function place(state, type, c, r) {
|
||||
}
|
||||
}
|
||||
if (def.trailLen) {
|
||||
// Bike-Trails ziehen sich hangAUFwärts über der Basisstation – gleiche
|
||||
// Richtung wie die Lift-Pisten (die Bahn bringt die Bikes hinauf, die
|
||||
// Trails führen zurück herunter). Sie kosten extra Natur.
|
||||
let cc = c;
|
||||
// Flowtrail-Strecke talwärts (wie die Rodelbahn): Kacheln werden
|
||||
// reserviert – dort kann nicht mehr gebaut werden. Kostet extra Natur.
|
||||
for (let i = 1; i <= def.trailLen; i++) {
|
||||
cc += (i % 2 ? 1 : -1);
|
||||
const t = state.map[r - i]?.[Math.max(1, Math.min(MAP_COLS - 2, cc))];
|
||||
if (t && t.terrain !== 'water' && !t.building) {
|
||||
state.trails.push({ c: t.c, r: t.r, owner: { c, r } });
|
||||
}
|
||||
const t = state.map[r + i]?.[c];
|
||||
if (t) t.bikeTrail = { c, r };
|
||||
}
|
||||
state.nature = Math.max(15, state.nature - 2);
|
||||
}
|
||||
@@ -391,6 +398,12 @@ export function demolish(state, c, r) {
|
||||
state.buildings = state.buildings.filter(b => !(b.c === c && b.r === r));
|
||||
state.pistes = state.pistes.filter(p => !(p.owner.c === c && p.owner.r === r));
|
||||
state.trails = state.trails.filter(t => !(t.owner.c === c && t.owner.r === r));
|
||||
if (def.trailLen) {
|
||||
for (let i = 1; i <= def.trailLen; i++) {
|
||||
const t = state.map[r + i]?.[c];
|
||||
if (t?.bikeTrail?.c === c && t?.bikeTrail?.r === r) delete t.bikeTrail;
|
||||
}
|
||||
}
|
||||
const name = def.name;
|
||||
for (let dr = 0; dr < size; dr++) {
|
||||
for (let dc = 0; dc < size; dc++) {
|
||||
|
||||
Reference in New Issue
Block a user