Files
ashen-realms/apps/api/src/database/seeds/local-location.content.ts
Bastian Wagner 6f0020137b feat(web): add the local location view at /location
The screen a player stands on between activities: name, region, scene
artwork with hotspots pinned by percentage, a four-button action bar and
a context sidebar covering identity, danger, encounters, interactions and
rewards.

It owns no knowledge of any particular place. Hotspots and actions are
routed by interaction type: HUNT and MAP hand off to the existing hunt
and map screens, and everything that reveals text goes through the
server-authoritative interaction endpoint. A second location therefore
renders by supplying different content, which the Südtor case in the page
spec exercises.

The shell drops its generic area rail on /location, where the screen's
own sidebar says the same thing better, and Ort joins the navigation as
its first entry. Root and unknown routes now land on the location rather
than the map: arriving somewhere should mean arriving at a place.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 10:51:08 +02:00

208 lines
6.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type {
LocationPointOfInterestContent,
LocationPrimaryActionContent,
LocationRewardPreviewContent,
LocationType,
} from '../../world/local-location.types';
/**
* Authored local-view content per location (plan §7§11).
*
* Coordinates are percentages of the artwork box, so a hotspot stays on the
* same painted detail at every viewport width. They are tuned against the real
* artwork in `apps/web/public/images/backgrounds/`, not against the
* composition mockup in `docs/references/`.
*/
export interface LocalLocationContent {
regionName: string;
regionTierLabel: string;
locationType: LocationType;
localDescription: string;
localArtworkPath: string;
localPointsOfInterest: LocationPointOfInterestContent[];
localPrimaryActions: LocationPrimaryActionContent[];
localRewardPreview: LocationRewardPreviewContent[];
}
export const BURNED_ROAD_LOCAL_CONTENT: LocalLocationContent = {
regionName: 'Aschenfelder',
regionTierLabel: 'Gebiet 1',
locationType: 'HUNTING_GROUND',
localDescription:
'Ein alter Handelsweg, der durch Feuer und Krieg in Asche gelegt wurde. Verbrannte Karren, zerbrochene Waffen und verstummte Schreie säumen den Pfad in die Aschenfelder.',
localArtworkPath: '/images/backgrounds/Aschestrasse.png',
localPointsOfInterest: [
{
key: 'hunt-area',
title: 'Jagdgebiet',
actionLabel: 'Jagd beginnen',
type: 'HUNT',
iconKey: 'hunt',
xPercent: 52,
yPercent: 44,
enabled: true,
},
{
key: 'wounded-scout',
title: 'Verwundeter Kundschafter',
actionLabel: 'Sprechen',
type: 'NPC',
iconKey: 'speak',
xPercent: 20,
yPercent: 60,
enabled: true,
resultTitle: 'Verwundeter Kundschafter',
resultText:
'„Die Straße ist nicht mehr sicher. Die Plünderer kommen aus Richtung des alten Wachtpostens. Wenn du weitergehst, halte die Augen offen."',
},
{
key: 'inspect-tracks',
title: 'Verdächtige Spuren',
actionLabel: 'Untersuchen',
type: 'INVESTIGATE',
iconKey: 'investigate',
xPercent: 32,
yPercent: 78,
enabled: true,
resultTitle: 'Verdächtige Spuren',
resultText:
'Zwischen Asche und zerbrochenen Steinen erkennst du mehrere frische Stiefelabdrücke. Sie führen nach Osten, in Richtung des verlassenen Wachtpostens.',
},
{
key: 'search-abandoned-wagon',
title: 'Verlassener Wagen',
actionLabel: 'Durchsuchen',
type: 'SEARCH',
iconKey: 'search',
xPercent: 80,
yPercent: 68,
enabled: true,
resultTitle: 'Verlassener Wagen',
resultText:
'Der Wagen wurde gründlich geplündert. Zwischen verbrannten Brettern findest du nur leere Kisten und Spuren eines hastigen Aufbruchs.',
},
],
localPrimaryActions: [
{
key: 'start-hunt',
label: 'Jagd beginnen',
description: 'Im Gebiet jagen',
type: 'HUNT',
iconKey: 'hunt',
enabled: true,
},
{
key: 'investigate-tracks',
label: 'Spuren untersuchen',
description: 'Hinweise finden',
type: 'INVESTIGATE',
iconKey: 'investigate',
enabled: true,
poiKey: 'inspect-tracks',
},
{
key: 'search-surroundings',
label: 'Umgebung durchsuchen',
description: 'Beute finden',
type: 'SEARCH',
iconKey: 'search',
enabled: true,
poiKey: 'search-abandoned-wagon',
},
{
key: 'open-map',
label: 'Zur Karte',
description: 'Gebiet wechseln',
type: 'MAP',
iconKey: 'map',
enabled: true,
},
],
// Only categories the loot tables on this road actually back: silver and
// experience from every kill, gear from the raiders, pelts from the beasts.
// Named items stay out — the view may not promise a drop the roll does not
// guarantee (spec §8, "Mögliche Belohnungen").
localRewardPreview: [
{ key: 'silver', label: 'Silber', iconKey: 'silver' },
{ key: 'experience', label: 'Erfahrung', iconKey: 'experience' },
{ key: 'equipment', label: 'Ausrüstung', iconKey: 'equipment' },
{ key: 'material', label: 'Material', iconKey: 'material' },
],
};
export const SOUTH_GATE_LOCAL_CONTENT: LocalLocationContent = {
regionName: 'Aschenfelder',
regionTierLabel: 'Gebiet 1',
locationType: 'TRANSITION',
localDescription:
'Am schwarzen Südtor endet der Schutz Graufurts. Hinter den Wachtfeuern beginnt die stille Weite der Aschenfelder.',
localArtworkPath: '/images/backgrounds/Suedtor.png',
localPointsOfInterest: [
{
key: 'gate-notice',
title: 'Aushangtafel',
actionLabel: 'Lesen',
type: 'INVESTIGATE',
iconKey: 'investigate',
xPercent: 22,
yPercent: 42,
enabled: true,
resultTitle: 'Aushangtafel',
resultText:
'Verwitterte Anschläge flattern im Wind. Ein frischer Zettel warnt vor Plünderern auf der Verbrannten Straße und verspricht Silber für jeden erlegten Räuber.',
},
{
key: 'gate-watch',
title: 'Torwache',
actionLabel: 'Sprechen',
type: 'NPC',
iconKey: 'speak',
xPercent: 45,
yPercent: 52,
enabled: true,
resultTitle: 'Torwache',
resultText:
'„Hinter dem Tor endet Graufurts Schutz. Wer nach Süden geht, geht auf eigene Gefahr — und kommt selten so zurück, wie er gegangen ist."',
},
{
key: 'south-road',
title: 'Straße nach Süden',
actionLabel: 'Zur Karte',
type: 'MAP',
iconKey: 'map',
xPercent: 66,
yPercent: 72,
enabled: true,
},
],
localPrimaryActions: [
{
key: 'talk-to-watch',
label: 'Wache ansprechen',
description: 'Lage erfragen',
type: 'NPC',
iconKey: 'speak',
enabled: true,
poiKey: 'gate-watch',
},
{
key: 'read-notice',
label: 'Aushang lesen',
description: 'Hinweise finden',
type: 'INVESTIGATE',
iconKey: 'investigate',
enabled: true,
poiKey: 'gate-notice',
},
{
key: 'open-map',
label: 'Zur Karte',
description: 'Gebiet wechseln',
type: 'MAP',
iconKey: 'map',
enabled: true,
},
],
localRewardPreview: [],
};