feat: mood text per scene + Danish translation of Fabius Bile mission
- Mood text field on scenes shown as amber italic read-aloud block
above scene description (gated by revealed flag for players)
- Scene editor includes Mood / Read-aloud textarea
- Scene editor moved full-width below two-column grid
- Mission "The Hunt for Fabius Bile" fully translated to Danish
("Jagten på Fabius Bile") with Danish names, descriptions,
objectives, complications, checks and mood text for all 10 scenes
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -635,6 +635,7 @@ export default function MissionTab({ authedPlayer }) {
|
|||||||
setSceneEdit({
|
setSceneEdit({
|
||||||
title: currentScene.title || currentScene.name || '',
|
title: currentScene.title || currentScene.name || '',
|
||||||
type: currentScene.type || 'combat',
|
type: currentScene.type || 'combat',
|
||||||
|
mood: currentScene.mood || '',
|
||||||
description: currentScene.description || currentScene.briefing || currentScene.summary || '',
|
description: currentScene.description || currentScene.briefing || currentScene.summary || '',
|
||||||
checks: (Array.isArray(currentScene.checks) ? currentScene.checks : []).map(c => ({ ...c })),
|
checks: (Array.isArray(currentScene.checks) ? currentScene.checks : []).map(c => ({ ...c })),
|
||||||
enemies: (Array.isArray(currentScene.enemies) ? currentScene.enemies : []).map(e => ({ ...e })),
|
enemies: (Array.isArray(currentScene.enemies) ? currentScene.enemies : []).map(e => ({ ...e })),
|
||||||
@@ -651,6 +652,7 @@ export default function MissionTab({ authedPlayer }) {
|
|||||||
title: sceneEdit.title.trim() || undefined,
|
title: sceneEdit.title.trim() || undefined,
|
||||||
name: sceneEdit.title.trim() || undefined,
|
name: sceneEdit.title.trim() || undefined,
|
||||||
type: sceneEdit.type,
|
type: sceneEdit.type,
|
||||||
|
mood: sceneEdit.mood,
|
||||||
description: sceneEdit.description,
|
description: sceneEdit.description,
|
||||||
briefing: sceneEdit.description,
|
briefing: sceneEdit.description,
|
||||||
checks: sceneEdit.checks,
|
checks: sceneEdit.checks,
|
||||||
@@ -876,6 +878,11 @@ export default function MissionTab({ authedPlayer }) {
|
|||||||
{/* #2 — scene text gated by revealed flag */}
|
{/* #2 — scene text gated by revealed flag */}
|
||||||
{isGM || sceneRevealed ? (
|
{isGM || sceneRevealed ? (
|
||||||
<>
|
<>
|
||||||
|
{currentScene.mood && (
|
||||||
|
<div className="mb-3 rounded border border-amber-500/20 bg-amber-950/20 px-4 py-3">
|
||||||
|
<p className="text-sm italic leading-relaxed text-amber-100">{currentScene.mood}</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<p className="whitespace-pre-wrap text-slate-200">{textForScene(currentScene) || 'No scene text stored.'}</p>
|
<p className="whitespace-pre-wrap text-slate-200">{textForScene(currentScene) || 'No scene text stored.'}</p>
|
||||||
{sceneObjectives.length > 0 && (
|
{sceneObjectives.length > 0 && (
|
||||||
<div className="mt-4">
|
<div className="mt-4">
|
||||||
@@ -1675,15 +1682,26 @@ export default function MissionTab({ authedPlayer }) {
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div className="min-w-0">
|
<div className="min-w-0">
|
||||||
|
<label className="mb-1 block text-xs text-slate-400">Mood / Read-aloud <span className="text-slate-500 normal-case">(vist i kursiv til spillerne)</span></label>
|
||||||
|
<textarea
|
||||||
|
value={sceneEdit.mood || ''}
|
||||||
|
onChange={e => seField('mood', e.target.value)}
|
||||||
|
rows={2}
|
||||||
|
placeholder="Kortfattet stemningssætter…"
|
||||||
|
className="w-full rounded border border-amber-800/40 bg-amber-950/10 px-3 py-2 text-sm italic text-amber-100 placeholder-slate-600"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
<label className="mb-1 block text-xs text-slate-400">Scene Description / Briefing</label>
|
<label className="mb-1 block text-xs text-slate-400">Scene Description / Briefing</label>
|
||||||
<textarea
|
<textarea
|
||||||
value={sceneEdit.description}
|
value={sceneEdit.description}
|
||||||
onChange={e => seField('description', e.target.value)}
|
onChange={e => seField('description', e.target.value)}
|
||||||
rows={3}
|
rows={4}
|
||||||
className="w-full min-w-0 rounded border border-slate-600 bg-slate-900 px-3 py-2 text-sm text-slate-100"
|
className="w-full rounded border border-slate-600 bg-slate-900 px-3 py-2 text-sm text-slate-100"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Checks + Enemies — side by side on wide screens */}
|
{/* Checks + Enemies — side by side on wide screens */}
|
||||||
<div className="grid min-w-0 gap-4 xl:grid-cols-2">
|
<div className="grid min-w-0 gap-4 xl:grid-cols-2">
|
||||||
|
|||||||
Reference in New Issue
Block a user