A table for a dozen wizards, begun by its host
Rooms take up to twelve seats and the host begins the duel with whoever is seated; a full table begins by itself. The lobby is a roster with a bot seat and the host's begin button. The ledger pins the turn and your own columns and scrolls sideways to the rest; the phone bar shows every wizard's health; a wizard who is out watches the rest; each charmed wizard gets their own gesture; an unnamed spell goes at whoever hurt you last, else the weakest opponent; a stab has a target from the start. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0141G6xqLeNRYEtviLWSB5Up
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
79947e31ba
commit
58d7db106e
@@ -6,7 +6,7 @@
|
||||
import SpellSheet from './SpellSheet.svelte';
|
||||
import TurnSummary from './TurnSummary.svelte';
|
||||
import WizardStatus from './WizardStatus.svelte';
|
||||
import { castKey, tokensText, type Duel } from '$lib/game/duel.svelte';
|
||||
import { castKey, listText, tokensText, type Duel } from '$lib/game/duel.svelte';
|
||||
import { GESTURE_SHORT, glyph } from '$lib/game/glyphs';
|
||||
import { MAGIC_GESTURES } from '$lib/game/spells';
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
const foeMonsters = $derived(duel.state.monsters.filter((m) => m.owner !== duel.me));
|
||||
const outcome = $derived(duel.state.over);
|
||||
const won = $derived(outcome?.winner === duel.me);
|
||||
const charmedName = $derived(duel.charmedFoe ? duel.state.wizards[duel.charmedFoe].name : '');
|
||||
const charmedHandName = $derived(duel.charmedFoe ? duel.state.wizards[duel.charmedFoe].constraints.charmed?.hand : '');
|
||||
</script>
|
||||
|
||||
<main class="board">
|
||||
@@ -35,6 +33,12 @@
|
||||
{/if}
|
||||
</div>
|
||||
{:else}
|
||||
{#if duel.out}
|
||||
<section class="move out" aria-labelledby="move-heading">
|
||||
<h2 id="move-heading">{duel.you.alive ? 'You have yielded' : 'You have fallen'}</h2>
|
||||
<p class="threats muted">The duel goes on without you. Watch the ledger fill; {listText(duel.others.filter((id) => duel.state.wizards[id].alive && !duel.state.wizards[id].surrendered).map((id) => duel.state.wizards[id].name))} still stand.</p>
|
||||
</section>
|
||||
{:else}
|
||||
<section class="move" aria-labelledby="move-heading">
|
||||
{#if duel.timeStopped}
|
||||
<h2 id="move-heading">Time stands still. Take your extra turn.</h2>
|
||||
@@ -162,23 +166,23 @@
|
||||
</select>
|
||||
</label>
|
||||
{/if}
|
||||
{#if duel.youCharmedFoe}
|
||||
{#each duel.charmedFoes as id (id)}
|
||||
<label class="field">
|
||||
<span>{charmedName}'s charmed {charmedHandName} hand makes</span>
|
||||
<select bind:value={duel.charmGesture}>
|
||||
<span>{duel.state.wizards[id].name}'s charmed {duel.state.wizards[id].constraints.charmed?.hand} hand makes</span>
|
||||
<select bind:value={duel.charmGestures[id]}>
|
||||
{#each MAGIC_GESTURES as g (g)}
|
||||
<option value={g}>{glyph(g)} {GESTURE_SHORT[g]}</option>
|
||||
{/each}
|
||||
</select>
|
||||
</label>
|
||||
{/if}
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
{#if duel.remote?.error}
|
||||
<p class="warning">{duel.remote.error}</p>
|
||||
{/if}
|
||||
{#if duel.moved}
|
||||
<p class="waiting">Your move is in. Waiting for {duel.awaiting.join(' and ')}.</p>
|
||||
<p class="waiting">Your move is in. Waiting for {duel.awaitingText}.</p>
|
||||
{/if}
|
||||
{#if duel.surrendering}
|
||||
<p class="warning">Both palms at once is surrender. You will lose the duel.</p>
|
||||
@@ -191,6 +195,7 @@
|
||||
{duel.moved ? 'Waiting' : duel.sending ? 'Sending' : duel.surrendering ? 'Surrender' : duel.timeStopped ? 'Act in the stopped moment' : 'Reveal gestures'}
|
||||
</button>
|
||||
</section>
|
||||
{/if}
|
||||
{/if}
|
||||
</section>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user