feat(sts-viewer): implement combat state and fix inventory removal
- Add `createCombatState` to initialize combat using inventory and run state - Implement `runContext` to bridge inventory data with combat logic - Update inventory to use `removeItem` instead of `removeItemFromGrid`
This commit is contained in:
parent
82c026628a
commit
9637312b7c
|
|
@ -0,0 +1,62 @@
|
||||||
|
import {
|
||||||
|
buildCombatState,
|
||||||
|
CombatState,
|
||||||
|
createRunState,
|
||||||
|
createStartWith,
|
||||||
|
data,
|
||||||
|
generateDeckFromInventory,
|
||||||
|
getAdjacentItems,
|
||||||
|
getItemEffects,
|
||||||
|
IRunContext,
|
||||||
|
} from "boardgame-core/samples/slay-the-spire-like";
|
||||||
|
import { createInventorySignal } from "./inventory";
|
||||||
|
import { GameModule } from "boardgame-core";
|
||||||
|
|
||||||
|
export function createCombatState() {
|
||||||
|
const inventory = createInventorySignal(true);
|
||||||
|
|
||||||
|
const deck = generateDeckFromInventory(inventory.value);
|
||||||
|
|
||||||
|
const run = createRunState();
|
||||||
|
|
||||||
|
const encounter = data.desert.getEncounters()[0];
|
||||||
|
|
||||||
|
const effects = getItemEffects(inventory.value);
|
||||||
|
const combat = buildCombatState(
|
||||||
|
{
|
||||||
|
hp: run.currentHp,
|
||||||
|
maxHp: run.maxHp,
|
||||||
|
itemEffects: effects,
|
||||||
|
},
|
||||||
|
deck,
|
||||||
|
encounter,
|
||||||
|
);
|
||||||
|
|
||||||
|
const runContext: IRunContext = {
|
||||||
|
getItemData(id: string) {
|
||||||
|
return inventory.value.items.get(id)?.meta?.itemData || null;
|
||||||
|
},
|
||||||
|
getAdjacentItems(id: string) {
|
||||||
|
return getAdjacentItems(inventory.value, id).keys();
|
||||||
|
},
|
||||||
|
getConsumedUses(id: string) {
|
||||||
|
return inventory.value.items.get(id)?.meta?.consumedUses || 0;
|
||||||
|
},
|
||||||
|
async setConsumedUsesAsync(id: string, uses: number) {
|
||||||
|
await inventory.produceAsync((draft) => {
|
||||||
|
const item = draft.items.get(id);
|
||||||
|
if (!item?.meta) return;
|
||||||
|
item.meta.consumedUses = uses;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const start = createStartWith((triggers, ctx) => {
|
||||||
|
data.desert.addTriggers(triggers, runContext);
|
||||||
|
}, runContext);
|
||||||
|
|
||||||
|
return {
|
||||||
|
start,
|
||||||
|
createInitialState: () => combat,
|
||||||
|
} as GameModule<CombatState>;
|
||||||
|
}
|
||||||
|
|
@ -6,7 +6,7 @@ import {
|
||||||
data,
|
data,
|
||||||
GameItemMeta,
|
GameItemMeta,
|
||||||
placeItem,
|
placeItem,
|
||||||
removeItemFromGrid,
|
removeItem,
|
||||||
Transform2D,
|
Transform2D,
|
||||||
validatePlacement,
|
validatePlacement,
|
||||||
} from "boardgame-core/samples/slay-the-spire-like";
|
} from "boardgame-core/samples/slay-the-spire-like";
|
||||||
|
|
@ -58,14 +58,14 @@ export function moveItem(
|
||||||
};
|
};
|
||||||
|
|
||||||
const removed = create(to.value, (inv) => {
|
const removed = create(to.value, (inv) => {
|
||||||
removeItemFromGrid(inv, itemId);
|
removeItem(inv, itemId);
|
||||||
});
|
});
|
||||||
const validation = validatePlacement(removed, item.shape, newTransform);
|
const validation = validatePlacement(removed, item.shape, newTransform);
|
||||||
if (!validation.valid) return false;
|
if (!validation.valid) return false;
|
||||||
|
|
||||||
batch(() => {
|
batch(() => {
|
||||||
from.produce((inv) => {
|
from.produce((inv) => {
|
||||||
removeItemFromGrid(inv, itemId);
|
removeItem(inv, itemId);
|
||||||
});
|
});
|
||||||
to.produce((inv) => {
|
to.produce((inv) => {
|
||||||
placeItem(inv, {
|
placeItem(inv, {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue