feat: implement core Foundry VTT system framework, including actor/item data models, spellcasting logic, dice mechanics, and automation scripts

This commit is contained in:
Octoturge
2026-06-14 10:12:47 +02:00
parent fb42c6e8cc
commit 624fe2ee1a
70 changed files with 1645 additions and 1146 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
// HbM Apply Condition pick a status effect and toggle it on targeted/selected tokens.
// HbM Apply Condition - pick a status effect and toggle it on targeted/selected tokens.
const targets = game.user.targets.size > 0 ? Array.from(game.user.targets) : canvas.tokens.controlled;
if (targets.length === 0) return ui.notifications.warn('Zaznacz lub naceluj token(y).');
const effects = CONFIG.statusEffects.filter((e) => e.id?.startsWith('hbm.'));
+3 -3
View File
@@ -1,11 +1,11 @@
// HbM Attribute Check pick attribute on selected token's actor, roll d6 pool.
// HbM Attribute Check - pick attribute on selected token's actor, roll d6 pool.
const actor = canvas.tokens.controlled[0]?.actor ?? game.user.character;
if (!actor) return ui.notifications.warn('Wybierz token postaci.');
const attrs = ['body', 'mind', 'soul', 'magic'];
const labels = { body: 'Ciało', mind: 'Umysł', soul: 'Dusza', magic: 'Magia' };
const opts = attrs.map((a) => `<option value="${a}">${labels[a]} (${actor.system.attributes[a]?.value ?? 0})</option>`).join('');
const result = await Dialog.prompt({
title: `Test atrybutu ${actor.name}`,
title: `Test atrybutu - ${actor.name}`,
content: `
<form>
<div class="form-group">
@@ -27,4 +27,4 @@ const result = await Dialog.prompt({
if (!result) return;
const pool = actor.system.attributes[result.attr]?.value ?? 1;
const roll = await new Roll(`${pool}d6cs>=${result.threshold}`).evaluate();
await roll.toMessage({ flavor: `${actor.name} test ${labels[result.attr]} (TS ${result.threshold})`, speaker: ChatMessage.getSpeaker({ actor }) });
await roll.toMessage({ flavor: `${actor.name} - test ${labels[result.attr]} (TS ${result.threshold})`, speaker: ChatMessage.getSpeaker({ actor }) });
+2 -2
View File
@@ -1,4 +1,4 @@
// HbM Group Cast Helper sum mana of controlled token actors (potential co-casters).
// HbM Group Cast Helper - sum mana of controlled token actors (potential co-casters).
const tokens = canvas.tokens.controlled;
if (tokens.length < 2) return ui.notifications.warn('Zaznacz co najmniej 2 tokeny współrzucających.');
const lines = [];
@@ -11,7 +11,7 @@ for (const t of tokens) {
const magic = a.system.attributes?.magic?.value ?? 0;
totalMana += mana;
totalPool += magic;
lines.push(`<li><strong>${a.name}</strong> Mana ${mana}, Magia ${magic}</li>`);
lines.push(`<li><strong>${a.name}</strong> - Mana ${mana}, Magia ${magic}</li>`);
}
const html = `
<div class="hbm-group-cast">
+3 -3
View File
@@ -1,6 +1,6 @@
// HbM Long Rest invoke game.hbm.rest(actor, 'long') on selected token's actor.
// HbM Long Rest - invoke game.hbm.rest(actor, 'long') on selected token's actor.
const actor = canvas.tokens.controlled[0]?.actor ?? game.user.character;
if (!actor) return ui.notifications.warn('Wybierz token postaci.');
if (!game.hbm?.rest) return ui.notifications.error('Brak game.hbm.rest system niezainicjowany.');
if (!game.hbm?.rest) return ui.notifications.error('Brak game.hbm.rest - system niezainicjowany.');
const result = await game.hbm.rest(actor, 'long');
ui.notifications.info(`${actor.name}: długi odpoczynek pełna regeneracja zasobów.`);
ui.notifications.info(`${actor.name}: długi odpoczynek - pełna regeneracja zasobów.`);
+1 -1
View File
@@ -1,4 +1,4 @@
// HbM Pool Roll prompts for pool size and threshold, then rolls a d6 pool.
// HbM Pool Roll - prompts for pool size and threshold, then rolls a d6 pool.
const result = await Dialog.prompt({
title: 'Rzut puli d6',
content: `
+1 -1
View File
@@ -1,4 +1,4 @@
// HbM Refill Zeal bumps zeal by 1 on selected token's actor (debug helper).
// HbM Refill Zeal - bumps zeal by 1 on selected token's actor (debug helper).
const actor = canvas.tokens.controlled[0]?.actor ?? game.user.character;
if (!actor) return ui.notifications.warn('Wybierz token postaci.');
const cur = actor.system.attributes?.zeal?.value ?? 0;
+3 -3
View File
@@ -1,6 +1,6 @@
// HbM Short Rest invoke game.hbm.rest(actor, 'short') on selected token's actor.
// HbM Short Rest - invoke game.hbm.rest(actor, 'short') on selected token's actor.
const actor = canvas.tokens.controlled[0]?.actor ?? game.user.character;
if (!actor) return ui.notifications.warn('Wybierz token postaci.');
if (!game.hbm?.rest) return ui.notifications.error('Brak game.hbm.rest system niezainicjowany.');
if (!game.hbm?.rest) return ui.notifications.error('Brak game.hbm.rest - system niezainicjowany.');
const result = await game.hbm.rest(actor, 'short');
ui.notifications.info(`${actor.name}: krótki odpoczynek przywrócono ${result?.healed ?? 0} PW.`);
ui.notifications.info(`${actor.name}: krótki odpoczynek - przywrócono ${result?.hpRestored ?? 0} PW.`);
+6
View File
@@ -0,0 +1,6 @@
// HbM Take a Breather - invoke game.hbm.rest(actor, 'breather') on selected token's actor.
const actor = canvas.tokens.controlled[0]?.actor ?? game.user.character;
if (!actor) return ui.notifications.warn('Wybierz token postaci.');
if (!game.hbm?.rest) return ui.notifications.error('Brak game.hbm.rest - system niezainicjowany.');
const result = await game.hbm.rest(actor, 'breather');
ui.notifications.info(`${actor.name}: chwila wytchnienia - przywrócono ${result?.hpRestored ?? 0} PW i ${result?.manaRestored ?? 0} Many.`);