diff --git a/css/dialogue.css b/css/dialogue.css index 552126e..700f773 100644 --- a/css/dialogue.css +++ b/css/dialogue.css @@ -8,9 +8,19 @@ grid-gap: 10px 15px; } -.numeric-label-field { - width: 50px !important; - text-align: center !important; +.plusMinusNumberFieldBox { + + display: flex; + gap: 10px; + + select[name="plusOrMinus"] { + flex: 1; + } + + .numeric-label-field { + flex: 1; + text-align: center !important; + } } .damage-modify-label-grid { diff --git a/lang/en.json b/lang/en.json index e2ccf7f..9a794a6 100644 --- a/lang/en.json +++ b/lang/en.json @@ -192,6 +192,8 @@ "DG.Mental.Motivations": "Motivation", "DG.Mental.Disorders": "Disorder", + "DG.Gear.WeaponTypes.Firearms": "Firearms", + "DG.Gear.WeaponTypes.Melee": "Melee", "DG.Gear.Weapons": "WEAPONS", "DG.Gear.Armor": "ARMOR", "DG.Gear.OtherGear": "OTHER GEAR", diff --git a/module/other/stat-parser-macro.js b/module/other/stat-parser-macro.js index 10acd86..f413db7 100644 --- a/module/other/stat-parser-macro.js +++ b/module/other/stat-parser-macro.js @@ -656,21 +656,24 @@ async function GetUserInput() { `; - new Dialog({ - title: "Stat Block Parser", + new foundry.applications.api.DialogV2({ + window: { title: "Stat Block Parser" }, content, - buttons: { - roll: { + buttons: [ + { label: "PARSE", - callback: async (html) => { - const textInput = html.find("[name=parse-input]")[0].value; + action: "roll", + callback: (event, button, dialog) => { + const textInput = + dialog.element.querySelector("[name=parse-input]")?.value; - const actorType = html.find("[name=actor-type]")[0].value; + const actorType = + dialog.element.querySelector("[name=actor-type]")?.value; RegexParseNpcStatBlock(textInput, actorType); }, }, - }, + ], }).render(true); } diff --git a/module/roll/roll.js b/module/roll/roll.js index a02a969..af59a02 100644 --- a/module/roll/roll.js +++ b/module/roll/roll.js @@ -3,6 +3,7 @@ import DGUtils from "../other/utility-functions.js"; import DG from "../config.js"; const { renderTemplate } = foundry.applications.handlebars; +const { DialogV2 } = foundry.applications.api; export class DGRoll extends Roll { /** @@ -142,7 +143,9 @@ export class DGPercentileRoll extends DGRoll { customModifierTarget = parseInt( this.actor.system.settings.rolling.defaultPercentileModifier, ); - } catch {} + } catch { + /* empty */ + } } const backingData = { @@ -158,23 +161,48 @@ export class DGPercentileRoll extends DGRoll { "systems/deltagreen/templates/dialog/modify-percentile-roll.html"; const content = await renderTemplate(template, backingData); return new Promise((resolve, reject) => { - new Dialog({ + const modButtons = [-40, -20, 20, 40].map((mod) => { + const sign = mod > 0 ? "Positive" : "Negative"; + return { + action: `roll${Math.abs(mod)}${sign}`, + label: String(mod), + callback: (event, button, dialog) => { + try { + const rollMode = + dialog.element.querySelector("[name='rollMode']")?.value; + resolve({ targetModifier: mod, rollMode }); + } catch (ex) { + reject(console.log(ex)); + } + }, + }; + }); + + new DialogV2({ content, - title: DGUtils.localizeWithFallback( - "DG.ModifySkillRollDialogue.Title", - "Modify Roll", - ), - default: "roll", - buttons: { - roll: { + window: { + title: DGUtils.localizeWithFallback( + "DG.ModifySkillRollDialogue.Title", + "Modify Roll", + ), + }, + buttons: [ + { + default: true, + action: "roll", label: DGUtils.localizeWithFallback("DG.Roll.Roll", "Roll"), - callback: (html) => { + callback: (event, button, dialog) => { try { - let targetModifier = html.find("[name='targetModifier']").val(); // this is text as a heads up + let targetModifier = dialog.element.querySelector( + "[name='targetModifier']", + )?.value; // this is text as a heads up - const rollMode = html.find("[name='rollMode']").val(); + const rollMode = + dialog.element.querySelector("[name='rollMode']")?.value; - const plusMinus = html.find("[name='plusOrMinus']").val(); + const plusMinus = dialog.element.querySelector( + "[name='plusOrMinus']", + )?.value; if ( targetModifier.trim() !== "" && @@ -200,55 +228,8 @@ export class DGPercentileRoll extends DGRoll { } }, }, - roll40Negative: { - label: "-40", - callback: (html) => { - try { - const rollMode = html.find("[name='rollMode']").val(); - const targetModifier = -40; - resolve({ targetModifier, rollMode }); - } catch (ex) { - reject(console.log(ex)); - } - }, - }, - roll20Negative: { - label: "-20", - callback: (html) => { - try { - const rollMode = html.find("[name='rollMode']").val(); - const targetModifier = -20; - resolve({ targetModifier, rollMode }); - } catch (ex) { - reject(console.log(ex)); - } - }, - }, - roll20Positive: { - label: "+20", - callback: (html) => { - try { - const rollMode = html.find("[name='rollMode']").val(); - const targetModifier = 20; - resolve({ targetModifier, rollMode }); - } catch (ex) { - reject(console.log(ex)); - } - }, - }, - roll40Positive: { - label: "+40", - callback: (html) => { - try { - const rollMode = html.find("[name='rollMode']").val(); - const targetModifier = 40; - resolve({ targetModifier, rollMode }); - } catch (ex) { - reject(console.log(ex)); - } - }, - }, - }, + ...modButtons, + ], }).render(true); }); } @@ -275,7 +256,7 @@ export class DGPercentileRoll extends DGRoll { this.options.rollMode = "blindroll"; } - let label = this.createLabel(); + const label = this.createLabel(); let resultString = ""; let styleOverride = ""; @@ -288,21 +269,20 @@ export class DGPercentileRoll extends DGRoll { } else { resultString = `${game.i18n.localize("DG.Roll.Success")}`; } + } else if (this.isCritical) { + resultString = `${game.i18n.localize("DG.Roll.CriticalFailure")}`; + resultString = `${resultString.toUpperCase()}`; + styleOverride = "color: red"; } else { - if (this.isCritical) { - resultString = `${game.i18n.localize("DG.Roll.CriticalFailure")}`; - resultString = `${resultString.toUpperCase()}`; - styleOverride = "color: red"; - } else { - resultString = `${game.i18n.localize("DG.Roll.Failure")}`; - } + resultString = `${game.i18n.localize("DG.Roll.Failure")}`; } - const failureMark = !this.isSuccess && this.skillPath - && !foundry.utils.getProperty(this.actor, `${this.skillPath}.failure`) - && game.settings.get(DG.ID, "skillFailure"); + const failureMark = + !this.isSuccess && + this.skillPath && + !foundry.utils.getProperty(this.actor, `${this.skillPath}.failure`) && + game.settings.get(DG.ID, "skillFailure"); - const { renderTemplate } = foundry.applications.handlebars; const html = await renderTemplate( "systems/deltagreen/templates/roll/percentile-roll.hbs", { @@ -310,26 +290,32 @@ export class DGPercentileRoll extends DGRoll { resultString, formula: this.formula, total: this.total, - failureMark - }); + failureMark, + }, + ); - //TODO: add setting for it? + // TODO: add setting for it? if (failureMark) { const keyForUpdate = `${this.skillPath}.failure`; - //TODO: auto-update actor or post icon with manual apply + // TODO: auto-update actor or post icon with manual apply await this.actor.update({ - [keyForUpdate]: true - }) + [keyForUpdate]: true, + }); - return this.toMessage({ flags: { deltagreen: { - rollbacks: { - [keyForUpdate]: false - } - } }, content: html, flavor: label }); - } else { - return this.toMessage({ content: html, flavor: label }); + return this.toMessage({ + flags: { + deltagreen: { + rollbacks: { + [keyForUpdate]: false, + }, + }, + }, + content: html, + flavor: label, + }); } + return this.toMessage({ content: html, flavor: label }); } /** @@ -383,16 +369,21 @@ export class DGPercentileRoll extends DGRoll { * @returns {string} */ createLabel() { - const startOfLabel = game.i18n.localize("DG.Roll.Rolling") - + ` ${this.localizedKey}` - const endOfLabel =`${game.i18n.localize("DG.Roll.Target")} ${this.effectiveTarget}` + const startOfLabel = `${game.i18n.localize("DG.Roll.Rolling")} ${ + this.localizedKey + }`; + const endOfLabel = `${game.i18n.localize("DG.Roll.Target")} ${ + this.effectiveTarget + }`; let label = this.isInhuman - // "Inhuman" stat being rolled. See function for details. - ? `${startOfLabel} [${game.i18n.localize("DG.Roll.Inhuman").toUpperCase()}] ${endOfLabel}` + ? // "Inhuman" stat being rolled. See function for details. + `${startOfLabel} [${game.i18n + .localize("DG.Roll.Inhuman") + .toUpperCase()}] ${endOfLabel}` : `${startOfLabel}
${endOfLabel}%`; - const {isExhausted, exhaustedCheckPenalty} = this.exhausted + const { isExhausted, exhaustedCheckPenalty } = this.exhausted; if (this.modifier || isExhausted) { label += ` (${this.target}%`; @@ -429,7 +420,7 @@ export class DGPercentileRoll extends DGRoll { exhaustedCheckPenalty = -20; } - return {isExhausted, exhaustedCheckPenalty}; + return { isExhausted, exhaustedCheckPenalty }; } /** @@ -510,7 +501,7 @@ export class DGPercentileRoll extends DGRoll { get effectiveTarget() { let target = 1; - let {isExhausted, exhaustedCheckPenalty} = this.exhausted + const { isExhausted, exhaustedCheckPenalty } = this.exhausted; if (!this.target || Number.isNaN(this.target)) { return null; @@ -715,22 +706,30 @@ export class DGDamageRoll extends DGRoll { const content = await renderTemplate(template, backingData); return new Promise((resolve, reject) => { - new Dialog({ + new DialogV2({ content, - title: game.i18n.localize("DG.ModifySkillRollDialogue.Title"), - default: "roll", - buttons: { - roll: { + window: { + title: game.i18n.localize("DG.ModifySkillRollDialogue.Title"), + }, + buttons: [ + { + default: true, label: game.i18n.translations.DG.Roll.Roll, - - callback: (html) => { + action: "roll", + callback: (event, button, dialog) => { try { - const outerModifier = html.find("[name='outerModifier']").val(); // this is text as a heads up - let innerModifier = html.find("[name='innerModifier']").val(); // this is text as a heads up - const modifiedBaseRoll = html - .find("[name='originalFormula']") - .val(); // this is text as a heads up - const rollMode = html.find("[name='targetRollMode']").val(); + const outerModifier = dialog.element.querySelector( + "[name='outerModifier']", + )?.value; // this is text as a heads up + let innerModifier = dialog.element.querySelector( + "[name='innerModifier']", + )?.value; // this is text as a heads up + const modifiedBaseRoll = dialog.element.querySelector( + "[name='originalFormula']", + )?.value; // this is text as a heads up + const rollMode = dialog.element.querySelector( + "[name='targetRollMode']", + )?.value; if (innerModifier.replace(" ", "") === "+0") { innerModifier = ""; @@ -749,7 +748,7 @@ export class DGDamageRoll extends DGRoll { } }, }, - }, + ], }).render(true); }); } diff --git a/module/sheets/agent-sheet.js b/module/sheets/agent-sheet.js index a13f10f..03e96ae 100644 --- a/module/sheets/agent-sheet.js +++ b/module/sheets/agent-sheet.js @@ -214,16 +214,19 @@ export default class DGAgentSheet extends DGActorSheet { }, ); - return Dialog.wait({ + return foundry.applications.api.DialogV2.wait({ content, - title: game.i18n.localize("DG.Skills.ApplySkillImprovements.Title"), - default: "apply", - buttons: { - apply: { + window: { + title: game.i18n.localize("DG.Skills.ApplySkillImprovements.Title"), + }, + buttons: [ + { + default: true, + action: "apply", label: game.i18n.localize("DG.Skills.Apply"), icon: "", }, - }, + ], }); } diff --git a/module/sheets/base-actor-sheet.js b/module/sheets/base-actor-sheet.js index cb21676..0213bfa 100644 --- a/module/sheets/base-actor-sheet.js +++ b/module/sheets/base-actor-sheet.js @@ -8,6 +8,7 @@ import { import DGSheetMixin from "./base-sheet.js"; const { ActorSheetV2 } = foundry.applications.sheets; +const { DialogV2 } = foundry.applications.api; export default class DGActorSheet extends DGSheetMixin(ActorSheetV2) { /** @override */ @@ -841,22 +842,25 @@ export default class DGActorSheet extends DGSheetMixin(ActorSheetV2) { htmlContent += ` `; htmlContent += ``; - new Dialog({ + new DialogV2({ content: htmlContent, - title: - game.i18n.translations.DG?.Skills?.EditTypedOrCustomSkill ?? - "Edit Typed or Custom Skill", - default: "add", - buttons: { - add: { + window: { + title: + game.i18n.translations.DG?.Skills?.EditTypedOrCustomSkill ?? + "Edit Typed or Custom Skill", + }, + buttons: [ + { + default: true, + action: "add", label: game.i18n.translations.DG?.Skills?.EditSkill ?? "Edit Skill", - callback: (btn) => { - const newTypeSkillLabel = btn - .find("[name='new-type-skill-label']") - .val(); - const newTypeSkillGroup = btn - .find("[name='new-type-skill-group']") - .val(); + callback: (event, button, dialog) => { + const newTypeSkillLabel = dialog.element.querySelector( + "[name='new-type-skill-label']", + )?.value; + const newTypeSkillGroup = dialog.element.querySelector( + "[name='new-type-skill-group']", + )?.value; this._updateTypedSkill( targetSkill, newTypeSkillLabel, @@ -864,7 +868,7 @@ export default class DGActorSheet extends DGSheetMixin(ActorSheetV2) { ); }, }, - }, + ], }).render(true); } @@ -909,26 +913,30 @@ export default class DGActorSheet extends DGSheetMixin(ActorSheetV2) { htmlContent += ` `; htmlContent += ``; - new Dialog({ + new DialogV2({ content: htmlContent, - title: - game.i18n.translations.DG?.Skills?.AddTypedOrCustomSkill ?? - "Add Typed or Custom Skill", + window: { + title: + game.i18n.translations.DG?.Skills?.AddTypedOrCustomSkill ?? + "Add Typed or Custom Skill", + }, default: "add", - buttons: { - add: { + buttons: [ + { + default: true, + action: "add", label: game.i18n.translations.DG?.Skills?.AddSkill ?? "Add Skill", - callback: (btn) => { - const newTypeSkillLabel = btn - .find("[name='new-type-skill-label']") - .val(); - const newTypeSkillGroup = btn - .find("[name='new-type-skill-group']") - .val(); + callback: (event, button, dialog) => { + const newTypeSkillLabel = dialog.element.querySelector( + "[name='new-type-skill-label']", + )?.value; + const newTypeSkillGroup = dialog.element.querySelector( + "[name='new-type-skill-group']", + )?.value; this._addNewTypedSkill(newTypeSkillLabel, newTypeSkillGroup); }, }, - }, + ], }).render(true); } @@ -1072,20 +1080,24 @@ export default class DGActorSheet extends DGSheetMixin(ActorSheetV2) { ); // Prepare and render dialog with above template. - new Dialog({ + new DialogV2({ content, - title: game.i18n.localize("DG.SpecialTraining.Dialog.Title"), + window: { + title: game.i18n.localize("DG.SpecialTraining.Dialog.Title"), + }, default: "confirm", - buttons: { - confirm: { + buttons: [ + { + default: true, + action: "confirm", label: buttonLabel, - callback: (btn) => { - const specialTrainingLabel = btn - .find("[name='special-training-label']") - .val(); - const specialTrainingAttribute = btn - .find("[name='special-training-skill']") - .val(); + callback: (event, button, dialog) => { + const specialTrainingLabel = dialog.element.querySelector( + "[name='special-training-label']", + )?.value; + const specialTrainingAttribute = dialog.element.querySelector( + "[name='special-training-skill']", + )?.value; if (action === "create") this._createSpecialTraining( specialTrainingLabel, @@ -1099,7 +1111,7 @@ export default class DGActorSheet extends DGSheetMixin(ActorSheetV2) { ); }, }, - }, + ], }).render(true); } @@ -1262,17 +1274,21 @@ export default class DGActorSheet extends DGSheetMixin(ActorSheetV2) { const { packType } = target.dataset; switch (packType) { case "weapon": { - new Dialog({ - title: "Select Compendium", - buttons: { - firearms: { + new DialogV2({ + window: { title: "Select Compendium" }, + buttons: [ + { + action: "firearms", + label: game.i18n.localize("DG.Gear.WeaponTypes.Firearms"), icon: '', callback: () => game.packs .find((k) => k.collection === "deltagreen.firearms") .render(true), }, - melee: { + { + action: "melee", + label: game.i18n.localize("DG.Gear.WeaponTypes.Melee"), icon: '', callback: () => game.packs @@ -1281,7 +1297,7 @@ export default class DGActorSheet extends DGSheetMixin(ActorSheetV2) { ) .render(true), }, - }, + ], }).render(true); break; } diff --git a/templates/dialog/modify-percentile-roll.html b/templates/dialog/modify-percentile-roll.html index c26f997..8df5c75 100644 --- a/templates/dialog/modify-percentile-roll.html +++ b/templates/dialog/modify-percentile-roll.html @@ -16,7 +16,7 @@ {{localize 'DG.ModifySkillRollDialogue.TargetModifier'}} -
+