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
+2 -1
View File
@@ -1 +1,2 @@
packs/** binary packs/** binary
node_modules/
+8 -4
View File
@@ -4,7 +4,11 @@
##TODO ##TODO
- [ ] envoyer les spécialités utilisables au rollDialog - [ ] envoyer les spécialités utilisables au rollDialog
- [ ] refacto des template chat de roll - [X] refacto des template chat de roll
- [ ] gérer les dés de totems humains et adapté : couleur différente/double succès - [X] gérer les dés de totems humains et adapté : couleur différente/double succès +update actor
- [ ] gérer les rerolls depuis chat(cf noc) - [X] gérer les rerolls depuis chat(cf noc)
- [ ] repasser sur les différents itemTypes et sheets - [X] gérer les rerolls après le jet en fonction du score d'effort et de la carac
- [ ] repasser sur les différents itemTypes et sheets
- [ ] update des reserves de sang-froids lors de jets
- [ ] gérer les rolls d'items
- [ ] ajout des domaines de prédilections
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1 -1
View File
File diff suppressed because one or more lines are too long
+5 -6
View File
@@ -91,17 +91,16 @@ export class VermineActorSheet extends ActorSheet {
} }
//click on wound radio //click on wound radio
html.find('[type="radio"][data-wound]').click(ev => { html.find('.hexa [type="radio"]').click(ev => {
this._onWoundClick(ev) this._onClickRadioHexa(ev)
}) })
} }
_onWoundClick(ev) { _onClickRadioHexa(ev) {
if (!ev.currentTarget.checked) { return } if (!ev.currentTarget.checked) { return }
let woundType = ev.currentTarget.dataset.wound; let prop = ev.currentTarget.name;
let targetProp = "system." + woundType + ".value";
let update = {}; let update = {};
update[targetProp] = ev.currentTarget.value - 1 update[prop] = ev.currentTarget.value - 1
this.actor.update(update) this.actor.update(update)
+26 -16
View File
@@ -1,6 +1,6 @@
import { onManageActiveEffect, prepareActiveEffectCategories } from "../system/effects.mjs"; import { onManageActiveEffect, prepareActiveEffectCategories } from "../system/effects.mjs";
import { VermineActorSheet } from "./actor-sheet.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"; import { TotemPicker } from "../system/applications.mjs";
/** /**
@@ -103,16 +103,35 @@ export class VermineCharacterSheet extends VermineActorSheet {
// Choose Totem // Choose Totem
html.find('.chooseTotem').click(this._onTotemButton.bind(this)); html.find('.chooseTotem').click(this._onTotemButton.bind(this));
html.find('.ability .rollable').click(this._onRoll.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. * Handle clickable rolls.
* @param {Event} event The originating click event * @param {Event} event The originating click event
* @private * @private
*/ */
_onRoll(event) { async _onRoll(event) {
event.preventDefault(); event.preventDefault();
const element = event.currentTarget; const element = event.currentTarget;
const dataset = element.dataset; const dataset = element.dataset;
@@ -129,26 +148,17 @@ export class VermineCharacterSheet extends VermineActorSheet {
// Handle rolls that supply the formula directly. // Handle rolls that supply the formula directly.
if (dataset.label) { if (dataset.label) {
dataset.rollType = dataset.type; 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 = { let data = {
actorId: this.actor.id, actorId: this.actor.id,
abilities: this.actor.system.abilities,
skills: this.actor.system.skills,
rollType: dataset.rollType, rollType: dataset.rollType,
labelKey: dataset.label, labelKey: dataset.label,
abilityScore: 0,
skillScore: 0,
label: game.i18n.localize(dataset.label) label: game.i18n.localize(dataset.label)
}; };
if (dataset.type == 'ability') {
data.abilityScore = this.actor.system.abilities[dataset.label].value; let dial = await RollDialog.create(data);
} else if (dataset.type == 'skill') { dial.render(true)
data.skillScore = this.actor.system.skills[dataset.label].value;
}
getRollBox(data);
return true; return true;
} }
} }
+128 -119
View File
@@ -35,24 +35,40 @@ export class CombatResultDialog extends Dialog {
} }
export class RollDialog extends Dialog { export class RollDialog extends Dialog {
static async create(rollData) {
let options = { classes: ["vermine-roll"], width: 420, height: 'fit-content', 'z-index': 99999 }; static async create(data = {
let html = await renderTemplate('systems/vermine2047/templates/roll.hbs', rollData); 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) { constructor(data, html, options, close = undefined) {
let conf = { let conf = {
title: "", title: "jet de dés",
content: html, content: html,
buttons: { buttons: {
roll: { roll: {
icon: '<i class="fas fa-check"></i>', icon: '<i class="fas fa-check"></i>',
label: "Lancer !", label: "Lancer !",
callback: () => { this.roll(data.actorId, data.label, data.NoD, data.Reroll) } callback: () => {
this.roll()
}
}, },
cancel: { cancel: {
icon: '<i class="fas fa-times"></i>', icon: '<i class="fas fa-times"></i>',
@@ -60,124 +76,117 @@ export class RollDialog extends Dialog {
callback: () => { this.close() } 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() { 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", "systems/vermine2047/templates/actor/creature/creature-combat.hbs",
// additional templates // 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) { Handlebars.registerHelper('skillLevel', function (property, level, options) {
if (level < 1 || level > 5) if (level < 1 || level > 5)
return ""; return "";
level = parseInt(level);
let levelData = CONFIG.VERMINE.SkillLevels[level]; let levelData = CONFIG.VERMINE.SkillLevels[level];
if (property == 'label') { if (property == 'label') {
return (levelData !== undefined) ? game.i18n.localize(levelData[property]) : ""; return (levelData !== undefined) ? game.i18n.localize(levelData[property]) : "";
@@ -247,6 +248,9 @@ export const registerHandlebarsHelpers = function () {
if (a <= b) { return options.fn(this); } if (a <= b) { return options.fn(this); }
return options.inverse(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) { Handlebars.registerHelper('repeat', function (times, start, block) {
var accum = ''; 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"; import { registerTours } from "./tour.mjs";
export const registerHooks = function () { export const registerHooks = function () {
/** /**
* Ready hook loads tables, and override's foundry's entity link functions to provide extension to pseudo entities * 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 () => { Hooks.once("ready", async () => {
console.info("Vermine 2047 | System Initialized."); console.info("Vermine 2047 | System Initialized.");
await registerTours(); await registerTours();
}); });
// changement de la pause // changement de la pause
Hooks.on("renderPause", async function () { Hooks.on("renderPause", async function () {
if ($("#pause").attr("class") !== "paused") return; if ($("#pause").attr("class") !== "paused") return;
$(".paused img").attr("src", 'systems/vermine2047/assets/images/ui/vermine_pause.webp'); $(".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..."); $("#pause.paused figcaption").text("Communauté endormie...");
}); });
@@ -34,16 +76,17 @@ export const registerHooks = function () {
return false; return false;
}); });
Hooks.on('getSceneControlButtons', (controls) => { Hooks.on('getSceneControlButtons', async (controls) => {
/*controls.find((c) => c.name === 'token').tools.push({ console.log;
name: 'Dice Roller', controls.find((c) => c.name === 'token').tools.push({
title: game.i18n.localize("VERMINE.RollTool"), name: 'Dice Roller',
icon: 'fas fa-dice-d6', title: game.i18n.localize("VERMINE.RollTool"),
button: true, icon: 'fas fa-dice-d10',
onClick() { button: true,
VermineRoll.ui(); onClick() {
} RollDialog.create().then(d => d.render(true));
});*/ }
});
}); });
/* -------------------------------------------- */ /* -------------------------------------------- */
@@ -53,17 +96,17 @@ export const registerHooks = function () {
Hooks.on("preCreateActor", function (actor) { Hooks.on("preCreateActor", function (actor) {
console.log('pre create actor', actor.img); console.log('pre create actor', actor.img);
if (actor.img == "icons/svg/mystery-man.svg") { 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) { Hooks.on("preCreateItem", function (item) {
if (item.img == "icons/svg/item-bag.svg") { if (item.img == "icons/svg/item-bag.svg") {
item.updateSource({"img": `systems/vermine2047/assets/icons/items/${item.type}.webp`}); item.updateSource({ "img": `systems/vermine2047/assets/icons/items/${item.type}.webp` });
// item.updateSource({"img": `systems/vermine2047/icons/competence.webp`}); // item.updateSource({"img": `systems/vermine2047/icons/competence.webp`});
} }
}); });
/* -------------------------------------------- */ /* -------------------------------------------- */
/* Combat Hooks */ /* Combat Hooks */
/* -------------------------------------------- */ /* -------------------------------------------- */
@@ -79,29 +122,29 @@ export const registerHooks = function () {
Hooks.on("updateCombat", function () { Hooks.on("updateCombat", function () {
if (game.user.isGM) { if (game.user.isGM) {
let combatant = (game.combat.combatant) ? game.combat.combatant.actor : ""; let combatant = (game.combat.combatant) ? game.combat.combatant.actor : "";
console.log('update combat', game.combat); console.log('update combat', game.combat);
/*if (combatant.type == "marker" && combatant.system.settings.general.isCounter == true) { /*if (combatant.type == "marker" && combatant.system.settings.general.isCounter == true) {
let step = (!combatant.system.settings.general.counting) ? -1 : combatant.system.settings.general.counting; let step = (!combatant.system.settings.general.counting) ? -1 : combatant.system.settings.general.counting;
let newQuantity = combatant.system.pools.quantity.value + step; let newQuantity = combatant.system.pools.quantity.value + step;
combatant.update({"system.pools.quantity.value": newQuantity}); combatant.update({"system.pools.quantity.value": newQuantity});
}*/ }*/
} }
}); });
/* Hooks.on("chatCommandsReady", function (chatCommands) { /* Hooks.on("chatCommandsReady", function (chatCommands) {
chatCommands.registerCommand(chatCommands.createCommandFromData({ chatCommands.registerCommand(chatCommands.createCommandFromData({
commandKey: "/dr", commandKey: "/dr",
invokeOnCommand: (chatlog, messageText, chatdata) => { invokeOnCommand: (chatlog, messageText, chatdata) => {
Roll.get().parse(messageText); Roll.get().parse(messageText);
}, },
shouldDisplayToChat: false, shouldDisplayToChat: false,
iconClass: "fa-dice-d6", iconClass: "fa-dice-d6",
description: "Roll Vermine 2047 check" description: "Roll Vermine 2047 check"
})); }));
});*/ });*/
} }
+197 -23
View File
@@ -1,20 +1,180 @@
export class VermineUtils { 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 = {}) { // Vérification des totems humains
const actor = game.actors.get(actorId); if (totems.human) {
let formula = '' + NoD + "d10"; 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()); let roll = new Roll(formula, actor.getRollData());
roll.toMessage({ await roll.evaluate();
speaker: ChatMessage.getSpeaker({ actor: actor }), await VermineUtils.showDiceSoNice(roll);
flavor: label, VermineUtils.diplayChatRoll(roll, ...arguments);
rollMode: game.settings.get('core', 'rollMode'),
});
return roll; 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) { static async showDiceSoNice(roll, rollMode) {
if (game.modules.get("dice-so-nice")?.active) { if (game.modules.get("dice-so-nice")?.active) {
if (game.dice3d) { if (game.dice3d) {
@@ -39,22 +199,36 @@ export class VermineUtils {
} }
} }
/* -------------------------------------------- */ /**
static async chatListeners(html) { * 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
html.on("click", '.roll-dice-bonus', event => { */
let rollData = this.getRollDataFromMessage(event) static async getRollFromMessage(messageId) {
let message = await game.messages.get(messageId);
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 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 helper/utility classes and constants.
import { preloadHandlebarsTemplates, registerHandlebarsHelpers } from "./system/handlebars-manager.mjs"; import { preloadHandlebarsTemplates, registerHandlebarsHelpers } from "./system/handlebars-manager.mjs";
import { VERMINE } from "./system/config.mjs"; import { VERMINE } from "./system/config.mjs";
import { initUserDice } from "./system/dice3d.mjs";
/* -------------------------------------------- */ /* -------------------------------------------- */
/* Init Hook */ /* Init Hook */
@@ -37,7 +38,6 @@ Hooks.once('init', async function () {
// Add custom constants for configuration. // Add custom constants for configuration.
CONFIG.VERMINE = VERMINE; CONFIG.VERMINE = VERMINE;
CONFIG.VERMINE.model = game.system.model CONFIG.VERMINE.model = game.system.model
console.log('__________________', CONFIG.VERMINE)
/** /**
* Set an initiative formula for the system * Set an initiative formula for the system
* @type {String} * @type {String}
@@ -97,6 +97,9 @@ Hooks.once('init', async function () {
el.classList.add('game-mode'); el.classList.add('game-mode');
el.id = 'game-mode-' + mode; el.id = 'game-mode-' + mode;
document.querySelector('#ui-left').prepend(el); document.querySelector('#ui-left').prepend(el);
// Preload Handlebars templates. // Preload Handlebars templates.
return preloadHandlebarsTemplates(); return preloadHandlebarsTemplates();
+1 -1
View File
@@ -5,7 +5,7 @@
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"test": "echo \"Error: no test specified\" && exit 1", "test": "echo \"Error: no test specified\" && exit 1",
"launch Foundry11": "cd C:/Program Files/Foundry Virtual Tabletop_V11/resources/app && node main.js", "launch window Foundry11": "cd C:/Program Files/Foundry Virtual Tabletop_V11/resources/app && node main.js",
"watch": "gulp watch", "watch": "gulp watch",
"buildStyle": "gulp buildStyles" "buildStyle": "gulp buildStyles"
}, },
+1 -1
View File
@@ -1 +1 @@
MANIFEST-000149 MANIFEST-000177
+3 -3
View File
@@ -1,3 +1,3 @@
2024/04/21-11:00:14.926 40b8 Recovering log #147 2024/04/28-09:24:23.659 2504 Recovering log #176
2024/04/21-11:00:14.930 40b8 Delete type=0 #147 2024/04/28-09:24:23.664 2504 Delete type=0 #176
2024/04/21-11:00:14.930 40b8 Delete type=3 #145 2024/04/28-09:24:23.664 2504 Delete type=3 #175
+3 -7
View File
@@ -1,7 +1,3 @@
2024/04/21-08:39:21.586 3594 Recovering log #144 2024/04/26-22:48:34.076 b5c Recovering log #174
2024/04/21-08:39:21.591 3594 Delete type=0 #144 2024/04/26-22:48:34.079 b5c Delete type=0 #174
2024/04/21-08:39:21.591 3594 Delete type=3 #143 2024/04/26-22:48:34.081 b5c Delete type=3 #173
2024/04/21-10:20:47.336 5c50 Level-0 table #148: started
2024/04/21-10:20:47.336 5c50 Level-0 table #148: 0 bytes OK
2024/04/21-10:20:47.337 5c50 Delete type=0 #146
2024/04/21-10:20:47.355 5c50 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end)
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
MANIFEST-000149 MANIFEST-000177
+3 -3
View File
@@ -1,3 +1,3 @@
2024/04/21-11:00:14.993 40b8 Recovering log #147 2024/04/28-09:24:23.727 2504 Recovering log #176
2024/04/21-11:00:14.999 40b8 Delete type=0 #147 2024/04/28-09:24:23.733 2504 Delete type=0 #176
2024/04/21-11:00:14.999 40b8 Delete type=3 #145 2024/04/28-09:24:23.733 2504 Delete type=3 #175
+3 -7
View File
@@ -1,7 +1,3 @@
2024/04/21-08:39:21.654 3594 Recovering log #144 2024/04/26-22:48:34.179 b5c Recovering log #174
2024/04/21-08:39:21.658 3594 Delete type=0 #144 2024/04/26-22:48:34.188 b5c Delete type=0 #174
2024/04/21-08:39:21.658 3594 Delete type=3 #143 2024/04/26-22:48:34.188 b5c Delete type=3 #173
2024/04/21-10:20:47.365 5c50 Level-0 table #148: started
2024/04/21-10:20:47.365 5c50 Level-0 table #148: 0 bytes OK
2024/04/21-10:20:47.367 5c50 Delete type=0 #146
2024/04/21-10:20:47.367 5c50 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end)
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
MANIFEST-000133 MANIFEST-000161
+3 -3
View File
@@ -1,3 +1,3 @@
2024/04/21-11:00:14.944 40b8 Recovering log #131 2024/04/28-09:24:23.680 2504 Recovering log #160
2024/04/21-11:00:14.950 40b8 Delete type=0 #131 2024/04/28-09:24:23.685 2504 Delete type=0 #160
2024/04/21-11:00:14.950 40b8 Delete type=3 #129 2024/04/28-09:24:23.685 2504 Delete type=3 #159
+3 -7
View File
@@ -1,7 +1,3 @@
2024/04/21-08:39:21.607 3594 Recovering log #128 2024/04/26-22:48:34.099 b5c Recovering log #158
2024/04/21-08:39:21.613 3594 Delete type=0 #128 2024/04/26-22:48:34.107 b5c Delete type=0 #158
2024/04/21-08:39:21.613 3594 Delete type=3 #127 2024/04/26-22:48:34.107 b5c Delete type=3 #157
2024/04/21-10:20:47.362 5c50 Level-0 table #132: started
2024/04/21-10:20:47.362 5c50 Level-0 table #132: 0 bytes OK
2024/04/21-10:20:47.363 5c50 Delete type=0 #130
2024/04/21-10:20:47.364 5c50 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end)
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
MANIFEST-000147 MANIFEST-000175
+3 -3
View File
@@ -1,3 +1,3 @@
2024/04/21-11:00:14.982 56d0 Recovering log #145 2024/04/28-09:24:23.715 d84 Recovering log #174
2024/04/21-11:00:14.987 56d0 Delete type=0 #145 2024/04/28-09:24:23.721 d84 Delete type=0 #174
2024/04/21-11:00:14.987 56d0 Delete type=3 #143 2024/04/28-09:24:23.721 d84 Delete type=3 #173
+3 -7
View File
@@ -1,7 +1,3 @@
2024/04/21-08:39:21.641 5300 Recovering log #142 2024/04/26-22:48:34.159 1544 Recovering log #172
2024/04/21-08:39:21.646 5300 Delete type=0 #142 2024/04/26-22:48:34.165 1544 Delete type=0 #172
2024/04/21-08:39:21.647 5300 Delete type=3 #141 2024/04/26-22:48:34.166 1544 Delete type=3 #171
2024/04/21-10:20:47.358 5c50 Level-0 table #146: started
2024/04/21-10:20:47.358 5c50 Level-0 table #146: 0 bytes OK
2024/04/21-10:20:47.360 5c50 Delete type=0 #144
2024/04/21-10:20:47.364 5c50 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end)
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
MANIFEST-000043 MANIFEST-000071
+3 -3
View File
@@ -1,3 +1,3 @@
2024/04/21-11:00:14.957 56d0 Recovering log #41 2024/04/28-09:24:23.691 d84 Recovering log #70
2024/04/21-11:00:14.962 56d0 Delete type=0 #41 2024/04/28-09:24:23.695 d84 Delete type=0 #70
2024/04/21-11:00:14.962 56d0 Delete type=3 #39 2024/04/28-09:24:23.695 d84 Delete type=3 #69
+3 -8
View File
@@ -1,8 +1,3 @@
2024/04/21-08:39:21.618 5300 Recovering log #38 2024/04/26-22:48:34.121 1544 Recovering log #68
2024/04/21-08:39:21.623 5300 Delete type=0 #38 2024/04/26-22:48:34.127 1544 Delete type=0 #68
2024/04/21-08:39:21.623 5300 Delete type=3 #37 2024/04/26-22:48:34.127 1544 Delete type=3 #67
2024/04/21-10:20:47.360 5c50 Level-0 table #42: started
2024/04/21-10:20:47.360 5c50 Level-0 table #42: 0 bytes OK
2024/04/21-10:20:47.362 5c50 Delete type=0 #40
2024/04/21-10:20:47.364 5c50 Manual compaction at level-0 from '!items!10vhNURxl8FOwfy0' @ 72057594037927935 : 1 .. '!items!vX832Z4LpasxLIIx' @ 0 : 0; will stop at (end)
2024/04/21-10:20:47.364 5c50 Manual compaction at level-1 from '!items!10vhNURxl8FOwfy0' @ 72057594037927935 : 1 .. '!items!vX832Z4LpasxLIIx' @ 0 : 0; will stop at (end)
+1 -1
View File
@@ -1 +1 @@
MANIFEST-000040 MANIFEST-000068
+3 -3
View File
@@ -1,3 +1,3 @@
2024/04/21-11:00:14.969 40b8 Recovering log #38 2024/04/28-09:24:23.703 2504 Recovering log #67
2024/04/21-11:00:14.975 40b8 Delete type=0 #38 2024/04/28-09:24:23.708 2504 Delete type=0 #67
2024/04/21-11:00:14.975 40b8 Delete type=3 #36 2024/04/28-09:24:23.708 2504 Delete type=3 #66
+3 -8
View File
@@ -1,8 +1,3 @@
2024/04/21-08:39:21.629 3594 Recovering log #35 2024/04/26-22:48:34.142 b5c Recovering log #65
2024/04/21-08:39:21.634 3594 Delete type=0 #35 2024/04/26-22:48:34.148 b5c Delete type=0 #65
2024/04/21-08:39:21.634 3594 Delete type=3 #34 2024/04/26-22:48:34.148 b5c Delete type=3 #64
2024/04/21-10:20:47.356 5c50 Level-0 table #39: started
2024/04/21-10:20:47.356 5c50 Level-0 table #39: 0 bytes OK
2024/04/21-10:20:47.358 5c50 Delete type=0 #37
2024/04/21-10:20:47.364 5c50 Manual compaction at level-0 from '!tables!UxgGMRs0kTplpTbe' @ 72057594037927935 : 1 .. '!tables.results!dXo0EN9ieo1tSnRY.ymnitiW2yAuk75M3' @ 0 : 0; will stop at (end)
2024/04/21-10:20:47.364 5c50 Manual compaction at level-1 from '!tables!UxgGMRs0kTplpTbe' @ 72057594037927935 : 1 .. '!tables.results!dXo0EN9ieo1tSnRY.ymnitiW2yAuk75M3' @ 0 : 0; will stop at (end)
+1 -1
View File
@@ -1 +1 @@
MANIFEST-000147 MANIFEST-000175
+3 -3
View File
@@ -1,3 +1,3 @@
2024/04/21-11:00:14.935 56d0 Recovering log #145 2024/04/28-09:24:23.670 d84 Recovering log #174
2024/04/21-11:00:14.939 56d0 Delete type=0 #145 2024/04/28-09:24:23.674 d84 Delete type=0 #174
2024/04/21-11:00:14.939 56d0 Delete type=3 #143 2024/04/28-09:24:23.675 d84 Delete type=3 #173
+3 -7
View File
@@ -1,7 +1,3 @@
2024/04/21-08:39:21.598 5300 Recovering log #142 2024/04/26-22:48:34.087 1544 Recovering log #172
2024/04/21-08:39:21.602 5300 Delete type=0 #142 2024/04/26-22:48:34.091 1544 Delete type=0 #172
2024/04/21-08:39:21.602 5300 Delete type=3 #141 2024/04/26-22:48:34.092 1544 Delete type=3 #171
2024/04/21-10:20:47.353 5c50 Level-0 table #146: started
2024/04/21-10:20:47.353 5c50 Level-0 table #146: 0 bytes OK
2024/04/21-10:20:47.354 5c50 Delete type=0 #144
2024/04/21-10:20:47.355 5c50 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end)
Binary file not shown.
Binary file not shown.
+141 -17
View File
@@ -105,10 +105,7 @@ ul.unstyled li {
.actor.sheet form .form { .actor.sheet form .form {
display: grid; display: grid;
/*grid:
"sidebar header" 75px
"sidebar nav" minmax(min-content, max-content)
"sidebar content" 1fr/230px 1fr;*/
grid-template-columns: minmax(230px, 1fr) 3fr; grid-template-columns: minmax(230px, 1fr) 3fr;
grid-template-rows: 1fr; grid-template-rows: 1fr;
align-items: flex-start; align-items: flex-start;
@@ -120,10 +117,28 @@ ul.unstyled li {
grid-row: span 1 / span 1; grid-row: span 1 / span 1;
background-image: url(/systems/vermine2047/assets/images/ui/barre_laterale.webp); background-image: url(/systems/vermine2047/assets/images/ui/barre_laterale.webp);
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: 12% 50%; background-size: cover;
background-size: 400%;
height: 100%; height: 100%;
box-shadow: -20px 0px 100px #000000b5 inset width: 240px;
padding: 0 0.3rem;
box-shadow: -20px 0px 100px #000000b5 inset;
.major-totem {
position: relative;
h4 {
position: absolute;
transform: rotate(-8deg);
opacity: 0.7;
transition: 0.2s;
}
&:hover h4 {
opacity: 1;
}
}
} }
.actor.sheet .form main { .actor.sheet .form main {
@@ -134,7 +149,6 @@ ul.unstyled li {
} }
.actor.sheet .form aside .image-wrapper { .actor.sheet .form aside .image-wrapper {
margin: 1rem auto 3rem;
text-align: center; text-align: center;
} }
@@ -211,6 +225,111 @@ ul.unstyled li {
overflow: hidden; overflow: hidden;
} }
.system-vermine2047 .sheet.actor form div.hexa {
clip-path: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%);
background: radial-gradient(circle, rgba(255, 255, 255, 0.425) 0%, rgba(0, 0, 0, 0.288) 100%);
height: unset;
max-width: 1.5rem;
aspect-ratio: 1/1;
color: black;
transform: rotate(90deg);
transition: 0.2s;
margin: 0.2rem;
&:hover {
background: radial-gradient(circle, rgba(255, 255, 255, 0.425) 0%, rgba(0, 0, 0, 0.288) 100%);
}
input {
opacity: 1;
min-width: 100%;
min-height: 100%;
opacity: 0
}
&.checked {
&:hover {
background: radial-gradient(circle, rgb(43, 43, 43) 0%, rgba(0, 0, 0, 0.288) 100%);
}
background: radial-gradient(circle, rgb(0, 0, 0) 0%, rgba(0, 0, 0, 0.288) 100%);
}
&.unavailable {
background: radial-gradient(circle, rgba(66, 15, 15, 0.664) 0%, rgba(131, 70, 70, 0.432) 100%);
}
}
.system-vermine2047 .sheet.actor div.minor-totems {
position: relative;
background-color: #929c6f85;
h5 {
position: absolute;
top: 0;
img {
max-width: 2rem;
position: absolute;
bottom: -2rem;
}
}
.totem-dice {
.human-dice,
.adapted-dice {
display: flex;
flex-direction: row;
margin-left: 2rem;
i {
padding-top: 0.5rem;
color: #064930;
}
}
.adapted-dice {
justify-content: flex-end;
margin-left: 0;
margin-right: 2rem;
transform: rotate(180deg);
i {
transform: rotate(180deg);
padding-top: 0.5rem;
color: rgb(85, 52, 2);
}
}
}
.human {
left: 0;
img {
left: 0;
}
}
.adapted {
right: 0;
img {
right: 0
}
}
}
.system-vermine2047 .sheet.actor form input[type=text], .system-vermine2047 .sheet.actor form input[type=text],
.system-vermine2047 .sheet.actor form input[type=number] { .system-vermine2047 .sheet.actor form input[type=number] {
width: calc(100% - 2px); width: calc(100% - 2px);
@@ -462,17 +581,22 @@ ul.unstyled li {
margin: 0 1rem; margin: 0 1rem;
flex: 0.5; flex: 0.5;
}
&.hexa { .hexa {
text-align: center; text-align: center;
clip-path: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%); clip-path: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%);
background: radial-gradient(circle, rgba(255, 255, 255, 0.425) 0%, rgba(0, 0, 0, 0.288) 100%); background: radial-gradient(circle, rgba(255, 255, 255, 0.425) 0%, rgba(0, 0, 0, 0.288) 100%);
max-height: 1.2rem; max-height: 1.2rem;
max-width: 1.2rem; max-width: 1.2rem;
aspect-ratio: 1/1; aspect-ratio: 1/1;
color: black; color: black;
vertical-align: bottom; vertical-align: center;
&.checked {
background: radial-gradient(circle, rgb(0, 0, 0) 0%, rgba(0, 0, 0, 0.288) 100%);
} }
} }
div.specialties { div.specialties {
+178
View File
@@ -0,0 +1,178 @@
ol#chat-log {
header.message-header {
background-color: black;
padding: 0 1rem;
}
.vermine-roll-message {
overflow: hidden;
box-shadow: 0px 0px 30px white inset;
padding: 0;
position: relative;
.flexrow {
align-items: center;
box-shadow: 0px 5px 10px 0px black;
}
h3,
h4 {
text-transform: uppercase;
font-family: "DistressBlack";
margin-top: 1rem;
border-bottom: none;
font-weight: 900;
font-weight: 900;
background: 50% 0%/cover no-repeat url(/systems/vermine2047/assets/images/ui/scotch.webp);
&+span {
font-family: "DistressBlack";
font-size: large;
text-transform: unset;
padding-left: 2rem;
background: -100% 0%/cover no-repeat url(/systems/vermine2047/assets/images/ui/scotch.webp);
&#allowed_reroll {
font-size: large;
}
}
}
h3 {
background: url(/systems/vermine2047/assets/images/ui/scotch.webp);
background-position: center;
background-size: 200%;
}
h4 {
text-align: end;
}
div.roll-total {
transform: rotate(-3deg) scale(1.3) translateX(2rem) translateY(0.5rem);
background: url(/systems/vermine2047/assets/images/ui/scotch.webp);
background-position: center;
background-size: 200%;
margin-bottom: 2rem;
padding: 0;
z-index: +1;
}
div.reroll {
button {
text-transform: uppercase;
font-family: "DistressBlack";
margin-top: 1rem;
box-shadow: 0px 0px 3px black;
background: 50% 0%/cover no-repeat url(/systems/vermine2047/assets/images/ui/scotch.webp);
}
padding: 0 2rem;
padding-bottom: 2rem;
justify-content: end;
text-align: center;
}
ul.roll-results {
list-style: none;
li.die {
position: relative;
max-width: 3rem;
line-height: 3rem;
float: left;
margin: 0.2rem;
background-image: url(/icons/dice/d10black.svg);
background-position: center;
background-repeat: no-repeat;
background-size: contain;
font-weight: 800;
font-size: 1rem;
color: #ffffff;
text-align: center;
transition: 0.3s;
border-bottom: 5px solid rgb(255, 0, 0);
border-radius: 2rem;
&::after {
content: "";
position: absolute;
top: -1rem;
text-wrap: nowrap;
color: black;
font-weight: 100;
font-size: smaller;
text-align: center;
opacity: 0;
}
&:hover::after {
opacity: 1
}
&.human,
&.adapted {
border-top: 5px solid rgb(255, 217, 0);
}
&.rerollable {
cursor: pointer;
&:hover {
transform: translateY(0.5rem)
}
}
&.success {
border-bottom: 5px solid rgb(0, 143, 7);
}
&.adapted {
&::after {
content: "adapté"
}
}
&.human {
&::after {
content: "humain"
}
}
&.rerolled {
transform: translateY(-0rem);
}
span {
text-align: center;
font-size: larger;
text-shadow: 0px 0px 8px black;
}
}
}
}
}
+2 -1
View File
@@ -1,2 +1,3 @@
@import "./base_work.scss"; @import "./base_work.scss";
@import "./style.scss"; @import "./style.scss";
@import "./roll.scss"
+17
View File
@@ -32,6 +32,23 @@
"templates": [ "templates": [
"base" "base"
], ],
"adaptation": {
"value": 1,
"min": 0,
"max": 5,
"totems": {
"human": {
"value": 1,
"min": 0,
"max": 3
},
"adapted": {
"value": 1,
"min": 0,
"max": 3
}
}
},
"identity": { "identity": {
"height": 0, "height": 0,
"weight": 0, "weight": 0,
+113 -44
View File
@@ -1,23 +1,73 @@
<div class="grid grid-2col"> <div class="grid grid-2col">
<div> <div>
<h4 class="align-center">{{ localize "VERMINE.self_control"}}</h4> <h4 class="align-center">{{ localize "VERMINE.self_control"}} :
<p class="align-center"> {{@root.system.attributes.self_control.value}}/
<input type="number" name="system.attributes.self_control.value" {{@root.system.attributes.self_control.max}}
value="{{ system.attributes.self_control.value }}" data-dtype="Number" </h4>
min="{{ system.attributes.self_control.min }}"
max="{{ system.attributes.self_control.max }}" /> / {{ <div class="flexrow">
system.attributes.self_control.max }} {{#repeat 10 1}}
</p> <div class="hexa
{{#iflteq @index @root.system.attributes.self_control.value }}
checked
{{/iflteq}}
{{#ifgt @index @root.system.attributes.self_control.max }}
unavailable
{{/ifgt}}">
{{#iflteq @index @root.system.attributes.self_control.max }}
<input type="radio" data-dtype="Number"
name="system.attributes.self_control.value"
value="{{@index}}" {{#ife @root.system.attributes.self_control.value
@index
}}checked="checked"{{/ife}}
class="
{{#iflteq @index @root.system.attributes.self_control.max }}
checked
{{/iflteq}}
" />
{{/iflteq}}
</div>
{{/repeat}}
</div>
</div> </div>
<div> <div>
<h4 class="align-center">{{ localize "VERMINE.effort"}}</h4> <h4 class="align-center">{{ localize "VERMINE.effort"}} :
<p class="align-center"> {{@root.system.attributes.effort.value}}/
<input type="number" name="system.attributes.effort.value" {{@root.system.attributes.effort.max}}
value="{{ system.attributes.effort.value }}" data-dtype="Number" </h4>
min="{{ system.attributes.effort.min }}"
max="{{ system.attributes.effort.max }}" /> / {{ <div class="flexrow">
system.attributes.effort.max }} {{#repeat 10 1}}
</p> <div
class="hexa
{{#iflteq @index @root.system.attributes.effort.value }}
checked
{{/iflteq}}
{{#ifgt @index @root.system.attributes.effort.max }}
unavailable
{{/ifgt}}">
{{#iflteq @index @root.system.attributes.effort.max }}
<input type="radio" data-dtype="Number"
name="system.attributes.effort.value"
value="{{@index}}" {{#ife @root.system.attributes.effort.value
@index
}}checked="checked"{{/ife}}
class="
{{#iflteq @index @root.system.attributes.effort.value }}
checked
{{/iflteq}}
" />
{{/iflteq}}
</div>
{{#ife @index 1}}
<br />
{{/ife}}
{{/repeat}}
</div>
</div> </div>
</div> </div>
<h4 class="item-name effect-name flexrow">{{ localize <h4 class="item-name effect-name flexrow">{{ localize
@@ -26,46 +76,65 @@
<li class="row mdb">{{ localize 'VERMINE.wounds.light'}} <span <li class="row mdb">{{ localize 'VERMINE.wounds.light'}} <span
data-tooltip="seuil">({{ data-tooltip="seuil">({{
system.minorWound.threshold }})</span> system.minorWound.threshold }})</span>
{{#repeat system.minorWound.max 1}} <div class="flexrow">
<input type="radio" data-dtype="Number" name="system.minorWound.value" {{#repeat system.minorWound.max 1}}
value="{{@index}}" {{#ife @root.system.minorWound.value @index <div class="hexa ability{{#iflteq @index @root.system.minorWound.value }}
}}checked="checked"{{/ife}} data-wound="minorWound" checked
class=" {{/iflteq}}">
<input type="radio" data-dtype="Number" name="system.minorWound.value"
value="{{@index}}" {{#ife @root.system.minorWound.value @index
}}checked="checked"{{/ife}} data-wound="minorWound"
class="
{{#iflteq @index @root.system.minorWound.value }} {{#iflteq @index @root.system.minorWound.value }}
checked checked
{{/iflteq}} {{/iflteq}}
" /> " />
{{/repeat}}</li> </div>
<li class="row mdb">{{ localize 'VERMINE.wounds.heavy'}} ({{ {{/repeat}}
system.majorWound.threshold }}) </div>
{{#repeat system.majorWound.max 1}} </li>
<input type="radio" name="system.majorWound.value" value="{{@index}}" {{#ife <li class="row mdb">{{ localize 'VERMINE.wounds.heavy'}}
@root.system.majorWound.value @index }}checked="checked"{{/ife}} <span>({{
data-wound="majorWound" system.majorWound.threshold }})</span>
class=" <div class="flexrow">
{{#repeat system.majorWound.max 1}}
<div class="hexa ability{{#iflteq @index @root.system.majorWound.value }}
checked
{{/iflteq}}">
<input type="radio" data-dtype="Number" name="system.majorWound.value"
value="{{@index}}" {{#ife @root.system.majorWound.value @index
}}checked="checked"{{/ife}} data-wound="majorWound"
class="
{{#iflteq @index @root.system.majorWound.value }} {{#iflteq @index @root.system.majorWound.value }}
checked checked
{{/iflteq}} {{/iflteq}}
" /> " />
{{/repeat}} </div>
{{/repeat}}
</div>
</li> </li>
<li class="row mdb">{{ localize 'VERMINE.wounds.deadly'}} ({{ <li class="row mdb">{{ localize 'VERMINE.wounds.deadly'}}
system.deadlyWound.threshold }}) <span>({{system.deadlyWound.threshold }})</span>
{{#repeat system.deadlyWound.max 1}} <div class="flexrow">
{{#repeat system.deadlyWound.max 1}}
<div class="hexa ability{{#iflteq @index @root.system.deadlyWound.value }}
checked
{{/iflteq}}">
<input type="radio" data-dtype="Number" name="system.deadlyWound.value"
value="{{@index}}" {{#ife @root.system.deadlyWound.value @index
}}checked="checked"{{/ife}} data-wound="deadlyWound"
class="
{{#iflteq @index @root.system.deadlyWound.value }}
checked
{{/iflteq}}
<input type="radio" name="system.deadlyWound.value" value="{{@index}}" " />
{{#ife </div>
@root.system.deadlyWound.value @index }}checked="checked"{{/ife}} {{/repeat}}
data-wound="deadlyWound" </div>
class="
{{#iflteq @index @root.system.deadlyWound.value }}
checked
{{/iflteq}}
" />
{{/repeat}}
</li> </li>
</ul> </ul>
<h4 class="item-name effect-name flexrow">{{ localize "UI.effects.name"}}</h4> <h4 class="item-name effect-name flexrow">{{ localize "UI.effects.name"}}</h4>
+43 -3
View File
@@ -2,15 +2,55 @@
<img class="profile-img" src="{{actor.img}}" data-edit="img" <img class="profile-img" src="{{actor.img}}" data-edit="img"
title="{{actor.name}}" height="100" width="100" /> title="{{actor.name}}" height="100" width="100" />
</div> </div>
<div class="minor-totems ">
<h3>{{localize "ITEMS.evolution"}}</h3>
<h5 class="human
{{#ifgt system.adaptation.totems.human.value system.adaptation.totems.adapted.value}}
major
{{/ifgt}}
">{{localize "TOTEMS.human.name"}}
<img src="/systems/vermine2047/assets/images/ui/totems/human.webp" />
</h5>
<h5 class="adapted
{{#ifgt system.adaptation.totems.human.value system.adaptation.totems.adapted.value}}
major
{{/ifgt}}">{{localize "TOTEMS.adapted.name"}}
<img src="/systems/vermine2047/assets/images/ui/totems/adapted.webp" />
</h5>
<div class="totem-dice flexrow flex-group-center">
<div class="human-dice flexrow">
{{#repeat system.adaptation.totems.human.max 1}}
<div class="hexa" data-totem-name="human" data-totem-value="{{@index}}">
{{#ifgteq system.adaptation.totems.human.value @index}}
<div class="human-die"><i class="fas fa-dice-d10"></i></div>
{{/ifgteq}}
</div>
{{/repeat}}
</div>
<div class="adapted-dice flexrow">
{{#repeat system.adaptation.totems.adapted.max 1}}
<div class="hexa" data-totem-name="adapted" data-totem-value="{{@index}}">
{{#ifgteq system.adaptation.totems.adapted.value @index}}
<div class="adapted-die"><i class="fas fa-dice-d10"></i></div>
{{/ifgteq}}</div>
{{/repeat}}
</div>
</div>
</div>
<ul class="padding-with-frieze unstyled paper"> <ul class="padding-with-frieze unstyled paper">
{{#if system.identity.totem }} {{#if system.identity.totem }}
<li class="row lgb"> <li class="row lgb major-totem">
<div class="flexcol flex-group-center items-center w-full"> <div class="flexcol flex-group-center items-center w-full">
<h4>{{ smarttl 'TOTEMS' system.identity.totem 'name' }}</h4>
<img <img
src="/systems/vermine2047/assets/images/ui/totems/{{ system.identity.totem }}.webp" src="/systems/vermine2047/assets/images/ui/totems/{{ system.identity.totem }}.webp"
alt="{{ smarttl 'TOTEMS' system.identity.totem 'name' }}" width="80" alt="{{ smarttl 'TOTEMS' system.identity.totem 'name' }}" width="80"
height="80" height="80" />
data-tooltip="{{localize system.identity.totem}}" />
</div> </div>
</li> </li>
{{/if}} {{/if}}
+62 -29
View File
@@ -1,36 +1,69 @@
<form class="{{cssClass}}" autocomplete="off"> <form
class="{{cssClass}}"
autocomplete="off"
>
<header class="sheet-header"> <header class="sheet-header">
<img class="profile-img" src="{{item.img}}" data-edit="img" title="{{item.name}}"/> <img
class="profile-img"
src="{{item.img}}"
data-edit="img"
title="{{item.name}}"
/>
<div class="header-fields"> <div class="header-fields">
<h1 class="charname"><input name="name" type="text" value="{{item.name}}" placeholder="Name"/></h1> <h1 class="charname"><input
name="name"
type="text"
value="{{item.name}}"
placeholder="Name"
/></h1>
</div> </div>
</header> </header>
<nav class="sheet-tabs tabs" data-group="primary">
<a class="item active" data-tab="description">{{ localize "VERMINE.stats" }}</a>
</nav>
<section class="sheet-body"> <section class="sheet-body">
<div class="tab flexrow" data-group="primary" data-tab="description"> <div class="flexrow">
<aside style="flex:1"> <div class="resource">
<div class="resource"> <label class="resource-label">{{ localize "VERMINE.clew"}}</label>
<label class="resource-label">{{ localize "VERMINE.clew"}}</label> <input
<input type="number" name="system.level" value="{{system.level}}" data-dtype="Number"/> type="number"
</div> name="system.level"
<div class="resource"> value="{{system.level}}"
<label class="resource-label">{{ localize "VERMINE.mobility"}}</label> data-dtype="Number"
<input type="number" name="system.mobility" value="{{system.mobility}}" data-dtype="Number"/> />
</div> </div>
<div class="resource"> <div class="resource">
<label class="resource-label">{{ localize "VERMINE.rarity"}}</label> <label class="resource-label">{{ localize "VERMINE.mobility"}}</label>
<input type="number" name="system.rarity" value="{{system.rarity}}" data-dtype="Number"/> <input
</div> type="number"
<div class="resource"> name="system.mobility"
<label class="resource-label">{{ localize "VERMINE.reliability"}}</label> value="{{system.mobility}}"
<input type="number" name="system.reliability" value="{{system.reliability}}" data-dtype="Number"/> data-dtype="Number"
</div> />
</aside> </div>
<main class="editor-wrapper" style="flex:10"> <div class="resource">
{{editor system.description target="system.description" rollData=rollData button=true owner=owner editable=editable}} <label class="resource-label">{{ localize "VERMINE.rarity"}}</label>
</main> <input
type="number"
name="system.rarity"
value="{{system.rarity}}"
data-dtype="Number"
/>
</div>
<div class="resource">
<label class="resource-label">{{ localize "VERMINE.reliability"}}</label>
<input
type="number"
name="system.reliability"
value="{{system.reliability}}"
data-dtype="Number"
/>
</div>
</div>
<main
class="editor-wrapper"
style="flex:10"
>
{{editor system.description target="system.description" rollData=rollData button=true owner=owner editable=editable}}
</main>
</div> </div>
</section> </section>
</form> </form>
-1
View File
@@ -9,7 +9,6 @@
data-edit="img" data-edit="img"
title="{{item.name}}" title="{{item.name}}"
/> />
{{log this}}
<div class="header-fields"> <div class="header-fields">
<h1 class="charname"><input <h1 class="charname"><input
name="name" name="name"
@@ -1,5 +1,6 @@
<form id="dice-pool-form" class="ecryme-dv-form" <form id="dice-pool-form" class="vermine form"
data-actor-id="{{ speakerId }}"> data-actor-id="{{ speakerId }}">
<input type="hidden" name="label" id="label" value="{{ label }}" /> <input type="hidden" name="label" id="label" value="{{ label }}" />
<input type="hidden" name="rollType" id="rollType" value="{{ rollType }}" /> <input type="hidden" name="rollType" id="rollType" value="{{ rollType }}" />
<input type="hidden" name="abilityScore" id="abilityScore" <input type="hidden" name="abilityScore" id="abilityScore"
@@ -16,10 +17,12 @@
<strong>{{#if (eq rollType 'skill')}}{{ smarttl "SKILLS" label <strong>{{#if (eq rollType 'skill')}}{{ smarttl "SKILLS" label
}}{{else}}{{ smarttl "ABILITIES" label }}{{/if}}</strong> </span> }}{{else}}{{ smarttl "ABILITIES" label }}{{/if}}</strong> </span>
</div> </div>
<div class="flexrow row mdb">
<div class="flexrow form-group row mdb">
<label class="label" style="flex: 60%;">{{localize <label class="label" style="flex: 60%;">{{localize
'VERMINE.difficulty'}}</label> 'VERMINE.difficulty'}}</label>
<select class="info-value" style="max-width: 40%;" data-dtype="String" <select class="info-value" data-roll="tue" style="max-width: 40%;"
data-dtype="String"
type="number" name="difficulty" id="difficulty" min="3" max="10"> type="number" name="difficulty" id="difficulty" min="3" max="10">
{{#select difficulty }} {{#select difficulty }}
<option value="{{ diffLevel 'difficulty' 1}}">{{ diffLevel 'label' 1}} - <option value="{{ diffLevel 'difficulty' 1}}">{{ diffLevel 'label' 1}} -
@@ -35,31 +38,64 @@
{{/select}} {{/select}}
</select> </select>
</div> </div>
<!--div class="flexrow row">
<input style="text-align: center;" class="numeric-entry" type="number" name="difficulty" value="7" id="difficulty" min="3" max="10">
</div-->
<div class="flexrow row mdb"> <div class="flexrow row mdb">
<label class="label" style="flex: 60%;">{{localize <label class="label" style="flex: 60%;">{{localize
'VERMINE.ability'}}</label> 'VERMINE.ability'}}</label>
<select class="info-value" style="max-width: 40%;" data-dtype="String" <select class="info-value" data-roll="true" style="max-width: 40%;"
data-dtype="String"
type="number" name="ability" id="ability" min="1" max="5"> type="number" name="ability" id="ability" min="1" max="5">
{{#if (eq rollType 'skill')}}<option>-- Choisissez une caractéristique <option>-- Choisissez une caractéristique
--</option>{{/if}} --</option>
{{#each abilities as |ability key| }} {{#each config.abilityCategories as |abilCategory catkey|}}
<option value="{{ key }}" {{#if (eq key @root.label)}}selected{{/if}}>
{{ smarttl "ABILITIES" key }} - {{ ability.value }}</option> <optgroup label="{{ smarttlk 'ABILITY_CATEGORIES' catkey 'name' }}">
{{#each @root.actor.system.abilities as |abil key|}}
{{#ife abil.category catkey}}
<option value="{{abil.value}}"
{{#ife @root.rollType "ability"}}
{{#ife @root.labelKey key}}
selected="true"
{{/ife}}
{{/ife}}>{{ smarttlk 'ABILITIES' key 'name'
}} / {{abil.value}}</option>
{{/ife}}
{{/each}}
</optgroup>
{{/each}} {{/each}}
</select> </select>
</div> </div>
{{#if (eq rollType 'skill')}}
<div class="flexrow row mdb"> <div class="flexrow row mdb">
<label class="label" style="flex: 60%;">{{localize <label class="label" style="flex: 60%;">{{localize
'VERMINE.skill_title'}}</label> 'VERMINE.skill_title'}}</label>
<select class="info-value" style="max-width: 40%;" data-dtype="String" <select class="info-value" data-roll="true" style="max-width: 40%;"
data-dtype="String"
type="number" name="skill" id="skill" min="1" max="5"> type="number" name="skill" id="skill" min="1" max="5">
{{#each skills as |skill key| }} <option>-- Choisissez une caractéristique
<option value="{{ key }}" {{#if (eq key @root.label)}}selected{{/if}}> --</option>
{{ smarttl "SKILLS" key }} - {{ skill.value }}</option> {{#each config.skillCategories as |skillCategory catkey|}}
<optgroup label="{{ smarttlk 'SKILLS_CATEGORIES' catkey 'name' }}">
{{#each @root.actor.system.skills as |skill key|}}
{{#ife skill.category catkey}}
<option value="{{skill.value}}" data-pool="{{skillLevel "dicePool"
skill.value}}"
data-reroll="{{skillLevel "reroll" skill.value}}"
{{#ife @root.rollType "skill"}}
{{#ife @root.labelKey key}}
selected="true"
{{/ife}}
{{/ife}}>
<b>{{ smarttlk 'SKILLS' key 'name' }},</b>
<i>dés:{{skillLevel "dicePool" skill.value}},
relances:{{skillLevel "reroll" skill.value}}</i>
</option>
{{/ife}}
{{/each}}
</optgroup>
{{/each}} {{/each}}
</select> </select>
</div> </div>
@@ -75,31 +111,52 @@
</div> </div>
<div class="flexrow row smb"> <div class="flexrow row smb">
<label class="label">{{localize 'VERMINE.specialty'}} (+1D)</label> <label class="label">{{localize 'VERMINE.specialty'}} (+1D)</label>
<input type="checkbox" name="usingSpecialization" id="usingSpecialization" <input type="checkbox" data-roll="true" name="usingSpecialization"
id="usingSpecialization"
value="1" {{#if specialty}}checked{{/if}}> value="1" {{#if specialty}}checked{{/if}}>
</div> </div>
{{/if}}
<div class="flexrow row smb"> <div class="flexrow row smb">
<label class="label">{{localize 'VERMINE.help'}} (+1D)</label> <label class="label">{{localize 'VERMINE.help'}} (+1D)</label>
<input type="checkbox" name="helped" id="helped" value="1" {{#if <input type="checkbox" data-roll="true" name="helped" id="helped"
value="1" {{#if
help}}checked{{/if}}> help}}checked{{/if}}>
</div> </div>
<div class="flexrow row mdb"> <div class="flexrow row mdb">
<label class="label">{{localize 'VERMINE.tooling'}} (+1D)</label> <label class="label">{{localize 'VERMINE.tooling'}} (+1D)</label>
<input type="checkbox" name="usingTools" id="usingTools" value="1" {{#if <input type="checkbox" data-roll="true" name="usingTools" id="usingTools"
value="1" {{#if
help}}checked{{/if}}> help}}checked{{/if}}>
</div> </div>
<div class="flexrow row mdb"> <div class="flexrow row mdb">
<label class="label" style="flex: 80%;">{{localize <label class="label" style="flex: 80%;">{{localize
'VERMINE.self_control'}}</label> 'VERMINE.self_control'}} <span id="self_control_value"></span>
<input type="number" class="numeric-entry" style="text-align: center;" </label>
name="self_control" id="self_control" min="0" max="5" value="0"> <input type="range" id="self_control" data-roll="true" name="self_control"
min="0"
max="0" value="0" />
</div>
<div class="flexrow">
<h4 class="label">utiliser des dés totems ?
</h4>
<div class="totem-human">
<label for="human-totem">totem humain </label>
<input type="checkbox" data-roll="true" name="human-totem"
id="human-totem"
value="1">
</div>
<div class="totem-adapted">
<label for="human-totem">totem adapté </label>
<input type="checkbox" data-roll="true" name="adapted-totem"
id="adapted-totem"
value="1">
</div>
</div> </div>
<div class="flexrow row mdb"> <div class="flexrow row mdb">
<label class="label" style="flex: 80%;">{{localize <label class="label" style="flex: 80%;">{{localize
'VERMINE.group'}}</label> 'VERMINE.group'}}</label>
<input type="number" class="numeric-entry" style="text-align: center;" <input type="number" data-roll="true" class="numeric-entry"
name="group" id="group" min="0" max value="0"> style="text-align: center;"
name="group" id="group" min="0" max="5" value="0">
</div> </div>
</div> </div>
<p><input type="hidden" name="speakerId" value="{{ speakerId }}" /> <p><input type="hidden" name="speakerId" value="{{ speakerId }}" />
+73 -24
View File
@@ -1,26 +1,75 @@
<div class="ecryme-dv roll attribute"> <div class="vermine-roll-message">
<div class="dice-roll"> {{log this}}
<div class="dice-result"> <h3>{{param.actor.name}} : test de {{param.rollLabel}}</h3>
<div class="dice-formula"> <div class="flexrow">
{{ ` + dicePool + `d6 }} <h4>difficulté</h4>
</div> <span id="difficulty">{{param.difficulty}}</span>
<div class="dice-tooltip expanded"> </div>
<section class="tooltip-part flexrow"> <ul class="flexrow roll-results initial-roll"
<div class="" style="flex:60%;"> data-difficulty="{{param.difficulty}}">
<div class="parameters"> {{#each roll.dice as |dieType index|}}
{{ targetText }} {{#each dieType.results as |die index|}}
</div> <li class="roll die flexcol
<div class="dice"> {{#if die.success}}
<ol class="dice-rolls">{{ diceString }}</ol> success
</div> {{/if}}
</div> {{#ifincludes dieType.options.flavor "adapted"}}
<div class="align-center"> adapted
Résultat {{/ifincludes}}
<p style="font-weight:bold; font-size:2em;">{{ (total + skill + _trait + _usingSpecialization + _used).toString() }}</p> {{#ifincludes dieType.options.flavor "regular"}}
</div> regular
</section> {{/ifincludes}}
</div>` + {{#ifincludes dieType.options.flavor "human"}}
`<h4 class="dice-total">{{ successText }}</h4> human
</div> {{/ifincludes}}
{{#ifgt @root.param.Reroll 0}}
rerollable
{{/ifgt}}
"
data-dice-type="
{{#ifincludes dieType.options.flavor "adapted"}}
adapted
{{/ifincludes}}
{{#ifincludes dieType.options.flavor "regular"}}
regular
{{/ifincludes}}
{{#ifincludes dieType.options.flavor "human"}}
human
{{/ifincludes}}">
<span>{{die.result}}</span>
</li>
{{/each}}
{{/each}}
</ul>
<div class="roll-total flexrow">
<h4>nombre de succès :</h4>
<span id="total">{{roll._total}}</span>
</div>
<div class="reroll flexrow">
<div class="reroll-from-effort ">
<div class="flexcol">
<h4 class="flexcol">
<span>effort</span>
</h4>
<input type="range" min="0"
{{#iflt param.max_effort param.actor.system.attributes.effort.value}}
max="{{param.max_effort}}"
{{/iflt}}
{{#iflteq param.actor.system.attributes.effort.value param.max_effort }}
max="{{param.actor.system.attributes.effort.value}}"
{{/iflteq}}
value="0"
id="effort-reroll">
</input>
</div>
<button class="grant-reroll" data-tooltip="s'accorder des relances"> <span id="granted-reroll">0</span> </button>
</div>
<div class="reroll-fromroll">
<h4>relances possibles : </h4>
<span id="allowed_reroll">{{param.Reroll}}</span>
</div> </div>
</div>
</div> </div>