From 77eb69b4e7ddba2f0e2651df5cd88e02a71a6521 Mon Sep 17 00:00:00 2001 From: customcommander Date: Mon, 16 Sep 2024 22:04:38 +0100 Subject: [PATCH] basic support for sowing grain/vegetable (wip) --- src/component-farmyard.js | 3 +- src/component-space.js | 4 ++ src/messages_en.yaml | 2 + src/task-113.js | 77 +++++++++++++++++++++++++++++++++++---- src/task-lib.js | 22 ++++++++--- 5 files changed, 93 insertions(+), 15 deletions(-) diff --git a/src/component-farmyard.js b/src/component-farmyard.js index e2f0736..8a35913 100644 --- a/src/component-farmyard.js +++ b/src/component-farmyard.js @@ -123,7 +123,8 @@ class FarmYard extends LitElement { return html` + type=${space?.type ?? nothing} + grain=${space?.grain ?? nothing}> ${map(selections ?? [], (sel) => this._cta(sel))} `; diff --git a/src/component-space.js b/src/component-space.js index a13738f..d6cdbe3 100644 --- a/src/component-space.js +++ b/src/component-space.js @@ -10,6 +10,10 @@ class Space extends LitElement { background-color: green; } + :host([type="field"][grain]) { + background-color: yellow; + } + :host([type="wooden-hut"]) { background-color: brown; } diff --git a/src/messages_en.yaml b/src/messages_en.yaml index 20049a8..408d452 100644 --- a/src/messages_en.yaml +++ b/src/messages_en.yaml @@ -40,6 +40,8 @@ select.stable: Stable select.wooden-hut: Wooden Hut select.clay-hut: Clay Hut select.stone-house: Stone House +select.sow-grain: Sow Grain +select.sow-vegetable: Sow Vegetable task-not-avail: > Not available until turn {turn} diff --git a/src/task-113.js b/src/task-113.js index 7f9eed7..335d8ca 100644 --- a/src/task-113.js +++ b/src/task-113.js @@ -4,9 +4,21 @@ */ -import {and, or} from 'xstate'; +import {and, or, enqueueActions} from 'xstate'; import {base} from './task-lib.js'; +function sow_grain({params: {space_id}}, game_context) { + game_context.supply.grain -= 1; + game_context.farmyard[space_id].grain = 3; + return game_context; +} + +function sow_vegetable({params: {space_id}}, game_context) { + game_context.supply.vegetable -= 1; + game_context.farmyard[space_id].vegetable = 2; + return game_context; +} + const machine = base.createMachine({ initial: 'idle', states: { @@ -14,17 +26,15 @@ const machine = base.createMachine({ on: { 'task.selected': [ { - target: 'work', - guard: and(['has-empty-fields?', or(['has-grain?', - 'has-vegetable?'])]), + target: 'select-space', + guard: and(['has-empty-fields?', or(['has-grain?', 'has-vegetable?'])]), actions: { - type: 'abort', + type: 'display-selection', params: { task_id: 113, - err: 'TODO' + opts: ['select.sow'] } } - }, { actions: { @@ -38,10 +48,61 @@ const machine = base.createMachine({ ] } }, + 'select-space': { + entry: 'compute-&-display-selection', + on: { + 'select.*': { + target: 'work', + }, + 'task.exit': { + target: 'idle', + actions: ['early-exit-stop', 'task-complete'] + } + }, + exit: 'clear-selection' + }, work: { + entry: { + type: 'game-update', + params: ({event: {type, space_id}}) => ({ + space_id, + reply_to: 113, + updater: ( type === 'select.sow-grain' ? sow_grain + : type === 'select.sow-vegetable' ? sow_vegetable + : null /* throw? */) + }) + }, + on: { + 'game.updated': [ + { + target: 'select-space', + guard: and(['has-empty-fields?', or(['has-grain?', 'has-vegetable?'])]), + actions: { + type: 'early-exit-init', + params: { + task_id: 113 + } + } + }, + { + target: 'idle', + actions: ['early-exit-stop', 'task-complete'] + } + ] + } } } }); -export default machine; +export default machine.provide({ + actions: { + 'compute-&-display-selection': + enqueueActions(({enqueue, check}) => { + const opts = []; + if (check('has-grain?')) opts.push('select.sow-grain'); + if (check('has-vegetable?')) opts.push('select.sow-vegetable'); + enqueue({type: 'display-selection', params: {task_id: 113, opts}}); + }) + } +}); diff --git a/src/task-lib.js b/src/task-lib.js index c3be638..0c2f643 100644 --- a/src/task-lib.js +++ b/src/task-lib.js @@ -8,6 +8,13 @@ import { produce } from 'immer'; + +function is_empty_field(space) { + if (space?.type !== 'field') return false; + const {grain = 0, vegetable = 0} = space; + return !grain && !vegetable; +} + /* TODO: If things of the same kind already exist @@ -19,7 +26,14 @@ function selection({params}, draft) { const spaces = Object.entries(draft.farmyard); draft.selection = opts.flatMap(opt => { - const avail = spaces.filter(([, sp]) => sp == null); + let avail; + + if (opt === 'select.sow-grain' || opt === 'select.sow-vegetable') { + avail = spaces.filter(([, sp]) => is_empty_field(sp)); + } else { + avail = spaces.filter(([, sp]) => sp == null); + } + return avail.map(([space_id]) => ({type: opt, task_id, space_id})); }); @@ -122,11 +136,7 @@ export const base = setup({ ({event: {game_context}}) => { const {farmyard} = game_context; const spaces = Object.values(farmyard); - return spaces.some(space => { - if (space?.type !== 'field') return false; - const {grain = 0, vegetable = 0} = space; - return !grain && !vegetable; - }); + return spaces.some(space => is_empty_field(space)); } } });