reroll OK

This commit is contained in:
rwanoux
2024-04-28 16:35:48 +02:00
parent 74e11d439c
commit 0fada335f4
85 changed files with 1273 additions and 435 deletions
+5 -6
View File
@@ -91,17 +91,16 @@ export class VermineActorSheet extends ActorSheet {
}
//click on wound radio
html.find('[type="radio"][data-wound]').click(ev => {
this._onWoundClick(ev)
html.find('.hexa [type="radio"]').click(ev => {
this._onClickRadioHexa(ev)
})
}
_onWoundClick(ev) {
_onClickRadioHexa(ev) {
if (!ev.currentTarget.checked) { return }
let woundType = ev.currentTarget.dataset.wound;
let targetProp = "system." + woundType + ".value";
let prop = ev.currentTarget.name;
let update = {};
update[targetProp] = ev.currentTarget.value - 1
update[prop] = ev.currentTarget.value - 1
this.actor.update(update)
+26 -16
View File
@@ -1,6 +1,6 @@
import { onManageActiveEffect, prepareActiveEffectCategories } from "../system/effects.mjs";
import { VermineActorSheet } from "./actor-sheet.mjs";
import { getRollBox } from "../system/dialogs.mjs";
import { RollDialog } from "../system/dialogs.mjs";
import { TotemPicker } from "../system/applications.mjs";
/**
@@ -103,16 +103,35 @@ export class VermineCharacterSheet extends VermineActorSheet {
// Choose Totem
html.find('.chooseTotem').click(this._onTotemButton.bind(this));
html.find('.ability .rollable').click(this._onRoll.bind(this));
html.find('[data-totem-name]').click(this._onClickTotemDice.bind(this))
}
async _onClickTotemDice(ev) {
let el = ev.currentTarget;
let totem = el.dataset.totemName;
let value = parseInt(el.dataset.totemValue);
let oldValue = this.actor.system.adaptation.totems[totem].value;
if (value === oldValue) { value-- };
let updates = {};
updates[`system.adaptation.totems.${totem}.value`] = value;
let totems = this.actor.system.adaptation.totems;
let sumTotems = Object.keys(totems).reduce(function (previous, key) {
return previous + totems[key].value;
}, 0);
if (sumTotems >5) {
ui.notifications.warn('vous ne pouvez pas avoir plus de 5 dés totems')
}
console.log(sumTotems, updates)
await this.actor.update(updates);
}
/**
* Handle clickable rolls.
* @param {Event} event The originating click event
* @private
*/
_onRoll(event) {
async _onRoll(event) {
event.preventDefault();
const element = event.currentTarget;
const dataset = element.dataset;
@@ -129,26 +148,17 @@ export class VermineCharacterSheet extends VermineActorSheet {
// Handle rolls that supply the formula directly.
if (dataset.label) {
dataset.rollType = dataset.type;
/*const label = game.i18n.localize(dataset.label) ? `[ability] ${game.i18n.localize(dataset.label)}` : '';
console.log($(element).attr('for'));
const NoD = this.actor.system.skills[$(element).attr('for').split('.')[2]]?.value || 0
return game.vermine2047.VermineRoll.roll(this.actor.id, label, NoD, 0, {});*/
let data = {
actorId: this.actor.id,
abilities: this.actor.system.abilities,
skills: this.actor.system.skills,
rollType: dataset.rollType,
labelKey: dataset.label,
abilityScore: 0,
skillScore: 0,
label: game.i18n.localize(dataset.label)
};
if (dataset.type == 'ability') {
data.abilityScore = this.actor.system.abilities[dataset.label].value;
} else if (dataset.type == 'skill') {
data.skillScore = this.actor.system.skills[dataset.label].value;
}
getRollBox(data);
let dial = await RollDialog.create(data);
dial.render(true)
return true;
}
}
+128 -119
View File
@@ -35,24 +35,40 @@ export class CombatResultDialog extends Dialog {
}
export class RollDialog extends Dialog {
static async create(rollData) {
let options = { classes: ["vermine-roll"], width: 420, height: 'fit-content', 'z-index': 99999 };
let html = await renderTemplate('systems/vermine2047/templates/roll.hbs', rollData);
static async create(data = {
label: null,
rolltype: null,
NoD: 1,
Reroll: false,
actorId: game.user.character.id
}) {
data.actor = await game.actors.get(data.actorId);
data.config = CONFIG.VERMINE;
let options = { classes: ["nocDialog"], width: 420, height: 'fit-content', 'z-index': 99999 };
let html = await renderTemplate('systems/vermine2047/templates/roll-dialog.hbs', data);
return new RollDialog(actor, rollData, html, options);
return new RollDialog(data, html, options);
}
static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
focus: true,
classes: ["dialog vermine-roll"],
});
}
/* -------------------------------------------- */
constructor(data, html, options, close = undefined) {
let conf = {
title: "",
title: "jet de dés",
content: html,
buttons: {
roll: {
icon: '<i class="fas fa-check"></i>',
label: "Lancer !",
callback: () => { this.roll(data.actorId, data.label, data.NoD, data.Reroll) }
callback: () => {
this.roll()
}
},
cancel: {
icon: '<i class="fas fa-times"></i>',
@@ -60,124 +76,117 @@ export class RollDialog extends Dialog {
callback: () => { this.close() }
}
},
close: close
close: close,
}
super(conf, options);
return super({ ...conf, ...data }, options);
this.data = data;
};
getData() {
let context = super.getData();
context.data = this.data;
context.config = CONFIG.VERMINE;
return context;
}
async activateListeners(html) {
super.activateListeners(html);
this.getRollData();
let rollInputs = html.find('[data-roll');
for (let inp of rollInputs) {
inp.addEventListener('change', await this.getRollData.bind(this))
};
let selectAbil = html.find('#ability')[0];
html.find("#self_control")[0].max = selectAbil.value;
selectAbil.addEventListener('change', this._onChangeAbility.bind(this));
let selfControl = html.find('#self_control')[0]
selfControl.addEventListener('change', this._onChangeSelfControl.bind(this));
};
async getRollData(ev) {
console.log(this)
this.rollData = {
actor: this.data.actor,
NoD: this.getDicePool(),
Reroll: this.getReroll(),
difficulty: this.getDifficulty(),
rollLabel: this.data.labelKey,
totems: this.getTotems(),
self_control: this.getSelfControl(),
max_effort: this.getMaxEffort()
}
console.log('____________________________________calculating roll', this.rollData);
};
_onChangeSelfControl(ev) {
let html = this.element[0];
html.querySelector('#self_control_value').innerText = ev.currentTarget.value;
};
getSelfControl() {
let html = this.element[0];
let selfControl = parseInt(html.querySelector('#self_control').value)
return selfControl
}
getMaxEffort() {
let html = this.element[0];
return parseInt(html.querySelector('#ability').value);
}
getTotems() {
let html = this.element[0];
let totems = {
human: html.querySelector('#human-totem').checked,
adapted: html.querySelector('#adapted-totem').checked,
}
return totems
}
_onChangeAbility(ev) {
let html = this.element[0];
let score = html.querySelector('#ability').options[html.querySelector('#ability').selectedIndex].value;
if (!typeof score == "number") {
score = 0
}
html.querySelector('#abilityScore').value = score;
html.querySelector('#self_control').max = score;
}
getDicePool() {
let html = this.element[0];
let abilValue = html.querySelector('#ability').options[html.querySelector('#ability').selectedIndex].value || 0;
let skillValue = html.querySelector('#skill').options[html.querySelector('#skill').selectedIndex].dataset.pool || 0;
let selfControl = html.querySelector('#self_control').value;
let bonuses =
(html.querySelector('#usingSpecialization').checked ? 1 : 0) +
(html.querySelector('#helped').checked ? 1 : 0) +
(html.querySelector('#usingTools').checked ? 1 : 0);
let total = parseInt(abilValue) + parseInt(selfControl) + parseInt(skillValue) + bonuses;
return total || 0;
}
getReroll() {
let html = this.element[0];
let selected = html.querySelector('#skill').selectedIndex;
let reroll = html.querySelector('#skill').options[selected].dataset.reroll || 0;
return parseInt(reroll) || 0;
}
getDifficulty() {
let html = this.element[0];
let selected = html.querySelector('#difficulty').selectedIndex;
let diff = html.querySelector('#difficulty').options[selected].value || 0;
return parseInt(diff) || 0;
}
roll() {
VermineUtils.roll(actorId, label, NoD, Reroll = 0, params = {})
if (this.rollData.self_control > 0) {
if (this.rollData.actor.system.attributes.self_control.value < this.rollData.self_control) {
return ui.notifications.warn('vous navez pas assez de sang-froid')
}
}
return VermineUtils.roll({ ...this.rollData })
}
}
export const getRollBox = async function (data) {
console.log(data)
let actor = await game.actors.get(data.actorId)
let html = await renderTemplate('systems/vermine2047/templates/roll.hbs', data);
let dial = new Dialog({
title: game.i18n.localize("ROLLS.tool"),
content: html,
buttons: {
roll: {
label: game.i18n.localize('ROLLS.roll_dice'),
callback: async (html) => {
let form = html.find('#dice-pool-form');
if (!form[0].checkValidity()) {
throw "Invalid Data";
}
let formData = {};
form.serializeArray().map(item => {
formData[item.name] = item.value;
});
// console.log("roll form data", formData);
let NoD = parseInt(formData.abilityScore, 10);
let Reroll = 0;
// difficulty
data.difficulty = (formData.difficulty != undefined) ? formData.difficulty : 7;
// maîtrise bonus
if (formData.rollType == 'skill') {
NoD += CONFIG.VERMINE.SkillLevels[formData.skillScore].dicePool || 0;
Reroll += CONFIG.VERMINE.SkillLevels[formData.skillScore].reroll || 0;
}
console.log('reroll', Reroll);
// réserves
if (formData.self_control > 0) {
NoD += parseInt(formData.self_control, 10);
let newSelfControl = actor.system.attributes.self_control.value - parseInt(formData.self_control);
if (newSelfControl < 0) {
return async () => {
await ui.notifications.notify(`vous ne disposez pas d'assez de sang-froid`);
dial.render(true);
}
}
await actor.update({
"system.attributes.self_control.value": newSelfControl
})
}
if (formData.group > 0) {
NoD += parseInt(formData.group, 10);
}
// checks
if (formData.usingSpecialization !== undefined && formData.usingSpecialization == 1) {
NoD += 1;
}
if (formData.usingTools !== undefined && formData.usingTools == 1) {
NoD += 1;
}
if (formData.helped !== undefined && formData.helped == 1) {
NoD += 1;
}
if (formData.abilityScore == 0 || !formData.abilityScore) {
ui.notifications.notify(`veuillez saisir une caractéristique`);
dial.render(true);
} else
return VermineUtils.roll(data.actorId, data.label, NoD, Reroll, data);
}
},
close: {
label: game.i18n.localize('Close'),
callback: () => { }
}
},
render: function (h) {
if (h.find('input[name="abilityScore"]').val() == 0 && data.rollType == 'ability') {
h.find('input[name="abilityScore"]').val(data.abilities[data.label].value);
}
h.find('select[name="ability"]').change((event) => {
if (event.target.value != undefined) {
const abilityScore = data.abilities[event.target.value].value;
console.log('ability', abilityScore);
// on enregistre la valeur de la caractéristique
h.find('input[name="abilityScore"]').val(abilityScore);
}
});
h.find('select[name="skill"]').change((event) => {
if (data.rollType == 'skill' && event.target.value != undefined) {
const skillScore = data.skills[event.target.value].value;
// on enregistre la valeur de la compétence
h.find('input[name="skillScore"]').val(skillScore);
// on met à jour les infos de niveaux de compétence
const skillLevel = CONFIG.VERMINE.SkillLevels[skillScore];
if (skillLevel != undefined) {
h.find('#skillLevel').text(game.i18n.localize(skillLevel.label));
h.find('#skillDicePool').text(skillLevel.dicePool);
h.find('#skillReroll').text(skillLevel.reroll);
} else {
h.find('#skillLevel').text('Inconnu');
h.find('#skillDicePool').text(0);
h.find('#skillReroll').text(0);
}
}
});
}
});
dial.render(true);
}
}
+54
View File
@@ -0,0 +1,54 @@
export async function initUserDice(dice3d) {
let baseColor = game.user.color;
dice3d.addColorset({
name: 'regular_' + game.user.name,
description: "regular dice for " + game.user.name,
category: "vermine 2047",
foreground: '#9F8003',
background: baseColor,
outline: 'black',
texture: 'none',
material: 'plastic',
visibility: 'visible'
});
dice3d.addColorset({
name: 'human_' + game.user.name,
description: "human totem dice for " + game.user.name,
category: "vermine 2047",
foreground: '#9F8003',
background: lightenColor(baseColor, 40),
outline: 'black',
material: 'plastic',
visibility: 'visible'
});
dice3d.addColorset({
name: 'adapted_' + game.user.name,
description: "adapted totem dice for " + game.user.name,
category: "vermine 2047",
foreground: '#9F8003',
background: darkenColor(baseColor, 40),
outline: 'black',
material: 'plastic',
visibility: 'visible'
});
await game.user.setFlag("world", "diceInit", true);
}
export function darkenColor(color, percent) {
const num = parseInt(color.replace('#', ''), 16);
const amt = Math.round(2.55 * percent);
const R = (num >> 16) + amt;
const G = ((num >> 8) & 0x00FF) + amt;
const B = (num & 0x0000FF) + amt;
return '#' + (0x1000000 + (R < 255 ? R < 1 ? 0 : R : 255) * 0x10000 + (G < 255 ? G < 1 ? 0 : G : 255) * 0x100 + (B < 255 ? B < 1 ? 0 : B : 255)).toString(16).slice(1);
}
export function lightenColor(color, percent) {
const num = parseInt(color.replace('#', ''), 16);
const amt = Math.round(2.55 * percent);
const R = (num >> 16) - amt;
const G = ((num >> 8) & 0x00FF) - amt;
const B = (num & 0x0000FF) - amt;
return '#' + (0x1000000 + (R < 0 ? 0 : R > 255 ? 255 : R) * 0x10000 + (G < 0 ? 0 : G > 255 ? 255 : G) * 0x100 + (B < 0 ? 0 : B > 255 ? 255 : B)).toString(16).slice(1);
}
+5 -1
View File
@@ -36,7 +36,7 @@ export const preloadHandlebarsTemplates = async function () {
"systems/vermine2047/templates/actor/creature/creature-combat.hbs",
// additional templates
"systems/vermine2047/templates/roll.hbs",
"systems/vermine2047/templates/roll-dialog.hbs",
]);
};
@@ -176,6 +176,7 @@ export const registerHandlebarsHelpers = function () {
Handlebars.registerHelper('skillLevel', function (property, level, options) {
if (level < 1 || level > 5)
return "";
level = parseInt(level);
let levelData = CONFIG.VERMINE.SkillLevels[level];
if (property == 'label') {
return (levelData !== undefined) ? game.i18n.localize(levelData[property]) : "";
@@ -247,6 +248,9 @@ export const registerHandlebarsHelpers = function () {
if (a <= b) { return options.fn(this); }
return options.inverse(this);
});
Handlebars.registerHelper('ifincludes', function (arg1, arg2, options) {
return (arg1.includes(arg2)) ? options.fn(this) : options.inverse(this);
});
Handlebars.registerHelper('repeat', function (times, start, block) {
var accum = '';
+81 -38
View File
@@ -1,20 +1,62 @@
import { RollDialog } from "./dialogs.mjs";
import { initUserDice } from "./dice3d.mjs";
import { VermineUtils } from "./roll.mjs";
import { registerTours } from "./tour.mjs";
export const registerHooks = function () {
/**
* Ready hook loads tables, and override's foundry's entity link functions to provide extension to pseudo entities
*/
CONFIG.debug.hooks = true;
Hooks.once('diceSoNiceReady', async (dice3d) => {
dice3d.addSystem({ id: "Vermine2047", name: "Vermine 2047" }, "preferred");
dice3d.addDicePreset({
type: "d10",
labels: [
"systems/vermine2047/assets/images/die/d10-1.webp",
"systems/vermine2047/assets/images/die/d10-2.webp",
"systems/vermine2047/assets/images/die/d10-3.webp",
"systems/vermine2047/assets/images/die/d10-4.webp",
"systems/vermine2047/assets/images/die/d10-5.webp",
"systems/vermine2047/assets/images/die/d10-6.webp",
"systems/vermine2047/assets/images/die/d10-7.webp",
"systems/vermine2047/assets/images/die/d10-8.webp",
"systems/vermine2047/assets/images/die/d10-9.webp",
"systems/vermine2047/assets/images/die/d10-0.webp",
],
system: "Vermine2047"
});
await initUserDice(dice3d);
});
Hooks.on('renderChatMessage', async (message, html, data) => {
if (message.user._id != game.user._id) { return }
await VermineUtils.chatListenners(html)
})
Hooks.on('updateUser', async () => {
if (game.dice3d) {
initUserDice(game.dice3d)
}
})
Hooks.once("ready", async () => {
console.info("Vermine 2047 | System Initialized.");
await registerTours();
});
// changement de la pause
Hooks.on("renderPause", async function () {
if ($("#pause").attr("class") !== "paused") return;
$(".paused img").attr("src", 'systems/vermine2047/assets/images/ui/vermine_pause.webp');
$(".paused img").css({ "opacity": 1});
$(".paused img").css({ "opacity": 1 });
$("#pause.paused figcaption").text("Communauté endormie...");
});
@@ -34,16 +76,17 @@ export const registerHooks = function () {
return false;
});
Hooks.on('getSceneControlButtons', (controls) => {
/*controls.find((c) => c.name === 'token').tools.push({
name: 'Dice Roller',
title: game.i18n.localize("VERMINE.RollTool"),
icon: 'fas fa-dice-d6',
button: true,
onClick() {
VermineRoll.ui();
}
});*/
Hooks.on('getSceneControlButtons', async (controls) => {
console.log;
controls.find((c) => c.name === 'token').tools.push({
name: 'Dice Roller',
title: game.i18n.localize("VERMINE.RollTool"),
icon: 'fas fa-dice-d10',
button: true,
onClick() {
RollDialog.create().then(d => d.render(true));
}
});
});
/* -------------------------------------------- */
@@ -53,17 +96,17 @@ export const registerHooks = function () {
Hooks.on("preCreateActor", function (actor) {
console.log('pre create actor', actor.img);
if (actor.img == "icons/svg/mystery-man.svg") {
actor.updateSource({"img": `systems/vermine2047/assets/icons/actors/${actor.type}.webp`});
actor.updateSource({ "img": `systems/vermine2047/assets/icons/actors/${actor.type}.webp` });
}
});
Hooks.on("preCreateItem", function (item) {
if (item.img == "icons/svg/item-bag.svg") {
item.updateSource({"img": `systems/vermine2047/assets/icons/items/${item.type}.webp`});
// item.updateSource({"img": `systems/vermine2047/icons/competence.webp`});
item.updateSource({ "img": `systems/vermine2047/assets/icons/items/${item.type}.webp` });
// item.updateSource({"img": `systems/vermine2047/icons/competence.webp`});
}
});
/* -------------------------------------------- */
/* Combat Hooks */
/* -------------------------------------------- */
@@ -79,29 +122,29 @@ export const registerHooks = function () {
Hooks.on("updateCombat", function () {
if (game.user.isGM) {
let combatant = (game.combat.combatant) ? game.combat.combatant.actor : "";
console.log('update combat', game.combat);
/*if (combatant.type == "marker" && combatant.system.settings.general.isCounter == true) {
let step = (!combatant.system.settings.general.counting) ? -1 : combatant.system.settings.general.counting;
let newQuantity = combatant.system.pools.quantity.value + step;
combatant.update({"system.pools.quantity.value": newQuantity});
}*/
let combatant = (game.combat.combatant) ? game.combat.combatant.actor : "";
console.log('update combat', game.combat);
/*if (combatant.type == "marker" && combatant.system.settings.general.isCounter == true) {
let step = (!combatant.system.settings.general.counting) ? -1 : combatant.system.settings.general.counting;
let newQuantity = combatant.system.pools.quantity.value + step;
combatant.update({"system.pools.quantity.value": newQuantity});
}*/
}
});
/* Hooks.on("chatCommandsReady", function (chatCommands) {
chatCommands.registerCommand(chatCommands.createCommandFromData({
commandKey: "/dr",
invokeOnCommand: (chatlog, messageText, chatdata) => {
Roll.get().parse(messageText);
},
shouldDisplayToChat: false,
iconClass: "fa-dice-d6",
description: "Roll Vermine 2047 check"
}));
});*/
/* Hooks.on("chatCommandsReady", function (chatCommands) {
chatCommands.registerCommand(chatCommands.createCommandFromData({
commandKey: "/dr",
invokeOnCommand: (chatlog, messageText, chatdata) => {
Roll.get().parse(messageText);
},
shouldDisplayToChat: false,
iconClass: "fa-dice-d6",
description: "Roll Vermine 2047 check"
}));
});*/
}
+197 -23
View File
@@ -1,20 +1,180 @@
export class VermineUtils {
/**
* Méthode pour effectuer un jet de dés avec différentes options
* @param {Object} options - Les options du jet de dés
* @returns {Roll} - Le résultat du jet de dés
*/
static async roll({ actor, NoD, Reroll = 0, difficulty = 7, self_control = 0, rollLabel = "jet custom", totems = { human: false, adapted: false }, max_effort = 0 }) {
// Déclaration des variables
let formula = "";
let modFormula = null;
static roll(actorId, label, NoD, Reroll = 0, params = {}) {
const actor = game.actors.get(actorId);
let formula = '' + NoD + "d10";
// Vérification des totems humains
if (totems.human) {
NoD--;
modFormula = "(1D10cs>=" + difficulty + `[human_${game.user.name}]*2)`;
await actor.update({
"system.adaptation.totems.human.value": actor.system.adaptation.totems.human.value - 1
})
}
// Vérification des totems adaptés
if (totems.adapted) {
NoD--;
// Construction de la formule modifiée
if (modFormula != null) {
modFormula = modFormula + "+(1D10cs>=" + difficulty + `[adapted_${game.user.name}]*2)`;
} else {
modFormula = "(1D10cs>=" + difficulty + `[adapted_${game.user.name}]*2)`;
}
await actor.update({
"system.adaptation.totems.adapted.value": actor.system.adaptation.totems.adapted.value - 1
})
};
formula += (params.difficulty != undefined) ? "cs>=" + params.difficulty : "cs>=7";
// Construction de la formule de base
let baseFormula = '' + NoD + "d10";
baseFormula += (difficulty != undefined) ? "cs>=" + difficulty : "cs>=7";
baseFormula += `[regular_${game.user.name}]`
// Construction de la formule finale
if (modFormula != null) {
formula = baseFormula + "+" + modFormula;
} else { formula = baseFormula }
// Création du jet de dés
let roll = new Roll(formula, actor.getRollData());
roll.toMessage({
speaker: ChatMessage.getSpeaker({ actor: actor }),
flavor: label,
rollMode: game.settings.get('core', 'rollMode'),
});
await roll.evaluate();
await VermineUtils.showDiceSoNice(roll);
VermineUtils.diplayChatRoll(roll, ...arguments);
return roll;
}
/* -------------------------------------------- */
/**
* Méthode pour gérer les événements de relance de dés
* @param {Object} message - Le message contenant l'événement de relance
* @param {Object} ev - L'événement de relance
*/
static async _onRerollSelect(message, ev) {
// Vérification de l'utilisateur
if (game.user._id != message.user._id) {
ui.notifications.warn('vous ne pouvez pas relancer un dés sur ce jet')
return false
}
// Récupération du nombre de relances autorisé
let rerollCount = ev.currentTarget.closest('div.vermine-roll-message').querySelector('#allowed_reroll')?.innerText;
// Vérification du nombre de relances restantes
if (!rerollCount || parseInt(rerollCount) < 1) {
console.log('no reroll')
ui.notifications.warn("plus de relance possible");
let rerollables = ev.currentTarget.closest('ul').querySelectorAll('.rerollable');
rerollables.forEach(el => el.classList.remove('rerollable'));
// Mise à jour du nombre de relances restantes
ev.currentTarget.closest('div.vermine-roll-message').querySelector('#allowed_reroll').innerText = rerollCount - 1;
let content = ev.currentTarget.closest('div.message-content').outerHTML;
await message.update({
content: content
})
return false
}
ev.currentTarget.classList.add('rerolled');
// Mise en place de la relance
await message.setFlag("world", "reroll", true);
// Récupération de la difficulté et du type de dé
let difficulty = ev.currentTarget.closest('ul').dataset.difficulty;
let diceType = ev.currentTarget.dataset.diceType;
// Mise à jour du nombre de relances restantes
ev.currentTarget.closest('div.vermine-roll-message').querySelector('#allowed_reroll').innerText = rerollCount - 1;
// Construction de la formule de relance
let formula = `1d10cs>=${difficulty}`;
console.log(diceType)
switch (diceType.trim()) {
case 'human':
formula = `(1d10cs>=${difficulty}[human_${game.user.name}])*2`
break;
case 'adapted':
formula = `(1d10cs>=${difficulty}[adapted_${game.user.name}])*2`
break;
default:
formula += `[regular_${game.user.name}]`
break;
};
// Création et évaluation du jet de dés de relance
let reroll = await new Roll(formula);
await reroll.evaluate();
await VermineUtils.showDiceSoNice(reroll);
// mise à jour de l'affichage du dés
console.log(reroll)
let result = reroll.dice[0].results[0].result;
ev.currentTarget.querySelector('span').innerText = result;
//mise à jour du total
let success = reroll.dice[0].results[0].success;
if (success) {
ev.currentTarget.classList.add('success')
let total = parseInt(ev.currentTarget.closest('.vermine-roll-message').querySelector('#total').innerText) + reroll.total
ev.currentTarget.closest('.vermine-roll-message').querySelector('#total').innerText = total
}
// Mise à jour de l'affichagedu message
ev.currentTarget.classList.remove("rerollable")
let content = ev.currentTarget.closest('div.message-content').outerHTML;
console.log(reroll, message);
await message.update({
content: content
})
}
/**
* Méthode pour gérer les événements de chat
* @param {HTMLElement} html - L'élément HTML contenant les événements de chat
*/
static async chatListenners(html) {
let reroll = html.find('#allowed_reroll')[0]?.innerText;
if (!reroll || parseInt(reroll) < 1) {
for (let die of html.find('.die')) {
die.classList.remove("rerollable")
};
} else {
for (let die of html.find('.die')) {
die.classList.add("rerollable")
};
}
html.find('.rerollable').click(async (ev) => {
ev.preventDefault();
let msgId = ev.currentTarget.closest("li.message").dataset.messageId;
let message = await game.messages.get(msgId);
await VermineUtils._onRerollSelect(message, ev);
});
html.find("#effort-reroll").change(ev => {
let label = html.find("#granted-reroll")[0]
label.innerText = ev.currentTarget.value
});
html.find("button.grant-reroll").click(async (ev) => {
html.find("#allowed_reroll")[0].innerText = html.find('#granted-reroll')[0].innerText
let mesEl = ev.currentTarget.closest('[data-message-id]')
let messageId = mesEl.dataset.messageId;
ev.currentTarget.closest('.reroll-from-effort').style.display="none"
let content = ev.currentTarget.closest(".vermine-roll-message").outerHTML;
let message = await game.messages.get(messageId);
await message.update({ content: content });
});
}
/**
* Méthode pour afficher les résultats des dés de manière graphique
* @param {Roll} roll - Le jet de dés à afficher
* @param {string} rollMode - Le mode d'affichage du jet de dés
*/
static async showDiceSoNice(roll, rollMode) {
if (game.modules.get("dice-so-nice")?.active) {
if (game.dice3d) {
@@ -39,22 +199,36 @@ export class VermineUtils {
}
}
/* -------------------------------------------- */
static async chatListeners(html) {
html.on("click", '.roll-dice-bonus', event => {
let rollData = this.getRollDataFromMessage(event)
let msgId = VermineRoll.findChatMessageId(event.currentTarget)
nocUtility.removeChatMessageId(msgId)
let nbDice = $(event.target).data('nb-dice')
console.log(">>>>>", nbDice)
this.rollBonus(rollData, nbDice)
})
/**
* Méthode pour récupérer un jet de dés à partir d'un message
* @param {string} messageId - L'identifiant du message contenant le jet de dés
*/
static async getRollFromMessage(messageId) {
let message = await game.messages.get(messageId);
}
/**
* Méthode pour afficher un jet de dés dans le chat
* @param {Roll} roll - Le jet de dés à afficher
* @param {Object} param - Les paramètres du jet de dés
* @returns {ChatMessage} - Le message affichant le jet de dés
*/
static async diplayChatRoll(roll, param) {
let content = await renderTemplate("systems/vermine2047/templates/roll-message.hbs", { roll, param })
let chatData = {
user: game.user._id,
speaker: ChatMessage.getSpeaker(),
content: content,
roll: roll
};
let msg = await ChatMessage.create(chatData);
await msg.setFlag('world', 'roll', roll);
return msg
}
}
+4 -1
View File
@@ -18,6 +18,7 @@ import { VermineCombat, VermineCombatTracker } from "./system/fight.mjs";
// Import helper/utility classes and constants.
import { preloadHandlebarsTemplates, registerHandlebarsHelpers } from "./system/handlebars-manager.mjs";
import { VERMINE } from "./system/config.mjs";
import { initUserDice } from "./system/dice3d.mjs";
/* -------------------------------------------- */
/* Init Hook */
@@ -37,7 +38,6 @@ Hooks.once('init', async function () {
// Add custom constants for configuration.
CONFIG.VERMINE = VERMINE;
CONFIG.VERMINE.model = game.system.model
console.log('__________________', CONFIG.VERMINE)
/**
* Set an initiative formula for the system
* @type {String}
@@ -97,6 +97,9 @@ Hooks.once('init', async function () {
el.classList.add('game-mode');
el.id = 'game-mode-' + mode;
document.querySelector('#ui-left').prepend(el);
// Preload Handlebars templates.
return preloadHandlebarsTemplates();