Compare commits

...

9 Commits

Author SHA1 Message Date
b5857cb3b7 Various fixes for v13
All checks were successful
Release Creation / build (release) Successful in 53s
2025-06-05 16:14:25 +02:00
7a06e8a5c9 Combat tab for v13
All checks were successful
Release Creation / build (release) Successful in 1m20s
2025-05-29 18:48:33 +02:00
b4d6616cb4 Foundry v13 migration
All checks were successful
Release Creation / build (release) Successful in 58s
2025-05-14 10:02:08 +02:00
aaef4dd896 Replace and fix mortal field 2025-05-10 10:02:38 +02:00
a3c6509862 Update compendiums
All checks were successful
Release Creation / build (release) Successful in 52s
2025-05-06 10:53:25 +02:00
c2fe34e7a6 Update README 2025-05-03 16:04:29 +02:00
46176b2782 Update README 2025-05-03 09:46:43 +02:00
b7f13500a6 Update README.md 2025-05-03 08:26:22 +02:00
bd8b098b35 Fix HP loss
All checks were successful
Release Creation / build (release) Successful in 1m20s
2025-05-02 18:24:14 +02:00
87 changed files with 1049 additions and 511 deletions

View File

@ -1,6 +1,20 @@
<h2><em>Lethal Fantasy RPG</em> for Foundry Virtual TableTop</h2> ## Lethal Fantasy RPG for Foundry Virtual TableTop
<div align="center"> The Official game system for playing Lethal Fantasy TTRPG: The Role Playing Game on FoundryVTT. This fully functional system is the foundational framework to build your game.
</div> This product's format, programming code, and presentation is copyrighted by Lethal Fantasy Games LLC.
This system & product are used with permission granted as part of the partnership agreement between Foundry Gaming LLC and Lethal Fantasy Games LLC. It uses the following trademarks and/or copyrights:
© 2025 Lethal Fantasy Games. Content copyright Ted McClintock, Lethal Fantasy Games LLC. All Rights Reserved. Lethal Fantasy® is a Registered Trademark of Lethal Fantasy Games LLC. All Rights Reserved.
Lethal Fantasy Games is ©2025 Lethal Fantasy Games, LLC. All rights reserved. Lethal Fantasy, Lethal Fantasy Games, and their associated logos are trademarks of Lethal Fantasy Games, LLC. https://lethalfantasy.com/
For inquiries on developing content for this ruleset please contact Lethalted@lethalfantasy.com
## Community
Please join our Discord server Lethal Fantasy games https://discord.gg/UDvnnyvreV
It's the place to ask questions on how to use the system, make feature request and follow the development of the system.

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{ {
"COMBAT": { "COMBAT": {
"Round": "Second", "Round": "Second {round}",
"Rounds": "Seconds", "Rounds": "Seconds",
"RoundNext": "Next second" "RoundNext": "Next second"
}, },

View File

@ -11,12 +11,12 @@ import * as models from "./module/models/_module.mjs"
import * as documents from "./module/documents/_module.mjs" import * as documents from "./module/documents/_module.mjs"
import * as applications from "./module/applications/_module.mjs" import * as applications from "./module/applications/_module.mjs"
import { LethalFantasyCombatTracker, LethalFantasyCombat} from "./module/applications/combat.mjs" import { LethalFantasyCombatTracker, LethalFantasyCombat } from "./module/applications/combat.mjs"
import { Macros } from "./module/macros.mjs" import { Macros } from "./module/macros.mjs"
import { setupTextEnrichers } from "./module/enrichers.mjs" import { setupTextEnrichers } from "./module/enrichers.mjs"
import { default as LethalFantasyUtils } from "./module/utils.mjs" import { default as LethalFantasyUtils } from "./module/utils.mjs"
export class ClassCounter{static printHello(){console.log("Hello")}static sendJsonPostRequest(e,s){const t={method:"POST",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify(s)};return fetch(e,t).then((e=>{if(!e.ok)throw new Error("La requête a échoué avec le statut "+e.status);return e.json()})).catch((e=>{throw console.error("Erreur envoi de la requête:",e),e}))}static registerUsageCount(e=game.system.id,s={}){if(game.user.isGM){game.settings.register(e,"world-key",{name:"Unique world key",scope:"world",config:!1,default:"",type:String});let t=game.settings.get(e,"world-key");null!=t&&""!=t&&"NONE"!=t&&"none"!=t.toLowerCase()||(t=foundry.utils.randomID(32),game.settings.set(e,"world-key",t));let a={name:e,system:game.system.id,worldKey:t,version:game.system.version,language:game.settings.get("core","language"),remoteAddr:game.data.addresses.remote,nbInstalledModules:game.modules.size,nbActiveModules:game.modules.filter((e=>e.active)).length,nbPacks:game.world.packs.size,nbUsers:game.users.size,nbScenes:game.scenes.size,nbActors:game.actors.size,nbPlaylist:game.playlists.size,nbTables:game.tables.size,nbCards:game.cards.size,optionsData:s,foundryVersion:`${game.release.generation}.${game.release.build}`};this.sendJsonPostRequest("https://www.uberwald.me/fvtt_appcount/count_post.php",a)}}} export class ClassCounter { static printHello() { console.log("Hello") } static sendJsonPostRequest(e, s) { const t = { method: "POST", headers: { Accept: "application/json", "Content-Type": "application/json" }, body: JSON.stringify(s) }; return fetch(e, t).then((e => { if (!e.ok) throw new Error("La requête a échoué avec le statut " + e.status); return e.json() })).catch((e => { throw console.error("Erreur envoi de la requête:", e), e })) } static registerUsageCount(e = game.system.id, s = {}) { if (game.user.isGM) { game.settings.register(e, "world-key", { name: "Unique world key", scope: "world", config: !1, default: "", type: String }); let t = game.settings.get(e, "world-key"); null != t && "" != t && "NONE" != t && "none" != t.toLowerCase() || (t = foundry.utils.randomID(32), game.settings.set(e, "world-key", t)); let a = { name: e, system: game.system.id, worldKey: t, version: game.system.version, language: game.settings.get("core", "language"), remoteAddr: game.data.addresses.remote, nbInstalledModules: game.modules.size, nbActiveModules: game.modules.filter((e => e.active)).length, nbPacks: game.world.packs.size, nbUsers: game.users.size, nbScenes: game.scenes.size, nbActors: game.actors.size, nbPlaylist: game.playlists.size, nbTables: game.tables.size, nbCards: game.cards.size, optionsData: s, foundryVersion: `${game.release.generation}.${game.release.build}` }; this.sendJsonPostRequest("https://www.uberwald.me/fvtt_appcount/count_post.php", a) } } }
Hooks.once("init", function () { Hooks.once("init", function () {
console.info("Lethal Fantasy RPG | Initializing System") console.info("Lethal Fantasy RPG | Initializing System")
@ -55,20 +55,20 @@ Hooks.once("init", function () {
} }
// Register sheet application classes // Register sheet application classes
Actors.unregisterSheet("core", ActorSheet) foundry.documents.collections.Actors.unregisterSheet("core", foundry.appv1.sheets.ActorSheet)
Actors.registerSheet("lethalFantasy", applications.LethalFantasyCharacterSheet, { types: ["character"], makeDefault: true }) foundry.documents.collections.Actors.registerSheet("lethalFantasy", applications.LethalFantasyCharacterSheet, { types: ["character"], makeDefault: true })
Actors.registerSheet("lethalFantasy", applications.LethalFantasyMonsterSheet, { types: ["monster"], makeDefault: true }) foundry.documents.collections.Actors.registerSheet("lethalFantasy", applications.LethalFantasyMonsterSheet, { types: ["monster"], makeDefault: true })
Items.unregisterSheet("core", ItemSheet) foundry.documents.collections.Items.unregisterSheet("core", foundry.appv1.sheets.ActorSheet)
Items.registerSheet("lethalFantasy", applications.LethalFantasySkillSheet, { types: ["skill"], makeDefault: true }) foundry.documents.collections.Items.registerSheet("lethalFantasy", applications.LethalFantasySkillSheet, { types: ["skill"], makeDefault: true })
Items.registerSheet("lethalFantasy", applications.LethalFantasyGiftSheet, { types: ["gift"], makeDefault: true }) foundry.documents.collections.Items.registerSheet("lethalFantasy", applications.LethalFantasyGiftSheet, { types: ["gift"], makeDefault: true })
Items.registerSheet("lethalFantasy", applications.LethalFantasyVulnerabilitySheet, { types: ["vulnerability"], makeDefault: true }) foundry.documents.collections.Items.registerSheet("lethalFantasy", applications.LethalFantasyVulnerabilitySheet, { types: ["vulnerability"], makeDefault: true })
Items.registerSheet("lethalFantasy", applications.LethalFantasyWeaponSheet, { types: ["weapon"], makeDefault: true }) foundry.documents.collections.Items.registerSheet("lethalFantasy", applications.LethalFantasyWeaponSheet, { types: ["weapon"], makeDefault: true })
Items.registerSheet("lethalFantasy", applications.LethalFantasySpellSheet, { types: ["spell"], makeDefault: true }) foundry.documents.collections.Items.registerSheet("lethalFantasy", applications.LethalFantasySpellSheet, { types: ["spell"], makeDefault: true })
Items.registerSheet("lethalFantasy", applications.LethalFantasyArmorSheet, { types: ["armor"], makeDefault: true }) foundry.documents.collections.Items.registerSheet("lethalFantasy", applications.LethalFantasyArmorSheet, { types: ["armor"], makeDefault: true })
Items.registerSheet("lethalFantasy", applications.LethalFantasyShieldSheet, { types: ["shield"], makeDefault: true }) foundry.documents.collections.Items.registerSheet("lethalFantasy", applications.LethalFantasyShieldSheet, { types: ["shield"], makeDefault: true })
Items.registerSheet("lethalFantasy", applications.LethalFantasyEquipmentSheet, { types: ["equipment"], makeDefault: true }) foundry.documents.collections.Items.registerSheet("lethalFantasy", applications.LethalFantasyEquipmentSheet, { types: ["equipment"], makeDefault: true })
Items.registerSheet("lethalFantasy", applications.LethalFantasyMiracleSheet, { types: ["miracle"], makeDefault: true }) foundry.documents.collections.Items.registerSheet("lethalFantasy", applications.LethalFantasyMiracleSheet, { types: ["miracle"], makeDefault: true })
// Other Document Configuration // Other Document Configuration
CONFIG.ChatMessage.documentClass = documents.LethalFantasyChatMessage CONFIG.ChatMessage.documentClass = documents.LethalFantasyChatMessage
@ -89,13 +89,13 @@ Hooks.once("init", function () {
setupTextEnrichers() setupTextEnrichers()
LethalFantasyUtils.registerHandlebarsHelpers() LethalFantasyUtils.registerHandlebarsHelpers()
LethalFantasyUtils.setHookListeners( ) LethalFantasyUtils.setHookListeners()
console.info("LETHAL FANTASY | System Initialized") console.info("LETHAL FANTASY | System Initialized")
}) })
/** /**
* Perform one-time configuration of system configuration objects. * Perform one-time configuration of system configuration objects.f
*/ */
function preLocalizeConfig() { function preLocalizeConfig() {
const localizeConfigObject = (obj, keys) => { const localizeConfigObject = (obj, keys) => {
@ -105,11 +105,6 @@ function preLocalizeConfig() {
} }
} }
} }
// CONFIG.Dice.rollModes = Object.fromEntries(Object.entries(CONFIG.Dice.rollModes).map(([key, value]) => [key, game.i18n.localize(value)]))
// localizeConfigObject(SYSTEM.ACTION.TAG_CATEGORIES, ["label"])
// localizeConfigObject(CONFIG.Dice.rollModes, ["label"])
} }
Hooks.once("ready", function () { Hooks.once("ready", function () {
@ -131,7 +126,12 @@ Hooks.once("ready", function () {
} }
}) })
Hooks.on("renderChatMessage", (message, html, data) => { // Test if version below 13
let hookName = "renderChatMessage"
if (foundry.utils.isNewerVersion(game.version, "12.0",)) {
hookName = "renderChatMessageHTML"
}
Hooks.on(hookName, (message, html, data) => {
const typeMessage = data.message.flags.lethalFantasy?.typeMessage const typeMessage = data.message.flags.lethalFantasy?.typeMessage
// Message de demande de jet de dés // Message de demande de jet de dés
if (typeMessage === "askRoll") { if (typeMessage === "askRoll") {

View File

@ -1,18 +1,54 @@
/* -------------------------------------------- */ /* -------------------------------------------- */
export class LethalFantasyCombatTracker extends CombatTracker { export class LethalFantasyCombatTracker extends foundry.applications.sidebar.tabs.CombatTracker {
async getData(options) { static PARTS = {
let data = await super.getData(options); "header": {
for (let u of data.turns) { "template": "systems/fvtt-lethal-fantasy/templates/combat-tracker-header-v2.hbs"
},
"tracker": {
"template": "systems/fvtt-lethal-fantasy/templates/combat-tracker-v2.hbs"
},
"footer": {
"template": "systems/fvtt-lethal-fantasy/templates/combat-tracker-footer-v2.hbs"
}
}
static DEFAULT_OPTIONS = foundry.utils.mergeObject(super.DEFAULT_OPTIONS, {
actions: {
initiativePlus: LethalFantasyCombatTracker.#initiativePlus,
initiativeMinus: LethalFantasyCombatTracker.#initiativeMinus,
},
});
async _prepareContext(options) {
let data = await super._prepareContext(options);
console?.log("Combat Tracker Data", data);
/*for (let u of data.turns) {
let c = game.combat.combatants.get(u.id); let c = game.combat.combatants.get(u.id);
u.progressionCount = c.system.progressionCount u.progressionCount = c.system.progressionCount
u.isMonster = c.actor.type === "monster" u.isMonster = c.actor.type === "monster"
} }
console.log("Combat Data", data); console.log("Combat Data", data);*/
return data; return data;
} }
static #initiativePlus(ev) {
ev.preventDefault();
let cId = ev.target.closest(".combatant").dataset.combatantId;
let c = game.combat.combatants.get(cId);
c.update({ 'initiative': c.initiative + 1 });
console.log("Initiative Plus");
}
static #initiativeMinus(ev) {
ev.preventDefault();
let cId = ev.target.closest(".combatant").dataset.combatantId;
let c = game.combat.combatants.get(cId);
let newInit = Math.max(c.initiative - 1, 0);
c.update({ 'initiative': newInit });
}
activateListeners(html) { activateListeners(html) {
super.activateListeners(html); super.activateListeners(html);
// Display Combat settings // Display Combat settings
@ -21,7 +57,6 @@ export class LethalFantasyCombatTracker extends CombatTracker {
let cId = ev.currentTarget.closest(".combatant").dataset.combatantId; let cId = ev.currentTarget.closest(".combatant").dataset.combatantId;
let c = game.combat.combatants.get(cId); let c = game.combat.combatants.get(cId);
c.update({ 'initiative': c.initiative + 1 }); c.update({ 'initiative': c.initiative + 1 });
console.log("Initiative Plus");
}); });
html.find(".initiative-minus").click(ev => { html.find(".initiative-minus").click(ev => {
@ -160,10 +195,10 @@ export class LethalFantasyCombat extends Combat {
} }
for (let c of this.combatants) { for (let c of this.combatants) {
if ( nextRound >= c.initiative) { if (nextRound >= c.initiative) {
let user = game.users.find(u => u.active && u.character && u.character.id === c.actor.id); let user = game.users.find(u => u.active && u.character && u.character.id === c.actor.id);
if (user?.hasPlayerOwner) { 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 }); game.socket.emit(`system.${SYSTEM.id}`, { type: "rollProgressionDice", progressionCount: c.system.progressionCount + 1, actorId: c.actor.id, combatId: this.id, combatantId: c.id });
} else { } else {
user = game.users.find(u => u.active && u.isGM); user = game.users.find(u => u.active && u.isGM);
c.actor.system.rollProgressionDice(this.id, c.id); c.actor.system.rollProgressionDice(this.id, c.id);

View File

@ -23,7 +23,7 @@ export default class LethalFantasyArmorSheet extends LethalFantasyItemSheet {
/** @override */ /** @override */
async _prepareContext() { async _prepareContext() {
const context = await super._prepareContext() const context = await super._prepareContext()
context.enrichedDescription = await TextEditor.enrichHTML(this.document.system.description, { async: true }) context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description, { async: true })
return context return context
} }

View File

@ -67,7 +67,7 @@ export default class LethalFantasyActorSheet extends HandlebarsApplicationMixin(
actor: this.document, actor: this.document,
system: this.document.system, system: this.document.system,
source: this.document.toObject(), source: this.document.toObject(),
enrichedDescription: await TextEditor.enrichHTML(this.document.system.description, { async: true }), enrichedDescription: await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description, { async: true }),
isEditMode: this.isEditMode, isEditMode: this.isEditMode,
isPlayMode: this.isPlayMode, isPlayMode: this.isPlayMode,
isEditable: this.isEditable, isEditable: this.isEditable,
@ -100,7 +100,7 @@ export default class LethalFantasyActorSheet extends HandlebarsApplicationMixin(
dragover: this._onDragOver.bind(this), dragover: this._onDragOver.bind(this),
drop: this._onDrop.bind(this), drop: this._onDrop.bind(this),
} }
return new DragDrop(d) return new foundry.applications.ux.DragDrop.implementation(d)
}) })
} }

View File

@ -58,22 +58,22 @@ export default class LethalFantasyItemSheet extends HandlebarsApplicationMixin(f
/** @override */ /** @override */
async _prepareContext() { async _prepareContext() {
const context = { let context = await super._prepareContext()
fields: this.document.schema.fields, context.fields = this.document.schema.fields
systemFields: this.document.system.schema.fields, context.systemFields = this.document.system.schema.fields
item: this.document, context.item = this.document
system: this.document.system, context.system = this.document.system
source: this.document.toObject(), context.source = this.document.toObject()
enrichedDescription: await TextEditor.enrichHTML(this.document.system.description, { async: true }), context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description, { async: true })
isEditMode: this.isEditMode, context.isEditMode = this.isEditMode
isPlayMode: this.isPlayMode, context.isPlayMode = this.isPlayMode
isEditable: this.isEditable, context.isEditable = this.isEditable
}
return context return context
} }
/** @override */ /** @override */
_onRender(context, options) { _onRender(context, options) {
super._onRender(context, options)
this.#dragDrop.forEach((d) => d.bind(this.element)) this.#dragDrop.forEach((d) => d.bind(this.element))
} }
@ -94,7 +94,7 @@ export default class LethalFantasyItemSheet extends HandlebarsApplicationMixin(f
dragover: this._onDragOver.bind(this), dragover: this._onDragOver.bind(this),
drop: this._onDrop.bind(this), drop: this._onDrop.bind(this),
} }
return new DragDrop(d) return new foundry.applications.ux.DragDrop.implementation(d)
}) })
} }

View File

@ -90,9 +90,6 @@ export default class LethalFantasyCharacterSheet extends LethalFantasyActorSheet
return context return context
} }
_generateTooltip(type, target) {
}
/** @override */ /** @override */
async _preparePartContext(partId, context) { async _preparePartContext(partId, context) {
const doc = this.document const doc = this.document
@ -127,8 +124,8 @@ export default class LethalFantasyCharacterSheet extends LethalFantasyActorSheet
break break
case "biography": case "biography":
context.tab = context.tabs.biography context.tab = context.tabs.biography
context.enrichedDescription = await TextEditor.enrichHTML(doc.system.description, { async: true }) context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(doc.system.description, { async: true })
context.enrichedNotes = await TextEditor.enrichHTML(doc.system.notes, { async: true }) context.enrichedNotes = await foundry.applications.ux.TextEditor.implementation.enrichHTML(doc.system.notes, { async: true })
break break
} }
return context return context
@ -143,18 +140,17 @@ export default class LethalFantasyCharacterSheet extends LethalFantasyActorSheet
*/ */
async _onDrop(event) { async _onDrop(event) {
if (!this.isEditable || !this.isEditMode) return if (!this.isEditable || !this.isEditMode) return
const data = TextEditor.getDragEventData(event) const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event)
// Handle different data types // Handle different data types
switch (data.type) { if (data.type === "Item") {
case "Item": const item = await fromUuid(data.uuid)
const item = await fromUuid(data.uuid) return this._onDropItem(item)
return this._onDropItem(item)
} }
} }
static async #onRangedAttackDefense(event, target) { static async #onRangedAttackDefense(event, target) {
const hasTarget = false // Future use : const hasTarget = false
let roll = await LethalFantasyRoll.promptRangedDefense({ let roll = await LethalFantasyRoll.promptRangedDefense({
actorId: this.actor.id, actorId: this.actor.id,
@ -250,6 +246,7 @@ export default class LethalFantasyCharacterSheet extends LethalFantasyActorSheet
async _onRoll(event, target) { async _onRoll(event, target) {
if (this.isEditMode) return if (this.isEditMode) return
console.log("Roll event", event)
const rollType = event.target.dataset.rollType const rollType = event.target.dataset.rollType
let rollKey = event.target.dataset.rollKey; let rollKey = event.target.dataset.rollKey;
let rollDice = event.target.dataset?.rollDice; let rollDice = event.target.dataset?.rollDice;

View File

@ -22,7 +22,7 @@ export default class LethalFantasyEquipmentSheet extends LethalFantasyItemSheet
/** @override */ /** @override */
async _prepareContext() { async _prepareContext() {
const context = await super._prepareContext() const context = await super._prepareContext()
context.enrichedDescription = await TextEditor.enrichHTML(this.document.system.description, { async: true }) context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description, { async: true })
return context return context
} }
} }

View File

@ -19,10 +19,4 @@ export default class LethalFantasyGiftSheet extends LethalFantasyItemSheet {
}, },
} }
/** @override */
async _prepareContext() {
const context = await super._prepareContext()
context.enrichedDescription = await TextEditor.enrichHTML(this.document.system.description, { async: true })
return context
}
} }

View File

@ -22,7 +22,7 @@ export default class LethalFantasyMiracleSheet extends LethalFantasyItemSheet {
/** @override */ /** @override */
async _prepareContext() { async _prepareContext() {
const context = await super._prepareContext() const context = await super._prepareContext()
context.enrichedDescription = await TextEditor.enrichHTML(this.document.system.description, { async: true }) context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description, { async: true })
return context return context
} }

View File

@ -63,9 +63,6 @@ export default class LethalFantasyMonsterSheet extends LethalFantasyActorSheet {
return context return context
} }
_generateTooltip(type, target) {
}
/** @override */ /** @override */
async _preparePartContext(partId, context) { async _preparePartContext(partId, context) {
const doc = this.document const doc = this.document
@ -78,8 +75,8 @@ export default class LethalFantasyMonsterSheet extends LethalFantasyActorSheet {
break break
case "biography": case "biography":
context.tab = context.tabs.biography context.tab = context.tabs.biography
context.enrichedDescription = await TextEditor.enrichHTML(doc.system.description, { async: true }) context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(doc.system.description, { async: true })
context.enrichedNotes = await TextEditor.enrichHTML(doc.system.notes, { async: true }) context.enrichedNotes = await foundry.applications.ux.TextEditor.implementation.enrichHTML(doc.system.notes, { async: true })
break break
} }
return context return context

View File

@ -22,7 +22,7 @@ export default class LethalFantasyShieldSheet extends LethalFantasyItemSheet {
/** @override */ /** @override */
async _prepareContext() { async _prepareContext() {
const context = await super._prepareContext() const context = await super._prepareContext()
context.enrichedDescription = await TextEditor.enrichHTML(this.document.system.description, { async: true }) context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description, { async: true })
return context return context
} }
} }

View File

@ -22,7 +22,7 @@ export default class LethalFantasySkillSheet extends LethalFantasyItemSheet {
/** @override */ /** @override */
async _prepareContext() { async _prepareContext() {
const context = await super._prepareContext() const context = await super._prepareContext()
context.enrichedDescription = await TextEditor.enrichHTML(this.document.system.description, { async: true }) context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description, { async: true })
return context return context
} }
} }

View File

@ -22,7 +22,7 @@ export default class LethalFantasySpellSheet extends LethalFantasyItemSheet {
/** @override */ /** @override */
async _prepareContext() { async _prepareContext() {
const context = await super._prepareContext() const context = await super._prepareContext()
context.enrichedDescription = await TextEditor.enrichHTML(this.document.system.description, { async: true }) context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description, { async: true })
return context return context
} }

View File

@ -22,7 +22,7 @@ export default class LethalFantasyVulnerabilitySheet extends LethalFantasyItemSh
/** @override */ /** @override */
async _prepareContext() { async _prepareContext() {
const context = await super._prepareContext() const context = await super._prepareContext()
context.enrichedDescription = await TextEditor.enrichHTML(this.document.system.description, { async: true }) context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description, { async: true })
return context return context
} }
} }

View File

@ -18,11 +18,11 @@ export default class LethalFantasyWeaponSheet extends LethalFantasyItemSheet {
template: "systems/fvtt-lethal-fantasy/templates/weapon.hbs", template: "systems/fvtt-lethal-fantasy/templates/weapon.hbs",
}, },
} }
/** @override */ /** @override */
async _prepareContext() { async _prepareContext() {
const context = await super._prepareContext() const context = await super._prepareContext()
context.enrichedDescription = await TextEditor.enrichHTML(this.document.system.description, { async: true }) context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description, { async: true })
return context return context
} }

View File

@ -44,22 +44,13 @@ export const MONEY = {
} }
export const MORTAL_CHOICES = { export const MORTAL_CHOICES = {
"mankind": {label: "Mankind", value: "Mankind", defenseBonus: 0}, "mankind": {label: "Mankind", id: "mankind", defenseBonus: 0},
"elf": {label: "Elf", value: "Elf", defenseBonus: 0}, "elf": {label: "Elf", id: "elf", defenseBonus: 0},
"dwarf": {label: "Dwarf", value: "Dwarf", defenseBonus: 0}, "dwarf": {label: "Dwarf", id: "dwarf", defenseBonus: 0},
"halfelf": {label: "Half-Elf", value: "Half-Elf", defenseBonus: 0}, "halfelf": {label: "Half-Elf", id: "halfelf", defenseBonus: 0},
"halforc": {label: "Half-Orc", value: "Half-Orc", defenseBonus: 0}, "halforc": {label: "Half-Orc", id: "halforc", defenseBonus: 0},
"gnome": {label: "Gnome", value: "Gnome", defenseBonus: 2}, "gnome": {label: "Gnome", id: "gnome", defenseBonus: 2},
"shirefolk": {label: "Shire Folk", value: "Shire Folk", defenseBonus: 2}, "halflings": {label: "Halflings", id: "halflings", defenseBonus: 2}
"Elf": {label: "Elf", value: "Elf", defenseBonus: 0},
"Half-orc": {label: "Half-Orc", value: "Half-Orc", defenseBonus: 0},
"Half-Orc": {label: "Half-Orc", value: "Half-Orc", defenseBonus: 0},
"Dwarf": {label: "Dwarf", value: "Dwarf", defenseBonus: 0},
"Half-elf": {label: "Half-Elf", value: "Half-Elf", defenseBonus: 0},
"Gnome": {label: "Gnome", value: "Gnome", defenseBonus: 2},
"Shire Folk": {label: "Shire Folk", value: "Shire Folk", defenseBonus: 2},
"Shire folk": {label: "Shire Folk", value: "Shire Folk", defenseBonus: 2},
"Mankind": {label: "Human", value: "Human", defenseBonus: 0},
} }
export const FAVOR_CHOICES = { export const FAVOR_CHOICES = {
@ -69,17 +60,16 @@ export const FAVOR_CHOICES = {
} }
export const MOVEMENT_CHOICES = { export const MOVEMENT_CHOICES = {
"none": {label: "None (D8E)", value: "D8"}, "none": {label: "None (D20E Disfavor)", disfavor: true, value: "2D20kl"},
"walk": {label: "Walk (D10E)", value: "D10"}, "walk": {label: "Walk (D20E Disfavor)", disfavor: true, value: "2D20kl"},
"jog": {label: "Jog (D12E)", value: "D12"}, "run": {label: "Jog/Run/Sprint (D20E Favor)", favor: true, value: "2D20kh"},
"run": {label: "Run (D20E)", value: "D20"}, "incombat": {label: "In Combat (D20E)", favor: false, value: "D20"}
"incombat": {label: "In Combat (D12E)", value: "D12"}
} }
export const MOVE_DIRECTION_CHOICES = { export const MOVE_DIRECTION_CHOICES = {
"none": {label: "None (+0)", value: "0"}, "none": {label: "None (+0)", value: "0"},
"away": {label: "Away (+4)", value: "+4"}, "away": {label: "Away (+4)", value: "+4"},
"toward": {label: "Toward (+0)", value: "0"}, "toward": {label: "Toward (-5)", value: "-5"},
"lateral": {label: "Lateral (+10)", value: "+10"} "lateral": {label: "Lateral (+10)", value: "+10"}
} }

View File

@ -292,7 +292,9 @@ export default class LethalFantasyRoll extends Roll {
hasModifier = false hasModifier = false
} }
const rollModes = Object.fromEntries(Object.entries(CONFIG.Dice.rollModes).map(([key, value]) => [key, game.i18n.localize(value)])) const rollModes = foundry.utils.duplicate(CONFIG.Dice.rollModes); // v12 : Object.fromEntries(Object.entries(CONFIG.Dice.rollModes).map(([key, value]) => [key, game.i18n.localize(value)]))
console.log("Roll mode", rollModes)
const fieldRollMode = new foundry.data.fields.StringField({ const fieldRollMode = new foundry.data.fields.StringField({
choices: rollModes, choices: rollModes,
blank: false, blank: false,
@ -329,7 +331,7 @@ export default class LethalFantasyRoll extends Roll {
favor: "none", favor: "none",
targetName targetName
} }
const content = await renderTemplate("systems/fvtt-lethal-fantasy/templates/roll-dialog.hbs", dialogContext) const content = await foundry.applications.handlebars.renderTemplate("systems/fvtt-lethal-fantasy/templates/roll-dialog.hbs", dialogContext)
let position = game.user.getFlag(SYSTEM.id, "roll-dialog-pos") || { top: -1, left: -1 } let position = game.user.getFlag(SYSTEM.id, "roll-dialog-pos") || { top: -1, left: -1 }
const label = game.i18n.localize("LETHALFANTASY.Roll.roll") const label = game.i18n.localize("LETHALFANTASY.Roll.roll")
@ -342,7 +344,8 @@ export default class LethalFantasyRoll extends Roll {
{ {
label: label, label: label,
callback: (event, button, dialog) => { callback: (event, button, dialog) => {
let position = $(dialog).position() console.log("Roll context", event, button, dialog)
let position = dialog.position
game.user.setFlag(SYSTEM.id, "roll-dialog-pos", foundry.utils.duplicate(position)) game.user.setFlag(SYSTEM.id, "roll-dialog-pos", foundry.utils.duplicate(position))
const output = Array.from(button.form.elements).reduce((obj, input) => { const output = Array.from(button.form.elements).reduce((obj, input) => {
if (input.name) obj[input.name] = input.value if (input.name) obj[input.name] = input.value
@ -566,7 +569,7 @@ export default class LethalFantasyRoll extends Roll {
/* ***********************************************************/ /* ***********************************************************/
static async promptInitiative(options = {}) { static async promptInitiative(options = {}) {
const rollModes = Object.fromEntries(Object.entries(CONFIG.Dice.rollModes).map(([key, value]) => [key, game.i18n.localize(value)])) const rollModes = foundry.utils.duplicate(CONFIG.Dice.rollModes); // v12 : Object.fromEntries(Object.entries(CONFIG.Dice.rollModes).map(([key, value]) => [key, game.i18n.localize(value)]))
const fieldRollMode = new foundry.data.fields.StringField({ const fieldRollMode = new foundry.data.fields.StringField({
choices: rollModes, choices: rollModes,
blank: false, blank: false,
@ -589,7 +592,7 @@ export default class LethalFantasyRoll extends Roll {
} }
console.log("CTX", dialogContext) console.log("CTX", dialogContext)
const content = await renderTemplate("systems/fvtt-lethal-fantasy/templates/roll-initiative-dialog.hbs", dialogContext) const content = await foundry.applications.handlebars.renderTemplate("systems/fvtt-lethal-fantasy/templates/roll-initiative-dialog.hbs", dialogContext)
const label = game.i18n.localize("LETHALFANTASY.Label.initiative") const label = game.i18n.localize("LETHALFANTASY.Label.initiative")
const rollContext = await foundry.applications.api.DialogV2.wait({ const rollContext = await foundry.applications.api.DialogV2.wait({
@ -628,7 +631,7 @@ export default class LethalFantasyRoll extends Roll {
/* ***********************************************************/ /* ***********************************************************/
static async promptCombatAction(options = {}) { static async promptCombatAction(options = {}) {
const rollModes = Object.fromEntries(Object.entries(CONFIG.Dice.rollModes).map(([key, value]) => [key, game.i18n.localize(value)])) const rollModes = foundry.utils.duplicate(CONFIG.Dice.rollModes); // v12 : Object.fromEntries(Object.entries(CONFIG.Dice.rollModes).map(([key, value]) => [key, game.i18n.localize(value)]))
const fieldRollMode = new foundry.data.fields.StringField({ const fieldRollMode = new foundry.data.fields.StringField({
choices: rollModes, choices: rollModes,
blank: false, blank: false,
@ -652,7 +655,7 @@ export default class LethalFantasyRoll extends Roll {
...options ...options
} }
const content = await renderTemplate("systems/fvtt-lethal-fantasy/templates/combat-action-dialog.hbs", dialogContext) const content = await foundry.applications.handlebars.renderTemplate("systems/fvtt-lethal-fantasy/templates/combat-action-dialog.hbs", dialogContext)
let buttons = [] let buttons = []
if (currentAction) { if (currentAction) {
@ -887,7 +890,7 @@ export default class LethalFantasyRoll extends Roll {
/* ***********************************************************/ /* ***********************************************************/
static async promptRangedDefense(rollTarget) { static async promptRangedDefense(rollTarget) {
const rollModes = Object.fromEntries(Object.entries(CONFIG.Dice.rollModes).map(([key, value]) => [key, game.i18n.localize(value)])) const rollModes = foundry.utils.duplicate(CONFIG.Dice.rollModes); // v12 : Object.fromEntries(Object.entries(CONFIG.Dice.rollModes).map(([key, value]) => [key, game.i18n.localize(value)]))
const fieldRollMode = new foundry.data.fields.StringField({ const fieldRollMode = new foundry.data.fields.StringField({
choices: rollModes, choices: rollModes,
blank: false, blank: false,
@ -910,7 +913,7 @@ export default class LethalFantasyRoll extends Roll {
} }
console.log("CTX", dialogContext) console.log("CTX", dialogContext)
const content = await renderTemplate("systems/fvtt-lethal-fantasy/templates/range-defense-dialog.hbs", dialogContext) const content = await foundry.applications.handlebars.renderTemplate("systems/fvtt-lethal-fantasy/templates/range-defense-dialog.hbs", dialogContext)
const label = game.i18n.localize("LETHALFANTASY.Label.rangeDefenseRoll") const label = game.i18n.localize("LETHALFANTASY.Label.rangeDefenseRoll")
const rollContext = await foundry.applications.api.DialogV2.wait({ const rollContext = await foundry.applications.api.DialogV2.wait({
@ -963,7 +966,7 @@ export default class LethalFantasyRoll extends Roll {
options.D30result = rollD30.total options.D30result = rollD30.total
let dice = rollContext.movement let dice = rollContext.movement
let maxValue = Number(dice.match(/\d+$/)[0]) // Update the max value agains let maxValue = 20 // As per latest changes (was : Number(dice.match(/\d+$/)[0])
let rollTotal = -1 let rollTotal = -1
let diceResults = [] let diceResults = []
let resultType let resultType
@ -1050,7 +1053,7 @@ export default class LethalFantasyRoll extends Roll {
async render(chatOptions = {}) { async render(chatOptions = {}) {
let chatData = await this._getChatCardData(chatOptions.isPrivate) let chatData = await this._getChatCardData(chatOptions.isPrivate)
console.log("ChatData", chatData) console.log("ChatData", chatData)
return await renderTemplate(this.constructor.CHAT_TEMPLATE, chatData) return await foundry.applications.handlebars.renderTemplate(this.constructor.CHAT_TEMPLATE, chatData)
} }
/* /*

View File

@ -174,6 +174,31 @@ export default class LethalFantasyCharacter extends foundry.abstract.TypeDataMod
/** @override */ /** @override */
static LOCALIZATION_PREFIXES = ["LETHALFANTASY.Character"] static LOCALIZATION_PREFIXES = ["LETHALFANTASY.Character"]
static migrateData(data) {
if (data?.biodata?.mortal) {
if (!SYSTEM.MORTAL_CHOICES[data.biodata.mortal]) {
for (let key in SYSTEM.MORTAL_CHOICES) {
let mortal = SYSTEM.MORTAL_CHOICES[key]
if ( mortal.label.toLowerCase() === data.biodata.mortal.toLowerCase()) {
data.biodata.mortal = mortal.id
}
if ( data.biodata.mortal.toLowerCase().includes("shire")) {
data.biodata.mortal = "halflings"
}
if ( data.biodata.mortal.toLowerCase().includes("human")) {
data.biodata.mortal = "mankind"
}
}
}
if (!SYSTEM.MORTAL_CHOICES[data.biodata.mortal]) {
console.warn("Lethal Fantasy | Migrate data: Mortal not found, forced to mankind", data.biodata.mortal)
data.biodata.mortal = "mankind"
}
}
return super.migrateData(data)
}
prepareDerivedData() { prepareDerivedData() {
super.prepareDerivedData(); super.prepareDerivedData();
let grit = 0 let grit = 0
@ -275,7 +300,7 @@ export default class LethalFantasyCharacter extends foundry.abstract.TypeDataMod
actorName: this.parent.name, actorName: this.parent.name,
actorImage: this.parent.img, actorImage: this.parent.img,
combatId, combatId,
combatantId , combatantId,
actorClass, actorClass,
maxInit, maxInit,
}) })
@ -302,10 +327,10 @@ export default class LethalFantasyCharacter extends foundry.abstract.TypeDataMod
let formula = "" let formula = ""
if (s.type === "spell") { if (s.type === "spell") {
let dice = LethalFantasyUtils.getLethargyDice(s.system.level) let dice = LethalFantasyUtils.getLethargyDice(s.system.level)
title = `${s.name} (Casting time: ${s.system.castingTime}, Lethargy: ${dice})` title = `${s.name} (Casting time: ${s.system.castingTime}, Lethargy: ${dice})`
formula = `${s.system.castingTime}+${dice}` formula = `${s.system.castingTime}+${dice}`
} else { } else {
title = `${s.name} (Prayer time: ${s.system.prayerTime})` title = `${s.name} (Prayer time: ${s.system.prayerTime})`
formula = `${s.system.prayerTime}` formula = `${s.system.prayerTime}`
} }
weaponsChoices.push({ id: s.id, name: title, combatProgressionDice: formula }) weaponsChoices.push({ id: s.id, name: title, combatProgressionDice: formula })

View File

@ -238,7 +238,7 @@ export default class LethalFantasyMonster extends foundry.abstract.TypeDataModel
async rollProgressionDice(combatId, combatantId) { async rollProgressionDice(combatId, combatantId) {
const rollModes = Object.fromEntries(Object.entries(CONFIG.Dice.rollModes).map(([key, value]) => [key, game.i18n.localize(value)])) const rollModes = foundry.utils.duplicate(CONFIG.Dice.rollModes)
const fieldRollMode = new foundry.data.fields.StringField({ const fieldRollMode = new foundry.data.fields.StringField({
choices: rollModes, choices: rollModes,
blank: false, blank: false,

View File

@ -22,39 +22,41 @@ export default class LethalFantasyUtils {
static setHookListeners() { static setHookListeners() {
Hooks.on('renderTokenHUD', async (hud, html, token) => { Hooks.on('renderTokenHUD', async (hud, html, token) => {
const lossHPButton = await renderTemplate('systems/fvtt-lethal-fantasy/templates/loss-hp-hud.hbs', {} ) const lossHPButton = await foundry.applications.handlebars.renderTemplate('systems/fvtt-lethal-fantasy/templates/loss-hp-hud.hbs', {} )
html.find('div.left').append(lossHPButton); $(html).find('div.left').append(lossHPButton);
html.find('img.lethal-hp-loss-hud').click((event) => { $(html).find('img.lethal-hp-loss-hud').click((event) => {
event.preventDefault(); event.preventDefault();
let hpMenu = html.find('.hp-loss-wrap')[0] let hpMenu = $(html).find('.hp-loss-wrap')[0]
if (hpMenu.classList.contains("hp-loss-hud-disabled")) { if (hpMenu.classList.contains("hp-loss-hud-disabled")) {
html.find('.hp-loss-wrap')[0].classList.add('hp-loss-hud-active'); $(html).find('.hp-loss-wrap')[0].classList.add('hp-loss-hud-active');
html.find('.hp-loss-wrap')[0].classList.remove('hp-loss-hud-disabled'); $(html).find('.hp-loss-wrap')[0].classList.remove('hp-loss-hud-disabled');
html.find('.hp-loss-wrap')[1].classList.add('hp-loss-hud-active'); $(html).find('.hp-loss-wrap')[1].classList.add('hp-loss-hud-active');
html.find('.hp-loss-wrap')[1].classList.remove('hp-loss-hud-disabled'); $(html).find('.hp-loss-wrap')[1].classList.remove('hp-loss-hud-disabled');
html.find('.hp-loss-wrap')[2].classList.add('hp-loss-hud-active'); $(html).find('.hp-loss-wrap')[2].classList.add('hp-loss-hud-active');
html.find('.hp-loss-wrap')[2].classList.remove('hp-loss-hud-disabled'); $(html).find('.hp-loss-wrap')[2].classList.remove('hp-loss-hud-disabled');
} else { } else {
html.find('.hp-loss-wrap')[0].classList.remove('hp-loss-hud-active'); $(html).find('.hp-loss-wrap')[0].classList.remove('hp-loss-hud-active');
html.find('.hp-loss-wrap')[0].classList.add('hp-loss-hud-disabled'); $(html).find('.hp-loss-wrap')[0].classList.add('hp-loss-hud-disabled');
html.find('.hp-loss-wrap')[1].classList.remove('hp-loss-hud-active'); $(html).find('.hp-loss-wrap')[1].classList.remove('hp-loss-hud-active');
html.find('.hp-loss-wrap')[1].classList.add('hp-loss-hud-disabled'); $(html).find('.hp-loss-wrap')[1].classList.add('hp-loss-hud-disabled');
html.find('.hp-loss-wrap')[2].classList.remove('hp-loss-hud-active'); $(html).find('.hp-loss-wrap')[2].classList.remove('hp-loss-hud-active');
html.find('.hp-loss-wrap')[2].classList.add('hp-loss-hud-disabled'); $(html).find('.hp-loss-wrap')[2].classList.add('hp-loss-hud-disabled');
} }
}) })
html.find('.loss-hp-hud-click').click((event) => { $(html).find('.loss-hp-hud-click').click((event) => {
event.preventDefault(); event.preventDefault();
let hpLoss = event.currentTarget.dataset.hpValue; let hpLoss = event.currentTarget.dataset.hpValue;
if (token) { if (token) {
let actor = game.actors.get(token.actorId); let tokenFull = canvas.tokens.placeables.find( t => t.id === token._id);
console.log(tokenFull, token)
let actor = tokenFull.actor;
actor.applyDamage(Number(hpLoss)); actor.applyDamage(Number(hpLoss));
html.find('.hp-loss-wrap')[0].classList.remove('hp-loss-hud-active'); $(html).find('.hp-loss-wrap')[0].classList.remove('hp-loss-hud-active');
html.find('.hp-loss-wrap')[0].classList.add('hp-loss-hud-disabled'); $(html).find('.hp-loss-wrap')[0].classList.add('hp-loss-hud-disabled');
html.find('.hp-loss-wrap')[1].classList.remove('hp-loss-hud-active'); $(html).find('.hp-loss-wrap')[1].classList.remove('hp-loss-hud-active');
html.find('.hp-loss-wrap')[1].classList.add('hp-loss-hud-disabled'); $(html).find('.hp-loss-wrap')[1].classList.add('hp-loss-hud-disabled');
html.find('.hp-loss-wrap')[2].classList.remove('hp-loss-hud-active'); $(html).find('.hp-loss-wrap')[2].classList.remove('hp-loss-hud-active');
html.find('.hp-loss-wrap')[2].classList.add('hp-loss-hud-disabled'); $(html).find('.hp-loss-wrap')[2].classList.add('hp-loss-hud-disabled');
} }
}) })
}) })

Binary file not shown.

Binary file not shown.

View File

@ -1 +1 @@
MANIFEST-000273 MANIFEST-000368

View File

@ -1,8 +1,8 @@
2025/04/27-22:21:03.476535 7fa7effff6c0 Recovering log #271 2025/06/05-15:50:28.883020 7ff25bfff6c0 Recovering log #366
2025/04/27-22:21:03.529446 7fa7effff6c0 Delete type=3 #269 2025/06/05-15:50:28.892731 7ff25bfff6c0 Delete type=3 #364
2025/04/27-22:21:03.529518 7fa7effff6c0 Delete type=0 #271 2025/06/05-15:50:28.892781 7ff25bfff6c0 Delete type=0 #366
2025/04/27-22:32:25.085954 7fa7eebff6c0 Level-0 table #276: started 2025/06/05-16:13:09.126587 7ff25a3ff6c0 Level-0 table #371: started
2025/04/27-22:32:25.085980 7fa7eebff6c0 Level-0 table #276: 0 bytes OK 2025/06/05-16:13:09.126654 7ff25a3ff6c0 Level-0 table #371: 0 bytes OK
2025/04/27-22:32:25.097677 7fa7eebff6c0 Delete type=0 #274 2025/06/05-16:13:09.133473 7ff25a3ff6c0 Delete type=0 #369
2025/04/27-22:32:25.110519 7fa7eebff6c0 Manual compaction at level-0 from '!folders!ATr9wZhg5uTVTksM' @ 72057594037927935 : 1 .. '!items!znm6T1ef4qQI8BX7' @ 0 : 0; will stop at (end) 2025/06/05-16:13:09.133695 7ff25a3ff6c0 Manual compaction at level-0 from '!folders!ATr9wZhg5uTVTksM' @ 72057594037927935 : 1 .. '!items!zw9RQocTdz3HRjZK' @ 0 : 0; will stop at (end)
2025/04/27-22:32:25.110580 7fa7eebff6c0 Manual compaction at level-1 from '!folders!ATr9wZhg5uTVTksM' @ 72057594037927935 : 1 .. '!items!znm6T1ef4qQI8BX7' @ 0 : 0; will stop at (end) 2025/06/05-16:13:09.133722 7ff25a3ff6c0 Manual compaction at level-1 from '!folders!ATr9wZhg5uTVTksM' @ 72057594037927935 : 1 .. '!items!zw9RQocTdz3HRjZK' @ 0 : 0; will stop at (end)

View File

@ -1,8 +1,8 @@
2025/04/27-22:10:37.047400 7fa7f51fa6c0 Recovering log #267 2025/06/05-15:38:54.440152 7ff2609fa6c0 Recovering log #362
2025/04/27-22:10:37.058458 7fa7f51fa6c0 Delete type=3 #265 2025/06/05-15:38:54.499643 7ff2609fa6c0 Delete type=3 #360
2025/04/27-22:10:37.058538 7fa7f51fa6c0 Delete type=0 #267 2025/06/05-15:38:54.499716 7ff2609fa6c0 Delete type=0 #362
2025/04/27-22:10:52.614770 7fa7eebff6c0 Level-0 table #272: started 2025/06/05-15:45:21.522661 7ff25a3ff6c0 Level-0 table #367: started
2025/04/27-22:10:52.614791 7fa7eebff6c0 Level-0 table #272: 0 bytes OK 2025/06/05-15:45:21.522692 7ff25a3ff6c0 Level-0 table #367: 0 bytes OK
2025/04/27-22:10:52.622121 7fa7eebff6c0 Delete type=0 #270 2025/06/05-15:45:21.550994 7ff25a3ff6c0 Delete type=0 #365
2025/04/27-22:10:52.628504 7fa7eebff6c0 Manual compaction at level-0 from '!folders!ATr9wZhg5uTVTksM' @ 72057594037927935 : 1 .. '!items!znm6T1ef4qQI8BX7' @ 0 : 0; will stop at (end) 2025/06/05-15:45:21.618228 7ff25a3ff6c0 Manual compaction at level-0 from '!folders!ATr9wZhg5uTVTksM' @ 72057594037927935 : 1 .. '!items!zw9RQocTdz3HRjZK' @ 0 : 0; will stop at (end)
2025/04/27-22:10:52.628572 7fa7eebff6c0 Manual compaction at level-1 from '!folders!ATr9wZhg5uTVTksM' @ 72057594037927935 : 1 .. '!items!znm6T1ef4qQI8BX7' @ 0 : 0; will stop at (end) 2025/06/05-15:45:21.618272 7ff25a3ff6c0 Manual compaction at level-1 from '!folders!ATr9wZhg5uTVTksM' @ 72057594037927935 : 1 .. '!items!zw9RQocTdz3HRjZK' @ 0 : 0; will stop at (end)

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1 +1 @@
MANIFEST-000272 MANIFEST-000367

View File

@ -1,8 +1,8 @@
2025/04/27-22:21:03.532054 7fa7ef7fe6c0 Recovering log #270 2025/06/05-15:50:28.899788 7ff25affd6c0 Recovering log #365
2025/04/27-22:21:03.584724 7fa7ef7fe6c0 Delete type=3 #268 2025/06/05-15:50:28.910099 7ff25affd6c0 Delete type=3 #363
2025/04/27-22:21:03.584865 7fa7ef7fe6c0 Delete type=0 #270 2025/06/05-15:50:28.910166 7ff25affd6c0 Delete type=0 #365
2025/04/27-22:32:25.103857 7fa7eebff6c0 Level-0 table #275: started 2025/06/05-16:13:09.075458 7ff25a3ff6c0 Level-0 table #370: started
2025/04/27-22:32:25.103878 7fa7eebff6c0 Level-0 table #275: 0 bytes OK 2025/06/05-16:13:09.075508 7ff25a3ff6c0 Level-0 table #370: 0 bytes OK
2025/04/27-22:32:25.110373 7fa7eebff6c0 Delete type=0 #273 2025/06/05-16:13:09.082149 7ff25a3ff6c0 Delete type=0 #368
2025/04/27-22:32:25.110550 7fa7eebff6c0 Manual compaction at level-0 from '!folders!yPWGvxHJbDNHVSnY' @ 72057594037927935 : 1 .. '!items!zjvGljrLk5SshC9D' @ 0 : 0; will stop at (end) 2025/06/05-16:13:09.102903 7ff25a3ff6c0 Manual compaction at level-0 from '!folders!yPWGvxHJbDNHVSnY' @ 72057594037927935 : 1 .. '!items!zjvGljrLk5SshC9D' @ 0 : 0; will stop at (end)
2025/04/27-22:32:25.110614 7fa7eebff6c0 Manual compaction at level-1 from '!folders!yPWGvxHJbDNHVSnY' @ 72057594037927935 : 1 .. '!items!zjvGljrLk5SshC9D' @ 0 : 0; will stop at (end) 2025/06/05-16:13:09.102950 7ff25a3ff6c0 Manual compaction at level-1 from '!folders!yPWGvxHJbDNHVSnY' @ 72057594037927935 : 1 .. '!items!zjvGljrLk5SshC9D' @ 0 : 0; will stop at (end)

View File

@ -1,8 +1,8 @@
2025/04/27-22:10:37.060842 7fa7f49f96c0 Recovering log #266 2025/06/05-15:38:54.508921 7ff25bfff6c0 Recovering log #361
2025/04/27-22:10:37.071585 7fa7f49f96c0 Delete type=3 #264 2025/06/05-15:38:54.560400 7ff25bfff6c0 Delete type=3 #359
2025/04/27-22:10:37.071676 7fa7f49f96c0 Delete type=0 #266 2025/06/05-15:38:54.560496 7ff25bfff6c0 Delete type=0 #361
2025/04/27-22:10:52.602346 7fa7eebff6c0 Level-0 table #271: started 2025/06/05-15:45:21.580332 7ff25a3ff6c0 Level-0 table #366: started
2025/04/27-22:10:52.602391 7fa7eebff6c0 Level-0 table #271: 0 bytes OK 2025/06/05-15:45:21.580366 7ff25a3ff6c0 Level-0 table #366: 0 bytes OK
2025/04/27-22:10:52.608549 7fa7eebff6c0 Delete type=0 #269 2025/06/05-15:45:21.618059 7ff25a3ff6c0 Delete type=0 #364
2025/04/27-22:10:52.628463 7fa7eebff6c0 Manual compaction at level-0 from '!folders!yPWGvxHJbDNHVSnY' @ 72057594037927935 : 1 .. '!items!zjvGljrLk5SshC9D' @ 0 : 0; will stop at (end) 2025/06/05-15:45:21.618252 7ff25a3ff6c0 Manual compaction at level-0 from '!folders!yPWGvxHJbDNHVSnY' @ 72057594037927935 : 1 .. '!items!zjvGljrLk5SshC9D' @ 0 : 0; will stop at (end)
2025/04/27-22:10:52.628540 7fa7eebff6c0 Manual compaction at level-1 from '!folders!yPWGvxHJbDNHVSnY' @ 72057594037927935 : 1 .. '!items!zjvGljrLk5SshC9D' @ 0 : 0; will stop at (end) 2025/06/05-15:45:21.618291 7ff25a3ff6c0 Manual compaction at level-1 from '!folders!yPWGvxHJbDNHVSnY' @ 72057594037927935 : 1 .. '!items!zjvGljrLk5SshC9D' @ 0 : 0; will stop at (end)

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1 +1 @@
MANIFEST-000272 MANIFEST-000367

View File

@ -1,8 +1,8 @@
2025/04/27-22:21:03.420246 7fa7f49f96c0 Recovering log #270 2025/06/05-15:50:28.868698 7ff2609fa6c0 Recovering log #365
2025/04/27-22:21:03.473337 7fa7f49f96c0 Delete type=3 #268 2025/06/05-15:50:28.879202 7ff2609fa6c0 Delete type=3 #363
2025/04/27-22:21:03.473392 7fa7f49f96c0 Delete type=0 #270 2025/06/05-15:50:28.879260 7ff2609fa6c0 Delete type=0 #365
2025/04/27-22:32:25.074302 7fa7eebff6c0 Level-0 table #275: started 2025/06/05-16:13:09.089330 7ff25a3ff6c0 Level-0 table #370: started
2025/04/27-22:32:25.074357 7fa7eebff6c0 Level-0 table #275: 0 bytes OK 2025/06/05-16:13:09.089359 7ff25a3ff6c0 Level-0 table #370: 0 bytes OK
2025/04/27-22:32:25.085821 7fa7eebff6c0 Delete type=0 #273 2025/06/05-16:13:09.096545 7ff25a3ff6c0 Delete type=0 #368
2025/04/27-22:32:25.110498 7fa7eebff6c0 Manual compaction at level-0 from '!folders!7j8H7DbmBb9Uza2X' @ 72057594037927935 : 1 .. '!items!zt8s7564ep1La4XQ' @ 0 : 0; will stop at (end) 2025/06/05-16:13:09.102932 7ff25a3ff6c0 Manual compaction at level-0 from '!folders!7j8H7DbmBb9Uza2X' @ 72057594037927935 : 1 .. '!items!zt8s7564ep1La4XQ' @ 0 : 0; will stop at (end)
2025/04/27-22:32:25.110565 7fa7eebff6c0 Manual compaction at level-1 from '!folders!7j8H7DbmBb9Uza2X' @ 72057594037927935 : 1 .. '!items!zt8s7564ep1La4XQ' @ 0 : 0; will stop at (end) 2025/06/05-16:13:09.102971 7ff25a3ff6c0 Manual compaction at level-1 from '!folders!7j8H7DbmBb9Uza2X' @ 72057594037927935 : 1 .. '!items!zt8s7564ep1La4XQ' @ 0 : 0; will stop at (end)

View File

@ -1,8 +1,8 @@
2025/04/27-22:10:37.034836 7fa7ef7fe6c0 Recovering log #266 2025/06/05-15:38:54.356422 7ff25b7fe6c0 Recovering log #361
2025/04/27-22:10:37.044865 7fa7ef7fe6c0 Delete type=3 #264 2025/06/05-15:38:54.437204 7ff25b7fe6c0 Delete type=3 #359
2025/04/27-22:10:37.044923 7fa7ef7fe6c0 Delete type=0 #266 2025/06/05-15:38:54.437267 7ff25b7fe6c0 Delete type=0 #361
2025/04/27-22:10:52.622268 7fa7eebff6c0 Level-0 table #271: started 2025/06/05-15:45:21.482142 7ff25a3ff6c0 Level-0 table #366: started
2025/04/27-22:10:52.622297 7fa7eebff6c0 Level-0 table #271: 0 bytes OK 2025/06/05-15:45:21.482216 7ff25a3ff6c0 Level-0 table #366: 0 bytes OK
2025/04/27-22:10:52.628287 7fa7eebff6c0 Delete type=0 #269 2025/06/05-15:45:21.522507 7ff25a3ff6c0 Delete type=0 #364
2025/04/27-22:10:52.628521 7fa7eebff6c0 Manual compaction at level-0 from '!folders!7j8H7DbmBb9Uza2X' @ 72057594037927935 : 1 .. '!items!zt8s7564ep1La4XQ' @ 0 : 0; will stop at (end) 2025/06/05-15:45:21.618214 7ff25a3ff6c0 Manual compaction at level-0 from '!folders!7j8H7DbmBb9Uza2X' @ 72057594037927935 : 1 .. '!items!zt8s7564ep1La4XQ' @ 0 : 0; will stop at (end)
2025/04/27-22:10:52.628588 7fa7eebff6c0 Manual compaction at level-1 from '!folders!7j8H7DbmBb9Uza2X' @ 72057594037927935 : 1 .. '!items!zt8s7564ep1La4XQ' @ 0 : 0; will stop at (end) 2025/06/05-15:45:21.618263 7ff25a3ff6c0 Manual compaction at level-1 from '!folders!7j8H7DbmBb9Uza2X' @ 72057594037927935 : 1 .. '!items!zt8s7564ep1La4XQ' @ 0 : 0; will stop at (end)

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1 @@
MANIFEST-000067

View File

View File

@ -0,0 +1,8 @@
2025/06/05-15:50:28.926119 7ff2609fa6c0 Recovering log #65
2025/06/05-15:50:28.936828 7ff2609fa6c0 Delete type=3 #63
2025/06/05-15:50:28.936884 7ff2609fa6c0 Delete type=0 #65
2025/06/05-16:13:09.082352 7ff25a3ff6c0 Level-0 table #70: started
2025/06/05-16:13:09.082382 7ff25a3ff6c0 Level-0 table #70: 0 bytes OK
2025/06/05-16:13:09.089177 7ff25a3ff6c0 Delete type=0 #68
2025/06/05-16:13:09.102923 7ff25a3ff6c0 Manual compaction at level-0 from '!folders!37mu4dxsSuftlnmP' @ 72057594037927935 : 1 .. '!items!zKOpU34oLziGJW6y' @ 0 : 0; will stop at (end)
2025/06/05-16:13:09.102957 7ff25a3ff6c0 Manual compaction at level-1 from '!folders!37mu4dxsSuftlnmP' @ 72057594037927935 : 1 .. '!items!zKOpU34oLziGJW6y' @ 0 : 0; will stop at (end)

View File

@ -0,0 +1,8 @@
2025/06/05-15:38:54.623832 7ff25affd6c0 Recovering log #61
2025/06/05-15:38:54.686829 7ff25affd6c0 Delete type=3 #59
2025/06/05-15:38:54.686886 7ff25affd6c0 Delete type=0 #61
2025/06/05-15:45:21.746826 7ff25a3ff6c0 Level-0 table #66: started
2025/06/05-15:45:21.746885 7ff25a3ff6c0 Level-0 table #66: 0 bytes OK
2025/06/05-15:45:21.784562 7ff25a3ff6c0 Delete type=0 #64
2025/06/05-15:45:21.784803 7ff25a3ff6c0 Manual compaction at level-0 from '!folders!37mu4dxsSuftlnmP' @ 72057594037927935 : 1 .. '!items!zKOpU34oLziGJW6y' @ 0 : 0; will stop at (end)
2025/06/05-15:45:21.839859 7ff25a3ff6c0 Manual compaction at level-1 from '!folders!37mu4dxsSuftlnmP' @ 72057594037927935 : 1 .. '!items!zKOpU34oLziGJW6y' @ 0 : 0; will stop at (end)

Binary file not shown.

Binary file not shown.

View File

@ -1 +1 @@
MANIFEST-000272 MANIFEST-000367

View File

@ -1,8 +1,8 @@
2025/04/27-22:21:03.587567 7fa7f51fa6c0 Recovering log #270 2025/06/05-15:50:28.913563 7ff25b7fe6c0 Recovering log #365
2025/04/27-22:21:03.645451 7fa7f51fa6c0 Delete type=3 #268 2025/06/05-15:50:28.923236 7ff25b7fe6c0 Delete type=3 #363
2025/04/27-22:21:03.645585 7fa7f51fa6c0 Delete type=0 #270 2025/06/05-15:50:28.923301 7ff25b7fe6c0 Delete type=0 #365
2025/04/27-22:32:25.097834 7fa7eebff6c0 Level-0 table #275: started 2025/06/05-16:13:09.096673 7ff25a3ff6c0 Level-0 table #370: started
2025/04/27-22:32:25.097881 7fa7eebff6c0 Level-0 table #275: 0 bytes OK 2025/06/05-16:13:09.096704 7ff25a3ff6c0 Level-0 table #370: 0 bytes OK
2025/04/27-22:32:25.103788 7fa7eebff6c0 Delete type=0 #273 2025/06/05-16:13:09.102790 7ff25a3ff6c0 Delete type=0 #368
2025/04/27-22:32:25.110534 7fa7eebff6c0 Manual compaction at level-0 from '!folders!mnO9OzE7BEE2KDfh' @ 72057594037927935 : 1 .. '!items!zkK6ixtCsCw3RH9X' @ 0 : 0; will stop at (end) 2025/06/05-16:13:09.102942 7ff25a3ff6c0 Manual compaction at level-0 from '!folders!mnO9OzE7BEE2KDfh' @ 72057594037927935 : 1 .. '!items!zkK6ixtCsCw3RH9X' @ 0 : 0; will stop at (end)
2025/04/27-22:32:25.110597 7fa7eebff6c0 Manual compaction at level-1 from '!folders!mnO9OzE7BEE2KDfh' @ 72057594037927935 : 1 .. '!items!zkK6ixtCsCw3RH9X' @ 0 : 0; will stop at (end) 2025/06/05-16:13:09.102964 7ff25a3ff6c0 Manual compaction at level-1 from '!folders!mnO9OzE7BEE2KDfh' @ 72057594037927935 : 1 .. '!items!zkK6ixtCsCw3RH9X' @ 0 : 0; will stop at (end)

View File

@ -1,8 +1,8 @@
2025/04/27-22:10:37.074061 7fa7effff6c0 Recovering log #266 2025/06/05-15:38:54.562778 7ff25b7fe6c0 Recovering log #361
2025/04/27-22:10:37.085221 7fa7effff6c0 Delete type=3 #264 2025/06/05-15:38:54.621024 7ff25b7fe6c0 Delete type=3 #359
2025/04/27-22:10:37.085303 7fa7effff6c0 Delete type=0 #266 2025/06/05-15:38:54.621100 7ff25b7fe6c0 Delete type=0 #361
2025/04/27-22:10:52.608683 7fa7eebff6c0 Level-0 table #271: started 2025/06/05-15:45:21.551139 7ff25a3ff6c0 Level-0 table #366: started
2025/04/27-22:10:52.608708 7fa7eebff6c0 Level-0 table #271: 0 bytes OK 2025/06/05-15:45:21.551169 7ff25a3ff6c0 Level-0 table #366: 0 bytes OK
2025/04/27-22:10:52.614653 7fa7eebff6c0 Delete type=0 #269 2025/06/05-15:45:21.580145 7ff25a3ff6c0 Delete type=0 #364
2025/04/27-22:10:52.628484 7fa7eebff6c0 Manual compaction at level-0 from '!folders!mnO9OzE7BEE2KDfh' @ 72057594037927935 : 1 .. '!items!zkK6ixtCsCw3RH9X' @ 0 : 0; will stop at (end) 2025/06/05-15:45:21.618241 7ff25a3ff6c0 Manual compaction at level-0 from '!folders!mnO9OzE7BEE2KDfh' @ 72057594037927935 : 1 .. '!items!zkK6ixtCsCw3RH9X' @ 0 : 0; will stop at (end)
2025/04/27-22:10:52.628557 7fa7eebff6c0 Manual compaction at level-1 from '!folders!mnO9OzE7BEE2KDfh' @ 72057594037927935 : 1 .. '!items!zkK6ixtCsCw3RH9X' @ 0 : 0; will stop at (end) 2025/06/05-15:45:21.618280 7ff25a3ff6c0 Manual compaction at level-1 from '!folders!mnO9OzE7BEE2KDfh' @ 72057594037927935 : 1 .. '!items!zkK6ixtCsCw3RH9X' @ 0 : 0; will stop at (end)

Binary file not shown.

View File

@ -4,6 +4,7 @@
overflow: scroll; overflow: scroll;
} }
.character-main { .character-main {
display: flex; display: flex;
@ -93,6 +94,10 @@
.character-characteristic { .character-characteristic {
display: flex; display: flex;
align-items: center; align-items: center;
span {
min-width: 2.2rem;
max-width: 2.2rem;
}
.rollable:hover, .rollable:hover,
.rollable:focus { .rollable:focus {
text-shadow: 0 0 8px var(--color-shadow-primary); text-shadow: 0 0 8px var(--color-shadow-primary);
@ -108,7 +113,7 @@
} }
} }
} }
.character-challenges { .character-challenges {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -218,7 +223,7 @@
} }
} }
.tab.character-biography { .tab.character-biography .main-div{
.biodata { .biodata {
display: grid; display: grid;
grid-template-columns: repeat(4, 1fr); grid-template-columns: repeat(4, 1fr);
@ -248,7 +253,7 @@
} }
} }
.tab.character-skills { .tab.character-skills .main-div{
display: grid; display: grid;
grid-template-columns: 1fr; grid-template-columns: 1fr;
legend { legend {
@ -310,7 +315,7 @@
} }
} }
.tab.character-equipment { .tab.character-equipment .main-div {
display: grid; display: grid;
grid-template-columns: 1fr; grid-template-columns: 1fr;
legend { legend {
@ -349,7 +354,7 @@
} }
} }
.tab.character-combat { .tab.character-combat .main-div {
display: grid; display: grid;
grid-template-columns: 1fr; grid-template-columns: 1fr;
legend { legend {
@ -497,7 +502,7 @@
} }
.tab.character-spells { .tab.character-spells .main-div {
display: grid; display: grid;
grid-template-columns: 1fr; grid-template-columns: 1fr;
legend { legend {
@ -558,7 +563,7 @@
} }
} }
.tab.character-miracles { .tab.character-miracles .main-div {
display: grid; display: grid;
grid-template-columns: 1fr; grid-template-columns: 1fr;
legend { legend {

View File

@ -5,6 +5,5 @@
@font-face { @font-face {
font-family: "BaskervilleBold"; font-family: "BaskervilleBold";
src: url("../fonts/baskerville-bold.ttf") format("truetype"); src: url("../assets/fonts/baskerville-bold.ttf") format("truetype");
} }

View File

@ -6,6 +6,17 @@
--logo-standard: url("../assets/ui/lf_logo_small_02.webp"); --logo-standard: url("../assets/ui/lf_logo_small_02.webp");
} }
.initiative-area {
min-width: 8rem;
max-width: 8rem;
display: flex;
flex-direction: row;
input {
min-width: 3rem;
max-width: 3rem;
}
}
#logo { #logo {
content: var(--logo-standard); content: var(--logo-standard);
width: 50px; width: 50px;

View File

@ -35,9 +35,10 @@
padding-bottom: 0; padding-bottom: 0;
width: max-content; width: max-content;
margin: 0; margin: 0;
color:#252424;
} }
#token-hud .hp-loss-wrap .hud-loss-hp-button-select { #token-hud .hp-loss-wrap .hud-loss-hp-button-select {
padding-left: 8px; padding-left: 8px;
font-size: 0.7rem; font-size: 0.9rem;
} }

View File

@ -6,6 +6,14 @@
background-repeat: no-repeat; background-repeat: no-repeat;
background-size: 100% 100%; background-size: 100% 100%;
nav.tabs [data-tab] {
color: #636060;
}
nav.tabs [data-tab].active {
color: #252424;
}
input:disabled, input:disabled,
select:disabled { select:disabled {
background-color: rgba(0, 0, 0, 0.2); background-color: rgba(0, 0, 0, 0.2);
@ -39,11 +47,11 @@
input, input,
select { select {
text-align: center; text-align: center;
font-size: calc(var(--font-size-standard) * 1.0); font-size: calc(var(--font-size-standard) * 1);
} }
select { select {
font-family: var(--font-secondary); font-family: var(--font-secondary);
font-size: calc(var(--font-size-standard) * 1.0); font-size: calc(var(--font-size-standard) * 1);
} }
} }
@ -67,23 +75,43 @@
padding-top: 4px; padding-top: 4px;
} }
overflow: auto;
.form-group {
display: flex;
flex: 1;
flex-direction: row;
label {
align-content: center;
min-width: 10rem;
max-width: 10rem;
}
select,
input {
text-align: left;
min-width: 12rem;
max-width: 12rem;
}
input[type="checkbox"] {
min-width: 1.2rem;
max-width: 1.2rem;
margin-right: 0.5rem;
}
}
label { label {
font-family: var(--font-secondary); font-family: var(--font-secondary);
font-size: calc(var(--font-size-standard) * 1.0); font-size: calc(var(--font-size-standard) * 1);
flex: 50%; flex: 50%;
} }
.align-top { .align-top {
align-self: flex-start; align-self: flex-start;
padding: 0.1rem; padding: 0.1rem;
margin-right: 0.2rem; margin-right: 0.2rem;
/*border-color: black;
border-width: 1px;
border-style: solid;
border-radius: 2%;*/
} }
.shift-right { .shift-right {
margin-left: 2rem; margin-left: 2rem;
} }
} }

View File

@ -19,12 +19,12 @@
border: none; border: none;
} }
} }
.monster-pc { .monster-pc {
display: flex; display: flex;
gap: 10px; gap: 10px;
flex: 1; flex: 1;
.monster-hp { .monster-hp {
display: flex; display: flex;
@ -99,6 +99,10 @@
text-shadow: 0 0 8px var(--color-shadow-primary); text-shadow: 0 0 8px var(--color-shadow-primary);
cursor: pointer; cursor: pointer;
} }
span {
min-width: 2.2rem;
max-width: 2.2rem;
}
.form-group { .form-group {
flex: 1; flex: 1;
padding-left: 4px; padding-left: 4px;
@ -223,7 +227,7 @@
} }
} }
.tab.monster-biography { .tab.monster-biography .main-div {
.biodata { .biodata {
display: grid; display: grid;
grid-template-columns: repeat(4, 1fr); grid-template-columns: repeat(4, 1fr);
@ -248,7 +252,7 @@
} }
} }
.tab.monster-skills { .tab.monster-skills .main-div{
display: grid; display: grid;
grid-template-columns: 1fr; grid-template-columns: 1fr;
legend { legend {
@ -462,4 +466,3 @@
min-height: 150px; min-height: 150px;
} }
} }

View File

@ -6,7 +6,7 @@
"download": "#{DOWNLOAD}#", "download": "#{DOWNLOAD}#",
"url": "#{URL}#", "url": "#{URL}#",
"license": "LICENSE", "license": "LICENSE",
"version": "12.0.35", "version": "13.0.0",
"authors": [ "authors": [
{ {
"name": "Uberwald", "name": "Uberwald",
@ -14,8 +14,8 @@
} }
], ],
"compatibility": { "compatibility": {
"minimum": "12", "minimum": "13",
"verified": "12" "verified": "13"
}, },
"esmodules": ["lethal-fantasy.mjs"], "esmodules": ["lethal-fantasy.mjs"],
"styles": ["css/fvtt-lethal-fantasy.css"], "styles": ["css/fvtt-lethal-fantasy.css"],
@ -82,6 +82,14 @@
"system": "fvtt-lethal-fantasy", "system": "fvtt-lethal-fantasy",
"path": "packs-system/lf-vulnerabilities", "path": "packs-system/lf-vulnerabilities",
"type": "Item" "type": "Item"
},
{
"name": "lf-spells-miracles",
"banner": "",
"label": "Spells & Miracles",
"system": "fvtt-lethal-fantasy",
"path": "packs-system/lf-spells-miracles",
"type": "Item"
} }
], ],
"flags": { "flags": {

View File

@ -1,4 +1,5 @@
<section class="tab character-{{tab.id}} {{tab.cssClass}}" data-tab="{{tab.id}}" data-group="{{tab.group}}"> <section class="tab character-{{tab.id}} {{tab.cssClass}}" data-tab="{{tab.id}}" data-group="{{tab.group}}">
<div class="main-div">
<fieldset> <fieldset>
<legend>{{localize "LETHALFANTASY.Label.biodata"}}</legend> <legend>{{localize "LETHALFANTASY.Label.biodata"}}</legend>
@ -92,5 +93,5 @@
<legend>{{localize "LETHALFANTASY.Label.notes"}}</legend> <legend>{{localize "LETHALFANTASY.Label.notes"}}</legend>
{{formInput systemFields.notes enriched=enrichedNotes value=system.notes name="system.notes" toggled=true}} {{formInput systemFields.notes enriched=enrichedNotes value=system.notes name="system.notes" toggled=true}}
</fieldset> </fieldset>
</div>
</section> </section>

View File

@ -1,10 +1,11 @@
<section class="tab character-{{tab.id}} {{tab.cssClass}}" data-tab="{{tab.id}}" data-group="{{tab.group}}"> <section class="tab character-{{tab.id}} {{tab.cssClass}}" data-tab="combat" data-group="sheet">
<div class="main-div">
<fieldset> <fieldset>
<legend>{{localize "LETHALFANTASY.Label.combatDetails"}}</legend> <legend>{{localize "LETHALFANTASY.Label.combatDetails"}}</legend>
<div class="combat-details"> <div class="combat-details">
<div class="combat-detail"> <div class="combat-detail">
<button class="action" data-action="rangedAttackDefense"> <button class="action" data-action="rangedAttackDefense">
{{localize "LETHALFANTASY.Label.rangedAttackDefense"}} {{localize "LETHALFANTASY.Label.rangedAttackDefense"}}
</button> </button>
@ -155,5 +156,6 @@
{{/each}} {{/each}}
</div> </div>
</fieldset> </fieldset>
<div>
</section> </section>

View File

@ -1,4 +1,5 @@
<section class="tab character-{{tab.id}} {{tab.cssClass}}" data-tab="{{tab.id}}" data-group="{{tab.group}}"> <section class="tab character-{{tab.id}} {{tab.cssClass}}" data-tab="{{tab.id}}" data-group="{{tab.group}}">
<div class="main-div">
<fieldset> <fieldset>
<legend>{{localize "LETHALFANTASY.Label.money"}}</legend> <legend>{{localize "LETHALFANTASY.Label.money"}}</legend>
@ -31,5 +32,5 @@
</div> </div>
</fieldset> </fieldset>
</div>
</section> </section>

View File

@ -81,16 +81,16 @@
<div class="character-save"> <div class="character-save">
<span class="name"> <span class="name">
<a class="rollable" data-roll-type="save" data-roll-key="contagion"><i <a class="rollable" data-roll-type="save" data-roll-key="contagion"><i
class="lf-roll-small fa-solid fa-dice-d20"></i> class="lf-roll-small fa-solid fa-dice-d20"></i>
{{localize "LETHALFANTASY.Label.saves.contagion"}} {{localize "LETHALFANTASY.Label.saves.contagion"}}
</a> </a>
</span> </span>
{{formField systemFields.saves.fields.contagion.fields.value value=system.saves.contagion.value {{formField systemFields.saves.fields.contagion.fields.value value=system.saves.contagion.value
disabled=true}} disabled=true}}
<span class="name"> <span class="name">
<a class="rollable" data-roll-type="save" data-roll-key="poison"><i <a class="rollable" data-roll-type="save" data-roll-key="poison"><i
class="lf-roll-small fa-solid fa-dice-d20"></i> class="lf-roll-small fa-solid fa-dice-d20"></i>
{{localize "LETHALFANTASY.Label.saves.poison"}} {{localize "LETHALFANTASY.Label.saves.poison"}}
</a> </a>
</span> </span>
@ -99,18 +99,18 @@
<span class="name-pain"> <span class="name-pain">
<a class="rollable" data-roll-type="save" data-roll-key="pain" data-roll-dice="D12"><i <a class="rollable" data-roll-type="save" data-roll-key="pain" data-roll-dice="D12"><i
class="lf-roll-small fa-solid fa-dice-d12"></i> class="lf-roll-small fa-solid fa-dice-d12"></i>
{{localize "LETHALFANTASY.Label.saves.pain"}} {{localize "LETHALFANTASY.Label.saves.pain"}}
</a> </a>
</span> </span>
<span class="name-pain"> <span class="name-pain">
<a class="rollable" data-roll-type="save" data-roll-key="pain" data-roll-dice="D20"><i <a class="rollable" data-roll-type="save" data-roll-key="pain" data-roll-dice="D20"><i
class="lf-roll-small fa-solid fa-dice-d20"></i> class="lf-roll-small fa-solid fa-dice-d20"></i>
{{localize "LETHALFANTASY.Label.saves.pain"}} {{localize "LETHALFANTASY.Label.saves.pain"}}
</a> </a>
</span> </span>
{{formField systemFields.saves.fields.pain.fields.value value=system.saves.pain.value disabled=true}} {{formField systemFields.saves.fields.pain.fields.value value=system.saves.pain.value disabled=true}}
<span data-tooltip="Pain save if wound exceeds"> <span data-tooltip="Pain save if wound exceeds">
{{formField systemFields.hp.fields.painDamage value=system.hp.painDamage disabled=isPlayMode tooltip="Pain Damage"}} {{formField systemFields.hp.fields.painDamage value=system.hp.painDamage disabled=isPlayMode tooltip="Pain Damage"}}
</span> </span>
@ -174,14 +174,14 @@
<fieldset class="character-characteristics character-characteristics-{{ifThen isPlayMode 'play' 'edit'}}"> <fieldset class="character-characteristics character-characteristics-{{ifThen isPlayMode 'play' 'edit'}}">
<legend>{{localize "LETHALFANTASY.Label.characteristics"}}</legend> <legend>{{localize "LETHALFANTASY.Label.characteristics"}}</legend>
<div class="character-characteristic"> <div class="character-characteristic">
{{localize "LETHALFANTASY.Label.str"}} <span>{{localize "LETHALFANTASY.Label.str"}}</span>
{{formField systemFields.characteristics.fields.str.fields.value value=system.characteristics.str.value {{formField systemFields.characteristics.fields.str.fields.value value=system.characteristics.str.value
disabled=isPlayMode data-char-id="str" }} disabled=isPlayMode data-char-id="str" }}
{{formField systemFields.characteristics.fields.str.fields.percent value=system.characteristics.str.percent {{formField systemFields.characteristics.fields.str.fields.percent value=system.characteristics.str.percent
disabled=isPlayMode type="number"}} disabled=isPlayMode type="number"}}
</div> </div>
<div class="character-characteristic"> <div class="character-characteristic">
{{localize "LETHALFANTASY.Label.int"}} <span>{{localize "LETHALFANTASY.Label.int"}}</span>
{{formField systemFields.characteristics.fields.int.fields.value value=system.characteristics.int.value {{formField systemFields.characteristics.fields.int.fields.value value=system.characteristics.int.value
disabled=isPlayMode data-char-id="int" }} disabled=isPlayMode data-char-id="int" }}
@ -189,7 +189,7 @@
disabled=isPlayMode type="number" }} disabled=isPlayMode type="number" }}
</div> </div>
<div class="character-characteristic"> <div class="character-characteristic">
{{localize "LETHALFANTASY.Label.wis"}} <span>{{localize "LETHALFANTASY.Label.wis"}}</span>
{{formField systemFields.characteristics.fields.wis.fields.value value=system.characteristics.wis.value {{formField systemFields.characteristics.fields.wis.fields.value value=system.characteristics.wis.value
disabled=isPlayMode data-char-id="wis" }} disabled=isPlayMode data-char-id="wis" }}
@ -197,7 +197,7 @@
disabled=isPlayMode type="number"}} disabled=isPlayMode type="number"}}
</div> </div>
<div class="character-characteristic"> <div class="character-characteristic">
{{localize "LETHALFANTASY.Label.dex"}} <span>{{localize "LETHALFANTASY.Label.dex"}}</span>
{{formField systemFields.characteristics.fields.dex.fields.value value=system.characteristics.dex.value {{formField systemFields.characteristics.fields.dex.fields.value value=system.characteristics.dex.value
disabled=isPlayMode data-char-id="wis" }} disabled=isPlayMode data-char-id="wis" }}
@ -205,7 +205,7 @@
disabled=isPlayMode type="number" }} disabled=isPlayMode type="number" }}
</div> </div>
<div class="character-characteristic"> <div class="character-characteristic">
{{localize "LETHALFANTASY.Label.con"}} <span>{{localize "LETHALFANTASY.Label.con"}}</span>
{{formField systemFields.characteristics.fields.con.fields.value value=system.characteristics.con.value {{formField systemFields.characteristics.fields.con.fields.value value=system.characteristics.con.value
disabled=isPlayMode data-char-id="con" }} disabled=isPlayMode data-char-id="con" }}
@ -213,7 +213,7 @@
disabled=isPlayMode type="number"}} disabled=isPlayMode type="number"}}
</div> </div>
<div class="character-characteristic"> <div class="character-characteristic">
{{localize "LETHALFANTASY.Label.cha"}} <span>{{localize "LETHALFANTASY.Label.cha"}}</span>
{{formField systemFields.characteristics.fields.cha.fields.value value=system.characteristics.cha.value {{formField systemFields.characteristics.fields.cha.fields.value value=system.characteristics.cha.value
disabled=isPlayMode data-char-id="cha" }} disabled=isPlayMode data-char-id="cha" }}
@ -221,7 +221,7 @@
disabled=isPlayMode type="number"}} disabled=isPlayMode type="number"}}
</div> </div>
<div class="character-characteristic"> <div class="character-characteristic">
{{localize "LETHALFANTASY.Label.luc"}} <span>{{localize "LETHALFANTASY.Label.luc"}}</span>
{{formField systemFields.characteristics.fields.luc.fields.value value=system.characteristics.luc.value {{formField systemFields.characteristics.fields.luc.fields.value value=system.characteristics.luc.value
disabled=isPlayMode data-char-id="luc" }} disabled=isPlayMode data-char-id="luc" }}
@ -229,7 +229,7 @@
disabled=isPlayMode type="number"}} disabled=isPlayMode type="number"}}
</div> </div>
<div class="character-characteristic"> <div class="character-characteristic">
{{localize "LETHALFANTASY.Label.app"}} <span>{{localize "LETHALFANTASY.Label.app"}}</span>
{{formField systemFields.characteristics.fields.app.fields.value value=system.characteristics.app.value {{formField systemFields.characteristics.fields.app.fields.value value=system.characteristics.app.value
disabled=isPlayMode data-char-id="app" }} disabled=isPlayMode data-char-id="app" }}

View File

@ -1,4 +1,5 @@
<section class="tab character-{{tab.id}} {{tab.cssClass}}" data-tab="{{tab.id}}" data-group="{{tab.group}}"> <section class="tab character-{{tab.id}} {{tab.cssClass}}" data-tab="{{tab.id}}" data-group="{{tab.group}}">
<div class="main-div">
<fieldset> <fieldset>
<legend>{{localize "LETHALFANTASY.Label.divinityPoints"}}</legend> <legend>{{localize "LETHALFANTASY.Label.divinityPoints"}}</legend>
@ -46,5 +47,6 @@
{{/each}} {{/each}}
</div> </div>
</fieldset> </fieldset>
</div>
</section> </section>

View File

@ -1,4 +1,5 @@
<section class="tab character-{{tab.id}} {{tab.cssClass}}" data-tab="{{tab.id}}" data-group="{{tab.group}}"> <section class="tab character-{{tab.id}} {{tab.cssClass}}" data-tab="skills" data-group="sheet">
<div class="main-div">
<fieldset> <fieldset>
<legend data-tooltip="{{localize " LETHALFANTASY.Tooltip.skills"}}" data-tooltip-direction="UP">{{localize <legend data-tooltip="{{localize " LETHALFANTASY.Tooltip.skills"}}" data-tooltip-direction="UP">{{localize
@ -68,5 +69,5 @@
{{/each}} {{/each}}
</div> </div>
</fieldset> </fieldset>
</div>
</section> </section>

View File

@ -1,19 +1,21 @@
<section class="tab character-{{tab.id}} {{tab.cssClass}}" data-tab="{{tab.id}}" data-group="{{tab.group}}"> <section class="tab character-{{tab.id}} {{tab.cssClass}}" data-tab="{{tab.id}}" data-group="{{tab.group}}">
<div class="main-div">
<fieldset> <fieldset>
<legend>{{localize "LETHALFANTASY.Label.aetherPoints"}}</legend> <legend>{{localize "LETHALFANTASY.Label.aetherPoints"}}</legend>
<div class="spell-details"> <div class="spell-details">
<div class="spell-detail"> <div class="spell-detail">
<span >Current</span> <span>Current</span>
{{formField systemFields.aetherPoints.fields.value value=system.aetherPoints.value localize=true}} {{formField systemFields.aetherPoints.fields.value value=system.aetherPoints.value localize=true}}
<a data-action="aetherPointsPlus"><i class="fa-solid fa-hexagon-plus"></i></a> <a data-action="aetherPointsPlus"><i class="fa-solid fa-hexagon-plus"></i></a>
<a data-action="aetherPointsMinus"><i class="fa-solid fa-hexagon-minus"></i></a> <a data-action="aetherPointsMinus"><i class="fa-solid fa-hexagon-minus"></i></a>
<span >Max</span> <span>Max</span>
{{formField systemFields.aetherPoints.fields.max value=system.aetherPoints.max localize=true disabled=isPlayMode}} {{formField systemFields.aetherPoints.fields.max value=system.aetherPoints.max localize=true
disabled=isPlayMode}}
</div> </div>
</div> </div>
</div> </div>
</fieldset> </fieldset>
<fieldset> <fieldset>
@ -22,9 +24,9 @@
data-action="createSpell"></i></a>{{/if}}</legend> data-action="createSpell"></i></a>{{/if}}</legend>
<div class="spells"> <div class="spells">
{{#each spells as |item|}} {{#each spells as |item|}}
<div class="spell" data-item-id="{{item.id}}" data-item-uuid="{{item.uuid}}" data-drag="true" > <div class="spell" data-item-id="{{item.id}}" data-item-uuid="{{item.uuid}}" data-drag="true">
<img class="item-img" src="{{item.img}}" data-tooltip="{{item.name}}" /> <img class="item-img" src="{{item.img}}" data-tooltip="{{item.name}}" />
<div class="name" > <div class="name">
{{item.name}} {{item.name}}
</div> </div>
@ -46,5 +48,5 @@
{{/each}} {{/each}}
</div> </div>
</fieldset> </fieldset>
</div>
</section> </section>

View File

@ -6,7 +6,7 @@
</div> </div>
<div class="intro-right"> <div class="intro-right">
<span>{{upperFirst rollName}}</span> <span>{{actingCharName}} - {{upperFirst rollName}}</span>
{{#if (match rollType "attack")}} {{#if (match rollType "attack")}}
<span>Attack roll !</span> <span>Attack roll !</span>

View File

@ -18,7 +18,7 @@
<fieldSet> <fieldSet>
<legend>{{localize "LETHALFANTASY.Roll.visibility"}}</legend> <legend>{{localize "LETHALFANTASY.Roll.visibility"}}</legend>
<select name="visibility"> <select name="visibility">
{{selectOptions rollModes selected=visibility}} {{selectOptions rollModes selected=visibility localize=true}}
</select> </select>
</fieldSet> </fieldSet>

View File

@ -0,0 +1,39 @@
<nav class="combat-controls" data-tooltip-direction="UP">
{{~#if hasCombat~}}
{{!-- GM Controls --}}
{{#if user.isGM}}
{{#if combat.round}}
<!-- <button type="button" class="inline-control combat-control icon fa-solid fa-backward-step"
data-action="previousRound" data-tooltip aria-label="{{ localize "COMBAT.RoundPrev" }}"></button>
<button type="button" class="inline-control combat-control icon fa-solid fa-arrow-left" data-action="previousTurn"
data-tooltip aria-label="{{ localize "COMBAT.TurnPrev" }}"></button> -->
<button type="button" class="combat-control combat-control-lg" data-action="endCombat">
<i class="fa-solid fa-xmark" inert></i>
<span>{{ localize "COMBAT.End" }}</span>
</button>
<!-- <button type="button" class="inline-control combat-control icon fa-solid fa-arrow-right" data-action="nextTurn"
data-tooltip aria-label="{{ localize "COMBAT.TurnNext" }}"></button> -->
<button type="button" class="inline-control combat-control icon fa-solid fa-forward-step" data-action="nextRound"
data-tooltip aria-label="{{ localize "COMBAT.RoundNext" }}"></button>
{{else}}
<button type="button" class="combat-control combat-control-lg" data-action="startCombat">
<i class="fa-solid fa-swords" inert></i>
<span>{{ localize "COMBAT.Begin" }}</span>
</button>
{{/if}}
{{!-- Active Player Controls --}}
{{else if control}}
<!-- <button type="button" class="inline-control combat-control icon fa-solid fa-arrow-left" data-action="previousTurn"
data-tooltip aria-label="{{ localize "COMBAT.TurnPrev" }}"></button>
<button type="button" class="combat-control combat-control-lg" data-action="nextTurn">
<i class="fa-solid fa-check"></i>
<span>{{ localize "COMBAT.TurnEnd" }}</span>
</button>
<button type="button" class="inline-control combat-control icon fa-solid fa-arrow-right" data-action="nextTurn"
data-tooltip aria-label="{{ localize "COMBAT.TurnNext" }}"></button> -->
{{/if}}
{{/if}}
</nav>

View File

@ -0,0 +1,92 @@
<header class="combat-tracker-header">
{{!-- Encounter Controls --}}
{{#if user.isGM}}
<nav class="encounters {{ css }}" aria-label="{{ localize "COMBAT.NavLabel" }}">
{{!-- Cycle Display --}}
{{#if displayCycle}}
<button type="button" class="inline-control icon fa-solid fa-plus" data-action="createCombat"
data-tooltip aria-label="{{ localize "COMBAT.Create" }}"></button>
<div class="cycle-combats">
<button type="button" class="inline-control icon fa-solid fa-caret-left" data-action="cycleCombat"
{{#if previousId}}data-combat-id="{{ previousId }}" {{else}}disabled{{/if}}
data-tooltip aria-label="{{ localize "COMBAT.EncounterPrevious" }}"></button>
<div class="encounter-count">
<span class="value">{{ currentIndex }}</span>
<span class="separator">&sol;</span>
<span class="max">{{ combats.length }}</span>
</div>
<button type="button" class="inline-control icon fa-solid fa-caret-right" data-action="cycleCombat"
{{#if nextId}}data-combat-id="{{ nextId }}" {{else}}disabled{{/if}}
data-tooltip aria-label="{{ localize "COMBAT.EncounterNext" }}"></button>
</div>
<button type="button" class="inline-control icon fa-solid fa-gear" data-action="trackerSettings"
data-tooltip aria-label="{{ localize "COMBAT.Settings" }}"></button>
{{!-- Tabbed Display --}}
{{else if combats.length}}
<button type="button" class="inline-control icon fa-solid fa-plus" data-action="createCombat"
data-tooltip aria-label="{{ localize "COMBAT.Create" }}"></button>
{{#each combats}}
<button type="button" class="inline-control {{#if active}}active{{/if}}" data-action="cycleCombat"
data-combat-id="{{ id }}">
{{ label }}
</button>
{{/each}}
<button type="button" class="inline-control icon fa-solid fa-gear" data-action="trackerSettings"
data-tooltip aria-label="{{ localize "COMBAT.Settings" }}"></button>
{{!-- No Combats --}}
{{else}}
<button type="button" class="combat-control-lg" data-action="createCombat">
<i class="fa-solid fa-plus" inert></i>
<span>{{ localize "COMBAT.Create" }}</span>
</button>
{{/if}}
</nav>
{{/if}}
<div class="encounter-controls {{#if hasCombat}}combat{{/if}}">
{{!-- Bulk Rolls --}}
<div class="control-buttons left flexrow">
{{#if user.isGM}}
<button type="button" class="inline-control combat-control icon fa-solid fa-users" data-action="rollAll"
{{#unless combat.turns.length}}disabled{{/unless}} data-tooltip="COMBAT.RollAll"
aria-label="{{ localize "COMBAT.RollAll" }}"></button>
<button type="button" class="inline-control combat-control icon fa-solid fa-users-cog" data-action="rollNPC"
{{#unless combat.turns.length}}disabled{{/unless}} data-tooltip="COMBAT.RollNPC"
aria-label="{{ localize "COMBAT.RollNPC" }}"></button>
{{else}}
<div class="spacer"></div>
<div class="spacer"></div>
{{/if}}
</div>
{{!-- Combat Status --}}
<strong class="encounter-title">
{{#if combats.length}}
{{#if combat.round}}
{{ localize "COMBAT.Round" round=combat.round }}
{{else}}
{{ localize "COMBAT.NotStarted" }}
{{/if}}
{{else}}
{{ localize "COMBAT.None" }}
{{/if}}
</strong>
{{!-- Combat Controls --}}
<div class="control-buttons right flexrow">
<div class="spacer"></div>
<button type="button" class="encounter-context-menu inline-control combat-control icon fa-solid fa-ellipsis-vertical"
{{#unless (and user.isGM hasCombat)}}disabled{{/unless}}></button>
</div>
</div>
</header>

View File

@ -0,0 +1,81 @@
<ol class="combat-tracker plain">
{{#each turns}}
<li class="combatant {{ css }}" data-combatant-id="{{ id }}" data-action="activateCombatant">
{{!-- TODO: Targets --}}
{{!-- Image --}}
<img class="token-image" src="{{ img }}" alt="{{ name }}" loading="lazy">
{{!-- Name & Controls --}}
<div class="token-name">
<strong class="name">{{ name }}</strong>
<div class="combatant-controls">
{{#if @root.user.isGM}}
<button type="button" class="inline-control combatant-control icon fa-solid fa-eye-slash {{#if hidden}}active{{/if}}"
data-action="toggleHidden" data-tooltip aria-label="{{ localize "COMBAT.ToggleVis" }}"></button>
<button type="button" class="inline-control combatant-control icon fa-solid fa-skull {{#if isDefeated}}active{{/if}}"
data-action="toggleDefeated" data-tooltip
aria-label="{{ localize "COMBAT.ToggleDead" }}"></button>
{{/if}}
{{#if canPing}}
<button type="button" class="inline-control combatant-control icon fa-solid fa-bullseye-arrow"
data-action="pingCombatant" data-tooltip
aria-label="{{ localize "COMBAT.PingCombatant" }}"></button>
{{/if}}
{{#unless @root.user.isGM}}
<button type="button" class="inline-control combatant-control icon fa-solid fa-arrows-to-eye"
data-action="panToCombatant" data-tooltip
aria-label="{{ localize "COMBAT.PanToCombatant" }}"></button>
{{/unless}}
{{!-- TODO: Target Control --}}
<div class="token-effects" data-tooltip-html="{{ effects.tooltip }}">
{{#each effects.icons}}
<img class="token-effect" src="{{ img }}" alt="{{ name }}">
{{/each}}
</div>
</div>
</div>
{{!-- Resource --}}
{{#if resource includeZero=true}}
<div class="token-resource">
<span class="resource">{{ resource }}</span>
</div>
{{/if}}
{{!-- Initiative --}}
<div class="token-initiative initiative-area">
{{#if initiative includeZero=true}}
{{!-- Decimal Initiative --}}
{{#if @root.hasDecimals}}
<span>{{ initiative }}</span>
{{!-- Simple Initiative --}}
{{else}}
<input type="text" class="initiative-input" inputmode="numeric" pattern="^[+=\-]?\d*" value="{{ initiative }}"
aria-label="{{ localize "COMBAT.InitiativeScore" }}" {{#unless @root.user.isGM}}readonly{{/unless}}>
{{/if}}
{{#if isOwner}}
<a data-action="initiativePlus" class="initiative-plus" data-combatant-id="{{this.id}}"><i class="fa-solid fa-hexagon-plus"></i></a>
<a data-action="initiativeMinus" class="initiative-minus" data-combatant-id="{{this.id}}"><i class="fa-solid fa-hexagon-minus"></i></a>
{{/if}}
{{#if isMonster}}
<span class="initiative">-</span>
{{else}}
<span class="initiative" data-tooltip="Current max. progression counter">{{progressionCount}}</span>
{{/if}}
{{!-- Roll Initiative --}}
{{else if isOwner}}
<button type="button" class="combatant-control roll" data-action="rollInitiative" data-tooltip
aria-label="{{ localize "COMBAT.InitiativeRoll" }}"
style="--initiative-icon: url('{{ @root.initiativeIcon.icon }}'); --initiative-icon-hover: url('{{ @root.initiativeIcon.hover }}');"></button>
{{/if}}
</div>
</li>
{{/each}}
</ol>

View File

@ -62,16 +62,16 @@
<div class="monster-save"> <div class="monster-save">
<span class="name"> <span class="name">
<a class="rollable" data-roll-type="save" data-roll-key="contagion"><i <a class="rollable" data-roll-type="save" data-roll-key="contagion"><i
class="lf-roll-small fa-solid fa-dice-d20"></i> class="lf-roll-small fa-solid fa-dice-d20"></i>
{{localize "LETHALFANTASY.Label.saves.contagion"}} {{localize "LETHALFANTASY.Label.saves.contagion"}}
</a> </a>
</span> </span>
{{formField systemFields.saves.fields.contagion.fields.value value=system.saves.contagion.value {{formField systemFields.saves.fields.contagion.fields.value value=system.saves.contagion.value
disabled=isPlayMode}} disabled=isPlayMode}}
<span class="name"> <span class="name">
<a class="rollable" data-roll-type="save" data-roll-key="poison"><i <a class="rollable" data-roll-type="save" data-roll-key="poison"><i
class="lf-roll-small fa-solid fa-dice-d20"></i> class="lf-roll-small fa-solid fa-dice-d20"></i>
{{localize "LETHALFANTASY.Label.saves.poison"}} {{localize "LETHALFANTASY.Label.saves.poison"}}
</a> </a>
</span> </span>
@ -80,7 +80,7 @@
<span class="name"> <span class="name">
<a class="rollable" data-roll-type="save" data-roll-key="paincourage" data-roll-dice="D20" data-tooltip="Pain/Courage check on wound of..."><i <a class="rollable" data-roll-type="save" data-roll-key="paincourage" data-roll-dice="D20" data-tooltip="Pain/Courage check on wound of..."><i
class="lf-roll-small fa-solid fa-dice-d20"></i> class="lf-roll-small fa-solid fa-dice-d20"></i>
{{localize "LETHALFANTASY.Label.saves.paincourage"}} {{localize "LETHALFANTASY.Label.saves.paincourage"}}
</a> </a>
</span> </span>
@ -91,7 +91,7 @@
</span> </span>
</div> </div>
</div> </div>
</fieldset> </fieldset>
@ -157,7 +157,7 @@
<fieldset class="monster-characteristics monster-characteristics-{{ifThen isPlayMode 'play' 'edit'}}"> <fieldset class="monster-characteristics monster-characteristics-{{ifThen isPlayMode 'play' 'edit'}}">
<legend>{{localize "LETHALFANTASY.Label.characteristics"}}</legend> <legend>{{localize "LETHALFANTASY.Label.characteristics"}}</legend>
<div class="monster-characteristic"> <div class="monster-characteristic">
{{localize "LETHALFANTASY.Label.int"}} <span>x{{localize "LETHALFANTASY.Label.int"}}</span>
{{formField systemFields.characteristics.fields.int.fields.value value=system.characteristics.int.value {{formField systemFields.characteristics.fields.int.fields.value value=system.characteristics.int.value
disabled=isPlayMode data-char-id="int" }} disabled=isPlayMode data-char-id="int" }}
@ -165,7 +165,7 @@
disabled=isPlayMode type="number" }} disabled=isPlayMode type="number" }}
</div> </div>
<div class="monster-characteristic"> <div class="monster-characteristic">
{{localize "LETHALFANTASY.Label.dex"}} <span>{{localize "LETHALFANTASY.Label.dex"}}</span>
{{formField systemFields.characteristics.fields.dex.fields.value value=system.characteristics.dex.value {{formField systemFields.characteristics.fields.dex.fields.value value=system.characteristics.dex.value
disabled=isPlayMode data-char-id="wis" }} disabled=isPlayMode data-char-id="wis" }}

View File

@ -1,79 +0,0 @@
<section>
{{!log "opponent sheet" this}}
<div class="opponent-header">
<img class="opponent-img" src="{{actor.img}}" data-edit="img" data-action="editImage" data-tooltip="{{actor.name}}" />
{{formInput fields.name value=source.name}}
<a class="control" data-action="toggleSheet" data-tooltip="TENEBRIS.ToggleSheet" data-tooltip-direction="UP">
<i class="fa-solid fa-user-{{ifThen isPlayMode 'lock' 'pen'}}"></i>
</a>
</div>
<div class="opponent-main">
<div class="opponent-gauche">
<fieldset class="opponent-caracteristiques">
<legend>{{localize "TENEBRIS.Character.Label.caracteristiques"}}</legend>
{{formField systemFields.dv value=system.dv disabled=isPlayMode}}
{{formField systemFields.pv.fields.value value=system.pv.value}}
{{formField systemFields.pv.fields.max value=system.pv.max disabled=isPlayMode}}
{{formField systemFields.armure value=system.armure disabled=isPlayMode}}
{{formField systemFields.malus value=system.malus disabled=isPlayMode}}
{{formField systemFields.actions value=system.actions disabled=isPlayMode}}
</fieldset>
<fieldset class="opponent-attacks">
<legend>{{localize "TENEBRIS.Character.Label.attaques"}}
{{#if isEditMode}}<a class="action" data-tooltip="{{localize 'TENEBRIS.Tooltip.addAttack'}}" data-tooltip-direction="UP"><i
class="fas fa-plus"
data-action="createAttack"
></i></a>{{/if}}</legend>
{{#each attacks as |attack|}}
<div class="opponent-attack" data-drag="true" data-drag-type="attack" data-roll-value="{{attack.system.degats}}" data-roll-target="{{attack.name}}">
<div class="attack-name">
<a
class="rollable"
data-item-id="{{attack.id}}"
data-item-name="{{attack.name}}"
data-action="roll"
data-roll-type="attack"
data-roll-value="{{attack.system.degats}}"
>{{attack.system.degats}}</a>
(<span data-tooltip="{{attack.system.toolTip}}">{{attack.name}}</span>)
</div>
{{#if @root.isEditMode}}
<div class="controls">
<a data-tooltip="{{localize 'TENEBRIS.Edit'}}" data-action="edit" data-item-id="{{attack.id}}" data-item-uuid="{{attack.uuid}}"><i class="fas fa-edit"></i></a>
<a data-tooltip="{{localize 'TENEBRIS.Delete'}}" data-action="delete" data-item-id="{{attack.id}}" data-item-uuid="{{attack.uuid}}"><i class="fas fa-trash"></i></a>
</div>
{{/if}}
</div>
{{/each}}
</fieldset>
{{#if (or isEditMode (and isPlayMode hasSpells))}}
<fieldset class="opponent-spells">
<legend>{{localize "TENEBRIS.Label.spells"}}{{#if isEditMode}}<a class="action" data-tooltip="{{localize "TENEBRIS.Tooltip.addSpell"}}" data-tooltip-direction="UP"><i class="fas fa-plus" data-action="createSpell"></i></a>{{/if}}</legend>
{{#each spells as |spell|}}
<div class="opponent-spell">
<div class="name" data-tooltip="{{{spell.system.description}}}">
{{spell.name}}
</div>
{{#if @root.isEditMode}}
<div class="controls">
<a data-tooltip="{{localize 'TENEBRIS.Edit'}}" data-action="edit" data-item-id="{{spell.id}}" data-item-uuid="{{spell.uuid}}"><i class="fas fa-edit"></i></a>
<a data-tooltip="{{localize 'TENEBRIS.Delete'}}" data-action="delete" data-item-id="{{spell.id}}" data-item-uuid="{{spell.uuid}}"><i class="fas fa-trash"></i></a>
</div>
{{/if}}
</div>
{{/each}}
</fieldset>
{{/if}}
</div>
<div class="opponent-droite">
<fieldset class="opponent-description">
<legend>{{localize "TENEBRIS.Label.description"}}</legend>
{{formInput systemFields.description enriched=enrichedDescription value=system.description name="system.description" toggled=true compact=true}}
</fieldset>
</div>
</div>
</section>

View File

@ -26,7 +26,7 @@
<div class="field-section"> <div class="field-section">
<span class="field-name">Range :</span> <span class="field-name">Range :</span>
<select name="range" data-tooltip-direction="UP"> <select name="range" data-tooltip-direction="UP">
{{selectOptions rangeChoices selected=range}} {{selectOptions rangeChoices selected=range}}
</select> </select>
@ -34,7 +34,7 @@
<div class="field-section"> <div class="field-section">
<span class="field-name">Aim :</span> <span class="field-name">Aim :</span>
<select name="attackerAim" data-tooltip-direction="UP"> <select name="attackerAim" data-tooltip-direction="UP">
{{selectOptions attackerAimChoices selected=attackerAim}} {{selectOptions attackerAimChoices selected=attackerAim}}
</select> </select>
@ -45,7 +45,7 @@
<fieldSet> <fieldSet>
<legend>{{localize "LETHALFANTASY.Roll.visibility"}}</legend> <legend>{{localize "LETHALFANTASY.Roll.visibility"}}</legend>
<select name="visibility"> <select name="visibility">
{{selectOptions rollModes selected=visibility}} {{selectOptions rollModes selected=visibility localize=true}}
</select> </select>
</fieldSet> </fieldSet>

View File

@ -90,7 +90,7 @@
<fieldSet> <fieldSet>
<legend>{{localize "LETHALFANTASY.Roll.visibility"}}</legend> <legend>{{localize "LETHALFANTASY.Roll.visibility"}}</legend>
<select name="visibility"> <select name="visibility">
{{selectOptions rollModes selected=visibility}} {{selectOptions rollModes selected=visibility localize=true}}
</select> </select>
</fieldSet> </fieldSet>

View File

@ -13,8 +13,8 @@
<fieldSet> <fieldSet>
<legend>{{localize "LETHALFANTASY.Roll.visibility"}}</legend> <legend>{{localize "LETHALFANTASY.Roll.visibility"}}</legend>
<select name="visibility"> <select name="visibility">
{{selectOptions rollModes selected=visibility}} {{selectOptions rollModes selected=visibility localize=true}}
</select> </select>
</fieldSet> </fieldSet>
</div> </div>

View File

@ -13,8 +13,8 @@
<fieldSet> <fieldSet>
<legend>{{localize "LETHALFANTASY.Roll.visibility"}}</legend> <legend>{{localize "LETHALFANTASY.Roll.visibility"}}</legend>
<select name="visibility"> <select name="visibility">
{{selectOptions rollModes selected=visibility}} {{selectOptions rollModes selected=visibility localize=true}}
</select> </select>
</fieldSet> </fieldSet>
</div> </div>