fix draft ui

This commit is contained in:
2026-04-10 15:49:51 -04:00
parent 30e3f88b21
commit e1df545f6e
2 changed files with 30 additions and 16 deletions

View File

@@ -13,5 +13,9 @@
"devDependencies": {
"typescript": "^6.0.2",
"vite": "^5.4.19"
},
"dependencies": {
"hono": "^4.12.12",
"waku": "^1.0.0-alpha.7"
}
}

View File

@@ -1,11 +1,11 @@
import "./styles.css";
import "./styles/globals.css";
import {
ROOT_SHIFT_COST,
ROUND_ANIMATION_BONUS_MS,
ROUND_ANIMATION_BRANCH_MS,
ROUND_ANIMATION_SUN_MS,
} from "./constants";
} from "./engine/constants";
import {
buildChildrenMap as buildChildrenMapForState,
buildParentMap as buildParentMapForState,
@@ -14,18 +14,18 @@ import {
getNodeOwner as getNodeOwnerForState,
getRootShiftMove as getRootShiftMoveForState,
playerHasLegalMove as playerHasLegalMoveForState,
} from "./rules-board";
} from "./engine/rules-board";
import {
buildEnergySimulation,
buildRoundAnimation as buildRoundAnimationForState,
maybeRollDisease as maybeRollDiseaseForState,
maybeRollSunbeam as maybeRollSunbeamForState,
scoreColumns as scoreColumnsForState,
} from "./rules-scoring";
} from "./engine/rules-scoring";
import {
createInitiativeDraft,
getInitiativeGraceRounds,
} from "./rules-initiative";
} from "./engine/rules-initiative";
import {
WEATHER_OFFER_PAIRS,
createWeatherDraft,
@@ -33,7 +33,7 @@ import {
getWeatherCard,
isWeatherCardAvailable,
isWeatherOfferResolved,
} from "./rules-weather";
} from "./engine/rules-weather";
import {
createInitialState,
createPlayers,
@@ -41,7 +41,7 @@ import {
createSetupState,
getMaxStartingNodesPerPlayer,
normalizeSeedInputs,
} from "./state";
} from "./engine/state";
import type {
GameState,
GrowTarget,
@@ -52,8 +52,8 @@ import type {
ShiftMove,
TurnMove,
WeatherCardId,
} from "./types";
import { keyFor, parseKey, tint, wait } from "./utils";
} from "./engine/types";
import { keyFor, parseKey, tint, wait } from "./engine/utils";
const app = document.querySelector("#app");
@@ -520,6 +520,9 @@ function chooseWeatherAction(offerId: string, cardId: WeatherCardId, action: "dr
return;
}
const offer = draft.offers.find((entry) => entry.id === offerId);
const otherCardId = offer?.options.find((option) => option !== cardId) ?? null;
const playerId = getCurrentWeatherPlayerId(draft);
if (action === "draft") {
const card = getWeatherCard(cardId);
@@ -531,6 +534,10 @@ function chooseWeatherAction(offerId: string, cardId: WeatherCardId, action: "dr
state.history.unshift(`${state.players[playerId].name} banned ${card?.title ?? cardId}.`);
}
if (otherCardId && !draft.locked.includes(otherCardId)) {
draft.locked.push(otherCardId);
}
if (draft.draftIndex >= draft.playerOrder.length - 1) {
finalizeWeatherDraft();
render();
@@ -1077,7 +1084,7 @@ function renderWeatherDraftModal() {
</div>
</div>
<div class="seed-editor">
<p class="seed-help">${currentPlayer?.name ?? "A player"} can draft or ban either card in each offer.</p>
<p class="seed-help">${currentPlayer?.name ?? "A player"} can draft or ban 1 card. Offered in pairs.</p>
<div class="weather-key" aria-label="Weather action key">
<span><strong>☀ Draft</strong>: take that card for 1 round</span>
<span><strong>✕ Ban</strong>: remove just that card</span>
@@ -1094,13 +1101,14 @@ function renderWeatherDraftModal() {
<div>
<p class="eyebrow">Offer</p>
<div class="weather-pair">
${offer.options.map((cardId) => {
${offer.options.map((cardId, optionIndex) => {
const card = getWeatherCard(cardId);
const drafted = draft.drafted.includes(cardId);
const banned = draft.banned.includes(cardId);
const locked = draft.locked.includes(cardId);
const available = isWeatherCardAvailable(draft, offer.id, cardId);
return `
<div class="weather-pair__option${drafted ? " weather-pair__option--drafted" : ""}${banned ? " weather-pair__option--banned" : ""}">
return `${optionIndex === 1 ? `<div class="weather-pair__divider">-- OR --</div>` : ""}
<div class="weather-pair__option${drafted ? " weather-pair__option--drafted" : ""}${banned ? " weather-pair__option--banned" : ""}${locked ? " weather-pair__option--locked" : ""}">
<h2>${card?.title ?? cardId}</h2>
<p>${card?.description ?? ""}</p>
${available ? `
@@ -1114,7 +1122,7 @@ function renderWeatherDraftModal() {
<span><strong>Ban</strong></span>
</button>
</div>
` : `<p class="weather-card__status">${drafted ? "Drafted" : "Banned"}</p>`}
` : `<p class="weather-card__status">${drafted ? "Drafted" : banned ? "Banned" : "Locked"}</p>`}
</div>
`;
}).join("")}
@@ -1396,7 +1404,6 @@ function renderSidebar() {
return `
<aside class="sidebar">
<button class="ghost-button new-game-launch" id="new-game">New Game</button>
<section class="panel status-panel status-panel--weather">
<h2>In Effect</h2>
${activeEffectsMarkup}
@@ -1455,7 +1462,10 @@ function renderSidebar() {
</section>
<section class="panel finish-panel">
<div class="button-row finish-panel__actions">
<button id="new-game" class="ghost-button finish-game-button">New Game</button>
<button id="finish-game" class="ghost-button finish-game-button" ${boardLocked ? "disabled" : ""}>End Game / Score Now</button>
</div>
</section>
</aside>
`;