code review: fix critical issues and improve code quality
- Fix constructor in rollDialog.mjs (spread operator for options) - Remove all console.log statements from production code - Add comprehensive JSDoc comments for all public APIs - Convert French comments to English for consistency - Use parseInt with radix parameter (10) throughout - Replace let with const where appropriate - Use Set for O(1) lookups in group-link.mjs methods - Use spread operators for array cloning - Optimize removeActorFromAllGroups with Set lookups - Improve registerHooks with better comments and Set usage - Simplify roll-message.hbs template logic - Fix duplicate VERMINE key in lang/fr.json - Add missing error translations - Add .eslintrc.js with FoundryVTT-compatible linting config Compatibility: FoundryVTT v11-v14 Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
@@ -1,70 +1,86 @@
|
||||
import { VermineUtils } from "../roll.mjs";
|
||||
|
||||
/**
|
||||
* Represents a dialog for rolling dice.
|
||||
* Dialog for rolling dice in Vermine2047.
|
||||
* Handles dice pool calculation, modifiers, and roll execution.
|
||||
*/
|
||||
export default class RollDialog extends Dialog {
|
||||
|
||||
/**
|
||||
* Creates a new RollDialog instance.
|
||||
* @param {Object} data - The data for the dialog.
|
||||
* @param {HTMLElement} html - The HTML content of the dialog.
|
||||
* @param {Object} options - The options for the dialog.
|
||||
* @param {Function} close - The callback function for closing the dialog.
|
||||
* @param {Object} data - The data for the dialog
|
||||
* @param {HTMLElement} html - The HTML content of the dialog
|
||||
* @param {Object} options - The options for the dialog
|
||||
* @param {Function} [close] - The callback function for closing the dialog
|
||||
*/
|
||||
|
||||
constructor(data, html, options, close = undefined) {
|
||||
let conf = {
|
||||
const conf = {
|
||||
title: "jet de dés",
|
||||
content: html,
|
||||
buttons: {
|
||||
roll: {
|
||||
icon: '<i class="fas fa-check"></i>',
|
||||
label: "Lancer !",
|
||||
callback: () => {
|
||||
this._onRoll()
|
||||
}
|
||||
callback: () => this._onRoll()
|
||||
},
|
||||
cancel: {
|
||||
icon: '<i class="fas fa-times"></i>',
|
||||
label: "Annuler",
|
||||
callback: () => { this.close() }
|
||||
callback: () => this.close()
|
||||
}
|
||||
},
|
||||
close: close,
|
||||
|
||||
}
|
||||
return super({ ...conf, ...data }, options);
|
||||
};
|
||||
close: close
|
||||
};
|
||||
super({ ...conf, ...data }, options);
|
||||
// Store reference to close callback
|
||||
this._closeCallback = close;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new RollDialog instance.
|
||||
* @param {Object} data - The data for the dialog.
|
||||
* @param {HTMLElement} html - The HTML content of the dialog.
|
||||
* @param {Object} options - The options for the dialog.
|
||||
* @param {Function} close - The callback function for closing the dialog.
|
||||
*/
|
||||
* Creates a new RollDialog instance.
|
||||
* @param {Object} [data] - The data for the dialog
|
||||
* @param {string} [data.label] - Roll label
|
||||
* @param {string} [data.rolltype] - Roll type
|
||||
* @param {number} [data.NoD=1] - Number of dice
|
||||
* @param {boolean} [data.Reroll=false] - Allow rerolls
|
||||
* @param {string} [data.actorId] - Actor ID for the roll
|
||||
* @returns {Promise<RollDialog|null>} The RollDialog instance or null if creation failed
|
||||
*/
|
||||
static async create(data = {
|
||||
label: null,
|
||||
rolltype: null,
|
||||
NoD: 1,
|
||||
Reroll: false,
|
||||
actorId: game.user.character?.id || canvas.tokens.controlled[0]?.actor.id
|
||||
actorId: game.user.character?.id ?? canvas.tokens.controlled[0]?.actor?.id
|
||||
}) {
|
||||
// Retrieve the actor data based on the actorId
|
||||
data.actor = await game.actors.get(data.actorId);
|
||||
if (!data.actor) {
|
||||
return await ui.notifications.warn("Vous n'avez pas de personnage attitré ou de token selectionné");
|
||||
|
||||
// Validate actorId
|
||||
const actorId = data.actorId;
|
||||
if (!actorId || typeof actorId !== 'string') {
|
||||
ui.notifications.warn(game.i18n.localize('VERMINE.error_no_actor_selected'));
|
||||
return null;
|
||||
}
|
||||
console.log(data.actor)
|
||||
data.availableSpecialties = data.actor.items.filter(it => it.type == "specialty");
|
||||
console.log(data.availableSpecialties)
|
||||
data.availableItems = data.actor.items.filter(it => it.type == "item");
|
||||
|
||||
// Retrieve the actor data based on the actorId
|
||||
data.actor = await game.actors.get(actorId);
|
||||
if (!data.actor) {
|
||||
ui.notifications.warn(game.i18n.localize('VERMINE.error_no_actor_selected'));
|
||||
return null;
|
||||
}
|
||||
|
||||
data.availableSpecialties = data.actor.items.filter(item => item.type === "specialty");
|
||||
data.availableItems = data.actor.items.filter(item => item.type === "item");
|
||||
data.config = CONFIG.VERMINE;
|
||||
|
||||
// Define options for the dialog
|
||||
let options = { classes: ["vermineDialog"], width: "fit-content", height: 'fit-content', 'z-index': 99999 };
|
||||
const options = {
|
||||
classes: ["vermineDialog"],
|
||||
width: "fit-content",
|
||||
height: 'fit-content',
|
||||
zIndex: 99999
|
||||
};
|
||||
|
||||
// Render the HTML template for the dialog
|
||||
let html = await renderTemplate('systems/vermine2047/templates/dialogs/roll-dialog.hbs', data);
|
||||
const html = await renderTemplate('systems/vermine2047/templates/dialogs/roll-dialog.hbs', data);
|
||||
|
||||
// Return a new RollDialog instance with the provided data, HTML, and options
|
||||
return new RollDialog(data, html, options);
|
||||
@@ -82,25 +98,31 @@ export default class RollDialog extends Dialog {
|
||||
}
|
||||
/**
|
||||
* Retrieves the data for the dialog.
|
||||
* @returns {Object} The context data for the dialog.
|
||||
* @returns {Object} The context data for the dialog
|
||||
*/
|
||||
getData() {
|
||||
// Get the context data from the superclass
|
||||
let context = super.getData();
|
||||
const context = super.getData();
|
||||
context.data = this.data;
|
||||
context.config = CONFIG.VERMINE;
|
||||
|
||||
// Return the context data
|
||||
return context;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares items for display.
|
||||
* @returns {Array} Filtered list of items
|
||||
*/
|
||||
prepareItems() {
|
||||
return this.data.actor.items.filter(it => it.type == "item")
|
||||
return this.data.actor.items.filter(it => it.type === "item");
|
||||
}
|
||||
prepareSpecialties() {
|
||||
return this.data.actor.items.filter(it => it.type == "specialty")
|
||||
|
||||
/**
|
||||
* Prepares specialties for display.
|
||||
* @returns {Array} Filtered list of specialties
|
||||
*/
|
||||
prepareSpecialties() {
|
||||
return this.data.actor.items.filter(it => it.type === "specialty");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -118,18 +140,18 @@ export default class RollDialog extends Dialog {
|
||||
await this.getRollData();
|
||||
|
||||
// Set up event listeners for all roll-related inputs
|
||||
let rollInputs = html.find('[data-roll]');
|
||||
for (let inp of rollInputs) {
|
||||
const rollInputs = html.find('[data-roll]');
|
||||
for (const inp of rollInputs) {
|
||||
inp.addEventListener('change', this._onRollInputChange.bind(this));
|
||||
};
|
||||
}
|
||||
|
||||
this.displaySpecialties();
|
||||
|
||||
let selectAbil = html.find('#ability')[0];
|
||||
const selectAbil = html.find('#ability')[0];
|
||||
// Set the maximum value for self control based on ability value
|
||||
html.find("#self_control")[0].max = selectAbil.value;
|
||||
selectAbil.addEventListener('change', this._onChangeAbility.bind(this));
|
||||
let selfControl = html.find('#self_control')[0]
|
||||
const selfControl = html.find('#self_control')[0];
|
||||
// Add event listener for self control changes
|
||||
selfControl.addEventListener('change', this._onChangeSelfControl.bind(this));
|
||||
|
||||
@@ -150,9 +172,9 @@ export default class RollDialog extends Dialog {
|
||||
|
||||
/**
|
||||
* Retrieves the roll data for the dialog.
|
||||
* @param {Event} ev - The event triggering the roll data retrieval.
|
||||
* @param {Event} _ev - The event triggering the roll data retrieval (unused).
|
||||
*/
|
||||
async getRollData(ev) {
|
||||
getRollData(_ev) {
|
||||
// Calculate and store the roll data
|
||||
this.rollData = {
|
||||
actor: this.data.actor,
|
||||
@@ -167,7 +189,7 @@ export default class RollDialog extends Dialog {
|
||||
max_effort: this.getMaxEffort(),
|
||||
keepTotem: this.getKeepTotem(),
|
||||
skillCategory: this.getSkillCategory()
|
||||
}
|
||||
};
|
||||
this.displaySpecialties();
|
||||
this._updateUI();
|
||||
};
|
||||
@@ -211,11 +233,11 @@ export default class RollDialog extends Dialog {
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles changes to roll inputs and updates UI
|
||||
* @param {Event} ev - The change event
|
||||
* Handles changes to roll inputs and updates UI.
|
||||
* @param {Event} ev - The change event.
|
||||
*/
|
||||
async _onRollInputChange(ev) {
|
||||
await this.getRollData();
|
||||
_onRollInputChange(ev) {
|
||||
this.getRollData(ev);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -280,41 +302,41 @@ export default class RollDialog extends Dialog {
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the bonus count for display
|
||||
* @returns {number} - Total bonus dice
|
||||
* Calculates the bonus count for display.
|
||||
* @returns {number} Total bonus dice.
|
||||
*/
|
||||
_calculateBonusCount() {
|
||||
let bonus = 0;
|
||||
|
||||
// Help bonus
|
||||
if (this._html.find('#helped')[0]?.checked) {
|
||||
if (this._html?.find('#helped')[0]?.checked) {
|
||||
bonus += 1;
|
||||
}
|
||||
|
||||
// Group bonus
|
||||
const groupValue = parseInt(this._html.find('#group')[0]?.value) || 0;
|
||||
const groupValue = parseInt(this._html?.find('#group')[0]?.value, 10) || 0;
|
||||
bonus += groupValue;
|
||||
|
||||
// Self control bonus
|
||||
const selfControlValue = parseInt(this._html.find('#self_control')[0]?.value) || 0;
|
||||
const selfControlValue = parseInt(this._html?.find('#self_control')[0]?.value, 10) || 0;
|
||||
bonus += selfControlValue;
|
||||
|
||||
// Tools bonus
|
||||
const toolsChecked = this._html.find('input[name="usingTools"]:checked')[0]?.value !== '0';
|
||||
const toolsChecked = this._html?.find('input[name="usingTools"]:checked')[0]?.value !== '0';
|
||||
if (toolsChecked) {
|
||||
bonus += 1;
|
||||
}
|
||||
|
||||
// Totems bonus
|
||||
if (this._html.find('#human-totem')[0]?.checked) {
|
||||
bonus += parseInt(this.data.actor.system.adaptation.totems.human.value) || 0;
|
||||
if (this._html?.find('#human-totem')[0]?.checked) {
|
||||
bonus += parseInt(this.data.actor?.system?.adaptation?.totems?.human?.value, 10) || 0;
|
||||
}
|
||||
if (this._html.find('#adapted-totem')[0]?.checked) {
|
||||
bonus += parseInt(this.data.actor.system.adaptation.totems.adapted.value) || 0;
|
||||
if (this._html?.find('#adapted-totem')[0]?.checked) {
|
||||
bonus += parseInt(this.data.actor?.system?.adaptation?.totems?.adapted?.value, 10) || 0;
|
||||
}
|
||||
|
||||
// Specialty bonus
|
||||
const specialtyChecked = this._html.find('input[name="usingSpecialization"]:checked')[0]?.value !== 'aucune';
|
||||
const specialtyChecked = this._html?.find('input[name="usingSpecialization"]:checked')[0]?.value !== 'aucune';
|
||||
if (specialtyChecked) {
|
||||
bonus += 1;
|
||||
}
|
||||
@@ -365,45 +387,69 @@ export default class RollDialog extends Dialog {
|
||||
* @param {Event} ev - The event triggering the change in self control value.
|
||||
*/
|
||||
_onChangeSelfControl(ev) {
|
||||
let html = this.element[0];
|
||||
// Update the displayed self control value based on the event
|
||||
html.querySelector('#self_control_value').innerText = ev.currentTarget.value;
|
||||
};
|
||||
const html = this.element[0];
|
||||
const selfControlValueElement = html.querySelector('#self_control_value');
|
||||
if (selfControlValueElement) {
|
||||
selfControlValueElement.innerText = ev.currentTarget.value;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Retrieves the handicap value from the HTML element.
|
||||
* @returns {number} The handicap value.
|
||||
*/
|
||||
getHandicap() {
|
||||
let html = this.element[0];
|
||||
// Parse and return the self control value from the HTML element
|
||||
let handicap = parseInt(html.querySelector('#handicap').value)
|
||||
return handicap
|
||||
const html = this.element[0];
|
||||
const handicapValue = html.querySelector('#handicap')?.value ?? '1';
|
||||
return parseInt(handicapValue, 10);
|
||||
}
|
||||
/**
|
||||
* Gets the roll type (ability or skill).
|
||||
* @returns {string} The roll type: 'skill' or 'ability'.
|
||||
*/
|
||||
getRollType() {
|
||||
let html = this.element[0];
|
||||
// Update the displayed self control value based on the event
|
||||
if (html.querySelector('select#skill').value) {
|
||||
return "skill"
|
||||
} return "ability"
|
||||
const html = this.element[0];
|
||||
return html.querySelector('select#skill')?.value ? "skill" : "ability";
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the label for the roll.
|
||||
* @returns {string} The roll label.
|
||||
*/
|
||||
getLabel() {
|
||||
let html = this.element[0];
|
||||
if (this.getRollType() == "skill") {
|
||||
return html.querySelector('select#skill').options[html.querySelector('select#skill').selectedIndex].dataset.label
|
||||
const html = this.element[0];
|
||||
const rollType = this.getRollType();
|
||||
|
||||
if (rollType === "skill") {
|
||||
const skillSelect = html.querySelector('select#skill');
|
||||
const selectedIndex = skillSelect?.selectedIndex ?? 0;
|
||||
return skillSelect?.options[selectedIndex]?.dataset?.label ?? "";
|
||||
}
|
||||
return html.querySelector('select#ability').options[html.querySelector('select#ability').selectedIndex].dataset.label
|
||||
|
||||
const abilitySelect = html.querySelector('select#ability');
|
||||
const selectedIndex = abilitySelect?.selectedIndex ?? 0;
|
||||
return abilitySelect?.options[selectedIndex]?.dataset?.label ?? "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays specialties related to the selected skill.
|
||||
*/
|
||||
displaySpecialties() {
|
||||
let specialties = this.element[0].querySelectorAll('[data-spec-skill]');
|
||||
for (let specEl of specialties) {
|
||||
specEl.style.display = "inline"
|
||||
const specialties = this.element[0]?.querySelectorAll('[data-spec-skill]');
|
||||
if (specialties) {
|
||||
specialties.forEach(specEl => {
|
||||
specEl.style.display = "inline";
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the self control value from the HTML element.
|
||||
* @returns {number} The self control value.
|
||||
*/
|
||||
getSelfControl() {
|
||||
let html = this.element[0];
|
||||
// Parse and return the self control value from the HTML element
|
||||
let selfControl = parseInt(html.querySelector('#self_control').value)
|
||||
return selfControl
|
||||
const html = this.element[0];
|
||||
const selfControlValue = html.querySelector('#self_control')?.value ?? '0';
|
||||
return parseInt(selfControlValue, 10);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -411,23 +457,21 @@ export default class RollDialog extends Dialog {
|
||||
* @returns {number} The maximum effort value.
|
||||
*/
|
||||
getMaxEffort() {
|
||||
let html = this.element[0];
|
||||
// Retrieve and return the maximum effort value from the HTML element
|
||||
return parseInt(html.querySelector('#ability').value);
|
||||
const html = this.element[0];
|
||||
const abilityValue = html.querySelector('#ability')?.value ?? '0';
|
||||
return parseInt(abilityValue, 10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the selected totems from the HTML element.
|
||||
* @returns {Object} An object containing the selected totems.
|
||||
* @returns {Object} An object containing the selected totems {human: boolean, adapted: boolean}.
|
||||
*/
|
||||
getTotems() {
|
||||
let html = this.element[0];
|
||||
// Check and store the status of human and adapted totems
|
||||
let totems = {
|
||||
human: html.querySelector('#human-totem')?.checked,
|
||||
adapted: html.querySelector('#adapted-totem')?.checked,
|
||||
}
|
||||
return totems
|
||||
const html = this.element[0];
|
||||
return {
|
||||
human: html.querySelector('#human-totem')?.checked ?? false,
|
||||
adapted: html.querySelector('#adapted-totem')?.checked ?? false
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -435,37 +479,50 @@ export default class RollDialog extends Dialog {
|
||||
* @param {Event} ev - The event triggering the change in ability value.
|
||||
*/
|
||||
_onChangeAbility(ev) {
|
||||
let html = this.element[0];
|
||||
// Retrieve the selected ability score and update related elements
|
||||
let score = html.querySelector('#ability').options[html.querySelector('#ability').selectedIndex].value;
|
||||
// Check if the score is a number, otherwise set it to 0
|
||||
if (!typeof score == "number") {
|
||||
score = 0
|
||||
const html = this.element[0];
|
||||
const abilitySelect = html.querySelector('#ability');
|
||||
const selectedIndex = abilitySelect?.selectedIndex ?? 0;
|
||||
const score = abilitySelect?.options[selectedIndex]?.value ?? '0';
|
||||
|
||||
const scoreElement = html.querySelector('#abilityScore');
|
||||
if (scoreElement) {
|
||||
scoreElement.value = score;
|
||||
}
|
||||
|
||||
const selfControlElement = html.querySelector('#self_control');
|
||||
if (selfControlElement) {
|
||||
selfControlElement.max = score;
|
||||
}
|
||||
html.querySelector('#abilityScore').value = score;
|
||||
html.querySelector('#self_control').max = score;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the total dice pool based on various factors.
|
||||
* @returns {number} The total dice pool value.
|
||||
*/
|
||||
* Retrieves the total dice pool based on various factors.
|
||||
* @returns {number} The total dice pool value.
|
||||
*/
|
||||
getDicePool() {
|
||||
// Retrieve the HTML element
|
||||
let html = this.element[0];
|
||||
// Get the ability value or set to 0 if not found
|
||||
let abilValue = html.querySelector('#ability').options[html.querySelector('#ability').selectedIndex].value || 0;
|
||||
// Get the skill value or set to 0 if not found
|
||||
let skillValue = html.querySelector('#skill').options[html.querySelector('#skill').selectedIndex].dataset.pool || 0;
|
||||
const html = this.element[0];
|
||||
|
||||
// Safely get ability value
|
||||
const abilitySelect = html.querySelector('#ability');
|
||||
const abilValue = abilitySelect?.options[abilitySelect?.selectedIndex]?.value ?? 0;
|
||||
|
||||
// Safely get skill value and pool
|
||||
const skillSelect = html.querySelector('#skill');
|
||||
const skillOption = skillSelect?.options[skillSelect?.selectedIndex];
|
||||
const skillValue = skillOption?.dataset?.pool ?? 0;
|
||||
|
||||
// Get the self control value
|
||||
let selfControl = html.querySelector('#self_control').value;
|
||||
const selfControl = html.querySelector('#self_control')?.value ?? 0;
|
||||
|
||||
// Calculate bonuses based on certain conditions
|
||||
console.log(html.querySelector('#usingTools').checked)
|
||||
let bonuses =
|
||||
const bonuses =
|
||||
(html.querySelector('#usingSpecialization')?.checked ? 1 : 0) +
|
||||
(html.querySelector('#helped').checked ? 1 : 0) +
|
||||
(html.querySelector('#usingTools').checked ? 1 : 0);
|
||||
(html.querySelector('#helped')?.checked ? 1 : 0) +
|
||||
(html.querySelector('#usingTools')?.checked ? 1 : 0);
|
||||
|
||||
// Calculate the total dice pool
|
||||
let total = parseInt(abilValue) + parseInt(selfControl) + parseInt(skillValue) + bonuses;
|
||||
const total = parseInt(abilValue, 10) + parseInt(selfControl, 10) + parseInt(skillValue, 10) + bonuses;
|
||||
return total || 0;
|
||||
}
|
||||
|
||||
@@ -474,69 +531,66 @@ export default class RollDialog extends Dialog {
|
||||
* @returns {number} The reroll value.
|
||||
*/
|
||||
getReroll() {
|
||||
// Retrieve the HTML element
|
||||
let html = this.element[0];
|
||||
// Get the selected skill index
|
||||
let selected = html.querySelector('#skill').selectedIndex;
|
||||
// Get the reroll value from the selected skill or set to 0 if not found
|
||||
let reroll = html.querySelector('#skill').options[selected].dataset.reroll || 0;
|
||||
return parseInt(reroll) || 0;
|
||||
const html = this.element[0];
|
||||
const skillSelect = html.querySelector('#skill');
|
||||
const selectedIndex = skillSelect?.selectedIndex ?? 0;
|
||||
const rerollValue = skillSelect?.options[selectedIndex]?.dataset?.reroll ?? '0';
|
||||
return parseInt(rerollValue, 10) || 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the difficulty value based on selected option.
|
||||
* @returns {number} The difficulty value.
|
||||
*/
|
||||
|
||||
getDifficulty() {
|
||||
// Retrieve the HTML element
|
||||
let html = this.element[0];
|
||||
// Get the selected index for difficulty
|
||||
let selected = html.querySelector('#difficulty').selectedIndex;
|
||||
// Get the difficulty value from the selected option or set to 0 if not found
|
||||
let diff = html.querySelector('#difficulty').options[selected].value || 0;
|
||||
return parseInt(diff) || 0;
|
||||
const html = this.element[0];
|
||||
const difficultySelect = html.querySelector('#difficulty');
|
||||
const selectedIndex = difficultySelect?.selectedIndex ?? 0;
|
||||
const diffValue = difficultySelect?.options[selectedIndex]?.value ?? '0';
|
||||
return parseInt(diffValue, 10) || 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a dice roll based on the roll data and handles self control checks.
|
||||
* @returns {Promise} A promise that resolves with the result of the dice roll.
|
||||
*/
|
||||
* Performs a dice roll based on the roll data and handles self control checks.
|
||||
* @returns {Promise<Roll|false>} A promise that resolves with the Roll result or false if cancelled.
|
||||
*/
|
||||
async _onRoll() {
|
||||
// Check if self control is required for the roll
|
||||
if (this.rollData.self_control > 0) {
|
||||
// Check if the actor has enough self control
|
||||
if (this.rollData.actor.system.attributes.self_control.value < this.rollData.self_control) {
|
||||
const currentSelfControl = this.rollData.actor?.system?.attributes?.self_control?.value ?? 0;
|
||||
if (currentSelfControl < this.rollData.self_control) {
|
||||
// Display a warning message if self control is insufficient
|
||||
ui.notifications.warn(game.i18n.localize('VERMINE.error_not_enough_self_control'));
|
||||
// Re-render the dialog
|
||||
this.render(true);
|
||||
return false; // Exit the function if self control is insufficient
|
||||
}
|
||||
|
||||
}
|
||||
let caracName = this.element[0].querySelector('[name="ability"]')?.value
|
||||
if (caracName == "0" || caracName === undefined) {
|
||||
|
||||
const caracName = this.element[0]?.querySelector('[name="ability"]')?.value;
|
||||
if (caracName === "0" || caracName === undefined) {
|
||||
// Display a warning message if no ability selected
|
||||
ui.notifications.warn(game.i18n.localize('VERMINE.error_select_ability'));
|
||||
// Re-render the dialog
|
||||
this.render(true);
|
||||
return false; // Exit the function if no ability
|
||||
}
|
||||
|
||||
// Deduct self control points if necessary
|
||||
if (this.rollData.self_control > 0) {
|
||||
const newSelfControl = this.rollData.actor.system.attributes.self_control.value - this.rollData.self_control;
|
||||
// Update the actor's self control value
|
||||
await this.rollData.actor.update({
|
||||
"system.attributes.self_control.value":
|
||||
this.rollData.actor.system.attributes.self_control.value - this.rollData.self_control
|
||||
await this.rollData.actor.update({
|
||||
"system.attributes.self_control.value": newSelfControl
|
||||
});
|
||||
}
|
||||
|
||||
// Perform the dice roll using VermineUtils
|
||||
return VermineUtils.roll({
|
||||
...this.rollData,
|
||||
skillLevel: this.getSkillLevel(),
|
||||
hasSpecialty: this.hasSpecialtySelected()
|
||||
return VermineUtils.roll({
|
||||
...this.rollData,
|
||||
skillLevel: this.getSkillLevel(),
|
||||
hasSpecialty: this.hasSpecialtySelected()
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user