diff --git a/css/fvtt-lethal-fantasy.css b/css/fvtt-lethal-fantasy.css index 2413461..2119d62 100644 --- a/css/fvtt-lethal-fantasy.css +++ b/css/fvtt-lethal-fantasy.css @@ -60,6 +60,12 @@ i.lethalfantasy { background-repeat: no-repeat; background-size: 100% 100%; } +.combat-sidebar li.combatant .token-initiative .initiative { + margin-right: 16px; +} +.combat-sidebar li.combatant .token-initiative { + flex: none; +} .lethalfantasy .character-sheet-common label { font-family: var(--font-secondary); font-size: calc(var(--font-size-standard) * 1.2); @@ -146,8 +152,8 @@ i.lethalfantasy { flex: 1; } .lethalfantasy .character-main .character-pc .character-left { - min-width: 220px; - max-width: 220px; + min-width: 200px; + max-width: 200px; display: flex; flex-direction: column; } @@ -165,28 +171,34 @@ i.lethalfantasy { } .lethalfantasy .character-main .character-pc .character-left .character-hp { display: flex; - gap: 2px; + gap: 4px; align-items: center; + margin-bottom: 4px; } -.lethalfantasy .character-main .character-pc .character-left .character-hp .character-hp-value .form-fields input { +.lethalfantasy .character-main .character-pc .character-left .character-hp .name { flex: none; - min-width: 3rem; - max-width: 3rem; - margin-left: 10px; - font-size: calc(var(--font-size-standard) * 1.4); + min-width: 2.5rem; + max-width: 2.5rem; +} +.lethalfantasy .character-main .character-pc .character-left .character-hp input { + flex: none; + min-width: 2.2rem; + max-width: 2.2rem; + margin-left: 4px; + font-size: calc(var(--font-size-standard) * 1); } .lethalfantasy .character-main .character-pc .character-left .character-hp .character-hp-max { clear: both; display: flex; flex-direction: row; flex-wrap: wrap; - margin: 3px 0; + margin: 4px 0; align-items: center; } .lethalfantasy .character-main .character-pc .character-left .character-hp .character-hp-max input { - width: 50px; + width: 3.2rem; text-align: center; - font-size: calc(var(--font-size-standard) * 1.4); + font-size: calc(var(--font-size-standard) * 1); } .lethalfantasy .character-main .character-pc .character-right { display: flex; @@ -200,16 +212,15 @@ i.lethalfantasy { width: 400px; } .lethalfantasy .character-main .character-pc-play { - min-width: 400px; + min-width: 320px; } .lethalfantasy .character-main .character-pc-edit { - min-width: 400px; + min-width: 320px; } .lethalfantasy .character-main .character-characteristics { display: flex; flex-direction: column; gap: 4px; - flex: 1; } .lethalfantasy .character-main .character-characteristics .character-characteristic { display: flex; @@ -323,10 +334,10 @@ i.lethalfantasy { width: 50px; } .lethalfantasy .character-main .character-characteristics-play { - min-width: 225px; + min-width: 160px; } .lethalfantasy .character-main .character-characteristic-edit { - min-width: 400px; + min-width: 160px; } .lethalfantasy .tab.character-biography .biodata { display: grid; @@ -485,8 +496,8 @@ i.lethalfantasy { gap: 4px; } .lethalfantasy .tab.character-combat .wounds .wound .wound-description { - min-width: 16rem; - max-width: 16rem; + min-width: 14rem; + max-width: 14rem; } .lethalfantasy .tab.character-combat .wounds .wound .wound-duration { min-width: 3rem; @@ -552,6 +563,27 @@ i.lethalfantasy { font-size: calc(var(--font-size-standard) * 1.4); padding-left: 4px; } +.lethalfantasy .tab.character-spells .spell-details { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 4px; +} +.lethalfantasy .tab.character-spells .spell-details .spell-detail { + display: flex; + align-items: center; + gap: 4px; +} +.lethalfantasy .tab.character-spells .spell-details .spell-detail button { + min-width: 10rem; +} +.lethalfantasy .tab.character-spells .spell-details .spell-detail .armor-hp { + min-width: 20rem; + max-width: 20rem; +} +.lethalfantasy .tab.character-spells .spell-details .spell-detail .armor-hp .input { + min-width: 3rem; + max-width: 3rem; +} .lethalfantasy .tab.character-spells .spells { display: grid; grid-template-columns: repeat(3, 1fr); @@ -583,6 +615,27 @@ i.lethalfantasy { font-size: calc(var(--font-size-standard) * 1.4); padding-left: 4px; } +.lethalfantasy .tab.character-miracles .miracle-details { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 4px; +} +.lethalfantasy .tab.character-miracles .miracle-details .miracle-detail { + display: flex; + align-items: center; + gap: 4px; +} +.lethalfantasy .tab.character-miracles .miracle-details .miracle-detail button { + min-width: 10rem; +} +.lethalfantasy .tab.character-miracles .miracle-details .miracle-detail .armor-hp { + min-width: 20rem; + max-width: 20rem; +} +.lethalfantasy .tab.character-miracles .miracle-details .miracle-detail .armor-hp .input { + min-width: 3rem; + max-width: 3rem; +} .lethalfantasy .tab.character-miracles .miracles { display: grid; grid-template-columns: repeat(3, 1fr); @@ -662,53 +715,53 @@ i.lethalfantasy { .lethalfantasy .monster-main { display: flex; } -.lethalfantasy .monster-main .monster-pc { - display: flex; - gap: 10px; - flex: 1; -} -.lethalfantasy .monster-main .monster-pc .monster-left { - min-width: 220px; - max-width: 220px; - display: flex; - flex-direction: column; -} -.lethalfantasy .monster-main .monster-pc .monster-left .monster-left-image { +.lethalfantasy .monster-main .monster-left-image { display: flex; justify-content: center; align-items: center; - padding-bottom: 8px; + padding-bottom: 4px; } -.lethalfantasy .monster-main .monster-pc .monster-left .monster-left-image .monster-img { +.lethalfantasy .monster-main .monster-left-image .monster-img { height: 140px; width: 140px; width: auto; border: none; } -.lethalfantasy .monster-main .monster-pc .monster-left .monster-hp { +.lethalfantasy .monster-main .monster-pc { display: flex; - gap: 2px; + gap: 10px; + flex: 1; +} +.lethalfantasy .monster-main .monster-pc .monster-hp { + display: flex; + gap: 4px; align-items: center; + margin-bottom: 4px; } -.lethalfantasy .monster-main .monster-pc .monster-left .monster-hp .monster-hp-value .form-fields input { +.lethalfantasy .monster-main .monster-pc .monster-hp .name { flex: none; - min-width: 3rem; - max-width: 3rem; - margin-left: 10px; - font-size: calc(var(--font-size-standard) * 1.4); + min-width: 2.5rem; + max-width: 2.5rem; } -.lethalfantasy .monster-main .monster-pc .monster-left .monster-hp .monster-hp-max { +.lethalfantasy .monster-main .monster-pc .monster-hp input { + flex: none; + min-width: 2.2rem; + max-width: 2.2rem; + margin-left: 4px; + font-size: calc(var(--font-size-standard) * 1); +} +.lethalfantasy .monster-main .monster-pc .monster-hp .character-hp-max { clear: both; display: flex; flex-direction: row; flex-wrap: wrap; - margin: 3px 0; + margin: 4px 0; align-items: center; } -.lethalfantasy .monster-main .monster-pc .monster-left .monster-hp .monster-hp-max input { - width: 50px; +.lethalfantasy .monster-main .monster-pc .monster-hp .character-hp-max input { + width: 3.2rem; text-align: center; - font-size: calc(var(--font-size-standard) * 1.4); + font-size: calc(var(--font-size-standard) * 1); } .lethalfantasy .monster-main .monster-pc .monster-right { display: flex; @@ -781,7 +834,7 @@ i.lethalfantasy { } .lethalfantasy .monster-main .monster-resists .monster-resist .form-group .form-fields { flex: none; - width: 50px; + width: 2.5rem; } .lethalfantasy .monster-main .monster-movements { display: flex; @@ -849,10 +902,10 @@ i.lethalfantasy { width: 50px; } .lethalfantasy .monster-main .monster-characteristics-play { - min-width: 225px; + min-width: 200px; } .lethalfantasy .monster-main .monster-characteristic-edit { - min-width: 400px; + min-width: 200px; } .lethalfantasy .tab.monster-biography .biodata { display: grid; @@ -1005,12 +1058,16 @@ i.lethalfantasy { align-items: center; gap: 4px; } +.lethalfantasy .tab.monster-combat .attacks .attack .name { + min-width: 8rem; + max-width: 8rem; +} .lethalfantasy .tab.monster-combat .attacks .attack .damage-dice { width: 4rem; max-width: 3.5rem; } .lethalfantasy .tab.monster-combat .attacks .attack .numeric { - width: 2.5rem; + width: 2.2rem; } .lethalfantasy .tab.monster-combat .attacks .attack .attack-icons a { margin-left: 4px; @@ -1065,37 +1122,6 @@ i.lethalfantasy { .lethalfantasy .tab.monster-spells prose-mirror.active { min-height: 150px; } -.lethalfantasy .tab.monster-miracles { - display: grid; - grid-template-columns: 1fr; -} -.lethalfantasy .tab.monster-miracles legend a { - font-size: calc(var(--font-size-standard) * 1.4); - padding-left: 4px; -} -.lethalfantasy .tab.monster-miracles .miracles { - display: grid; - grid-template-columns: repeat(3, 1fr); - gap: 4px; -} -.lethalfantasy .tab.monster-miracles .miracles .miracle { - display: flex; - align-items: center; - gap: 4px; -} -.lethalfantasy .tab.monster-miracles .miracles .miracle .item-img { - width: 24px; - height: 24px; -} -.lethalfantasy .tab.monster-miracles .miracles .miracle .name { - min-width: 12rem; -} -.lethalfantasy .tab.monster-miracles prose-mirror.inactive { - min-height: 40px; -} -.lethalfantasy .tab.monster-miracles prose-mirror.active { - min-height: 150px; -} .lethalfantasy .skill-content { font-family: var(--font-primary); font-size: calc(var(--font-size-standard) * 1); diff --git a/lang/en.json b/lang/en.json index 609cc78..68f4ecf 100644 --- a/lang/en.json +++ b/lang/en.json @@ -278,6 +278,12 @@ } }, "Label": { + "progressionDice": "Progression dice", + "rollProgressionCount": "Roll progression count", + "rollProgressionDice": "Roll progression dice", + "earned": "Earned", + "divinityPoints": "Divinity points", + "aetherPoints": "Aether points", "attacks": "Attacks", "monster": "Monster", "Resist" :"Resist", @@ -446,7 +452,9 @@ "Notifications": { "rollFromWeapon": "Roll from an equipped weapon", "rollTypeNotFound": "Roll type not found", - "skillNotFound": "Skill not found" + "skillNotFound": "Skill not found", + "messageProgressionOK": "{name} can attack this second with {weapon}.", + "messageProgressionKO": "{name} can't attack this second." }, "Opponent": { "FIELDS": {} diff --git a/lethal-fantasy.mjs b/lethal-fantasy.mjs index 63887fa..f9b7adc 100644 --- a/lethal-fantasy.mjs +++ b/lethal-fantasy.mjs @@ -12,9 +12,7 @@ import * as documents from "./module/documents/_module.mjs" import * as applications from "./module/applications/_module.mjs" import { LethalFantasyCombatTracker, LethalFantasyCombat} from "./module/applications/combat.mjs" -import { handleSocketEvent } from "./module/socket.mjs" import { Macros } from "./module/macros.mjs" -import { initControlButtons } from "./module/control-buttons.mjs" import { setupTextEnrichers } from "./module/enrichers.mjs" import { default as LethalFantasyUtils } from "./module/utils.mjs" @@ -87,10 +85,7 @@ Hooks.once("init", function () { }) // Activate socket handler - game.socket.on(`system.${SYSTEM.id}`, handleSocketEvent) - - - initControlButtons() + game.socket.on(`system.${SYSTEM.id}`, LethalFantasyUtils.handleSocketEvent) setupTextEnrichers() LethalFantasyUtils.registerHandlebarsHelpers() diff --git a/module/applications/combat.mjs b/module/applications/combat.mjs index 74c0427..04efef4 100644 --- a/module/applications/combat.mjs +++ b/module/applications/combat.mjs @@ -2,6 +2,17 @@ /* -------------------------------------------- */ export class LethalFantasyCombatTracker extends CombatTracker { + async getData(options) { + let data = await super.getData(options); + for (let u of data.turns) { + let c = game.combat.combatants.get(u.id); + u.progressionCount = c.system.progressionCount + } + console.log("Combat Data", data); + return data; + } + + /* -------------------------------------------- */ static get defaultOptions() { let path = "systems/fvtt-lethal-fantasy/templates/combat-tracker.hbs"; @@ -36,104 +47,25 @@ export class LethalFantasyCombat extends Combat { async rollInitiative(ids, options) { console.log("%%%%%%%%% Roll Initiative", ids, options); - await this.setFlag("acks", "lock-turns", true); ids = typeof ids === "string" ? [ids] : ids; let messages = []; let rollMode = game.settings.get("core", "rollMode"); - // Get current groups - let groups = this.getFlag('acks', 'groups') || []; - let maxInit = { value: -1, cId: "" } let updates = []; for (let cId of ids) { const c = this.combatants.get(cId); - //console.log("Init for combattant", cId, c, ids) - let id = c._id || c.id - // get the associated token - let tokenId = c.token.id; - // Check if the current token ID is in a group - let groupData = groups.find((groupData) => groupData.tokens.includes(tokenId)); - let initValue = -1; - let showMessage = true - let roll - if (groupData && groupData.initiative > 0) { - initValue = groupData.initiative; - showMessage = false + let user = game.users.find(u => u.active && u.character && u.character.id === c.actor.id); + if (user?.hasPlayerOwner) { + console.log("Rolling initiative for", c.actor.name); + game.socket.emit(`system.${SYSTEM.id}`, { type: "rollInitiative", actorId: c.actor.id, combatId: this.id, combatantId: c.id }); } else { - roll = c.getInitiativeRoll(); - await roll.evaluate(); - initValue = roll.total; - } - if (groupData) { - groupData.initiative = initValue - } - updates.push({ _id: id, initiative: initValue }); - if (initValue > maxInit.value) { - maxInit.value = initValue; - maxInit.cId = id; - } - - if (showMessage) { - // Determine the roll mode - if ((c.token.hidden || c.hidden) - && (rollMode === "roll")) { - rollMode = "gmroll"; - } - - // Construct chat message data - const messageData = foundry.utils.mergeObject({ - speaker: { - scene: canvas.scene._id, - actor: c.actor?.id || null, - token: c.token.id, - alias: c.token.name - }, - flavor: game.i18n.format('ACKS.roll.individualInit', { - name: c.token.name, - }), - }, {}); - - const chatData = await roll.toMessage(messageData, { - rollMode, - create: false, - }); - if (messages.length > 0) { - chatData.sound = null; - } - messages.push(chatData); + user = game.users.find(u => u.active && u.isGM); + c.actor.system.rollInitiative(this.id, c.id); } } - await CONFIG.ChatMessage.documentClass.create(messages); - this.pools = AcksCombat.getCombatantsPool(); - await this.processOutNumbering(); - - await this.setFlag("acks", "lock-turns", false); - await this.updateEmbeddedDocuments("Combatant", updates); - - setTimeout(function () { - const updateData = { turn: 0 }; - game.combat.update(updateData); - }, 200); - return this; - - } - - async startCombat() { - console.log("Start Combat 1 !") - // Send chat message to all players to roll for initiative - ChatMessage.create({ - user: game.user.id, - content: await renderTemplate(`systems/fvtt-lethal-fantasy/templates/chat-ask-initiative.hbs`, { - title: "Initiative roll requested", - text: text, - rollType: type, - }), - flags: { "fvtt-lethal-fantasy": { msg: "request-initiative-roll", content: {} } }, - }) - ChatMessage.create({ content: message, type: CONST.CHAT_MESSAGE_TYPES.GAME }); } async nextTurn() { @@ -170,12 +102,25 @@ export class LethalFantasyCombat extends Combat { this.turnsDone = false let turn = this.turn === null ? null : 0; // Preserve the fact that it's no-one's turn currently. - console.log("ROUND", this.round, this.turns); + console.log("ROUND", this); let advanceTime = Math.max(this.turns.length - this.turn, 0) * CONFIG.time.turnTime; advanceTime += CONFIG.time.roundTime; let nextRound = this.round + 1; + for (let c of this.combatants) { + if ( nextRound >= c.initiative) { + c.update({ 'system.progressionCount': c.system.progressionCount + 1 }); + let user = game.users.find(u => u.active && u.character && u.character.id === c.actor.id); + if (user?.hasPlayerOwner) { + game.socket.emit(`system.${SYSTEM.id}`, { type: "rollProgressionDice", progressionCount: c.system.progressionCount+1, actorId: c.actor.id, combatId: this.id, combatantId: c.id }); + } else { + user = game.users.find(u => u.active && u.isGM); + c.actor.system.rollProgressionDice(this.id, c.id, c.system.progressionCount+1); + } + } + } + // Update the document, passing data through a hook first const updateData = { round: nextRound, turn }; const updateOptions = { advanceTime, direction: 1 }; diff --git a/module/applications/sheets/character-sheet.mjs b/module/applications/sheets/character-sheet.mjs index 7f3bd40..0c37264 100644 --- a/module/applications/sheets/character-sheet.mjs +++ b/module/applications/sheets/character-sheet.mjs @@ -6,7 +6,7 @@ export default class LethalFantasyCharacterSheet extends LethalFantasyActorSheet static DEFAULT_OPTIONS = { classes: ["character"], position: { - width: 1080, + width: 972, height: 780, }, window: { @@ -18,6 +18,10 @@ export default class LethalFantasyCharacterSheet extends LethalFantasyActorSheet rollInitiative: LethalFantasyCharacterSheet.#onRollInitiative, armorHitPointsPlus: LethalFantasyCharacterSheet.#onArmorHitPointsPlus, armorHitPointsMinus: LethalFantasyCharacterSheet.#onArmorHitPointsMinus, + divinityPointsPlus: LethalFantasyCharacterSheet.#onDivinityPointsPlus, + divinityPointsMinus: LethalFantasyCharacterSheet.#onDivinityPointsMinus, + aetherPointsPlus: LethalFantasyCharacterSheet.#onAetherPointsPlus, + aetherPointsMinus: LethalFantasyCharacterSheet.#onAetherPointsMinus, }, } @@ -162,22 +166,7 @@ export default class LethalFantasyCharacterSheet extends LethalFantasyActorSheet } static async #onRollInitiative(event, target) { - const hasTarget = false - let actorClass = this.actor.system.biodata.class; - - let wisDef = SYSTEM.CHARACTERISTICS_TABLES.wis.find((c) => c.value === this.actor.system.characteristics.wis.value) - let maxInit = Number(wisDef.init_cap) || 1000 - - let roll = await LethalFantasyRoll.promptInitiative({ - actorId: this.actor.id, - actorName: this.actor.name, - actorImage: this.actor.img, - actorClass, - maxInit, - }) - if (!roll) return null - - await roll.toMessage({}, { rollMode: roll.options.rollMode }) + await this.document.system.rollInitiative() } static #onArmorHitPointsPlus(event, target) { @@ -192,6 +181,34 @@ export default class LethalFantasyCharacterSheet extends LethalFantasyActorSheet this.actor.update({ "system.combat.armorHitPoints": Math.max(armorHP, 0) }) } + static #onDivinityPointsPlus(event, target) { + let points = this.actor.system.divinityPoints.value + points += 1 + points = Math.min(points, this.actor.system.divinityPoints.max) + this.actor.update({ "system.divinityPoints.value": points }) + } + + static #onDivinityPointsMinus(event, target) { + let points = this.actor.system.divinityPoints.value + points -= 1 + points = Math.max(points, 0) + this.actor.update({ "system.divinityPoints.value": points }) + } + + static #onAetherPointsPlus(event, target) { + let points = this.actor.system.aetherPoints.value + points += 1 + points = Math.min(points, this.actor.system.aetherPoints.max) + this.actor.update({ "system.aetherPoints.value": points }) + } + + static #onAetherPointsMinus(event, target) { + let points = this.actor.system.aetherPoints.value + points -= 1 + points = Math.max(points, 0) + this.actor.update({ "system.aetherPoints.value": points }) + } + static #onCreateEquipment(event, target) { } diff --git a/module/applications/sheets/monster-sheet.mjs b/module/applications/sheets/monster-sheet.mjs index 7e4ab48..ff324fb 100644 --- a/module/applications/sheets/monster-sheet.mjs +++ b/module/applications/sheets/monster-sheet.mjs @@ -6,7 +6,7 @@ export default class LethalFantasyMonsterSheet extends LethalFantasyActorSheet { static DEFAULT_OPTIONS = { classes: ["monster"], position: { - width: 980, + width: 1060, height: 780, }, window: { @@ -118,37 +118,7 @@ export default class LethalFantasyMonsterSheet extends LethalFantasyActorSheet { } static async #onRollInitiative(event, target) { - const hasTarget = false - let actorClass = this.actor.system.biodata.class; - - let wisDef = SYSTEM.CHARACTERISTICS_TABLES.wis.find((c) => c.value === this.actor.system.characteristics.wis.value) - let maxInit = Number(wisDef.init_cap) || 1000 - - let roll = await LethalFantasyRoll.promptInitiative({ - actorId: this.actor.id, - actorName: this.actor.name, - actorImage: this.actor.img, - actorClass, - maxInit, - }) - if (!roll) return null - - await roll.toMessage({}, { rollMode: roll.options.rollMode }) - } - - static #onArmorHitPointsPlus(event, target) { - let armorHP = this.actor.system.combat.armorHitPoints - armorHP += 1 - this.actor.update({ "system.combat.armorHitPoints": armorHP }) - } - - static #onArmorHitPointsMinus(event, target) { - let armorHP = this.actor.system.combat.armorHitPoints - armorHP -= 1 - this.actor.update({ "system.combat.armorHitPoints": Math.max(armorHP, 0) }) - } - - static #onCreateEquipment(event, target) { + await this.document.system.rollInitiative(event, target) } getBestWeaponClassSkill(skills, rollType, multiplier = 1.0) { diff --git a/module/control-buttons.mjs b/module/control-buttons.mjs deleted file mode 100644 index 6069314..0000000 --- a/module/control-buttons.mjs +++ /dev/null @@ -1,44 +0,0 @@ -/** - * Menu spécifique au système - */ -export function initControlButtons() { - CONFIG.Canvas.layers.tenebris = { layerClass: ControlsLayer, group: "primary" } - - Hooks.on("getSceneControlButtons", (btns) => { - let menu = [] - - menu.push({ - name: "fortune", - title: game.i18n.localize("TENEBRIS.Fortune.title"), - icon: "fa-solid fa-clover", - button: true, - onClick: () => { - if (!foundry.applications.instances.has("tenebris-application-fortune")) { - game.system.applicationFortune.render(true) - } else game.system.applicationFortune.close() - }, - }) - - if (game.user.isGM) { - menu.push({ - name: "gm-manager", - title: game.i18n.localize("TENEBRIS.Manager.title"), - icon: "fa-solid fa-users", - button: true, - onClick: () => { - if (!foundry.applications.instances.has("tenebris-application-manager")) { - game.system.applicationManager.render(true) - } else game.system.applicationManager.close() - }, - }) - } - - btns.push({ - name: "tenebris", - title: "Cthulhu LethalFantasy", - icon: "tenebris", - layer: "tenebris", - tools: menu, - }) - }) -} diff --git a/module/documents/roll.mjs b/module/documents/roll.mjs index 6e154b5..d9ed10f 100644 --- a/module/documents/roll.mjs +++ b/module/documents/roll.mjs @@ -229,7 +229,7 @@ export default class LethalFantasyRoll extends Roll { options.rollName = options.rollTarget.name hasModifier = true hasChangeDice = false - options.rollTarget.value = 0 + options.rollTarget.value = options.rollTarget.damageModifier options.rollTarget.charModifier = 0 dice = options.rollTarget.damageDice dice = dice.replace("E", "") @@ -517,11 +517,95 @@ export default class LethalFantasyRoll extends Roll { let initRoll = new Roll(`min(${rollContext.initiativeDice}, ${options.maxInit})`, options.data, rollContext) await initRoll.evaluate() - initRoll.toMessage( {flavor: `Initiative for ${options.actorName}`}, {rollMode: rollContext.visibility} ) + let msg = await initRoll.toMessage( {flavor: `Initiative for ${options.actorName}`}, {rollMode: rollContext.visibility} ) + await game.dice3d.waitFor3DAnimationByMessageID(msg.id) + + if (options.combatId && options.combatantId) { + let combat = game.combats.get(options.combatId) + combat.updateEmbeddedDocuments("Combatant", [ { _id: options.combatantId, initiative: initRoll.total, 'system.progressionCount': 0 } ]); + } + + } + + static async promptProgressionDice(options = {}) { + + const rollModes = Object.fromEntries(Object.entries(CONFIG.Dice.rollModes).map(([key, value]) => [key, game.i18n.localize(value)])) + const fieldRollMode = new foundry.data.fields.StringField({ + choices: rollModes, + blank: false, + default: "public", + }) + let dialogContext = { + progressionDiceId: "", + fieldRollMode, + rollModes, + ...options + } + + console.log("CTX PROGRESSION", dialogContext) + + const content = await renderTemplate("systems/fvtt-lethal-fantasy/templates/roll-progression-dice-dialog.hbs", dialogContext) + + const label = game.i18n.localize("LETHALFANTASY.Label.rollProgressionDice") + const rollContext = await foundry.applications.api.DialogV2.wait({ + window: { title: "Progression Roll" }, + classes: ["lethalfantasy"], + content, + buttons: [ + { + action: "roll", + label: label, + callback: (event, button, dialog) => { + const output = Array.from(button.form.elements).reduce((obj, input) => { + if (input.name) obj[input.name] = input.value + return obj + }, {}) + return output + }, + }, + { + action: "cancel", + label: "Other action, no weapon progression dice", + callback: (event, button, dialog) => { return null; } + } + ], + rejectClose: false // Click on Close button will not launch an error + }) + + console.log("RollContext", rollContext) + if (rollContext === null || !rollContext?.progressionDiceId) { + return + } + + // Get the weapons from the actor items + let actor = game.actors.get(options.actorId) + let weapon = actor.items.find(i => i.type === "weapon" && i.id === rollContext.progressionDiceId) + // Get the dice and roll it + let formula = weapon.system.combatProgressionDice + let roll = new Roll(formula) + await roll.evaluate() + + let max = roll.dice[0].faces - 1 + max = Math.min(options.rollProgressionCount, max) + let msg = await roll.toMessage( {flavor: `Progression Roll for ${weapon.name}, progression count : ${options.rollProgressionCount}/${max}`}, {rollMode: rollContext.visibility} ) + await game.dice3d.waitFor3DAnimationByMessageID(msg.id) + + if (roll.total <= max ) { + // Notify that the player can act now with a chat message + let message = game.i18n.format("LETHALFANTASY.Notifications.messageProgressionOK", { name: actor.name, weapon: weapon.name, roll: roll.total }) + ChatMessage.create({ content: message, speaker: ChatMessage.getSpeaker({ actor: actor }) }) + // Update the combatant progression count + let combat = game.combats.get(options.combatId) + let combatant = combat.combatants.get(options.combatantId) + combatant.update({ 'system.progressionCount': 0 }) + } else { + // Notify that the player cannot act now with a chat message + let message = game.i18n.format("LETHALFANTASY.Notifications.messageProgressionKO", { name: actor.name, weapon: weapon.name, roll: roll.total }) + ChatMessage.create({ content: message, speaker: ChatMessage.getSpeaker({ actor: actor }) }) + } } static async promptRangedDefense(rollTarget) { - const rollModes = Object.fromEntries(Object.entries(CONFIG.Dice.rollModes).map(([key, value]) => [key, game.i18n.localize(value)])) const fieldRollMode = new foundry.data.fields.StringField({ @@ -681,30 +765,8 @@ export default class LethalFantasyRoll extends Roll { return await renderTemplate(this.constructor.CHAT_TEMPLATE, chatData) } - /** + /* * Generates the data required for rendering a roll chat card. - * - * @param {boolean} isPrivate Indicates if the chat card is private. - * @returns {Promise} A promise that resolves to an object containing the chat card data. - * @property {Array} css - CSS classes for the chat card. - * @property {Object} data - The data associated with the roll. - * @property {number} diceTotal - The total value of the dice rolled. - * @property {boolean} isGM - Indicates if the user is a Game Master. - * @property {string} formula - The formula used for the roll. - * @property {number} total - The total result of the roll. - * @property {boolean} isSave - Indicates if the roll is a saving throw. - * @property {boolean} isDamage - Indicates if the roll is for damage. - * @property {boolean} isFailure - Indicates if the roll is a failure. - * @property {string} actorId - The ID of the actor performing the roll. - * @property {string} actingCharName - The name of the character performing the roll. - * @property {string} actingCharImg - The image of the character performing the roll. - * @property {string} resultType - The type of result (e.g., success, failure). - * @property {boolean} hasTarget - Indicates if the roll has a target. - * @property {string} targetName - The name of the target. - * @property {number} targetArmor - The armor value of the target. - * @property {boolean} isPrivate - Indicates if the chat card is private. - * @property {string} cssClass - The combined CSS classes as a single string. - * @property {string} tooltip - The tooltip text for the chat card. */ async _getChatCardData(isPrivate) { const cardData = { diff --git a/module/models/character.mjs b/module/models/character.mjs index 5c42dd7..d2e45c9 100644 --- a/module/models/character.mjs +++ b/module/models/character.mjs @@ -59,7 +59,7 @@ export default class LethalFantasyCharacter extends foundry.abstract.TypeDataMod ) const woundFieldSchema = { - value: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), + value: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), duration: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), description: new fields.StringField({ initial: "", required: false, nullable: true }), } @@ -68,9 +68,11 @@ export default class LethalFantasyCharacter extends foundry.abstract.TypeDataMod value: new fields.NumberField({ ...requiredInteger, initial: 1, min: 0 }), max: new fields.NumberField({ ...requiredInteger, initial: 1, min: 0 }), painDamage: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), - wounds: new fields.ArrayField(new fields.SchemaField(woundFieldSchema ) , { initial: [{description:"", value:0, duration:0},{description:"", value:0, duration:0}, - {description:"", value:0, duration:0},{description:"", value:0, duration:0},{description:"", value:0, duration:0},{description:"", value:0, duration:0}, - {description:"", value:0, duration:0},{description:"", value:0, duration:0}], min:8} ), + wounds: new fields.ArrayField(new fields.SchemaField(woundFieldSchema), { + initial: [{ description: "", value: 0, duration: 0 }, { description: "", value: 0, duration: 0 }, + { description: "", value: 0, duration: 0 }, { description: "", value: 0, duration: 0 }, { description: "", value: 0, duration: 0 }, { description: "", value: 0, duration: 0 }, + { description: "", value: 0, duration: 0 }, { description: "", value: 0, duration: 0 }], min: 8 + }), }) schema.perception = new fields.SchemaField({ @@ -99,7 +101,7 @@ export default class LethalFantasyCharacter extends foundry.abstract.TypeDataMod vertical: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), }) schema.biodata = new fields.SchemaField({ - class: new fields.StringField({required: true, initial: "untrained", choices: SYSTEM.CHAR_CLASSES}), + class: new fields.StringField({ required: true, initial: "untrained", choices: SYSTEM.CHAR_CLASSES }), level: new fields.NumberField({ ...requiredInteger, initial: 1, min: 1 }), mortal: new fields.StringField({ required: true, nullable: false, initial: "" }), alignment: new fields.StringField({ required: true, nullable: false, initial: "" }), @@ -110,13 +112,13 @@ export default class LethalFantasyCharacter extends foundry.abstract.TypeDataMod magicUser: new fields.BooleanField({ initial: false }), clericUser: new fields.BooleanField({ initial: false }), }) - + schema.modifiers = new fields.SchemaField({ levelSpellModifier: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), saveModifier: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), levelMiracleModifier: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), intSpellModifier: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), - chaMiracleModifier: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), + chaMiracleModifier: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), }) schema.developmentPoints = new fields.SchemaField({ @@ -127,6 +129,14 @@ export default class LethalFantasyCharacter extends foundry.abstract.TypeDataMod total: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), used: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }) }) + schema.aetherPoints = new fields.SchemaField({ + max: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), + value: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }) + }) + schema.divinityPoints = new fields.SchemaField({ + max: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), + value: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }) + }) schema.combat = new fields.SchemaField({ attackModifier: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), defenseModifier: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), @@ -187,7 +197,7 @@ export default class LethalFantasyCharacter extends foundry.abstract.TypeDataMod let conDef = SYSTEM.CHARACTERISTICS_TABLES.con.find(s => s.value === this.characteristics.con.value) this.saves.pain.value = conDef.pain_save + this.modifiers.saveModifier this.saves.toughness.value = conDef.toughness_save + this.modifiers.saveModifier - this.challenges.dying.value = conDef.stabilization_dice + this.challenges.dying.value = conDef.stabilization_dice this.saves.contagion.value = this.characteristics.con.value + this.modifiers.saveModifier this.saves.poison.value = this.characteristics.con.value + this.modifiers.saveModifier @@ -209,7 +219,7 @@ export default class LethalFantasyCharacter extends foundry.abstract.TypeDataMod let chaDef = SYSTEM.CHARACTERISTICS_TABLES[chaKey].find(s => s.value === this.characteristics[chaKey].value) this.combat.damageModifier += chaDef.damage } - + } /** @@ -234,4 +244,46 @@ export default class LethalFantasyCharacter extends foundry.abstract.TypeDataMod await roll.toMessage({}, { rollMode: roll.options.rollMode }) } + + async rollInitiative(combatId = undefined, combatantId = undefined) { + const hasTarget = false + let actorClass = this.biodata.class; + + let wisDef = SYSTEM.CHARACTERISTICS_TABLES.wis.find((c) => c.value === this.characteristics.wis.value) + let maxInit = Number(wisDef.init_cap) || 1000 + console.log("Rolling initiative for", this) + + let roll = await LethalFantasyRoll.promptInitiative({ + actorId: this.parent.id, + actorName: this.parent.name, + actorImage: this.parent.img, + combatId, + combatantId , + actorClass, + maxInit, + }) + if (!roll) return null + + await roll.toMessage({}, { rollMode: roll.options.rollMode }) + } + + async rollProgressionDice(combatId, combatantId, rollProgressionCount) { + + // Get all weapons from the actor + let weapons = this.parent.items.filter(i => i.type === "weapon") + let weaponsChoices = weapons.map(w => { return { id: w.id, name: `${w.name} (${w.system.combatProgressionDice})`, combatProgressionDice: w.system.combatProgressionDice } }) + + let roll = await LethalFantasyRoll.promptProgressionDice({ + actorId: this.parent.id, + actorName: this.parent.name, + actorImage: this.parent.img, + weaponsChoices, + combatId, + combatantId, + rollProgressionCount, + type: "progression", + + }) + } + } diff --git a/module/models/monster.mjs b/module/models/monster.mjs index fd50b24..b5b9bc0 100644 --- a/module/models/monster.mjs +++ b/module/models/monster.mjs @@ -70,6 +70,7 @@ export default class LethalFantasyMonster extends foundry.abstract.TypeDataModel attackModifier: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), defenseModifier: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), damageDice: new fields.StringField({ required: true, nullable: false, initial: "1D6" }), + damageModifier: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), } return new fields.SchemaField(schema, { label }) } @@ -104,7 +105,7 @@ export default class LethalFantasyMonster extends foundry.abstract.TypeDataModel height: new fields.NumberField({ ...requiredInteger, initial: 170, min: 50 }), length: new fields.StringField({ required: true, nullable: false, initial: "" }), weight: new fields.NumberField({ ...requiredInteger, initial: 70, min: 0 }) - }) + }) schema.combat = new fields.SchemaField({ attackModifier: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), defenseModifier: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), @@ -141,4 +142,59 @@ export default class LethalFantasyMonster extends foundry.abstract.TypeDataModel await roll.toMessage({}, { rollMode: roll.options.rollMode }) } + + async rollInitiative(combatId = undefined, combatantId = undefined) { + const hasTarget = false + + let maxInit = 100 + + let roll = await LethalFantasyRoll.promptInitiative({ + actorId: this.parent.id, + actorName: this.parent.name, + actorImage: this.parent.img, + combatId, + combatantId, + maxInit, + }) + if (!roll) return null + + await roll.toMessage({}, { rollMode: roll.options.rollMode }) + } + + async rollProgressionDice(combatId, combatantId, rollProgressionCount) { + + const rollModes = Object.fromEntries(Object.entries(CONFIG.Dice.rollModes).map(([key, value]) => [key, game.i18n.localize(value)])) + const fieldRollMode = new foundry.data.fields.StringField({ + choices: rollModes, + blank: false, + default: "public", + }) + + let roll = new Roll("1D8") + await roll.evaluate() + let max = rollProgressionCount + let msg = await roll.toMessage({ flavor: `Progression Roll for ${this.parent.name}, progression count : ${rollProgressionCount}/${max}` } ) + await game.dice3d.waitFor3DAnimationByMessageID(msg.id) + + let hasAttack = false + for (let key in this.attacks) { + let attack = this.attacks[key] + if (attack.attackScore > 0 && attack.attackScore === roll.total) { + hasAttack = true + let message = game.i18n.format("LETHALFANTASY.Notifications.messageProgressionOK", { name: this.parent.name, weapon: attack.name, roll: roll.total }) + ChatMessage.create({ content: message, speaker: ChatMessage.getSpeaker({ actor: this.parent }) }) + // Update the combatant progression count + let combat = game.combats.get(combatId) + let combatant = combat.combatants.get(combatantId) + combatant.update({ 'system.progressionCount': 0 }) + } + } + if (!hasAttack) { + let message = game.i18n.format("LETHALFANTASY.Notifications.messageProgressionKO", { name: this.parent.name, roll: roll.total }) + ChatMessage.create({ content: message, speaker: ChatMessage.getSpeaker({ actor: this.parent }) }) + } + + } + } + diff --git a/module/socket.mjs b/module/socket.mjs deleted file mode 100644 index 449fdf4..0000000 --- a/module/socket.mjs +++ /dev/null @@ -1,32 +0,0 @@ - -/** - * Handles socket events based on the provided action. - * - * @param {Object} [params={}] The parameters for the socket event. - * @param {string|null} [params.action=null] The action to be performed. - * @param {Object} [params.data={}] The data associated with the action. - * @returns {*} The result of the action handler, if applicable. - */ -export function handleSocketEvent({ action = null, data = {} } = {}) { - console.debug("handleSocketEvent", action, data) - switch (action) { - case "fortune": - return LethalFantasyFortune.handleSocketEvent(data) - case "askRoll": - return _askRoll(data) - } -} - -/** - * Handles the socket event to ask for a roll. - * - * @param {Object} [options={}] The options object. - * @param {string} [options.userId] The ID of the user who initiated the roll. - */ -export function _askRoll({ userId } = {}) { - console.debug(`handleSocketEvent _askRoll from ${userId} !`) - const currentUser = game.user._id - if (userId === currentUser) { - foundry.audio.AudioHelper.play({ src: "/systems/fvtt-lethal-fantasy/sounds/drums.wav", volume: 0.8, autoplay: true, loop: false }, false) - } -} diff --git a/module/utils.mjs b/module/utils.mjs index 704c049..e502544 100644 --- a/module/utils.mjs +++ b/module/utils.mjs @@ -13,6 +13,21 @@ export default class LethalFantasyUtils { return compendiumData.filter(filter) } + static handleSocketEvent(msg = {}) { + console.log(`handleSocketEvent !`, msg) + let actor + switch (msg.type) { + case "rollInitiative": + actor = game.actors.get(msg.actorId) + actor.system.rollInitiative(msg.combatId, msg.combatantId) + break + case "rollProgressionDice": + actor = game.actors.get(msg.actorId) + actor.system.rollProgressionDice(msg.combatId, msg.combatantId, msg.rollProgressionCount) + break + } + } + static registerHandlebarsHelpers() { Handlebars.registerHelper('isNull', function (val) { diff --git a/packs-system/lf-equipment/000056.log b/packs-system/lf-equipment/000076.log similarity index 100% rename from packs-system/lf-equipment/000056.log rename to packs-system/lf-equipment/000076.log diff --git a/packs-system/lf-equipment/CURRENT b/packs-system/lf-equipment/CURRENT index 17608f2..f8d57cc 100644 --- a/packs-system/lf-equipment/CURRENT +++ b/packs-system/lf-equipment/CURRENT @@ -1 +1 @@ -MANIFEST-000054 +MANIFEST-000074 diff --git a/packs-system/lf-equipment/LOG b/packs-system/lf-equipment/LOG index 8417c5f..5ec3c79 100644 --- a/packs-system/lf-equipment/LOG +++ b/packs-system/lf-equipment/LOG @@ -1,8 +1,8 @@ -2025/01/15-17:03:43.719769 7ffb05ffb6c0 Recovering log #52 -2025/01/15-17:03:43.729657 7ffb05ffb6c0 Delete type=3 #50 -2025/01/15-17:03:43.729729 7ffb05ffb6c0 Delete type=0 #52 -2025/01/15-17:13:30.945519 7ff867fff6c0 Level-0 table #57: started -2025/01/15-17:13:30.945543 7ff867fff6c0 Level-0 table #57: 0 bytes OK -2025/01/15-17:13:30.982929 7ff867fff6c0 Delete type=0 #55 -2025/01/15-17:13:31.063470 7ff867fff6c0 Manual compaction at level-0 from '!folders!ATr9wZhg5uTVTksM' @ 72057594037927935 : 1 .. '!items!zFrygJ2TnrxchBai' @ 0 : 0; will stop at (end) -2025/01/15-17:13:31.063497 7ff867fff6c0 Manual compaction at level-1 from '!folders!ATr9wZhg5uTVTksM' @ 72057594037927935 : 1 .. '!items!zFrygJ2TnrxchBai' @ 0 : 0; will stop at (end) +2025/01/17-19:47:11.164832 7f3b911f96c0 Recovering log #72 +2025/01/17-19:47:11.212359 7f3b911f96c0 Delete type=3 #70 +2025/01/17-19:47:11.212431 7f3b911f96c0 Delete type=0 #72 +2025/01/17-23:59:30.263234 7f3b8b3ff6c0 Level-0 table #77: started +2025/01/17-23:59:30.263263 7f3b8b3ff6c0 Level-0 table #77: 0 bytes OK +2025/01/17-23:59:30.269621 7f3b8b3ff6c0 Delete type=0 #75 +2025/01/17-23:59:30.282079 7f3b8b3ff6c0 Manual compaction at level-0 from '!folders!ATr9wZhg5uTVTksM' @ 72057594037927935 : 1 .. '!items!zFrygJ2TnrxchBai' @ 0 : 0; will stop at (end) +2025/01/17-23:59:30.282123 7f3b8b3ff6c0 Manual compaction at level-1 from '!folders!ATr9wZhg5uTVTksM' @ 72057594037927935 : 1 .. '!items!zFrygJ2TnrxchBai' @ 0 : 0; will stop at (end) diff --git a/packs-system/lf-equipment/LOG.old b/packs-system/lf-equipment/LOG.old index 12da452..6ee7e63 100644 --- a/packs-system/lf-equipment/LOG.old +++ b/packs-system/lf-equipment/LOG.old @@ -1,7 +1,8 @@ -2025/01/15-16:54:53.448674 7ffb057fa6c0 Recovering log #48 -2025/01/15-16:54:53.459274 7ffb057fa6c0 Delete type=3 #46 -2025/01/15-16:54:53.459345 7ffb057fa6c0 Delete type=0 #48 -2025/01/15-16:55:56.518322 7ff867fff6c0 Level-0 table #53: started -2025/01/15-16:55:56.537208 7ff867fff6c0 Level-0 table #53: 28711 bytes OK -2025/01/15-16:55:56.571804 7ff867fff6c0 Delete type=0 #51 -2025/01/15-16:55:56.731643 7ff867fff6c0 Manual compaction at level-0 from '!folders!ATr9wZhg5uTVTksM' @ 72057594037927935 : 1 .. '!items!zFrygJ2TnrxchBai' @ 0 : 0; will stop at (end) +2025/01/16-23:12:53.401299 7ffb067fc6c0 Recovering log #68 +2025/01/16-23:12:53.411672 7ffb067fc6c0 Delete type=3 #66 +2025/01/16-23:12:53.411749 7ffb067fc6c0 Delete type=0 #68 +2025/01/17-07:54:26.962616 7ff867fff6c0 Level-0 table #73: started +2025/01/17-07:54:26.962692 7ff867fff6c0 Level-0 table #73: 0 bytes OK +2025/01/17-07:54:26.994859 7ff867fff6c0 Delete type=0 #71 +2025/01/17-07:54:27.074108 7ff867fff6c0 Manual compaction at level-0 from '!folders!ATr9wZhg5uTVTksM' @ 72057594037927935 : 1 .. '!items!zFrygJ2TnrxchBai' @ 0 : 0; will stop at (end) +2025/01/17-07:54:27.074173 7ff867fff6c0 Manual compaction at level-1 from '!folders!ATr9wZhg5uTVTksM' @ 72057594037927935 : 1 .. '!items!zFrygJ2TnrxchBai' @ 0 : 0; will stop at (end) diff --git a/packs-system/lf-equipment/MANIFEST-000054 b/packs-system/lf-equipment/MANIFEST-000054 deleted file mode 100644 index d19e986..0000000 Binary files a/packs-system/lf-equipment/MANIFEST-000054 and /dev/null differ diff --git a/packs-system/lf-equipment/MANIFEST-000074 b/packs-system/lf-equipment/MANIFEST-000074 new file mode 100644 index 0000000..e9a46fe Binary files /dev/null and b/packs-system/lf-equipment/MANIFEST-000074 differ diff --git a/packs-system/lf-gifts/000056.log b/packs-system/lf-gifts/000076.log similarity index 100% rename from packs-system/lf-gifts/000056.log rename to packs-system/lf-gifts/000076.log diff --git a/packs-system/lf-gifts/CURRENT b/packs-system/lf-gifts/CURRENT index 17608f2..f8d57cc 100644 --- a/packs-system/lf-gifts/CURRENT +++ b/packs-system/lf-gifts/CURRENT @@ -1 +1 @@ -MANIFEST-000054 +MANIFEST-000074 diff --git a/packs-system/lf-gifts/LOG b/packs-system/lf-gifts/LOG index 230480a..59f77fb 100644 --- a/packs-system/lf-gifts/LOG +++ b/packs-system/lf-gifts/LOG @@ -1,8 +1,8 @@ -2025/01/15-17:03:43.732673 7ffb057fa6c0 Recovering log #52 -2025/01/15-17:03:43.743050 7ffb057fa6c0 Delete type=3 #50 -2025/01/15-17:03:43.743102 7ffb057fa6c0 Delete type=0 #52 -2025/01/15-17:13:30.983070 7ff867fff6c0 Level-0 table #57: started -2025/01/15-17:13:30.983104 7ff867fff6c0 Level-0 table #57: 0 bytes OK -2025/01/15-17:13:31.026101 7ff867fff6c0 Delete type=0 #55 -2025/01/15-17:13:31.063480 7ff867fff6c0 Manual compaction at level-0 from '!folders!yPWGvxHJbDNHVSnY' @ 72057594037927935 : 1 .. '!items!zjvGljrLk5SshC9D' @ 0 : 0; will stop at (end) -2025/01/15-17:13:31.063519 7ff867fff6c0 Manual compaction at level-1 from '!folders!yPWGvxHJbDNHVSnY' @ 72057594037927935 : 1 .. '!items!zjvGljrLk5SshC9D' @ 0 : 0; will stop at (end) +2025/01/17-19:47:11.219943 7f3b919fa6c0 Recovering log #72 +2025/01/17-19:47:11.271701 7f3b919fa6c0 Delete type=3 #70 +2025/01/17-19:47:11.271773 7f3b919fa6c0 Delete type=0 #72 +2025/01/17-23:59:30.276140 7f3b8b3ff6c0 Level-0 table #77: started +2025/01/17-23:59:30.276162 7f3b8b3ff6c0 Level-0 table #77: 0 bytes OK +2025/01/17-23:59:30.281988 7f3b8b3ff6c0 Delete type=0 #75 +2025/01/17-23:59:30.282094 7f3b8b3ff6c0 Manual compaction at level-0 from '!folders!yPWGvxHJbDNHVSnY' @ 72057594037927935 : 1 .. '!items!zjvGljrLk5SshC9D' @ 0 : 0; will stop at (end) +2025/01/17-23:59:30.282117 7f3b8b3ff6c0 Manual compaction at level-1 from '!folders!yPWGvxHJbDNHVSnY' @ 72057594037927935 : 1 .. '!items!zjvGljrLk5SshC9D' @ 0 : 0; will stop at (end) diff --git a/packs-system/lf-gifts/LOG.old b/packs-system/lf-gifts/LOG.old index 8147195..ad98557 100644 --- a/packs-system/lf-gifts/LOG.old +++ b/packs-system/lf-gifts/LOG.old @@ -1,7 +1,8 @@ -2025/01/15-16:54:53.461720 7ffb067fc6c0 Recovering log #48 -2025/01/15-16:54:53.471141 7ffb067fc6c0 Delete type=3 #46 -2025/01/15-16:54:53.471198 7ffb067fc6c0 Delete type=0 #48 -2025/01/15-16:55:56.616536 7ff867fff6c0 Level-0 table #53: started -2025/01/15-16:55:56.634525 7ff867fff6c0 Level-0 table #53: 15152 bytes OK -2025/01/15-16:55:56.671555 7ff867fff6c0 Delete type=0 #51 -2025/01/15-16:55:56.731669 7ff867fff6c0 Manual compaction at level-0 from '!folders!yPWGvxHJbDNHVSnY' @ 72057594037927935 : 1 .. '!items!zjvGljrLk5SshC9D' @ 0 : 0; will stop at (end) +2025/01/16-23:12:53.414138 7ffb04ff96c0 Recovering log #68 +2025/01/16-23:12:53.424560 7ffb04ff96c0 Delete type=3 #66 +2025/01/16-23:12:53.424630 7ffb04ff96c0 Delete type=0 #68 +2025/01/17-07:54:27.053199 7ff867fff6c0 Level-0 table #73: started +2025/01/17-07:54:27.053227 7ff867fff6c0 Level-0 table #73: 0 bytes OK +2025/01/17-07:54:27.073980 7ff867fff6c0 Delete type=0 #71 +2025/01/17-07:54:27.074166 7ff867fff6c0 Manual compaction at level-0 from '!folders!yPWGvxHJbDNHVSnY' @ 72057594037927935 : 1 .. '!items!zjvGljrLk5SshC9D' @ 0 : 0; will stop at (end) +2025/01/17-07:54:27.074188 7ff867fff6c0 Manual compaction at level-1 from '!folders!yPWGvxHJbDNHVSnY' @ 72057594037927935 : 1 .. '!items!zjvGljrLk5SshC9D' @ 0 : 0; will stop at (end) diff --git a/packs-system/lf-gifts/MANIFEST-000054 b/packs-system/lf-gifts/MANIFEST-000054 deleted file mode 100644 index 913a6ff..0000000 Binary files a/packs-system/lf-gifts/MANIFEST-000054 and /dev/null differ diff --git a/packs-system/lf-gifts/MANIFEST-000074 b/packs-system/lf-gifts/MANIFEST-000074 new file mode 100644 index 0000000..8526744 Binary files /dev/null and b/packs-system/lf-gifts/MANIFEST-000074 differ diff --git a/packs-system/lf-skills/000056.log b/packs-system/lf-skills/000076.log similarity index 100% rename from packs-system/lf-skills/000056.log rename to packs-system/lf-skills/000076.log diff --git a/packs-system/lf-skills/CURRENT b/packs-system/lf-skills/CURRENT index 17608f2..f8d57cc 100644 --- a/packs-system/lf-skills/CURRENT +++ b/packs-system/lf-skills/CURRENT @@ -1 +1 @@ -MANIFEST-000054 +MANIFEST-000074 diff --git a/packs-system/lf-skills/LOG b/packs-system/lf-skills/LOG index d5d0dc5..e3cb58a 100644 --- a/packs-system/lf-skills/LOG +++ b/packs-system/lf-skills/LOG @@ -1,8 +1,8 @@ -2025/01/15-17:03:43.706874 7ffb04ff96c0 Recovering log #52 -2025/01/15-17:03:43.716786 7ffb04ff96c0 Delete type=3 #50 -2025/01/15-17:03:43.716860 7ffb04ff96c0 Delete type=0 #52 -2025/01/15-17:13:30.905655 7ff867fff6c0 Level-0 table #57: started -2025/01/15-17:13:30.905694 7ff867fff6c0 Level-0 table #57: 0 bytes OK -2025/01/15-17:13:30.945404 7ff867fff6c0 Delete type=0 #55 -2025/01/15-17:13:31.063454 7ff867fff6c0 Manual compaction at level-0 from '!folders!7j8H7DbmBb9Uza2X' @ 72057594037927935 : 1 .. '!items!zt8s7564ep1La4XQ' @ 0 : 0; will stop at (end) -2025/01/15-17:13:31.063503 7ff867fff6c0 Manual compaction at level-1 from '!folders!7j8H7DbmBb9Uza2X' @ 72057594037927935 : 1 .. '!items!zt8s7564ep1La4XQ' @ 0 : 0; will stop at (end) +2025/01/17-19:47:11.076852 7f3b909f86c0 Recovering log #72 +2025/01/17-19:47:11.156242 7f3b909f86c0 Delete type=3 #70 +2025/01/17-19:47:11.156312 7f3b909f86c0 Delete type=0 #72 +2025/01/17-23:59:30.269721 7f3b8b3ff6c0 Level-0 table #77: started +2025/01/17-23:59:30.269744 7f3b8b3ff6c0 Level-0 table #77: 0 bytes OK +2025/01/17-23:59:30.276051 7f3b8b3ff6c0 Delete type=0 #75 +2025/01/17-23:59:30.282087 7f3b8b3ff6c0 Manual compaction at level-0 from '!folders!7j8H7DbmBb9Uza2X' @ 72057594037927935 : 1 .. '!items!zt8s7564ep1La4XQ' @ 0 : 0; will stop at (end) +2025/01/17-23:59:30.282129 7f3b8b3ff6c0 Manual compaction at level-1 from '!folders!7j8H7DbmBb9Uza2X' @ 72057594037927935 : 1 .. '!items!zt8s7564ep1La4XQ' @ 0 : 0; will stop at (end) diff --git a/packs-system/lf-skills/LOG.old b/packs-system/lf-skills/LOG.old index d53177e..6359405 100644 --- a/packs-system/lf-skills/LOG.old +++ b/packs-system/lf-skills/LOG.old @@ -1,8 +1,8 @@ -2025/01/15-16:54:53.435891 7ffb05ffb6c0 Recovering log #48 -2025/01/15-16:54:53.445636 7ffb05ffb6c0 Delete type=3 #46 -2025/01/15-16:54:53.445687 7ffb05ffb6c0 Delete type=0 #48 -2025/01/15-16:55:56.571979 7ff867fff6c0 Level-0 table #53: started -2025/01/15-16:55:56.572010 7ff867fff6c0 Level-0 table #53: 0 bytes OK -2025/01/15-16:55:56.616420 7ff867fff6c0 Delete type=0 #51 -2025/01/15-16:55:56.731658 7ff867fff6c0 Manual compaction at level-0 from '!folders!7j8H7DbmBb9Uza2X' @ 72057594037927935 : 1 .. '!items!zt8s7564ep1La4XQ' @ 0 : 0; will stop at (end) -2025/01/15-16:55:56.731692 7ff867fff6c0 Manual compaction at level-1 from '!folders!7j8H7DbmBb9Uza2X' @ 72057594037927935 : 1 .. '!items!zt8s7564ep1La4XQ' @ 0 : 0; will stop at (end) +2025/01/16-23:12:53.388461 7ffb05ffb6c0 Recovering log #68 +2025/01/16-23:12:53.398277 7ffb05ffb6c0 Delete type=3 #66 +2025/01/16-23:12:53.398338 7ffb05ffb6c0 Delete type=0 #68 +2025/01/17-07:54:27.022206 7ff867fff6c0 Level-0 table #73: started +2025/01/17-07:54:27.022245 7ff867fff6c0 Level-0 table #73: 0 bytes OK +2025/01/17-07:54:27.053062 7ff867fff6c0 Delete type=0 #71 +2025/01/17-07:54:27.074144 7ff867fff6c0 Manual compaction at level-0 from '!folders!7j8H7DbmBb9Uza2X' @ 72057594037927935 : 1 .. '!items!zt8s7564ep1La4XQ' @ 0 : 0; will stop at (end) +2025/01/17-07:54:27.074195 7ff867fff6c0 Manual compaction at level-1 from '!folders!7j8H7DbmBb9Uza2X' @ 72057594037927935 : 1 .. '!items!zt8s7564ep1La4XQ' @ 0 : 0; will stop at (end) diff --git a/packs-system/lf-skills/MANIFEST-000054 b/packs-system/lf-skills/MANIFEST-000054 deleted file mode 100644 index e2fde64..0000000 Binary files a/packs-system/lf-skills/MANIFEST-000054 and /dev/null differ diff --git a/packs-system/lf-skills/MANIFEST-000074 b/packs-system/lf-skills/MANIFEST-000074 new file mode 100644 index 0000000..12bd268 Binary files /dev/null and b/packs-system/lf-skills/MANIFEST-000074 differ diff --git a/packs-system/lf-vulnerabilities/000056.log b/packs-system/lf-vulnerabilities/000076.log similarity index 100% rename from packs-system/lf-vulnerabilities/000056.log rename to packs-system/lf-vulnerabilities/000076.log diff --git a/packs-system/lf-vulnerabilities/CURRENT b/packs-system/lf-vulnerabilities/CURRENT index 17608f2..f8d57cc 100644 --- a/packs-system/lf-vulnerabilities/CURRENT +++ b/packs-system/lf-vulnerabilities/CURRENT @@ -1 +1 @@ -MANIFEST-000054 +MANIFEST-000074 diff --git a/packs-system/lf-vulnerabilities/LOG b/packs-system/lf-vulnerabilities/LOG index 8296ad8..f9e22ee 100644 --- a/packs-system/lf-vulnerabilities/LOG +++ b/packs-system/lf-vulnerabilities/LOG @@ -1,8 +1,8 @@ -2025/01/15-17:03:43.745320 7ffb067fc6c0 Recovering log #52 -2025/01/15-17:03:43.754748 7ffb067fc6c0 Delete type=3 #50 -2025/01/15-17:03:43.754838 7ffb067fc6c0 Delete type=0 #52 -2025/01/15-17:13:31.026257 7ff867fff6c0 Level-0 table #57: started -2025/01/15-17:13:31.026286 7ff867fff6c0 Level-0 table #57: 0 bytes OK -2025/01/15-17:13:31.063313 7ff867fff6c0 Delete type=0 #55 -2025/01/15-17:13:31.063490 7ff867fff6c0 Manual compaction at level-0 from '!folders!mnO9OzE7BEE2KDfh' @ 72057594037927935 : 1 .. '!items!zkK6ixtCsCw3RH9X' @ 0 : 0; will stop at (end) -2025/01/15-17:13:31.063511 7ff867fff6c0 Manual compaction at level-1 from '!folders!mnO9OzE7BEE2KDfh' @ 72057594037927935 : 1 .. '!items!zkK6ixtCsCw3RH9X' @ 0 : 0; will stop at (end) +2025/01/17-19:47:11.275966 7f3b8bfff6c0 Recovering log #72 +2025/01/17-19:47:11.332695 7f3b8bfff6c0 Delete type=3 #70 +2025/01/17-19:47:11.332765 7f3b8bfff6c0 Delete type=0 #72 +2025/01/17-23:59:30.257100 7f3b8b3ff6c0 Level-0 table #77: started +2025/01/17-23:59:30.257148 7f3b8b3ff6c0 Level-0 table #77: 0 bytes OK +2025/01/17-23:59:30.263106 7f3b8b3ff6c0 Delete type=0 #75 +2025/01/17-23:59:30.282069 7f3b8b3ff6c0 Manual compaction at level-0 from '!folders!mnO9OzE7BEE2KDfh' @ 72057594037927935 : 1 .. '!items!zkK6ixtCsCw3RH9X' @ 0 : 0; will stop at (end) +2025/01/17-23:59:30.282110 7f3b8b3ff6c0 Manual compaction at level-1 from '!folders!mnO9OzE7BEE2KDfh' @ 72057594037927935 : 1 .. '!items!zkK6ixtCsCw3RH9X' @ 0 : 0; will stop at (end) diff --git a/packs-system/lf-vulnerabilities/LOG.old b/packs-system/lf-vulnerabilities/LOG.old index 3b1b9f7..1ad4b1d 100644 --- a/packs-system/lf-vulnerabilities/LOG.old +++ b/packs-system/lf-vulnerabilities/LOG.old @@ -1,7 +1,8 @@ -2025/01/15-16:54:53.473037 7ffb04ff96c0 Recovering log #48 -2025/01/15-16:54:53.482869 7ffb04ff96c0 Delete type=3 #46 -2025/01/15-16:54:53.482939 7ffb04ff96c0 Delete type=0 #48 -2025/01/15-16:55:56.671688 7ff867fff6c0 Level-0 table #53: started -2025/01/15-16:55:56.695395 7ff867fff6c0 Level-0 table #53: 20606 bytes OK -2025/01/15-16:55:56.731487 7ff867fff6c0 Delete type=0 #51 -2025/01/15-16:55:56.731680 7ff867fff6c0 Manual compaction at level-0 from '!folders!mnO9OzE7BEE2KDfh' @ 72057594037927935 : 1 .. '!items!zkK6ixtCsCw3RH9X' @ 0 : 0; will stop at (end) +2025/01/16-23:12:53.426846 7ffb057fa6c0 Recovering log #68 +2025/01/16-23:12:53.436800 7ffb057fa6c0 Delete type=3 #66 +2025/01/16-23:12:53.436869 7ffb057fa6c0 Delete type=0 #68 +2025/01/17-07:54:26.995011 7ff867fff6c0 Level-0 table #73: started +2025/01/17-07:54:26.995042 7ff867fff6c0 Level-0 table #73: 0 bytes OK +2025/01/17-07:54:27.021986 7ff867fff6c0 Delete type=0 #71 +2025/01/17-07:54:27.074123 7ff867fff6c0 Manual compaction at level-0 from '!folders!mnO9OzE7BEE2KDfh' @ 72057594037927935 : 1 .. '!items!zkK6ixtCsCw3RH9X' @ 0 : 0; will stop at (end) +2025/01/17-07:54:27.074180 7ff867fff6c0 Manual compaction at level-1 from '!folders!mnO9OzE7BEE2KDfh' @ 72057594037927935 : 1 .. '!items!zkK6ixtCsCw3RH9X' @ 0 : 0; will stop at (end) diff --git a/packs-system/lf-vulnerabilities/MANIFEST-000054 b/packs-system/lf-vulnerabilities/MANIFEST-000074 similarity index 73% rename from packs-system/lf-vulnerabilities/MANIFEST-000054 rename to packs-system/lf-vulnerabilities/MANIFEST-000074 index d15f895..7cb2880 100644 Binary files a/packs-system/lf-vulnerabilities/MANIFEST-000054 and b/packs-system/lf-vulnerabilities/MANIFEST-000074 differ diff --git a/styles/character.less b/styles/character.less index 2923d87..540f67c 100644 --- a/styles/character.less +++ b/styles/character.less @@ -13,8 +13,8 @@ flex: 1; .character-left { - min-width: 220px; - max-width: 220px; + min-width: 200px; + max-width: 200px; display: flex; flex-direction: column; @@ -32,28 +32,32 @@ } .character-hp { display: flex; - gap: 2px; + gap: 4px; align-items: center; - .character-hp-value { - .form-fields input { - flex: none; - min-width: 3rem; - max-width: 3rem; - margin-left: 10px; - font-size: calc(var(--font-size-standard) * 1.4); - } + margin-bottom: 4px; + .name { + flex: none; + min-width: 2.5rem; + max-width: 2.5rem; + } + input { + flex: none; + min-width: 2.2rem; + max-width: 2.2rem; + margin-left: 4px; + font-size: calc(var(--font-size-standard) * 1.0); } .character-hp-max { clear: both; display: flex; flex-direction: row; flex-wrap: wrap; - margin: 3px 0; + margin: 4px 0; align-items: center; input { - width: 50px; + width: 3.2rem; text-align: center; - font-size: calc(var(--font-size-standard) * 1.4); + font-size: calc(var(--font-size-standard) * 1.0); } } } @@ -74,18 +78,17 @@ } .character-pc-play { - min-width: 400px; + min-width: 320px; } .character-pc-edit { - min-width: 400px; + min-width: 320px; } .character-characteristics { display: flex; flex-direction: column; gap: 4px; - flex: 1; .character-characteristic { display: flex; @@ -105,6 +108,7 @@ } } } + .character-challenges { display: flex; flex-direction: column; @@ -206,11 +210,11 @@ } .character-characteristics-play { - min-width: 225px; + min-width: 160px; } .character-characteristic-edit { - min-width: 400px; + min-width: 160px; } } @@ -386,8 +390,8 @@ align-items: center; gap: 4px; .wound-description { - min-width: 16rem; - max-width: 16rem; + min-width: 14rem; + max-width: 14rem; } .wound-duration { min-width: 3rem; @@ -460,6 +464,29 @@ } } + .spell-details { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 4px; + .spell-detail { + display: flex; + align-items: center; + gap: 4px; + button { + min-width: 10rem; + } + .armor-hp { + min-width: 20rem; + max-width: 20rem; + .input { + min-width: 3rem; + max-width: 3rem; + } + } + } + } + + .spells { display: grid; grid-template-columns: repeat(3, 1fr); @@ -496,6 +523,28 @@ } } + .miracle-details { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 4px; + .miracle-detail { + display: flex; + align-items: center; + gap: 4px; + button { + min-width: 10rem; + } + .armor-hp { + min-width: 20rem; + max-width: 20rem; + .input { + min-width: 3rem; + max-width: 3rem; + } + } + } + } + .miracles { display: grid; grid-template-columns: repeat(3, 1fr); diff --git a/styles/global.less b/styles/global.less index 9eece97..97b8c2f 100644 --- a/styles/global.less +++ b/styles/global.less @@ -58,3 +58,11 @@ i.lethalfantasy { background-repeat: no-repeat; background-size: 100% 100%; } + +.combat-sidebar li.combatant .token-initiative .initiative{ + margin-right: 16px; +} + +.combat-sidebar li.combatant .token-initiative { + flex:none; +} diff --git a/styles/monster.less b/styles/monster.less index dcae669..75be617 100644 --- a/styles/monster.less +++ b/styles/monster.less @@ -7,54 +7,53 @@ .monster-main { display: flex; + .monster-left-image { + display: flex; + justify-content: center; + align-items: center; + padding-bottom: 4px; + .monster-img { + height: 140px; + width: 140px; + width: auto; + border: none; + } + } + .monster-pc { display: flex; gap: 10px; flex: 1; + - .monster-left { - min-width: 220px; - max-width: 220px; + .monster-hp { display: flex; - flex-direction: column; - - .monster-left-image { - display: flex; - justify-content: center; - align-items: center; - padding-bottom: 8px; - .monster-img { - height: 140px; - width: 140px; - width: auto; - border: none; - } + gap: 4px; + align-items: center; + margin-bottom: 4px; + .name { + flex: none; + min-width: 2.5rem; + max-width: 2.5rem; } - .monster-hp { + input { + flex: none; + min-width: 2.2rem; + max-width: 2.2rem; + margin-left: 4px; + font-size: calc(var(--font-size-standard) * 1.0); + } + .character-hp-max { + clear: both; display: flex; - gap: 2px; + flex-direction: row; + flex-wrap: wrap; + margin: 4px 0; align-items: center; - .monster-hp-value { - .form-fields input { - flex: none; - min-width: 3rem; - max-width: 3rem; - margin-left: 10px; - font-size: calc(var(--font-size-standard) * 1.4); - } - } - .monster-hp-max { - clear: both; - display: flex; - flex-direction: row; - flex-wrap: wrap; - margin: 3px 0; - align-items: center; - input { - width: 50px; - text-align: center; - font-size: calc(var(--font-size-standard) * 1.4); - } + input { + width: 3.2rem; + text-align: center; + font-size: calc(var(--font-size-standard) * 1.0); } } } @@ -105,6 +104,7 @@ } } } + .monster-resists { display: flex; flex-direction: column; @@ -134,7 +134,7 @@ padding-left: 4px; .form-fields { flex: none; - width: 50px; + width: 2.5rem; } } } @@ -210,11 +210,11 @@ } .monster-characteristics-play { - min-width: 225px; + min-width: 200px; } .monster-characteristic-edit { - min-width: 400px; + min-width: 200px; } } @@ -384,12 +384,16 @@ display: flex; align-items: center; gap: 4px; + .name { + min-width: 8rem; + max-width: 8rem; + } .damage-dice { width: 4rem; max-width: 3.5rem; } .numeric { - width: 2.5rem; + width: 2.2rem; } .attack-icons a { margin-left: 4px; @@ -454,38 +458,3 @@ } } -.tab.monster-miracles { - display: grid; - grid-template-columns: 1fr; - legend { - a { - font-size: calc(var(--font-size-standard) * 1.4); - padding-left: 4px; - } - } - - .miracles { - display: grid; - grid-template-columns: repeat(3, 1fr); - gap: 4px; - .miracle { - display: flex; - align-items: center; - gap: 4px; - .item-img { - width: 24px; - height: 24px; - } - .name { - min-width: 12rem; - } - } - } - - prose-mirror.inactive { - min-height: 40px; - } - prose-mirror.active { - min-height: 150px; - } -} diff --git a/system.json b/system.json index caf8e1e..4545120 100644 --- a/system.json +++ b/system.json @@ -6,7 +6,7 @@ "download": "#{DOWNLOAD}#", "url": "#{URL}#", "license": "LICENSE", - "version": "12.0.18", + "version": "12.0.19", "authors": [ { "name": "Uberwald", diff --git a/templates/character-main.hbs b/templates/character-main.hbs index a258a1f..ccb2e68 100644 --- a/templates/character-main.hbs +++ b/templates/character-main.hbs @@ -10,7 +10,7 @@ data-tooltip="{{actor.name}}" /> -
+
{{localize "LETHALFANTASY.Label.HP"}} {{formInput systemFields.hp.fields.value value=system.hp.value disabled=isPlayMode classes="character-hp-value"}} @@ -21,7 +21,7 @@ {{localize "LETHALFANTASY.Label.grit"}} {{formInput systemFields.grit.fields.current value=system.grit.current disabled=isPlayMode classes="character-hp"}} - {{localize "LETHALFANTASY.Label.gritEarned"}} + {{localize "LETHALFANTASY.Label.earned"}} {{formInput systemFields.grit.fields.earned value=system.grit.earned disabled=isPlayMode classes="character-hp"}}
@@ -29,7 +29,7 @@ {{localize "LETHALFANTASY.Label.luck"}} {{formInput systemFields.luck.fields.current value=system.luck.current disabled=isPlayMode classes="character-hp"}} - {{localize "LETHALFANTASY.Label.luckEarned"}} + {{localize "LETHALFANTASY.Label.earned"}} {{formInput systemFields.luck.fields.earned value=system.luck.earned disabled=isPlayMode classes="character-hp"}} diff --git a/templates/character-miracles.hbs b/templates/character-miracles.hbs index 43556e9..75ebc54 100644 --- a/templates/character-miracles.hbs +++ b/templates/character-miracles.hbs @@ -1,5 +1,21 @@
+
+ {{localize "LETHALFANTASY.Label.divinityPoints"}} +
+
+ Current + {{formField systemFields.divinityPoints.fields.value value=system.divinityPoints.value localize=true}} + + + + Max + {{formField systemFields.divinityPoints.fields.max value=system.divinityPoints.max localize=true disabled=isPlayMode}} +
+
+ +
+
{{localize "LETHALFANTASY.Label.miracles"}}{{#if isEditMode}} +
+ {{localize "LETHALFANTASY.Label.aetherPoints"}} +
+
+ Current + {{formField systemFields.aetherPoints.fields.value value=system.aetherPoints.value localize=true}} + + + + Max + {{formField systemFields.aetherPoints.fields.max value=system.aetherPoints.max localize=true disabled=isPlayMode}} +
+
+ +
+
{{localize "LETHALFANTASY.Label.spells"}}{{#if isEditMode}} {{/if}} -
+ + {{/each}} diff --git a/templates/monster-combat.hbs b/templates/monster-combat.hbs index 1f49a12..8efc4e9 100644 --- a/templates/monster-combat.hbs +++ b/templates/monster-combat.hbs @@ -34,7 +34,10 @@
- + +
+
+
diff --git a/templates/roll-progression-dice-dialog.hbs b/templates/roll-progression-dice-dialog.hbs new file mode 100644 index 0000000..2dae45f --- /dev/null +++ b/templates/roll-progression-dice-dialog.hbs @@ -0,0 +1,20 @@ +
+ +
+ {{localize "LETHALFANTASY.Label.progressionDice"}} + + + + +
+ +
+ {{localize "LETHALFANTASY.Roll.visibility"}} + +
+ +
\ No newline at end of file