diff --git a/client/src/api.ts b/client/src/api.ts index 926468a..bc91fdb 100644 --- a/client/src/api.ts +++ b/client/src/api.ts @@ -6,6 +6,9 @@ import type { GameItem, GameTalent, RollResult, + Spell, + CharacterSpell, + SpellCastResult, } from "./types"; const BASE = "/api"; @@ -134,3 +137,36 @@ export const getGameTalents = () => request("/game-talents"); // Rolls export const getRolls = (campaignId: number) => request(`/campaigns/${campaignId}/rolls`); + +// Spells +export async function getSpells(spellClass?: string): Promise { + const qs = spellClass ? `?class=${spellClass}` : ""; + return request(`/spells${qs}`); +} + +export async function getCharacterSpells(characterId: number): Promise { + return request(`/characters/${characterId}/spells`); +} + +export async function addCharacterSpell(characterId: number, spellId: number): Promise { + return request(`/characters/${characterId}/spells`, { + method: "POST", + body: JSON.stringify({ spell_id: spellId }), + }); +} + +export async function removeCharacterSpell(characterId: number, spellId: number): Promise { + return request(`/characters/${characterId}/spells/${spellId}`, { method: "DELETE" }); +} + +export async function castSpell(characterId: number, spellId: number): Promise { + return request(`/characters/${characterId}/spells/${spellId}/cast`, { method: "POST" }); +} + +export async function restCharacter(characterId: number): Promise { + return request(`/characters/${characterId}/rest`, { method: "POST" }); +} + +export async function undoRoll(campaignId: number, rollId: number): Promise { + return request(`/campaigns/${campaignId}/rolls/${rollId}/undo`, { method: "POST" }); +} diff --git a/client/src/types.ts b/client/src/types.ts index c3c7b48..0209ee3 100644 --- a/client/src/types.ts +++ b/client/src/types.ts @@ -96,6 +96,7 @@ export interface RollResult { character_name: string; character_color: string; type: "attack" | "ability-check" | "custom"; + subtype?: string; label: string; dice_expression: string; rolls: number[]; @@ -104,5 +105,55 @@ export interface RollResult { advantage: boolean; disadvantage: boolean; nat20: boolean; + undone?: boolean; created_at: string; } + +export interface Spell { + id: number; + name: string; + class: "wizard" | "priest" | "both"; + tier: number; + casting_stat: "INT" | "WIS"; + duration: string; + range: string; + is_focus: number; + description: string; +} + +export interface CharacterSpell { + id: number; + spell_id: number; + character_id?: number; + exhausted: number; + locked_until: string | null; + focus_active: number; + focus_started_at: string | null; + name: string; + class: "wizard" | "priest" | "both"; + tier: number; + casting_stat: "INT" | "WIS"; + duration: string; + range: string; + is_focus: number; + description: string; +} + +export interface SpellCastResult { + rollId: number; + roll: number; + modifier: number; + total: number; + dc: number; + result: "success" | "failure" | "crit_success" | "crit_fail"; + mishapResult: Record | null; +} + +export interface Condition { + id: number; + character_id: number; + name: string; + description: string; + rounds_remaining: number | null; + expires_at: string | null; +}