diff --git a/lang/en.json b/lang/en.json index e3dabc2..fc15c9d 100644 --- a/lang/en.json +++ b/lang/en.json @@ -137,6 +137,9 @@ "BOL.ui.bonusmalus": "Additionnal bonus/malus", "BOL.ui.nbdices": "Number of Dices", "BOL.ui.totalmod": "Total Mod.", + "BOL.ui.rangeModifiers": "Range modifier", + "BOL.ui.money": "Bougette", + "BOL.ui.moneyTitle": "Gold & Treasure", "BOL.featureCategory.origins": "Origines", "BOL.featureCategory.races": "Races", @@ -152,6 +155,12 @@ "BOL.featureSubtypes.flaw": "Désavantage", "BOL.featureSubtypes.language": "Langage", "BOL.featureSubtypes.gods": "Faith & Gods", + + "BOL.bougette.nomoney": "Nothing", + "BOL.bougette.tolive": "To live", + "BOL.bougette.easylife": "Easy Life", + "BOL.bougette.luxury" : "Luxury life", + "BOL.bougette.rich": "Rich!", "BOL.itemCategory.object": "Objet", "BOL.itemCategory.equipment": "Équipement", diff --git a/lang/fr.json b/lang/fr.json index e2a1226..8e9ee15 100644 --- a/lang/fr.json +++ b/lang/fr.json @@ -139,6 +139,9 @@ "BOL.ui.bonusmalus": "Dés Bonus/Malus additionnels", "BOL.ui.nbdices": "Nombre de dés", "BOL.ui.totalmod": "Total Mod.", + "BOL.ui.rangeModifiers": "Mod. de Portée", + "BOL.ui.money": "Bougette", + "BOL.ui.moneyTitle": "Or et Piecettes", "BOL.featureCategory.origins": "Origines", "BOL.featureCategory.races": "Races", @@ -147,6 +150,12 @@ "BOL.featureCategory.flaws": "Désavantages", "BOL.featureCategory.languages": "Langues", + "BOL.bougette.nomoney": "A sec", + "BOL.bougette.tolive": "De quoi vivre", + "BOL.bougette.easylife": "A l'aise", + "BOL.bougette.luxury" : "Luxe&Volupté", + "BOL.bougette.rich": "Richissime", + "BOL.featureSubtypes.origin": "Origine", "BOL.featureSubtypes.race": "Race", "BOL.featureSubtypes.career": "Carrière", diff --git a/module/actor/actor-sheet.js b/module/actor/actor-sheet.js index ca13fb2..33dd183 100644 --- a/module/actor/actor-sheet.js +++ b/module/actor/actor-sheet.js @@ -3,6 +3,7 @@ * @extends {ActorSheet} */ import {BoLRoll} from "../controllers/bol-rolls.js"; +import { BoLUtility } from "../system/bol-utility.js"; export class BoLActorSheet extends ActorSheet { @@ -34,7 +35,7 @@ export class BoLActorSheet extends ActorSheet { const li = $(ev.currentTarget).parents(".item"); const item = this.actor.items.get(li.data("itemId")); item.sheet.render(true); - }); + }) // Equip/Unequip item html.find('.item-equip').click(this._onToggleEquip.bind(this)); @@ -135,12 +136,13 @@ export class BoLActorSheet extends ActorSheet { formData.vehicles = this.actor.vehicles; formData.ammos = this.actor.ammos; formData.misc = this.actor.misc; - formData.combat = this.actor.buildCombat(); + formData.combat = this.actor.buildCombat() formData.features = this.actor.buildFeatures() formData.isGM = game.user.isGM formData.options= this.options formData.owner= this.document.isOwner formData.editScore= this.options.editScore + formData.useBougette = BoLUtility.getUseBougette() formData.isSorcerer = this.actor.isSorcerer() formData.isAlchemist = this.actor.isAlchemist() diff --git a/module/actor/actor.js b/module/actor/actor.js index 5e4cf36..663835f 100644 --- a/module/actor/actor.js +++ b/module/actor/actor.js @@ -10,10 +10,7 @@ export class BoLActor extends Actor { /** @override */ prepareData() { const actorData = this.data; - // 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. + if (actorData.type === 'character') { actorData.type = 'player'; actorData.villainy = false; @@ -356,7 +353,19 @@ export class BoLActor extends Actor { if ( protect.data.subtype == 'helm') { formula += "+1" } else if ( protect.data.subtype == 'armor') { - formula += "+" + protect.data.properties.soak.formula; + if ( BoLUtility.this.getRollArmor() ) { + if ( !protect.data.properties.soak.formula || protect.data.properties.soak.formula=="") { + ui.notifications.warn(`L'armure ${protect.name} n'a pas de formule pour la protection !`) + } else { + formula += "+" + protect.data.properties.soak.formula + } + } else { + if ( protect.data.properties.soak.value == undefined ) { + ui.notifications.warn(`L'armure ${protect.name} n'a pas de valeur fixe pour la protection !`) + } else { + formula += "+ " + protect.data.properties.soak.value + } + } } } console.log("Protect Formula", formula) diff --git a/module/bol.js b/module/bol.js index 6b1434f..c75b4c2 100644 --- a/module/bol.js +++ b/module/bol.js @@ -6,7 +6,6 @@ import { BoLItemSheet } from "./item/item-sheet.js"; import { System, BOL } from "./system/config.js"; 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 { Macros } from "./system/macros.js"; import { BoLUtility } from "./system/bol-utility.js"; @@ -50,9 +49,6 @@ Hooks.once('init', async function () { // Inot useful stuff BoLUtility.init(); - // Register System Settings - registerSystemSettings(); - // Preload Handlebars Templates await preloadHandlebarsTemplates(); @@ -95,6 +91,7 @@ function welcomeMessage() { Bienvenue dans Barbarians of Lemuria (Ludospherik version)

Les livres nécessaires pour jouer sont disponibles sur le site de l'éditeur : http://www.ludospherik.fr/content/14-barbarians-of-lemuria

Bon jeu en Lemurie !

+

Tout le support et le suivi de ce système es disponible via le Discord Foundry FR : https://discord.gg/pPSDNJk

` }); } diff --git a/module/controllers/bol-rolls.js b/module/controllers/bol-rolls.js index 5157e24..ea14062 100644 --- a/module/controllers/bol-rolls.js +++ b/module/controllers/bol-rolls.js @@ -75,15 +75,17 @@ export class BoLRoll { ui.notifications.warn("Unable to find weapon !"); return; } - let weaponData = weapon.data.data; + let weaponData = weapon.data.data let attribute = eval(`actor.data.data.attributes.${weaponData.properties.attackAttribute}`) let aptitude = eval(`actor.data.data.aptitudes.${weaponData.properties.attackAptitude}`) + console.debug("WEAPON!", weaponData) let attackDef = { mode: "weapon", actor: actor, actorData: actorData, weapon: weapon, + isRanged: weaponData.properties.ranged || weaponData.properties.throwing, target: target, careerBonus: 0, defender: (target) ? game.actors.get(target.data.actorId) : undefined, @@ -92,10 +94,10 @@ export class BoLRoll { attrValue: attribute.value, aptValue: aptitude.value, mod: 0, + modRanged: 0, label: (weapon.name) ? weapon.name : game.i18n.localize('BOL.ui.noWeaponName'), description: actor.name + " - " + game.i18n.localize('BOL.ui.weaponAttack'), } - console.debug("WEAPON!", attackDef, weaponData); return this.displayRollDialog(attackDef); } @@ -177,7 +179,7 @@ export class BoLRoll { } $('#roll-modifier').val( this.rollData.attrValue + "+" + this.rollData.aptValue + "+" + this.rollData.careerBonus + "+" + this.rollData.mod + "+" + - this.rollData.weaponModifier + "-" + this.rollData.defence + "+" + this.rollData.shieldMalus ) + this.rollData.modRanged + "+" + this.rollData.weaponModifier + "-" + this.rollData.defence + "+" + this.rollData.shieldMalus ) } /* -------------------------------------------- */ @@ -195,6 +197,10 @@ export class BoLRoll { this.rollData.mod = Number(event.currentTarget.value) this.updateTotalDice() }) + html.find('#modRanged').change((event) => { + this.rollData.modRanged = Number(event.currentTarget.value) + this.updateTotalDice() + }) html.find('#attr').change((event) => { let attrKey = event.currentTarget.value @@ -264,6 +270,7 @@ export class BoLRoll { rollData.shieldMalus = 0 } rollData.careerBonus = rollData.careerBonus ?? 0 + rollData.modRanged = rollData.modRanged ?? 0 rollData.mod = rollData.mod ?? 0 rollData.id = randomID(16) @@ -449,17 +456,16 @@ export class BoLDefaultRoll { bonusDmg = 12 } let attrDamageValue = this.getDamageAttributeValue(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 weaponFormula = BoLUtility.getDamageFormula(this.rollData.weapon.data.data) + let damageFormula = weaponFormula + "+" + bonusDmg + "+" + attrDamageValue console.log("DAMAGE !!!", damageFormula, attrDamageValue) //console.log("Formula", weaponFormula, damageFormula, this.rollData.weapon.data.data.properties.damage) this.rollData.damageFormula = damageFormula this.rollData.damageRoll = new Roll(damageFormula) - this.rollData.damageTotal = this.rollData.damageRoll.total await this.rollData.damageRoll.roll({ "async": false }) + this.rollData.damageTotal = this.rollData.damageRoll.total } $(`#${this.rollData.optionsId}`).hide() // Hide the options roll buttons this.sendDamageMessage() diff --git a/module/system/bol-utility.js b/module/system/bol-utility.js index b98f871..788fdad 100644 --- a/module/system/bol-utility.js +++ b/module/system/bol-utility.js @@ -1,14 +1,48 @@ import { BoLDefaultRoll } from "../controllers/bol-rolls.js"; // Spell circle to min PP cost -const __circle2minpp = { 0: 0, 1: 2,2: 6, 3: 11} +const __circle2minpp = { 0: 0, 1: 2, 2: 6, 3: 11 } export class BoLUtility { /* -------------------------------------------- */ - static async init() { + static init() { this.attackStore = {} + + game.settings.register("bol", "rollArmor", { + name: "Effectuer des jets pour les armures", + hint: "Effectue un jet de dés pour les armures (valeur fixe si désactivé)", + scope: "world", + config: true, + default: true, + type: Boolean, + onChange: lang => window.location.reload() + }); + game.settings.register("bol", "useBougette", { + name: "Utiliser la Bougette (règle fan-made)", + hint: "Utilise un indicateur de Bougette, comme décrit dans l'aide de jeu Gold&Glory du RatierBretonnien (https://www.lahiette.com/leratierbretonnien/)", + scope: "world", + config: true, + default: false, + type: Boolean, + onChange: lang => window.location.reload() + }); + + this.rollArmor = game.settings.get("bol", "rollArmor") // Roll armor or not + this.useBougette = game.settings.get("bol", "useBougette") // Use optionnal bougette rules + + console.log("UTIL", this) + } + + + /* -------------------------------------------- */ + static getRollArmor() { + return this.rollArmor + } + /* -------------------------------------------- */ + static getUseBougette() { + return this.useBougette } /* -------------------------------------------- */ @@ -117,60 +151,60 @@ export class BoLUtility { } else { BoLUtility.processAttackSuccess(attackDef); } - } + } } - + /* -------------------------------------------- */ static async chatListeners(html) { // Damage handling - html.on("click", '.chat-damage-apply', event => { + html.on("click", '.chat-damage-apply', event => { let rollData = BoLUtility.getLastRoll() $(`#${rollData.applyId}`).hide() BoLUtility.sendAttackSuccess(rollData) }); - html.on("click", '.chat-damage-roll', event => { + html.on("click", '.chat-damage-roll', event => { event.preventDefault(); let rollData = BoLUtility.getLastRoll() rollData.damageMode = event.currentTarget.attributes['data-damage-mode'].value; let bolRoll = new BoLDefaultRoll(rollData) bolRoll.rollDamage() }); - + html.on("click", '.transform-heroic-roll', event => { event.preventDefault(); let rollData = BoLUtility.getLastRoll() rollData.actor.subHeroPoints(1) - let r = new BoLDefaultRoll( rollData ) + let r = new BoLDefaultRoll(rollData) r.upgradeToCritical(); - } ); - + }); + html.on("click", '.hero-reroll', event => { event.preventDefault(); let rollData = BoLUtility.getLastRoll() rollData.actor.subHeroPoints(1) rollData.reroll = false // Disable reroll option for second roll - let r = new BoLDefaultRoll( rollData ) + let r = new BoLDefaultRoll(rollData) r.roll(); - } ); + }); - html.on("click", '.damage-handling', event => { + html.on("click", '.damage-handling', event => { event.preventDefault(); let attackId = event.currentTarget.attributes['data-attack-id'].value; let defenseMode = event.currentTarget.attributes['data-defense-mode'].value; let weaponId = (event.currentTarget.attributes['data-weapon-id']) ? event.currentTarget.attributes['data-weapon-id'].value : -1 - if ( game.user.isGM) { + if (game.user.isGM) { BoLUtility.processDamageHandling(event, attackId, defenseMode, weaponId) } else { - game.socket.emit("system.bol", { msg: "msg_damage_handling", data: {event: event, attackId: attackId, defenseMode: defenseMode, weaponId: weaponId} }); + game.socket.emit("system.bol", { msg: "msg_damage_handling", data: { event: event, attackId: attackId, defenseMode: defenseMode, weaponId: weaponId } }); } }); } /* -------------------------------------------- */ - static async processDamageHandling(event, attackId, defenseMode, weaponId=-1) { - if ( !game.user.isGM) { + static async processDamageHandling(event, attackId, defenseMode, weaponId = -1) { + if (!game.user.isGM) { return; } BoLUtility.removeChatMessageId(BoLUtility.findChatMessageId(event.currentTarget)); @@ -184,12 +218,12 @@ export class BoLUtility { attackDef.defenseMode = defenseMode; if (defenseMode == 'damage-with-armor') { - let armorFormula = attackDef.defender.getArmorFormula() + let armorFormula = attackDef.defender.getArmorFormula() attackDef.rollArmor = new Roll(armorFormula) - attackDef.rollArmor.roll( {async: false} ) - attackDef.armorProtect = (attackDef.rollArmor.total<0) ? 0 : attackDef.rollArmor.total; + attackDef.rollArmor.roll({ async: false }) + attackDef.armorProtect = (attackDef.rollArmor.total < 0) ? 0 : attackDef.rollArmor.total; attackDef.finalDamage = attackDef.damageRoll.total - attackDef.armorProtect; - attackDef.finalDamage = (attackDef.finalDamage<0) ? 0 : attackDef.finalDamage; + attackDef.finalDamage = (attackDef.finalDamage < 0) ? 0 : attackDef.finalDamage; attackDef.defender.sufferDamage(attackDef.finalDamage); } if (defenseMode == 'damage-without-armor') { @@ -197,21 +231,21 @@ export class BoLUtility { attackDef.defender.sufferDamage(attackDef.finalDamage); } if (defenseMode == 'hero-reduce-damage') { - let armorFormula = attackDef.defender.getArmorFormula(); + let armorFormula = attackDef.defender.getArmorFormula(); attackDef.rollArmor = new Roll(armorFormula) - attackDef.rollArmor.roll( {async: false} ); - attackDef.armorProtect = (attackDef.rollArmor.total<0) ? 0 : attackDef.rollArmor.total; + attackDef.rollArmor.roll({ async: false }); + attackDef.armorProtect = (attackDef.rollArmor.total < 0) ? 0 : attackDef.rollArmor.total; attackDef.rollHero = new Roll("1d6"); - attackDef.rollHero.roll( {async: false} ); + attackDef.rollHero.roll({ async: false }); attackDef.finalDamage = attackDef.damageRoll.total - attackDef.rollHero.total - attackDef.armorProtect; - attackDef.finalDamage = (attackDef.finalDamage<0) ? 0 : attackDef.finalDamage; + attackDef.finalDamage = (attackDef.finalDamage < 0) ? 0 : attackDef.finalDamage; attackDef.defender.sufferDamage(attackDef.finalDamage); attackDef.defender.subHeroPoints(1); } if (defenseMode == 'hero-in-extremis') { attackDef.finalDamage = 0; attackDef.weaponHero = attackDef.defender.weapons.find(item => item._id == weaponId); - attackDef.defender.deleteEmbeddedDocuments("Item", [ weaponId ]); + attackDef.defender.deleteEmbeddedDocuments("Item", [weaponId]); } ChatMessage.create({ alias: attackDef.defender.name, @@ -221,7 +255,7 @@ export class BoLUtility { attacker: attackDef.attacker, rollArmor: attackDef.rollArmor, rollHero: attackDef.rollHero, - weaponHero : attackDef.weaponHero, + weaponHero: attackDef.weaponHero, armorProtect: attackDef.armorProtect, defender: attackDef.defender, defenseMode: attackDef.defenseMode, @@ -264,11 +298,11 @@ export class BoLUtility { /* -------------------------------------------- */ static removeChatMessageId(messageId) { - if (messageId){ + if (messageId) { game.messages.get(messageId)?.delete(); } } - + static findChatMessageId(current) { return BoLUtility.getChatMessageId(BoLUtility.findChatMessage(current)); } @@ -378,23 +412,29 @@ export class BoLUtility { if (sockmsg.name == "msg_damage_handling") { BoLUtility.processDamageHandling(sockmsg.data.event, sockmsg.data.attackId, sockmsg.data.defenseMode) } - } + } /* -------------------------------------------- */ - static computeSpellCost( spell, nbOptCond= 0) { + static computeSpellCost(spell, nbOptCond = 0) { let pp = spell.data.data.properties.ppcost let minpp = __circle2minpp[spell.data.data.properties.circle] - pp = (pp-nbOptCond', - label: game.i18n.localize("Roll"), - callback: () => { this.roll() } - }, - cancel: { - icon: '', - label: game.i18n.localize("Cancel"), - callback: () => { this.close() } - } }, - default: "roll", - close: close - } - - super(conf, options); - - console.log("ROLLDATA ", rollData); - this.actor = actor; - this.rollData = rollData; - } - - /* -------------------------------------------- */ - roll () { - BoLUtility.rollBoL( this.rollData ) - } - - /* -------------------------------------------- */ - activateListeners(html) { - super.activateListeners(html); - - let dialog = this; - function onLoad() { - } - $(function () { onLoad(); }); - - html.find('#bonusMalus').change((event) => { - this.rollData.bonusMalus = Number(event.currentTarget.value); - }); - html.find('#d6Bonus').change((event) => { - this.rollData.d6Bonus = Number(event.currentTarget.value); - }); - html.find('#d6Malus').change((event) => { - this.rollData.d6Malus = Number(event.currentTarget.value); - }); - } -} diff --git a/module/system/settings.js b/module/system/settings.js deleted file mode 100644 index 1e061c9..0000000 --- a/module/system/settings.js +++ /dev/null @@ -1,23 +0,0 @@ -export const registerSystemSettings = function() { - - game.settings.register("bol", "displayDifficulty", { - name: "Affiche la difficulté", - hint: "Active l'affichage de la difficulté sur les jets de compétences/attributs et d'armes.", - scope: "world", - config: true, - default: true, - type: Boolean, - onChange: lang => window.location.reload() - }); - - game.settings.register("bol", "rollArmor", { - name: "Effectuer des jets pour les armures", - hint: "Effectue un jet de dés pour les armures (valeur fixe si désactivé)", - scope: "world", - config: true, - default: true, - type: Boolean, - onChange: lang => window.location.reload() - }); - -}; diff --git a/packs/aides-de-jeu.db b/packs/aides-de-jeu.db index f15bf59..75f3551 100644 --- a/packs/aides-de-jeu.db +++ b/packs/aides-de-jeu.db @@ -1,3 +1,4 @@ {"_id":"3xJg1rCxnWvEmoxS","name":"Points d'héroisme","content":"

Vous pouvez utiliser les points d’héroïsme pour peser sur l’issue d’un combat ou d’une situation afin de faire pencher la balance en votre faveur. Voici les différentes façons d’utiliser un point d’héroïsme :

\n

 

\n

Coup de chance

\n

Quand la description d’une scène n’a pas clairement défini certains détails, le joueur peut suggérer quelque chose qui paraisse raisonnable et utiliser 1 point d’héroïsme pour que cela devienne une réalité. Cette façon d’utiliser un point d’héroïsme reste soumise à l’approbation du MJ. Cela ne doit pas permettre d’apporter un changement majeur dans une scène ni de modifier un élément qui a déjà été déterminé.

\n

Par exemple, si un personnage est emprisonné dans une geôle, il peut utiliser 1 point d’héroïsme pour découvrir une pierre disjointe dans le mur et réussir à l’extraire, peut-être dans le but d’assommer le garde la prochaine fois que celui-ci viendra lui apporter sa pitance.

\n

Un sorcier peut utiliser 1 point d’héroïsme afin de remplir une condition d’incantation. Par exemple, si le MJ n’a pas encore précisé le moment de la journée, le sorcier pourra s’exclamer: « Ah, cette heure du jour est idéale pour la réussite de mon invocation ! »

\n

 

\n

Défier la mort

\n

Les points d’héroïsme peuvent toujours servir à garder un héros en vie alors qu’il devrait mourir. Si vous avez subi des dégâts qui ont fait chuter votre vitalité entre -1 et -5, vous pouvez dépenser 1 point d’héroïsme pour ramener immédiatement votre vitalité à 0. Vous êtes vivant, mais inconscient.

\n

Si les dégâts subis vous amènent au-dessous de -5 en vitalité, vous pouvez dépenser 1 point d’héroïsme pour stabiliser vos blessures. Vous restez inconscient, et vous pourrez vous remettre sur pied avec quelques jours de repos.

\n

 

\n

Faveur divine

\n

Vous pouvez dépenser 1 point d’héroïsme pour relancer les dés d’un jet d’action (même si vous avez obtenu un double 1, qui est un échec automatique). Vous devez relancer tous les dés (y compris les dés de bonus) et conserver le résultat du second jet.

\n

 

\n

Juste une égratignure

\n

Quand un héros subit des dégâts, il peut prendre un petit moment (ce qui lui coûte sa prochaine action) pour se remettre du coup qu’il vient d’encaisser. En d’autres termes, sa blessure n’est finalement pas aussi grave qu’elle paraissait. Vous lancez 1d6 et récupérez le nombre correspondant de points de vitalité (sans pouvoir dépasser le nombre de points de dégâts subis du fait de cette attaque).

\n

 

\n

Parade in extremis

\n

Vous pouvez dépenser 1 point d’héroïsme pour éviter de subir les dégâts d’une attaque en interposant votre bouclier ou votre arme au dernier moment. Toutefois, le coup fracasse votre bouclier ou brise votre arme qui devient alors inutilisable.

\n

 

\n

Négocier avec le MJ

\n

Tout autre avantage ponctuel (non couvert par les différentes options d’utilisation des points d’héroïsme) que vous pourriez convaincre le MJ de vous accorder.

\n

 

\n

Succès héroïque

\n

Lorsque vous obtenez un double 6 sur un jet d’action, il s’agit d’un succès héroïque. Mais vous pouvez aussi convertir un simple succès en succès héroïque par la dépense de 1 point d’héroïsme. Le résultat exact d’un succès héroïque dépend de la tâche entreprise, mais dans tous les cas le héros réussit brillamment son action.

\n

Au combat, un succès héroïque vous permet de choisir une des options suivantes :

\n

Carnage. Vous effectuez immédiatement une nouvelle attaque, contre le même adversaire ou contre un adversaire différent. Vous ne pouvez pas dépenser de point d’héroïsme dans le cadre de cette attaque supplémentaire.

\n

Coup dévastateur. Vous ajoutez +6 aux dégâts.

\n

Coup précis. Vous frappez votre ennemi à un endroit précis, dans l’intention de l’estropier afin de diminuer ses capacités. Vous déterminez les dégâts normalement et imposez à la cible un dé de malus à un type spécifique de jets d’action (en règle générale, vous voudrez affecter ses jets d’attaque, mais ce n’est pas une obligation ; un coup porté à l’œil imposera un dé de malus à tous les jets d’action faisant appel à la vue, ce qui peut inclure – ou pas– les jets d’attaque). Les autres options d’un coup précis peuvent être de trancher un tentacule ou un dard, ou d’ouvrir une large plaie dans le cuir épais d’un monstre (pour réduire la protection de la créature d’une catégorie). Vous pourrez décider avec le MJ d’autres effets similaires en fonction des circonstances.

\n

Désarmement. Si votre adversaire a une arme en main, vous le désarmez (au lieu de lui infliger des dégâts).

\n

Massacrer la piétaille. Si vous combattez de la piétaille, les dégâts infligés représentent le nombre d’adversaires mis hors de combat par votre assaut. Ils ne sont pas forcément morts, mais ils ne sont pas près de revenir vous affronter de sitôt.

\n

Renversement. Vous pouvez renverser un adversaire, dont la taille peut être supérieure à la vôtre d’une catégorie au maximum. L’adversaire se retrouve à terre après avoir été repoussé de quelques pas (il ne fait pas bon combattre au bord d’une falaise !). Si le combat continue, l’adversaire qui se relève subit un dé de malus à sa prochaine action.

\n

 

\n

Succès légendaire

\n

Si vous obtenez un double 6 sur un jet d’action et qu’il s’agit d’un succès héroïque (pas d’un jet d’action qui ne pouvait réussir que sur un double 6), vous pouvez dépenser 1 point d’héroïsme pour transformer ce succès héroïque en succès légendaire, et cela même si vous avez dépensé 1 point d’héroïsme pour refaire votre jet d’action, du moment que vous obtenez un double 6 au second jet.

\n

Le succès légendaire n’est accessible que si vous obtenez un double 6. Vous ne pouvez pas convertir un succès normal en succès héroïque, puis dépenser un deuxième point d’héroïsme pour le transformer en succès légendaire.

\n

Au combat, un succès légendaire vous permet de choisir deux options de succès héroïque. Par exemple, si vous affrontez de la piétaille, vous pouvez choisir Massacrer la piétaille et Coup dévastateur afin d’éliminer encore plus d’adversaires. Vous pouvez choisir deux fois la même option, si vous le souhaitez (par exemple, choisir deux fois Coup dévastateur pour un bonus aux dégâts de +12 !).

\n

 

\n

Récupérer les points d’héroïsme

\n

Vous récupérez à la fin d’une aventure tous les points d’héroïsme utilisés.

\n

Vous ne pouvez pas dépasser votre total de points d’héroïsme de départ, à moins de recevoir un point d’héroïsme en bonus du fait d’un échec critique.

","folder":null,"sort":0,"permission":{"default":0,"zN9ZZg5J7XzNELjd":3},"flags":{"core":{"sourceId":"JournalEntry.yOiargvrodwnCkoY"}}} +{"name":"Monnaies de Lemurie","content":"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
  
LieuMonnaies/Echanges
Cote de FeuTroc
Désert de BesharTroc
HalakhSekh
Iles du CrâneToutes monnaies
Jungle de Qo et QushTroc
LysorStratere
MalakutRoue
Marais de FestrelTroc
Marais de KashtTroc
Montagnes de l’AxosTroc
OomisTetras
ParsoolDiobole
Plaines de KlaarTroc, Toutes monnaies
SatarlaSolis
ShamballahDzungli
Terres DésoléesTroc
TyrusDrachme
UrcebPiacor
ValgardOsdul
ZalutAb’Shelar
BeiWeiTroc
GhataïTroc, Bin-Teng
Khansan, Liu, Tor XianBin-Teng
","folder":null,"sort":0,"permission":{"default":0,"kQghu0tL1dft5xLu":3},"flags":{"core":{"sourceId":"JournalEntry.6ZssoVs8jkt4AGcG"}},"_id":"BqmB3vIaTkiDl8q0"} {"_id":"RY7oMQlyVpmkIDLZ","name":"Points de vilenie","content":"

Les rivaux disposent de points de vilenie, l’équivalent des points d’héroïsme des héros, qui s’utilisent de la même façon, avec quelques options supplémentaires : 

\n

Bouclier humain : un rival peut utiliser un des PNJ piétaille qui l’entourent comme « bouclier humain » pour absorber les dégâts d’une attaque. Cela fonctionne comme l’option «parade in extremis » des points d’héroïsme (cf. @JournalEntry[yOiargvrodwnCkoY]{Utiliser les points d'héroisme}).

\n

Fuite opportune : le rival parvient à s’enfuir quand les choses commencent à tourner mal pour lui :

\n

-Alors que l’attention des héros est détournée, le rival disparaît au coin d’un couloir…

\n

-Alors que les héros avancent vers le nécromancien pour en finir avec lui, il sourit et ouvre un panneau secret dans le mur par lequel il s’enfuit…

\n

-Le rival tombe d’une falaise, mais quand les héros se penchent au bord du précipice pour constater sa mort, nulle trace de son corps en contrebas…

\n

Peu importe la manière, le rival parvient à s’enfuir, pour recommencer à comploter. En combinant cette option à celle de «défier la mort », un rival peut parvenir à s’échapper même s’il semble bel et bien mort. Il doit toutefois avoir une occasion de prendre la fuite, aussi les héros doivent-ils être distraits par autre chose pour que celui-ci puisse utiliser ses points de vilenie afin d’échapper à son destin.

","folder":null,"sort":0,"permission":{"default":0,"zN9ZZg5J7XzNELjd":3},"flags":{"core":{"sourceId":"JournalEntry.OKwvpofahg0lZ4YM"}}} {"name":"Vademecum des Joueurs","content":"","img":"systems/bol/images/vademecum.webp","folder":null,"sort":0,"permission":{"default":0,"kQghu0tL1dft5xLu":3},"flags":{"core":{"sourceId":"JournalEntry.Ha8snCaU5ATV0Wph"}},"_id":"veAAxCtCKcFIsnln"} diff --git a/system.json b/system.json index 2ad6a68..c3d5a22 100644 --- a/system.json +++ b/system.json @@ -7,8 +7,8 @@ "url": "https://github.com/ZigmundKreud/bol", "license": "LICENSE.txt", "flags": {}, - "version": "1.0.10", - "templateVersion": 20, + "version": "1.1.0", + "templateVersion": 21, "minimumCoreVersion": "0.8.6", "compatibleCoreVersion": "9", "scripts": [], diff --git a/template.json b/template.json index adfbe3d..9b680dd 100644 --- a/template.json +++ b/template.json @@ -138,6 +138,9 @@ "templates": [ "base" ], "type": "player", "villainy": false, + "bougette": { + "state": "nomoney" + }, "xp": { "key": "xp", "label": "BOL.traits.xp", diff --git a/templates/actor/parts/tabs/actor-equipment.hbs b/templates/actor/parts/tabs/actor-equipment.hbs index 9d5434d..2dc0639 100644 --- a/templates/actor/parts/tabs/actor-equipment.hbs +++ b/templates/actor/parts/tabs/actor-equipment.hbs @@ -1,336 +1,394 @@ +{{#if useBougette}}
    -
  1. -
    {{localize "BOL.ui.weapons"}}
    -
    {{localize "BOL.ui.slot"}}
    -
    {{localize "BOL.ui.qty"}}
    -
    {{localize "BOL.ui.price"}}
    -
    {{localize "BOL.ui.equip"}}
    -
    -
  2. -{{#each weapons as |item id|}} -
  3. -

    -
    - {{item.name}} -

    -
    - {{#if item.data.properties.equipable}} - {{localize (concat "BOL.equipmentSlots." item.data.properties.slot)}} - {{/if}} -
    -
    - {{#if item.data.properties.stackable}} -   - {{item.data.quantity}}  - - {{/if}} -
    -
    - {{item.data.price}} -
    -
    - {{#if data.properties.equipable}} - {{#if data.worn}} - - {{else}} - - {{/if}} - {{/if}} -
    -
    - -
    -
  4. -{{/each}} +
  5. +
    {{localize "BOL.ui.moneyTitle"}}
    +
     
    +
  6. +
  7. +

    +
    + {{localize "BOL.ui.money"}} +

    + +
  8. +
+{{/if}} + +
    +
  1. +
    {{localize "BOL.ui.weapons"}}
    +
    {{localize "BOL.ui.slot"}}
    +
    {{localize "BOL.ui.qty"}}
    +
    {{localize "BOL.ui.price"}}
    +
    {{localize "BOL.ui.equip"}}
    +
    +
  2. + {{#each weapons as |item id|}} +
  3. +

    +
    + {{item.name}} +

    +
    + {{#if item.data.properties.equipable}} + {{localize (concat + "BOL.equipmentSlots." item.data.properties.slot)}} + {{/if}} +
    +
    + {{#if item.data.properties.stackable}} +   + {{item.data.quantity}}  + + {{/if}} +
    +
    + {{item.data.price}} +
    +
    + {{#if data.properties.equipable}} + {{#if data.worn}} + + {{else}} + + {{/if}} + {{/if}} +
    +
    + +
    +
  4. + {{/each}}
    -
  1. -
    {{localize "BOL.ui.protections"}}
    -
    {{localize "BOL.ui.slot"}}
    -
    {{localize "BOL.ui.protection"}}
    -
    {{localize "BOL.ui.qty"}}
    -
    {{localize "BOL.ui.price"}}
    -
    {{localize "BOL.ui.equip"}}
    -
    -
  2. - {{#each protections as |item id|}} -
  3. -

    -
    - {{item.name}} -

    -
    - {{#if item.data.properties.equipable}} - {{localize (concat "BOL.equipmentSlots." item.data.properties.slot)}} - {{/if}} -
    -
    - {{#if item.data.properties.equipable}} - {{data.properties.soak.formula}} - {{/if}} -
    -
    - {{#if item.data.properties.stackable}} -   - {{item.data.quantity}}  - - {{/if}} -
    -
    - {{item.data.price}} -
    -
    - {{#if data.properties.equipable}} - {{#if data.worn}} - - {{else}} - - {{/if}} - {{/if}} -
    -
    - -
    -
  4. - {{/each}} +
  5. +
    {{localize "BOL.ui.protections"}}
    +
    {{localize "BOL.ui.slot"}}
    +
    {{localize "BOL.ui.protection"}}
    +
    {{localize "BOL.ui.qty"}}
    +
    {{localize "BOL.ui.price"}}
    +
    {{localize "BOL.ui.equip"}}
    +
    +
  6. + {{#each protections as |item id|}} +
  7. +

    +
    + {{item.name}} +

    +
    + {{#if item.data.properties.equipable}} + {{localize (concat + "BOL.equipmentSlots." item.data.properties.slot)}} + {{/if}} +
    +
    + {{#if item.data.properties.equipable}} + {{data.properties.soak.formula}} + {{/if}} +
    +
    + {{#if item.data.properties.stackable}} +   + {{item.data.quantity}}  + + {{/if}} +
    +
    + {{item.data.price}} +
    +
    + {{#if data.properties.equipable}} + {{#if data.worn}} + + {{else}} + + {{/if}} + {{/if}} +
    +
    + +
    +
  8. + {{/each}}
    -
  1. -
    {{localize "BOL.ui.ammos"}}
    -
    {{localize "BOL.ui.slot"}}
    -
    {{localize "BOL.ui.qty"}}
    -
    {{localize "BOL.ui.price"}}
    -
    {{localize "BOL.ui.equip"}}
    -
    -
  2. - {{#each ammos as |item id|}} -
  3. -

    -
    - {{item.name}} -

    -
    - {{#if item.data.properties.equipable}} - {{localize (concat "BOL.equipmentSlots." item.data.properties.slot)}} - {{/if}} -
    -
    - {{#if item.data.properties.stackable}} -   - {{item.data.quantity}}  - - {{/if}} -
    -
    - {{item.data.price}} -
    -
    - {{#if data.properties.equipable}} - {{#if data.worn}} - - {{else}} - - {{/if}} - {{/if}} -
    -
    - -
    -
  4. - {{/each}} +
  5. +
    {{localize "BOL.ui.ammos"}}
    +
    {{localize "BOL.ui.slot"}}
    +
    {{localize "BOL.ui.qty"}}
    +
    {{localize "BOL.ui.price"}}
    +
    {{localize "BOL.ui.equip"}}
    +
    +
  6. + {{#each ammos as |item id|}} +
  7. +

    +
    + {{item.name}} +

    +
    + {{#if item.data.properties.equipable}} + {{localize (concat + "BOL.equipmentSlots." item.data.properties.slot)}} + {{/if}} +
    +
    + {{#if item.data.properties.stackable}} +   + {{item.data.quantity}}  + + {{/if}} +
    +
    + {{item.data.price}} +
    +
    + {{#if data.properties.equipable}} + {{#if data.worn}} + + {{else}} + + {{/if}} + {{/if}} +
    +
    + +
    +
  8. + {{/each}}
    -
  1. -
    {{localize "BOL.ui.containers"}}
    -
    {{localize "BOL.ui.slot"}}
    -
    {{localize "BOL.ui.qty"}}
    -
    {{localize "BOL.ui.price"}}
    -
    {{localize "BOL.ui.equip"}}
    -
    -
  2. - {{#each containers as |item id|}} -
  3. -

    -
    - {{item.name}} -

    -
    - {{#if item.data.properties.equipable}} - {{localize (concat "BOL.equipmentSlots." item.data.properties.slot)}} - {{/if}} -
    -
    - {{#if item.data.properties.stackable}} -   - {{item.data.quantity}}  - - {{/if}} -
    -
    - {{item.data.price}} -
    -
    - {{#if data.properties.equipable}} - {{#if data.worn}} - - {{else}} - - {{/if}} - {{/if}} -
    -
    - -
    -
  4. - {{/each}} +
  5. +
    {{localize "BOL.ui.containers"}}
    +
    {{localize "BOL.ui.slot"}}
    +
    {{localize "BOL.ui.qty"}}
    +
    {{localize "BOL.ui.price"}}
    +
    {{localize "BOL.ui.equip"}}
    +
    +
  6. + {{#each containers as |item id|}} +
  7. +

    +
    + {{item.name}} +

    +
    + {{#if item.data.properties.equipable}} + {{localize (concat + "BOL.equipmentSlots." item.data.properties.slot)}} + {{/if}} +
    +
    + {{#if item.data.properties.stackable}} +   + {{item.data.quantity}}  + + {{/if}} +
    +
    + {{item.data.price}} +
    +
    + {{#if data.properties.equipable}} + {{#if data.worn}} + + {{else}} + + {{/if}} + {{/if}} +
    +
    + +
    +
  8. + {{/each}}
    -
  1. -
    {{localize "BOL.ui.treasure"}}
    -
    {{localize "BOL.ui.slot"}}
    -
    {{localize "BOL.ui.qty"}}
    -
    {{localize "BOL.ui.price"}}
    -
    {{localize "BOL.ui.equip"}}
    -
    -
  2. - {{#each treasure as |item id|}} -
  3. -

    -
    - {{item.name}} -

    -
    - {{#if item.data.properties.equipable}} - {{localize (concat "BOL.equipmentSlots." item.data.properties.slot)}} - {{/if}} -
    -
    - {{#if item.data.properties.stackable}} -   - {{item.data.quantity}}  - - {{/if}} -
    -
    - {{item.data.price}} -
    -
    - {{#if data.properties.equipable}} - {{#if data.worn}} - - {{else}} - - {{/if}} - {{/if}} -
    -
    - -
    -
  4. - {{/each}} +
  5. +
    {{localize "BOL.ui.treasure"}}
    +
    {{localize "BOL.ui.slot"}}
    +
    {{localize "BOL.ui.qty"}}
    +
    {{localize "BOL.ui.price"}}
    +
    {{localize "BOL.ui.equip"}}
    +
    +
  6. + {{#each treasure as |item id|}} +
  7. +

    +
    + {{item.name}} +

    +
    + {{#if item.data.properties.equipable}} + {{localize (concat + "BOL.equipmentSlots." item.data.properties.slot)}} + {{/if}} +
    +
    + {{#if item.data.properties.stackable}} +   + {{item.data.quantity}}  + + {{/if}} +
    +
    + {{item.data.price}} +
    +
    + {{#if data.properties.equipable}} + {{#if data.worn}} + + {{else}} + + {{/if}} + {{/if}} +
    +
    + +
    +
  8. + {{/each}}
    -
  1. -
    {{localize "BOL.ui.vehicles"}}
    -
    {{localize "BOL.ui.slot"}}
    -
    {{localize "BOL.ui.qty"}}
    -
    {{localize "BOL.ui.price"}}
    -
    {{localize "BOL.ui.equip"}}
    -
    -
  2. - {{#each vehicles as |item id|}} -
  3. -

    -
    - {{item.name}} -

    -
    - {{#if item.data.properties.equipable}} - {{localize (concat "BOL.equipmentSlots." item.data.properties.slot)}} - {{/if}} -
    -
    - {{#if item.data.properties.stackable}} -   - {{item.data.quantity}}  - - {{/if}} -
    -
    - {{item.data.price}} -
    -
    - {{#if data.properties.equipable}} - {{#if data.worn}} - - {{else}} - - {{/if}} - {{/if}} -
    -
    - -
    -
  4. - {{/each}} +
  5. +
    {{localize "BOL.ui.vehicles"}}
    +
    {{localize "BOL.ui.slot"}}
    +
    {{localize "BOL.ui.qty"}}
    +
    {{localize "BOL.ui.price"}}
    +
    {{localize "BOL.ui.equip"}}
    +
    +
  6. + {{#each vehicles as |item id|}} +
  7. +

    +
    + {{item.name}} +

    +
    + {{#if item.data.properties.equipable}} + {{localize (concat + "BOL.equipmentSlots." item.data.properties.slot)}} + {{/if}} +
    +
    + {{#if item.data.properties.stackable}} +   + {{item.data.quantity}}  + + {{/if}} +
    +
    + {{item.data.price}} +
    +
    + {{#if data.properties.equipable}} + {{#if data.worn}} + + {{else}} + + {{/if}} + {{/if}} +
    +
    + +
    +
  8. + {{/each}}
    -
  1. -
    {{localize "BOL.ui.misc"}}
    -
    {{localize "BOL.ui.slot"}}
    -
    {{localize "BOL.ui.qty"}}
    -
    {{localize "BOL.ui.price"}}
    -
    {{localize "BOL.ui.equip"}}
    -
    -
  2. - {{#each misc as |item id|}} -
  3. -

    -
    - {{item.name}} -

    -
    - {{#if item.data.properties.equipable}} - {{localize (concat "BOL.equipmentSlots." item.data.properties.slot)}} - {{/if}} -
    -
    - {{#if item.data.properties.stackable}} -   - {{item.data.quantity}}  - - {{/if}} -
    -
    - {{item.data.price}} -
    -
    - {{#if data.properties.equipable}} - {{#if data.worn}} - - {{else}} - - {{/if}} - {{/if}} -
    -
    - -
    -
  4. - {{/each}} -
+
  • +
    {{localize "BOL.ui.misc"}}
    +
    {{localize "BOL.ui.slot"}}
    +
    {{localize "BOL.ui.qty"}}
    +
    {{localize "BOL.ui.price"}}
    +
    {{localize "BOL.ui.equip"}}
    +
    +
  • + {{#each misc as |item id|}} +
  • +

    +
    + {{item.name}} +

    +
    + {{#if item.data.properties.equipable}} + {{localize (concat + "BOL.equipmentSlots." item.data.properties.slot)}} + {{/if}} +
    +
    + {{#if item.data.properties.stackable}} +   + {{item.data.quantity}}  + + {{/if}} +
    +
    + {{item.data.price}} +
    +
    + {{#if data.properties.equipable}} + {{#if data.worn}} + + {{else}} + + {{/if}} + {{/if}} +
    +
    + +
    +
  • + {{/each}} + \ No newline at end of file diff --git a/templates/dialogs/mod-roll-part.hbs b/templates/dialogs/mod-roll-part.hbs index 0e3e31a..1ee2dd6 100644 --- a/templates/dialogs/mod-roll-part.hbs +++ b/templates/dialogs/mod-roll-part.hbs @@ -1,22 +1,43 @@ -
    -
    - -
    -
    - -
    -
    +{{#if isRanged}} +
    +
    + +
    +
    + +
    +
    +{{/if}} + +
    +
    + +
    +
    + +
    +
    \ No newline at end of file diff --git a/ui/.directory b/ui/.directory new file mode 100644 index 0000000..4fcea70 --- /dev/null +++ b/ui/.directory @@ -0,0 +1,4 @@ +[Dolphin] +Timestamp=2022,2,20,16,48,54.627 +Version=4 +VisibleRoles=Details_text,Details_size,Details_modificationtime,Details_creationtime,CustomizedDetails diff --git a/ui/attributes/.directory b/ui/attributes/.directory new file mode 100644 index 0000000..95e214b --- /dev/null +++ b/ui/attributes/.directory @@ -0,0 +1,4 @@ +[Dolphin] +Timestamp=2022,2,20,21,30,17.02 +Version=4 +VisibleRoles=Details_text,Details_size,Details_modificationtime,Details_creationtime,CustomizedDetails diff --git a/ui/icons/.directory b/ui/icons/.directory new file mode 100644 index 0000000..67a7301 --- /dev/null +++ b/ui/icons/.directory @@ -0,0 +1,4 @@ +[Dolphin] +Timestamp=2022,2,20,21,29,59.667 +Version=4 +VisibleRoles=Details_text,Details_size,Details_modificationtime,Details_creationtime,CustomizedDetails