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:
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -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
|
||||
};
|
||||
|
||||
|
207
module/controllers/bol-rolls.js
Normal file
207
module/controllers/bol-rolls.js
Normal 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);
|
||||
// }
|
||||
// }
|
@ -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 = {
|
||||
|
@ -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
52
module/system/macros.js
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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(); });
|
||||
|
@ -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"
|
||||
|
Reference in New Issue
Block a user