80 lines
3.1 KiB
Svelte
80 lines
3.1 KiB
Svelte
<script>
|
||
import Card from './Card.svelte';
|
||
import ChallengePanel from './scene/ChallengePanel.svelte';
|
||
import ObstacleBoard from './scene/ObstacleBoard.svelte';
|
||
import CrewColumn from './scene/CrewColumn.svelte';
|
||
import EventLog from './EventLog.svelte';
|
||
|
||
export let state;
|
||
|
||
// The inline Event Log can be toggled from a fixed corner button to declutter.
|
||
let logOpen = true;
|
||
|
||
$: hand = state.player.hand_cards ? JSON.parse(state.player.hand_cards) : [];
|
||
$: playerTechs = { J: state.player.tech_jack, Q: state.player.tech_queen, K: state.player.tech_king };
|
||
$: isDeep = state.player.role === 'deep';
|
||
$: openChallenges = (state.challenges || []).filter(c => c.status === 'open');
|
||
// The Challenge area is shown when something is happening there, or to the Deep
|
||
// (who calls Challenges and ends the scene from it).
|
||
$: showChallengeArea = isDeep || openChallenges.length > 0;
|
||
</script>
|
||
|
||
<div class="scene-view-layout" class:log-collapsed={!logOpen} id="scene-layout-container" data-game-id={state.game.id} data-player-id={state.player.id}>
|
||
<!-- LEFT COLUMN: The Crew -->
|
||
<CrewColumn {state} />
|
||
|
||
<!-- MIDDLE COLUMN: Your hand, the Challenge, the Obstacle list -->
|
||
<div class="table-column">
|
||
{#if !isDeep}
|
||
<div class="card glass-panel hand-card">
|
||
<span class="hand-label">🃏 Your Hand</span>
|
||
|
||
<div class="hand-flex">
|
||
{#each hand as card}
|
||
<Card {card} techs={playerTechs}
|
||
draggable={true}
|
||
on:dragstart={(e) => {
|
||
e.dataTransfer.setData('text/plain', card);
|
||
e.currentTarget.classList.add("dragging");
|
||
}}
|
||
on:dragend={(e) => {
|
||
e.currentTarget.classList.remove("dragging");
|
||
}} />
|
||
{:else}
|
||
<p class="empty-text text-center">Empty hand. Match an obstacle’s color to draw cards.</p>
|
||
{/each}
|
||
</div>
|
||
</div>
|
||
{/if}
|
||
|
||
{#if showChallengeArea}
|
||
<div class="card glass-panel challenge-area-card">
|
||
<ChallengePanel {state} />
|
||
</div>
|
||
{/if}
|
||
|
||
<div class="card glass-panel obstacle-list-card">
|
||
<div class="card-header">
|
||
<h3>🌊 Obstacles</h3>
|
||
<span class="deck-counter">🎴 Deck: {state.game.deck_cards ? JSON.parse(state.game.deck_cards).length : 0} cards left</span>
|
||
</div>
|
||
<ObstacleBoard {state} />
|
||
</div>
|
||
</div>
|
||
|
||
<!-- RIGHT COLUMN: The Event Log (collapsible to a corner button) -->
|
||
{#if logOpen}
|
||
<div class="log-column">
|
||
<EventLog {state} inline on:collapse={() => (logOpen = false)} />
|
||
</div>
|
||
{/if}
|
||
</div>
|
||
|
||
<button
|
||
class="log-reopen-btn"
|
||
title={logOpen ? 'Hide the event log' : 'Show the event log'}
|
||
on:click={() => (logOpen = !logOpen)}
|
||
>
|
||
{logOpen ? '✕ Close Log' : '📜 Event Log'}
|
||
</button>
|