| @@ -54,6 +54,7 @@ | ||||
|   "BOL.ui.roll" : "Utiliser", | ||||
|   "BOL.ui.equipment" : "Équipement", | ||||
|   "BOL.ui.equipmentProperties" : "Propiétés d'équipement", | ||||
|   "BOL.ui.weaponAttack" : "Weapon attack", | ||||
|   "BOL.ui.weaponProperties" : "Propiétés offensives", | ||||
|   "BOL.ui.protectionProperties" : "Protection", | ||||
|   "BOL.ui.magicalProperties" : "Propriétés magiques", | ||||
| @@ -107,6 +108,7 @@ | ||||
|   "BOL.ui.duration": "Duration",  | ||||
|   "BOL.ui.spellkeep": "Maintain", | ||||
|   "BOL.ui.concentrate": "Concentrate", | ||||
|   "BOL.ui.registerInit": "Register Init.", | ||||
|  | ||||
|   "BOL.featureCategory.origins": "Origines", | ||||
|   "BOL.featureCategory.races": "Races", | ||||
|   | ||||
| @@ -54,6 +54,7 @@ | ||||
|   "BOL.ui.roll" : "Utiliser", | ||||
|   "BOL.ui.equipment" : "Équipement", | ||||
|   "BOL.ui.equipmentProperties" : "Propriétés d'équipement", | ||||
|   "BOL.ui.weaponAttack" : "Attaque d'arme", | ||||
|   "BOL.ui.weaponProperties" : "Propriétés offensives", | ||||
|   "BOL.ui.protectionProperties" : "Protection", | ||||
|   "BOL.ui.magicalProperties" : "Propriétés magiques", | ||||
| @@ -108,6 +109,7 @@ | ||||
|   "BOL.ui.duration": "Durée",  | ||||
|   "BOL.ui.spellkeep": "Prolongation", | ||||
|   "BOL.ui.concentrate": "Concentration", | ||||
|   "BOL.ui.registerInit": "Enregistrer comme Init. de combat", | ||||
|    | ||||
|   "BOL.featureCategory.origins": "Origines", | ||||
|   "BOL.featureCategory.races": "Races", | ||||
|   | ||||
| @@ -182,6 +182,7 @@ export class BoLActorSheet extends ActorSheet { | ||||
|     const dataset = element.dataset; | ||||
|     const actorData = this.getData(); | ||||
|     const rollType = dataset.rollType; | ||||
|     const li = $(event.currentTarget).closest(".item"); | ||||
|     switch(rollType) { | ||||
|       case "attribute" : | ||||
|         BoLRoll.attributeCheck(this.actor, actorData, dataset, event); | ||||
| @@ -192,6 +193,12 @@ export class BoLActorSheet extends ActorSheet { | ||||
|       case "weapon":  | ||||
|         BoLRoll.weaponCheck(this.actor, actorData, dataset, event); | ||||
|         break; | ||||
|       case "protection":  | ||||
|         this.actor.rollProtection(li.data("item-id")) | ||||
|         break; | ||||
|       case "damage":  | ||||
|         this.actor.rollWeaponDamage(li.data("item-id")) | ||||
|         break; | ||||
|       default : break; | ||||
|     } | ||||
|   } | ||||
|   | ||||
| @@ -1,3 +1,5 @@ | ||||
| import { BoLDefaultRoll } from "../controllers/bol-rolls.js"; | ||||
|  | ||||
| /** | ||||
|  * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system. | ||||
|  * @extends {Actor} | ||||
| @@ -241,6 +243,16 @@ export class BoLActor extends Actor { | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /*-------------------------------------------- */ | ||||
|   registerInit(initScore, isCritical, isFumble) { | ||||
|     this.update( { 'data.combat.lastinit': initScore, 'data.combat.iscritical': isCritical, 'data.combat.isfumble': isFumble} ) | ||||
|   } | ||||
|  | ||||
|   /*-------------------------------------------- */ | ||||
|   getLastInitData() { | ||||
|     return this.data.data.combat | ||||
|   } | ||||
|  | ||||
|   /*-------------------------------------------- */ | ||||
|   async subHeroPoints( nb) { | ||||
|     let newHeroP = this.data.data.resources.hero.value - nb; | ||||
| @@ -270,6 +282,27 @@ export class BoLActor extends Actor { | ||||
|     return (formula == "") ? 0 :formula; | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   rollProtection( itemId) { | ||||
|     let armor = this.data.items.get( itemId ) | ||||
|     if ( armor ) { | ||||
|       let armorFormula = armor.data.data.properties.soak.formula;         | ||||
|       let rollArmor = new Roll(armorFormula) | ||||
|       rollArmor.roll( {async: false} ).toMessage(); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   rollWeaponDamage( itemId) { | ||||
|     let weapon = this.data.items.get(itemId ) | ||||
|     if ( weapon ) { | ||||
|       console.log("WE", weapon) | ||||
|       let r = new BoLDefaultRoll( { id: randomID(16), isSuccess: true, mode: "weapon", weapon: weapon, actor: this} ) | ||||
|       r.setSuccess(true) | ||||
|       r.processResult() | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   toggleEquipItem(item) { | ||||
|     const equipable = item.data.data.properties.equipable; | ||||
|   | ||||
| @@ -8,9 +8,9 @@ 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 { Macros } from "./system/macros.js"; | ||||
| import { BoLUtility } from "./system/bol-utility.js"; | ||||
| import { BoLCombatManager } from "./system/bol-combat.js"; | ||||
|  | ||||
| Hooks.once('init', async function () { | ||||
|  | ||||
| @@ -33,12 +33,13 @@ Hooks.once('init', async function () { | ||||
|    */ | ||||
|   CONFIG.Combat.initiative = { | ||||
|     formula: "2d6+@attributes.mind.value+@aptitudes.init.value", | ||||
|     decimals: 0 | ||||
|     decimals: 3 | ||||
|   }; | ||||
|   0 | ||||
|    | ||||
|   // Define custom Entity classes | ||||
|   CONFIG.Actor.documentClass = BoLActor; | ||||
|   CONFIG.Item.documentClass = BoLItem; | ||||
|   CONFIG.Combat.documentClass = BoLCombatManager; | ||||
|  | ||||
|   // Register sheet application classes | ||||
|   Actors.unregisterSheet("core", ActorSheet); | ||||
|   | ||||
| @@ -1,10 +1,20 @@ | ||||
| import { BoLUtility } from "../system/bol-utility.js"; | ||||
|  | ||||
| const __adv2dice = { ["1B"]: 3, ["2B"]: 4, ["2"]: 2, ["1M"]: 3, ["2M"]: 4} | ||||
| const _apt2attr = {init: "mind", melee: "agility", ranged: "agility", def: "vigor"} | ||||
|  | ||||
| export class BoLRoll { | ||||
|   static options() { | ||||
|     return { classes: ["bol", "dialog"] }; | ||||
|   } | ||||
|  | ||||
|   static convertToAdv( adv) { | ||||
|     if (adv == 0) return "2" | ||||
|     return Math.abs(adv) + (adv < 0)?'M':'B'; | ||||
|   } | ||||
|   static getDefaultAttribute( key ) { | ||||
|     return _apt2attr[key] | ||||
|   } | ||||
|   static attributeCheck(actor, actorData, dataset, event) { | ||||
|     // const elt = $(event.currentTarget)[0]; | ||||
|     // let key = elt.attributes["data-rolling"].value; | ||||
| @@ -13,7 +23,17 @@ export class BoLRoll { | ||||
|     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); | ||||
|     return this.displayRollDialog( | ||||
|       { | ||||
|         mode: "attribute",  | ||||
|         actor: actor, | ||||
|         actorData: actorData, | ||||
|         attribute: attribute, | ||||
|         label: label, | ||||
|         description: description, | ||||
|         adv: this.convertToAdv(adv), | ||||
|         mod: 0 | ||||
|       }); | ||||
|   } | ||||
|  | ||||
|   static aptitudeCheck(actor, actorData, dataset, event) { | ||||
| @@ -21,10 +41,25 @@ export class BoLRoll { | ||||
|     // let key = elt.attributes["data-rolling"].value; | ||||
|     const key = dataset.key; | ||||
|     const adv = dataset.adv; | ||||
|  | ||||
|     let aptitude = eval(`actor.data.data.aptitudes.${key}`); | ||||
|     let attrKey = this.getDefaultAttribute(key) | ||||
|     let attribute = eval(`actor.data.data.attributes.${attrKey}`); | ||||
|  | ||||
|     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); | ||||
|     return this.displayRollDialog( | ||||
|       { | ||||
|         mode: "aptitude",  | ||||
|         actor: actor, | ||||
|         actorData: actorData, | ||||
|         attribute: attribute, | ||||
|         aptitude: aptitude, | ||||
|         label: label, | ||||
|         description: description, | ||||
|         adv: this.convertToAdv(adv), | ||||
|         mod: 0 | ||||
|       }); | ||||
|   } | ||||
|  | ||||
|   static weaponCheck(actor, actorData, dataset, event) { | ||||
| @@ -39,102 +74,57 @@ export class BoLRoll { | ||||
|     } | ||||
|     let weaponData = weapon.data.data; | ||||
|     let attackDef = { | ||||
|       id: randomID(16), | ||||
|       attacker: actor, | ||||
|       attackerData: actorData, | ||||
|       mode: "weapon", | ||||
|       actor: actor, | ||||
|       actorData: actorData, | ||||
|       weapon: weapon, | ||||
|       mod: 0, | ||||
|       target: target, | ||||
|       defender: (target) ? game.actors.get(target.data.actorId) : undefined, | ||||
|       adv: dataset.adv || 0, | ||||
|       attribute: eval(`actor.data.data.attributes.${weaponData.properties.attackAttribute}`), | ||||
|       aptitude: eval(`actor.data.data.aptitudes.${weaponData.properties.attackAptitude}`), | ||||
|       label: (weapon.name) ? weapon.name : game.i18n.localize('BOL.ui.noWeaponName'), | ||||
|       description: actor.name + " - " + game.i18n.localize('BOL.ui.weaponAttack'), | ||||
|       adv: "2", | ||||
|  | ||||
|     } | ||||
|     console.debug("WEAPON!", attackDef, weaponData); | ||||
|     return this.weaponRollDialog(attackDef); | ||||
|     return this.displayRollDialog(attackDef); | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   /* 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.features.careers, | ||||
|       boons: actorData.features.boons, | ||||
|       flaws: actorData.features.flaws | ||||
|     }; | ||||
|   static async displayRollDialog(rollData, onEnter = "submit") { | ||||
|  | ||||
|     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(); | ||||
|             let careers = html.find('#career').val(); | ||||
|             const career = (!careers || careers.length == 0) ? 0 : Math.max(...careers.map(i => parseInt(i))); | ||||
|             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); | ||||
|           } | ||||
|     const rollOptionTpl = `systems/bol/templates/dialogs/${rollData.mode}-roll-dialog.hbs` | ||||
|     rollData.careers = rollData.actorData.features.careers | ||||
|     rollData.boons = rollData.actorData.features.boons | ||||
|     rollData.flaws = rollData.actorData.features.flaws | ||||
|     rollData.defence = 0 | ||||
|     rollData.mod = 0 | ||||
|     rollData.id = randomID(16) | ||||
|  | ||||
|     // Weapon mode specific management | ||||
|     if (rollData.mode == "weapon") { | ||||
|       if (rollData.defender) { // If target is selected | ||||
|         rollData.defence = rollData.defender.defenseValue, | ||||
|         rollData.shieldBlock = 'none' | ||||
|         let shields = rollData.defender.shields | ||||
|         for (let shield of shields) { | ||||
|           rollData.shieldBlock = (shield.data.properties.blocking.blockingAll) ? 'blockall' : 'blockone'; | ||||
|           rollData.shieldAttackMalus = (shield.data.properties.blocking.malus) ? shield.data.properties.blocking.malus : 1; | ||||
|           rollData.applyShieldMalus = false | ||||
|         } | ||||
|       }, | ||||
|       default: onEnter, | ||||
|       close: () => { } | ||||
|     }, this.options()); | ||||
|     return d.render(true); | ||||
|   } | ||||
|  | ||||
|   static async weaponRollDialog(attackDef) { | ||||
|     const rollOptionTpl = 'systems/bol/templates/dialogs/weapon-roll-dialog.hbs'; | ||||
|     const dialogData = { | ||||
|       attr: attackDef.attribute, | ||||
|       adv: attackDef.adv, | ||||
|       mod: attackDef.mod, | ||||
|       apt: attackDef.aptitude, | ||||
|       weapon: attackDef.weapon, | ||||
|       attackId: attackDef.id, | ||||
|       careers: attackDef.attackerData.features.careers, | ||||
|       boons: attackDef.attackerData.features.boons, | ||||
|       flaws: attackDef.attackerData.features.flaws, | ||||
|       defence: 0 | ||||
|     }; | ||||
|      | ||||
|     if (attackDef.defender) { | ||||
|       dialogData.defence = attackDef.defender.defenseValue, | ||||
|         dialogData.shieldBlock = 'none' | ||||
|       let shields = attackDef.defender.shields | ||||
|       for (let shield of shields) { | ||||
|         dialogData.shieldBlock = (shield.data.properties.blocking.blockingAll) ? 'blockall' : 'blockone'; | ||||
|         dialogData.shieldAttackMalus = (shield.data.properties.blocking.malus) ? shield.data.properties.blocking.malus : 1; | ||||
|         dialogData.applyShieldMalus = false | ||||
|       } | ||||
|     } | ||||
|     const rollOptionContent = await renderTemplate(rollOptionTpl, dialogData); | ||||
|  | ||||
|     console.log("ROL1", rollData) | ||||
|  | ||||
|     const rollOptionContent = await renderTemplate(rollOptionTpl, rollData); | ||||
|     let d = new Dialog({ | ||||
|       title: attackDef.label, | ||||
|       title: rollData.label, | ||||
|       content: rollOptionContent, | ||||
|       rollData: rollData, | ||||
|       buttons: { | ||||
|         cancel: { | ||||
|           icon: '<i class="fas fa-times"></i>', | ||||
| @@ -146,74 +136,35 @@ export class BoLRoll { | ||||
|           icon: '<i class="fas fa-check"></i>', | ||||
|           label: game.i18n.localize("BOL.ui.submit"), | ||||
|           callback: (html) => { | ||||
|             const attr = html.find('#attr').val(); | ||||
|             const apt = html.find('#apt').val(); | ||||
|             const adv = html.find('#adv').val(); | ||||
|             const mod = html.find('#mod').val() || 0; | ||||
|             rollData.attrKey = html.find('#attr').val(); | ||||
|             rollData.aptKey = html.find('#apt').val(); | ||||
|             rollData.adv = $("input[name='adv']:checked").val() || "2"; | ||||
|             //rollData.adv = html.find('#adv').val() || 0; | ||||
|             rollData.mod = html.find('#mod').val() || 0; | ||||
|             let careers = html.find('#career').val(); | ||||
|             rollData.career = (!careers || careers.length == 0) ? 0 : Math.max(...careers.map(i => parseInt(i))); | ||||
|             rollData.registerInit = (rollData.aptKey == 'init') ?  $('#register-init').is(":checked") : false; | ||||
|              | ||||
|             let shieldMalus = 0; | ||||
|             const applyShieldMalus = html.find('#applyShieldMalus').val() || false; | ||||
|             if (applyShieldMalus || dialogData.shieldBlock == 'blockall') { | ||||
|               shieldMalus = dialogData.shieldAttackMalus; | ||||
|             if ( rollData.mode == "weapon") { | ||||
|               const applyShieldMalus = html.find('#applyShieldMalus').val() || false; | ||||
|               if (applyShieldMalus || rollData.shieldBlock == 'blockall') { | ||||
|                 shieldMalus = rollData.shieldAttackMalus; | ||||
|               } | ||||
|             } | ||||
|  | ||||
|             let careers = html.find('#career').val(); | ||||
|             const career = (!careers || careers.length == 0) ? 0 : Math.max(...careers.map(i => parseInt(i))); | ||||
|             const isMalus = adv < 0; | ||||
|             const dicePool = (isMalus) ? 2 - parseInt(adv) : 2 + parseInt(adv); | ||||
|             const attrValue = eval(`attackDef.attacker.data.data.attributes.${attr}.value`); | ||||
|             const aptValue = eval(`attackDef.attacker.data.data.aptitudes.${apt}.value`); | ||||
|             const modifiers = parseInt(attrValue) + parseInt(aptValue) + parseInt(mod) + parseInt(career) - dialogData.defence - shieldMalus; | ||||
|             const formula = (isMalus) ? dicePool + "d6kl2 + " + modifiers : dicePool + "d6kh2 + " + modifiers; | ||||
|             attackDef.formula = formula; | ||||
|             let r = new BoLAttackRoll(attackDef); | ||||
|             r.roll(); | ||||
|           } | ||||
|         } | ||||
|       }, | ||||
|       default: 'submit', | ||||
|       close: () => { } | ||||
|     }, this.options()); | ||||
|     return d.render(true); | ||||
|   } | ||||
|             const isMalus = rollData.adv.includes('M'); | ||||
|             const dicePool = __adv2dice[rollData.adv] | ||||
|             //// const dicePool = (isMalus) ? 2 - parseInt(rollData.adv) : 2 + parseInt(rollData.adv); | ||||
|             const attrValue = (rollData.attrKey) && eval(`rollData.actor.data.data.attributes.${rollData.attrKey}.value`) || 0; | ||||
|             const aptValue = (rollData.aptKey) && eval(`rollData.actor.data.data.aptitudes.${rollData.aptKey}.value`) || 0 | ||||
|              | ||||
|   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.features.careers, | ||||
|       boons: actorData.features.boons, | ||||
|       flaws: actorData.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(); | ||||
|             let careers = html.find('#career').val(); | ||||
|             const career = (!careers || careers.length == 0) ? 0 : Math.max(...careers.map(i => parseInt(i))); | ||||
|             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 modifiers = parseInt(attrValue) + parseInt(aptValue) + parseInt(rollData.mod) + parseInt(rollData.career) - rollData.defence - shieldMalus; | ||||
|             const formula = (isMalus) ? dicePool + "d6kl2 + " + modifiers : dicePool + "d6kh2 + " + modifiers; | ||||
|             let r = new BoLDefaultRoll(label, formula, description); | ||||
|             r.roll(actor); | ||||
|             rollData.formula = formula; | ||||
|  | ||||
|             let r = new BoLDefaultRoll(rollData); | ||||
|             r.roll(); | ||||
|           } | ||||
|         } | ||||
|       }, | ||||
| @@ -225,192 +176,96 @@ export class BoLRoll { | ||||
| } | ||||
|  | ||||
| export class BoLDefaultRoll { | ||||
|   constructor(label, formula, description, isWeapon = false) { | ||||
|     this._label = label; | ||||
|     this._formula = formula; | ||||
|     this._isSuccess = false; | ||||
|     this._isCritical = false; | ||||
|     this._isFumble = false; | ||||
|     this._isWeapon = isWeapon; | ||||
|     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" } | ||||
|       }); | ||||
|     }); | ||||
|     if (this._isSuccess && this._isWeapon) { | ||||
|  | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   _buildChatMessage(actor) { | ||||
|     const rollMessageTpl = 'systems/bol/templates/chat/rolls/default-roll-card.hbs'; | ||||
|     const tplData = { | ||||
|       actor: actor, | ||||
|       label: this._label, | ||||
|       reroll: actor.heroReroll(), | ||||
|       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 BoLAttackRoll { | ||||
|   constructor(attackDef) { | ||||
|     this.attackDef = attackDef; | ||||
|     this._isSuccess = false; | ||||
|     this._isCritical = false; | ||||
|     this._isFumble = false; | ||||
|   constructor(rollData) { | ||||
|     BoLUtility.storeRoll(rollData); | ||||
|     this.rollData = rollData | ||||
|     this.rollData.isSuccess = false; | ||||
|     this.rollData.isCritical = false; | ||||
|     this.rollData.isFumble = false; | ||||
|   } | ||||
|  | ||||
|   async roll() { | ||||
|     console.log("Attack def",this.attackDef.formula ) | ||||
|     const r = new Roll(this.attackDef.formula); | ||||
|     console.log("ROLL", this.rollData) | ||||
|  | ||||
|     const r = new Roll(this.rollData.formula); | ||||
|     await r.roll({ "async": false }); | ||||
|     await BoLUtility.showDiceSoNice(r); | ||||
|     //await BoLUtility.showDiceSoNice(r); | ||||
|     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(this.attackDef.attacker).then(msgFlavor => { | ||||
|     this.rollData.isSuccess = (r.total >= 9); | ||||
|     this.rollData.isCritical = (diceTotal === 12); | ||||
|     this.rollData.isFumble = (diceTotal === 2); | ||||
|     this.rollData.isFailure = !this.rollData.isSuccess | ||||
|     this.rollData.reroll =  this.rollData.actor.heroReroll() | ||||
|  | ||||
|     if (this.rollData.registerInit) { | ||||
|       this.rollData.actor.registerInit( r.total, this.rollData.isCritical); | ||||
|     } | ||||
|  | ||||
|     this._buildChatMessage(this.rollData).then(msgFlavor => { | ||||
|       r.toMessage({ | ||||
|         user: game.user.id, | ||||
|         flavor: msgFlavor, | ||||
|         speaker: ChatMessage.getSpeaker({ actor: this.attackDef.attacker }), | ||||
|         speaker: ChatMessage.getSpeaker({ actor: this.rollData.actor }), | ||||
|         flags: { msgType: "default" } | ||||
|       }).then( this.processResult() ); | ||||
|       }).then(this.processResult()); | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   async processDefense() { | ||||
|     if (this._isCritical) { | ||||
|     if (this.rollData.isCritical) { | ||||
|       ChatMessage.create({ | ||||
|         alias: this.attackDef.attacker.name, | ||||
|         whisper: BoLUtility.getWhisperRecipientsAndGMs(this.attackDef.attacker.name), | ||||
|         content: await renderTemplate('systems/bol/templates/chat/rolls/attack-heroic-card.hbs', { | ||||
|           attackId: attackDef.id, | ||||
|           attacker: attackDef.attacker, | ||||
|           defender: attackDef.defender, | ||||
|           defenderWeapons: defenderWeapons, | ||||
|           damageTotal: attackDef.damageRoll.total | ||||
|         }) | ||||
|         alias: this.rollData.actor.name, | ||||
|         whisper: BoLUtility.getWhisperRecipientsAndGMs(this.rollData.actor.name), | ||||
|         content: await renderTemplate('systems/bol/templates/chat/rolls/attack-heroic-card.hbs', this.rollData ) | ||||
|       }) | ||||
|     } else { | ||||
|       BoLUtility.sendAttackSuccess( this.attackDef); | ||||
|       BoLUtility.sendAttackSuccess(this.rollData); | ||||
|     } | ||||
|   } | ||||
|    | ||||
|   async processResult( ) { | ||||
|     if (this._isSuccess) { | ||||
|       let attrDamage = this.attackDef.weapon.data.data.properties.damageAttribute; | ||||
|       let weaponFormula = BoLUtility.getDamageFormula(this.attackDef.weapon.data.data.properties.damage,  | ||||
|         this.attackDef.weapon.data.data.properties.damageModifiers, | ||||
|         this.attackDef.weapon.data.data.properties.damageMultiplier) | ||||
|       let damageFormula = weaponFormula + "+" + this.attackDef.attacker.data.data.attributes[attrDamage].value; | ||||
|       console.log("Formula", damageFormula) | ||||
|       this.damageRoll = new Roll(damageFormula); | ||||
|       await this.damageRoll.roll({ "async": false }); | ||||
|       await BoLUtility.showDiceSoNice(this.damageRoll); | ||||
|       // Update attackDef object | ||||
|       this.attackDef.damageFormula = damageFormula; | ||||
|       this.attackDef.damageRoll = this.damageRoll; | ||||
|   setSuccess( flag) { | ||||
|     this.rollData.isSuccess = flag | ||||
|   } | ||||
|  | ||||
|       this._buildDamageChatMessage(this.attackDef.attacker, this.attackDef.weapon, this.damageRoll.total).then(msgFlavor => { | ||||
|         this.damageRoll.toMessage({ | ||||
|   async processResult() { | ||||
|     if ( this.rollData.mode != "weapon") { // Only specific process in Weapon mode | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     if (this.rollData.isSuccess) { | ||||
|       let attrDamage = this.rollData.weapon.data.data.properties.damageAttribute; | ||||
|       let weaponFormula = BoLUtility.getDamageFormula(this.rollData.weapon.data.data.properties.damage, | ||||
|         this.rollData.weapon.data.data.properties.damageModifiers, | ||||
|         this.rollData.weapon.data.data.properties.damageMultiplier) | ||||
|       let damageFormula = weaponFormula + ((attrDamage) ? "+" + this.rollData.actor.data.data.attributes[attrDamage].value : "+0"); | ||||
|  | ||||
|       //console.log("Formula", weaponFormula, damageFormula, this.rollData.weapon.data.data.properties.damage) | ||||
|       this.rollData.damageRoll = new Roll(damageFormula); | ||||
|       await this.rollData.damageRoll.roll({ "async": false }); | ||||
|       await BoLUtility.showDiceSoNice(this.rollData.damageRoll); | ||||
|       // Update rollData object | ||||
|       this.rollData.damageFormula = damageFormula; | ||||
|  | ||||
|       this._buildDamageChatMessage( this.rollData ).then(msgFlavor => { | ||||
|         this.rollData.damageRoll.toMessage({ | ||||
|           user: game.user.id, | ||||
|           flavor: msgFlavor, | ||||
|           speaker: ChatMessage.getSpeaker({ actor: this.attackDef.attacker }), | ||||
|           speaker: ChatMessage.getSpeaker({ actor: this.rollData.actor }), | ||||
|           flags: { msgType: "default" } | ||||
|         }).then( this.processDefense() ); | ||||
|         }).then(this.processDefense()); | ||||
|       }); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   _buildDamageChatMessage(actor, weapon, total) { | ||||
|         const rollMessageTpl = 'systems/bol/templates/chat/rolls/damage-roll-card.hbs'; | ||||
|         const tplData = { | ||||
|           actor: actor, | ||||
|           label: this._label, | ||||
|           weapon: weapon, | ||||
|           damage: total, | ||||
|           isCritical: this._isCritical, | ||||
|         }; | ||||
|         return renderTemplate(rollMessageTpl, tplData); | ||||
|       } | ||||
|   _buildDamageChatMessage(rollData) { | ||||
|     const rollMessageTpl = 'systems/bol/templates/chat/rolls/damage-roll-card.hbs'; | ||||
|     return renderTemplate(rollMessageTpl, rollData); | ||||
|   } | ||||
|  | ||||
|   _buildChatMessage(actor) { | ||||
|         const rollMessageTpl = 'systems/bol/templates/chat/rolls/default-roll-card.hbs'; | ||||
|         const tplData = { | ||||
|           actor: actor, | ||||
|           label: this._label, | ||||
|           reroll: actor.heroReroll(), | ||||
|           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); | ||||
|       } | ||||
|   _buildChatMessage(rollData) { | ||||
|     const rollMessageTpl = 'systems/bol/templates/chat/rolls/default-roll-card.hbs'; | ||||
|     return renderTemplate(rollMessageTpl, rollData); | ||||
|   } | ||||
|  | ||||
| } | ||||
| // 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); | ||||
| //     } | ||||
| // } | ||||
|   | ||||
| @@ -1,5 +1,17 @@ | ||||
| /* | ||||
| Init order =  | ||||
|   10 - Legendary | ||||
|   9 - Heroic | ||||
|   8 - Success | ||||
|   7 - Rivals/adversary | ||||
|   6 - Coriaces/tough | ||||
|   5 - Failure | ||||
|   4 - Pietaille | ||||
|   3 - Echec critique | ||||
| */ | ||||
|  | ||||
| export class RdDCombatManager extends Combat { | ||||
|  | ||||
| export class BoLCombatManager extends Combat { | ||||
|  | ||||
|   /************************************************************************************/ | ||||
|   async rollInitiative(ids, formula = undefined, messageOptions = {}) { | ||||
| @@ -9,13 +21,33 @@ export class RdDCombatManager extends Combat { | ||||
|     const currentId = this.combatant._id; | ||||
|  | ||||
|     // calculate initiative | ||||
|     if ( game.combat.current.round == 1) { | ||||
|       for (let cId = 0; cId < ids.length; cId++) { | ||||
|         const combatant = this.combatants.get(ids[cId]); | ||||
|         // TODO  | ||||
|         console.log("TODO : Compute init for actor"); | ||||
|     for (let cId = 0; cId < ids.length; cId++) { | ||||
|       const combatant = this.combatants.get(ids[cId]); | ||||
|       let fvttInit = 5 | ||||
|       if (combatant.actor.type == 'character') { | ||||
|         let initData = combatant.actor.getLastInitData(); | ||||
|         if (initData.isLegendary) { | ||||
|           fvttInit = 10 | ||||
|         } else if (initData.isCritical) { | ||||
|           fvttInit = 9 | ||||
|         } else if (initData.lastinit >= 9) { | ||||
|           fvttInit = 8 | ||||
|         } else if (initData.isFumble) { | ||||
|           fvttInit = 3 | ||||
|         } | ||||
|       } else { | ||||
|         fvttInit = 4 // Pietaille par defaut | ||||
|         if ( combatant.actor.getSubtype == 'adversary') { | ||||
|           fvttInit = 7 | ||||
|         }  | ||||
|         if ( combatant.actor.getSubtype == 'tough') { | ||||
|           fvttInit = 6 | ||||
|         }  | ||||
|       } | ||||
|       fvttInit += (cId / 100) | ||||
|       await this.updateEmbeddedDocuments("Combatant", [{ _id: ids[cId], initiative: fvttInit }]); | ||||
|     } | ||||
|     console.log("TODO : Compute init for actor"); | ||||
|   } | ||||
|    | ||||
| } | ||||
|    | ||||
|   | ||||
| @@ -1,11 +1,11 @@ | ||||
| import { BoLDefaultRoll } from "../controllers/bol-rolls.js"; | ||||
|  | ||||
| export class BoLUtility { | ||||
|  | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static async init() { | ||||
|     this.attackStore = {}; | ||||
|     Hooks.on('renderChatLog', (log, html, data) => BoLUtility.chatListeners(html)); | ||||
|     this.attackStore = {} | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
| @@ -25,6 +25,16 @@ export class BoLUtility { | ||||
|     return it; | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static storeRoll(roll) { | ||||
|     this.lastRoll = roll | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static getLastRoll() { | ||||
|     return this.lastRoll | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static createDirectOptionList(min, max) { | ||||
|     let options = {}; | ||||
| @@ -123,7 +133,11 @@ export class BoLUtility { | ||||
|  | ||||
|     html.on("click", '.hero-reroll', event => { | ||||
|       event.preventDefault(); | ||||
|       ui.notifications.warn("Not implemented up to now"); | ||||
|  | ||||
|       let rollData = BoLUtility.getLastRoll() | ||||
|       rollData.actor.subHeroPoints(1) | ||||
|       let r = new BoLDefaultRoll( rollData ) | ||||
|       r.roll(); | ||||
|     } ); | ||||
|  | ||||
|     html.on("click", '.damage-handling', event => {       | ||||
|   | ||||
| @@ -114,4 +114,5 @@ export const registerHandlebarsHelpers = function () { | ||||
|  | ||||
|      | ||||
|  | ||||
|  | ||||
| } | ||||
| @@ -30,9 +30,15 @@ export const preloadHandlebarsTemplates = async function () { | ||||
|         "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" | ||||
|         "systems/bol/templates/roll/parts/roll-dialog-attribute.hbs", | ||||
|         "systems/bol/templates/dialogs/aptitude-roll-part.hbs", | ||||
|         "systems/bol/templates/dialogs/attribute-roll-part.hbs", | ||||
|         "systems/bol/templates/dialogs/mod-roll-part.hbs", | ||||
|         "systems/bol/templates/dialogs/adv-roll-part.hbs", | ||||
|         "systems/bol/templates/dialogs/career-roll-part.hbs", | ||||
|     ]; | ||||
|  | ||||
|     // Load the template parts | ||||
|   | ||||
| @@ -7,8 +7,8 @@ | ||||
|   "url": "https://github.com/ZigmundKreud/bol", | ||||
|   "license": "LICENSE.txt", | ||||
|   "flags": {}, | ||||
|   "version": "0.8.9.6", | ||||
|   "templateVersion": 14, | ||||
|   "version": "0.8.9.9", | ||||
|   "templateVersion": 16, | ||||
|   "minimumCoreVersion": "0.8.6", | ||||
|   "compatibleCoreVersion": "9", | ||||
|   "scripts": [], | ||||
|   | ||||
| @@ -11,6 +11,12 @@ | ||||
|           "notes": "", | ||||
|           "languages": [] | ||||
|         }, | ||||
|         "combat": { | ||||
|           "lastinit": 0, | ||||
|           "iscritical": false, | ||||
|           "isfumble": false, | ||||
|           "islegendary": false           | ||||
|         }, | ||||
|         "prot": { | ||||
|           "key": "prot", | ||||
|           "label": "BOL.aptitudes.prot", | ||||
|   | ||||
							
								
								
									
										193
									
								
								template2.json
									
									
									
									
									
								
							
							
						
						
									
										193
									
								
								template2.json
									
									
									
									
									
								
							| @@ -1,193 +0,0 @@ | ||||
| { | ||||
|   "Actor": { | ||||
|     "types": [ | ||||
|       "character", | ||||
|       "encounter" | ||||
|     ], | ||||
|     "templates": { | ||||
|       "base": { | ||||
|         "details": { | ||||
|           "biography": "", | ||||
|           "notes": "", | ||||
|           "languages": [] | ||||
|         }, | ||||
|         "prot": { | ||||
|           "key": "prot", | ||||
|           "label": "BOL.aptitudes.prot", | ||||
|           "base": 0, | ||||
|           "value": 0, | ||||
|           "bonus": 0 | ||||
|         }, | ||||
|         "attributes": { | ||||
|           "vigor": { | ||||
|             "key": "vigor", | ||||
|             "label": "BOL.attributes.vigor", | ||||
|             "base": 0, | ||||
|             "value": 0, | ||||
|             "min": -1, | ||||
|             "max": 5, | ||||
|             "bonus": 0 | ||||
|           }, | ||||
|           "agility": { | ||||
|             "key": "agility", | ||||
|             "label": "BOL.attributes.agility", | ||||
|             "base": 0, | ||||
|             "value": 0, | ||||
|             "min": -1, | ||||
|             "max": 5, | ||||
|             "bonus": 0 | ||||
|           }, | ||||
|           "mind": { | ||||
|             "key": "mind", | ||||
|             "label": "BOL.attributes.mind", | ||||
|             "base": 0, | ||||
|             "value": 0, | ||||
|             "min": -1, | ||||
|             "max": 5, | ||||
|             "bonus": 0 | ||||
|           }, | ||||
|           "appeal": { | ||||
|             "key": "appeal", | ||||
|             "label": "BOL.attributes.appeal", | ||||
|             "base": 0, | ||||
|             "value": 0, | ||||
|             "bonus": 0 | ||||
|           } | ||||
|         }, | ||||
|         "aptitudes": { | ||||
|           "init": { | ||||
|             "key": "init", | ||||
|             "label": "BOL.aptitudes.init", | ||||
|             "base": 0, | ||||
|             "value": 0, | ||||
|             "bonus": 0 | ||||
|           }, | ||||
|           "melee": { | ||||
|             "key": "melee", | ||||
|             "label": "BOL.aptitudes.melee", | ||||
|             "base": 0, | ||||
|             "value": 0, | ||||
|             "bonus": 0 | ||||
|           }, | ||||
|           "ranged": { | ||||
|             "key": "ranged", | ||||
|             "label": "BOL.aptitudes.ranged", | ||||
|             "base": 0, | ||||
|             "value": 0, | ||||
|             "bonus": 0 | ||||
|           }, | ||||
|           "def": { | ||||
|             "key": "def", | ||||
|             "label": "BOL.aptitudes.def", | ||||
|             "base": 0, | ||||
|             "value": 0, | ||||
|             "bonus": 0 | ||||
|           } | ||||
|         }, | ||||
|         "resources": { | ||||
|           "hp": { | ||||
|             "key": "hp", | ||||
|             "label": "BOL.resources.hp", | ||||
|             "base": 0, | ||||
|             "value": 0, | ||||
|             "bonus": 0, | ||||
|             "max": 0 | ||||
|           }, | ||||
|           "hero": { | ||||
|             "key": "hero", | ||||
|             "label": "BOL.resources.hero", | ||||
|             "value": 5, | ||||
|             "max": 5 | ||||
|           }, | ||||
|           "faith": { | ||||
|             "key": "faith", | ||||
|             "label": "BOL.resources.faith", | ||||
|             "value": 0, | ||||
|             "max": 0 | ||||
|           }, | ||||
|           "power": { | ||||
|             "key": "power", | ||||
|             "label": "BOL.resources.power", | ||||
|             "value": 0, | ||||
|             "max": 0 | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "character": { | ||||
|       "templates": [ "base" ], | ||||
|       "type": "npc", | ||||
|       "villainy": false, | ||||
|       "xp": { | ||||
|         "key": "xp", | ||||
|         "label": "BOL.traits.xp", | ||||
|         "total": 0, | ||||
|         "spent": 0 | ||||
|       }, | ||||
|       "creation": { | ||||
|         "key": "creation", | ||||
|         "label": "BOL.resources.creation", | ||||
|         "value": 0, | ||||
|         "max": 0 | ||||
|       } | ||||
|     }, | ||||
|     "encounter": { | ||||
|       "templates": [ "base" ], | ||||
|       "type": "tough", | ||||
|       "size": "", | ||||
|       "environment": "" | ||||
|     } | ||||
|   }, | ||||
|   "Item": { | ||||
|     "types": [ | ||||
|       "item", | ||||
|       "feature" | ||||
|     ], | ||||
|     "templates": { | ||||
|       "base": { | ||||
|         "category": null, | ||||
|         "subtype": "default", | ||||
|         "description": "", | ||||
|         "properties": {} | ||||
|       }, | ||||
|       "equipment": { | ||||
|         "quantity": 1, | ||||
|         "weight": 0, | ||||
|         "price": 0, | ||||
|         "worn": false, | ||||
|         "properties": { | ||||
|           "ranged": false, | ||||
|           "melee": false, | ||||
|           "spell": false, | ||||
|           "protection": false, | ||||
|           "weapon": false, | ||||
|           "armor": false, | ||||
|           "helm": false, | ||||
|           "shield": false, | ||||
|           "equipable": false, | ||||
|           "consumable": false, | ||||
|           "magical": false, | ||||
|           "2H": false, | ||||
|           "reloadable": false, | ||||
|           "bow": false, | ||||
|           "crossbow": false, | ||||
|           "throwing": false | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "item": { | ||||
|       "templates": [ | ||||
|         "base", | ||||
|         "equipment" | ||||
|       ] | ||||
|     }, | ||||
|     "feature": { | ||||
|       "rank": 0, | ||||
|       "templates": [ | ||||
|         "base" | ||||
|       ], | ||||
|       "properties": {} | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| @@ -11,9 +11,9 @@ | ||||
|                 <li class="item flexrow" data-item-id="{{item._id}}"> | ||||
|                     <div class="item-image" ><img src="{{item.img}}" title="{{item.name}}"/></div> | ||||
|                     <h4 class="item-name flex2">{{#if ../weapon}}<a class="rollable" data-roll-type="weapon">{{/if}}{{item.name}}{{#if ../weapon}}</a>{{/if}}</h4> | ||||
|                     {{#if ../protection}}<div class="item-field">{{item.data.properties.soak.value}}</div>{{/if}} | ||||
|                     {{#if ../protection}}<div class="item-field"><a class="rollable" data-roll-type="protection">{{item.data.properties.soak.formula}}</a> / {{item.data.properties.soak.value}}</div>{{/if}} | ||||
|                     {{#if ../blocking}}<div class="item-field">{{item.data.properties.blocking.malus}}</div>{{/if}} | ||||
|                     {{#if ../weapon}}<div class="item-field">{{item.data.properties.damage}}</div>{{/if}} | ||||
|                     {{#if ../weapon}}<div class="item-field"><a class="rollable" data-roll-type="damage">{{item.data.properties.damage}}</a></div>{{/if}} | ||||
|                     {{#if ../ranged}}<div class="item-field">{{item.data.properties.range}}</div>{{else}}<div class="item-field"></div>{{/if}} | ||||
|                 </li> | ||||
|             {{/each}} | ||||
|   | ||||
| @@ -15,9 +15,9 @@ | ||||
|             <a class="item-edit">{{item.name}}</a> | ||||
|         </h4> | ||||
|         <div class="item-field flex2 center"> | ||||
|     {{#if item.data.properties.equipable}} | ||||
|         {{#if item.data.properties.equipable}} | ||||
|             <span class="item-field" style="font-size: smaller; font-style: italic; color:#4b4a44">{{localize (concat "BOL.equipmentSlots." item.data.properties.slot)}}</span> | ||||
|     {{/if}} | ||||
|        {{/if}} | ||||
|         </div> | ||||
|         <div class="item-field group-btns flex1 center"> | ||||
|         {{#if item.data.properties.stackable}} | ||||
| @@ -50,6 +50,7 @@ | ||||
|     <li class="item flexrow item-header"> | ||||
|         <div class="item-name flex4 left">{{localize "BOL.ui.protections"}}</div> | ||||
|         <div class="item-field flex2 center">{{localize "BOL.ui.slot"}}</div> | ||||
|         <div class="item-field flex1 center">{{localize "BOL.ui.protection"}}</div> | ||||
|         <div class="item-field flex1 center">{{localize "BOL.ui.qty"}}</div> | ||||
|         <div class="item-field flex1 center">{{localize "BOL.ui.price"}}</div> | ||||
|         <div class="item-field flex1 center">{{localize "BOL.ui.equip"}}</div> | ||||
| @@ -66,6 +67,11 @@ | ||||
|                     <span class="item-field" style="font-size: smaller; font-style: italic; color:#4b4a44">{{localize (concat "BOL.equipmentSlots." item.data.properties.slot)}}</span> | ||||
|                 {{/if}} | ||||
|             </div> | ||||
|             <div class="item-field flex2 center"> | ||||
|                 {{#if item.data.properties.equipable}} | ||||
|                     <span class="item-field" style="font-size: smaller; font-style: italic; color:#4b4a44">{{data.properties.soak.formula}}</span> | ||||
|                 {{/if}} | ||||
|             </div>             | ||||
|             <div class="item-field group-btns flex1 center"> | ||||
|                 {{#if item.data.properties.stackable}} | ||||
|                     <a class="inc-dec-btns" data-operator="minus" data-target="data.quantity" data-incr="1" data-min="0" data-max="{{item.data.properties.stacksize}}"><i class="fas fa-minus-square"></i></a>  | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| <img class="chat-icon" src="{{attacker.img}}" alt="{{attacker.name}}"/> | ||||
| <img class="chat-icon" src="{{actor.img}}" alt="{{actor.name}}"/> | ||||
| Jet Héroïque ! | ||||
| <button class="damage-increase" data-damage-mode="damage-plus-6" data-attack-id="{{attackId}}">Augmenter les dommages de 6</button> | ||||
| <button class="damage-increase" data-damage-mode="damage-plus-12" data-attack-id="{{attackId}}">Augmenter les dommages de 12 (1 point d'Heroisme)</button> | ||||
| <button class="damage-increase" data-damage-mode="damage-normal" data-attack-id="{{attackId}}">Laisser les dommages inchangés</button> | ||||
| <button class="damage-increase" data-damage-mode="damage-plus-6" data-attack-id="{{id}}">Augmenter les dommages de 6</button> | ||||
| <button class="damage-increase" data-damage-mode="damage-plus-12" data-attack-id="{{id}}">Augmenter les dommages de 12 (1 point d'Heroisme)</button> | ||||
| <button class="damage-increase" data-damage-mode="damage-normal" data-attack-id="{{id}}">Laisser les dommages inchangés</button> | ||||
|  | ||||
|   | ||||
| @@ -13,9 +13,11 @@ | ||||
|         <h2 class="failure"><i class="fas fa-times"></i> {{localize "BOL.ui.failure"}}...</h2> | ||||
|     {{/if}} | ||||
| {{/if}} | ||||
|  | ||||
| <h3><strong>{{description}}</strong></h3>  | ||||
|  | ||||
| {{#if reroll}} | ||||
| <a class="button hero-reroll" data-actor-id="{{actor.id}}">Relancer!</a> | ||||
| <a class="button hero-reroll" data-roll-id=="{{rollId}}"" data-actor-id="{{actor.id}}">Relancer!</a> | ||||
| {{/if}} | ||||
| {{!#if hasDescription}} | ||||
| <!--<h4>--> | ||||
|   | ||||
							
								
								
									
										12
									
								
								templates/dialogs/adv-roll-part.hbs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								templates/dialogs/adv-roll-part.hbs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
|     <div class="flexrow" style="margin-bottom: 1px;"> | ||||
|         <div class="flex1 center bg-darkred"> | ||||
|             <label for="adv">{{localize 'BOL.ui.advantages'}}</label> | ||||
|         </div> | ||||
|         <div class="flex1 center cell"> | ||||
|             <input type="radio" name="adv" value="1B" {{#if (eq adv "1B")}}checked{{/if}}/>2d6B<br /> | ||||
|             <input type="radio" name="adv" value="2B" {{#if (eq adv "2B")}}checked{{/if}}/>2d6BB<br /> | ||||
|             <input type="radio" name="adv" value="2" {{#if (eq adv "2")}}checked{{/if}}/>2d6<br /> | ||||
|             <input type="radio" name="adv" value="1M" {{#if (eq adv "1M")}}checked{{/if}}/>2d6M<br /> | ||||
|             <input type="radio" name="adv" value="2M" {{#if (eq adv "2M")}}checked{{/if}}/>2d6MM<br /> | ||||
|         </div> | ||||
|     </div> | ||||
| @@ -7,47 +7,30 @@ | ||||
|             </div> | ||||
|         </div> | ||||
|     </header> | ||||
|     <div class="flexrow" style="margin-bottom: 1px;"> | ||||
|    | ||||
|     {{> "systems/bol/templates/dialogs/attribute-roll-part.hbs"}} | ||||
|  | ||||
|     {{> "systems/bol/templates/dialogs/aptitude-roll-part.hbs"}} | ||||
|  | ||||
|     {{#if (equals aptitude.key "init" )}} | ||||
|       <div class="flexrow" style="margin-bottom: 1px;"> | ||||
|         <div class="flex1 center bg-darkred"> | ||||
|             <label for="apt">{{localize 'BOL.ui.aptitude'}}</label> | ||||
|             <label for="mod">{{localize 'BOL.ui.registerInit'}}</label> | ||||
|         </div> | ||||
|         <div class="flex1 center cell"> | ||||
|             <select class="flex1" name="apt" id="apt" data-type="String"> | ||||
|                 <option value="init" {{#if (equals apt.key "init")}}selected{{/if}}>{{localize 'BOL.aptitudes.init'}}</option> | ||||
|                 <option value="melee" {{#if (equals apt.key "melee")}}selected{{/if}}>{{localize 'BOL.aptitudes.melee'}}</option> | ||||
|                 <option value="ranged" {{#if (equals apt.key "ranged")}}selected{{/if}}>{{localize 'BOL.aptitudes.ranged'}}</option> | ||||
|                 <option value="def" {{#if (equals apt.key "def")}}selected{{/if}}>{{localize 'BOL.aptitudes.def'}}</option> | ||||
|             </select> | ||||
|         </div> | ||||
|     </div> | ||||
|     <div class="flexrow" style="margin-bottom: 1px;"> | ||||
|         <div class="flex1 center bg-darkred"> | ||||
|             <label for="adv">{{localize 'BOL.ui.advantages'}}</label> | ||||
|         </div> | ||||
|         <div class="flex1 center cell"> | ||||
|             <input type="text" class="field-value" name="adv" id="adv" value="{{adv}}" data-type="Number"> | ||||
|         </div> | ||||
|     </div> | ||||
|     <div class="flexrow" style="margin-bottom: 1px;"> | ||||
|         <div class="flex1 center bg-darkred"> | ||||
|             <label for="mod">{{localize 'BOL.ui.modifiers'}}</label> | ||||
|         </div> | ||||
|         <div class="flex1 center cell"> | ||||
|             <input type="text" class="field-value" name="mod" id="mod" value="{{mod}}" data-type="Number"> | ||||
|         </div> | ||||
|     </div> | ||||
|     {{#if careers.items}} | ||||
|     <div class="flexrow" style="margin-bottom: 1px;"> | ||||
|         <div class="flex1 center bg-darkred"> | ||||
|             <label for="mod">{{localize 'BOL.ui.careers'}}</label> | ||||
|         </div> | ||||
|         <div class="flex1 center cell"> | ||||
|             <select class="flex1" name="career" id="career" data-type="String" multiple> | ||||
|                 {{#each careers.items as | career id|}} | ||||
|                     <option value="{{career.data.rank}}">{{career.name}} ({{numberFormat career.data.rank decimals=0 sign=true}})</option> | ||||
|                 {{/each}} | ||||
|             </select> | ||||
|           <label class="checkbox"> | ||||
|             <input class="field-value" type="checkbox" name="register-init" id="register-init" checked /> | ||||
|           </label> | ||||
|         </div> | ||||
|     </div> | ||||
|  | ||||
|     {{/if}} | ||||
|  | ||||
|  | ||||
|     {{> "systems/bol/templates/dialogs/adv-roll-part.hbs"}} | ||||
|  | ||||
|     {{> "systems/bol/templates/dialogs/mod-roll-part.hbs"}} | ||||
|  | ||||
|     {{> "systems/bol/templates/dialogs/career-roll-part.hbs"}} | ||||
|  | ||||
| </form> | ||||
							
								
								
									
										16
									
								
								templates/dialogs/aptitude-roll-part.hbs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								templates/dialogs/aptitude-roll-part.hbs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | ||||
| <div class="flexrow" style="margin-bottom: 1px;"> | ||||
|   <div class="flex1 center bg-darkred"> | ||||
|     <label for="apt">{{localize 'BOL.ui.aptitude'}}</label> | ||||
|   </div> | ||||
|   <div class="flex1 center cell"> | ||||
|     <select class="flex1" name="apt" id="apt" data-type="String"> | ||||
|       <option value="init" {{#if (equals aptitude.key "init" )}}selected{{/if}}>{{localize 'BOL.aptitudes.init'}} | ||||
|       </option> | ||||
|       <option value="melee" {{#if (equals aptitude.key "melee" )}}selected{{/if}}>{{localize 'BOL.aptitudes.melee'}} | ||||
|       </option> | ||||
|       <option value="ranged" {{#if (equals aptitude.key "ranged" )}}selected{{/if}}>{{localize 'BOL.aptitudes.ranged'}} | ||||
|       </option> | ||||
|       <option value="def" {{#if (equals aptitude.key "def" )}}selected{{/if}}>{{localize 'BOL.aptitudes.def'}}</option> | ||||
|     </select> | ||||
|   </div> | ||||
| </div> | ||||
| @@ -7,49 +7,15 @@ | ||||
|             </div> | ||||
|         </div> | ||||
|     </header> | ||||
|     <div class="flexrow" style="margin-bottom: 1px;"> | ||||
|         <div class="flex1 center bg-darkred"> | ||||
|             <label for="attr">{{localize 'BOL.ui.attribute'}}</label> | ||||
|         </div> | ||||
|         <div class="flex1 center cell"> | ||||
|             <select class="flex1" name="attr" id="attr" data-type="String"> | ||||
|                 <option value="vigor" {{#if (equals attr.key "vigor")}}selected{{/if}}>{{localize 'BOL.attributes.vigor'}}</option> | ||||
|                 <option value="agility" {{#if (equals attr.key "agility")}}selected{{/if}}>{{localize 'BOL.attributes.agility'}}</option> | ||||
|                 <option value="mind" {{#if (equals attr.key "mind")}}selected{{/if}}>{{localize 'BOL.attributes.mind'}}</option> | ||||
|                 <option value="appeal" {{#if (equals attr.key "appeal")}}selected{{/if}}>{{localize 'BOL.attributes.appeal'}}</option> | ||||
|             </select> | ||||
|         </div> | ||||
|     </div> | ||||
|     <div class="flexrow" style="margin-bottom: 1px;"> | ||||
|         <div class="flex1 center bg-darkred"> | ||||
|             <label for="adv">{{localize 'BOL.ui.advantages'}}</label> | ||||
|         </div> | ||||
|         <div class="flex1 center cell"> | ||||
|             <input type="text" class="field-value" name="adv" id="adv" value="{{adv}}" data-type="Number"> | ||||
|         </div> | ||||
|     </div> | ||||
|     <div class="flexrow" style="margin-bottom: 1px;"> | ||||
|         <div class="flex1 center bg-darkred"> | ||||
|             <label for="mod">{{localize 'BOL.ui.modifiers'}}</label> | ||||
|         </div> | ||||
|         <div class="flex1 center cell"> | ||||
|             <input type="text" class="field-value" name="mod" id="mod" value="{{mod}}" data-type="Number"> | ||||
|         </div> | ||||
|     </div> | ||||
|     {{#if careers.items}} | ||||
|     <div class="flexrow" style="margin-bottom: 1px;"> | ||||
|         <div class="flex1 center bg-darkred"> | ||||
|             <label for="mod">{{localize 'BOL.ui.careers'}}</label> | ||||
|         </div> | ||||
|         <div class="flex1 center cell"> | ||||
|             <select class="flex1" name="career" id="career" data-type="String" multiple> | ||||
|                 {{#each careers.items as | career id|}} | ||||
|                     <option value="{{career.data.rank}}">{{career.name}} ({{numberFormat career.data.rank decimals=0 sign=true}})</option> | ||||
|                 {{/each}} | ||||
|             </select> | ||||
|         </div> | ||||
|     </div> | ||||
|     {{/if}} | ||||
|  | ||||
|     {{> "systems/bol/templates/dialogs/attribute-roll-part.hbs"}} | ||||
|  | ||||
|     {{> "systems/bol/templates/dialogs/adv-roll-part.hbs"}} | ||||
|  | ||||
|     {{> "systems/bol/templates/dialogs/mod-roll-part.hbs"}} | ||||
|  | ||||
|     {{> "systems/bol/templates/dialogs/career-roll-part.hbs"}} | ||||
|  | ||||
|     <!--<div class="flexrow" style="margin-bottom: 1px;">--> | ||||
|     <!--    <div class="flex1 center bg-darkred">--> | ||||
|     <!--        <label for="mod">{{!localize 'BOL.ui.boons'}}</label>--> | ||||
|   | ||||
							
								
								
									
										13
									
								
								templates/dialogs/attribute-roll-part.hbs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								templates/dialogs/attribute-roll-part.hbs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
|     <div class="flexrow" style="margin-bottom: 1px;"> | ||||
|         <div class="flex1 center bg-darkred"> | ||||
|             <label for="attr">{{localize 'BOL.ui.attribute'}}</label> | ||||
|         </div> | ||||
|         <div class="flex1 center cell"> | ||||
|             <select class="flex1" name="attr" id="attr" data-type="String"> | ||||
|                 <option value="vigor" {{#if (equals attribute.key "vigor")}}selected{{/if}}>{{localize 'BOL.attributes.vigor'}}</option> | ||||
|                 <option value="agility" {{#if (equals attribute.key "agility")}}selected{{/if}}>{{localize 'BOL.attributes.agility'}}</option> | ||||
|                 <option value="mind" {{#if (equals attribute.key "mind")}}selected{{/if}}>{{localize 'BOL.attributes.mind'}}</option> | ||||
|                 <option value="appeal" {{#if (equals attribute.key "appeal")}}selected{{/if}}>{{localize 'BOL.attributes.appeal'}}</option> | ||||
|             </select> | ||||
|         </div> | ||||
|     </div> | ||||
							
								
								
									
										14
									
								
								templates/dialogs/career-roll-part.hbs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								templates/dialogs/career-roll-part.hbs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | ||||
|     {{#if careers.items}} | ||||
|     <div class="flexrow" style="margin-bottom: 1px;"> | ||||
|         <div class="flex1 center bg-darkred"> | ||||
|             <label for="mod">{{localize 'BOL.ui.careers'}}</label> | ||||
|         </div> | ||||
|         <div class="flex1 center cell"> | ||||
|             <select class="flex1" name="career" id="career" data-type="String" multiple> | ||||
|                 {{#each careers.items as | career id|}} | ||||
|                     <option value="{{career.data.rank}}">{{career.name}} ({{numberFormat career.data.rank decimals=0 sign=true}})</option> | ||||
|                 {{/each}} | ||||
|             </select> | ||||
|         </div> | ||||
|     </div> | ||||
|     {{/if}} | ||||
							
								
								
									
										19
									
								
								templates/dialogs/mod-roll-part.hbs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								templates/dialogs/mod-roll-part.hbs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | ||||
|     <div class="flexrow" style="margin-bottom: 1px;"> | ||||
|         <div class="flex1 center bg-darkred"> | ||||
|             <label for="mod">{{localize 'BOL.ui.modifiers'}}</label> | ||||
|         </div> | ||||
|         <div class="flex1 center cell"> | ||||
|           <select name="mod" id="mod"  value="{{mod}}"> | ||||
|             {{#select mod}} | ||||
|             <option value="2">Trés Facile (+2)</option> | ||||
|             <option value="1">Facile (+1)</option> | ||||
|             <option value="0">Moyenne (0)</option> | ||||
|             <option value="-1">Ardue (-1)</option> | ||||
|             <option value="-2">Difficile (-2)</option> | ||||
|             <option value="-4">Très Difficile (-4)</option> | ||||
|             <option value="-6">Impossible (-6)</option> | ||||
|             <option value="-8">Héroïque (-8)</option> | ||||
|             {{/select}} | ||||
|           </select> | ||||
|         </div> | ||||
|     </div> | ||||
| @@ -7,48 +7,15 @@ | ||||
|             </div> | ||||
|         </div> | ||||
|     </header> | ||||
|     <div class="flexrow" style="margin-bottom: 1px;"> | ||||
|         <div class="flex1 center bg-darkred"> | ||||
|             <label for="attr">{{localize 'BOL.ui.attribute'}}</label> | ||||
|         </div> | ||||
|         <div class="flex1 center cell"> | ||||
|             <select class="flex1" name="attr" id="attr" data-type="String"> | ||||
|                 <option value="vigor" {{#if (equals attr.key "vigor")}}selected{{/if}}>{{localize 'BOL.attributes.vigor'}}</option> | ||||
|                 <option value="agility" {{#if (equals attr.key "agility")}}selected{{/if}}>{{localize 'BOL.attributes.agility'}}</option> | ||||
|                 <option value="mind" {{#if (equals attr.key "mind")}}selected{{/if}}>{{localize 'BOL.attributes.mind'}}</option> | ||||
|                 <option value="appeal" {{#if (equals attr.key "appeal")}}selected{{/if}}>{{localize 'BOL.attributes.appeal'}}</option> | ||||
|             </select> | ||||
|         </div> | ||||
|     </div> | ||||
|     <div class="flexrow" style="margin-bottom: 1px;"> | ||||
|         <div class="flex1 center bg-darkred"> | ||||
|             <label for="apt">{{localize 'BOL.ui.aptitude'}}</label> | ||||
|         </div> | ||||
|         <div class="flex1 center cell"> | ||||
|             <select class="flex1" name="apt" id="apt" data-type="String"> | ||||
|                 <option value="init" {{#if (equals apt.key "init")}}selected{{/if}}>{{localize 'BOL.aptitudes.init'}}</option> | ||||
|                 <option value="melee" {{#if (equals apt.key "melee")}}selected{{/if}}>{{localize 'BOL.aptitudes.melee'}}</option> | ||||
|                 <option value="ranged" {{#if (equals apt.key "ranged")}}selected{{/if}}>{{localize 'BOL.aptitudes.ranged'}}</option> | ||||
|                 <option value="def" {{#if (equals apt.key "def")}}selected{{/if}}>{{localize 'BOL.aptitudes.def'}}</option> | ||||
|             </select> | ||||
|         </div> | ||||
|     </div> | ||||
|     <div class="flexrow" style="margin-bottom: 1px;"> | ||||
|         <div class="flex1 center bg-darkred"> | ||||
|             <label for="adv">{{localize 'BOL.ui.advantages'}}</label> | ||||
|         </div> | ||||
|         <div class="flex1 center cell"> | ||||
|             <input type="text" class="field-value" name="adv" id="adv" value="{{adv}}" data-type="Number"> | ||||
|         </div> | ||||
|     </div> | ||||
|     <div class="flexrow" style="margin-bottom: 1px;"> | ||||
|         <div class="flex1 center bg-darkred"> | ||||
|             <label for="mod">{{localize 'BOL.ui.modifiers'}}</label> | ||||
|         </div> | ||||
|         <div class="flex1 center cell"> | ||||
|             <input type="text" class="field-value" name="mod" id="mod" value="{{mod}}" data-type="Number"> | ||||
|         </div> | ||||
|     </div> | ||||
|  | ||||
|     {{> "systems/bol/templates/dialogs/attribute-roll-part.hbs"}} | ||||
|  | ||||
|     {{> "systems/bol/templates/dialogs/aptitude-roll-part.hbs"}} | ||||
|  | ||||
|     {{> "systems/bol/templates/dialogs/adv-roll-part.hbs"}} | ||||
|  | ||||
|     {{> "systems/bol/templates/dialogs/mod-roll-part.hbs"}} | ||||
|  | ||||
|     <div class="flexrow" style="margin-bottom: 1px;"> | ||||
|         <div class="flex1 center bg-darkred"> | ||||
|             <label for="mod">{{localize 'BOL.ui.targetDefence'}}</label> | ||||
| @@ -75,18 +42,7 @@ | ||||
|           </div> | ||||
|       </div> | ||||
|       {{/if}} | ||||
|     {{#if careers.items}} | ||||
|     <div class="flexrow" style="margin-bottom: 1px;"> | ||||
|         <div class="flex1 center bg-darkred"> | ||||
|             <label for="mod">{{localize 'BOL.ui.careers'}}</label> | ||||
|         </div> | ||||
|         <div class="flex1 center cell"> | ||||
|             <select class="flex1" name="career" id="career" data-type="String" multiple> | ||||
|                 {{#each careers.items as | career id|}} | ||||
|                     <option value="{{career.data.rank}}">{{career.name}} ({{numberFormat career.data.rank decimals=0 sign=true}})</option> | ||||
|                 {{/each}} | ||||
|             </select> | ||||
|         </div> | ||||
|     </div> | ||||
|     {{/if}} | ||||
|  | ||||
|     {{> "systems/bol/templates/dialogs/career-roll-part.hbs"}} | ||||
|  | ||||
| </form> | ||||
		Reference in New Issue
	
	Block a user