diff --git a/packages/web/src/App.svelte b/packages/web/src/App.svelte index 9ddd71f..f95edb3 100644 --- a/packages/web/src/App.svelte +++ b/packages/web/src/App.svelte @@ -2478,11 +2478,38 @@
Your turn — round {view.turn.round}. {#if view.turn.actionsEnded} - turn spent — end it when ready + {#if me?.carriedTreasureId} + picking up ended your actions for this turn, and the treasure comes with you — + End turn now, then carry it home to score. + {:else} + picking up ended your actions for this turn — End turn when ready. + {/if} {:else} {view.turn.movementAllowance - view.turn.movementUsed} moves left{view.turn.attackUsed ? " · attack spent" : ""} {/if}
+ {#if !prefs.coached && !view.turn.actionsEnded} + +
+ How a turn works. Walk up to {view.turn.movementAllowance} squares by tapping + squares beside your wizard (or with the arrow keys); play a NUMBER card first to walk farther. + Tap a card to cast it. When you're done, End turn. Stuck? Ask the automatons for hints. + +
+ {/if} + {#if me?.carriedTreasureId && !view.turn.actionsEnded} + {@const chest = view.treasures.find((t) => t.id === me!.carriedTreasureId)} + {@const away = dreadDistance(view.board, me!.position, me!.home)} +
+ 💰 Carrying {chest && chest.owner !== view.you ? `${chest.owner}'s treasure` : "your own treasure"} — + {#if chest && chest.owner !== view.you} + your home is {away} square{away === 1 ? "" : "s"} away; drop it there to score. Two scored wins the game. + {:else} + it scores nothing in your arms; drop it on your home to keep it safe. + {/if} +
+ {/if} {:else}
{view.activePlayerId} is taking their turn…
{/if} @@ -3507,6 +3534,8 @@ transform: rotate(-0.4deg); } .slip.yours { border-left: 4px solid #2e7d32; } + .slip.coach { border-left: 4px solid #c9a72a; } + .slip.coach .stamp { margin-left: 0.5rem; } .slip.urgent { border-left: 4px solid #b3372b; transform: rotate(0.4deg); } .slip.ambush-note { border-left: 4px solid #43331f; font-size: 0.85rem; } .slip.catchup { border-left: 4px solid #5b3f9e; display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; } diff --git a/packages/web/src/prefs.svelte.ts b/packages/web/src/prefs.svelte.ts index 555e30c..38491cc 100644 --- a/packages/web/src/prefs.svelte.ts +++ b/packages/web/src/prefs.svelte.ts @@ -25,6 +25,8 @@ export interface Prefs { /** The hand of cards stands in a column at the board's left instead of * lying along the bottom (wide screens only). */ handLeft: boolean; + /** The first-turn coaching slip has been read and dismissed. */ + coached: boolean; } const KEY = "wizwar-prefs"; @@ -33,6 +35,7 @@ function load(): Prefs { const fallback: Prefs = { art: "photo", autoGrab: false, flourishes: true, wizardName: "", color: null, cautions: true, botTier: "adept", instantReplay: true, liveFp: false, handLeft: false, + coached: false, }; try { const raw = localStorage.getItem(KEY); @@ -49,6 +52,7 @@ function load(): Prefs { instantReplay: p.instantReplay !== false, liveFp: p.liveFp === true, handLeft: p.handLeft === true, + coached: p.coached === true, }; } catch { return fallback;