20 Commits

Author SHA1 Message Date
fa3054f24b Some granted dice/favor fixes
All checks were successful
Release Creation / build (release) Successful in 2m48s
2025-10-01 17:17:33 +02:00
59a891630e Fix tooltip
All checks were successful
Release Creation / build (release) Successful in 38s
2025-09-20 09:34:13 +02:00
35b88b3914 Poison/Contagion fixes again
All checks were successful
Release Creation / build (release) Successful in 42s
2025-09-19 23:32:15 +02:00
cb8bcfd9ea Ranged defense fixes again
All checks were successful
Release Creation / build (release) Successful in 43s
2025-09-19 22:30:26 +02:00
eedce1a498 Latest fixes
All checks were successful
Release Creation / build (release) Successful in 46s
2025-09-17 07:47:40 +02:00
76a99fe33f Various fixes 2025-09-16 23:49:02 +02:00
59a39850ce Fix miracle/spell rolls + upadte compendiums
All checks were successful
Release Creation / build (release) Successful in 56s
2025-09-09 20:14:25 +02:00
6eeb391d1a Move aiming to attacker
All checks were successful
Release Creation / build (release) Successful in 1m9s
2025-09-05 23:26:11 +02:00
c7727076bf Various fixes and renamingé
All checks were successful
Release Creation / build (release) Successful in 1m30s
2025-09-02 21:06:33 +02:00
d0411f9ec9 Various fixes and renamingé 2025-09-02 18:17:31 +02:00
e5653a4edc Latest modifications & changes
All checks were successful
Release Creation / build (release) Successful in 1m47s
2025-08-31 11:28:52 +02:00
527e33a805 Roll D12 for monsters, with enabled fields for attacks
All checks were successful
Release Creation / build (release) Successful in 1m22s
2025-06-10 20:37:46 +02:00
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
90 changed files with 1638 additions and 952 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": {
"Round": "Second",
"Round": "Second {round}",
"Rounds": "Seconds",
"RoundNext": "Next second"
},
@@ -83,7 +83,7 @@
},
"challenges": {
"agility": {
"label": "Agility"
"label": "Dexterity"
},
"dying": {
"label": "Dying"
@@ -181,7 +181,7 @@
},
"challenges": {
"agility": {
"label": "Agility"
"label": "Dexterity"
},
"dying": {
"label": "Dying"
@@ -281,6 +281,7 @@
}
},
"Label": {
"agility": "Dexterity",
"gotoToken": "Go to token",
"combatAction": "Combat action",
"currentAction": "Current ongoing action",
@@ -348,7 +349,7 @@
"cha": "CHA",
"challenge": "Challenge",
"challenges": {
"agility": "Agility",
"agility": "Dexterity",
"dying": "Dying",
"strength": "Strength"
},

View File

@@ -11,12 +11,12 @@ import * as models from "./module/models/_module.mjs"
import * as documents from "./module/documents/_module.mjs"
import * as applications from "./module/applications/_module.mjs"
import { LethalFantasyCombatTracker, LethalFantasyCombat} from "./module/applications/combat.mjs"
import { LethalFantasyCombatTracker, LethalFantasyCombat } from "./module/applications/combat.mjs"
import { Macros } from "./module/macros.mjs"
import { setupTextEnrichers } from "./module/enrichers.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 () {
console.info("Lethal Fantasy RPG | Initializing System")
@@ -55,20 +55,20 @@ Hooks.once("init", function () {
}
// Register sheet application classes
Actors.unregisterSheet("core", ActorSheet)
Actors.registerSheet("lethalFantasy", applications.LethalFantasyCharacterSheet, { types: ["character"], makeDefault: true })
Actors.registerSheet("lethalFantasy", applications.LethalFantasyMonsterSheet, { types: ["monster"], makeDefault: true })
foundry.documents.collections.Actors.unregisterSheet("core", foundry.appv1.sheets.ActorSheet)
foundry.documents.collections.Actors.registerSheet("lethalFantasy", applications.LethalFantasyCharacterSheet, { types: ["character"], makeDefault: true })
foundry.documents.collections.Actors.registerSheet("lethalFantasy", applications.LethalFantasyMonsterSheet, { types: ["monster"], makeDefault: true })
Items.unregisterSheet("core", ItemSheet)
Items.registerSheet("lethalFantasy", applications.LethalFantasySkillSheet, { types: ["skill"], makeDefault: true })
Items.registerSheet("lethalFantasy", applications.LethalFantasyGiftSheet, { types: ["gift"], makeDefault: true })
Items.registerSheet("lethalFantasy", applications.LethalFantasyVulnerabilitySheet, { types: ["vulnerability"], makeDefault: true })
Items.registerSheet("lethalFantasy", applications.LethalFantasyWeaponSheet, { types: ["weapon"], makeDefault: true })
Items.registerSheet("lethalFantasy", applications.LethalFantasySpellSheet, { types: ["spell"], makeDefault: true })
Items.registerSheet("lethalFantasy", applications.LethalFantasyArmorSheet, { types: ["armor"], makeDefault: true })
Items.registerSheet("lethalFantasy", applications.LethalFantasyShieldSheet, { types: ["shield"], makeDefault: true })
Items.registerSheet("lethalFantasy", applications.LethalFantasyEquipmentSheet, { types: ["equipment"], makeDefault: true })
Items.registerSheet("lethalFantasy", applications.LethalFantasyMiracleSheet, { types: ["miracle"], makeDefault: true })
foundry.documents.collections.Items.unregisterSheet("core", foundry.appv1.sheets.ActorSheet)
foundry.documents.collections.Items.registerSheet("lethalFantasy", applications.LethalFantasySkillSheet, { types: ["skill"], makeDefault: true })
foundry.documents.collections.Items.registerSheet("lethalFantasy", applications.LethalFantasyGiftSheet, { types: ["gift"], makeDefault: true })
foundry.documents.collections.Items.registerSheet("lethalFantasy", applications.LethalFantasyVulnerabilitySheet, { types: ["vulnerability"], makeDefault: true })
foundry.documents.collections.Items.registerSheet("lethalFantasy", applications.LethalFantasyWeaponSheet, { types: ["weapon"], makeDefault: true })
foundry.documents.collections.Items.registerSheet("lethalFantasy", applications.LethalFantasySpellSheet, { types: ["spell"], makeDefault: true })
foundry.documents.collections.Items.registerSheet("lethalFantasy", applications.LethalFantasyArmorSheet, { types: ["armor"], makeDefault: true })
foundry.documents.collections.Items.registerSheet("lethalFantasy", applications.LethalFantasyShieldSheet, { types: ["shield"], makeDefault: true })
foundry.documents.collections.Items.registerSheet("lethalFantasy", applications.LethalFantasyEquipmentSheet, { types: ["equipment"], makeDefault: true })
foundry.documents.collections.Items.registerSheet("lethalFantasy", applications.LethalFantasyMiracleSheet, { types: ["miracle"], makeDefault: true })
// Other Document Configuration
CONFIG.ChatMessage.documentClass = documents.LethalFantasyChatMessage
@@ -89,13 +89,13 @@ Hooks.once("init", function () {
setupTextEnrichers()
LethalFantasyUtils.registerHandlebarsHelpers()
LethalFantasyUtils.setHookListeners( )
LethalFantasyUtils.setHookListeners()
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() {
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 () {
@@ -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
// Message de demande de jet de dés
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) {
let data = await super.getData(options);
for (let u of data.turns) {
static PARTS = {
"header": {
"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);
u.progressionCount = c.system.progressionCount
u.isMonster = c.actor.type === "monster"
}
console.log("Combat Data", data);
console.log("Combat Data", 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) {
super.activateListeners(html);
// Display Combat settings
@@ -21,7 +57,6 @@ export class LethalFantasyCombatTracker extends CombatTracker {
let cId = ev.currentTarget.closest(".combatant").dataset.combatantId;
let c = game.combat.combatants.get(cId);
c.update({ 'initiative': c.initiative + 1 });
console.log("Initiative Plus");
});
html.find(".initiative-minus").click(ev => {
@@ -160,10 +195,10 @@ export class LethalFantasyCombat extends Combat {
}
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);
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 {
user = game.users.find(u => u.active && u.isGM);
c.actor.system.rollProgressionDice(this.id, c.id);

View File

@@ -23,7 +23,7 @@ export default class LethalFantasyArmorSheet extends LethalFantasyItemSheet {
/** @override */
async _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
}

View File

@@ -67,7 +67,7 @@ export default class LethalFantasyActorSheet extends HandlebarsApplicationMixin(
actor: this.document,
system: this.document.system,
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,
isPlayMode: this.isPlayMode,
isEditable: this.isEditable,
@@ -100,7 +100,7 @@ export default class LethalFantasyActorSheet extends HandlebarsApplicationMixin(
dragover: this._onDragOver.bind(this),
drop: this._onDrop.bind(this),
}
return new DragDrop(d)
return new foundry.applications.ux.DragDrop.implementation(d)
})
}
@@ -140,7 +140,7 @@ export default class LethalFantasyActorSheet extends HandlebarsApplicationMixin(
if ("link" in event.target.dataset) return
const el = event.currentTarget.closest('[data-drag="true"]')
const dragType = el.dataset.dragType
const dragType = el?.dataset?.dragType
let dragData = {}

View File

@@ -58,22 +58,22 @@ export default class LethalFantasyItemSheet extends HandlebarsApplicationMixin(f
/** @override */
async _prepareContext() {
const context = {
fields: this.document.schema.fields,
systemFields: this.document.system.schema.fields,
item: this.document,
system: this.document.system,
source: this.document.toObject(),
enrichedDescription: await TextEditor.enrichHTML(this.document.system.description, { async: true }),
isEditMode: this.isEditMode,
isPlayMode: this.isPlayMode,
isEditable: this.isEditable,
}
let context = await super._prepareContext()
context.fields = this.document.schema.fields
context.systemFields = this.document.system.schema.fields
context.item = this.document
context.system = this.document.system
context.source = this.document.toObject()
context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description, { async: true })
context.isEditMode = this.isEditMode
context.isPlayMode = this.isPlayMode
context.isEditable = this.isEditable
return context
}
/** @override */
_onRender(context, options) {
super._onRender(context, options)
this.#dragDrop.forEach((d) => d.bind(this.element))
}
@@ -94,7 +94,7 @@ export default class LethalFantasyItemSheet extends HandlebarsApplicationMixin(f
dragover: this._onDragOver.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
}
_generateTooltip(type, target) {
}
/** @override */
async _preparePartContext(partId, context) {
const doc = this.document
@@ -127,8 +124,8 @@ export default class LethalFantasyCharacterSheet extends LethalFantasyActorSheet
break
case "biography":
context.tab = context.tabs.biography
context.enrichedDescription = await TextEditor.enrichHTML(doc.system.description, { async: true })
context.enrichedNotes = await TextEditor.enrichHTML(doc.system.notes, { async: true })
context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(doc.system.description, { async: true })
context.enrichedNotes = await foundry.applications.ux.TextEditor.implementation.enrichHTML(doc.system.notes, { async: true })
break
}
return context
@@ -143,18 +140,17 @@ export default class LethalFantasyCharacterSheet extends LethalFantasyActorSheet
*/
async _onDrop(event) {
if (!this.isEditable || !this.isEditMode) return
const data = TextEditor.getDragEventData(event)
const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event)
// Handle different data types
switch (data.type) {
case "Item":
const item = await fromUuid(data.uuid)
return this._onDropItem(item)
if (data.type === "Item") {
const item = await fromUuid(data.uuid)
return this._onDropItem(item)
}
}
static async #onRangedAttackDefense(event, target) {
const hasTarget = false
// Future use : const hasTarget = false
let roll = await LethalFantasyRoll.promptRangedDefense({
actorId: this.actor.id,

View File

@@ -22,7 +22,7 @@ export default class LethalFantasyEquipmentSheet extends LethalFantasyItemSheet
/** @override */
async _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
}
}

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 */
async _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
}

View File

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

View File

@@ -22,7 +22,7 @@ export default class LethalFantasyShieldSheet extends LethalFantasyItemSheet {
/** @override */
async _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
}
}

View File

@@ -22,7 +22,7 @@ export default class LethalFantasySkillSheet extends LethalFantasyItemSheet {
/** @override */
async _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
}
}

View File

@@ -22,7 +22,7 @@ export default class LethalFantasySpellSheet extends LethalFantasyItemSheet {
/** @override */
async _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
}

View File

@@ -22,7 +22,7 @@ export default class LethalFantasyVulnerabilitySheet extends LethalFantasyItemSh
/** @override */
async _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
}
}

View File

@@ -18,11 +18,11 @@ export default class LethalFantasyWeaponSheet extends LethalFantasyItemSheet {
template: "systems/fvtt-lethal-fantasy/templates/weapon.hbs",
},
}
/** @override */
async _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
}

View File

@@ -44,118 +44,121 @@ export const MONEY = {
}
export const MORTAL_CHOICES = {
"mankind": {label: "Mankind", value: "Mankind", defenseBonus: 0},
"elf": {label: "Elf", value: "Elf", defenseBonus: 0},
"dwarf": {label: "Dwarf", value: "Dwarf", defenseBonus: 0},
"halfelf": {label: "Half-Elf", value: "Half-Elf", defenseBonus: 0},
"halforc": {label: "Half-Orc", value: "Half-Orc", defenseBonus: 0},
"gnome": {label: "Gnome", value: "Gnome", defenseBonus: 2},
"shirefolk": {label: "Shire Folk", value: "Shire Folk", 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},
"mankind": { label: "Mankind", id: "mankind", defenseBonus: 0 },
"elf": { label: "Elf", id: "elf", defenseBonus: 0 },
"dwarf": { label: "Dwarf", id: "dwarf", defenseBonus: 0 },
"halfelf": { label: "Half-Elf", id: "halfelf", defenseBonus: 0 },
"halforc": { label: "Half-Orc", id: "halforc", defenseBonus: 0 },
"gnome": { label: "Gnome", id: "gnome", defenseBonus: 2 },
"halflings": { label: "Halfling", id: "halflings", defenseBonus: 2 }
}
export const FAVOR_CHOICES = {
"none": {label: "None", value: "none"},
"favor": {label: "Favor", value: "favor"},
"disfavor": {label: "Disfavor", value: "disfavor"}
"none": { label: "None", value: "none" },
"favor": { label: "Favor", value: "favor" },
"disfavor": { label: "Disfavor", value: "disfavor" }
}
export const MOVEMENT_CHOICES = {
"none": {label: "None (D8E)", value: "D8"},
"walk": {label: "Walk (D10E)", value: "D10"},
"jog": {label: "Jog (D12E)", value: "D12"},
"run": {label: "Run (D20E)", value: "D20"},
"incombat": {label: "In Combat (D12E)", value: "D12"}
"none": { label: "None (D20E Disfavor)", disfavor: true, value: "2D20kl" },
"walk": { label: "Walk (D20E)", disfavor: true, value: "D20" },
"incombat": { label: "In Combat (D20E)", favor: false, value: "D20" },
"run": { label: "Jog/Run/Sprint (D20E Favor)", favor: true, value: "2D20kh" }
}
export const MOVE_DIRECTION_CHOICES = {
"none": {label: "None (+0)", value: "0"},
"away": {label: "Away (+4)", value: "+4"},
"toward": {label: "Toward (+0)", value: "0"},
"lateral": {label: "Lateral (+10)", value: "+10"}
"away": { label: "Away (+0)", value: "+0" },
"toward": { label: "Toward (0)", value: "0" },
"lateral": { label: "Lateral (Red +5)", value: "+5" },
"none": { label: "None (+0)", value: "0" },
}
export const SIZE_CHOICES = {
"tiny": {label: "Tiny (+10)", value: "+10"},
"small": {label: "Small (+5)", value: "+5"},
"medium": {label: "Medium (+0)", value: "0"},
"huge": {label: "Huge (-10)", value: "-10"}
"tiny": { label: "Tiny (Blue +11)", value: "+11" },
"small": { label: "Small (Purple +7)", value: "+7" },
"medium": { label: "Medium (Red +5)", value: "+5" },
"large": { label: "Large (Yellow +1)", value: "+1" },
"huge": { label: "Huge (0)", value: "0" }
}
export const RANGE_CHOICES = {
"pointblank": {label: "Point Blank (-5)", value: "-5"},
"short": {label: "Short (+0)", value: "0"},
"medium": {label: "Medium (+8)", value: "+8"},
"long": {label: "Long (+15)", value: "+15"},
"extreme": {label: "Extreme (+20)", value: "+20"},
"beyondskill": {label: "Beyond Skill (+25)", value: "+25"}
"pointblank": { label: "Point Blank (Special)", value: "pointblank" },
"short": { label: "Short (+0)", value: "0" },
"medium": { label: "Medium (Red +5)", value: "+5" },
"long": { label: "Long (Purle +7)", value: "+7" },
"extreme": { label: "Extreme (Grey +9)", value: "+9" },
"beyondskill": { label: "Beyond Skill (Blue +11)", value: "beyondskill" }
}
export const ATTACKER_AIM_CHOICES = {
"simple": {label: "Simple (+0)", value: "0"},
"careful": {label: "Careful (-4)", value: "-4"},
"focused": {label: "Focused (-8)", value: "-8"}
"simple": { label: "Simple (+0)", value: "0" },
"careful": { label: "Careful (Red +5)", value: "+4" },
"focused": { label: "Focused (Grey +9)", value: "+9" }
}
export const SPELL_LETHARGY_DICE = [
{dice: "D6", level: "1-5", value: "6", maxLevel: 5},
{dice: "D8", level: "6-10", value: "8", maxLevel: 10},
{dice: "D10", value: "10", level: "11-15", maxLevel: 15},
{dice: "D12", value: "12", level: "16-20", maxLevel: 20},
{dice: "D20", value: "20", level: "21-25", maxLevel: 25}
{ dice: "D6", level: "1-5", value: "6", maxLevel: 5 },
{ dice: "D8", level: "6-10", value: "8", maxLevel: 10 },
{ dice: "D10", value: "10", level: "11-15", maxLevel: 15 },
{ dice: "D12", value: "12", level: "16-20", maxLevel: 20 },
{ dice: "D20", value: "20", level: "21-25", maxLevel: 25 }
]
export const GRANTED_DICE_CHOICES = {
"0": { label: "None", value: "0" },
"D2": { label: "D2", value: "D2" },
"D3": { label: "D3", value: "D3" },
"D4": { label: "D4", value: "D4" },
"D6": { label: "D6", value: "D6" },
"D8": { label: "D8", value: "D8" },
"D10": { label: "D10", value: "D10" },
"D12": { label: "D12", value: "D12" },
"D20": { label: "D20", value: "D20" }
}
export const INITIATIVE_DICE_CHOICES_PER_CLASS = {
"untrained": [
{ "name": "Asleep or totally distracted (2D12)", "value": "2D12" },
{ "name": "Awake but unsuspecting (2D8)", "value": "2D8" },
{ "name": "Declared Ready on Alert (2D6)", "value": "2D6" },
{ "name": "Aware of the enemy, can hear them but not see (2D4)", "value": "2D4" },
{ "name": "Aware and know exactly where the enemy is (2D3)", "value": "2D3" }
/*{ "name": "Aware of the enemy, can hear them but not see (2D4)", "value": "2D4" },
{ "name": "Aware and know exactly where the enemy is (2D3)", "value": "2D3" }*/
],
"fighter": [
{ "name": "Asleep or totally distracted (1D12)", "value": "1D12" },
{ "name": "Awake but unsuspecting (1D8)", "value": "1D8" },
{ "name": "Declared Ready on Alert (1D6)", "value": "1D6" },
{ "name": "Aware of the enemy, can hear them but not see (1D4)", "value": "1D4" },
{ "name": "Aware and know exactly where the enemy is (1D3)", "value": "1D3" }
{ "name": "Declared Ready on Alert (1)", "value": "1" },
/*{ "name": "Aware of the enemy, can hear them but not see (1D4)", "value": "1D4" },
{ "name": "Aware and know exactly where the enemy is (1D3)", "value": "1D3" }*/
],
"rogue": [
{ "name": "Asleep or totally distracted (1D10)", "value": "1D10" },
{ "name": "Awake but unsuspecting (1D8)", "value": "1D8" },
{ "name": "Declared Ready on Alert (1D6)", "value": "1D6" },
{ "name": "Aware of the enemy, can hear them but not see (1D3)", "value": "1D3" },
{ "name": "Aware and know exactly where the enemy is (1D2)", "value": "1D2" }
{ "name": "Declared Ready on Alert (1)", "value": "1" },
/*{ "name": "Aware of the enemy, can hear them but not see (1D3)", "value": "1D3" },
{ "name": "Aware and know exactly where the enemy is (1D2)", "value": "1D2" }*/
],
"ranger": [
{ "name": "Asleep or totally distracted (1D10)", "value": "1D10" },
{ "name": "Awake but unsuspecting (1D8)", "value": "1D8" },
{ "name": "Declared Ready on Alert (1D6)", "value": "1D6" },
{ "name": "Aware of the enemy, can hear them but not see (1D4)", "value": "1D4" },
{ "name": "Aware and know exactly where the enemy is (1D3)", "value": "1D3"}
{ "name": "Declared Ready on Alert (1)", "value": "1" },
/*{ "name": "Aware of the enemy, can hear them but not see (1D4)", "value": "1D4" },
{ "name": "Aware and know exactly where the enemy is (1D3)", "value": "1D3" }*/
],
"cleric": [
{ "name": "Asleep or totally distracted (1D12)", "value": "1D12" },
{ "name": "Awake but unsuspecting (1D10)", "value": "1D10" },
{ "name": "Declared Ready on Alert (1D8)", "value": "1D8" },
{ "name": "Aware of the enemy, can hear them but not see (1D6)", "value": "1D6" },
{ "name": "Aware and know exactly where the enemy is (1D4)", "value": "1D4" }
{ "name": "Declared Ready on Alert (1)", "value": "1" },
/*{ "name": "Aware of the enemy, can hear them but not see (1D6)", "value": "1D6" },
{ "name": "Aware and know exactly where the enemy is (1D4)", "value": "1D4" }*/
],
"magicuser": [
{ "name": "Sleeping to recover Aether Points (2D20)", "value": "2D20" },
{ "name": "Asleep or totally distracted (1D20)", "value": "1D20" },
{ "name": "Awake but unsuspecting (1D12)", "value": "1D12" },
{ "name": "Declared Ready on Alert (1D10)", "value": "1D10" },
{ "name": "Aware of the enemy, can hear them but not see (1D8)", "value": "1D8" },
{ "name": "Aware and know exactly where the enemy is (1D6)", "value": "1D6" }
{ "name": "Declared Ready on Alert (1)", "value": "1" },
/*{ "name": "Aware of the enemy, can hear them but not see (1D8)", "value": "1D8" },
{ "name": "Aware and know exactly where the enemy is (1D6)", "value": "1D6" }*/
]
}
@@ -169,12 +172,12 @@ export const CHAR_CLASSES = {
}
export const CHAR_CLASSES_DEFINES = {
"untrained": {id: "untrained", label: "Untrained"},
"fighter": {id: "fighter", label: "Fighter"},
"rogue": {id: "rogue", label: "Rogue"},
"ranger": {id: "ranger", label: "Ranger"},
"cleric": {id: "cleric", label: "Cleric"},
"magicuser": {id: "magicuser", label: "Magic User"}
"untrained": { id: "untrained", label: "Untrained" },
"fighter": { id: "fighter", label: "Fighter" },
"rogue": { id: "rogue", label: "Rogue" },
"ranger": { id: "ranger", label: "Ranger" },
"cleric": { id: "cleric", label: "Cleric" },
"magicuser": { id: "magicuser", label: "Magic User" }
}
export const DICE_VALUES = {
@@ -187,10 +190,10 @@ export const DICE_VALUES = {
"d20": "D20"
}
export const CHARACTERISTIC_ATTACK = [ "str", "int", "wis", "dex"]
export const CHARACTERISTIC_RANGED_ATTACK = [ "int", "wis", "dex"]
export const CHARACTERISTIC_DEFENSE = [ "int", "wis", "dex" ]
export const CHARACTERISTIC_DAMAGE = [ "str" ]
export const CHARACTERISTIC_ATTACK = ["str", "int", "wis", "dex"]
export const CHARACTERISTIC_RANGED_ATTACK = ["int", "wis", "dex"]
export const CHARACTERISTIC_DEFENSE = ["int", "wis", "dex"]
export const CHARACTERISTIC_DAMAGE = ["str"]
export const DEFENSE_DICE_VALUES = {
"0": "0",
@@ -226,41 +229,41 @@ export const SPELL_CRITICAL = {
}
export const CHOICE_MODIFIERS = {
"-9": "-9",
"-8": "-8",
"-7": "-7",
"-6": "-6",
"-5": "-5",
"-4": "-4",
"-3": "-3",
"-2": "-2",
"-1": "-1",
"+0": "0",
"+1": "+1",
"+2": "+2",
"+3": "+3",
"+4": "+4",
"+5": "+5",
"+6": "+6",
"+7": "+7",
"+8": "+8",
"+9": "+9",
"+10": "+10",
"+11": "+11",
"+12": "+12",
"+13": "+13",
"+14": "+14",
"+15": "+15",
"+16": "+16",
"+17": "+17",
"+18": "+18",
"+19": "+19",
"+20": "+20",
"+21": "+21",
"+22": "+22",
"+23": "+23",
"+24": "+24",
"+25": "+25"
"-9": "-9",
"-8": "-8",
"-7": "-7",
"-6": "-6",
"-5": "-5",
"-4": "-4",
"-3": "-3",
"-2": "-2",
"-1": "-1",
"+0": "0",
"+1": "+1",
"+2": "+2",
"+3": "+3",
"+4": "+4",
"+5": "+5",
"+6": "+6",
"+7": "+7",
"+8": "+8",
"+9": "+9",
"+10": "+10",
"+11": "+11",
"+12": "+12",
"+13": "+13",
"+14": "+14",
"+15": "+15",
"+16": "+16",
"+17": "+17",
"+18": "+18",
"+19": "+19",
"+20": "+20",
"+21": "+21",
"+22": "+22",
"+23": "+23",
"+24": "+24",
"+25": "+25"
}
export const ASCII = `
@@ -319,5 +322,6 @@ export const SYSTEM = {
MORTAL_CHOICES,
SPELL_CRITICAL,
MIRACLE_TYPES,
SPELL_LETHARGY_DICE
SPELL_LETHARGY_DICE,
GRANTED_DICE_CHOICES
}

View File

@@ -96,6 +96,10 @@ export default class LethalFantasyRoll extends Roll {
return this.options.badResult
}
get rollData() {
return this.options.rollData
}
/**
* Prompt the user with a dialog to configure and execute a roll.
*
@@ -124,6 +128,10 @@ export default class LethalFantasyRoll extends Roll {
let hasFavor = false
let hasMaxValue = true
let hasGrantedDice = false
let pointBlank = false
let letItFly = false
let saveSpell = false
let beyondSkill = false
let hasStaticModifier = false
let hasExplode = true
@@ -132,13 +140,11 @@ export default class LethalFantasyRoll extends Roll {
hasD30 = options.rollType === "save"
if (options.rollTarget.rollKey === "dying") {
dice = options.rollTarget.value
maxValue = Number(options.rollTarget.value.match(/\d+/)[0])
hasModifier = false
hasChangeDice = true
hasFavor = true
} else {
dice = "1D20"
maxValue = 20
hasFavor = true
}
@@ -148,7 +154,6 @@ export default class LethalFantasyRoll extends Roll {
dice = options.rollTarget.formula
baseFormula = options.rollTarget.formula
hasModifier = false
maxValue = 100
hasMaxValue = false
hasChangeDice = false
hasFavor = false
@@ -158,7 +163,6 @@ export default class LethalFantasyRoll extends Roll {
options.rollName = options.rollTarget.name
dice = "1D20"
baseFormula = "D20"
maxValue = 20
hasModifier = true
hasChangeDice = false
hasFavor = true
@@ -172,29 +176,27 @@ export default class LethalFantasyRoll extends Roll {
} else if (options.rollType === "monster-skill") {
options.rollName = game.i18n.localize(`LETHALFANTASY.Label.${options.rollTarget.rollKey}`)
dice = "1D100"
baseFormula = "D100"
maxValue = 100
dice = "1D20"
baseFormula = "D20"
hasModifier = true
hasFavor = true
hasChangeDice = false
} else if (options.rollType === "skill") {
options.rollName = options.rollTarget.name
dice = "1D100"
baseFormula = "D100"
maxValue = 100
hasD30 = true
dice = "1D20"
baseFormula = "D20"
hasModifier = true
hasFavor = true
hasChangeDice = false
options.rollTarget.value = options.rollTarget.system.skillTotal
options.rollTarget.value = Math.floor(options.rollTarget.system.skillTotal / 10)
} else if (options.rollType === "weapon-attack" || options.rollType === "weapon-defense") {
hasD30 = true
options.rollName = options.rollTarget.name
dice = "1D20"
baseFormula = "D20"
maxValue = 20
hasModifier = true
hasChangeDice = false
hasFavor = true
@@ -216,7 +218,6 @@ export default class LethalFantasyRoll extends Roll {
options.rollName = options.rollTarget.name
dice = "1D20"
baseFormula = "D20"
maxValue = 20
hasModifier = true
hasChangeDice = false
options.rollTarget.value = options.rollTarget.actorModifiers.levelSpellModifier + options.rollTarget.actorModifiers.intSpellModifier
@@ -234,7 +235,6 @@ export default class LethalFantasyRoll extends Roll {
options.rollName = options.rollTarget.name
dice = "1D20"
baseFormula = "D20"
maxValue = 20
hasChangeDice = false
options.rollTarget.value = options.rollTarget.actorModifiers.levelMiracleModifier + options.rollTarget.actorModifiers.chaMiracleModifier
options.rollTarget.charModifier = options.rollTarget.actorModifiers.chaMiracleModifier
@@ -271,7 +271,6 @@ export default class LethalFantasyRoll extends Roll {
}
dice = dice.replace("E", "")
baseFormula = dice
maxValue = 20
} else if (options.rollType.includes("monster-damage")) {
options.rollName = options.rollTarget.name
@@ -282,7 +281,6 @@ export default class LethalFantasyRoll extends Roll {
dice = options.rollTarget.damageDice
dice = dice.replace("E", "")
baseFormula = dice
maxValue = 20
}
@@ -292,7 +290,9 @@ export default class LethalFantasyRoll extends Roll {
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({
choices: rollModes,
blank: false,
@@ -315,7 +315,10 @@ export default class LethalFantasyRoll extends Roll {
hasModifier,
hasFavor,
hasChangeDice,
pointBlank,
baseValue: options.rollTarget.value,
attackerAimChoices: SYSTEM.ATTACKER_AIM_CHOICES,
attackerAim: "0",
changeDice: `${dice}`,
fieldRollMode,
choiceModifier,
@@ -329,7 +332,7 @@ export default class LethalFantasyRoll extends Roll {
favor: "none",
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 }
const label = game.i18n.localize("LETHALFANTASY.Roll.roll")
@@ -342,7 +345,8 @@ export default class LethalFantasyRoll extends Roll {
{
label: label,
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))
const output = Array.from(button.form.elements).reduce((obj, input) => {
if (input.name) obj[input.name] = input.value
@@ -354,9 +358,21 @@ export default class LethalFantasyRoll extends Roll {
],
actions: {
"selectGranted": (event, button, dialog) => {
hasGrantedDice = true
hasGrantedDice = event.target.checked
},
"gotoToken" : (event, button, dialog) => {
"selectBeyondSkill": (event, button, dialog) => {
beyondSkill = button.checked
},
"selectPointBlank": (event, button, dialog) => {
pointBlank = button.checked
},
"selectLetItFly": (event, button, dialog) => {
letItFly = button.checked
},
"saveSpellCheck": (event, button, dialog) => {
saveSpell = button.checked
},
"gotoToken": (event, button, dialog) => {
let tokenId = $(button).data("tokenId")
let token = canvas.tokens?.get(tokenId)
if (token) {
@@ -372,6 +388,7 @@ export default class LethalFantasyRoll extends Roll {
// If the user cancels the dialog, exit
if (rollContext === null) return
console.log("rollContext", rollContext, hasGrantedDice)
rollContext.saveSpell = saveSpell // Update fucking flag
let fullModifier = 0
let titleFormula = ""
@@ -380,21 +397,19 @@ export default class LethalFantasyRoll extends Roll {
let bonus = Number(options.rollTarget.value)
fullModifier = rollContext.modifier === "" ? 0 : parseInt(rollContext.modifier, 10) + bonus
fullModifier += (rollContext.saveSpell) ? options.rollTarget.actorModifiers.saveModifier : 0
if (Number(rollContext.attackerAim) > 0) {
fullModifier += Number(rollContext.attackerAim)
}
if (fullModifier === 0) {
modifierFormula = "0"
} else {
if (options.rollType === "skill" || options.rollType === "monster-skill") {
modifierFormula = `${fullModifier}`
} else {
let modAbs = Math.abs(fullModifier)
modifierFormula = `D${modAbs + 1} - 1`
}
let modAbs = Math.abs(fullModifier)
modifierFormula = `D${modAbs + 1} - 1`
}
if (hasStaticModifier) {
modifierFormula += ` + ${options.rollTarget.staticModifier}`
}
// modifierFormula += ` + ${options.rollTarget.charModifier}`
let sign = fullModifier < 0 ? "-" : "+"
if (hasExplode) {
titleFormula = `${dice}E ${sign} ${modifierFormula}`
@@ -412,6 +427,14 @@ export default class LethalFantasyRoll extends Roll {
}
}
// Latest addition : favor choice at point blank range
if (pointBlank) {
rollContext.favor = "favor"
}
if (beyondSkill) {
rollContext.favor = "disfavor"
}
// Specific pain case
if (options.rollType === "save" && options.rollTarget.rollKey === "pain" || options.rollTarget.rollKey === "paincourage") {
baseFormula = options.rollTarget.rollDice
@@ -421,8 +444,21 @@ export default class LethalFantasyRoll extends Roll {
}
// Specific pain/poison/contagion case
if (options.rollType === "save" && (options.rollTarget.rollKey === "pain" || options.rollTarget.rollKey === "paincourage" || options.rollTarget.rollKey === "poison" || options.rollTarget.rollKey === "contagion")) {
if (options.rollType === "save" && (options.rollTarget.rollKey === "poison" || options.rollTarget.rollKey === "contagion")) {
hasD30 = false
hasStaticModifier = true
modifierFormula = ` + ${Math.abs(fullModifier)}`
titleFormula = `${dice}E + ${Math.abs(fullModifier)}`
}
if (letItFly) {
baseFormula = "1D20"
titleFormula = `1D20E`
modifierFormula = "0"
fullModifier = 0
hasFavor = false
hasExplode = true
rollContext.favor = "none"
}
maxValue = Number(baseFormula.match(/\d+$/)[0]) // Update the max value agains
@@ -437,6 +473,9 @@ export default class LethalFantasyRoll extends Roll {
actorImage: options.actorImage,
rollMode: rollContext.visibility,
hasTarget: options.hasTarget,
pointBlank,
beyondSkill,
letItFly,
hasGrantedDice,
titleFormula,
targetName,
@@ -463,15 +502,17 @@ export default class LethalFantasyRoll extends Roll {
if (rollContext.favor === "favor") {
rollFavor = new this(baseFormula, options.data, rollData)
await rollFavor.evaluate()
console.log("Rolling with favor", rollFavor)
if (game?.dice3d) {
game.dice3d.showForRoll(rollFavor, game.user, true)
}
if (rollFavor.result > rollBase.result) {
if (Number(rollFavor.result) > Number(rollBase.result)) {
badResult = rollBase.result
rollBase = rollFavor
} else {
badResult = rollFavor.result
}
rollFavor = null
}
if (rollContext.favor === "disfavor") {
@@ -480,12 +521,13 @@ export default class LethalFantasyRoll extends Roll {
if (game?.dice3d) {
game.dice3d.showForRoll(rollFavor, game.user, true)
}
if (rollFavor.result < rollBase.result) {
if (Number(rollFavor.result) < Number(rollBase.result)) {
badResult = rollBase.result
rollBase = rollFavor
} else {
badResult = rollFavor.result
}
rollFavor = null
}
if (hasD30) {
@@ -496,7 +538,7 @@ export default class LethalFantasyRoll extends Roll {
options.D30result = rollD30.total
}
let rollTotal = -1
let rollTotal = 0
let diceResults = []
let resultType
let diceSum = 0
@@ -521,7 +563,8 @@ export default class LethalFantasyRoll extends Roll {
}
}
if (hasGrantedDice) {
if (hasGrantedDice && options.rollTarget.grantedDice && options.rollTarget.grantedDice !== "") {
titleFormula += ` + ${options.rollTarget.grantedDice.toUpperCase()}`
let grantedRoll = new Roll(options.rollTarget.grantedDice)
await grantedRoll.evaluate()
if (game?.dice3d) {
@@ -534,12 +577,12 @@ export default class LethalFantasyRoll extends Roll {
if (fullModifier !== 0) {
diceResults.push({ dice: `${rollModifier.formula.toUpperCase()}`, value: rollModifier.total })
if (fullModifier < 0) {
rollTotal = Math.max(diceSum - rollModifier.total, 0)
rollTotal += Math.max(diceSum - rollModifier.total, 0)
} else {
rollTotal = diceSum + rollModifier.total
rollTotal += diceSum + rollModifier.total
}
} else {
rollTotal = diceSum
rollTotal += diceSum
}
rollBase.options.resultType = resultType
@@ -549,6 +592,7 @@ export default class LethalFantasyRoll extends Roll {
rollBase.options.titleFormula = titleFormula
rollBase.options.D30result = options.D30result
rollBase.options.badResult = badResult
rollBase.options.rollData = foundry.utils.duplicate(rollData)
/**
* A hook event that fires after the roll has been made.
@@ -566,7 +610,7 @@ export default class LethalFantasyRoll extends Roll {
/* ***********************************************************/
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({
choices: rollModes,
blank: false,
@@ -587,9 +631,8 @@ export default class LethalFantasyRoll extends Roll {
fieldRollMode,
rollModes
}
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 rollContext = await foundry.applications.api.DialogV2.wait({
@@ -622,13 +665,12 @@ export default class LethalFantasyRoll extends Roll {
let combat = game.combats.get(options.combatId)
combat.updateEmbeddedDocuments("Combatant", [{ _id: options.combatantId, initiative: initRoll.total, 'system.progressionCount': 0 }]);
}
}
/* ***********************************************************/
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({
choices: rollModes,
blank: false,
@@ -652,7 +694,7 @@ export default class LethalFantasyRoll extends Roll {
...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 = []
if (currentAction) {
@@ -766,7 +808,7 @@ export default class LethalFantasyRoll extends Roll {
await combatant.setFlag(SYSTEM.id, "currentAction", actionItem)
let message = `${combatant.name} action : ${selectedItem.name}, start rolling progression dice or casting time`
ChatMessage.create({ content: message, speaker: ChatMessage.getSpeaker({ actor: combatant.actor }) })
rollContext = (actionItem.type == "weapon") ? "rollProgressionDice" : "rollLethargyDice" // Set the roll context to rollProgressionDice
rollContext = (actionItem.type === "weapon") ? "rollProgressionDice" : "rollLethargyDice" // Set the roll context to rollProgressionDice
currentAction = actionItem
}
@@ -885,9 +927,9 @@ export default class LethalFantasyRoll extends Roll {
}
/* ***********************************************************/
static async promptRangedDefense(rollTarget) {
static async promptRangedDefense(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);
const fieldRollMode = new foundry.data.fields.StringField({
choices: rollModes,
blank: false,
@@ -902,15 +944,14 @@ export default class LethalFantasyRoll extends Roll {
attackerAimChoices: SYSTEM.ATTACKER_AIM_CHOICES,
movement: "none",
moveDirection: "none",
size: "medium",
size: "+5",
range: "short",
attackerAim: "simple",
fieldRollMode,
rollModes
}
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 rollContext = await foundry.applications.api.DialogV2.wait({
@@ -932,27 +973,41 @@ export default class LethalFantasyRoll extends Roll {
rejectClose: false // Click on Close button will not launch an error
})
// If the user cancels the dialog, exit
if (rollContext === null) return
console.log("RollContext", rollContext)
// Add disfavor/favor option if point blank range
if (rollContext.range === "pointblank") {
rollContext.movement = rollContext.movement.replace("kh", "")
rollContext.movement = rollContext.movement.replace("kl", "")
rollContext.movement += "kl" // Add the kl to the movement (disfavor for point blank range)
rollContext.range = "0"
}
if (rollContext.range === "beyondskill") {
rollContext.movement = rollContext.movement.replace("kh", "")
rollContext.movement = rollContext.movement.replace("kl", "")
rollContext.movement += "kh" // Add the kl to the movement (favor for point blank range)
rollContext.range = "+11"
}
// Build the final modifier
let fullModifier = Number(rollContext.moveDirection) +
Number(rollContext.size) +
Number(rollContext.range) +
Number(rollContext.attackerAim)
console.log("Modifier", fullModifier)
Number(rollContext?.attackerAim || 0)
let modifierFormula
if (fullModifier === 0) {
modifierFormula = "0"
} else {
let modAbs = Math.abs(fullModifier)
modifierFormula = `${modAbs}`
modifierFormula = `D${modAbs + 1} -1`
}
// If the user cancels the dialog, exit
if (rollContext === null) return
let rollData = { ...rollContext }
let options = { ...rollContext }
// Merge rollContext object into options object
options = { ...options, ...rollContext }
options.rollName = "Ranged Defense"
const rollBase = new this(rollContext.movement, options.data, rollData)
@@ -962,8 +1017,17 @@ export default class LethalFantasyRoll extends Roll {
let rollD30 = await new Roll("1D30").evaluate()
options.D30result = rollD30.total
let badResult = 0
if (rollContext.movement.includes("kh")) {
rollData.favor = "favor"
badResult = Math.min(rollBase.terms[0].results[0].result, rollBase.terms[0].results[1]?.result || 20)
}
if (rollContext.movement.includes("kl")) {
rollData.favor = "disfavor"
badResult = Math.max(rollBase.terms[0].results[0].result, rollBase.terms[0].results[1]?.result || 1)
}
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 diceResults = []
let resultType
@@ -987,15 +1051,16 @@ export default class LethalFantasyRoll extends Roll {
} else {
rollTotal = diceSum
}
rollBase.options = { ...rollBase.options, ...options }
rollBase.options.resultType = resultType
rollBase.options.rollTotal = rollTotal
rollBase.options.diceResults = diceResults
rollBase.options.rollTarget = options.rollTarget
rollBase.options.titleFormula = `${dice}E + ${modifierFormula}`
rollBase.options.titleFormula = `1D20E + ${modifierFormula}`
rollBase.options.D30result = options.D30result
rollBase.options.rollName = "Ranged Defense"
rollBase.options.badResult = badResult
rollBase.options.rollData = foundry.utils.duplicate(rollData)
/**
* A hook event that fires after the roll has been made.
* @function
@@ -1050,7 +1115,7 @@ export default class LethalFantasyRoll extends Roll {
async render(chatOptions = {}) {
let chatData = await this._getChatCardData(chatOptions.isPrivate)
console.log("ChatData", chatData)
return await renderTemplate(this.constructor.CHAT_TEMPLATE, chatData)
return await foundry.applications.handlebars.renderTemplate(this.constructor.CHAT_TEMPLATE, chatData)
}
/*
@@ -1079,6 +1144,7 @@ export default class LethalFantasyRoll extends Roll {
targetArmor: this.targetArmor,
D30result: this.D30result,
badResult: this.badResult,
rollData: this.rollData,
isPrivate: isPrivate
}
cardData.cssClass = cardData.css.join(" ")
@@ -1110,6 +1176,7 @@ export default class LethalFantasyRoll extends Roll {
targetArmor: this.targetArmor,
targetMalus: this.targetMalus,
realDamage: this.realDamage,
rollData: this.rollData,
...messageData,
},
{ rollMode: rollMode },

View File

@@ -90,9 +90,9 @@ export default class LethalFantasyCharacter extends foundry.abstract.TypeDataMod
current: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
})
schema.granted = new fields.SchemaField({
attackDice: new fields.StringField({ required: true, nullable: false, initial: "" }),
defenseDice: new fields.StringField({ required: true, nullable: false, initial: "" }),
damageDice: new fields.StringField({ required: true, nullable: false, initial: "" })
attackDice: new fields.StringField({ required: true, nullable: false, initial: "0", choices: SYSTEM.GRANTED_DICE_CHOICES }),
defenseDice: new fields.StringField({ required: true, nullable: false, initial: "0", choices: SYSTEM.GRANTED_DICE_CHOICES }),
damageDice: new fields.StringField({ required: true, nullable: false, initial: "0", choices: SYSTEM.GRANTED_DICE_CHOICES })
})
schema.movement = new fields.SchemaField({
@@ -174,6 +174,31 @@ export default class LethalFantasyCharacter extends foundry.abstract.TypeDataMod
/** @override */
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() {
super.prepareDerivedData();
let grit = 0
@@ -210,8 +235,8 @@ export default class LethalFantasyCharacter extends foundry.abstract.TypeDataMod
this.saves.toughness.value = conDef.toughness_save + this.modifiers.saveModifier
this.challenges.dying.value = conDef.stabilization_dice
this.saves.contagion.value = this.characteristics.con.value + this.modifiers.saveModifier
this.saves.poison.value = this.characteristics.con.value + this.modifiers.saveModifier
this.saves.contagion.value = this.characteristics.con.value;// + this.modifiers.saveModifier
this.saves.poison.value = this.characteristics.con.value; // + this.modifiers.saveModifier
this.combat.attackModifier = 0
for (let chaKey of SYSTEM.CHARACTERISTIC_ATTACK) {
@@ -268,14 +293,13 @@ export default class LethalFantasyCharacter extends foundry.abstract.TypeDataMod
let wisDef = SYSTEM.CHARACTERISTICS_TABLES.wis.find((c) => c.value === this.characteristics.wis.value)
let maxInit = Number(wisDef.init_cap) || 1000
console.log("Rolling initiative for", this)
let roll = await LethalFantasyRoll.promptInitiative({
actorId: this.parent.id,
actorName: this.parent.name,
actorImage: this.parent.img,
combatId,
combatantId ,
combatantId,
actorClass,
maxInit,
})
@@ -302,10 +326,10 @@ export default class LethalFantasyCharacter extends foundry.abstract.TypeDataMod
let formula = ""
if (s.type === "spell") {
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}`
} else {
title = `${s.name} (Prayer time: ${s.system.prayerTime})`
title = `${s.name} (Prayer time: ${s.system.prayerTime})`
formula = `${s.system.prayerTime}`
}
weaponsChoices.push({ id: s.id, name: title, combatProgressionDice: formula })

View File

@@ -73,6 +73,7 @@ export default class LethalFantasyMonster extends foundry.abstract.TypeDataModel
defenseModifier: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }),
damageDice: new fields.StringField({ required: true, nullable: false, initial: "1D6" }),
damageModifier: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }),
enabled: new fields.BooleanField({ initial: true, required: true, nullable: false }),
}
return new fields.SchemaField(schema, { label })
}
@@ -108,9 +109,9 @@ export default class LethalFantasyMonster extends foundry.abstract.TypeDataModel
schema.biodata = new fields.SchemaField({
alignment: new fields.StringField({ required: true, nullable: false, initial: "" }),
vision: new fields.StringField({ required: true, nullable: false, initial: "" }),
height: new fields.StringField({ required: true, nullable: false, initial: "" }),
height: new fields.StringField({ required: true, nullable: false, initial: "" }),
length: new fields.StringField({ required: true, nullable: false, initial: "" }),
weight: new fields.StringField({ required: true, nullable: false, initial: "" })
weight: new fields.StringField({ required: true, nullable: false, initial: "" })
})
schema.combat = new fields.SchemaField({
attackModifier: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }),
@@ -170,7 +171,7 @@ export default class LethalFantasyMonster extends foundry.abstract.TypeDataModel
case "weapon-damage-small":
case "weapon-damage-medium":
case "weapon-attack":
case "weapon-defense":
case "weapon-defense": {
let weapon = this.actor.items.find((i) => i.type === "weapon" && i.id === rollKey)
let skill
let skills = this.actor.items.filter((i) => i.type === "skill" && i.name.toLowerCase() === weapon.name.toLowerCase())
@@ -205,6 +206,7 @@ export default class LethalFantasyMonster extends foundry.abstract.TypeDataModel
rollTarget.weaponSkillModifier = skill.weaponSkillModifier
rollTarget.rollKey = rollKey
rollTarget.combat = foundry.utils.duplicate(this.combat)
}
break
default:
ui.notifications.error(game.i18n.localize("LETHALFANTASY.Notifications.rollTypeNotFound") + String(rollType))
@@ -238,18 +240,18 @@ export default class LethalFantasyMonster extends foundry.abstract.TypeDataModel
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({
choices: rollModes,
blank: false,
default: "public",
})
let roll = new Roll("1D8")
let roll = new Roll("1D12")
await roll.evaluate()
let combatant = game.combats.get(combatId)?.combatants?.get(combatantId)
let msg = await roll.toMessage({ flavor: `Progression Roll for ${this.parent.name}` } )
let msg = await roll.toMessage({ flavor: `Progression Roll for ${this.parent.name}` })
if (game?.dice3d) {
await game.dice3d.waitFor3DAnimationByMessageID(msg.id)
}
@@ -257,14 +259,14 @@ export default class LethalFantasyMonster extends foundry.abstract.TypeDataModel
let hasAttack = false
for (let key in this.attacks) {
let attack = this.attacks[key]
if (attack.attackScore > 0 && attack.attackScore === roll.total) {
if (attack.enabled && attack.attackScore > 0 && attack.attackScore === roll.total) {
hasAttack = true
let message = game.i18n.format("LETHALFANTASY.Notifications.messageProgressionOKMonster", { isMonster: true, name: this.parent.name, weapon: attack.name, roll: roll.total })
ChatMessage.create({ content: message, speaker: ChatMessage.getSpeaker({ actor: this.parent }) })
let token = combatant?.token
this.prepareMonsterRoll("monster-attack", key, undefined, token?.id)
if ( token?.object ) {
token.object?.control({releaseOthers: true});
if (token?.object) {
token.object?.control({ releaseOthers: true });
return canvas.animatePan(token.object.center);
}
}
@@ -272,7 +274,7 @@ export default class LethalFantasyMonster extends foundry.abstract.TypeDataModel
if (!hasAttack) {
let message = game.i18n.format("LETHALFANTASY.Notifications.messageProgressionKOMonster", { isMonster: true, name: this.parent.name, roll: roll.total })
ChatMessage.create({ content: message, speaker: ChatMessage.getSpeaker({ actor: this.parent }) })
}
}
}

View File

@@ -22,28 +22,28 @@ export default class LethalFantasyUtils {
static setHookListeners() {
Hooks.on('renderTokenHUD', async (hud, html, token) => {
const lossHPButton = await renderTemplate('systems/fvtt-lethal-fantasy/templates/loss-hp-hud.hbs', {} )
html.find('div.left').append(lossHPButton);
html.find('img.lethal-hp-loss-hud').click((event) => {
const lossHPButton = await foundry.applications.handlebars.renderTemplate('systems/fvtt-lethal-fantasy/templates/loss-hp-hud.hbs', {} )
$(html).find('div.left').append(lossHPButton);
$(html).find('img.lethal-hp-loss-hud').click((event) => {
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")) {
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')[1].classList.add('hp-loss-hud-active');
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.remove('hp-loss-hud-disabled');
$(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')[1].classList.add('hp-loss-hud-active');
$(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.remove('hp-loss-hud-disabled');
} else {
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')[1].classList.remove('hp-loss-hud-active');
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.add('hp-loss-hud-disabled');
$(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')[1].classList.remove('hp-loss-hud-active');
$(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.add('hp-loss-hud-disabled');
}
})
html.find('.loss-hp-hud-click').click((event) => {
$(html).find('.loss-hp-hud-click').click((event) => {
event.preventDefault();
let hpLoss = event.currentTarget.dataset.hpValue;
if (token) {
@@ -51,12 +51,12 @@ export default class LethalFantasyUtils {
console.log(tokenFull, token)
let actor = tokenFull.actor;
actor.applyDamage(Number(hpLoss));
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')[1].classList.remove('hp-loss-hud-active');
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.add('hp-loss-hud-disabled');
$(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')[1].classList.remove('hp-loss-hud-active');
$(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.add('hp-loss-hud-disabled');
}
})
})

Binary file not shown.

Binary file not shown.

View File

@@ -1 +1 @@
MANIFEST-000281
MANIFEST-000436

View File

@@ -1,8 +1,8 @@
2025/05/02-18:08:30.093606 7fc4edbfa6c0 Recovering log #279
2025/05/02-18:08:30.104455 7fc4edbfa6c0 Delete type=3 #277
2025/05/02-18:08:30.104565 7fc4edbfa6c0 Delete type=0 #279
2025/05/02-18:21:55.109498 7fc4e73ff6c0 Level-0 table #284: started
2025/05/02-18:21:55.109535 7fc4e73ff6c0 Level-0 table #284: 0 bytes OK
2025/05/02-18:21:55.116187 7fc4e73ff6c0 Delete type=0 #282
2025/05/02-18:21:55.129360 7fc4e73ff6c0 Manual compaction at level-0 from '!folders!ATr9wZhg5uTVTksM' @ 72057594037927935 : 1 .. '!items!znm6T1ef4qQI8BX7' @ 0 : 0; will stop at (end)
2025/05/02-18:21:55.129430 7fc4e73ff6c0 Manual compaction at level-1 from '!folders!ATr9wZhg5uTVTksM' @ 72057594037927935 : 1 .. '!items!znm6T1ef4qQI8BX7' @ 0 : 0; will stop at (end)
2025/10/01-16:42:57.866432 7fc499ffb6c0 Recovering log #434
2025/10/01-16:42:57.877314 7fc499ffb6c0 Delete type=3 #432
2025/10/01-16:42:57.877388 7fc499ffb6c0 Delete type=0 #434
2025/10/01-17:11:30.188440 7fc497ff76c0 Level-0 table #439: started
2025/10/01-17:11:30.188469 7fc497ff76c0 Level-0 table #439: 0 bytes OK
2025/10/01-17:11:30.194363 7fc497ff76c0 Delete type=0 #437
2025/10/01-17:11:30.200618 7fc497ff76c0 Manual compaction at level-0 from '!folders!ATr9wZhg5uTVTksM' @ 72057594037927935 : 1 .. '!items!zw9RQocTdz3HRjZK' @ 0 : 0; will stop at (end)
2025/10/01-17:11:30.200653 7fc497ff76c0 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/28-21:05:33.969865 7fa7f49f96c0 Recovering log #275
2025/04/28-21:05:33.982957 7fa7f49f96c0 Delete type=3 #273
2025/04/28-21:05:33.983066 7fa7f49f96c0 Delete type=0 #275
2025/04/29-00:08:44.421059 7fa7eebff6c0 Level-0 table #280: started
2025/04/29-00:08:44.421086 7fa7eebff6c0 Level-0 table #280: 0 bytes OK
2025/04/29-00:08:44.492658 7fa7eebff6c0 Delete type=0 #278
2025/04/29-00:08:44.570180 7fa7eebff6c0 Manual compaction at level-0 from '!folders!ATr9wZhg5uTVTksM' @ 72057594037927935 : 1 .. '!items!znm6T1ef4qQI8BX7' @ 0 : 0; will stop at (end)
2025/04/29-00:08:44.570235 7fa7eebff6c0 Manual compaction at level-1 from '!folders!ATr9wZhg5uTVTksM' @ 72057594037927935 : 1 .. '!items!znm6T1ef4qQI8BX7' @ 0 : 0; will stop at (end)
2025/10/01-09:52:37.607891 7fc498ff96c0 Recovering log #430
2025/10/01-09:52:37.617656 7fc498ff96c0 Delete type=3 #428
2025/10/01-09:52:37.617728 7fc498ff96c0 Delete type=0 #430
2025/10/01-10:19:09.456857 7fc497ff76c0 Level-0 table #435: started
2025/10/01-10:19:09.456891 7fc497ff76c0 Level-0 table #435: 0 bytes OK
2025/10/01-10:19:09.500293 7fc497ff76c0 Delete type=0 #433
2025/10/01-10:19:09.675931 7fc497ff76c0 Manual compaction at level-0 from '!folders!ATr9wZhg5uTVTksM' @ 72057594037927935 : 1 .. '!items!zw9RQocTdz3HRjZK' @ 0 : 0; will stop at (end)
2025/10/01-10:19:09.675968 7fc497ff76c0 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-000280
MANIFEST-000436

View File

@@ -1,8 +1,8 @@
2025/05/02-18:08:30.109165 7fc4ecbf86c0 Recovering log #278
2025/05/02-18:08:30.121216 7fc4ecbf86c0 Delete type=3 #276
2025/05/02-18:08:30.121310 7fc4ecbf86c0 Delete type=0 #278
2025/05/02-18:21:55.122892 7fc4e73ff6c0 Level-0 table #283: started
2025/05/02-18:21:55.122930 7fc4e73ff6c0 Level-0 table #283: 0 bytes OK
2025/05/02-18:21:55.129027 7fc4e73ff6c0 Delete type=0 #281
2025/05/02-18:21:55.129407 7fc4e73ff6c0 Manual compaction at level-0 from '!folders!yPWGvxHJbDNHVSnY' @ 72057594037927935 : 1 .. '!items!zjvGljrLk5SshC9D' @ 0 : 0; will stop at (end)
2025/05/02-18:21:55.129496 7fc4e73ff6c0 Manual compaction at level-1 from '!folders!yPWGvxHJbDNHVSnY' @ 72057594037927935 : 1 .. '!items!zjvGljrLk5SshC9D' @ 0 : 0; will stop at (end)
2025/10/01-16:42:57.881962 7fc4987f86c0 Recovering log #434
2025/10/01-16:42:57.892761 7fc4987f86c0 Delete type=3 #432
2025/10/01-16:42:57.892833 7fc4987f86c0 Delete type=0 #434
2025/10/01-17:11:30.181134 7fc497ff76c0 Level-0 table #439: started
2025/10/01-17:11:30.181171 7fc497ff76c0 Level-0 table #439: 0 bytes OK
2025/10/01-17:11:30.188327 7fc497ff76c0 Delete type=0 #437
2025/10/01-17:11:30.200601 7fc497ff76c0 Manual compaction at level-0 from '!folders!yPWGvxHJbDNHVSnY' @ 72057594037927935 : 1 .. '!items!zjvGljrLk5SshC9D' @ 0 : 0; will stop at (end)
2025/10/01-17:11:30.200645 7fc497ff76c0 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/28-21:05:33.988908 7fa7ef7fe6c0 Recovering log #274
2025/04/28-21:05:34.005200 7fa7ef7fe6c0 Delete type=3 #272
2025/04/28-21:05:34.005349 7fa7ef7fe6c0 Delete type=0 #274
2025/04/29-00:08:44.365001 7fa7eebff6c0 Level-0 table #279: started
2025/04/29-00:08:44.365047 7fa7eebff6c0 Level-0 table #279: 0 bytes OK
2025/04/29-00:08:44.420965 7fa7eebff6c0 Delete type=0 #277
2025/04/29-00:08:44.570160 7fa7eebff6c0 Manual compaction at level-0 from '!folders!yPWGvxHJbDNHVSnY' @ 72057594037927935 : 1 .. '!items!zjvGljrLk5SshC9D' @ 0 : 0; will stop at (end)
2025/04/29-00:08:44.570222 7fa7eebff6c0 Manual compaction at level-1 from '!folders!yPWGvxHJbDNHVSnY' @ 72057594037927935 : 1 .. '!items!zjvGljrLk5SshC9D' @ 0 : 0; will stop at (end)
2025/10/01-09:52:37.622704 7fc4997fa6c0 Recovering log #430
2025/10/01-09:52:37.632146 7fc4997fa6c0 Delete type=3 #428
2025/10/01-09:52:37.632199 7fc4997fa6c0 Delete type=0 #430
2025/10/01-10:19:09.736826 7fc497ff76c0 Level-0 table #435: started
2025/10/01-10:19:09.736857 7fc497ff76c0 Level-0 table #435: 0 bytes OK
2025/10/01-10:19:09.782928 7fc497ff76c0 Delete type=0 #433
2025/10/01-10:19:09.809673 7fc497ff76c0 Manual compaction at level-0 from '!folders!yPWGvxHJbDNHVSnY' @ 72057594037927935 : 1 .. '!items!zjvGljrLk5SshC9D' @ 0 : 0; will stop at (end)
2025/10/01-10:19:09.809700 7fc497ff76c0 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-000280
MANIFEST-000436

View File

@@ -1,8 +1,8 @@
2025/05/02-18:08:30.076028 7fc4edbfa6c0 Recovering log #278
2025/05/02-18:08:30.087953 7fc4edbfa6c0 Delete type=3 #276
2025/05/02-18:08:30.088039 7fc4edbfa6c0 Delete type=0 #278
2025/05/02-18:21:55.116367 7fc4e73ff6c0 Level-0 table #283: started
2025/05/02-18:21:55.116408 7fc4e73ff6c0 Level-0 table #283: 0 bytes OK
2025/05/02-18:21:55.122719 7fc4e73ff6c0 Delete type=0 #281
2025/05/02-18:21:55.129386 7fc4e73ff6c0 Manual compaction at level-0 from '!folders!7j8H7DbmBb9Uza2X' @ 72057594037927935 : 1 .. '!items!zt8s7564ep1La4XQ' @ 0 : 0; will stop at (end)
2025/05/02-18:21:55.129477 7fc4e73ff6c0 Manual compaction at level-1 from '!folders!7j8H7DbmBb9Uza2X' @ 72057594037927935 : 1 .. '!items!zt8s7564ep1La4XQ' @ 0 : 0; will stop at (end)
2025/10/01-16:42:57.852986 7fc498ff96c0 Recovering log #434
2025/10/01-16:42:57.862534 7fc498ff96c0 Delete type=3 #432
2025/10/01-16:42:57.862603 7fc498ff96c0 Delete type=0 #434
2025/10/01-17:11:30.174361 7fc497ff76c0 Level-0 table #439: started
2025/10/01-17:11:30.174817 7fc497ff76c0 Level-0 table #439: 0 bytes OK
2025/10/01-17:11:30.181000 7fc497ff76c0 Delete type=0 #437
2025/10/01-17:11:30.200584 7fc497ff76c0 Manual compaction at level-0 from '!folders!7j8H7DbmBb9Uza2X' @ 72057594037927935 : 1 .. '!items!zt8s7564ep1La4XQ' @ 0 : 0; will stop at (end)
2025/10/01-17:11:30.200638 7fc497ff76c0 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/28-21:05:33.953840 7fa7effff6c0 Recovering log #274
2025/04/28-21:05:33.964089 7fa7effff6c0 Delete type=3 #272
2025/04/28-21:05:33.964167 7fa7effff6c0 Delete type=0 #274
2025/04/29-00:08:44.318603 7fa7eebff6c0 Level-0 table #279: started
2025/04/29-00:08:44.318649 7fa7eebff6c0 Level-0 table #279: 0 bytes OK
2025/04/29-00:08:44.364829 7fa7eebff6c0 Delete type=0 #277
2025/04/29-00:08:44.570130 7fa7eebff6c0 Manual compaction at level-0 from '!folders!7j8H7DbmBb9Uza2X' @ 72057594037927935 : 1 .. '!items!zt8s7564ep1La4XQ' @ 0 : 0; will stop at (end)
2025/04/29-00:08:44.570209 7fa7eebff6c0 Manual compaction at level-1 from '!folders!7j8H7DbmBb9Uza2X' @ 72057594037927935 : 1 .. '!items!zt8s7564ep1La4XQ' @ 0 : 0; will stop at (end)
2025/10/01-09:52:37.593230 7fc4987f86c0 Recovering log #430
2025/10/01-09:52:37.603848 7fc4987f86c0 Delete type=3 #428
2025/10/01-09:52:37.603909 7fc4987f86c0 Delete type=0 #430
2025/10/01-10:19:09.418020 7fc497ff76c0 Level-0 table #435: started
2025/10/01-10:19:09.418055 7fc497ff76c0 Level-0 table #435: 0 bytes OK
2025/10/01-10:19:09.456709 7fc497ff76c0 Delete type=0 #433
2025/10/01-10:19:09.675920 7fc497ff76c0 Manual compaction at level-0 from '!folders!7j8H7DbmBb9Uza2X' @ 72057594037927935 : 1 .. '!items!zt8s7564ep1La4XQ' @ 0 : 0; will stop at (end)
2025/10/01-10:19:09.675962 7fc497ff76c0 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-000136

View File

View File

@@ -0,0 +1,8 @@
2025/10/01-16:42:57.908006 7fc4997fa6c0 Recovering log #134
2025/10/01-16:42:57.919602 7fc4997fa6c0 Delete type=3 #132
2025/10/01-16:42:57.919658 7fc4997fa6c0 Delete type=0 #134
2025/10/01-17:11:30.207352 7fc497ff76c0 Level-0 table #139: started
2025/10/01-17:11:30.207416 7fc497ff76c0 Level-0 table #139: 0 bytes OK
2025/10/01-17:11:30.214221 7fc497ff76c0 Delete type=0 #137
2025/10/01-17:11:30.239177 7fc497ff76c0 Manual compaction at level-0 from '!folders!37mu4dxsSuftlnmP' @ 72057594037927935 : 1 .. '!items!zKOpU34oLziGJW6y' @ 0 : 0; will stop at (end)
2025/10/01-17:11:30.278471 7fc497ff76c0 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/10/01-09:52:37.648603 7fc498ff96c0 Recovering log #130
2025/10/01-09:52:37.658051 7fc498ff96c0 Delete type=3 #128
2025/10/01-09:52:37.658136 7fc498ff96c0 Delete type=0 #130
2025/10/01-10:19:09.381699 7fc497ff76c0 Level-0 table #135: started
2025/10/01-10:19:09.381742 7fc497ff76c0 Level-0 table #135: 0 bytes OK
2025/10/01-10:19:09.417885 7fc497ff76c0 Delete type=0 #133
2025/10/01-10:19:09.675902 7fc497ff76c0 Manual compaction at level-0 from '!folders!37mu4dxsSuftlnmP' @ 72057594037927935 : 1 .. '!items!zKOpU34oLziGJW6y' @ 0 : 0; will stop at (end)
2025/10/01-10:19:09.675956 7fc497ff76c0 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-000280
MANIFEST-000435

View File

@@ -1,8 +1,8 @@
2025/05/02-18:08:30.126416 7fc4e7fff6c0 Recovering log #278
2025/05/02-18:08:30.137455 7fc4e7fff6c0 Delete type=3 #276
2025/05/02-18:08:30.137553 7fc4e7fff6c0 Delete type=0 #278
2025/05/02-18:21:55.102804 7fc4e73ff6c0 Level-0 table #283: started
2025/05/02-18:21:55.102870 7fc4e73ff6c0 Level-0 table #283: 0 bytes OK
2025/05/02-18:21:55.109338 7fc4e73ff6c0 Delete type=0 #281
2025/05/02-18:21:55.129316 7fc4e73ff6c0 Manual compaction at level-0 from '!folders!mnO9OzE7BEE2KDfh' @ 72057594037927935 : 1 .. '!items!zkK6ixtCsCw3RH9X' @ 0 : 0; will stop at (end)
2025/05/02-18:21:55.129455 7fc4e73ff6c0 Manual compaction at level-1 from '!folders!mnO9OzE7BEE2KDfh' @ 72057594037927935 : 1 .. '!items!zkK6ixtCsCw3RH9X' @ 0 : 0; will stop at (end)
2025/10/01-16:42:57.895507 7fc498ff96c0 Recovering log #433
2025/10/01-16:42:57.905329 7fc498ff96c0 Delete type=3 #431
2025/10/01-16:42:57.905405 7fc498ff96c0 Delete type=0 #433
2025/10/01-17:11:30.194475 7fc497ff76c0 Level-0 table #438: started
2025/10/01-17:11:30.194505 7fc497ff76c0 Level-0 table #438: 0 bytes OK
2025/10/01-17:11:30.200450 7fc497ff76c0 Delete type=0 #436
2025/10/01-17:11:30.200628 7fc497ff76c0 Manual compaction at level-0 from '!folders!mnO9OzE7BEE2KDfh' @ 72057594037927935 : 1 .. '!items!zkK6ixtCsCw3RH9X' @ 0 : 0; will stop at (end)
2025/10/01-17:11:30.200661 7fc497ff76c0 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/28-21:05:34.008354 7fa7f51fa6c0 Recovering log #274
2025/04/28-21:05:34.023701 7fa7f51fa6c0 Delete type=3 #272
2025/04/28-21:05:34.023772 7fa7f51fa6c0 Delete type=0 #274
2025/04/29-00:08:44.492763 7fa7eebff6c0 Level-0 table #279: started
2025/04/29-00:08:44.492793 7fa7eebff6c0 Level-0 table #279: 0 bytes OK
2025/04/29-00:08:44.569850 7fa7eebff6c0 Delete type=0 #277
2025/04/29-00:08:44.570197 7fa7eebff6c0 Manual compaction at level-0 from '!folders!mnO9OzE7BEE2KDfh' @ 72057594037927935 : 1 .. '!items!zkK6ixtCsCw3RH9X' @ 0 : 0; will stop at (end)
2025/04/29-00:08:44.570247 7fa7eebff6c0 Manual compaction at level-1 from '!folders!mnO9OzE7BEE2KDfh' @ 72057594037927935 : 1 .. '!items!zkK6ixtCsCw3RH9X' @ 0 : 0; will stop at (end)
2025/10/01-09:52:37.634817 7fc4987f86c0 Recovering log #429
2025/10/01-09:52:37.645670 7fc4987f86c0 Delete type=3 #427
2025/10/01-09:52:37.645745 7fc4987f86c0 Delete type=0 #429
2025/10/01-10:19:09.704901 7fc497ff76c0 Level-0 table #434: started
2025/10/01-10:19:09.704973 7fc497ff76c0 Level-0 table #434: 0 bytes OK
2025/10/01-10:19:09.736698 7fc497ff76c0 Delete type=0 #432
2025/10/01-10:19:09.809658 7fc497ff76c0 Manual compaction at level-0 from '!folders!mnO9OzE7BEE2KDfh' @ 72057594037927935 : 1 .. '!items!zkK6ixtCsCw3RH9X' @ 0 : 0; will stop at (end)
2025/10/01-10:19:09.809691 7fc497ff76c0 Manual compaction at level-1 from '!folders!mnO9OzE7BEE2KDfh' @ 72057594037927935 : 1 .. '!items!zkK6ixtCsCw3RH9X' @ 0 : 0; will stop at (end)

Binary file not shown.

View File

@@ -45,7 +45,7 @@
min-width: 2.2rem;
max-width: 2.2rem;
margin-left: 4px;
font-size: calc(var(--font-size-standard) * 1.0);
font-size: calc(var(--font-size-standard) * 1);
}
.character-hp-max {
clear: both;
@@ -57,7 +57,7 @@
input {
width: 3.2rem;
text-align: center;
font-size: calc(var(--font-size-standard) * 1.0);
font-size: calc(var(--font-size-standard) * 1);
}
}
}
@@ -93,6 +93,10 @@
.character-characteristic {
display: flex;
align-items: center;
span {
min-width: 2.2rem;
max-width: 2.2rem;
}
.rollable:hover,
.rollable:focus {
text-shadow: 0 0 8px var(--color-shadow-primary);
@@ -108,7 +112,7 @@
}
}
}
.character-challenges {
display: flex;
flex-direction: column;
@@ -218,7 +222,7 @@
}
}
.tab.character-biography {
.tab.character-biography .main-div {
.biodata {
display: grid;
grid-template-columns: repeat(4, 1fr);
@@ -248,7 +252,7 @@
}
}
.tab.character-skills {
.tab.character-skills .main-div {
display: grid;
grid-template-columns: 1fr;
legend {
@@ -310,7 +314,7 @@
}
}
.tab.character-equipment {
.tab.character-equipment .main-div {
display: grid;
grid-template-columns: 1fr;
legend {
@@ -349,7 +353,7 @@
}
}
.tab.character-combat {
.tab.character-combat .main-div {
display: grid;
grid-template-columns: 1fr;
legend {
@@ -371,6 +375,9 @@
min-width: 2.5rem;
max-width: 2.5rem;
}
.ranged-attack-button {
font-size: 0.8rem;
}
button {
min-width: 9rem;
}
@@ -469,7 +476,7 @@
min-width: 12rem;
}
.item-detail {
min-width:2rem;
min-width: 2rem;
}
}
.shields {
@@ -488,16 +495,15 @@
}
}
.item-detail {
min-width:2.5rem;
min-width: 2.5rem;
}
.name {
min-width: 12rem;
}
}
}
.tab.character-spells {
.tab.character-spells .main-div {
display: grid;
grid-template-columns: 1fr;
legend {
@@ -530,7 +536,6 @@
}
}
.spells {
display: grid;
grid-template-columns: repeat(2, 1fr);
@@ -541,7 +546,8 @@
align-items: center;
gap: 4px;
.item-img {
width: 24px;
min-width: 24px;
max-width: 24px;
height: 24px;
}
.name {
@@ -558,7 +564,7 @@
}
}
.tab.character-miracles {
.tab.character-miracles .main-div {
display: grid;
grid-template-columns: 1fr;
legend {

View File

@@ -5,6 +5,5 @@
@font-face {
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");
}
.initiative-area {
min-width: 8rem;
max-width: 8rem;
display: flex;
flex-direction: row;
input {
min-width: 3rem;
max-width: 3rem;
}
}
#logo {
content: var(--logo-standard);
width: 50px;

View File

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

View File

@@ -6,6 +6,14 @@
background-repeat: no-repeat;
background-size: 100% 100%;
nav.tabs [data-tab] {
color: #636060;
}
nav.tabs [data-tab].active {
color: #252424;
}
input:disabled,
select:disabled {
background-color: rgba(0, 0, 0, 0.2);
@@ -39,11 +47,11 @@
input,
select {
text-align: center;
font-size: calc(var(--font-size-standard) * 1.0);
font-size: calc(var(--font-size-standard) * 1);
}
select {
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;
}
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 {
font-family: var(--font-secondary);
font-size: calc(var(--font-size-standard) * 1.0);
font-size: calc(var(--font-size-standard) * 1);
flex: 50%;
}
.align-top {
align-self: flex-start;
padding: 0.1rem;
margin-right: 0.2rem;
/*border-color: black;
border-width: 1px;
border-style: solid;
border-radius: 2%;*/
}
.shift-right {
margin-left: 2rem;
}
}
}

View File

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

View File

@@ -25,7 +25,6 @@
border-radius: 4px;
padding: 0.5rem;
}
}
.lethalfantasy-range-defense-dialog {
@@ -34,10 +33,17 @@
fieldset {
padding: 4px;
}
.fieldset-centered {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
}
select {
margin-left: 0.5rem;
min-width: 10rem;
max-width: 10rem;
min-width: 12rem;
max-width: 12rem;
}
.field-section {
display: flex;
@@ -45,13 +51,12 @@
justify-content: left;
}
.field-name {
width:4rem;
min-width: 4rem;
max-width: 4rem;
width: 5rem;
min-width: 5rem;
max-width: 5em;
}
}
.dialog-form {
.form-footer {
button {
@@ -87,7 +92,6 @@
}
}
.main,
.dialog-damage,
.dialog-resource,
@@ -99,8 +103,13 @@
justify-content: center;
align-items: center;
font-family: var(--font-secondary);
font-size: calc(var(--font-size-standard) * 1.0);
font-size: calc(var(--font-size-standard) * 1);
color: var(--color-dark-1);
select {
min-width: 8rem;
max-width: 8rem;
margin-left: 1rem;
}
}
&.dice-roll {
@@ -133,7 +142,7 @@
flex-direction: column;
.introText {
font-family: var(--font-secondary);
font-size: calc(var(--font-size-standard) * 1.0);
font-size: calc(var(--font-size-standard) * 1);
width: 210px;
margin-left: 20px;
}
@@ -144,7 +153,7 @@
flex-direction: column;
justify-content: center;
align-items: center;
font-size: calc(var(--font-size-standard) * 1.0);
font-size: calc(var(--font-size-standard) * 1);
text-shadow: 0 0 10px var(--color-shadow-primary);
}
}

View File

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

View File

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

View File

@@ -1,159 +1,164 @@
<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>
<legend>{{localize "LETHALFANTASY.Label.combatDetails"}}</legend>
<div class="combat-details">
<div class="combat-detail">
<button class="action" data-action="rangedAttackDefense">
{{localize "LETHALFANTASY.Label.rangedAttackDefense"}}
</button>
<fieldset>
<legend>{{localize "LETHALFANTASY.Label.combatDetails"}}</legend>
<div class="combat-details">
<div class="combat-detail">
<button class="action" data-action="rollInitiative">
{{localize "LETHALFANTASY.Label.rollInitiative"}}
</button>
<button class="action ranged-attack-button" data-action="rangedAttackDefense">
{{localize "LETHALFANTASY.Label.rangedAttackDefense"}}
</button>
<button class="action ranged-attack-button" data-action="rollInitiative">
{{localize "LETHALFANTASY.Label.rollInitiative"}}
</button>
<div class="flexrow armor-hp">
<span class="name">{{localize "LETHALFANTASY.Label.armorHitPoints"}}</span>
{{formInput systemFields.combat.fields.armorHitPoints value=system.combat.armorHitPoints localize=true }}
<a data-action="armorHitPointsPlus"><i class="fa-solid fa-hexagon-plus"></i></a>
<a data-action="armorHitPointsMinus"><i class="fa-solid fa-hexagon-minus"></i></a>
</div>
<div class="flexrow granted">
<span class="">{{localize
"LETHALFANTASY.Label.grantedAttackDice"}}</a></span>
{{formInput systemFields.granted.fields.attackDice value=system.granted.attackDice disabled=isPlayMode }}
</div>
<div class="flexrow granted ">
<span class="">{{localize
"LETHALFANTASY.Label.grantedDefenseDice"}}</a></span>
{{formInput systemFields.granted.fields.defenseDice value=system.granted.defenseDice disabled=isPlayMode }}
</div>
<div class="flexrow granted">
<span class="">{{localize
"LETHALFANTASY.Label.grantedDamageDice"}}</a></span>
{{formInput systemFields.granted.fields.damageDice value=system.granted.damageDice disabled=isPlayMode }}
</div>
<div class="flexrow armor-hp">
<span class="name">{{localize "LETHALFANTASY.Label.armorHitPoints"}}</span>
{{formInput systemFields.combat.fields.armorHitPoints value=system.combat.armorHitPoints localize=true }}
<a data-action="armorHitPointsPlus"><i class="fa-solid fa-hexagon-plus"></i></a>
<a data-action="armorHitPointsMinus"><i class="fa-solid fa-hexagon-minus"></i></a>
</div>
<div class="flexrow granted">
<span class=""><a class="rollable" data-roll-type="granted" data-roll-key="attackDice"><i
class="lf-roll-small fa-solid fa-dice-d20"></i>{{localize "LETHALFANTASY.Label.grantedAttackDice"}}</a></span>
{{formInput systemFields.granted.fields.attackDice value=system.granted.attackDice disabled=isPlayMode }}
</div>
<div class="flexrow granted ">
<span class=""><a class="rollable" data-roll-type="granted" data-roll-key="defenseDice"><i
class="lf-roll-small fa-solid fa-dice-d20"></i>{{localize "LETHALFANTASY.Label.grantedDefenseDice"}}</a></span>
{{formInput systemFields.granted.fields.defenseDice value=system.granted.defenseDice disabled=isPlayMode }}
</div>
<div class="flexrow granted">
<span class=""><a class="rollable" data-roll-type="granted" data-roll-key="damageDice"><i
class="lf-roll-small fa-solid fa-dice-d20"></i>{{localize "LETHALFANTASY.Label.grantedDamageDice"}}</a></span>
{{formInput systemFields.granted.fields.damageDice value=system.granted.damageDice disabled=isPlayMode }}
</div>
</div>
</div>
</fieldset>
</fieldset>
<fieldset>
<legend>{{localize "LETHALFANTASY.Label.wounds"}}</legend>
<div class="wounds">
<fieldset>
<legend>{{localize "LETHALFANTASY.Label.wounds"}}</legend>
<div class="wounds">
{{#each system.hp.wounds as |wound idx|}}
<div class="wound">
Name:<input class="wound-description wound-data" type="text" data-type="String" data-index="{{@index}}" value="{{wound.description}}" data-name="description" >
Duration:<input class="wound-duration wound-data" type="text" data-type="Number" data-index="{{@index}}" value="{{wound.duration}}" data-name="duration" >
HP:<input class="wound-value wound-data" type="text" data-type="Number" data-index="{{@index}}" value="{{wound.value}}" data-name="value" >
Name:<input class="wound-description wound-data" type="text" data-type="String" data-index="{{@index}}"
value="{{wound.description}}" data-name="description">
Duration:<input class="wound-duration wound-data" type="text" data-type="Number" data-index="{{@index}}"
value="{{wound.duration}}" data-name="duration">
HP:<input class="wound-value wound-data" type="text" data-type="Number" data-index="{{@index}}"
value="{{wound.value}}" data-name="value">
</div>
{{/each}}
</div>
</fieldset>
<fieldset>
<legend>{{localize "LETHALFANTASY.Label.weapons"}}</legend>
<div class="weapons">
{{#each weapons as |item|}}
<div class="weapon" data-item-id="{{item.id}}" data-item-uuid="{{item.uuid}}" data-drag="true"
data-drag-type="damage">
{{#if (ne item.img "icons/svg/item-bag.svg")}}
<img class="item-img" src="{{item.img}}" data-tooltip="{{item.name}}" />
{{/if}}
<div class="name">
{{item.name}}
</div>
<div class="attack-icons">
<a class="rollable" data-roll-type="weapon-attack" data-roll-key="{{item.id}}" data-tooltip="Roll Attack">
<i class="lf-roll-small fa-solid fa-swords" data-roll-type="weapon-attack" data-roll-key="{{item.id}}"></i>
</a>
<a class="rollable" data-roll-type="weapon-defense" data-roll-key="{{item.id}}" data-tooltip="Roll Defense">
<i class="fa-solid fa-shield-halved" data-roll-type="weapon-defense" data-roll-key="{{item.id}}"></i>
</a>
<a class="rollable" data-roll-type="weapon-damage-small" data-roll-key="{{item.id}}"
data-tooltip="Roll Damage (Small)">
<i class="fa-regular fa-face-head-bandage" data-roll-type="weapon-damage-small"
data-roll-key="{{item.id}}"></i>S
</a>
<a class="rollable" data-roll-type="weapon-damage-medium" data-roll-key="{{item.id}}"
data-tooltip="Roll Damage (Medium)">
<i class="fa-regular fa-face-head-bandage" data-roll-type="weapon-damage-medium"
data-roll-key="{{item.id}}"></i>M
</a>
</div>
<div class="controls">
<a data-tooltip="{{localize 'LETHALFANTASY.Edit'}}" data-action="edit" data-item-id="{{item.id}}"
data-item-uuid="{{item.uuid}}"><i class="fas fa-edit"></i></a>
<a data-tooltip="{{localize 'LETHALFANTASY.Delete'}}" data-action="delete" data-item-id="{{item.id}}"
data-item-uuid="{{item.uuid}}"><i class="fas fa-trash"></i></a>
</div>
</div>
{{/each}}
</div>
</fieldset>
</fieldset>
<fieldset>
<legend>{{localize "LETHALFANTASY.Label.armors"}}</legend>
<div class="armors">
{{#each armors as |item|}}
<div class="armor" data-item-id="{{item.id}}" data-item-uuid="{{item.uuid}}">
<img class="item-img" src="{{item.img}}" data-tooltip="{{item.name}}" />
<div class="name" data-tooltip="{{{item.system.description}}}">
{{item.name}}
</div>
<div class="item-detail" data-tooltip="Defense">{{item.system.defense}}</div>
<div class="item-detail" data-tooltip="Maximum movement">{{item.system.maximumMovement}}</div>
<div class="item-detail" data-tooltip="HP">{{item.system.hp}}</div>
<div class="item-detail" data-tooltip="Damage Reduction">{{item.system.damageReduction}}</div>
<div class="controls">
<a data-tooltip="{{localize 'LETHALFANTASY.Edit'}}" data-action="edit" data-item-id="{{item.id}}"
data-item-uuid="{{item.uuid}}"><i class="fas fa-edit"></i></a>
<a data-tooltip="{{localize 'LETHALFANTASY.Delete'}}" data-action="delete" data-item-id="{{item.id}}"
data-item-uuid="{{item.uuid}}"><i class="fas fa-trash"></i></a>
<fieldset>
<legend>{{localize "LETHALFANTASY.Label.weapons"}}</legend>
<div class="weapons">
{{#each weapons as |item|}}
<div class="weapon" data-item-id="{{item.id}}" data-item-uuid="{{item.uuid}}" data-drag="true"
data-drag-type="damage">
{{#if (ne item.img "icons/svg/item-bag.svg")}}
<img class="item-img" src="{{item.img}}" data-tooltip="{{item.name}}" />
{{/if}}
<div class="name" data-tooltip="{{item.system.description}}">
{{item.name}}
</div>
<div class="attack-icons">
<a class="rollable" data-roll-type="weapon-attack" data-roll-key="{{item.id}}" data-tooltip="Roll Attack">
<i class="lf-roll-small fa-solid fa-swords" data-roll-type="weapon-attack"
data-roll-key="{{item.id}}"></i>
</a>
<a class="rollable" data-roll-type="weapon-defense" data-roll-key="{{item.id}}" data-tooltip="Roll Defense">
<i class="fa-solid fa-shield-halved" data-roll-type="weapon-defense" data-roll-key="{{item.id}}"></i>
</a>
<a class="rollable" data-roll-type="weapon-damage-small" data-roll-key="{{item.id}}"
data-tooltip="Roll Damage (Small)">
<i class="fa-regular fa-face-head-bandage" data-roll-type="weapon-damage-small"
data-roll-key="{{item.id}}"></i>S
</a>
<a class="rollable" data-roll-type="weapon-damage-medium" data-roll-key="{{item.id}}"
data-tooltip="Roll Damage (Medium)">
<i class="fa-regular fa-face-head-bandage" data-roll-type="weapon-damage-medium"
data-roll-key="{{item.id}}"></i>M
</a>
</div>
<div class="controls">
<a data-tooltip="{{localize 'LETHALFANTASY.Edit'}}" data-action="edit" data-item-id="{{item.id}}"
data-item-uuid="{{item.uuid}}"><i class="fas fa-edit"></i></a>
<a data-tooltip="{{localize 'LETHALFANTASY.Delete'}}" data-action="delete" data-item-id="{{item.id}}"
data-item-uuid="{{item.uuid}}"><i class="fas fa-trash"></i></a>
</div>
</div>
{{/each}}
</div>
{{/each}}
</div>
</fieldset>
</fieldset>
<fieldset>
<legend>{{localize "LETHALFANTASY.Label.shields"}}</legend>
<div class="shields">
{{#each shields as |item|}}
<div class="shield" data-item-id="{{item.id}}" data-item-uuid="{{item.uuid}}">
<img class="item-img" src="{{item.img}}" data-tooltip="{{item.name}}" />
<div class="name" data-tooltip="{{{item.system.description}}}">
{{item.name}}
</div>
<div class="item-detail" data-tooltip="Defense">
<a class="rollable" data-roll-type="shield-roll" data-roll-key="{{item.id}}" data-tooltip="Shield Defense">
<i class="lf-roll-small fa-solid fa-shield" data-roll-type="shield-roll" data-roll-key="{{item.id}}"></i>
{{upperFirst item.system.defense}}
</a>
</div>
<div class="item-detail" data-tooltip="Movement reduction">{{item.system.movementreduction}}</div>
<div class="item-detail" data-tooltip="Has cover">{{#if item.system.hascover}}Cover{{/if}}</div>
<div class="controls">
<a data-tooltip="{{localize 'LETHALFANTASY.Edit'}}" data-action="edit" data-item-id="{{item.id}}"
data-item-uuid="{{item.uuid}}"><i class="fas fa-edit"></i></a>
<a data-tooltip="{{localize 'LETHALFANTASY.Delete'}}" data-action="delete" data-item-id="{{item.id}}"
data-item-uuid="{{item.uuid}}"><i class="fas fa-trash"></i></a>
<fieldset>
<legend>{{localize "LETHALFANTASY.Label.armors"}}</legend>
<div class="armors">
{{#each armors as |item|}}
<div class="armor" data-item-id="{{item.id}}" data-item-uuid="{{item.uuid}}">
<img class="item-img" src="{{item.img}}" data-tooltip="{{item.name}}" />
<div class="name" data-tooltip="{{item.system.description}}">
{{item.name}}
</div>
<div class="item-detail" data-tooltip="Defense">{{item.system.defense}}</div>
<div class="item-detail" data-tooltip="Maximum movement">{{item.system.maximumMovement}}</div>
<div class="item-detail" data-tooltip="HP">{{item.system.hp}}</div>
<div class="item-detail" data-tooltip="Damage Reduction">{{item.system.damageReduction}}</div>
<div class="controls">
<a data-tooltip="{{localize 'LETHALFANTASY.Edit'}}" data-action="edit" data-item-id="{{item.id}}"
data-item-uuid="{{item.uuid}}"><i class="fas fa-edit"></i></a>
<a data-tooltip="{{localize 'LETHALFANTASY.Delete'}}" data-action="delete" data-item-id="{{item.id}}"
data-item-uuid="{{item.uuid}}"><i class="fas fa-trash"></i></a>
</div>
</div>
{{/each}}
</div>
{{/each}}
</div>
</fieldset>
</fieldset>
<fieldset>
<legend>{{localize "LETHALFANTASY.Label.shields"}}</legend>
<div class="shields">
{{#each shields as |item|}}
<div class="shield" data-item-id="{{item.id}}" data-item-uuid="{{item.uuid}}">
<img class="item-img" src="{{item.img}}" data-tooltip="{{item.name}}" />
<div class="name" data-tooltip="{{item.system.description}}">
{{item.name}}
</div>
<div class="item-detail" data-tooltip="Defense">
<a class="rollable" data-roll-type="shield-roll" data-roll-key="{{item.id}}" data-tooltip="Shield Defense">
<i class="lf-roll-small fa-solid fa-shield" data-roll-type="shield-roll" data-roll-key="{{item.id}}"></i>
{{upperFirst item.system.defense}}
</a>
</div>
<div class="item-detail" data-tooltip="Movement reduction">{{item.system.movementreduction}}</div>
<div class="item-detail" data-tooltip="Has cover">{{#if item.system.hascover}}Cover{{/if}}</div>
<div class="controls">
<a data-tooltip="{{localize 'LETHALFANTASY.Edit'}}" data-action="edit" data-item-id="{{item.id}}"
data-item-uuid="{{item.uuid}}"><i class="fas fa-edit"></i></a>
<a data-tooltip="{{localize 'LETHALFANTASY.Delete'}}" data-action="delete" data-item-id="{{item.id}}"
data-item-uuid="{{item.uuid}}"><i class="fas fa-trash"></i></a>
</div>
</div>
{{/each}}
</div>
</fieldset>
</div>
</section>

View File

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

View File

@@ -13,9 +13,11 @@
<fieldset class="">
<div class="flexrow character-hp">
<span class="name">{{localize "LETHALFANTASY.Label.HP"}}</span>
{{formInput systemFields.hp.fields.value value=system.hp.value disabled=isPlayMode classes="character-hp-value"}}
{{formInput systemFields.hp.fields.value value=system.hp.value disabled=isPlayMode
classes="character-hp-value"}}
&nbsp;/&nbsp;
{{formInput systemFields.hp.fields.max value=system.hp.max disabled=isPlayMode classes="character-hp-value"}}
{{formInput systemFields.hp.fields.max value=system.hp.max disabled=isPlayMode
classes="character-hp-value"}}
</div>
<div class="flexrow character-hp">
<span class="name">{{localize "LETHALFANTASY.Label.grit"}}</span>
@@ -36,7 +38,8 @@
<div class="flexrow ">
<span class="">{{localize "LETHALFANTASY.Label.damageResistanceShort"}}</span>
{{formInput systemFields.hp.fields.damageResistance value=system.hp.fields.damageResistance disabled=isPlayMode classes="character-hp"}}
{{formInput systemFields.hp.fields.damageResistance value=system.hp.fields.damageResistance
disabled=isPlayMode classes="character-hp"}}
</div>
@@ -81,39 +84,43 @@
<div class="character-save">
<span class="name">
<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"}}
</a>
</span>
</span>
{{formField systemFields.saves.fields.contagion.fields.value value=system.saves.contagion.value
disabled=true}}
<span class="name">
<a class="rollable" data-roll-type="save" data-roll-key="poison"><i
class="lf-roll-small fa-solid fa-dice-d20"></i>
{{localize "LETHALFANTASY.Label.saves.poison"}}
class="lf-roll-small fa-solid fa-dice-d20"></i>
{{localize "LETHALFANTASY.Label.saves.poison"}}
</a>
</span>
{{formField systemFields.saves.fields.poison.fields.value value=system.saves.poison.value
</span>
{{formField systemFields.saves.fields.poison.fields.value value=system.saves.poison.value
disabled=true }}
<!--
<span class="name-pain">
<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>
{{localize "LETHALFANTASY.Label.saves.pain"}}
<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>
{{localize "LETHALFANTASY.Label.saves.pain"}}
</a>
</span>
<span class="name-pain">
<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>
{{localize "LETHALFANTASY.Label.saves.pain"}}
<span class="name-pain">
<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>
{{localize "LETHALFANTASY.Label.saves.pain"}}
</a>
</span>
</span>
{{formField systemFields.saves.fields.pain.fields.value value=system.saves.pain.value disabled=true}}
<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>
-->
</div>
</div>
</fieldset>
@@ -132,7 +139,7 @@
class="lf-roll-small fa-solid fa-dice-d20"></i>{{localize
"LETHALFANTASY.Label.challenges.agility"}}</a></span>
{{formField systemFields.challenges.fields.agility.fields.value value=system.challenges.agility.value
disabled=true
disabled=true
}}
<span class="name"><a class="rollable" data-roll-type="challenge" data-roll-key="dying"><i
class="lf-roll-small fa-solid fa-dice-d20"></i>{{localize
@@ -174,14 +181,14 @@
<fieldset class="character-characteristics character-characteristics-{{ifThen isPlayMode 'play' 'edit'}}">
<legend>{{localize "LETHALFANTASY.Label.characteristics"}}</legend>
<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
disabled=isPlayMode data-char-id="str" }}
{{formField systemFields.characteristics.fields.str.fields.percent value=system.characteristics.str.percent
disabled=isPlayMode type="number"}}
</div>
<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
disabled=isPlayMode data-char-id="int" }}
@@ -189,7 +196,7 @@
disabled=isPlayMode type="number" }}
</div>
<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
disabled=isPlayMode data-char-id="wis" }}
@@ -197,7 +204,7 @@
disabled=isPlayMode type="number"}}
</div>
<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
disabled=isPlayMode data-char-id="wis" }}
@@ -205,7 +212,7 @@
disabled=isPlayMode type="number" }}
</div>
<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
disabled=isPlayMode data-char-id="con" }}
@@ -213,7 +220,7 @@
disabled=isPlayMode type="number"}}
</div>
<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
disabled=isPlayMode data-char-id="cha" }}
@@ -221,21 +228,13 @@
disabled=isPlayMode type="number"}}
</div>
<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
disabled=isPlayMode data-char-id="luc" }}
{{formField systemFields.characteristics.fields.luc.fields.percent value=system.characteristics.luc.percent
disabled=isPlayMode type="number"}}
</div>
<div class="character-characteristic">
{{localize "LETHALFANTASY.Label.app"}}
{{formField systemFields.characteristics.fields.app.fields.value value=system.characteristics.app.value
disabled=isPlayMode data-char-id="app" }}
{{formField systemFields.characteristics.fields.app.fields.percent value=system.characteristics.app.percent
disabled=isPlayMode type="number"}}
</div>
</fieldset>
</section>

View File

@@ -1,50 +1,52 @@
<section class="tab character-{{tab.id}} {{tab.cssClass}}" data-tab="{{tab.id}}" data-group="{{tab.group}}">
<div class="main-div">
<fieldset>
<legend>{{localize "LETHALFANTASY.Label.divinityPoints"}}</legend>
<div class="miracle-details">
<div class="miracle-detail">
<span >Current</span>
{{formField systemFields.divinityPoints.fields.value value=system.divinityPoints.value localize=true}}
<a data-action="divinityPointsPlus"><i class="fa-solid fa-hexagon-plus"></i></a>
<a data-action="divinityPointsMinus"><i class="fa-solid fa-hexagon-minus"></i></a>
<fieldset>
<legend>{{localize "LETHALFANTASY.Label.divinityPoints"}}</legend>
<div class="miracle-details">
<div class="miracle-detail">
<span>Current</span>
{{formField systemFields.divinityPoints.fields.value value=system.divinityPoints.value localize=true}}
<a data-action="divinityPointsPlus"><i class="fa-solid fa-hexagon-plus"></i></a>
<a data-action="divinityPointsMinus"><i class="fa-solid fa-hexagon-minus"></i></a>
<span >Max</span>
{{formField systemFields.divinityPoints.fields.max value=system.divinityPoints.max localize=true disabled=isPlayMode}}
<span>Max</span>
{{formField systemFields.divinityPoints.fields.max value=system.divinityPoints.max localize=true
disabled=isPlayMode}}
</div>
</div>
</div>
</fieldset>
</fieldset>
<fieldset>
<legend>{{localize "LETHALFANTASY.Label.miracles"}}{{#if isEditMode}}<a class="action" data-tooltip="{{localize "
LETHALFANTASY.Tooltip.addMiracle"}}" data-tooltip-direction="UP"><i class="fas fa-plus"
data-action="createMiracle"></i></a>{{/if}}</legend>
<div class="miracles">
{{#each miracles as |item|}}
<div class="miracle" data-item-id="{{item.id}}" data-item-uuid="{{item.uuid}}" data-drag="true" >
<img class="item-img" src="{{item.img}}" data-tooltip="{{item.name}}" />
<div class="name" >
{{item.name}}
</div>
<a class="rollable" data-roll-type="miracle-attack" data-roll-key="{{item.id}}" data-tooltip="Miracle Attack">
<i class="lf-roll-small fa-solid fa-swords" data-roll-type="miracle-attack" data-roll-key="{{item.id}}"></i>
</a>
<a class="rollable" data-roll-type="miracle-power" data-roll-key="{{item.id}}" data-tooltip="Miracle Power">
<i class="fa-duotone fa-solid fa-stars" data-roll-type="miracle-power" data-roll-key="{{item.id}}"></i>
</a>
<div class="controls">
<a data-tooltip="{{localize 'LETHALFANTASY.Edit'}}" data-action="edit" data-item-id="{{item.id}}"
data-item-uuid="{{item.uuid}}"><i class="fas fa-edit"></i></a>
<a data-tooltip="{{localize 'LETHALFANTASY.Delete'}}" data-action="delete" data-item-id="{{item.id}}"
data-item-uuid="{{item.uuid}}"><i class="fas fa-trash"></i></a>
<fieldset>
<legend>{{localize "LETHALFANTASY.Label.miracles"}}{{#if isEditMode}}<a class="action" data-tooltip="{{localize "
LETHALFANTASY.Tooltip.addMiracle"}}" data-tooltip-direction="UP"><i class="fas fa-plus"
data-action="createMiracle"></i></a>{{/if}}</legend>
<div class="miracles">
{{#each miracles as |item|}}
<div class="miracle" data-item-id="{{item.id}}" data-item-uuid="{{item.uuid}}" data-drag="true">
<img class="item-img" src="{{item.img}}" data-tooltip="{{item.name}}" />
<div class="name">
{{item.name}}
</div>
<a class="rollable" data-roll-type="miracle-attack" data-roll-key="{{item.id}}" data-tooltip="Miracle Attack">
<i class="lf-roll-small fa-solid fa-swords" data-roll-type="miracle-attack" data-roll-key="{{item.id}}"></i>
</a>
<a class="rollable" data-roll-type="miracle-power" data-roll-key="{{item.id}}" data-tooltip="Miracle Power">
<i class="fa-duotone fa-solid fa-stars" data-roll-type="miracle-power" data-roll-key="{{item.id}}"></i>
</a>
<div class="controls">
<a data-tooltip="{{localize 'LETHALFANTASY.Edit'}}" data-action="edit" data-item-id="{{item.id}}"
data-item-uuid="{{item.uuid}}"><i class="fas fa-edit"></i></a>
<a data-tooltip="{{localize 'LETHALFANTASY.Delete'}}" data-action="delete" data-item-id="{{item.id}}"
data-item-uuid="{{item.uuid}}"><i class="fas fa-trash"></i></a>
</div>
</div>
{{/each}}
</div>
{{/each}}
</div>
</fieldset>
</fieldset>
</div>
</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>
<legend data-tooltip="{{localize " LETHALFANTASY.Tooltip.skills"}}" data-tooltip-direction="UP">{{localize
@@ -68,5 +69,5 @@
{{/each}}
</div>
</fieldset>
</div>
</section>

View File

@@ -1,50 +1,51 @@
<section class="tab character-{{tab.id}} {{tab.cssClass}}" data-tab="{{tab.id}}" data-group="{{tab.group}}">
<div class="main-div">
<fieldset>
<legend>{{localize "LETHALFANTASY.Label.aetherPoints"}}</legend>
<div class="spell-details">
<div class="spell-detail">
<span >Current</span>
{{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="aetherPointsMinus"><i class="fa-solid fa-hexagon-minus"></i></a>
<fieldset>
<legend>{{localize "LETHALFANTASY.Label.aetherPoints"}}</legend>
<div class="spell-details">
<div class="spell-detail">
<span>Current</span>
{{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="aetherPointsMinus"><i class="fa-solid fa-hexagon-minus"></i></a>
<span >Max</span>
{{formField systemFields.aetherPoints.fields.max value=system.aetherPoints.max localize=true disabled=isPlayMode}}
<span>Max</span>
{{formField systemFields.aetherPoints.fields.max value=system.aetherPoints.max localize=true
disabled=isPlayMode}}
</div>
</div>
</div>
</fieldset>
</fieldset>
<fieldset>
<legend>{{localize "LETHALFANTASY.Label.spells"}}{{#if isEditMode}}<a class="action" data-tooltip="{{localize "
LETHALFANTASY.Tooltip.addSpell"}}" data-tooltip-direction="UP"><i class="fas fa-plus"
data-action="createSpell"></i></a>{{/if}}</legend>
<div class="spells">
{{#each spells as |item|}}
<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}}" />
<div class="name" >
{{item.name}}
</div>
<a class="rollable" data-roll-type="spell-attack" data-roll-key="{{item.id}}" data-tooltip="Spell Attack">
<i class="lf-roll-small fa-solid fa-swords" data-roll-type="spell-attack" data-roll-key="{{item.id}}"></i>
</a>
<a class="rollable" data-roll-type="spell-power" data-roll-key="{{item.id}}" data-tooltip="Spell Power">
<i class="fa-duotone fa-solid fa-stars" data-roll-type="spell-power" data-roll-key="{{item.id}}"></i>
</a>
<div class="controls">
<a data-tooltip="{{localize 'LETHALFANTASY.Edit'}}" data-action="edit" data-item-id="{{item.id}}"
data-item-uuid="{{item.uuid}}"><i class="fas fa-edit"></i></a>
<a data-tooltip="{{localize 'LETHALFANTASY.Delete'}}" data-action="delete" data-item-id="{{item.id}}"
data-item-uuid="{{item.uuid}}"><i class="fas fa-trash"></i></a>
<fieldset>
<legend>{{localize "LETHALFANTASY.Label.spells"}}{{#if isEditMode}}<a class="action" data-tooltip="{{localize "
LETHALFANTASY.Tooltip.addSpell"}}" data-tooltip-direction="UP"><i class="fas fa-plus"
data-action="createSpell"></i></a>{{/if}}</legend>
<div class="spells">
{{#each spells as |item|}}
<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}}" />
<div class="name">
{{item.name}}
</div>
<a class="rollable" data-roll-type="spell-attack" data-roll-key="{{item.id}}" data-tooltip="Spell Attack">
<i class="lf-roll-small fa-solid fa-swords" data-roll-type="spell-attack" data-roll-key="{{item.id}}"></i>
</a>
<a class="rollable" data-roll-type="spell-power" data-roll-key="{{item.id}}" data-tooltip="Spell Power">
<i class="fa-duotone fa-solid fa-stars" data-roll-type="spell-power" data-roll-key="{{item.id}}"></i>
</a>
<div class="controls">
<a data-tooltip="{{localize 'LETHALFANTASY.Edit'}}" data-action="edit" data-item-id="{{item.id}}"
data-item-uuid="{{item.uuid}}"><i class="fas fa-edit"></i></a>
<a data-tooltip="{{localize 'LETHALFANTASY.Delete'}}" data-action="delete" data-item-id="{{item.id}}"
data-item-uuid="{{item.uuid}}"><i class="fas fa-trash"></i></a>
</div>
</div>
{{/each}}
</div>
{{/each}}
</div>
</fieldset>
</fieldset>
</div>
</section>

View File

@@ -6,7 +6,7 @@
</div>
<div class="intro-right">
<span>{{upperFirst rollName}}</span>
<span><STRONG>{{actingCharName}} - {{upperFirst rollName}}</STRONG></span>
{{#if (match rollType "attack")}}
<span>Attack roll !</span>
@@ -15,15 +15,31 @@
<span>Defense roll !</span>
{{/if}}
{{#if (eq rollData.favor "favor")}}
<span><strong>Favor roll</strong></span>
{{/if}}
{{#if (eq rollData.favor "disfavor")}}
<span><strong>Disfavor roll</strong></span>
{{/if}}
{{#if badResult}}
<span>{{localize "LETHALFANTASY.Label.otherResult"}} : {{badResult}}</span>
<span><strong>{{localize "LETHALFANTASY.Label.otherResult"}}</strong> : {{badResult}}</span>
{{/if}}
{{#if rollTarget.weapon}}
<span>{{rollTarget.weapon.name}}</span>
{{/if}}
<span>Formula : {{titleFormula}}</span>
{{#if rollData.letItFly}}
<span>Let It Fly attack ! </span>
{{/if}}
{{#if rollData.pointBlank}}
<span>Point Blank Range Attack !</span>
{{/if}}
{{#if rollData.beyondSkill}}
<span>Beyond Skill Range Attack !</span>
{{/if}}
<span><strong>Formula</strong> : {{titleFormula}}</span>
{{#each diceResults as |result|}}
<span>{{result.dice}} : {{result.value}}</span>

View File

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

@@ -4,7 +4,7 @@
<legend>{{localize "LETHALFANTASY.Label.combatDetails"}}</legend>
<div class="combat-details">
<div class="combat-detail">
<button class="action" data-action="rangedAttackDefense">
{{localize "LETHALFANTASY.Label.rangedAttackDefense"}}
</button>
@@ -21,6 +21,9 @@
<div class="attacks">
{{#each system.attacks as |item key|}}
<div class="attack" data-attack-key="{{key}}" >
<div class="">
<input type="checkbox" name="system.attacks.{{item.key}}.enabled" value="{{item.enabled}}" data-tooltip="Attack enabled/disabled" />
</div>
<div class="name">
<input type="text" name="system.attacks.{{item.key}}.name" value="{{item.name}}" data-tooltip="Attack name" />
</div>

View File

@@ -13,13 +13,15 @@
<fieldset class="monster-characteristics monster-characteristics-{{ifThen isPlayMode 'play' 'edit'}}">
<div class="flexrow monster-hp">
<span class="name">{{localize "LETHALFANTASY.Label.HP"}}</span>
{{formInput systemFields.hp.fields.value value=system.hp.value disabled=isPlayMode classes="monster-hp-value"}}
{{formInput systemFields.hp.fields.value value=system.hp.value disabled=isPlayMode
classes="monster-hp-value"}}
&nbsp;/&nbsp;
{{formInput systemFields.hp.fields.max value=system.hp.max disabled=isPlayMode classes="monster-hp-value"}}
</div>
<div class="flexrow monster-hp">
<span class="damage-resistance">{{localize "LETHALFANTASY.Label.damageResistance"}}</span>
{{formInput systemFields.hp.fields.damageResistance value=system.hp.damageResistance disabled=isPlayMode classes="monster-hp-value"}}
{{formInput systemFields.hp.fields.damageResistance value=system.hp.damageResistance disabled=isPlayMode
classes="monster-hp-value"}}
</div>
</fieldset>
@@ -41,7 +43,8 @@
class="lf-roll-small fa-solid fa-dice-d20"></i>
{{localize "LETHALFANTASY.Label.saves.will"}}
</a></span>
{{formField systemFields.saves.fields.will.fields.value value=system.saves.will.value disabled=isPlayMode }}
{{formField systemFields.saves.fields.will.fields.value value=system.saves.will.value disabled=isPlayMode
}}
<span class="name">
<a class="rollable" data-roll-type="save" data-roll-key="dodge"><i
class="lf-roll-small fa-solid fa-dice-d20"></i>
@@ -62,25 +65,25 @@
<div class="monster-save">
<span class="name">
<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"}}
</a>
</span>
</span>
{{formField systemFields.saves.fields.contagion.fields.value value=system.saves.contagion.value
disabled=isPlayMode}}
<span class="name">
<a class="rollable" data-roll-type="save" data-roll-key="poison"><i
class="lf-roll-small fa-solid fa-dice-d20"></i>
{{localize "LETHALFANTASY.Label.saves.poison"}}
</a>
</span>
{{formField systemFields.saves.fields.poison.fields.value value=system.saves.poison.value
disabled=isPlayMode }}
<span class="name">
<a class="rollable" data-roll-type="save" data-roll-key="poison"><i
class="lf-roll-small fa-solid fa-dice-d20"></i>
{{localize "LETHALFANTASY.Label.saves.poison"}}
</a>
</span>
{{formField systemFields.saves.fields.poison.fields.value value=system.saves.poison.value
disabled=isPlayMode }}
<!-- <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
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"}}
</a>
</span>
@@ -88,10 +91,10 @@
<span data-tooltip="Pain save if wound exceeds">
{{formField systemFields.hp.fields.painDamage value=system.hp.painDamage disabled=isPlayMode tooltip="Pain Damage"}}
</span>
</span>-->
</div>
</div>
</fieldset>
@@ -102,19 +105,22 @@
<span class="name"><a class="rollable" data-roll-type="monster-skill" data-roll-key="resistTorture"><i
class="lf-roll-small fa-solid fa-dice-d20"></i>{{localize
"LETHALFANTASY.Label.resistTorture"}}</a></span>
{{formField systemFields.resists.fields.resistTorture.fields.value value=system.resists.resistTorture.value
{{formField systemFields.resists.fields.resistTorture.fields.value
value=system.resists.resistTorture.value
disabled=isPlayMode
}}
<span class="name"><a class="rollable" data-roll-type="monster-skill" data-roll-key="resistPerformance"><i
class="lf-roll-small fa-solid fa-dice-d20"></i>{{localize
"LETHALFANTASY.Label.resistPerformance"}}</a></span>
{{formField systemFields.resists.fields.resistPerformance.fields.value value=system.resists.resistPerformance.value
disabled=isPlayMode
{{formField systemFields.resists.fields.resistPerformance.fields.value
value=system.resists.resistPerformance.value
disabled=isPlayMode
}}
<span class="name"><a class="rollable" data-roll-type="monster-skill" data-roll-key="resistIntimidation"><i
class="lf-roll-small fa-solid fa-dice-d20"></i>{{localize
<span class="name"><a class="rollable" data-roll-type="monster-skill"
data-roll-key="resistIntimidation"><i class="lf-roll-small fa-solid fa-dice-d20"></i>{{localize
"LETHALFANTASY.Label.resistIntimidation"}}</a></span>
{{formField systemFields.resists.fields.resistIntimidation.fields.value value=system.resists.resistIntimidation.value
{{formField systemFields.resists.fields.resistIntimidation.fields.value
value=system.resists.resistIntimidation.value
disabled=isPlayMode }}
<span class="name"><a class="rollable" data-roll-type="monster-skill" data-roll-key="perception"><i
@@ -157,7 +163,7 @@
<fieldset class="monster-characteristics monster-characteristics-{{ifThen isPlayMode 'play' 'edit'}}">
<legend>{{localize "LETHALFANTASY.Label.characteristics"}}</legend>
<div class="monster-characteristic">
{{localize "LETHALFANTASY.Label.int"}}
<span>{{localize "LETHALFANTASY.Label.int"}}</span>
{{formField systemFields.characteristics.fields.int.fields.value value=system.characteristics.int.value
disabled=isPlayMode data-char-id="int" }}
@@ -165,7 +171,7 @@
disabled=isPlayMode type="number" }}
</div>
<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
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,27 +26,21 @@
<div class="field-section">
<span class="field-name">Range :</span>
<select name="range" data-tooltip-direction="UP">
{{selectOptions rangeChoices selected=range}}
</select>
</div>
<div class="field-section">
<span class="field-name">Aim :</span>
<select name="attackerAim" data-tooltip-direction="UP">
{{selectOptions attackerAimChoices selected=attackerAim}}
</select>
</div>
</fieldSet>
<fieldSet>
<legend>{{localize "LETHALFANTASY.Roll.visibility"}}</legend>
<select name="visibility">
{{selectOptions rollModes selected=visibility}}
</select>
<span class="fieldset-centered">
<select name="visibility">
{{selectOptions rollModes selected=visibility localize=true}}
</select>
</span>
</fieldSet>
</div>

View File

@@ -5,7 +5,8 @@
{{#if rollTarget.tokenId}}
<div class="dialog-save">
<a class="goto-token-button" data-action="gotoToken" data-token-id="{{rollTarget.tokenId}}">{{localize "LETHALFANTASY.Label.gotoToken"}} </a>
<a class="goto-token-button" data-action="gotoToken" data-token-id="{{rollTarget.tokenId}}">{{localize
"LETHALFANTASY.Label.gotoToken"}} </a>
</div>
{{/if}}
@@ -30,17 +31,37 @@
{{#if (match rollType "attack")}}
<div class="dialog-save">Add Granted Attack Dice
<input type="checkbox" data-action="selectGranted" name="granted" >
<input type="checkbox" data-action="selectGranted" name="granted">
</div>
{{#if rollTarget.weapon}}
{{#if (eq rollTarget.weapon.system.weaponType "melee")}}
{{else}}
<div class="dialog-save">Point Blank Range Attack
<input type="checkbox" data-action="selectPointBlank" name="pointBlankV">
</div>
<div class="dialog-save">Beyond Skill Range Attack
<input type="checkbox" data-action="selectBeyondSkill" name="beyondSkillV">
</div>
<div class="dialog-save">Let it Fly (Pure D20E)
<input type="checkbox" data-action="selectLetItFly" name="letItFlyV">
</div>
<div class="dialog-save">Aiming
<select name="attackerAim" data-tooltip-direction="UP">
{{selectOptions attackerAimChoices selected=attackerAim}}
</select>
</div>
{{/if}}
{{/if}}
{{/if}}
{{#if (match rollType "defense")}}
<div class="dialog-save">Add Granted Defense Dice
<input type="checkbox" data-action="selectGranted" name="granted" >
<input type="checkbox" data-action="selectGranted" name="granted">
</div>
{{/if}}
{{#if (match rollType "damage")}}
<div class="dialog-save">Add Granted Damage Dice
<input type="checkbox" data-action="selectGranted" name="granted" >
<input type="checkbox" data-action="selectGranted" name="granted">
</div>
{{/if}}
@@ -71,7 +92,7 @@
{{#if rollTarget.magicUser}}
<div>
<span>Save against spell (+{{rollTarget.actorModifiers.saveModifier}}) ?</span>
<input type="checkbox" name="saveSpell" value="saveSpell">
<input type="checkbox" name="saveSpellCheck" data-action="saveSpellCheck">
</div>
{{/if}}
{{/if}}
@@ -90,7 +111,7 @@
<fieldSet>
<legend>{{localize "LETHALFANTASY.Roll.visibility"}}</legend>
<select name="visibility">
{{selectOptions rollModes selected=visibility}}
{{selectOptions rollModes selected=visibility localize=true}}
</select>
</fieldSet>

View File

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

View File

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

View File

@@ -29,7 +29,7 @@
</div>
<div class="align-top">
<label>Destruction</label>
<!-- <label>Destruction</label>
<div class="shift-right">
{{formField systemFields.destruction.fields.bashing value=system.destruction.bashing}}
{{formField systemFields.destruction.fields.slashing value=system.destruction.slashing}}
@@ -41,7 +41,7 @@
{{formField systemFields.autodestruction.fields.bashing value=system.autodestruction.bashing}}
{{formField systemFields.autodestruction.fields.slashing value=system.autodestruction.slashing}}
{{formField systemFields.autodestruction.fields.piercing value=system.autodestruction.piercing}}
</div>
</div> -->
{{formField systemFields.equipped value=system.equipped}}