fix: Dice So Nice import v14 compat, override Foundry text colors for readability
Release Creation / build (release) Failing after 1m28s

- hooks.mjs: replace static dice-so-nice import with dynamic import
  using game.modules.get('dice-so-nice').id (path removed in v14)
- hooks.mjs: fix permission condition (|| -> &&), jQuery -> vanilla JS
- less/base.less: override --color-text-* and --button-text-color
  for both .themed.theme-dark (AppV2) and body.theme-dark (legacy apps)
- target #settings-config buttons + labels + hints for dark grays
This commit is contained in:
2026-07-12 22:05:45 +02:00
parent dcc24b47ec
commit 90de66d668
44 changed files with 516 additions and 4305 deletions
+52 -54
View File
@@ -28,7 +28,8 @@ export class VermineUtils {
skillCategory = null,
keepTotem = null,
skillLevel = null,
hasSpecialty = false
hasSpecialty = false,
handicap = 0
}) {
// Validate inputs
if (!actor) {
@@ -100,10 +101,13 @@ export class VermineUtils {
NoD++; // Cancel the decrement for adapted
} else if (keepTotem === 'adapted' && totems.human) {
modFormula = `(1D10cs>=${adjustedDifficulty}[adapted_${safeUserName}]*2)`;
NoD++; // Cancel the decrement for human
NoD++; // Cancel the decrement for human
}
}
// Apply handicap (wounds/maluses reduce dice pool)
NoD = Math.max(1, NoD - handicap)
// Build base formula
const baseFormula = `${NoD}d10cs>=${adjustedDifficulty}[regular_${safeUserName}]`;
@@ -364,67 +368,61 @@ export class VermineUtils {
* @param {HTMLElement} html - The HTML element containing chat events.
*/
static async chatListenners(html) {
// Ensure html is a jQuery object
const $html = $(html);
// Get reroll count
const rerollCountElement = $html.find('#allowed_reroll')[0];
const rerollCountElement = html.querySelector('#allowed_reroll');
const rerollCount = rerollCountElement?.innerText;
// Enable/disable rerolls based on count
if (!rerollCount || parseInt(rerollCount, 10) < 1) {
// Disable rerolls for all dice
$html.find('.die').each(function() {
this.classList.remove("rerollable");
});
} else {
// Enable rerolls for all dice
$html.find('.die').each(function() {
this.classList.add("rerollable");
});
}
const dieClass = !rerollCount || parseInt(rerollCount, 10) < 1 ? 'remove' : 'add';
html.querySelectorAll('.die').forEach(el => el.classList[dieClass]("rerollable"));
// Add click event for rerollable dice
$html.find('.rerollable').click(async (ev) => {
ev.preventDefault();
const msgId = ev.currentTarget.closest("li.message")?.dataset?.messageId;
if (msgId) {
const message = await game.messages.get(msgId);
await VermineUtils.onReroll(message, ev);
}
html.querySelectorAll('.rerollable').forEach(el => {
el.addEventListener('click', async (ev) => {
ev.preventDefault();
const msgId = ev.currentTarget.closest("li.message")?.dataset?.messageId;
if (msgId) {
const message = await game.messages.get(msgId);
await VermineUtils.onReroll(message, ev);
}
});
});
// Update granted reroll label
$html.find("#effort-reroll").change(ev => {
const label = $html.find("#granted-reroll")[0];
if (label) {
label.innerText = ev.currentTarget.value;
}
});
const effortReroll = html.querySelector("#effort-reroll");
if (effortReroll) {
effortReroll.addEventListener('change', ev => {
const label = html.querySelector("#granted-reroll");
if (label) {
label.innerText = ev.currentTarget.value;
}
});
}
// Add click event for granting rerolls
$html.find("button.grant-reroll").click(async (ev) => {
const grantedRerollElement = $html.find('#granted-reroll')[0];
const allowedRerollElement = $html.find("#allowed_reroll")[0];
if (grantedRerollElement && allowedRerollElement) {
allowedRerollElement.innerText = grantedRerollElement.innerText;
}
const mesEl = ev.currentTarget.closest('[data-message-id]');
const messageId = mesEl?.dataset?.messageId;
if (messageId) {
// Hide reroll grant area
ev.currentTarget.closest('.reroll-from-effort').style.display = "none";
const rollMessage = ev.currentTarget.closest(".vermine-roll-message");
if (rollMessage) {
const content = rollMessage.outerHTML;
const message = await game.messages.get(messageId);
await message.update({ content: content });
html.querySelectorAll("button.grant-reroll").forEach(el => {
el.addEventListener('click', async (ev) => {
const grantedRerollElement = html.querySelector('#granted-reroll');
const allowedRerollElement = html.querySelector("#allowed_reroll");
if (grantedRerollElement && allowedRerollElement) {
allowedRerollElement.innerText = grantedRerollElement.innerText;
}
}
const mesEl = ev.currentTarget.closest('[data-message-id]');
const messageId = mesEl?.dataset?.messageId;
if (messageId) {
ev.currentTarget.closest('.reroll-from-effort').style.display = "none";
const rollMessage = ev.currentTarget.closest(".vermine-roll-message");
if (rollMessage) {
const content = rollMessage.outerHTML;
const message = await game.messages.get(messageId);
await message.update({ content: content });
}
}
});
});
}
@@ -448,10 +446,10 @@ export class VermineUtils {
blind = true;
// Falls through
case "gmroll": // GM + rolling player
whisper = this.getUsers(user => user.isGM);
whisper = game.users?.filter(user => user.isGM) || [];
break;
case "roll": // Everybody
whisper = this.getUsers(user => user.active);
whisper = game.users?.filter(user => user.active) || [];
break;
case "selfroll":
whisper = [game.user.id];