Confrontation stuff

This commit is contained in:
LeRatierBretonnien 2023-05-30 19:25:26 +02:00
parent 4058cd530b
commit dbb22bbeb7
17 changed files with 467 additions and 178 deletions

View File

@ -1,11 +1,13 @@
{ {
"ACTOR": { "TYPES": {
"TypePersonnage": "PC" "Actor":{
"Personnage": "PC"
}, },
"ITEM": { "Item": {
"TypeTrait": "Trait", "Trait": "Trait",
"TypeWeapon": "Weapon", "Weapon": "Weapon",
"TypeEquipment": "Equipment" "Equipment": "Equipment"
}
}, },
"ECRY": { "ECRY": {
"chat": { "chat": {
@ -78,7 +80,12 @@
"traitmalus": "Malus traits", "traitmalus": "Malus traits",
"applyideal": "Apply ideal", "applyideal": "Apply ideal",
"applyspleen": "Apply spleen", "applyspleen": "Apply spleen",
"skilltranscendence": "Self Transcendence" "skilltranscendence": "Self Transcendence",
"confrontation": "Confrontation",
"rollnormal": "Normal (4d6)",
"rollspleen": "With Spleen (5d6, worst 4 are kept)",
"rollideal": "With Ideal (5d6, best 4 are kept)"
} }
} }
} }

View File

@ -1,11 +1,13 @@
{ {
"ACTOR": { "TYPES": {
"TypePersonnage": "PC" "Actor":{
"Personnage": "PJ"
}, },
"ITEM": { "Item": {
"TypeTrait": "Trait", "Trait": "Trait",
"TypeWeapon": "Weapon", "Weapon": "Arme",
"TypeEquipment": "Equipment" "Equipment": "Equipement"
}
}, },
"ECRY": { "ECRY": {
"chat": { "chat": {
@ -78,7 +80,11 @@
"traitmalus": "Traits malus", "traitmalus": "Traits malus",
"applyideal": "Utiliser l'idéal", "applyideal": "Utiliser l'idéal",
"applyspleen": "Utiliser le spleen", "applyspleen": "Utiliser le spleen",
"skilltranscendence": "Dépassement de soi" "skilltranscendence": "Dépassement de soi",
"confrontation": "Confrontation",
"rollnormal": "Normal (4d6)",
"rollspleen": "Avec le Spleen (5d6, 4 plus bas conservés)",
"rollideal": "Avec l'Idéal (5d6, 4 plus haut conservés)"
} }
} }
} }

View File

@ -115,6 +115,12 @@ export class EcrymeActorSheet extends ActorSheet {
let skillKey = $(event.currentTarget).data("skill-key") let skillKey = $(event.currentTarget).data("skill-key")
this.actor.rollSkill(categKey, skillKey) this.actor.rollSkill(categKey, skillKey)
}); });
html.find('.roll-skill-confront').click((event) => {
let categKey = $(event.currentTarget).data("category-key")
let skillKey = $(event.currentTarget).data("skill-key")
this.actor.rollSkillConfront(categKey, skillKey)
});
html.find('.roll-weapon').click((event) => { html.find('.roll-weapon').click((event) => {
const armeId = $(event.currentTarget).data("arme-id") const armeId = $(event.currentTarget).data("arme-id")
this.actor.rollArme(armeId) this.actor.rollArme(armeId)

View File

@ -1,7 +1,7 @@
/* -------------------------------------------- */ /* -------------------------------------------- */
import { EcrymeUtility } from "../common/ecryme-utility.js"; import { EcrymeUtility } from "../common/ecryme-utility.js";
import { EcrymeRollDialog } from "../dialogs/ecryme-roll-dialog.js"; import { EcrymeRollDialog } from "../dialogs/ecryme-roll-dialog.js";
import { EcrymeConfrontStartDialog } from "../dialogs/ecryme-confront-start-dialog.js";
/* -------------------------------------------- */ /* -------------------------------------------- */
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -304,7 +304,7 @@ export class EcrymeActor extends Actor {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
rollSkill(categKey, skillKey) { getCommonSkill(categKey, skillKey) {
let skill = this.system.skills[categKey].skilllist[skillKey] let skill = this.system.skills[categKey].skilllist[skillKey]
let rollData = this.getCommonRollData() let rollData = this.getCommonRollData()
skill = duplicate(skill) skill = duplicate(skill)
@ -312,12 +312,29 @@ export class EcrymeActor extends Actor {
skill.skillKey = skillKey skill.skillKey = skillKey
skill.spec = this.getSpecializations(skillKey) skill.spec = this.getSpecializations(skillKey)
rollData.skill = skill rollData.skill = skill
rollData.mode = "skill"
rollData.title = game.i18n.localize(skill.name)
rollData.img = skill.img rollData.img = skill.img
return rollData
}
/* -------------------------------------------- */
rollSkill(categKey, skillKey) {
let rollData = this.getCommonSkill(categKey, skillKey)
rollData.mode = "skill"
rollData.title = game.i18n.localize(rollData.skill.name)
this.startRoll(rollData) this.startRoll(rollData)
} }
/* -------------------------------------------- */
async rollSkillConfront(categKey, skillKey) {
let rollData = this.getCommonSkill(categKey, skillKey)
rollData.mode = "skill"
rollData.title = game.i18n.localize("ECRY.ui.confrontation") + " : " + game.i18n.localize(rollData.skill.name)
rollData.executionDices = []
rollData.preservationDices = []
let confrontStartDialog = await EcrymeConfrontStartDialog.create(this, rollData)
confrontStartDialog.render(true)
}
/* -------------------------------------------- */ /* -------------------------------------------- */
rollWeapon(weaponId) { rollWeapon(weaponId) {
let weapon = this.items.get(weaponId) let weapon = this.items.get(weaponId)
@ -341,7 +358,6 @@ export class EcrymeActor extends Actor {
/* -------------------------------------------- */ /* -------------------------------------------- */
async startRoll(rollData) { async startRoll(rollData) {
console.log("ROLLDATA", rollData)
let rollDialog = await EcrymeRollDialog.create(this, rollData) let rollDialog = await EcrymeRollDialog.create(this, rollData)
rollDialog.render(true) rollDialog.render(true)
} }

View File

@ -111,7 +111,7 @@ export class EcrymeUtility {
return false return false
} }
options.push({ options.push({
name: game.i18.localize("ECRY.chat.spectranscend") + i, name: game.i18n.localize("ECRY.chat.spectranscend") + i,
icon: '<i class="fas fa-plus-square"></i>', icon: '<i class="fas fa-plus-square"></i>',
condition: canTranscendRoll[i], condition: canTranscendRoll[i],
callback: li => { callback: li => {
@ -149,7 +149,8 @@ export class EcrymeUtility {
'systems/fvtt-ecryme/templates/actors/editor-notes-gm.hbs', 'systems/fvtt-ecryme/templates/actors/editor-notes-gm.hbs',
'systems/fvtt-ecryme/templates/items/partial-item-nav.hbs', 'systems/fvtt-ecryme/templates/items/partial-item-nav.hbs',
'systems/fvtt-ecryme/templates/items/partial-item-equipment.hbs', 'systems/fvtt-ecryme/templates/items/partial-item-equipment.hbs',
'systems/fvtt-ecryme/templates/items/partial-item-description.hbs' 'systems/fvtt-ecryme/templates/items/partial-item-description.hbs',
'systems/fvtt-ecryme/templates/dialogs/partial-common-roll-dialog.hbs'
] ]
return loadTemplates(templatePaths); return loadTemplates(templatePaths);
} }
@ -303,22 +304,14 @@ export class EcrymeUtility {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async rollEcryme(rollData) { static computeRollFormula(rollData, isConfrontation = false) {
let actor = game.actors.get(rollData.actorId)
// Fix difficulty
if (!rollData.difficulty || rollData.difficulty == "-") {
rollData.difficulty = 0
}
rollData.difficulty = Number(rollData.difficulty)
// Build the dice formula // Build the dice formula
let diceFormula = "2d6" let diceFormula = (isConfrontation) ? "4d6" : "2d6"
if (rollData.useIdeal) { if (rollData.useIdeal) {
diceFormula = "3d6kh2" diceFormula = (isConfrontation) ? "5d6kh2" : "3d6kh2"
} }
if (rollData.useSpleen) { if (rollData.useSpleen) {
diceFormula = "3d6kl2" diceFormula = (isConfrontation) ? "5d6kl2" : "3d6kl2"
} }
if (rollData.skill) { if (rollData.skill) {
diceFormula += "+" + rollData.skill.value diceFormula += "+" + rollData.skill.value
@ -352,6 +345,20 @@ export class EcrymeUtility {
diceFormula += "+" + rollData.bonusMalusTraits diceFormula += "+" + rollData.bonusMalusTraits
diceFormula += "+" + rollData.bonusMalusPerso diceFormula += "+" + rollData.bonusMalusPerso
rollData.diceFormula = diceFormula rollData.diceFormula = diceFormula
return diceFormula
}
/* -------------------------------------------- */
static async rollEcryme(rollData) {
let actor = game.actors.get(rollData.actorId)
// Fix difficulty
if (!rollData.difficulty || rollData.difficulty == "-") {
rollData.difficulty = 0
}
rollData.difficulty = Number(rollData.difficulty)
let diceFormula = this.computeRollFormula(rollData)
// Performs roll // Performs roll
let myRoll = new Roll(diceFormula).roll({ async: false }) let myRoll = new Roll(diceFormula).roll({ async: false })

View File

@ -0,0 +1,90 @@
import { EcrymeUtility } from "../common/ecryme-utility.js";
import { EcrymeRollDialog } from "./ecryme-roll-dialog.js";
export class EcrymeConfrontDialog extends Dialog {
/* -------------------------------------------- */
static async create(actor, rollData) {
let options = mergeObject(super.defaultOptions, {
classes: ["fvtt-ecryme ecryme-confrontation-dialog"],
dragDrop: [{ dragSelector: ".confront-dice-container", dropSelector: null }],
width: 540, height: 'fit-content', 'z-index': 99999
});
let html = await renderTemplate('systems/fvtt-ecryme/templates/dialogs/confront-dialog.hbs', rollData);
return new EcrymeConfrontDialog(actor, rollData, html, options);
}
/* -------------------------------------------- */
constructor(actor, rollData, html, options, close = undefined) {
let conf = {
title: game.i18n.localize("ECRY.ui.confront"),
content: html,
buttons: {
rollNormal: {
icon: '<i class="fas fa-check"></i>',
label: game.i18n.localize("ECRY.ui.rollnormal"),
callback: () => { this.rollConfront("4d6") }
},
cancel: {
icon: '<i class="fas fa-times"></i>',
label: game.i18n.localize("ECRY.ui.cancel"),
callback: () => { this.close() }
}
},
close: close
}
super(conf, options);
this.actor = actor;
this.rollData = rollData;
}
/* -------------------------------------------- */
async roll() {
}
/* ------------------ -------------------------- */
_onDragStart(event) {
super._onDragStart(event)
const diceData = {
diceIndex : $(event.srcElement).data("dice-idx"),
diceValue : $(event.srcElement).data("dice-value"),
}
event.dataTransfer.setData("text/plain", JSON.stringify( diceData ));
console.log(">>>>> DRAG START!!!!", event)
}
/* ------------------ -------------------------- */
async refreshDialog() {
const content = await renderTemplate("systems/fvtt-ecryme/templates/dialogs/confront-dialog.hbs", this.rollData)
this.data.content = content
this.render(true)
}
/* -------------------------------------------- */
_onDrop(event) {
let dataJSON = event.dataTransfer.getData('text/plain')
let data = JSON.parse(dataJSON)
let idx = Number(data.diceIndex)
console.log("DATA", data, event, event.srcElement.className)
if ( event.srcElement.className.includes("execution")) {
this.rollData.availableDices[idx].location = "execution"
}
if ( event.srcElement.className.includes("preservation")) {
this.rollData.availableDices[idx].location = "preservation"
}
if ( event.srcElement.className.includes("dice-list")) {
this.rollData.availableDices[idx].location = "mainpool"
}
this.refreshDialog()
}
/* -------------------------------------------- */
activateListeners(html) {
super.activateListeners(html);
}
}

View File

@ -0,0 +1,74 @@
import { EcrymeUtility } from "../common/ecryme-utility.js";
import {EcrymeConfrontDialog } from "./ecryme-confront-dialog.js";
export class EcrymeConfrontStartDialog extends Dialog {
/* -------------------------------------------- */
static async create(actor, rollData) {
let options = { classes: ["fvtt-ecryme ecryme-confront-dialog"], width: 540, height: 'fit-content', 'z-index': 99999 }
let html = await renderTemplate('systems/fvtt-ecryme/templates/dialogs/confront-start-dialog.hbs', rollData);
return new EcrymeConfrontStartDialog(actor, rollData, html, options);
}
/* -------------------------------------------- */
constructor(actor, rollData, html, options, close = undefined) {
let conf = {
title: game.i18n.localize("ECRY.ui.confront"),
content: html,
buttons: {
rollNormal: {
icon: '<i class="fas fa-check"></i>',
label: game.i18n.localize("ECRY.ui.rollnormal"),
callback: () => { this.rollConfront("4d6") }
},
rollSpleen: {
icon: '<i class="fas fa-check"></i>',
label: game.i18n.localize("ECRY.ui.rollspleen"),
callback: () => { this.rollConfront("5d6kl4") }
},
rollIdeal: {
icon: '<i class="fas fa-check"></i>',
label: game.i18n.localize("ECRY.ui.rollideal"),
callback: () => { this.rollConfront("5d6kh4") }
},
cancel: {
icon: '<i class="fas fa-times"></i>',
label: game.i18n.localize("ECRY.ui.cancel"),
callback: () => { this.close() }
}
},
close: close
}
super(conf, options);
this.actor = actor;
this.rollData = rollData;
}
/* -------------------------------------------- */
async rollConfront( diceFormula ) {
// Do the initial roll
let myRoll = new Roll(diceFormula).roll({async: false})
await EcrymeUtility.showDiceSoNice(myRoll, game.settings.get("core", "rollMode"))
// Fill the available dice table
let rollData = this.rollData
rollData.roll = duplicate(myRoll)
rollData.availableDices = []
for (let result of myRoll.terms[0].results) {
if ( !result.discarded) {
let resultDup = duplicate(result)
resultDup.location = "mainpool"
rollData.availableDices.push(resultDup)
}
}
let confrontDialog = await EcrymeConfrontDialog.create(this.actor, rollData)
confrontDialog.render(true)
}
/* -------------------------------------------- */
activateListeners(html) {
super.activateListeners(html);
}
}

View File

@ -12,7 +12,6 @@ export class EcrymeRollDialog extends Dialog {
/* -------------------------------------------- */ /* -------------------------------------------- */
constructor(actor, rollData, html, options, close = undefined) { constructor(actor, rollData, html, options, close = undefined) {
let isCard = rollData.attr && rollData.attr.iscard
let conf = { let conf = {
title: game.i18n.localize("ECRY.ui.rolltitle"), title: game.i18n.localize("ECRY.ui.rolltitle"),
content: html, content: html,

View File

@ -8,7 +8,6 @@ export class EcrymeItemSheet extends ItemSheet {
/** @override */ /** @override */
static get defaultOptions() { static get defaultOptions() {
return mergeObject(super.defaultOptions, { return mergeObject(super.defaultOptions, {
classes: ["fvtt-ecryme", "sheet", "item"], classes: ["fvtt-ecryme", "sheet", "item"],
template: "systems/fvtt-ecryme/templates/item-sheet.hbs", template: "systems/fvtt-ecryme/templates/item-sheet.hbs",

View File

@ -1326,3 +1326,30 @@ ul, li {
margin-top: 4px; margin-top: 4px;
margin-bottom: 4px; margin-bottom: 4px;
} }
.confront-dice {
border-width: 0px;
}
.confront-dice-container {
position: relative;
max-width: 128px;
flex-grow: 1;
text-align: center;
color: black;
}
.confront-dice-centered {
position: absolute;
top: 50%;
left: 50%;
font-size: 2rem;
color: darkgreen;
font-family: MailartRubberstamp;
transform: translate(-50%, -80%);
}
.confront-area {
min-height: 96px;
border-width: 2px;
border-color: #000000;
border-radius: 4px;
border: 2px ridge #443307;
}

View File

@ -1306,3 +1306,30 @@ ul, li {
margin-top: 4px; margin-top: 4px;
margin-bottom: 4px; margin-bottom: 4px;
} }
.confront-dice {
border-width: 0px;
}
.confront-dice-container {
position: relative;
max-width: 128px;
flex-grow: 1;
text-align: center;
color: black;
}
.confront-dice-centered {
position: absolute;
top: 50%;
left: 50%;
font-size: 2rem;
color: darkgreen;
font-family: MailartRubberstamp;
transform: translate(-50%, -80%);
}
.confront-area {
min-height: 96px;
border-width: 2px;
border-color: #000000;
border-radius: 4px;
border: 2px ridge #443307;
}

View File

@ -75,6 +75,9 @@
{{#each category.skilllist as |skill skillkey|}} {{#each category.skilllist as |skill skillkey|}}
<li class="item flexrow list-item"> <li class="item flexrow list-item">
<span class="item-name-label-long"> <span class="item-name-label-long">
<a class="roll-skill-confront" data-category-key="{{categkey}}" data-skill-key="{{skillkey}}">
<i class="fa-regular fa-swords"></i>
</a>
<a class="roll-skill" data-category-key="{{categkey}}" data-skill-key="{{skillkey}}"> <a class="roll-skill" data-category-key="{{categkey}}" data-skill-key="{{skillkey}}">
<i class="fa-solid fa-dice-d6"></i> <i class="fa-solid fa-dice-d6"></i>
{{localize skill.name}} {{localize skill.name}}

View File

@ -0,0 +1,58 @@
<form class="confrontation-roll-dialog">
<header class="roll-dialog-header">
{{#if img}}
<img class="actor-icon" src="{{img}}" data-edit="img" title="{{name}}" />
{{/if}}
<h1 class="dialog-roll-title roll-dialog-header">{{title}}</h1>
</header>
<div class="flexcol">
<div class="flexrow">
<div class="flexrow confront-area confront-execution-area" >
{{#each availableDices as |dice idx|}}
{{#if (eq dice.location "execution")}}
<div class="confront-dice-container" >
<span draggable="true" data-dice-idx={{idx}} data-dice-value="{{dice.result}}">
<img class="confront-dice" src="icons/svg/d6-grey.svg">
<label class="confront-dice-centered">{{dice.result}}</label>
</span>
</div>
{{/if}}
{{/each}}
</div>
<div class="flexrow confront-area confront-preservation-area" >
{{#each availableDices as |dice idx|}}
{{#if (eq dice.location "preservation")}}
<div class="confront-dice-container" >
<span draggable="true" data-dice-idx={{idx}} data-dice-value="{{dice.result}}">
<img class="confront-dice" src="icons/svg/d6-grey.svg">
<label class="confront-dice-centered">{{dice.result}}</label>
</span>
</div>
{{/if}}
{{/each}}
</div>
</div>
<div class="flexrow confront-area confrontation-dice-list">
{{#each availableDices as |dice idx|}}
{{#if (eq dice.location "mainpool")}}
<div class="confront-dice-container" >
<span draggable="true" data-dice-idx={{idx}} data-dice-value="{{dice.result}}">
<img class="confront-dice" src="icons/svg/d6-grey.svg">
<label class="confront-dice-centered">{{dice.result}}</label>
</span>
</div>
{{/if}}
{{/each}}
</div>
{{> systems/fvtt-ecryme/templates/dialogs/partial-common-roll-dialog.hbs}}
</div>
</form>

View File

@ -0,0 +1,13 @@
<form class="confrontation-roll-dialog">
<header class="roll-dialog-header">
{{#if img}}
<img class="actor-icon" src="{{img}}" data-edit="img" title="{{name}}" />
{{/if}}
<h1 class="dialog-roll-title roll-dialog-header">{{title}}</h1>
</header>
<div class="flexcol">
</div>
</form>

View File

@ -1,45 +0,0 @@
<form class="skill-roll-dialog">
<header class="roll-dialog-header">
{{#if img}}
<img class="actor-icon" src="{{img}}" data-edit="img" title="{{name}}" />
{{/if}}
<h1 class="dialog-roll-title roll-dialog-header">{{title}}</h1>
</header>
<div class="flexcol">
<div class="flexrow">
<span class="roll-dialog-label">{{attr.label}} : </span>
<span class="roll-dialog-label">
{{attr.value}}
</span>
</div>
<div class="flexrow">
<span class="roll-dialog-label">Degré de la confrontation : </span>
<select id="confrontationDegre" name="confrontationDegre">
{{#select confrontationDegre}}
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
{{/select}}
</select>
</div>
<div class="flexrow">
<span class="roll-dialog-label">Modificateur de confrontation : </span>
<select id="confrontationModif" name="confrontationModif">
{{#select confrontationModif}}
<option value="-1">-1</option>
<option value="0">0</option>
<option value="1">+1</option>
{{/select}}
</select>
</div>
</div>
</form>

View File

@ -0,0 +1,78 @@
{{#if skill}}
<div class="flexrow">
<span class="roll-dialog-label">{{localize skill.name}} : </span>
<span class="roll-dialog-label">
{{skill.value}}
</span>
</div>
<div class="flexrow">
<span class="roll-dialog-label">{{localize "ECRY.ui.skilltranscendence"}} : </span>
<select class="" id="roll-select-transcendence" data-type="Number">
{{#select skillTranscendence}}
{{#for 0 skill.value 1}}
<option value="{{this}}">{{this}}</option>
{{/for}}
{{/select}}
</select>
</div>
<div class="flexrow">
<span class="roll-dialog-label">{{localize "ECRY.ui.spec"}} : </span>
<select class="" id="roll-specialization" data-type="String" multiple>
{{#each skill.spec as | spec idx|}}
<option value="{{spec._id}}">{{spec.name}}</option>
{{/each}}
</select>
</div>
{{#if spleen}}
<div class="flexrow">
<span class="roll-dialog-label">{{localize "ECRY.ui.applyspleen"}} {{spleen.name}}</span>
<input type="checkbox" class="item-field-label-short" id="roll-use-spleen" {{checked useSpleen}} />
</div>
{{/if}}
{{#if ideal}}
<div class="flexrow">
<span class="roll-dialog-label">{{localize "ECRY.ui.applyideal"}} {{ideal.name}}</span>
<input type="checkbox" class="item-field-label-short" id="roll-use-ideal" {{checked useIdeal}} />
</div>
{{/if}}
<div class="flexrow">
<span class="roll-dialog-label">{{localize "ECRY.ui.traitbonus"}} : </span>
<select class="" id="roll-trait-bonus" data-type="String" multiple>
{{#each traits as | trait idx|}}
<option value="{{trait._id}}">{{trait.name}} ({{trait.system.level}})</option>
{{/each}}
</select>
</div>
<div class="flexrow">
<span class="roll-dialog-label">{{localize "ECRY.ui.traitmalus"}} : </span>
<select class="" id="roll-trait-malus" data-type="String" multiple>
{{#each traits as | trait idx|}}
<option value="{{trait._id}}">{{trait.name}} ({{trait.system.level}})</option>
{{/each}}
</select>
</div>
{{/if}}
<div class="flexrow">
<span class="roll-dialog-label">Bonus/Malus : </span>
<select id="bonusMalusPerso" name="bonusMalusPerso">
{{#select bonusMalusPerso}}
<option value="-3">-3</option>
<option value="-2">-2</option>
<option value="-1">-1</option>
<option value="0">0</option>
<option value="1">+1</option>
<option value="2">+2</option>
<option value="3">+3</option>
{{/select}}
</select>
</div>

View File

@ -8,83 +8,7 @@
<div class="flexcol"> <div class="flexcol">
{{#if skill}} {{> systems/fvtt-ecryme/templates/dialogs/partial-common-roll-dialog.hbs}}
<div class="flexrow">
<span class="roll-dialog-label">{{localize skill.name}} : </span>
<span class="roll-dialog-label">
{{skill.value}}
</span>
</div>
<div class="flexrow">
<span class="roll-dialog-label">{{localize "ECRY.ui.skilltranscendence"}} : </span>
<select class="" id="roll-select-transcendence" data-type="Number">
{{#select skillTranscendence}}
{{#for 0 skill.value 1}}
<option value="{{this}}">{{this}}</option>
{{/for}}
{{/select}}
</select>
</div>
<div class="flexrow">
<span class="roll-dialog-label">{{localize "ECRY.ui.spec"}} : </span>
<select class="" id="roll-specialization" data-type="String" multiple>
{{#each skill.spec as | spec idx|}}
<option value="{{spec._id}}">{{spec.name}}</option>
{{/each}}
</select>
</div>
{{#if spleen}}
<div class="flexrow">
<span class="roll-dialog-label">{{localize "ECRY.ui.applyspleen"}} {{spleen.name}}</span>
<input type="checkbox" class="item-field-label-short" id="roll-use-spleen" {{checked useSpleen}} />
</div>
{{/if}}
{{#if ideal}}
<div class="flexrow">
<span class="roll-dialog-label">{{localize "ECRY.ui.applyideal"}} {{ideal.name}}</span>
<input type="checkbox" class="item-field-label-short" id="roll-use-ideal" {{checked useIdeal}} />
</div>
{{/if}}
<div class="flexrow">
<span class="roll-dialog-label">{{localize "ECRY.ui.traitbonus"}} : </span>
<select class="" id="roll-trait-bonus" data-type="String" multiple>
{{#each traits as | trait idx|}}
<option value="{{trait._id}}">{{trait.name}} ({{trait.system.level}})</option>
{{/each}}
</select>
</div>
<div class="flexrow">
<span class="roll-dialog-label">{{localize "ECRY.ui.traitmalus"}} : </span>
<select class="" id="roll-trait-malus" data-type="String" multiple>
{{#each traits as | trait idx|}}
<option value="{{trait._id}}">{{trait.name}} ({{trait.system.level}})</option>
{{/each}}
</select>
</div>
{{/if}}
<div class="flexrow">
<span class="roll-dialog-label">Bonus/Malus : </span>
<select id="bonusMalusPerso" name="bonusMalusPerso">
{{#select bonusMalusPerso}}
<option value="-3">-3</option>
<option value="-2">-2</option>
<option value="-1">-1</option>
<option value="0">0</option>
<option value="1">+1</option>
<option value="2">+2</option>
<option value="3">+3</option>
{{/select}}
</select>
</div>
<div class="flexrow"> <div class="flexrow">
<span class="roll-dialog-label">Difficulté : </span> <span class="roll-dialog-label">Difficulté : </span>