From 585b9a1ab527de1c0cc422bafbea6063521a04f2 Mon Sep 17 00:00:00 2001 From: LeRatierBretonnien Date: Sun, 25 May 2025 00:01:39 +0200 Subject: [PATCH] Add rolls and new fixes --- css/fvtt-hellborn.css | 75 +++++++-- lang/en.json | 25 ++- .../applications/sheets/character-sheet.mjs | 6 +- module/applications/sheets/tarot-sheet.mjs | 7 +- module/config/system.mjs | 52 +++--- module/documents/roll.mjs | 151 +++++++++--------- module/models/character.mjs | 8 +- module/models/tarot.mjs | 7 +- module/utils.mjs | 17 +- styles/character.less | 61 +++++-- styles/global.less | 6 + styles/roll.less | 13 +- system.json | 2 +- templates/character-equipment.hbs | 9 +- templates/character-main.hbs | 32 +++- templates/character-maleficas.hbs | 3 +- templates/character-status.hbs | 32 ++-- templates/chat-message.hbs | 50 ++++-- templates/roll-dialog.hbs | 45 ++---- templates/tarot.hbs | 11 +- 20 files changed, 389 insertions(+), 223 deletions(-) diff --git a/css/fvtt-hellborn.css b/css/fvtt-hellborn.css index 3c54f9a..c95f153 100644 --- a/css/fvtt-hellborn.css +++ b/css/fvtt-hellborn.css @@ -28,6 +28,11 @@ height: 50px; margin-left: 15px; } +.scrollable-content { + max-height: 600px; + overflow-y: auto; + padding-right: 10px; +} nav.tabs [data-tab] { color: var(--title-color); } @@ -283,6 +288,18 @@ i.fvtt-hellborn { font-size: calc(var(--font-size-standard) * 1.4); padding-left: 5px; } +.fvtt-hellborn .tab.character-status .main-div .mortality { + display: flex; + align-items: center; + gap: 4px; + margin-left: 4px; + min-width: 12rem; + max-width: 12rem; +} +.fvtt-hellborn .tab.character-status .main-div .mortality label { + min-width: 5rem; + max-width: 5rem; +} .fvtt-hellborn .tab.character-status .main-div .counters { display: flex; direction: column; @@ -348,8 +365,8 @@ i.fvtt-hellborn { max-width: 5rem; } .fvtt-hellborn .tab.character-status .main-div .perks .perk .level { - min-width: 2rem; - max-width: 2rem; + min-width: 4rem; + max-width: 4rem; } .fvtt-hellborn .tab.character-status .main-div .perks .perk .name { min-width: 10rem; @@ -391,12 +408,12 @@ i.fvtt-hellborn { max-width: 12rem; } .fvtt-hellborn .tab.character-maleficas .main-div .maleficas .malefica .domain { - min-width: 6rem; - max-width: 6rem; + min-width: 5rem; + max-width: 5rem; } .fvtt-hellborn .tab.character-maleficas .main-div .maleficas .malefica .level { - min-width: 2rem; - max-width: 2rem; + min-width: 3rem; + max-width: 3rem; } .fvtt-hellborn .tab.character-maleficas .main-div .maleficas .malefica .item-img { width: 24px; @@ -405,7 +422,7 @@ i.fvtt-hellborn { } .fvtt-hellborn .tab.character-maleficas .main-div .rituals { display: grid; - grid-template-columns: repeat(2, 1fr); + grid-template-columns: repeat(1, 1fr); gap: 4px; } .fvtt-hellborn .tab.character-maleficas .main-div .rituals .ritual { @@ -420,6 +437,10 @@ i.fvtt-hellborn { min-width: 1.8rem; max-width: 1.8rem; } +.fvtt-hellborn .tab.character-maleficas .main-div .rituals .ritual .ingredients { + min-width: 26rem; + max-width: 26rem; +} .fvtt-hellborn .tab.character-maleficas .main-div .rituals .ritual .name { min-width: 12rem; max-width: 12rem; @@ -450,6 +471,23 @@ i.fvtt-hellborn { font-size: calc(var(--font-size-standard) * 1.4); padding-left: 5px; } +.fvtt-hellborn .tab.character-equipment .main-div .limboes { + display: flex; + flex-direction: row; +} +.fvtt-hellborn .tab.character-equipment .main-div .limboes .form-group { + display: flex; + flex-direction: row; + align-items: center; + gap: 4px; + margin-left: 4px; + min-width: 14rem; + max-width: 14rem; +} +.fvtt-hellborn .tab.character-equipment .main-div .limboes input { + min-width: 8rem; + max-width: 8rem; +} .fvtt-hellborn .tab.character-equipment .main-div .weapons { display: grid; grid-template-columns: repeat(1, 1fr); @@ -473,8 +511,8 @@ i.fvtt-hellborn { max-width: 1.8rem; } .fvtt-hellborn .tab.character-equipment .main-div .weapons .weapon .properties { - min-width: 24rem; - max-width: 24rem; + min-width: 21rem; + max-width: 21rem; } .fvtt-hellborn .tab.character-equipment .main-div .weapons .weapon .type { min-width: 4rem; @@ -2469,22 +2507,22 @@ i.fvtt-hellborn { font-family: var(--font-secondary); font-size: calc(var(--font-size-standard) * 1.1); } -.application.dialog.fvtt-cthulhu-eternal { +.application.dialog.fvtt-hellborn { color: var(--color-dark-1); background-color: var(--color-light-1); } -.application.dialog.fvtt-cthulhu-eternal button { +.application.dialog.fvtt-hellborn button { background-image: none; background-color: var(--color-dark-6); color: var(--color-light-1); } -.application.dialog.fvtt-cthulhu-eternal input, -.application.dialog.fvtt-cthulhu-eternal select { +.application.dialog.fvtt-hellborn input, +.application.dialog.fvtt-hellborn select { background-color: rgba(0, 0, 0, 0.1); border-color: var(--color-dark-6); color: var(--color-dark-2); } -.fvtt-cthulhu-eternal-roll-dialog fieldset { +.fvtt-hellborn-roll-dialog fieldset { padding: 10px; background-color: var(--color-light-1); } @@ -2562,12 +2600,17 @@ i.fvtt-hellborn { margin-left: 4rem; display: none; } +.dice-roll .intro-chat .intro-right ul .result-unknown { + color: var(--color-dark-2); + font-family: var(--font-title); + font-size: var(--font-size-result); +} .dice-roll .intro-chat .intro-right ul .result-success { color: var(--color-success); font-family: var(--font-title); font-size: var(--font-size-result); } -.dice-roll .intro-chat .intro-right ul .result-critical-success { +.dice-roll .intro-chat .intro-right ul .result-satanic-success { color: var(--color-critical-success); font-family: var(--font-title); font-size: var(--font-size-result); @@ -2577,7 +2620,7 @@ i.fvtt-hellborn { font-family: var(--font-title); font-size: var(--font-size-result); } -.dice-roll .intro-chat .intro-right ul .result-critical-failure { +.dice-roll .intro-chat .intro-right ul .result-fiendish-failure { color: var(--color-critical-failure); font-family: var(--font-title); font-size: var(--font-size-result); diff --git a/lang/en.json b/lang/en.json index 5c0681a..33061f3 100644 --- a/lang/en.json +++ b/lang/en.json @@ -21,6 +21,18 @@ }, "Character": { "FIELDS": { + "mortality": { + "label": "Mortality", + "current": { + "label": "Mortality" + } + }, + "limboes": { + "label": "Limboes" + }, + "ammo": { + "label": "Ammo" + }, "age": { "label": "Age" }, @@ -315,6 +327,12 @@ } }, "Label": { + "difficulty": "Difficulty", + "unknown": "Unknown", + "statRoll": "Stat Roll", + "stat": "Stat", + "formula": "Formula", + "characteristics": "Characteristics", "deals": "Deals", "tarot": "Tarot", "backstory": "Backstory", @@ -342,8 +360,11 @@ "combat": "Combat", "Counters": "Counters", "creature": "Creature", - "criticalFailure": "Critical Failure", - "criticalSuccess": "Critical Success", + "fiendishSuccess": "Fiendish Failure", + "satanicSuccess": "Satanic Success", + "bonus": "Bonus", + "penalty": "Penalty", + "quote": "Quote", "current": "Curr.", "damage": "Damage", "damages": "Damages", diff --git a/module/applications/sheets/character-sheet.mjs b/module/applications/sheets/character-sheet.mjs index 6ee6d98..6ba81fb 100644 --- a/module/applications/sheets/character-sheet.mjs +++ b/module/applications/sheets/character-sheet.mjs @@ -73,6 +73,8 @@ export default class HellbornCharacterSheet extends HellbornActorSheet { const doc = this.document context.trait = doc.itemTypes['species-trait']?.[0] + context.upright = doc.itemTypes.tarot.find(t => t.system.orientation === "Upright") + context.downright = doc.itemTypes.tarot.find(t => t.system.orientation === "Downright") return context } @@ -108,8 +110,6 @@ export default class HellbornCharacterSheet extends HellbornActorSheet { case "biography": context.tab = context.tabs.biography context.deals = doc.itemTypes.deal - context.deals.sort((a, b) => a.name.localeCompare(b.name)) - context.tarot = doc.itemTypes.tarot?.[0] context.enrichedBackstory = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.backstory, { async: true }) context.enrichedAppearance = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.appearance, { async: true }) context.enrichedScars = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.scars, { async: true }) @@ -199,7 +199,7 @@ export default class HellbornCharacterSheet extends HellbornActorSheet { const item = await fromUuid(data.uuid) if (item.type === "tarot") { // Delete the existing tarot item - const existingTarot = this.document.items.find(i => i.type === "tarot") + const existingTarot = this.document.items.find(i => i.type === "tarot" && i.system.orientation === item.system.orientation) if (existingTarot) { await existingTarot.delete() // Display info message diff --git a/module/applications/sheets/tarot-sheet.mjs b/module/applications/sheets/tarot-sheet.mjs index 8dbc2f6..512baec 100644 --- a/module/applications/sheets/tarot-sheet.mjs +++ b/module/applications/sheets/tarot-sheet.mjs @@ -6,7 +6,7 @@ export default class HellbornTarotSheet extends HellbornItemSheet { classes: ["tarot"], position: { width: 800, - height: 640 + height: 800 }, window: { contentClasses: ["tarot-content"], @@ -23,8 +23,9 @@ export default class HellbornTarotSheet extends HellbornItemSheet { /** @override */ async _prepareContext() { const context = await super._prepareContext() - context.enrichedPositiveEffect = await TextEditor.enrichHTML(this.document.system.positiveEffect, { async: true }) - context.enrichedNegativeEffect = await TextEditor.enrichHTML(this.document.system.negativeEffect, { async: true }) + context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description, { async: true }) + context.enrichedPositiveEffect = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.positiveEffect, { async: true }) + context.enrichedNegativeEffect = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.negativeEffect, { async: true }) return context } } diff --git a/module/config/system.mjs b/module/config/system.mjs index ddb82a3..1b8e3b7 100644 --- a/module/config/system.mjs +++ b/module/config/system.mjs @@ -31,6 +31,25 @@ export const STATS = { "soul": { id: "soul", label: "Soul" } } +export const DIFFICULTY_CHOICES = { + "unknown": { id: "unknown", label: "Unknown", value: "0" }, + "trivial": { id: "trivial", label: "Trivial", value: "7" }, + "easy": { id: "easy", label: "Easy", value: "9" }, + "normal": { id: "normal", label: "Normal", value: "11" }, + "hard": { id: "hard", label: "Hard", value: "15" }, + "very-hard": { id: "very-hard", label: "Very Hard", value: "18" }, + "impossible": { id: "impossible", label: "Impossible", value: "20" } +} + +export const CHOICE_ADVANTAGES_DISADVANTAGES ={ + "0": { id: "0", label: "None", value: "0" }, + "1": { id: "1", label: "One", value: "1" }, + "2": { id: "2", label: "Two", value: "2" }, + "3": { id: "3", label: "Three", value: "3" }, + "4": { id: "4", label: "Four", value: "4" }, + "5": { id: "5", label: "Five", value: "5" }, +} + export const PERK_ROLES = { "abbetor": { id: "abbetor", label: "Abbetor" }, "blade": { id: "blade", label: "Blade" }, @@ -71,34 +90,6 @@ export const WEAPON_TYPES = { "ranged": { id: "ranged", label: "Ranged" }, } -export const RANGED_SUBTYPES = { - "pistols": { id: "pistols", label: "Pistols" }, - "rifles": { id: "rifles", label: "Rifles" }, - "shotguns": { id: "shotguns", label: "Shotguns" }, - "submachineguns": { id: "submachineguns ", label: "Sub machine guns" }, - "grenades": { id: "grenades", label: "Grenades" }, - "heavy": { id: "heavy", label: "Heavy Weapons" }, -} - -export const ATTACK_MODIFIERS = { - "two-attacks": -1, - "aiming": 1, - "dim": -1, - "darkness": -2, - "prone": -1, - "cover": -2, - "recoil-first": -1, - "recoil-third": -2, - "aware": -1 -} - -export const MODIFIER_CHOICES = { - "easy": { id: "easy", label: "HELLBORN.Label.Easy", value :"1" }, - "moderate": { id: "moderate", label: "HELLBORN.Label.Moderate", value: "0" }, - "difficult": { id: "difficult", label: "HELLBORN.Label.Difficult", value: "-1" }, - "formidable": { id: "formidable", label: "HELLBORN.Label.Formidable", value: "-2" }, - "impossible": { id: "impossible", label: "HELLBORN.Label.Impossible", value: "-4" } -} /** * Include all constant definitions within the SYSTEM global export @@ -112,9 +103,8 @@ export const SYSTEM = { PERK_LEVELS, MALEFICA_LEVELS, MALEFICA_DOMAINS, - MODIFIER_CHOICES, - ATTACK_MODIFIERS, WEAPON_TYPES, - RANGED_SUBTYPES, + DIFFICULTY_CHOICES, + CHOICE_ADVANTAGES_DISADVANTAGES, ASCII } diff --git a/module/documents/roll.mjs b/module/documents/roll.mjs index 5d29dde..ef3b56e 100644 --- a/module/documents/roll.mjs +++ b/module/documents/roll.mjs @@ -62,11 +62,7 @@ export default class HellbornRoll extends Roll { static updateFullFormula(options) { let fullFormula - if ( options.numericModifier >= 0) { - fullFormula = `${options.formula} + ${options.rollItem.value} + ${options.numericModifier}D` - } else { - fullFormula = `${options.formula} + ${options.rollItem.value} - ${Math.abs(options.numericModifier)}D` - } + fullFormula = `3D6 + ${options.nbAdvantages}D6kh - ${options.nbDisadvantages}D6kh + ${options.rollItem.value}` $('#roll-dialog-full-formula').text(fullFormula) options.fullFormula = fullFormula } @@ -86,81 +82,68 @@ export default class HellbornRoll extends Roll { * @returns {Promise} The roll result or null if the dialog was cancelled. */ static async prompt(options = {}) { - let formula = "2d6" + let formula = `3D6 + 0D6KH - 0D6KH + ${options?.rollItem?.value}` switch (options.rollType) { - case "skill": + case "stat": break case "damage": - let formula = options.rollItem.system.damage - let damageRoll = new Roll(formula) - await damageRoll.evaluate() - await damageRoll.toMessage({ - flavor: `${options.rollItem.name} - Damage Roll` - }); - return + { + let formula = options.rollItem.system.damage + let damageRoll = new Roll(formula) + await damageRoll.evaluate() + await damageRoll.toMessage({ + flavor: `${options.rollItem.name} - Damage Roll` + }); + return + } case "weapon": - let actor = game.actors.get(options.actorId) - options.weapon = foundry.utils.duplicate(options.rollItem) - options.rollItem = actor.system.skills.combat + { + let actor = game.actors.get(options.actorId) + options.weapon = foundry.utils.duplicate(options.rollItem) + let statKey = "skin" + if (options.weapon.system.weaponType === "melee") { + if ( options.weapon.system.properties.toLowerCase().match("heavy") || options.weapon.system.properties.toLowerCase().match("oversized")) { + statKey = "flesh" + } + } + options.rollItem = actor.system.stats[statKey] + } break default: break } - 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", }) - const choiceModifier = SYSTEM.MODIFIER_CHOICES - let choiceRangeModifier = {} - let rangeModifier = 0 - if ( options.weapon) { - // Build the range modifiers - let range = SYSTEM.WEAPON_RANGE[options.weapon.system.rangeType] - for (let [key, value] of Object.entries(range.range)) { - choiceRangeModifier[key] = { label: `${key} (${value}D)`, value: value } - if (!rangeModifier && value) { - rangeModifier = value - } - } - } - - let modifier = "0" - options.numericModifier = rangeModifier - let fullFormula = `${formula} + ${options.rollItem.value}` - if (options.isEncumbered) { - options.numericModifier += -1 - fullFormula += ` - ${options.numericModifier}D` - } else { - options.numericModifier += 0 - fullFormula += ` + ${options.numericModifier}D` - } - options.fullFormula = fullFormula options.formula = formula + options.nbAdvantages = "0" + options.nbDisadvantages = "0" let dialogContext = { actorId: options.actorId, actorName: options.actorName, rollType: options.rollType, rollItem: foundry.utils.duplicate(options.rollItem), // Object only, no class - fullFormula, weapon: options?.weapon, - isEncumbered: options.isEncumbered, - talents: options.talents, + formula: formula, + fullFormula: formula, rollModes, fieldRollMode, - choiceModifier, - choiceRangeModifier, - rangeModifier, - formula, + difficultyChoices: SYSTEM.DIFFICULTY_CHOICES, + choiceAdvantages: SYSTEM.CHOICE_ADVANTAGES_DISADVANTAGES, + choiceDisadvantages: SYSTEM.CHOICE_ADVANTAGES_DISADVANTAGES, hasTarget: options.hasTarget, - modifier, + difficulty: "unknown", + nbAdvantages: "0", + nbDisadvantages: "0", } - const content = await renderTemplate("systems/fvtt-hellborn/templates/roll-dialog.hbs", dialogContext) + const content = await foundry.applications.handlebars.renderTemplate("systems/fvtt-hellborn/templates/roll-dialog.hbs", dialogContext) const title = HellbornRoll.createTitle(options.rollType, options.rollTarget) const label = game.i18n.localize("HELLBORN.Roll.roll") @@ -184,19 +167,19 @@ export default class HellbornRoll extends Roll { }, rejectClose: false, // Click on Close button will not launch an error render: (event, dialog) => { - $(".roll-skill-modifier").change(event => { - options.numericModifier += Number(event.target.value) + $(".roll-stat-advantages").change(event => { + options.nbAdvantages = Number(event.target.value) HellbornRoll.updateFullFormula(options) }) - $(".roll-skill-range-modifier").change(event => { - options.numericModifier += Number(event.target.value) + $(".roll-stat-disadvantages").change(event => { + options.nbDisadvantages = Number(event.target.value) HellbornRoll.updateFullFormula(options) }) $(".select-combat-option").change(event => { console.log(event) let field = $(event.target).data("field") let modifier = SYSTEM.ATTACK_MODIFIERS[field] - if ( event.target.checked) { + if (event.target.checked) { options.numericModifier += modifier } else { options.numericModifier -= modifier @@ -211,42 +194,55 @@ export default class HellbornRoll extends Roll { let rollData = foundry.utils.mergeObject(foundry.utils.duplicate(options), rollContext) rollData.rollMode = rollContext.visibility - // Update target score rollData.targetScore = 8 if (Hooks.call("fvtt-hellborn.preRoll", options, rollData) === false) return - let diceFormula = `${2+Math.abs(options.numericModifier)}D6` - if ( options.numericModifier > 0 ) { - diceFormula += `kh2 + ${options.rollItem.value}` - } else { - diceFormula += `kl2 + ${options.rollItem.value}` - } - + options.nbAdvantages = Number(options.nbAdvantages) + options.nbDisadvantages = Number(options.nbDisadvantages) + let diceFormula = `3D6 + ${options.nbAdvantages}D6kh - ${options.nbDisadvantages}D6kh + ${options.rollItem.value}` const roll = new this(diceFormula, options.data, rollData) await roll.evaluate() + console.log("Roll", rollData, roll) + options.difficulty = (rollData.difficulty === "unknown") ? 0 : (Number(rollData.difficulty) || 0) - roll.displayRollResult(roll, options, rollData) + roll.displayRollResult(roll, options, rollData, roll) if (Hooks.call("fvtt-hellborn.Roll", options, rollData, roll) === false) return return roll } - displayRollResult(formula, options, rollData) { - - // Compute the result quality + displayRollResult(formula, options, rollData, roll) { let resultType = "failure" - if (this.total >= 8) { + if (options.difficulty === 0) { + resultType = "unknown" + } else if (this.total >= options.difficulty) { resultType = "success" - // Detect if decimal == unit in the dire total result } - + // Compute the result quality + this.options.satanicSuccess = false + this.options.fiendishFailure = false + this.options.rollData = foundry.utils.duplicate(rollData) + if (resultType === "success") { + let nb6 = roll.terms[0].results.filter(r => r.result === 6).length + nb6 += roll.terms[3].total === 6 ? 1 : 0 + this.options.satanicSuccess = nb6 >= 3 + if (this.options.satanicSuccess) { + resultType = "success" + } + } + if (resultType === "failure") { + let nb1 = roll.terms[0].results.filter(r => r.result === 1).length + nb1 += roll.terms[5].total === 1 ? 1 : 0 + this.options.fiendishFailure = nb1 >= 3 + if (this.options.fiendishFailure) { + resultType = "failure" + } + } this.options.resultType = resultType this.options.isSuccess = resultType === "success" this.options.isFailure = resultType === "failure" - this.options.isEncumbered = rollData.isEncumbered - this.options.rollData = foundry.utils.duplicate(rollData) } /** @@ -258,8 +254,8 @@ export default class HellbornRoll extends Roll { */ static createTitle(type, target) { switch (type) { - case "skill": - return `${game.i18n.localize("HELLBORN.Label.titleSkill")}` + case "stat": + return `${game.i18n.localize("HELLBORN.Label.titleStat")}` case "weapon": return `${game.i18n.localize("HELLBORN.Label.titleWeapon")}` default: @@ -270,7 +266,7 @@ export default class HellbornRoll extends Roll { /** @override */ async render(chatOptions = {}) { let chatData = await this._getChatCardData(chatOptions.isPrivate) - return await renderTemplate(this.constructor.CHAT_TEMPLATE, chatData) + return await foundry.applications.handlebars.renderTemplate(this.constructor.CHAT_TEMPLATE, chatData) } /** @@ -317,7 +313,6 @@ export default class HellbornRoll extends Roll { cardData.realDamage = this.realDamage cardData.isPrivate = isPrivate cardData.weapon = this.weapon - cardData.isEncumbered = this.isEncumbered cardData.cssClass = cardData.css.join(" ") cardData.tooltip = isPrivate ? "" : await this.getTooltip() diff --git a/module/models/character.mjs b/module/models/character.mjs index 77fb5b0..a16ae0f 100644 --- a/module/models/character.mjs +++ b/module/models/character.mjs @@ -56,9 +56,12 @@ export default class HellbornActor extends foundry.abstract.TypeDataModel { schema.species = new fields.StringField({ required: true, nullable: false, initial: "" }) schema.trait = new fields.StringField({ required: true, nullable: false, initial: "" }) + schema.limboes = new fields.StringField({ required: true, nullable: false, initial: "" }) + schema.ammo = new fields.StringField({ required: true, nullable: false, initial: "" }) + schema.mortality = new fields.SchemaField({ - current: new fields.NumberField({ ...requiredInteger, initial: 1, min: 0 }), - max: new fields.NumberField({ ...requiredInteger, initial: 1, min: 0 }), + current: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), + max: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), }) schema.trauma = new fields.SchemaField({ @@ -134,7 +137,6 @@ export default class HellbornActor extends foundry.abstract.TypeDataModel { actorId: this.parent.id, actorName: this.parent.name, actorImage: this.parent.img, - talents: this.parent.items.filter(i => i.type === "talent" && i.system.isAdvantage), hasTarget, target: opponentTarget }) diff --git a/module/models/tarot.mjs b/module/models/tarot.mjs index 682ffbd..a447b4c 100644 --- a/module/models/tarot.mjs +++ b/module/models/tarot.mjs @@ -5,7 +5,12 @@ export default class HellbornTarot extends foundry.abstract.TypeDataModel { const fields = foundry.data.fields; const schema = {}; - schema.orientation = new fields.StringField({ required: true, initial: "Upright", choices: {"Upright": {label: "Upright"}, "Reversed": {label: "Reversed"}} }); + schema.quote = new fields.StringField({ required: true, nullable: false, initial: "" }); + schema.bonus = new fields.StringField({ required: true, nullable: false, initial: "" }); + schema.penalty = new fields.StringField({ required: true, nullable: false, initial: "" }); + + schema.orientation = new fields.StringField({ required: true, initial: "Upright", choices: {"Upright": {label: "Upright"}, "Downright": {label: "Downright"}} }); + schema.description = new fields.HTMLField({ required: true, textSearch: true }) schema.positiveEffect = new fields.HTMLField({ required: true, textSearch: true }) schema.negativeEffect = new fields.HTMLField({ required: true, textSearch: true }) schema.image = new fields.FilePathField({ diff --git a/module/utils.mjs b/module/utils.mjs index 7358dde..e1b46b1 100644 --- a/module/utils.mjs +++ b/module/utils.mjs @@ -168,7 +168,22 @@ export default class HellbornUtils { Handlebars.registerHelper('isCreature', function (key) { return key === "creature" || key === "daemon"; }) - + Handlebars.registerHelper('getRomanLevel', function (level) { + if (level=== "highpowers") return "High"; + if (level === "mastery") return "Mastery"; + level = parseInt(level); + if (level === 0) return "I"; + if (level === 1) return "II"; + if (level === 2) return "III"; + if (level === 3) return "IV"; + if (level === 4) return "V"; + if (level === 5) return "VI"; + if (level === 6) return "VII"; + if (level === 7) return "VIII"; + if (level === 8) return "IX"; + if (level === 9) return "X"; + return level; + }) // Handle v12 removal of this helper Handlebars.registerHelper('select', function (selected, options) { const escapedValue = RegExp.escape(Handlebars.escapeExpression(selected)); diff --git a/styles/character.less b/styles/character.less index 4920e81..5ba284c 100644 --- a/styles/character.less +++ b/styles/character.less @@ -78,7 +78,7 @@ max-width: 16rem; margin-bottom: auto; } - .trait{ + .trait { min-width: 13rem; max-width: 13rem; margin-right: 1rem; @@ -139,7 +139,7 @@ } .character-stats-play { - min-width:120px; + min-width: 120px; } .character-stats-edit { @@ -157,6 +157,19 @@ padding-left: 5px; } } + .mortality { + display: flex; + align-items: center; + gap: 4px; + margin-left: 4px; + min-width: 12rem; + max-width: 12rem; + label { + min-width: 5rem; + max-width: 5rem; + } + } + .counters { display: flex; direction: column; @@ -220,8 +233,8 @@ max-width: 5rem; } .level { - min-width: 2rem; - max-width: 2rem; + min-width: 4rem; + max-width: 4rem; } .name { min-width: 10rem; @@ -267,12 +280,12 @@ max-width: 12rem; } .domain { - min-width: 6rem; - max-width: 6rem; + min-width: 5rem; + max-width: 5rem; } .level { - min-width: 2rem; - max-width: 2rem; + min-width: 3rem; + max-width: 3rem; } .item-img { width: 24px; @@ -284,7 +297,7 @@ .rituals { display: grid; - grid-template-columns: repeat(2, 1fr); + grid-template-columns: repeat(1, 1fr); gap: 4px; .ritual { display: flex; @@ -297,6 +310,10 @@ min-width: 1.8rem; max-width: 1.8rem; } + .ingredients { + min-width: 26rem; + max-width: 26rem; + } .name { min-width: 12rem; max-width: 12rem; @@ -320,10 +337,8 @@ } } } - } - .tab.character-equipment .main-div { background-color: var(--color-light-1); display: grid; @@ -335,6 +350,24 @@ } } + .limboes { + display: flex; + flex-direction: row; + .form-group { + display: flex; + flex-direction: row; + align-items: center; + gap: 4px; + margin-left: 4px; + min-width: 14rem; + max-width: 14rem; + } + input { + min-width: 8rem; + max-width: 8rem; + } + } + .weapons { display: grid; grid-template-columns: repeat(1, 1fr); @@ -356,8 +389,8 @@ max-width: 1.8rem; } .properties { - min-width: 24rem; - max-width: 24rem; + min-width: 21rem; + max-width: 21rem; } .type { min-width: 4rem; @@ -469,7 +502,7 @@ } } .splitted-text { - display:flex; + display: flex; flex-direction: row; gap: 4px; fieldset { diff --git a/styles/global.less b/styles/global.less index 1fe579f..3f84666 100644 --- a/styles/global.less +++ b/styles/global.less @@ -24,6 +24,12 @@ margin-left: 15px; } +.scrollable-content { + max-height: 600px; // Définissez la hauteur maximale selon vos besoins + overflow-y: auto; // Active le défilement vertical quand nécessaire + padding-right: 10px; // Espace pour la barre de défilement +} + nav.tabs [data-tab] { color: var(--title-color); } diff --git a/styles/roll.less b/styles/roll.less index 3053f8d..9c3b5b0 100644 --- a/styles/roll.less +++ b/styles/roll.less @@ -1,4 +1,4 @@ -.application.dialog.fvtt-cthulhu-eternal { +.application.dialog.fvtt-hellborn { color: var(--color-dark-1); background-color: var(--color-light-1); @@ -16,7 +16,7 @@ } } -.fvtt-cthulhu-eternal-roll-dialog { +.fvtt-hellborn-roll-dialog { fieldset { padding: 10px; background-color: var(--color-light-1); @@ -98,12 +98,17 @@ margin-left: 4rem; display: none; } + .result-unknown { + color: var(--color-dark-2); + font-family: var(--font-title); + font-size: var(--font-size-result); + } .result-success { color: var(--color-success); font-family: var(--font-title); font-size: var(--font-size-result); } - .result-critical-success { + .result-satanic-success { color: var(--color-critical-success); font-family: var(--font-title); font-size: var(--font-size-result); @@ -113,7 +118,7 @@ font-family: var(--font-title); font-size: var(--font-size-result); } - .result-critical-failure { + .result-fiendish-failure { color: var(--color-critical-failure); font-family: var(--font-title); font-size: var(--font-size-result); diff --git a/system.json b/system.json index 40409be..161f33e 100644 --- a/system.json +++ b/system.json @@ -45,7 +45,7 @@ "malefica": { "htmlFields": ["description"] }, "species-trait": { "htmlFields": ["description"] }, "ritual": { "htmlFields": ["description"] }, - "tarot": { "htmlFields": ["description"] }, + "tarot": { "htmlFields": ["description", "positiveEffect", "negativeEFfect"] }, "deal": { "htmlFields": ["description"] } } }, diff --git a/templates/character-equipment.hbs b/templates/character-equipment.hbs index 821b07e..ce8fab5 100644 --- a/templates/character-equipment.hbs +++ b/templates/character-equipment.hbs @@ -1,5 +1,6 @@
+
{{localize "HELLBORN.Label.weapons"}}{{#if isEditMode}} - {{localize "HELLBORN.Label.damageShort"}} : {{item.system.damage}}
@@ -84,5 +84,12 @@ {{/each}}
+ +
+ Limbos & Ammo + {{formField systemFields.limboes value=system.limboes rootId=partId disabled=isPlayMode}} + {{formField systemFields.ammo value=system.ammo rootId=partId disabled=isPlayMode}} +
+
\ No newline at end of file diff --git a/templates/character-main.hbs b/templates/character-main.hbs index 5b986f5..e9f1386 100644 --- a/templates/character-main.hbs +++ b/templates/character-main.hbs @@ -36,6 +36,28 @@ data-item-uuid="{{trait.uuid}}"> +
+
+ + +
+ + +
+
+
+
+ + +
+ + +
+
@@ -46,27 +68,27 @@
{{localize "HELLBORN.Label.stats"}}
-
-
-
-
-
diff --git a/templates/character-maleficas.hbs b/templates/character-maleficas.hbs index fc7a546..188867c 100644 --- a/templates/character-maleficas.hbs +++ b/templates/character-maleficas.hbs @@ -16,7 +16,7 @@ {{item.name}}
{{upperFirst item.system.domain}} - {{upperFirst item.system.level}} + {{getRomanLevel item.system.level}} + {{upperFirst item.system.ingredients}} {{upperFirst item.system.difficulty}} {{upperFirst item.system.threshold}} {{upperFirst item.system.limit}} diff --git a/templates/character-status.hbs b/templates/character-status.hbs index 07a7261..70a57dc 100644 --- a/templates/character-status.hbs +++ b/templates/character-status.hbs @@ -2,7 +2,7 @@ \ No newline at end of file diff --git a/templates/chat-message.hbs b/templates/chat-message.hbs index 0780085..cfea0ad 100644 --- a/templates/chat-message.hbs +++ b/templates/chat-message.hbs @@ -7,8 +7,8 @@
    - {{#if (eq rollType "skill")}} -
  • {{localize "HELLBORN.Label.skillRoll"}}
  • + {{#if (eq rollType "stat")}} +
  • {{localize "HELLBORN.Label.statRoll"}}
  • {{/if}} @@ -16,24 +16,42 @@
  • Weapon : {{weapon.name}}
  • {{/if}} -
  • {{localize rollItem.label}} : {{fullFormula}}
  • +
  • {{localize rollItem.label}} : {{rollItem.value}}
  • - {{#if isEncumbered}} -
  • Encumbered : -1D
  • - {{/if}} +
  • {{localize "HELLBORN.Label.difficulty"}} : {{difficulty}}
  • -
  • {{localize "HELLBORN.Label.modifier"}} : {{numericModifier}}D
  • - - {{#if isSuccess}} -
  • - {{localize "HELLBORN.Label.success"}} + {{#if (eq resultType "unknown")}} +
  • + {{localize "HELLBORN.Label.unknown"}}
  • - {{/if}} + {{else}} + {{#if isSuccess}} + {{#if satanicSuccess}} +
  • + {{localize "HELLBORN.Label.satanicSuccess"}} +
  • + {{else}} +
  • + {{localize "HELLBORN.Label.success"}} +
  • + {{/if}} + {{/if}} - {{#if isFailure}} -
  • - {{localize "HELLBORN.Label.failure"}} -
  • + + {{#if isFailure}} + {{#if fiendishFailure}} +
  • + {{localize "HELLBORN.Label.fiendishFailure"}} +
  • + {{else}} +
  • + {{localize "HELLBORN.Label.failure"}} +
  • + {{/if}} + {{/if}} + + {{#if isCritical}} + {{/if}} {{/if}}
diff --git a/templates/roll-dialog.hbs b/templates/roll-dialog.hbs index daaf78a..6c7bc2a 100644 --- a/templates/roll-dialog.hbs +++ b/templates/roll-dialog.hbs @@ -2,46 +2,35 @@
- {{#if (eq rollType "skill")}} - {{localize "HELLBORN.Label.skill"}} + {{#if (eq rollType "stat")}} + {{localize "HELLBORN.Label.stat"}} {{/if}} -
{{localize rollItem.label}} : 2d6+{{rollItem.value}}
+
{{localize rollItem.label}} : 3d6+{{rollItem.value}}
{{#if weapon}} -
Weapon : {{weapon.name}}
- {{/if}} - - {{#if isEncumbered}} -
Encumbered : -1D
+
Weapon : {{weapon.name}}
{{/if}}
- {{localize "HELLBORN.Label.modifier"}} + Advantages & Disadvantages - + {{selectOptions choiceAdvantages selected=nbAdvantages localize=true}} + + - {{#if weapon}} - -
    -
  • Two Attacks :
  • -
  • Aiming :
  • -
  • Dim Lightning :
  • -
  • Darkness :
  • -
  • Target Prone/Obscured :
  • -
  • Target Cover :
  • -
  • 1/2 Auto Fire Recoil :
  • -
  • 2+ Auto Fire Recoil :
  • -
  • Target Aware :
  • -
- {{/if}} +
+
+ Difficulty +
@@ -52,7 +41,7 @@
{{localize "HELLBORN.Label.rollView"}}
diff --git a/templates/tarot.hbs b/templates/tarot.hbs index 53c8b24..705ef4d 100644 --- a/templates/tarot.hbs +++ b/templates/tarot.hbs @@ -9,8 +9,17 @@
-
+
+ {{localize "HELLBORN.Label.quote"}} + {{formInput systemFields.quote value=system.quote toggled=true}} + {{localize "HELLBORN.Label.bonus"}} + {{formInput systemFields.bonus value=system.bonus toggled=true}} + {{localize "HELLBORN.Label.penalty"}} + {{formInput systemFields.penalty value=system.penalty toggled=true}} + {{localize "HELLBORN.Label.description"}} + {{formInput systemFields.description enriched=enrichedDescription value=system.description name="system.description" + toggled=true}} {{localize "HELLBORN.Label.positiveEffect"}} {{formInput systemFields.positiveEffect enriched=enrichedPositiveEffect value=system.positiveEffect name="system.positiveEffect" toggled=true}}