create-lt-adventure 0.0.16 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +85 -85
- package/addons/github-workflow/addon.json +5 -5
- package/addons/github-workflow/main.yml +96 -48
- package/addons/github-workflow/{setup.ts → setup.mjs} +115 -112
- package/addons/sf2e-pf2e-redirects/addon.json +5 -0
- package/addons/sf2e-pf2e-redirects/setup.mjs +119 -0
- package/dist/bin.js +223 -84
- package/dist/bin.js.map +1 -1
- package/dist/migrate.d.ts +2 -0
- package/dist/migrate.d.ts.map +1 -0
- package/dist/migrate.js +169 -0
- package/dist/migrate.js.map +1 -0
- package/dist/options.d.ts +5 -2
- package/dist/options.d.ts.map +1 -1
- package/dist/options.js +14 -5
- package/dist/options.js.map +1 -1
- package/package.json +68 -66
- package/templates/vite/.env.example +1 -1
- package/templates/vite/CHANGELOG +1 -0
- package/templates/vite/gitignore +37 -37
- package/templates/vite/module.json +37 -36
- package/templates/vite/package.json +3 -2
- package/templates/vite/scripts/extractPacks.mjs +54 -49
- package/templates/vite/scripts/jsonReplacer.mjs +11 -0
- package/templates/vite/scripts/onCreate.mjs +41 -13
- package/templates/vite/scripts/symlink.mjs +78 -78
- package/templates/vite/src/adventureSheet/index.js +497 -497
- package/templates/vite/src/hooks.ts +22 -0
- package/templates/vite/src/index.js +4 -4
- package/templates/vite/src/lib/utils.ts +1 -0
- package/templates/vite/src/misc/prosemirror.js +46 -46
- package/templates/vite/src/module.css +306 -306
- package/templates/vite/src/types.d.ts +7 -7
- package/templates/vite/tsconfig.json +33 -29
- package/templates/vite/vite.config.ts +129 -128
- package/templates/vite/bun.lock +0 -802
|
@@ -1,498 +1,498 @@
|
|
|
1
|
-
import moduleJSON from "moduleJSON";
|
|
2
|
-
|
|
3
|
-
const affectedDocuments = ["journal"];
|
|
4
|
-
|
|
5
|
-
const backgrounds = [
|
|
6
|
-
{ maxWidth: 130, image: "bg-header-length-01.svg" },
|
|
7
|
-
{ maxWidth: 150, image: "bg-header-length-02.svg" },
|
|
8
|
-
{ maxWidth: 210, image: "bg-header-length-03.svg" },
|
|
9
|
-
{ maxWidth: 250, image: "bg-header-length-04.svg" },
|
|
10
|
-
{ maxWidth: 300, image: "bg-header-length-05.svg" },
|
|
11
|
-
{ maxWidth: 400, image: "bg-header-length-06.svg" },
|
|
12
|
-
{ maxWidth: Infinity, image: "bg-header-length-07.svg" },
|
|
13
|
-
];
|
|
14
|
-
|
|
15
|
-
const DnDSheet = CONFIG.JournalEntry.sheetClasses.base['dnd5e.JournalEntrySheet5e'].cls;
|
|
16
|
-
|
|
17
|
-
export class LootTavernSheet extends DnDSheet {
|
|
18
|
-
static DEFAULT_OPTIONS = {
|
|
19
|
-
classes: [`${moduleJSON.id}-journal`],
|
|
20
|
-
actions: {
|
|
21
|
-
"openLootDevTools": this.openLootDevTools
|
|
22
|
-
},
|
|
23
|
-
window: {
|
|
24
|
-
controls: [
|
|
25
|
-
{
|
|
26
|
-
"icon": "fa-solid fa-wrench",
|
|
27
|
-
"label": "Loot Tavern Dev Tools",
|
|
28
|
-
"action": "openLootDevTools",
|
|
29
|
-
visible: () => moduleJSON.version === "dev",
|
|
30
|
-
}
|
|
31
|
-
]
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
static openLootDevTools(event) {
|
|
36
|
-
event.stopPropagation(); // Don't trigger other events
|
|
37
|
-
if (event.detail > 1) return; // Ignore repeated clicks
|
|
38
|
-
const docSheetConfigWidth = foundry.applications.apps.DocumentSheetConfig.DEFAULT_OPTIONS.position.width;
|
|
39
|
-
const fields = foundry.applications.fields;
|
|
40
|
-
|
|
41
|
-
const placeholder = `modules/${moduleJSON.id}/assets/setup.webp`
|
|
42
|
-
|
|
43
|
-
const headersInput = fields.createCheckboxInput({ name: "helianaHeaders", value: this.document.getFlag(moduleJSON.id, "helianaHeaders"), placeholder })
|
|
44
|
-
const selectGroup = fields.createFormGroup({
|
|
45
|
-
input: headersInput,
|
|
46
|
-
label: "Heliana-styled Headers",
|
|
47
|
-
hint: undefined
|
|
48
|
-
})
|
|
49
|
-
|
|
50
|
-
const imageInput = fields.createTextInput({ name: "image", value: this.document.getFlag(moduleJSON.id, "image"), placeholder })
|
|
51
|
-
const imageGroup = fields.createFormGroup({
|
|
52
|
-
input: imageInput,
|
|
53
|
-
label: "Main Image",
|
|
54
|
-
hint: undefined
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
const sidebarImageInput = fields.createTextInput({ name: "sidebarImage", value: this.document.getFlag(moduleJSON.id, "sidebarImage"), placeholder })
|
|
58
|
-
const sidebarImageGroup = fields.createFormGroup({
|
|
59
|
-
input: sidebarImageInput,
|
|
60
|
-
label: "Sidebar Background Image",
|
|
61
|
-
hint: undefined
|
|
62
|
-
})
|
|
63
|
-
|
|
64
|
-
const borderNumberInput = fields.createSelectInput({
|
|
65
|
-
options: Array(31).fill().map((x, i) => ({ label: i, value: i })),
|
|
66
|
-
name: 'borderNumber',
|
|
67
|
-
value: this.document.getFlag(moduleJSON.id, "borderNumber") || 26,
|
|
68
|
-
})
|
|
69
|
-
const borderNumberGroup = fields.createFormGroup({
|
|
70
|
-
input: borderNumberInput,
|
|
71
|
-
label: "Border Select",
|
|
72
|
-
hint: "Pick a style of border you want."
|
|
73
|
-
})
|
|
74
|
-
|
|
75
|
-
const formContent = [
|
|
76
|
-
selectGroup,
|
|
77
|
-
imageGroup,
|
|
78
|
-
sidebarImageGroup,
|
|
79
|
-
borderNumberGroup
|
|
80
|
-
]
|
|
81
|
-
|
|
82
|
-
const updateFlags = (flags) => this.document.update({ [`flags.${moduleJSON.id}`]: flags });
|
|
83
|
-
|
|
84
|
-
const dialog = new foundry.applications.api.DialogV2({
|
|
85
|
-
id: `${this.id}-dev-menu`,
|
|
86
|
-
classes: [],
|
|
87
|
-
window: {
|
|
88
|
-
title: `${this.document.name} Dev Config`,
|
|
89
|
-
resizable: true,
|
|
90
|
-
},
|
|
91
|
-
position: {
|
|
92
|
-
width: 550,
|
|
93
|
-
top: this.position.top + 40,
|
|
94
|
-
left: this.position.left + ((this.position.width - docSheetConfigWidth) / 2)
|
|
95
|
-
},
|
|
96
|
-
// ../../assets/Art/ReignOfIron-Landscape-Vertical.webp
|
|
97
|
-
content: formContent.map(x => x.outerHTML).join(""),
|
|
98
|
-
buttons: [
|
|
99
|
-
{
|
|
100
|
-
action: "submit",
|
|
101
|
-
label: "Submit",
|
|
102
|
-
default: true,
|
|
103
|
-
callback: async function (event, target) {
|
|
104
|
-
const flags = Object.fromEntries(Object.values(target.form.elements).map(x => [x.name, x.checked || x.value]).filter(x => x[0]))
|
|
105
|
-
|
|
106
|
-
await updateFlags(flags)
|
|
107
|
-
},
|
|
108
|
-
},
|
|
109
|
-
],
|
|
110
|
-
});
|
|
111
|
-
dialog.render(true);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
async render(force, options) {
|
|
115
|
-
const doc = this.document;
|
|
116
|
-
const modFlags = doc.flags?.[moduleJSON.id] ?? {};
|
|
117
|
-
await super.render(force, options);
|
|
118
|
-
|
|
119
|
-
const html = this.element;
|
|
120
|
-
|
|
121
|
-
// Sidebar Background
|
|
122
|
-
const sidebarImg = this.document.getFlag(moduleJSON.id, "sidebarImage");
|
|
123
|
-
if (sidebarImg) html.style.setProperty("--sidebarImage", `url("/${sidebarImg}")`);
|
|
124
|
-
|
|
125
|
-
const borderNumber = this.document.getFlag(moduleJSON.id, "borderNumber");
|
|
126
|
-
if (!isNaN(borderNumber)) html.style.setProperty("--urlBorderImage", `url("/modules/${moduleJSON.id}/assets/journals/borders/panel-border-${("00" + Number(borderNumber)).slice(-3)}.webp")`);
|
|
127
|
-
|
|
128
|
-
let borderRadius = "7px";
|
|
129
|
-
let borderSizeMod = "0px";
|
|
130
|
-
let borderCut = "32";
|
|
131
|
-
let borderOutset = "32";
|
|
132
|
-
switch (Number(borderNumber)) {
|
|
133
|
-
case 0: {
|
|
134
|
-
borderRadius = `7px`;
|
|
135
|
-
borderSizeMod = `25px`;
|
|
136
|
-
break;
|
|
137
|
-
}
|
|
138
|
-
case 1: {
|
|
139
|
-
borderRadius = `15px`;
|
|
140
|
-
borderSizeMod = `0px`;
|
|
141
|
-
break;
|
|
142
|
-
}
|
|
143
|
-
case 2: {
|
|
144
|
-
borderRadius = `15px`;
|
|
145
|
-
borderSizeMod = `0px`;
|
|
146
|
-
break;
|
|
147
|
-
}
|
|
148
|
-
case 3: {
|
|
149
|
-
borderRadius = `0px`;
|
|
150
|
-
borderSizeMod = `35px`;
|
|
151
|
-
break;
|
|
152
|
-
}
|
|
153
|
-
case 4: {
|
|
154
|
-
borderRadius = `6px`;
|
|
155
|
-
borderSizeMod = `20px`;
|
|
156
|
-
break;
|
|
157
|
-
}
|
|
158
|
-
case 5: {
|
|
159
|
-
borderRadius = `0px`;
|
|
160
|
-
borderSizeMod = `0px`;
|
|
161
|
-
break;
|
|
162
|
-
}
|
|
163
|
-
case 6: {
|
|
164
|
-
borderRadius = `10px`;
|
|
165
|
-
borderSizeMod = `0px`;
|
|
166
|
-
break;
|
|
167
|
-
}
|
|
168
|
-
case 7: {
|
|
169
|
-
borderRadius = `15px`;
|
|
170
|
-
borderSizeMod = `0px`;
|
|
171
|
-
break;
|
|
172
|
-
}
|
|
173
|
-
case 8:
|
|
174
|
-
case 9: {
|
|
175
|
-
borderRadius = `10px`;
|
|
176
|
-
borderSizeMod = `12px`;
|
|
177
|
-
break;
|
|
178
|
-
}
|
|
179
|
-
case 10: {
|
|
180
|
-
borderRadius = `16px`;
|
|
181
|
-
borderSizeMod = `5px`;
|
|
182
|
-
break;
|
|
183
|
-
}
|
|
184
|
-
case 11:
|
|
185
|
-
case 12: {
|
|
186
|
-
borderRadius = `16px`;
|
|
187
|
-
borderSizeMod = `5px`;
|
|
188
|
-
break;
|
|
189
|
-
}
|
|
190
|
-
case 13: {
|
|
191
|
-
borderRadius = `12px`;
|
|
192
|
-
borderSizeMod = `5px`;
|
|
193
|
-
break;
|
|
194
|
-
}
|
|
195
|
-
case 14: {
|
|
196
|
-
borderRadius = `10px`;
|
|
197
|
-
borderSizeMod = `20px`;
|
|
198
|
-
break;
|
|
199
|
-
}
|
|
200
|
-
case 15: {
|
|
201
|
-
borderRadius = `0px`;
|
|
202
|
-
borderSizeMod = `5px`;
|
|
203
|
-
break;
|
|
204
|
-
}
|
|
205
|
-
case 16: {
|
|
206
|
-
borderRadius = `8px`;
|
|
207
|
-
borderSizeMod = `10px`;
|
|
208
|
-
break;
|
|
209
|
-
}
|
|
210
|
-
case 17: {
|
|
211
|
-
borderRadius = `11px`;
|
|
212
|
-
borderSizeMod = `10px`;
|
|
213
|
-
break;
|
|
214
|
-
}
|
|
215
|
-
case 18:
|
|
216
|
-
case 19: {
|
|
217
|
-
borderRadius = `16px`;
|
|
218
|
-
borderSizeMod = `0px`;
|
|
219
|
-
break;
|
|
220
|
-
}
|
|
221
|
-
case 20: {
|
|
222
|
-
borderRadius = `0px`;
|
|
223
|
-
borderSizeMod = `10px`;
|
|
224
|
-
borderCut = `40`
|
|
225
|
-
borderOutset = `46`
|
|
226
|
-
break;
|
|
227
|
-
}
|
|
228
|
-
case 21: {
|
|
229
|
-
borderRadius = `25px`;
|
|
230
|
-
borderSizeMod = `0px`;
|
|
231
|
-
break;
|
|
232
|
-
}
|
|
233
|
-
case 22: {
|
|
234
|
-
borderRadius = `10px`;
|
|
235
|
-
borderSizeMod = `6px`;
|
|
236
|
-
break;
|
|
237
|
-
}
|
|
238
|
-
case 23: {
|
|
239
|
-
borderRadius = `24px`;
|
|
240
|
-
borderSizeMod = `0px`;
|
|
241
|
-
break;
|
|
242
|
-
}
|
|
243
|
-
case 24: {
|
|
244
|
-
borderRadius = `0px`;
|
|
245
|
-
borderSizeMod = `50px`;
|
|
246
|
-
break;
|
|
247
|
-
}
|
|
248
|
-
case 25: {
|
|
249
|
-
borderRadius = `27px`;
|
|
250
|
-
borderSizeMod = `0px`;
|
|
251
|
-
borderCut = `40`
|
|
252
|
-
borderOutset = `32`
|
|
253
|
-
break;
|
|
254
|
-
}
|
|
255
|
-
case 26: {
|
|
256
|
-
borderRadius = `30px`;
|
|
257
|
-
borderSizeMod = `0px`;
|
|
258
|
-
break;
|
|
259
|
-
}
|
|
260
|
-
case 27: {
|
|
261
|
-
borderRadius = `0px`;
|
|
262
|
-
borderSizeMod = `8px`;
|
|
263
|
-
break;
|
|
264
|
-
}
|
|
265
|
-
case 28: {
|
|
266
|
-
borderRadius = `15px`;
|
|
267
|
-
borderSizeMod = `8px`;
|
|
268
|
-
break;
|
|
269
|
-
}
|
|
270
|
-
case 29: {
|
|
271
|
-
borderRadius = `15px`;
|
|
272
|
-
borderSizeMod = `8px`;
|
|
273
|
-
break;
|
|
274
|
-
}
|
|
275
|
-
case 30: {
|
|
276
|
-
borderRadius = `15px`;
|
|
277
|
-
borderSizeMod = `0px`;
|
|
278
|
-
break;
|
|
279
|
-
}
|
|
280
|
-
default: {
|
|
281
|
-
console.log("wtf??", borderNumber)
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
html.style.setProperty("--ltBorderRadius", borderRadius);
|
|
286
|
-
html.style.setProperty("--ltBorderSizeMod", borderSizeMod);
|
|
287
|
-
html.style.setProperty("--ltBorderCut", borderCut);
|
|
288
|
-
html.style.setProperty("--ltBorderOutset", borderOutset);
|
|
289
|
-
|
|
290
|
-
if (this.mode === 2) {
|
|
291
|
-
const imgPath = this.document.flags[moduleJSON.id]?.image;
|
|
292
|
-
if (!imgPath) return;
|
|
293
|
-
const scrollable = html.querySelector(".journal-entry-content .scrollable");
|
|
294
|
-
|
|
295
|
-
// Create and insert scenery element
|
|
296
|
-
const sceneryDiv = document.createElement("div");
|
|
297
|
-
sceneryDiv.className = "scenery mask upside-down";
|
|
298
|
-
sceneryDiv.innerHTML = `<img src="/${imgPath}">`;
|
|
299
|
-
scrollable.prepend(sceneryDiv);
|
|
300
|
-
|
|
301
|
-
const scenery = scrollable.querySelector(".scenery");
|
|
302
|
-
|
|
303
|
-
scrollable.addEventListener("scroll", ({ target }) => {
|
|
304
|
-
const opacity = Math.max(10, 100 - target.scrollTop / 2);
|
|
305
|
-
scenery.style.opacity = `${opacity}%`;
|
|
306
|
-
scenery.style.pointerEvents = opacity < 50 ? "none" : "auto";
|
|
307
|
-
});
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
const header = html.querySelector("header.journal-header");
|
|
311
|
-
header.remove();
|
|
312
|
-
|
|
313
|
-
const title = document.createElement('header');
|
|
314
|
-
title.textContent = this.document.name;
|
|
315
|
-
scenery.appendChild(title);
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
// Level Select
|
|
319
|
-
const levelSelect = html.querySelector("#level-select");
|
|
320
|
-
|
|
321
|
-
if (levelSelect) {
|
|
322
|
-
// Add radio inputs to each level
|
|
323
|
-
const levelOptions = levelSelect.querySelectorAll("[data-level]");
|
|
324
|
-
levelOptions.forEach((option) => {
|
|
325
|
-
const input = document.createElement("input");
|
|
326
|
-
input.type = "radio";
|
|
327
|
-
input.name = "level-selector";
|
|
328
|
-
option.prepend(input);
|
|
329
|
-
});
|
|
330
|
-
|
|
331
|
-
// Handle radio button clicks
|
|
332
|
-
const radioInputs = levelSelect.querySelectorAll("input[type='radio']");
|
|
333
|
-
radioInputs.forEach((radio) => {
|
|
334
|
-
radio.addEventListener("click", function () {
|
|
335
|
-
const radioElement = this;
|
|
336
|
-
|
|
337
|
-
if (radioElement.checked) {
|
|
338
|
-
// Uncheck all radios in the group
|
|
339
|
-
const groupName = radioElement.name;
|
|
340
|
-
const allRadios = levelSelect.querySelectorAll(`input[type='radio'][name='${groupName}']`);
|
|
341
|
-
allRadios.forEach((r) => {
|
|
342
|
-
(r).checked = false;
|
|
343
|
-
});
|
|
344
|
-
|
|
345
|
-
// Check the clicked radio
|
|
346
|
-
radioElement.checked = true;
|
|
347
|
-
|
|
348
|
-
// Get level and update
|
|
349
|
-
const parent = radioElement.parentElement;
|
|
350
|
-
const level = parseInt(parent.dataset.level || "0", 10);
|
|
351
|
-
|
|
352
|
-
ui.notifications.info(`Setting the adventure level to ${level}!`);
|
|
353
|
-
doc.update({ flags: { [moduleJSON.id]: { level } } });
|
|
354
|
-
|
|
355
|
-
// Determine changes based on level
|
|
356
|
-
let changes = [11, 3, 3, "1d6"];
|
|
357
|
-
switch (level) {
|
|
358
|
-
case 1:
|
|
359
|
-
case 2:
|
|
360
|
-
changes = [11, 3, 3, "1d6"];
|
|
361
|
-
break;
|
|
362
|
-
case 3:
|
|
363
|
-
case 4:
|
|
364
|
-
changes = [12, 4, 3, "1d6"];
|
|
365
|
-
break;
|
|
366
|
-
case 5:
|
|
367
|
-
case 6:
|
|
368
|
-
changes = [13, 5, 5, "2d4"];
|
|
369
|
-
break;
|
|
370
|
-
case 7:
|
|
371
|
-
case 8:
|
|
372
|
-
changes = [14, 6, 7, "2d6"];
|
|
373
|
-
break;
|
|
374
|
-
case 9:
|
|
375
|
-
case 10:
|
|
376
|
-
case 11:
|
|
377
|
-
changes = [15, 7, 10, "3d6"];
|
|
378
|
-
break;
|
|
379
|
-
case 12:
|
|
380
|
-
case 13:
|
|
381
|
-
case 14:
|
|
382
|
-
changes = [16, 8, 14, "4d6"];
|
|
383
|
-
break;
|
|
384
|
-
case 15:
|
|
385
|
-
case 16:
|
|
386
|
-
case 17:
|
|
387
|
-
changes = [17, 9, 21, "6d6"];
|
|
388
|
-
break;
|
|
389
|
-
case 18:
|
|
390
|
-
case 19:
|
|
391
|
-
case 20:
|
|
392
|
-
changes = [18, 10, 28, "8d6"];
|
|
393
|
-
break;
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
// Update all flags
|
|
397
|
-
doc.update({
|
|
398
|
-
flags: {
|
|
399
|
-
[moduleJSON.id]: {
|
|
400
|
-
level,
|
|
401
|
-
dc: changes[0],
|
|
402
|
-
mod: changes[1],
|
|
403
|
-
damage: changes[2],
|
|
404
|
-
damageDice: changes[3],
|
|
405
|
-
},
|
|
406
|
-
},
|
|
407
|
-
});
|
|
408
|
-
} else {
|
|
409
|
-
(this).checked = false;
|
|
410
|
-
}
|
|
411
|
-
});
|
|
412
|
-
});
|
|
413
|
-
|
|
414
|
-
// Set checked state for previously chosen level
|
|
415
|
-
const chosenLevel = modFlags.level;
|
|
416
|
-
if (chosenLevel) {
|
|
417
|
-
const chosenOption = levelSelect.querySelector(`[data-level="${chosenLevel}"]`);
|
|
418
|
-
if (chosenOption) {
|
|
419
|
-
const chosenInput = chosenOption.querySelector("input");
|
|
420
|
-
chosenInput.checked = true;
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
async _renderPageViews(context, options) {
|
|
427
|
-
const rendered = await super._renderPageViews(context, options);
|
|
428
|
-
this.applyHelianaHeaders()
|
|
429
|
-
return rendered;
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
applyHelianaHeaders(target = this.element) {
|
|
433
|
-
const headers = target.querySelectorAll("h2");
|
|
434
|
-
headers.forEach((h2) => {
|
|
435
|
-
const parent = h2.parentElement;
|
|
436
|
-
if (!parent) return;
|
|
437
|
-
parent.classList.add("heliana-style-bg");
|
|
438
|
-
|
|
439
|
-
// Find appropriate background based on header width
|
|
440
|
-
const background = backgrounds.find((bg) => h2.offsetWidth <= bg.maxWidth);
|
|
441
|
-
|
|
442
|
-
if (background) {
|
|
443
|
-
parent.style.backgroundImage = `url("/modules/${moduleJSON.id}/assets/journals/headers/${background.image}")`;
|
|
444
|
-
}
|
|
445
|
-
});
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
async deleteSelf() {
|
|
449
|
-
await this.close({ force: true });
|
|
450
|
-
// @ts-expect-error Intentional for purposes of HMR
|
|
451
|
-
this.document._sheet = null;
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
function registerSheet(sheet) {
|
|
456
|
-
foundry.applications.apps.DocumentSheetConfig.registerSheet(JournalEntry, moduleJSON.id, sheet, {
|
|
457
|
-
label: `LT - ${moduleJSON.title} Sheet`,
|
|
458
|
-
canBeDefault: false,
|
|
459
|
-
});
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
function unregisterSheet(sheet) {
|
|
463
|
-
foundry.applications.apps.DocumentSheetConfig.unregisterSheet(JournalEntry, moduleJSON.id, sheet);
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
// Assuming we are inside a Hooks.on("ready")
|
|
467
|
-
registerSheet(LootTavernSheet)
|
|
468
|
-
|
|
469
|
-
if (import.meta.hot) {
|
|
470
|
-
import.meta.hot.accept(async (newModule) => {
|
|
471
|
-
if (!newModule) return;
|
|
472
|
-
let reopenedDocuments = [];
|
|
473
|
-
|
|
474
|
-
unregisterSheet(LootTavernSheet);
|
|
475
|
-
|
|
476
|
-
for (const type of affectedDocuments) {
|
|
477
|
-
for (const doc of game[type].contents) {
|
|
478
|
-
// @ts-expect-error Custom function for LootTavernSheets
|
|
479
|
-
if (doc.sheet.deleteSelf) {
|
|
480
|
-
// @ts-expect-error Custom function for LootTavernSheets
|
|
481
|
-
await doc.sheet.deleteSelf();
|
|
482
|
-
reopenedDocuments.push(doc.uuid);
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
};
|
|
486
|
-
|
|
487
|
-
registerSheet(newModule.LootTavernSheet);
|
|
488
|
-
console.log(`Registered new ${newModule.LootTavernSheet.name} sheet.`)
|
|
489
|
-
|
|
490
|
-
reopenedDocuments.forEach(async (uuid) => {
|
|
491
|
-
const doc = await fromUuid(uuid);
|
|
492
|
-
if (!doc) return;
|
|
493
|
-
|
|
494
|
-
doc?.sheet?.render(true);
|
|
495
|
-
});
|
|
496
|
-
reopenedDocuments = [];
|
|
497
|
-
});
|
|
1
|
+
import moduleJSON from "moduleJSON";
|
|
2
|
+
|
|
3
|
+
const affectedDocuments = ["journal"];
|
|
4
|
+
|
|
5
|
+
const backgrounds = [
|
|
6
|
+
{ maxWidth: 130, image: "bg-header-length-01.svg" },
|
|
7
|
+
{ maxWidth: 150, image: "bg-header-length-02.svg" },
|
|
8
|
+
{ maxWidth: 210, image: "bg-header-length-03.svg" },
|
|
9
|
+
{ maxWidth: 250, image: "bg-header-length-04.svg" },
|
|
10
|
+
{ maxWidth: 300, image: "bg-header-length-05.svg" },
|
|
11
|
+
{ maxWidth: 400, image: "bg-header-length-06.svg" },
|
|
12
|
+
{ maxWidth: Infinity, image: "bg-header-length-07.svg" },
|
|
13
|
+
];
|
|
14
|
+
|
|
15
|
+
const DnDSheet = CONFIG.JournalEntry.sheetClasses.base['dnd5e.JournalEntrySheet5e'].cls;
|
|
16
|
+
|
|
17
|
+
export class LootTavernSheet extends DnDSheet {
|
|
18
|
+
static DEFAULT_OPTIONS = {
|
|
19
|
+
classes: [`${moduleJSON.id}-journal`],
|
|
20
|
+
actions: {
|
|
21
|
+
"openLootDevTools": this.openLootDevTools
|
|
22
|
+
},
|
|
23
|
+
window: {
|
|
24
|
+
controls: [
|
|
25
|
+
{
|
|
26
|
+
"icon": "fa-solid fa-wrench",
|
|
27
|
+
"label": "Loot Tavern Dev Tools",
|
|
28
|
+
"action": "openLootDevTools",
|
|
29
|
+
visible: () => moduleJSON.version === "dev",
|
|
30
|
+
}
|
|
31
|
+
]
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
static openLootDevTools(event) {
|
|
36
|
+
event.stopPropagation(); // Don't trigger other events
|
|
37
|
+
if (event.detail > 1) return; // Ignore repeated clicks
|
|
38
|
+
const docSheetConfigWidth = foundry.applications.apps.DocumentSheetConfig.DEFAULT_OPTIONS.position.width;
|
|
39
|
+
const fields = foundry.applications.fields;
|
|
40
|
+
|
|
41
|
+
const placeholder = `modules/${moduleJSON.id}/assets/setup.webp`
|
|
42
|
+
|
|
43
|
+
const headersInput = fields.createCheckboxInput({ name: "helianaHeaders", value: this.document.getFlag(moduleJSON.id, "helianaHeaders"), placeholder })
|
|
44
|
+
const selectGroup = fields.createFormGroup({
|
|
45
|
+
input: headersInput,
|
|
46
|
+
label: "Heliana-styled Headers",
|
|
47
|
+
hint: undefined
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
const imageInput = fields.createTextInput({ name: "image", value: this.document.getFlag(moduleJSON.id, "image"), placeholder })
|
|
51
|
+
const imageGroup = fields.createFormGroup({
|
|
52
|
+
input: imageInput,
|
|
53
|
+
label: "Main Image",
|
|
54
|
+
hint: undefined
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
const sidebarImageInput = fields.createTextInput({ name: "sidebarImage", value: this.document.getFlag(moduleJSON.id, "sidebarImage"), placeholder })
|
|
58
|
+
const sidebarImageGroup = fields.createFormGroup({
|
|
59
|
+
input: sidebarImageInput,
|
|
60
|
+
label: "Sidebar Background Image",
|
|
61
|
+
hint: undefined
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
const borderNumberInput = fields.createSelectInput({
|
|
65
|
+
options: Array(31).fill().map((x, i) => ({ label: i, value: i })),
|
|
66
|
+
name: 'borderNumber',
|
|
67
|
+
value: this.document.getFlag(moduleJSON.id, "borderNumber") || 26,
|
|
68
|
+
})
|
|
69
|
+
const borderNumberGroup = fields.createFormGroup({
|
|
70
|
+
input: borderNumberInput,
|
|
71
|
+
label: "Border Select",
|
|
72
|
+
hint: "Pick a style of border you want."
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
const formContent = [
|
|
76
|
+
selectGroup,
|
|
77
|
+
imageGroup,
|
|
78
|
+
sidebarImageGroup,
|
|
79
|
+
borderNumberGroup
|
|
80
|
+
]
|
|
81
|
+
|
|
82
|
+
const updateFlags = (flags) => this.document.update({ [`flags.${moduleJSON.id}`]: flags });
|
|
83
|
+
|
|
84
|
+
const dialog = new foundry.applications.api.DialogV2({
|
|
85
|
+
id: `${this.id}-dev-menu`,
|
|
86
|
+
classes: [],
|
|
87
|
+
window: {
|
|
88
|
+
title: `${this.document.name} Dev Config`,
|
|
89
|
+
resizable: true,
|
|
90
|
+
},
|
|
91
|
+
position: {
|
|
92
|
+
width: 550,
|
|
93
|
+
top: this.position.top + 40,
|
|
94
|
+
left: this.position.left + ((this.position.width - docSheetConfigWidth) / 2)
|
|
95
|
+
},
|
|
96
|
+
// ../../assets/Art/ReignOfIron-Landscape-Vertical.webp
|
|
97
|
+
content: formContent.map(x => x.outerHTML).join(""),
|
|
98
|
+
buttons: [
|
|
99
|
+
{
|
|
100
|
+
action: "submit",
|
|
101
|
+
label: "Submit",
|
|
102
|
+
default: true,
|
|
103
|
+
callback: async function (event, target) {
|
|
104
|
+
const flags = Object.fromEntries(Object.values(target.form.elements).map(x => [x.name, x.checked || x.value]).filter(x => x[0]))
|
|
105
|
+
|
|
106
|
+
await updateFlags(flags)
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
],
|
|
110
|
+
});
|
|
111
|
+
dialog.render(true);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
async render(force, options) {
|
|
115
|
+
const doc = this.document;
|
|
116
|
+
const modFlags = doc.flags?.[moduleJSON.id] ?? {};
|
|
117
|
+
await super.render(force, options);
|
|
118
|
+
|
|
119
|
+
const html = this.element;
|
|
120
|
+
|
|
121
|
+
// Sidebar Background
|
|
122
|
+
const sidebarImg = this.document.getFlag(moduleJSON.id, "sidebarImage");
|
|
123
|
+
if (sidebarImg) html.style.setProperty("--sidebarImage", `url("/${sidebarImg}")`);
|
|
124
|
+
|
|
125
|
+
const borderNumber = this.document.getFlag(moduleJSON.id, "borderNumber");
|
|
126
|
+
if (!isNaN(borderNumber)) html.style.setProperty("--urlBorderImage", `url("/modules/${moduleJSON.id}/assets/journals/borders/panel-border-${("00" + Number(borderNumber)).slice(-3)}.webp")`);
|
|
127
|
+
|
|
128
|
+
let borderRadius = "7px";
|
|
129
|
+
let borderSizeMod = "0px";
|
|
130
|
+
let borderCut = "32";
|
|
131
|
+
let borderOutset = "32";
|
|
132
|
+
switch (Number(borderNumber)) {
|
|
133
|
+
case 0: {
|
|
134
|
+
borderRadius = `7px`;
|
|
135
|
+
borderSizeMod = `25px`;
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
case 1: {
|
|
139
|
+
borderRadius = `15px`;
|
|
140
|
+
borderSizeMod = `0px`;
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
case 2: {
|
|
144
|
+
borderRadius = `15px`;
|
|
145
|
+
borderSizeMod = `0px`;
|
|
146
|
+
break;
|
|
147
|
+
}
|
|
148
|
+
case 3: {
|
|
149
|
+
borderRadius = `0px`;
|
|
150
|
+
borderSizeMod = `35px`;
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
case 4: {
|
|
154
|
+
borderRadius = `6px`;
|
|
155
|
+
borderSizeMod = `20px`;
|
|
156
|
+
break;
|
|
157
|
+
}
|
|
158
|
+
case 5: {
|
|
159
|
+
borderRadius = `0px`;
|
|
160
|
+
borderSizeMod = `0px`;
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
163
|
+
case 6: {
|
|
164
|
+
borderRadius = `10px`;
|
|
165
|
+
borderSizeMod = `0px`;
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
168
|
+
case 7: {
|
|
169
|
+
borderRadius = `15px`;
|
|
170
|
+
borderSizeMod = `0px`;
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
case 8:
|
|
174
|
+
case 9: {
|
|
175
|
+
borderRadius = `10px`;
|
|
176
|
+
borderSizeMod = `12px`;
|
|
177
|
+
break;
|
|
178
|
+
}
|
|
179
|
+
case 10: {
|
|
180
|
+
borderRadius = `16px`;
|
|
181
|
+
borderSizeMod = `5px`;
|
|
182
|
+
break;
|
|
183
|
+
}
|
|
184
|
+
case 11:
|
|
185
|
+
case 12: {
|
|
186
|
+
borderRadius = `16px`;
|
|
187
|
+
borderSizeMod = `5px`;
|
|
188
|
+
break;
|
|
189
|
+
}
|
|
190
|
+
case 13: {
|
|
191
|
+
borderRadius = `12px`;
|
|
192
|
+
borderSizeMod = `5px`;
|
|
193
|
+
break;
|
|
194
|
+
}
|
|
195
|
+
case 14: {
|
|
196
|
+
borderRadius = `10px`;
|
|
197
|
+
borderSizeMod = `20px`;
|
|
198
|
+
break;
|
|
199
|
+
}
|
|
200
|
+
case 15: {
|
|
201
|
+
borderRadius = `0px`;
|
|
202
|
+
borderSizeMod = `5px`;
|
|
203
|
+
break;
|
|
204
|
+
}
|
|
205
|
+
case 16: {
|
|
206
|
+
borderRadius = `8px`;
|
|
207
|
+
borderSizeMod = `10px`;
|
|
208
|
+
break;
|
|
209
|
+
}
|
|
210
|
+
case 17: {
|
|
211
|
+
borderRadius = `11px`;
|
|
212
|
+
borderSizeMod = `10px`;
|
|
213
|
+
break;
|
|
214
|
+
}
|
|
215
|
+
case 18:
|
|
216
|
+
case 19: {
|
|
217
|
+
borderRadius = `16px`;
|
|
218
|
+
borderSizeMod = `0px`;
|
|
219
|
+
break;
|
|
220
|
+
}
|
|
221
|
+
case 20: {
|
|
222
|
+
borderRadius = `0px`;
|
|
223
|
+
borderSizeMod = `10px`;
|
|
224
|
+
borderCut = `40`
|
|
225
|
+
borderOutset = `46`
|
|
226
|
+
break;
|
|
227
|
+
}
|
|
228
|
+
case 21: {
|
|
229
|
+
borderRadius = `25px`;
|
|
230
|
+
borderSizeMod = `0px`;
|
|
231
|
+
break;
|
|
232
|
+
}
|
|
233
|
+
case 22: {
|
|
234
|
+
borderRadius = `10px`;
|
|
235
|
+
borderSizeMod = `6px`;
|
|
236
|
+
break;
|
|
237
|
+
}
|
|
238
|
+
case 23: {
|
|
239
|
+
borderRadius = `24px`;
|
|
240
|
+
borderSizeMod = `0px`;
|
|
241
|
+
break;
|
|
242
|
+
}
|
|
243
|
+
case 24: {
|
|
244
|
+
borderRadius = `0px`;
|
|
245
|
+
borderSizeMod = `50px`;
|
|
246
|
+
break;
|
|
247
|
+
}
|
|
248
|
+
case 25: {
|
|
249
|
+
borderRadius = `27px`;
|
|
250
|
+
borderSizeMod = `0px`;
|
|
251
|
+
borderCut = `40`
|
|
252
|
+
borderOutset = `32`
|
|
253
|
+
break;
|
|
254
|
+
}
|
|
255
|
+
case 26: {
|
|
256
|
+
borderRadius = `30px`;
|
|
257
|
+
borderSizeMod = `0px`;
|
|
258
|
+
break;
|
|
259
|
+
}
|
|
260
|
+
case 27: {
|
|
261
|
+
borderRadius = `0px`;
|
|
262
|
+
borderSizeMod = `8px`;
|
|
263
|
+
break;
|
|
264
|
+
}
|
|
265
|
+
case 28: {
|
|
266
|
+
borderRadius = `15px`;
|
|
267
|
+
borderSizeMod = `8px`;
|
|
268
|
+
break;
|
|
269
|
+
}
|
|
270
|
+
case 29: {
|
|
271
|
+
borderRadius = `15px`;
|
|
272
|
+
borderSizeMod = `8px`;
|
|
273
|
+
break;
|
|
274
|
+
}
|
|
275
|
+
case 30: {
|
|
276
|
+
borderRadius = `15px`;
|
|
277
|
+
borderSizeMod = `0px`;
|
|
278
|
+
break;
|
|
279
|
+
}
|
|
280
|
+
default: {
|
|
281
|
+
console.log("wtf??", borderNumber)
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
html.style.setProperty("--ltBorderRadius", borderRadius);
|
|
286
|
+
html.style.setProperty("--ltBorderSizeMod", borderSizeMod);
|
|
287
|
+
html.style.setProperty("--ltBorderCut", borderCut);
|
|
288
|
+
html.style.setProperty("--ltBorderOutset", borderOutset);
|
|
289
|
+
|
|
290
|
+
if (this.mode === 2) {
|
|
291
|
+
const imgPath = this.document.flags[moduleJSON.id]?.image;
|
|
292
|
+
if (!imgPath) return;
|
|
293
|
+
const scrollable = html.querySelector(".journal-entry-content .scrollable");
|
|
294
|
+
|
|
295
|
+
// Create and insert scenery element
|
|
296
|
+
const sceneryDiv = document.createElement("div");
|
|
297
|
+
sceneryDiv.className = "scenery mask upside-down";
|
|
298
|
+
sceneryDiv.innerHTML = `<img src="/${imgPath}">`;
|
|
299
|
+
scrollable.prepend(sceneryDiv);
|
|
300
|
+
|
|
301
|
+
const scenery = scrollable.querySelector(".scenery");
|
|
302
|
+
|
|
303
|
+
scrollable.addEventListener("scroll", ({ target }) => {
|
|
304
|
+
const opacity = Math.max(10, 100 - target.scrollTop / 2);
|
|
305
|
+
scenery.style.opacity = `${opacity}%`;
|
|
306
|
+
scenery.style.pointerEvents = opacity < 50 ? "none" : "auto";
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
const header = html.querySelector("header.journal-header");
|
|
311
|
+
header.remove();
|
|
312
|
+
|
|
313
|
+
const title = document.createElement('header');
|
|
314
|
+
title.textContent = this.document.name;
|
|
315
|
+
scenery.appendChild(title);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// Level Select
|
|
319
|
+
const levelSelect = html.querySelector("#level-select");
|
|
320
|
+
|
|
321
|
+
if (levelSelect) {
|
|
322
|
+
// Add radio inputs to each level
|
|
323
|
+
const levelOptions = levelSelect.querySelectorAll("[data-level]");
|
|
324
|
+
levelOptions.forEach((option) => {
|
|
325
|
+
const input = document.createElement("input");
|
|
326
|
+
input.type = "radio";
|
|
327
|
+
input.name = "level-selector";
|
|
328
|
+
option.prepend(input);
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
// Handle radio button clicks
|
|
332
|
+
const radioInputs = levelSelect.querySelectorAll("input[type='radio']");
|
|
333
|
+
radioInputs.forEach((radio) => {
|
|
334
|
+
radio.addEventListener("click", function () {
|
|
335
|
+
const radioElement = this;
|
|
336
|
+
|
|
337
|
+
if (radioElement.checked) {
|
|
338
|
+
// Uncheck all radios in the group
|
|
339
|
+
const groupName = radioElement.name;
|
|
340
|
+
const allRadios = levelSelect.querySelectorAll(`input[type='radio'][name='${groupName}']`);
|
|
341
|
+
allRadios.forEach((r) => {
|
|
342
|
+
(r).checked = false;
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
// Check the clicked radio
|
|
346
|
+
radioElement.checked = true;
|
|
347
|
+
|
|
348
|
+
// Get level and update
|
|
349
|
+
const parent = radioElement.parentElement;
|
|
350
|
+
const level = parseInt(parent.dataset.level || "0", 10);
|
|
351
|
+
|
|
352
|
+
ui.notifications.info(`Setting the adventure level to ${level}!`);
|
|
353
|
+
doc.update({ flags: { [moduleJSON.id]: { level } } });
|
|
354
|
+
|
|
355
|
+
// Determine changes based on level
|
|
356
|
+
let changes = [11, 3, 3, "1d6"];
|
|
357
|
+
switch (level) {
|
|
358
|
+
case 1:
|
|
359
|
+
case 2:
|
|
360
|
+
changes = [11, 3, 3, "1d6"];
|
|
361
|
+
break;
|
|
362
|
+
case 3:
|
|
363
|
+
case 4:
|
|
364
|
+
changes = [12, 4, 3, "1d6"];
|
|
365
|
+
break;
|
|
366
|
+
case 5:
|
|
367
|
+
case 6:
|
|
368
|
+
changes = [13, 5, 5, "2d4"];
|
|
369
|
+
break;
|
|
370
|
+
case 7:
|
|
371
|
+
case 8:
|
|
372
|
+
changes = [14, 6, 7, "2d6"];
|
|
373
|
+
break;
|
|
374
|
+
case 9:
|
|
375
|
+
case 10:
|
|
376
|
+
case 11:
|
|
377
|
+
changes = [15, 7, 10, "3d6"];
|
|
378
|
+
break;
|
|
379
|
+
case 12:
|
|
380
|
+
case 13:
|
|
381
|
+
case 14:
|
|
382
|
+
changes = [16, 8, 14, "4d6"];
|
|
383
|
+
break;
|
|
384
|
+
case 15:
|
|
385
|
+
case 16:
|
|
386
|
+
case 17:
|
|
387
|
+
changes = [17, 9, 21, "6d6"];
|
|
388
|
+
break;
|
|
389
|
+
case 18:
|
|
390
|
+
case 19:
|
|
391
|
+
case 20:
|
|
392
|
+
changes = [18, 10, 28, "8d6"];
|
|
393
|
+
break;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// Update all flags
|
|
397
|
+
doc.update({
|
|
398
|
+
flags: {
|
|
399
|
+
[moduleJSON.id]: {
|
|
400
|
+
level,
|
|
401
|
+
dc: changes[0],
|
|
402
|
+
mod: changes[1],
|
|
403
|
+
damage: changes[2],
|
|
404
|
+
damageDice: changes[3],
|
|
405
|
+
},
|
|
406
|
+
},
|
|
407
|
+
});
|
|
408
|
+
} else {
|
|
409
|
+
(this).checked = false;
|
|
410
|
+
}
|
|
411
|
+
});
|
|
412
|
+
});
|
|
413
|
+
|
|
414
|
+
// Set checked state for previously chosen level
|
|
415
|
+
const chosenLevel = modFlags.level;
|
|
416
|
+
if (chosenLevel) {
|
|
417
|
+
const chosenOption = levelSelect.querySelector(`[data-level="${chosenLevel}"]`);
|
|
418
|
+
if (chosenOption) {
|
|
419
|
+
const chosenInput = chosenOption.querySelector("input");
|
|
420
|
+
chosenInput.checked = true;
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
async _renderPageViews(context, options) {
|
|
427
|
+
const rendered = await super._renderPageViews(context, options);
|
|
428
|
+
this.applyHelianaHeaders()
|
|
429
|
+
return rendered;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
applyHelianaHeaders(target = this.element) {
|
|
433
|
+
const headers = target.querySelectorAll("h2");
|
|
434
|
+
headers.forEach((h2) => {
|
|
435
|
+
const parent = h2.parentElement;
|
|
436
|
+
if (!parent) return;
|
|
437
|
+
parent.classList.add("heliana-style-bg");
|
|
438
|
+
|
|
439
|
+
// Find appropriate background based on header width
|
|
440
|
+
const background = backgrounds.find((bg) => h2.offsetWidth <= bg.maxWidth);
|
|
441
|
+
|
|
442
|
+
if (background) {
|
|
443
|
+
parent.style.backgroundImage = `url("/modules/${moduleJSON.id}/assets/journals/headers/${background.image}")`;
|
|
444
|
+
}
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
async deleteSelf() {
|
|
449
|
+
await this.close({ force: true });
|
|
450
|
+
// @ts-expect-error Intentional for purposes of HMR
|
|
451
|
+
this.document._sheet = null;
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
function registerSheet(sheet) {
|
|
456
|
+
foundry.applications.apps.DocumentSheetConfig.registerSheet(JournalEntry, moduleJSON.id, sheet, {
|
|
457
|
+
label: `LT - ${moduleJSON.title} Sheet`,
|
|
458
|
+
canBeDefault: false,
|
|
459
|
+
});
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
function unregisterSheet(sheet) {
|
|
463
|
+
foundry.applications.apps.DocumentSheetConfig.unregisterSheet(JournalEntry, moduleJSON.id, sheet);
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
// Assuming we are inside a Hooks.on("ready")
|
|
467
|
+
registerSheet(LootTavernSheet)
|
|
468
|
+
|
|
469
|
+
if (import.meta.hot) {
|
|
470
|
+
import.meta.hot.accept(async (newModule) => {
|
|
471
|
+
if (!newModule) return;
|
|
472
|
+
let reopenedDocuments = [];
|
|
473
|
+
|
|
474
|
+
unregisterSheet(LootTavernSheet);
|
|
475
|
+
|
|
476
|
+
for (const type of affectedDocuments) {
|
|
477
|
+
for (const doc of game[type].contents) {
|
|
478
|
+
// @ts-expect-error Custom function for LootTavernSheets
|
|
479
|
+
if (doc.sheet.deleteSelf) {
|
|
480
|
+
// @ts-expect-error Custom function for LootTavernSheets
|
|
481
|
+
await doc.sheet.deleteSelf();
|
|
482
|
+
reopenedDocuments.push(doc.uuid);
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
};
|
|
486
|
+
|
|
487
|
+
registerSheet(newModule.LootTavernSheet);
|
|
488
|
+
console.log(`Registered new ${newModule.LootTavernSheet.name} sheet.`)
|
|
489
|
+
|
|
490
|
+
reopenedDocuments.forEach(async (uuid) => {
|
|
491
|
+
const doc = await fromUuid(uuid);
|
|
492
|
+
if (!doc) return;
|
|
493
|
+
|
|
494
|
+
doc?.sheet?.render(true);
|
|
495
|
+
});
|
|
496
|
+
reopenedDocuments = [];
|
|
497
|
+
});
|
|
498
498
|
}
|