Support des jets d'attributs et d'aptitudes

Ajout des macros
Amélioration des cartons dans le chat avec gestion des succès/échecs/échecs critiques.
Support des carrières dans les dialogues de tests d'attibuts et d'aptitudes.
This commit is contained in:
ZigmundKreud
2021-12-22 05:12:40 +01:00
parent 4c349d89a8
commit d5a5990faa
41 changed files with 750 additions and 578 deletions

View File

@ -2,6 +2,8 @@
* Extend the basic ActorSheet with some very simple modifications
* @extends {ActorSheet}
*/
import {BoLRoll} from "../controllers/bol-rolls.js";
export class BoLActorSheet extends ActorSheet {
/** @override */
@ -33,18 +35,6 @@ export class BoLActorSheet extends ActorSheet {
const item = this.actor.items.get(li.data("itemId"));
item.sheet.render(true);
});
html.find('.roll-attribute').click(ev => {
this.actor.rollAttributeAptitude( $(ev.currentTarget).data("attr-key") );
});
html.find('.roll-career').click(ev => {
const li = $(ev.currentTarget).parents(".item");
this.actor.rollCareer( li.data("itemId") );
});
html.find('.roll-weapon').click(ev => {
const li = $(ev.currentTarget).parents(".item");
this.actor.rollWeapon( li.data("itemId") );
});
// Equip/Unequip item
html.find('.item-equip').click(this._onToggleEquip.bind(this));
@ -57,6 +47,18 @@ export class BoLActorSheet extends ActorSheet {
// Rollable abilities.
html.find('.rollable').click(this._onRoll.bind(this));
// html.find('.roll-attribute').click(ev => {
// this.actor.rollAttributeAptitude( $(ev.currentTarget).data("attr-key") );
// });
// html.find('.roll-career').click(ev => {
// const li = $(ev.currentTarget).parents(".item");
// this.actor.rollCareer( li.data("itemId") );
// });
// html.find('.roll-weapon').click(ev => {
// const li = $(ev.currentTarget).parents(".item");
// this.actor.rollWeapon( li.data("itemId") );
// });
}
/* -------------------------------------------- */
@ -121,14 +123,16 @@ export class BoLActorSheet extends ActorSheet {
event.preventDefault();
const element = event.currentTarget;
const dataset = element.dataset;
if (dataset.roll) {
let roll = new Roll(dataset.roll, this.actor.data.data);
let label = dataset.label ? `Rolling ${dataset.label}` : '';
roll.roll().toMessage({
speaker: ChatMessage.getSpeaker({ actor: this.actor }),
flavor: label
});
const actorData = this.getData();
const rollType = dataset.rollType;
switch(rollType) {
case "attribute" :
BoLRoll.attributeCheck(this.actor, actorData, dataset, event);
break;
case "aptitude" :
BoLRoll.aptitudeCheck(this.actor, actorData, dataset, event);
break;
default : break;
}
}

View File

@ -1,6 +1,3 @@
import { BoLRollDialog } from "../system/roll-dialog.js";
import { BoLUtility } from "../system/bol-utility.js";
/**
* Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
* @extends {Actor}
@ -14,9 +11,7 @@ export class BoLActor extends Actor {
// console.log(actorData);
// const data = actorData.data;
// const flags = actorData.flags;
// Make separate methods for each Actor type (character, npc, etc.) to keep
// things organized.
// Make separate methods for each Actor type (character, npc, etc.) to keep things organized.
if (actorData.type === 'character') {
this._prepareCharacterData(actorData);
}
@ -165,97 +160,6 @@ export class BoLActor extends Actor {
};
}
/* -------------------------------------------- */
buildRollData(mode, title) {
return {
mode : mode,
title : title,
actorId: this.id,
actorImg: this.img,
boons : this.boons,
flaws : this.flaws,
d6Bonus: 0,
d6Malus: 0,
rollMode: game.settings.get("core", "rollMode"),
optionsBonusMalus: BoLUtility.buildListOptions(-8, +2),
bonusMalus: 0
}
}
saveRollData( rollData) {
this.currentRollData = rollData;
}
/* -------------------------------------------- */
async rollAttributeAptitude( attrKey ) {
let attr = this.data.data.attributes[attrKey];
if ( !attr) {
attr = this.data.data.aptitudes[attrKey];
}
if (attr) {
let rollData = this.buildRollData("attribute", game.i18n.localize(attr.label));
rollData.attribute = duplicate(attr);
let rollDialog = await BoLRollDialog.create( this, rollData);
rollDialog.render( true );
} else {
ui.notifications.warn("Unable to find attribute " + attrKey );
}
}
/* -------------------------------------------- */
async rollCareer( careerId ) {
let career = BoLUtility.data(this.data.items.find( item => item.type == 'feature' && item.id == careerId));
if (career) {
let rollData = this.buildRollData("career", `${career.name} : ${career.data.rank}`);
rollData.career = career;
rollData.rollAttribute = 'mind';
rollData.attributes = duplicate(this.data.data.attributes);
let rollDialog = await BoLRollDialog.create( this, rollData);
rollDialog.render( true );
} else {
ui.notifications.warn("Unable to find career for actor " + this.name + " - Career ID " + careerId);
}
}
/* -------------------------------------------- */
async rollWeapon( weaponId ) {
let weapon = BoLUtility.data(this.data.items.find( item => item.type == 'item' && item.id == weaponId));
if (weapon) {
let target = BoLUtility.getTarget();
// if ( !target) {
// ui.notifications.warn("You must have a target to attack with a Weapon");
// return;
// }
let objectDefender = (target) ? BoLUtility.data(game.actors.get(target.data.actorId)) : null;
objectDefender = (objectDefender) ? mergeObject(objectDefender, target.data.actorData) : null;
let rollData = this.buildRollData("weapon", weapon.name);
rollData.weapon = weapon;
rollData.target = target;
rollData.isRanged = BoLUtility.isRangedWeapon( weapon );
rollData.defender = objectDefender;
rollData.rollAttribute = 'agility';
rollData.attributes = duplicate(this.data.data.attributes); // For damage bonus
rollData.rangeModifier = 0;
if ( weapon.data.type == 'melee') {
rollData.aptitude = duplicate(this.data.data.aptitudes.melee);
} else {
rollData.aptitude = duplicate(this.data.data.aptitudes.ranged);
}
console.log("WEAPON ! ", rollData);
let rollDialog = await BoLRollDialog.create( this, rollData);
rollDialog.render( true );
} else {
ui.notifications.warn("Unable to find weapon for actor " + this.name + " - Weapon ID " + weaponId);
}
}
/**
*
* @param {*} item
* @param {*} bypassChecks
* @returns
*/
toggleEquipItem(item) {
const equipable = item.data.data.properties.equipable;
if(equipable){
@ -264,6 +168,4 @@ export class BoLActor extends Actor {
return item.update(itemData);
}
}
}

View File

@ -8,13 +8,15 @@ import {preloadHandlebarsTemplates} from "./system/templates.js";
import {registerHandlebarsHelpers} from "./system/helpers.js";
import {registerSystemSettings} from "./system/settings.js";
import registerHooks from "./system/hooks.js";
import {DataLoader} from "./system/data.js";
// import {DataLoader} from "./system/data.js";
import {Macros} from "./system/macros.js";
Hooks.once('init', async function () {
game.bol = {
BoLActor,
BoLItem,
macros : Macros,
config:BOL
};

View File

@ -0,0 +1,207 @@
export class BoLRoll {
static options() {
return { classes: ["bol", "dialog"] };
}
static attributeCheck(actor, actorData, dataset, event) {
// const elt = $(event.currentTarget)[0];
// let key = elt.attributes["data-rolling"].value;
const key = dataset.key;
const adv = dataset.adv;
let attribute = eval(`actor.data.data.attributes.${key}`);
let label = (attribute.label) ? game.i18n.localize(attribute.label) : null;
let description = actor.name + " - " + game.i18n.localize('BOL.ui.attributeCheck') + " - " + game.i18n.localize(attribute.label) ;
return this.attributeRollDialog(actor, actorData, attribute, label, description, adv, 0);
}
static aptitudeCheck(actor, actorData, dataset, event) {
// const elt = $(event.currentTarget)[0];
// let key = elt.attributes["data-rolling"].value;
const key = dataset.key;
const adv = dataset.adv;
let aptitude = eval(`actor.data.data.aptitudes.${key}`);
let label = (aptitude.label) ? game.i18n.localize(aptitude.label) : null;
let description = actor.name + " - " + game.i18n.localize('BOL.ui.aptitudeCheck') + " - " + game.i18n.localize(aptitude.label) ;
return this.aptitudeRollDialog(actor, actorData, aptitude, label, description, adv, 0);
}
/* -------------------------------------------- */
/* ROLL DIALOGS */
/* -------------------------------------------- */
static async attributeRollDialog(actor, actorData, attribute, label, description, adv, mod, onEnter = "submit") {
const rollOptionTpl = 'systems/bol/templates/dialogs/attribute-roll-dialog.hbs';
const dialogData = {
adv:adv,
mod: mod,
attr:attribute,
careers:actorData.data.features.careers,
boons:actorData.data.features.boons,
flaws:actorData.data.features.flaws
};
const rollOptionContent = await renderTemplate(rollOptionTpl, dialogData);
let d = new Dialog({
title: label,
content: rollOptionContent,
buttons: {
cancel: {
icon: '<i class="fas fa-times"></i>',
label: game.i18n.localize("BOL.ui.cancel"),
callback: () => {
}
},
submit: {
icon: '<i class="fas fa-check"></i>',
label: game.i18n.localize("BOL.ui.submit"),
callback: (html) => {
const attr = html.find('#attr').val();
const adv = html.find('#adv').val();
const mod = html.find('#mod').val();
const careers = html.find('#career').val();
const career = (careers.size >0) ? Math.max(...html.find('#career').val().map(i => parseInt(i))) : 0;
const isMalus = adv < 0;
const dicePool = (isMalus) ? 2 - parseInt(adv) : 2 + parseInt(adv);
const attrValue = eval(`actor.data.data.attributes.${attr}.value`);
const modifiers = parseInt(attrValue) + parseInt(mod) + parseInt(career);
const formula = (isMalus) ? dicePool + "d6kl2 + " + modifiers : dicePool + "d6kh2 + " + modifiers;
let r = new BoLDefaultRoll(label, formula, description);
r.roll(actor);
}
}
},
default: onEnter,
close: () => {}
}, this.options());
return d.render(true);
}
static async aptitudeRollDialog(actor, actorData, aptitude, label, description, adv, mod, onEnter = "submit") {
const rollOptionTpl = 'systems/bol/templates/dialogs/aptitude-roll-dialog.hbs';
const dialogData = {
adv:adv,
mod: mod,
apt:aptitude,
careers:actorData.data.features.careers,
boons:actorData.data.features.boons,
flaws:actorData.data.features.flaws
};
const rollOptionContent = await renderTemplate(rollOptionTpl, dialogData);
let d = new Dialog({
title: label,
content: rollOptionContent,
buttons: {
cancel: {
icon: '<i class="fas fa-times"></i>',
label: game.i18n.localize("BOL.ui.cancel"),
callback: () => {
}
},
submit: {
icon: '<i class="fas fa-check"></i>',
label: game.i18n.localize("BOL.ui.submit"),
callback: (html) => {
const apt = html.find('#apt').val();
const adv = html.find('#adv').val();
const mod = html.find('#mod').val();
const careers = html.find('#career').val();
const career = (careers.size >0) ? Math.max(...html.find('#career').val().map(i => parseInt(i))) : 0;
const isMalus = adv < 0;
const dicePool = (isMalus) ? 2 - parseInt(adv) : 2 + parseInt(adv);
const aptValue = eval(`actor.data.data.aptitudes.${apt}.value`);
const modifiers = parseInt(aptValue) + parseInt(mod) + parseInt(career);
const formula = (isMalus) ? dicePool + "d6kl2 + " + modifiers : dicePool + "d6kh2 + " + modifiers;
let r = new BoLDefaultRoll(label, formula, description);
r.roll(actor);
}
}
},
default: onEnter,
close: () => {}
}, this.options());
return d.render(true);
}
}
export class BoLDefaultRoll {
constructor(label, formula, description){
this._label = label;
this._formula = formula;
this._isSuccess = false;
this._isCritical = false;
this._isFumble = false;
this._description = description;
}
async roll(actor){
const r = new Roll(this._formula);
await r.roll({"async": true});
const activeDice = r.terms[0].results.filter(r => r.active);
const diceTotal = activeDice.map(r => r.result).reduce((a, b) => a + b);
this._isSuccess = (r.total >= 9);
this._isCritical = (diceTotal === 12);
this._isFumble = (diceTotal === 2);
this._buildChatMessage(actor).then(msgFlavor => {
r.toMessage({
user: game.user.id,
flavor: msgFlavor,
speaker: ChatMessage.getSpeaker({actor: actor}),
flags : {msgType : "default"}
});
});
}
_buildChatMessage(actor) {
const rollMessageTpl = 'systems/bol/templates/chat/rolls/default-roll-card.hbs';
const tplData = {
actor : actor,
label : this._label,
isSuccess : this._isSuccess,
isFailure : !this._isSuccess,
isCritical : this._isCritical,
isFumble : this._isFumble,
hasDescription : this._description && this._description.length > 0,
description : this._description
};
return renderTemplate(rollMessageTpl, tplData);
}
}
// export class BoLWeaponRoll {
// constructor(actor, label, formula, isCritical, description){
// this._label = label;
// this._formula = formula;
// this._isCritical = isCritical;
// this._description = description;
// }
//
// _buildChatMessage() {
// const rollMessageTpl = 'systems/bol/templates/chat/rolls/weapon-roll-card.hbs';
// const tplData = {
// label : this._label,
// isCritical : this._isCritical,
// hasDescription : this._description && this._description.length > 0,
// description : this._description
// };
// return renderTemplate(rollMessageTpl, tplData);
// }
// }
// export class BoLSpellRoll {
// constructor(actor, label, formula, isCritical, description){
// this._label = label;
// this._formula = formula;
// this._isCritical = isCritical;
// this._description = description;
// }
//
// _buildChatMessage() {
// const rollMessageTpl = 'systems/bol/templates/chat/rolls/spell-roll-card.hbs';
// const tplData = {
// label : this._label,
// isCritical : this._isCritical,
// hasDescription : this._description && this._description.length > 0,
// description : this._description
// };
// return renderTemplate(rollMessageTpl, tplData);
// }
// }

View File

@ -98,8 +98,7 @@ BOL.featureSubtypes = {
"race" : "BOL.featureSubtypes.race",
"career" : "BOL.featureSubtypes.career",
"boon" : "BOL.featureSubtypes.boon",
"flaw" : "BOL.featureSubtypes.flaw",
"language" : "BOL.featureSubtypes.language"
"flaw" : "BOL.featureSubtypes.flaw"
}
BOL.itemIcons = {

View File

@ -1,202 +1,61 @@
export default function registerHooks() {
// Hooks.on("getChatLogEntryContext", (html, options) => {
// let canApplyDamage = li => li.find("h2.damage").length;
// let canApplyHealing = li => li.find("h2.heal").length;
// options.push(
// {
// name: game.i18n.localize("COF.ui.applyDamage"),
// icon: '<i class="fas fa-user-minus"></i>',
// condition: canApplyDamage,
// callback: li => {
// const dmg = parseInt(li.find(".dice-total").text());
// Hitpoints.applyToTargets(-dmg);
// }
// },
// {
// name: game.i18n.localize("COF.ui.applyDamage"),
// icon: '<i class="fas fa-user-minus"></i>',
// condition: canApplyHealing,
// callback: li => {
// const dmg = parseInt(li.find(".dice-total").text());
// Hitpoints.applyToTargets(-dmg);
// }
// },
// {
// name: game.i18n.localize("COF.ui.applyHalfDamage"),
// icon: '<i class="fas fa-user-shield"></i>',
// condition: canApplyDamage,
// callback: li => {
// const dmg = Math.ceil(parseInt(li.find(".dice-total").text()) / 2);
// Hitpoints.applyToTargets(-dmg);
// }
// },
// {
// name: game.i18n.localize("COF.ui.applyDoubleDamage"),
// icon: '<i class="fas fa-user-injured"></i>',
// condition: canApplyDamage,
// callback: li => {
// const dmg = parseInt(li.find(".dice-total").text())*2;
// Hitpoints.applyToTargets(-dmg);
// }
// },
// {
// name: game.i18n.localize("COF.ui.applyHealing"),
// icon: '<i class="fas fa-user-plus"></i>',
// condition: canApplyDamage,
// callback: li => {
// const dmg = parseInt(li.find(".dice-total").text());
// Hitpoints.applyToTargets(dmg);
// }
// },
// {
// name: game.i18n.localize("COF.ui.applyHealing"),
// icon: '<i class="fas fa-user-plus"></i>',
// condition: canApplyHealing,
// callback: li => {
// const dmg = parseInt(li.find(".dice-total").text());
// Hitpoints.applyToTargets(dmg);
// }
// }
// );
// });
//
// /**
// * Create a macro when dropping an entity on the hotbar
// * Item - open roll dialog for item
// * Actor - open actor sheet
// * Journal - open journal sheet
// */
//
// Hooks.on("hotbarDrop", async (bar, data, slot) => {
// // Create item macro if rollable item - weapon, spell, prayer, trait, or skill
// if (data.type == "Item") {
// let item = data.data;
// let command = `let onlyDamage = false;\nlet customLabel = "";\nlet skillDescription = "";\nlet dmgDescription = "";\n\nif (event) {\n if (event.shiftKey) onlyDamage = true;\n}\n\ngame.cof.macros.rollItemMacro("${item._id}", "${item.name}", "${item.type}", 0, 0, 0, onlyDamage, customLabel, skillDescription, dmgDescription);`;
//
// let macro = game.macros.entities.find(m => (m.name === item.name) && (m.command === command));
// if (!macro) {
// macro = await Macro.create({
// name: item.name,
// type : "script",
// img: item.img,
// command : command
// }, {displaySheet: false})
// }
// game.user.assignHotbarMacro(macro, slot);
// }
// // Create a macro to open the actor sheet of the actor dropped on the hotbar
// else if (data.type == "Actor") {
// let actor = game.actors.get(data.id);
// let command = `game.actors.get("${data.id}").sheet.render(true)`
// let macro = game.macros.entities.find(m => (m.name === actor.name) && (m.command === command));
// if (!macro) {
// macro = await Macro.create({
// name: actor.data.name,
// type: "script",
// img: actor.data.img,
// command: command
// }, {displaySheet: false})
// game.user.assignHotbarMacro(macro, slot);
// }
// }
// // Create a macro to open the journal sheet of the journal dropped on the hotbar
// else if (data.type == "JournalEntry") {
// let journal = game.journal.get(data.id);
// let command = `game.journal.get("${data.id}").sheet.render(true)`
// let macro = game.macros.entities.find(m => (m.name === journal.name) && (m.command === command));
// if (!macro) {
// macro = await Macro.create({
// name: journal.data.name,
// type: "script",
// img: (journal.data.img) ? journal.data.img : "icons/svg/book.svg",
// command: command
// }, {displaySheet: false})
// game.user.assignHotbarMacro(macro, slot);
// }
// }
// return false;
// });
//
//
// /**
// * Intercepte les commandes de chat
// * /stat - Jet de caractéristique
// * /skill stat - Jet de caractéristique
// * /stats - Génère les caractéristiques d'un personnage
// */
//
// Hooks.on("chatMessage", (html, content, msg) => {
// let regExp;
// regExp = /(\S+)/g;
// let commands = content.match(regExp);
// let command = (commands.length>0 && commands[0].split("/").length > 0) ? commands[0].split("/")[1].trim() : null;
// let arg1 = (commands.length > 1) ? commands[1].trim() : null;
// const actor = game.cof.macros.getSpeakersActor();
//
// const validCommands = ["for", "str", "dex", "con", "int", "sag", "wis", "cha", "atc", "melee", "atd", "ranged", "atm", "magic"];
//
// if(command && validCommands.includes(command)) {
// game.cof.macros.rollStatMacro(actor, command, 0, 0, null);
// return false;
// }
// else if(command && command === "skill") {
// if(arg1 && validCommands.includes(arg1)) {
// game.cof.macros.rollStatMacro(actor, arg1, 0, 0, null);
// } else {
// ui.notifications.error("Vous devez préciser la caractéristique à tester, par exemple \"/skill str\".");
// }
// return false;
// }
// else if(command && command === "stats") {
// CharacterGeneration.statsCommand();
// return false;
// }
// });
//
// Hooks.on("renderChatMessage", (message, html, data) => {
// // Affiche ou non les boutons d'application des dommages
// if (game.settings.get("cof", "displayChatDamageButtonsToAll")) {
// html.find(".apply-dmg").click(ev => Hitpoints.onClickChatMessageApplyButton(ev, html, data));
// }
// else {
// if (game.user.isGM){
// html.find(".apply-dmg").click(ev => Hitpoints.onClickChatMessageApplyButton(ev, html, data));
// }
// else {
// html.find(".apply-dmg").each((i, btn) => {
// btn.style.display = "none"
// });
// }
// }
// });
/**
* Create a macro when dropping an entity on the hotbar
* Item - open roll dialog for item
* Actor - open actor sheet
* Journal - open journal sheet
*/
Hooks.on("hotbarDrop", async (bar, data, slot) => {
console.log(data.type);
// Create item macro if rollable item - weapon, spell, prayer, trait, or skill
if (data.type == "Item") {
let item = data.data;
console.log(item);
// let command = `let onlyDamage = false;\nlet customLabel = "";\nlet skillDescription = "";\nlet dmgDescription = "";\n\nif (event) {\n if (event.shiftKey) onlyDamage = true;\n}\n\ngame.cof.macros.rollItemMacro("${item._id}", "${item.name}", "${item.type}", 0, 0, 0, onlyDamage, customLabel, skillDescription, dmgDescription);`;
// Hooks.on("preCreateChatMessage", (data, options, user) => {
// console.debug("preCreateChatMessage");
// // console.log(data,options,user);
// return true;
// });
// Hooks.on("createChatMessage", (message, options, user) => {
// console.debug("createChatMessage");
// // console.log(message,options,user);
// return true;
// });
// Hooks.on("updateChatMessage", (message, update, options, user) => {
// console.debug("updateChatMessage");
// // console.log(message,update,options,user);
// return true;
// });
// Hooks.on("renderItemSheet", (app, html, data) => {
// console.debug("renderItemSheet");
// return true;
// });
// Hooks.on("renderChatLog", (app, html, data) => {
// console.debug("renderChatLog");
// return true;
// });
// Hooks.on('dropCanvasData', function (canvas, dropData) {
// console.debug("dropCanvasData");
// return true;
// });
// let macro = game.macros.entities.find(m => (m.name === item.name) && (m.command === command));
// if (!macro) {
// macro = await Macro.create({
// name: item.name,
// type : "script",
// img: item.img,
// command : command
// }, {displaySheet: false})
// }
// game.user.assignHotbarMacro(macro, slot);
}
// Create a macro to open the actor sheet of the actor dropped on the hotbar
else if (data.type == "Actor") {
let actor = game.actors.get(data.id);
let command = `/*\nPersonnalisez la macro selon vos besoins en suivant les exemples suivants : \ngame.bol.macros.rollMacro('attribute', 'vigor|agility|mind|appeal', adv, mod);\ngame.bol.macros.rollMacro('aptitude', 'init|melee|ranged|def', adv, mod);\n*/\ngame.bol.macros.rollMacro('attribute', 'vigor', 0, 0);`;
let macro = game.macros.entities.find(m => (m.name === actor.name) && (m.command === command));
if (!macro) {
macro = await Macro.create({
name: actor.data.name,
type: "script",
img: "icons/svg/dice-target.svg",
command: command
}, {displaySheet: false})
game.user.assignHotbarMacro(macro, slot);
}
}
// Create a macro to open the journal sheet of the journal dropped on the hotbar
else if (data.type == "JournalEntry") {
let journal = game.journal.get(data.id);
console.log(journal);
let command = `game.journal.get("${data.id}").sheet.render(true)`
let macro = game.macros.entities.find(m => (m.name === journal.name) && (m.command === command));
if (!macro) {
macro = await Macro.create({
name: journal.data.name,
type: "script",
img: (journal.data.img) ? journal.data.img : "icons/svg/book.svg",
command: command
}, {displaySheet: false})
game.user.assignHotbarMacro(macro, slot);
}
}
return false;
});
}

52
module/system/macros.js Normal file
View File

@ -0,0 +1,52 @@
import {BoLRoll} from "../controllers/bol-rolls.js";
export class Macros {
/**
* @name getSpeakersActor
* @description
*
* @returns
*/
static getSpeakersActor = function(){
// Vérifie qu'un seul token est sélectionné
const tokens = canvas.tokens.controlled;
if (tokens.length > 1) {
ui.notifications.warn(game.i18n.localize('BOL.notification.MacroMultipleTokensSelected'));
return null;
}
const speaker = ChatMessage.getSpeaker();
let actor;
// Si un token est sélectionné, le prendre comme acteur cible
if (speaker.token) actor = game.actors.tokens[speaker.token];
// Sinon prendre l'acteur par défaut pour l'utilisateur courrant
if (!actor) actor = game.actors.get(speaker.actor);
return actor;
}
static rollMacro = async function (rollType, key, adv, mod){
const actor = this.getSpeakersActor();
// Several tokens selected
if (actor === null) return;
// No token selected
if (actor === undefined) return ui.notifications.error(game.i18n.localize("BOL.notification.MacroNoTokenSelected"));
const actorData = {};
actorData.data = {
features : actor.buildFeatures()
};
if(rollType === "attribute") {
let attribute = eval(`actor.data.data.attributes.${key}`);
let rollLabel = (attribute.label) ? game.i18n.localize(attribute.label) : null;
let description = actor.name + " - " + game.i18n.localize('BOL.ui.attributeCheck') + " - " + game.i18n.localize(attribute.label) ;
BoLRoll.attributeRollDialog(actor, actorData, attribute, rollLabel, description, adv, mod);
}
else if(rollType === "aptitude") {
let aptitude = eval(`actor.data.data.aptitudes.${key}`);
let rollLabel = (aptitude.label) ? game.i18n.localize(aptitude.label) : null;
let description = actor.name + " - " + game.i18n.localize('BOL.ui.aptitudeCheck') + " - " + game.i18n.localize(aptitude.label) ;
BoLRoll.aptitudeRollDialog(actor, actorData, aptitude, rollLabel, description, adv, mod);
}
}
}

View File

@ -1,4 +1,4 @@
import { BoLUtility } from "../system/bol-utility.js";
import { BoLUtility } from "./bol-utility.js";
export class BoLRollDialog extends Dialog {
@ -47,7 +47,7 @@ export class BoLRollDialog extends Dialog {
activateListeners(html) {
super.activateListeners(html);
var dialog = this;
let dialog = this;
function onLoad() {
}
$(function () { onLoad(); });

View File

@ -16,14 +16,19 @@ export const preloadHandlebarsTemplates = async function () {
// ITEMS
"systems/bol/templates/item/parts/item-header.hbs",
"systems/bol/templates/item/parts/properties/feature-properties.hbs",
"systems/bol/templates/item/parts/properties/equipment-properties.hbs",
"systems/bol/templates/item/parts/properties/protection-properties.hbs",
"systems/bol/templates/item/parts/properties/shield-properties.hbs",
"systems/bol/templates/item/parts/properties/weapon-properties.hbs",
"systems/bol/templates/item/parts/properties/armor-properties.hbs",
"systems/bol/templates/item/parts/properties/melee-properties.hbs",
"systems/bol/templates/item/parts/properties/ranged-properties.hbs",
"systems/bol/templates/item/parts/properties/item-properties.hbs",
"systems/bol/templates/item/parts/properties/item/equipment-properties.hbs",
"systems/bol/templates/item/parts/properties/item/protection-properties.hbs",
"systems/bol/templates/item/parts/properties/item/shield-properties.hbs",
"systems/bol/templates/item/parts/properties/item/weapon-properties.hbs",
"systems/bol/templates/item/parts/properties/item/armor-properties.hbs",
"systems/bol/templates/item/parts/properties/item/melee-properties.hbs",
"systems/bol/templates/item/parts/properties/item/ranged-properties.hbs",
"systems/bol/templates/item/parts/properties/feature/career-properties.hbs",
"systems/bol/templates/item/parts/properties/feature/boon-properties.hbs",
"systems/bol/templates/item/parts/properties/feature/flaw-properties.hbs",
"systems/bol/templates/item/parts/properties/feature/origin-properties.hbs",
"systems/bol/templates/item/parts/properties/feature/race-properties.hbs",
// DIALOGS
"systems/bol/templates/roll/parts/roll-dialog-modifiers.hbs",
"systems/bol/templates/roll/parts/roll-dialog-attribute.hbs"