Skip to content
This repository was archived by the owner on Aug 10, 2025. It is now read-only.

Commit cb7752c

Browse files
committed
add script choice dialog
1 parent a20c0bd commit cb7752c

5 files changed

Lines changed: 89 additions & 6 deletions

File tree

lang/en.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
"ConfirmDelete": {
2020
"Title": "Delete {type}: {name}",
2121
"AreYouSure": "Are you sure that you want to delete the {type} '{name}'? This action cannot be undone."
22+
},
23+
"ScriptChoice": {
24+
"Prompt": "Choose which script will be executed."
2225
}
2326
}
2427
}

less/scriptable-items.less

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,22 @@
4848
}
4949
}
5050
}
51+
52+
.dialog.script-choice-dialog {
53+
button {
54+
display: flex;
55+
flex-direction: row;
56+
flex-wrap: nowrap;
57+
justify-content: center;
58+
align-items: center;
59+
60+
img {
61+
width: 32px;
62+
height: 32px;
63+
border: none;
64+
}
65+
}
66+
.dialog-buttons {
67+
flex-direction: column;
68+
}
69+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { LANG_ID } from "../constants.mjs";
2+
import { ScriptModel } from "../data/script-model.mjs";
3+
4+
export class ScriptChoiceDialog extends Dialog {
5+
constructor(scripts, dialogData, options) {
6+
super(dialogData, options);
7+
this.options.classes = ["dialog", "dnd5e", "script-choice-dialog"];
8+
9+
this.scripts = scripts;
10+
}
11+
12+
/**
13+
* A constructor function which displays the Script Choice Dialog app for a given Array of Scripts.
14+
* Returns a Promise which resolves to the chosen Script's id once the choice is made.
15+
* @param {ScriptModel[]} scripts Array of Scripts being chosen from.
16+
* @returns {Promise} Promise that is resolved when the use dialog is acted upon.
17+
*/
18+
static async create(scripts) {
19+
if (!scripts.length) return null;
20+
21+
return new Promise((resolve) => {
22+
const dlg = new this(scripts, {
23+
title: "Select a Script",
24+
content: `<p>${game.i18n.localize(`${LANG_ID}.Dialog.ScriptChoice.Prompt`)}</p>`,
25+
buttons: scripts.reduce((obj, script) => {
26+
obj[script.id] = {
27+
icon: `<img src="${script.img}">`,
28+
label: script.name,
29+
callback: () => {
30+
resolve(script.id);
31+
},
32+
};
33+
return obj;
34+
}, {}),
35+
default: scripts[0].id,
36+
close: () => resolve(null),
37+
});
38+
dlg.render(true);
39+
});
40+
}
41+
}
42+
43+
globalThis["ScriptChoiceDialog"] = ScriptChoiceDialog;

scripts/scriptable-items.mjs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
* Main Module File
33
*/
44

5+
import { ScriptChoiceDialog } from "./applications/script-choice-dialog.mjs";
56
import { MODULE_ID, SETTING, TRIGGER } from "./constants.mjs";
67
import { ScriptsOverview } from "./applications/scripts-overview.mjs";
78
import { getSetting, registerModuleSettings } from "./settings.mjs";
@@ -35,13 +36,15 @@ Hooks.on("dnd5e.preUseItem", (item, config, options) => {
3536
);
3637
if (!scripts.length) return true;
3738

38-
let script = scripts[0];
39-
if (scripts.length > 1) {
40-
ui.notifications.error(
41-
`The ${TRIGGER.PRE_USE} trigger currently only supports one script per item.`,
42-
);
43-
return true;
39+
if (scripts.length > 1 && options._selectedScript == null) {
40+
ScriptChoiceDialog.create(scripts).then((scriptId) => {
41+
if (scriptId == null) return;
42+
options._selectedScript = scripts.find((x) => x.id === scriptId);
43+
item.use(config, options);
44+
});
45+
return false;
4446
}
47+
const script = options._selectedScript ?? scripts[0];
4548

4649
script.executeScript({ trigger: TRIGGER.PRE_USE }).then((result) => {
4750
if (result === true) {

styles/scriptable-items.css

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,18 @@
3636
.app.sheet form.script-config multi-select .tags .tag {
3737
cursor: pointer;
3838
}
39+
.dialog.script-choice-dialog button {
40+
display: flex;
41+
flex-direction: row;
42+
flex-wrap: nowrap;
43+
justify-content: center;
44+
align-items: center;
45+
}
46+
.dialog.script-choice-dialog button img {
47+
width: 32px;
48+
height: 32px;
49+
border: none;
50+
}
51+
.dialog.script-choice-dialog .dialog-buttons {
52+
flex-direction: column;
53+
}

0 commit comments

Comments
 (0)